UNPKG

@powership/server

Version:
1 lines 19.8 kB
{"version":3,"file":"Server.mjs","names":["HTTP","hope","NodeLogger","nonNullValues","httpErrors","createAsyncPlugin","isHttpError","ServerLogs","ServerRequest","ServerResponse","_404","parseHTTPBody","createHandler","InternalServerError","NotFound","Server","defaultHandlers","onError","_response","close","error","handledCount","httpError","errorResponse","create","onResponse","_request","body","constructor","definition","definitionInput","handlers","hooks","createHooks","closeServer","server","Promise","resolve","reject","err","hasStarted","handleRequest","request","closed","app","hopeForResponse","start","args","finalResponse","arg0","appResponse","statusCode","result","e","catch","onParseBody","dispatch","req","res","onRequest","response","withServer","port","_startHandlers","info","usedDefinition","undefined","middlewares","length","logWarning","createServer","_requestListener","httpServerRequest","httpServerResponse","httpMethod","method","requestBody","appRequest","headers","locals","url","headersNamed","streamBody","toHttpResponse","forEach","name","value","setHeader","on","end","pipe","console","trace","headersSent","Object","entries","k","v","message","listen","addressInfo","address","Error","assign","started","handlerByName","appHandler","warn","hookName","handler","defineProperty","pushMiddleware","willStartServer"],"sources":["../src/Server.ts"],"sourcesContent":["import * as HTTP from 'http';\nimport type { AddressInfo } from 'net';\n\nimport { hope, Hope, NodeLogger } from '@powership/utils';\nimport { Compute, nonNullValues } from '@powership/utils';\nimport httpErrors from 'http-errors';\nimport { createAsyncPlugin } from 'plugin-hooks';\n\nimport { isHttpError, RequestBody } from './BaseRequestHandler';\nimport { ServerLogs } from './ServerLogs';\nimport { ServerRequest } from './ServerRequest';\nimport { ServerResponse } from './ServerResponse';\nimport { UnhandledSymbol } from './Symbol';\nimport { _404 } from './_404';\nimport { parseHTTPBody } from './bodyParserHandler';\nimport { createHandler } from './createHandler';\n\nconst { InternalServerError, NotFound } = httpErrors;\n\nexport type ServerDefinition = {\n handlers: Handler<any>[];\n};\n\nexport class Server {\n defaultHandlers = [\n createHandler('defaultErrorHandler', {\n // Handling errors\n onError(_response, { close, error }) {\n if (this.handledCount) return;\n\n // initial Response\n\n ServerLogs.error(error);\n\n const httpError = isHttpError(error)\n ? error\n : new InternalServerError();\n\n const errorResponse = ServerResponse.create(httpError);\n\n close(errorResponse);\n },\n }),\n\n createHandler('notFoundHandler', {\n onResponse(_request, { close }) {\n if (this.handledCount) return; // TODO should be the last handler. check\n\n const httpError = new NotFound();\n httpError.body = _404();\n const errorResponse = ServerResponse.create(httpError);\n\n close(errorResponse);\n },\n }),\n ];\n\n constructor(definition: ServerDefinition) {\n this.definitionInput = definition;\n this.handlers = [...definition.handlers, ...this.defaultHandlers];\n }\n\n static create = (definition: ServerDefinition) => {\n return new Server(definition);\n };\n\n hooks = createHooks();\n\n private server?: HTTP.Server;\n\n closeServer = async (): Promise<'NOT_STARTED' | 'CLOSED'> => {\n const server = this.server;\n if (!server) return 'NOT_STARTED';\n\n return new Promise((resolve, reject) => {\n server.close((err) => {\n if (err) return reject(err);\n resolve('CLOSED');\n });\n });\n };\n\n usedDefinition?: ServerDefinition;\n hasStarted = false;\n\n readonly definitionInput:\n | ServerDefinition\n | ((app: Server) => ServerDefinition);\n\n readonly handlers: Handler[];\n\n handleRequest = (request: ServerRequest): Hope<ServerResponse> => {\n let closed = false;\n const app = this;\n\n const hopeForResponse = hope<ServerResponse>();\n\n (async () => {\n try {\n if (!app.hasStarted) {\n await this.start();\n }\n\n const hooks = app.hooks;\n\n await (async () => {\n const close: CloseResponseFunction = function close(...args) {\n //\n const finalResponse = (() => {\n const arg0 = args[0];\n if (!arg0) return appResponse;\n if (typeof arg0 === 'object') return arg0;\n appResponse.statusCode = arg0;\n return appResponse;\n })();\n\n if (closed || hopeForResponse.result || hopeForResponse.error) {\n closed = true;\n return;\n } else {\n closed = true;\n }\n\n if (!finalResponse) {\n closed = true;\n hopeForResponse.resolve(appResponse);\n return;\n }\n\n try {\n hopeForResponse.resolve(finalResponse);\n } catch (e: any) {\n if (!(hopeForResponse.result || hopeForResponse.error)) {\n onError(e).catch(ServerLogs.error);\n }\n }\n };\n\n let appResponse = ServerResponse.create();\n\n request.body = await hooks.onParseBody.dispatch(request.body, {\n req: request,\n res: appResponse,\n app,\n close,\n });\n\n request = await hooks.onRequest.dispatch(request, {\n app,\n response: appResponse,\n close,\n });\n\n appResponse = await hooks.onResponse.dispatch(appResponse, {\n app,\n request,\n close,\n });\n\n async function onError(error: Error) {\n const errorResponse = await hooks.onError.dispatch(appResponse, {\n request,\n error,\n close,\n });\n\n close(errorResponse);\n }\n\n if (!closed) {\n close(appResponse);\n }\n })();\n } catch (e: any) {\n hopeForResponse.reject(e);\n }\n })();\n\n return hopeForResponse;\n };\n\n withServer: ServerServerInfo | false = false;\n\n start(port: number): Promise<ServerStartResult>;\n start(port?: undefined): Promise<Server & { withServer: false }>;\n async start(port?: number | undefined) {\n const app = this;\n\n if (!app.hasStarted) {\n this._startHandlers();\n }\n\n if (app.hasStarted) {\n ServerLogs.info('RESTARTING_APP');\n await this.closeServer();\n }\n\n app.hasStarted = true;\n\n this.usedDefinition = await (() => {\n if (typeof this.definitionInput === 'function') {\n return this.definitionInput(this);\n }\n return this.definitionInput;\n })();\n\n const hooks = this.hooks;\n\n if (port === undefined) return app;\n\n if (!hooks.onResponse.middlewares.length) {\n NodeLogger.logWarning(`⚠️ No handlers listening to onResponse.`);\n }\n\n let server = HTTP.createServer(async function _requestListener(\n httpServerRequest,\n httpServerResponse\n ) {\n try {\n const { httpMethod } = nonNullValues({\n httpMethod: httpServerRequest.method,\n });\n\n const requestBody = await parseHTTPBody(\n httpServerRequest,\n httpServerResponse\n );\n\n const appRequest = ServerRequest.create({\n body: requestBody,\n headers: httpServerRequest.headers,\n locals: {},\n url: httpServerRequest.url,\n method: httpMethod,\n });\n\n const response = await app.handleRequest(appRequest);\n\n const { statusCode, body, headersNamed, streamBody } =\n response.toHttpResponse();\n\n httpServerResponse.statusCode = statusCode;\n\n headersNamed.forEach(({ name, value }) => {\n httpServerResponse.setHeader(name, value);\n });\n\n if (streamBody) {\n streamBody.on('error', (error) => {\n ServerLogs.error(error);\n httpServerResponse.statusCode = 500;\n httpServerResponse.end();\n });\n streamBody.pipe(httpServerResponse);\n } else {\n httpServerResponse.end(body);\n }\n } catch (error) {\n console.trace(error);\n ServerLogs.error(error);\n\n if (httpServerResponse.headersSent) {\n ServerLogs.error(`ERROR_AFTER_HEADERS_SENT`, error);\n } else {\n const error = new InternalServerError();\n httpServerResponse.statusCode = error.statusCode;\n if (error.headers) {\n Object.entries(error.headers).forEach(([k, v]) => {\n httpServerResponse.setHeader(k, v as any);\n });\n }\n httpServerResponse.end(error.message);\n }\n }\n });\n\n // server = await this.hooks.willStartServer.dispatch(server, { app: this });\n\n return new Promise(async (resolve, reject) => {\n try {\n server.listen(port, () => {\n const addressInfo = server.address();\n\n if (!addressInfo || typeof addressInfo !== 'object') {\n ServerLogs.info({ addressInfo });\n throw new Error(`Failed to recovery server addressInfo.`);\n }\n\n app.withServer = {\n server,\n ...addressInfo,\n };\n\n resolve(\n Object.assign(app, {\n server,\n ...addressInfo,\n })\n );\n });\n await this.hooks.started.dispatch(server, { app: this });\n } catch (e) {\n reject(e);\n }\n });\n }\n\n private _startHandlers = () => {\n const handlerByName: { [K: string]: Handler } = {};\n this.handlers.forEach((appHandler) => {\n const { hooks, name } = appHandler;\n\n if (handlerByName[name] && handlerByName[name] !== appHandler) {\n console.warn(`Handler with name \"${name}\" already registered.`);\n } else {\n handlerByName[name] = appHandler;\n }\n\n Object.entries(hooks).forEach(([hookName, handler]) => {\n try {\n Object.defineProperty(handler, 'name', {\n value: `${name}_${hookName}`,\n });\n } catch (e) {}\n\n this.hooks[hookName].pushMiddleware(handler);\n });\n });\n return handlerByName;\n };\n}\n\nexport type Handler<\n Data extends Record<string, any> | undefined = {} | undefined\n> = {\n name: string;\n hooks: ServerHooksRecord;\n data: Data;\n};\n\nexport type ServerHooksRecord = {\n [K in keyof ServerHooks]?: Parameters<\n ServerHooks[K]\n >[0] extends infer Register\n ? Register\n : never;\n};\n\nexport type ServerHooks = ReturnType<typeof createHooks>;\n\nfunction createHooks() {\n return {\n willStartServer: createAsyncPlugin<HTTP.Server, { app: Server }>(),\n started: createAsyncPlugin<HTTP.Server, { app: Server }>(),\n onParseBody: createAsyncPlugin<\n RequestBody | UnhandledSymbol,\n {\n req: ServerRequest;\n res: ServerResponse;\n app: Server;\n close: CloseResponseFunction;\n }\n >(),\n onRequest: createAsyncPlugin<\n ServerRequest,\n { response: ServerResponse; app: Server; close: CloseResponseFunction }\n >(),\n onResponse: createAsyncPlugin<\n ServerResponse,\n { request: ServerRequest; app: Server; close: CloseResponseFunction }\n >(),\n onError: createAsyncPlugin<\n ServerResponse,\n {\n request: ServerRequest;\n error: Error;\n close: CloseResponseFunction;\n }\n >(),\n };\n}\n\nexport type ServerServerInfo = Compute<{ server: HTTP.Server } & AddressInfo>;\n\nexport type ServerStartResult = Server &\n ServerServerInfo & { withServer: ServerServerInfo };\n\nexport interface CloseResponseFunction {\n (response?: ServerResponse | ServerResponse['statusCode']): void;\n}\n"],"mappings":"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","ignoreList":[]}