Skip to content

Instantly share code, notes, and snippets.

@StanSarr
Created November 13, 2018 01:07
Show Gist options
  • Select an option

  • Save StanSarr/7e12d5892dd36e40af155816ec80adf6 to your computer and use it in GitHub Desktop.

Select an option

Save StanSarr/7e12d5892dd36e40af155816ec80adf6 to your computer and use it in GitHub Desktop.
Json codec middleware
// @flow
/* eslint-disable flowtype/no-weak-types */
import { type Fetch, type Request, type Response } from '../fetch';
export type JSONValue = any;
export type JSONRequest = {|
cache?: $PropertyType<Request, 'cache'>,
credentials?: $PropertyType<Request, 'credentials'>,
data: JSONValue,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
[string]: any,
},
integrity?: $PropertyType<Request, 'integrity'>,
keepalive?: $PropertyType<Request, 'keepalive'>,
method?: $PropertyType<Request, 'method'>,
mode?: $PropertyType<Request, 'mode'>,
redirect?: $PropertyType<Request, 'redirect'>,
referrer?: $PropertyType<Request, 'referrer'>,
referrerPolicy?: $PropertyType<Request, 'referrerPolicy'>,
url: $PropertyType<Request, 'url'>,
window?: $PropertyType<Request, 'window'>,
|};
export type JSONResponse = {|
data: JSONValue,
headers: $PropertyType<Response, 'headers'>,
ok: $PropertyType<Response, 'ok'>,
redirected: $PropertyType<Response, 'redirected'>,
status: $PropertyType<Response, 'status'>,
statusText: $PropertyType<Response, 'statusText'>,
trailer: $PropertyType<Response, 'trailer'>,
type: $PropertyType<Response, 'type'>,
url: $PropertyType<Response, 'url'>,
|};
export function createJSONRequest({
headers,
data = null,
...params
}: {|
...$Rest<JSONRequest, {| data: mixed, headers: mixed |}>,
data?: $PropertyType<JSONRequest, 'data'>,
headers?: {
[string]: any,
},
|}): JSONRequest {
return {
data,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...headers,
},
...params,
};
}
export function createJSONResponse({
ok = true,
headers = {},
redirected = false,
status = 200,
statusText = 'OK',
type = 'basic',
data = undefined,
trailer = Promise.resolve(),
...params
}: $Shape<JSONResponse>): JSONResponse {
return {
ok,
headers,
redirected,
status,
statusText,
type,
data,
trailer,
...params,
};
}
/**
* JSONCodec middleware
*/
export function JSONCodec() {
return (next: Fetch) =>
async function fetch(request: JSONRequest): Promise<JSONResponse> {
const { headers, data: requestData, ...requestParams } = request;
const response = await next({
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...headers,
},
...(requestData ? { body: JSON.stringify(requestData) } : {}),
...requestParams,
});
const data = await response.json();
return {
data,
headers: response.headers,
ok: response.ok,
redirected: response.redirected,
status: response.status,
statusText: response.statusText,
trailer: response.trailer,
type: response.type,
url: response.url,
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment