Skip to content

Instantly share code, notes, and snippets.

@serebano
Created August 7, 2024 13:27
Show Gist options
  • Save serebano/9678b3b65973b167b354791e28f8abe9 to your computer and use it in GitHub Desktop.
Save serebano/9678b3b65973b167b354791e28f8abe9 to your computer and use it in GitHub Desktop.
export default function RequestModule() {
/**
* Type utils
*/
type Simplify<T> = { [KeyType in keyof T]: T[KeyType] };
function deepAssign(
target: Record<string, any>,
...sources: Record<string, any>[]
) {
for (const source of sources) {
for (const k in source) {
const vs = source[k], vt = target[k];
if (Object(vs) == vs && Object(vt) === vt) {
target[k] = deepAssign(vt, vs);
continue;
}
target[k] = source[k];
}
}
return target;
}
/**
* Represents a raw request message.
*
* @remarks
* This request message is used to generate JavaScript API.
* It includes various headers and a JSON payload containing information
* about the request.
*
* @public
*/
const requestMessage = `POST /post?q1=v1 HTTP/1.1
Host: httpbin.proxyman.app
Content-Type: application/json
Connection: close
Content-Length: 37
{"JJJ":"fooooo","name":"JSON Sample"}`;
/**
* Request url
*/
const url = 'https://httpbin.proxyman.app/post?q1=v1';
/**
* Request method
*/
const method = 'POST';
/**
* Request path
*/
const path = '/post?q1=v1';
/**
* Request headers
*/
const headers = {
'Host': 'httpbin.proxyman.app',
'Content-Type': 'application/json',
'Connection': 'close',
'Content-Length': '37',
} as HeadersDefaults;
/**
* Request body
*/
const body = {
'JJJ': 'fooooo',
'name': 'JSON Sample',
} as PayloadDefaults;
/**
* Represents the parameters for the headers in a request.
*
* @type {HeadersParams}
*/
const headersParams = {};
/**
* HeadersDefaults Type
*/
type HeadersDefaults = {
'Host': 'httpbin.proxyman.app';
'Content-Type': 'application/json';
'Connection': 'close';
'Content-Length': '37';
};
/**
* HeadersParams Type
*/
type HeadersParams = typeof headersParams;
/**
* Represents the parameters for the body in a request.
*
* @type {PayloadParams}
*/
const payloadParams = { 'JJJ': 'fooooo', 'name': 'JSON Sample' };
/**
* PayloadDefaults Type
*/
type PayloadDefaults = { 'JJJ': 'fooooo'; 'name': 'JSON Sample' };
/**
* PayloadParams Type
*/
type PayloadParams = typeof payloadParams;
/**
* Represents the parameters in a request.
*
* @type {RequestParams}
*/
const requestParams = {
headers: headersParams,
payload: payloadParams,
} as RequestParams;
/**
* RequestParams Type
*/
type RequestParams = { headers: HeadersParams; payload: PayloadParams };
/**
* RequestInit Type
*/
type RequestInitType = {
url: string;
path: string;
query: Record<string, string | string[]>;
method: 'POST';
headers: HeadersDefaults & HeadersParams;
body: PayloadParams;
rawBody: string;
};
function createRequestInit(
params: Partial<RequestParams> = requestParams,
): RequestInitType {
const _url = new URL(url);
const _query = Object.fromEntries(_url.searchParams.entries());
const _headers = deepAssign(
headers,
params.headers || {},
) as RequestInitType['headers'];
const _body = deepAssign(
body,
params.payload || {},
) as RequestInitType['body'];
const _rawBody = JSON.stringify(_body);
return {
url: _url.toString(),
path: _url.pathname,
query: _query,
method,
headers: _headers,
body: _body,
rawBody: _rawBody,
};
}
/**
* Creates a request object for fetching
*
* @param params - The request parameters.
* @returns A new Request object.
*/
function createRequest(
params: Partial<RequestParams> = requestParams,
): Request {
const initDict = createRequestInit(params);
return new Request(url, {
...initDict,
body: initDict.rawBody,
});
}
return { createRequest, createRequestInit, requestParams };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment