Skip to content

Commit

Permalink
Make non textual requests (#666)
Browse files Browse the repository at this point in the history
* add requestAs constructor

* to arrow functions

* bump version to 5.1.0
  • Loading branch information
StefanoMagrassi authored Feb 3, 2023
1 parent 4e0faa4 commit 2d90173
Show file tree
Hide file tree
Showing 22 changed files with 345 additions and 165 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## [5.1.0](https://github.com/contactlab/appy/releases/tag/5.1.0)

**New Feature:**

- Make non-textual requests (#665)

**Dependencies:**

- [Security] Bump json5 from 1.0.1 to 1.0.2 (#656)

## [5.0.0](https://github.com/contactlab/appy/releases/tag/5.0.0)

**Breaking:**
Expand Down
10 changes: 10 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ nav_order: 2

# Changelog

## [5.1.0](https://github.com/contactlab/appy/releases/tag/5.1.0)

**New Feature:**

- Make non-textual requests (#665)

**Dependencies:**

- [Security] Bump json5 from 1.0.1 to 1.0.2 (#656)

## [5.0.0](https://github.com/contactlab/appy/releases/tag/5.0.0)

**Breaking:**
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/combinators/abort.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ users().then((result) => {
**Signature**

```ts
export declare function withCancel<A>(controller: AbortController): (req: Req<A>) => Req<A>
export declare const withCancel: (controller: AbortController) => Combinator
```
Added in v3.1.0
Expand Down Expand Up @@ -105,7 +105,7 @@ users().then((result) => {
**Signature**

```ts
export declare function withTimeout<A>(millis: number): (req: Req<A>) => Req<A>
export declare const withTimeout: (millis: number) => <A>(req: Req<A>) => Req<A>
```
Added in v3.1.0
2 changes: 1 addition & 1 deletion docs/modules/combinators/body.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Sets the provided `body` (automatically converted to string when JSON) on `Req`
**Signature**

```ts
export declare function withBody<A>(body: unknown): (req: Req<A>) => Req<A>
export declare const withBody: (body: unknown) => Combinator
```
Added in v3.0.0
4 changes: 2 additions & 2 deletions docs/modules/combinators/decoder.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ It automatically sets "JSON" request header's
**Signature**

```ts
export declare function withDecoder<A, B>(decoder: Decoder<B>): (req: Req<A>) => Req<B>
export declare const withDecoder: <B>(decoder: Decoder<B>) => <A>(req: Req<A>) => Req<B>
```
Added in v3.0.0
Expand All @@ -77,7 +77,7 @@ Converts a `GenericDecoder<L, A>` into a `Decoder<A>`.
**Signature**
```ts
export declare function toDecoder<L, A>(dec: GenericDecoder<L, A>, onLeft: (e: L) => Error): Decoder<A>
export declare const toDecoder: <L, A>(dec: GenericDecoder<L, A>, onLeft: (e: L) => Error) => Decoder<A>
```
Added in v3.0.0
2 changes: 1 addition & 1 deletion docs/modules/combinators/headers.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Merges provided `Headers` with `Req` ones and returns the updated `Req`.
**Signature**

```ts
export declare function withHeaders<A>(headers: HeadersInit): (req: Req<A>) => Req<A>
export declare const withHeaders: (headers: HeadersInit) => Combinator
```
Added in v3.0.0
2 changes: 1 addition & 1 deletion docs/modules/combinators/method.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Sets provided method on `Req` and returns the updated `Req`.
**Signature**

```ts
export declare function withMethod<A>(method: string): (req: Req<A>) => Req<A>
export declare const withMethod: (method: string) => Combinator
```
Added in v4.0.0
2 changes: 1 addition & 1 deletion docs/modules/combinators/url-params.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Adds provided url search parameters (as `Record<string, string>`) to `Req`'s inp
**Signature**
```ts
export declare function withUrlParams<A>(params: Params): (req: Req<A>) => Req<A>
export declare const withUrlParams: (params: Params) => Combinator
```
Added in v3.0.0
57 changes: 52 additions & 5 deletions docs/modules/request.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Added in v4.0.0
- [toRequestError](#torequesterror)
- [toResponseError](#toresponseerror)
- [Request](#request)
- [Combinator (type alias)](#combinator-type-alias)
- [Req (interface)](#req-interface)
- [ReqInput (type alias)](#reqinput-type-alias)
- [RequestInfoInit (type alias)](#requestinfoinit-type-alias)
Expand All @@ -31,6 +32,7 @@ Added in v4.0.0
- [Resp (interface)](#resp-interface)
- [creators](#creators)
- [request](#request)
- [requestAs](#requestas)

---

Expand Down Expand Up @@ -87,7 +89,7 @@ Creates a `RequestError` object.
**Signature**

```ts
export declare function toRequestError(error: Error, input: RequestInfoInit): RequestError
export declare const toRequestError: (error: Error, input: RequestInfoInit) => RequestError
```
Added in v4.0.0
Expand All @@ -99,13 +101,25 @@ Creates a `ResponseError` object.
**Signature**
```ts
export declare function toResponseError(error: Error, response: Response): ResponseError
export declare const toResponseError: (error: Error, response: Response) => ResponseError
```
Added in v4.0.0
# Request
## Combinator (type alias)
A combinator is a function to transform/operate on a `Req`.
**Signature**
```ts
export type Combinator = <A>(req: Req<A>) => Req<A>
```
Added in v5.1.0
## Req (interface)
`Req<A>` encodes a resource's request, or rather, an async operation that can fail or return a `Resp<A>`.
Expand Down Expand Up @@ -151,7 +165,7 @@ Normalizes the input of a `Req` to a `RequestInfoInit` tuple even when only a si
**Signature**
```ts
export declare function normalizeReqInput(input: ReqInput): RequestInfoInit
export declare const normalizeReqInput: (input: ReqInput) => RequestInfoInit
```
Added in v4.0.0
Expand Down Expand Up @@ -185,13 +199,13 @@ Example:

```ts
import { request } from '@contactlab/appy'
import { fold } from 'fp-ts/Either'
import { match } from 'fp-ts/Either'

// Default method is GET like original `fetch()`
const users = request('https://reqres.in/api/users')

users().then(
fold(
match(
(err) => console.error(err),
(data) => console.log(data)
)
Expand All @@ -205,3 +219,36 @@ export declare const request: Req<string>
```
Added in v4.0.0
## requestAs
Return a `Req` which will be executed using `fetch()` under the hood.
The `data` in the returned `Resp` object is of the type specified in the `type` parameter which is one of [supported `Request` methods](https://developer.mozilla.org/en-US/docs/Web/API/Response#instance_methods).
Example:
```ts
import { requestAs } from '@contactlab/appy'
import { match } from 'fp-ts/Either'

// Default method is GET like original `fetch()`
const users = requestAs('json')('https://reqres.in/api/users')

users().then(
match(
(err) => console.error(err),
(data) => console.log(data)
)
)
```

**Signature**

```ts
export declare const requestAs: <K extends 'arrayBuffer' | 'blob' | 'formData' | 'json' | 'text'>(
type: K
) => Req<BodyTypeData<K>>
```
Added in v5.1.0
2 changes: 1 addition & 1 deletion docs/modules/response.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Clones a `Response` object with the provided content as body.
**Signature**

```ts
export declare function cloneResponse<A>(from: Response, content: A): Response
export declare const cloneResponse: <A>(from: Response, content: A) => Response
```
Added in v4.0.1
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contactlab/appy",
"version": "5.0.0",
"version": "5.1.0",
"description": "A functional wrapper around Fetch API",
"main": "./index.js",
"module": "./_es6/index.js",
Expand Down
20 changes: 8 additions & 12 deletions src/combinators/abort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import * as RTE from 'fp-ts/ReaderTaskEither';
import * as TU from 'fp-ts/Tuple';
import {pipe} from 'fp-ts/function';
import {Req, normalizeReqInput} from '../request';
import {type Req, type Combinator, normalizeReqInput} from '../request';

/**
* Sets `signal` on `Req` in order to make request cancellable through `AbortController`.
Expand All @@ -60,11 +60,8 @@ import {Req, normalizeReqInput} from '../request';
* @category combinators
* @since 3.1.0
*/
export function withCancel<A>(
controller: AbortController
): (req: Req<A>) => Req<A> {
return setSignal(controller.signal);
}
export const withCancel = (controller: AbortController): Combinator =>
setSignal(controller.signal);

/**
* Aborts the request if it does not respond within provided milliseconds.
Expand All @@ -87,8 +84,9 @@ export function withCancel<A>(
* @category combinators
* @since 3.1.0
*/
export function withTimeout<A>(millis: number): (req: Req<A>) => Req<A> {
return req => {
export const withTimeout =
(millis: number) =>
<A>(req: Req<A>): Req<A> => {
const controller = new AbortController();

return pipe(
Expand All @@ -105,10 +103,9 @@ export function withTimeout<A>(millis: number): (req: Req<A>) => Req<A> {
)
);
};
}

function setSignal<A>(signal: AbortSignal): (req: Req<A>) => Req<A> {
return RTE.local(input =>
const setSignal = (signal: AbortSignal): Combinator =>
RTE.local(input =>
pipe(
normalizeReqInput(input),
// The "weird" merging is due to the mix of the contravariant nature of `Reader`
Expand All @@ -119,4 +116,3 @@ function setSignal<A>(signal: AbortSignal): (req: Req<A>) => Req<A> {
TU.mapSnd(init => Object.assign({}, {signal}, init))
)
);
}
33 changes: 17 additions & 16 deletions src/combinators/body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ import * as RTE from 'fp-ts/ReaderTaskEither';
import * as TU from 'fp-ts/Tuple';
import {pipe} from 'fp-ts/function';
import {
Req,
ReqInput,
type Req,
type ReqInput,
type Err,
type Combinator,
normalizeReqInput,
toRequestError,
Err
toRequestError
} from '../request';

/**
Expand All @@ -38,12 +39,14 @@ import {
* @category combinators
* @since 3.0.0
*/
export function withBody<A>(body: unknown): (req: Req<A>) => Req<A> {
return req => pipe(toBodyInit(body), RTE.chain(setBody(req)));
}
export const withBody =
(body: unknown): Combinator =>
req =>
pipe(toBodyInit(body), RTE.chain(setBody(req)));

function setBody<A>(req: Req<A>): (body: BodyInit) => Req<A> {
return body =>
const setBody =
<A>(req: Req<A>) =>
(body: BodyInit): Req<A> =>
pipe(
req,
RTE.local(input =>
Expand All @@ -58,12 +61,11 @@ function setBody<A>(req: Req<A>): (body: BodyInit) => Req<A> {
)
)
);
}

function toBodyInit(
const toBodyInit = (
body: unknown
): RTE.ReaderTaskEither<ReqInput, Err, BodyInit> {
return pipe(
): RTE.ReaderTaskEither<ReqInput, Err, BodyInit> =>
pipe(
RTE.ask<ReqInput>(),
RTE.chain(input =>
RTE.fromEither(
Expand All @@ -74,12 +76,11 @@ function toBodyInit(
)
)
);
}

function toStringWhenJSON(body: unknown): E.Either<Error, BodyInit> {
const toStringWhenJSON = (body: unknown): E.Either<Error, BodyInit> => {
if (Object.getPrototypeOf(body).constructor.name !== 'Object') {
return E.right(body as BodyInit); // type assertion mandatory...
}

return pipe(stringify(body), E.mapLeft(E.toError));
}
};
Loading

0 comments on commit 2d90173

Please sign in to comment.