UNPKG

@powership/server

Version:
1 lines 16.7 kB
{"version":3,"file":"BaseRequestHandler.mjs","names":["getTypeName","inspectObject","isProduction","httpErrors","StatusCodes","StatusCodesEnum","qs","ServerLogs","UnhandledSymbol","createRouteMatcher","HttpError","InternalServerError","isHttpError","PreconditionFailed","BaseRequest","constructor","init","replace","input","query","method","host","headers","pathname","port","urlObject","parseInit","parseHeaders","get","toUpperCase","URL","url","parse","search","undefined","Headers","Object","entries","forEach","name","v","Array","isArray","el","Error","append","BaseRequestHandler","body","statusCode","graphQLData","data","errors","graphQLResponse","length","map","message","join","response","jsonBody","path","e","toHttpResponse","toHttp","toHttpRequest","testRoute","routePattern","match","httpStatusCode","toString","INTERNAL_SERVER_ERROR","httpResponseBody","isStream","JSON","stringify","fatal","constructorName","console","error","headersNamed","parsed","reduce","acc","value","httpHeaders","type","req","bodyInit","streamBody","payload","pipe","abort","on"],"sources":["../src/BaseRequestHandler.ts"],"sourcesContent":["import { getTypeName } from '@powership/utils';\nimport { inspectObject, isProduction } from '@powership/utils';\nimport httpErrors from 'http-errors';\nimport { StatusCodes as StatusCodesEnum } from 'http-status-codes';\nimport qs, { ParsedQs } from 'qs';\n\nimport { ServerLogs } from './ServerLogs';\nimport { UnhandledSymbol } from './Symbol';\nimport { createRouteMatcher, RouteMatcher } from './routeMatch';\nimport { Readable, Stream } from 'node:stream';\n\nconst { HttpError, InternalServerError, isHttpError, PreconditionFailed } =\n httpErrors;\nexport { HttpError, isHttpError };\n\nexport type BaseRequestHandlerInit = {\n url?: string;\n headers?: HeaderRecordInit | Headers;\n body?: RequestBody;\n statusCode?: ServerResponseStatus;\n method?: string;\n};\n\nexport class BaseRequest {\n urlObject!: URL;\n pathname!: string;\n host!: string;\n port!: string;\n query!: ParsedQs;\n headers!: Headers;\n method!: string;\n input!: BaseRequestHandlerInit;\n\n constructor(init: BaseRequestHandlerInit) {\n this.replace(init);\n }\n\n replace = (init: BaseRequestHandlerInit) => {\n this.input = init;\n\n const {\n //\n query,\n method,\n host,\n headers,\n pathname,\n port,\n urlObject,\n } = this.parseInit(init);\n\n this.query = query;\n this.method = method;\n this.headers = headers;\n this.host = host;\n this.pathname = pathname;\n this.port = port;\n this.urlObject = urlObject;\n\n return this;\n };\n\n parseInit = (init: BaseRequestHandlerInit) => {\n const headers = BaseRequest.parseHeaders(init.headers);\n const host = headers.get('host') || 'UNKNOWN';\n const method = (init.method || 'UNKNOWN').toUpperCase();\n\n const urlObject = new URL(\n init.url || '',\n `http://${host}` // fixme get protocol\n );\n\n const query = qs.parse(urlObject.search);\n const pathname = urlObject.pathname;\n const port = urlObject.port;\n\n return { headers, host, method, query, pathname, port, urlObject };\n };\n\n static parseHeaders = (input: BaseRequestHandlerInit['headers']): Headers => {\n if (input === undefined) return new Headers();\n if (input instanceof Headers) return input;\n if (input && typeof input === 'object') {\n const headers = new Headers();\n Object.entries(input).forEach(([name, v]) => {\n //\n if (Array.isArray(v)) {\n v.forEach((el) => {\n if (typeof el !== 'string') {\n throw new Error(`INVALID_HEADER_TYPE: ${typeof el}`);\n }\n headers.append(name, `${v}`);\n });\n return;\n }\n\n switch (typeof v) {\n case 'boolean':\n case 'string': {\n headers.append(name, `${v}`);\n break;\n }\n default: {\n throw new Error(`INVALID_HEADER_TYPE: ${typeof v}`);\n }\n }\n });\n return headers;\n }\n throw new Error('INVALID_HEADERS_CONFIG');\n };\n}\n\nexport type _GraphQLDataBasic = null | undefined | string | number;\n\nexport type GraphQLDataResponse =\n | _GraphQLDataBasic\n | GraphQLDataResponse[]\n | Record<string, _GraphQLDataBasic>;\n\nexport type GraphQLResponseRecord = {\n [K: string]: GraphQLDataResponse;\n};\n\nexport class BaseRequestHandler extends BaseRequest {\n body: RequestBody;\n headers: Headers;\n statusCode: ServerResponseStatus;\n\n constructor(input: BaseRequestHandlerInit = {}) {\n super(input);\n\n const { body = UnhandledSymbol, headers, statusCode = 404 } = input;\n\n this.statusCode = statusCode;\n this.body = body;\n this.headers = BaseRequestHandler.parseHeaders(headers);\n }\n\n graphQLData(): GraphQLResponseRecord {\n const { data, errors } = this.graphQLResponse();\n if (errors?.length) {\n throw new PreconditionFailed(errors.map((el) => el.message).join('. '));\n }\n return data;\n }\n\n graphQLResponse(): {\n errors?: { message: string; path: string }[];\n data: GraphQLResponseRecord;\n } {\n try {\n const response = BaseRequestHandler.jsonBody(this.body);\n const { errors, data } = response;\n\n if (!errors && !('data' in response)) {\n return { errors: [{ message: 'Empty response.', path: '' }], data: {} };\n }\n\n return { errors, data };\n } catch (e: any) {\n return { errors: [{ message: e.message, path: '' }], data: {} };\n }\n }\n\n toHttpResponse = (): HTTPHandlerParsed => {\n return BaseRequestHandler.toHttp(this, 'RESPONSE');\n };\n\n toHttpRequest = (): HTTPHandlerParsed => {\n return BaseRequestHandler.toHttp(this, 'REQUEST');\n };\n\n /**\n * Return the matched routePattern parameters or null\n * if the route has no parameters, an empty object is returned\n * https://github.com/snd/url-pattern\n * @param routePattern\n */\n testRoute = <Path extends string>(routePattern: Path) => {\n return BaseRequestHandler.createRouteMatcher(routePattern).match(\n this.urlObject.pathname.replace(/\\/$/, '')\n );\n };\n\n static createRouteMatcher<Path extends string>(\n routePattern: Path\n ): RouteMatcher<Path> {\n return createRouteMatcher(routePattern);\n }\n\n static httpStatusCode(statusCode: ServerResponseStatus): number {\n if (statusCode in StatusCodesEnum) {\n if (statusCode?.toString().match(/^\\d*$/)) {\n return +statusCode;\n }\n return +StatusCodesEnum[statusCode];\n }\n return StatusCodesEnum.INTERNAL_SERVER_ERROR;\n }\n\n static httpResponseBody(body: BaseRequestHandler['body']) {\n if (typeof body === 'string') return body;\n\n if (body === UnhandledSymbol) return '';\n\n if (!body) return '';\n\n if (isStream(body)) {\n return body;\n }\n\n if (typeof body === 'object') {\n try {\n return JSON.stringify(body);\n } catch (e) {\n ServerLogs.fatal(e);\n throw new InternalServerError();\n }\n }\n\n return '';\n }\n\n static jsonBody(body: BaseRequestHandler['body']): Record<string, any> {\n const constructorName = getTypeName(body);\n\n if (constructorName === 'String') {\n try {\n return JSON.parse(body as string);\n } catch (e) {\n console.error(`Failed to parse json.`);\n if (!isProduction()) {\n console.error(inspectObject(e));\n }\n }\n }\n\n if (constructorName === 'Object') {\n return body as object;\n }\n\n ServerLogs.fatal(`Invalid body`, inspectObject(body));\n return {};\n }\n\n static headersNamed(\n headers: BaseRequestHandlerInit['headers']\n ): HeaderNamed[] {\n const parsed = BaseRequestHandler.parseHeaders(headers);\n\n // @ts-ignore\n return [...parsed.entries()].reduce((acc, [name, value]) => {\n return [...acc, { name, value }];\n }, []);\n }\n\n static httpHeaders(headers: BaseRequestHandlerInit['headers']): HeaderRecord {\n return BaseRequestHandler.headersNamed(headers).reduce(\n (acc, { name, value }) => ({ ...acc, [name]: value }),\n {}\n );\n }\n\n static toHttp(\n input: BaseRequestHandlerInit | BaseRequestHandler,\n type: 'REQUEST' | 'RESPONSE'\n ): HTTPHandlerParsed {\n const req = new BaseRequest(input);\n\n const { body: bodyInit } = input;\n\n const body =\n type === 'RESPONSE'\n ? this.httpResponseBody(bodyInit ?? UnhandledSymbol)\n : bodyInit === UnhandledSymbol\n ? ''\n : bodyInit ?? '';\n\n return {\n body,\n streamBody: isStream(body) ? body : undefined,\n headers: this.httpHeaders(input.headers),\n statusCode: this.httpStatusCode(input.statusCode ?? 404),\n headersNamed: this.headersNamed(input.headers),\n payload: {},\n method: req.method,\n query: req.query,\n type,\n };\n }\n}\n\nfunction isStream(value: any): value is Readable {\n return (\n typeof value?.pipe === 'function' &&\n typeof value?.abort === 'function' &&\n typeof value?.on === 'function'\n );\n}\n\nexport type HTTPHandlerParsed = {\n headers: HeaderRecord;\n body: RequestBody;\n /**\n * undefined if body is not streamable\n */\n streamBody: Readable | undefined;\n statusCode: number;\n headersNamed: HeaderNamed[];\n payload: Record<string, unknown>;\n method: string;\n query: ParsedQs;\n type: 'REQUEST' | 'RESPONSE';\n};\n\nexport type RequestBody =\n | string\n | Record<string, unknown>\n | UnhandledSymbol\n | Stream;\n\nexport type HeaderNamed = { name: string; value: string };\n\nexport type HeaderRecord = {\n [K: string]: string[];\n};\n\nexport type HeaderRecordInit = {\n [K: string]: string | boolean | string[] | undefined;\n};\n\nexport type ServerResponseStatus =\n | keyof typeof StatusCodesEnum\n | StatusCodesEnum;\n"],"mappings":"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","ignoreList":[]}