@3sixty/api-server-fastify 0.20.0-next.0 → 0.20.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/fastifySocketIo.js.map +1 -1
- package/dist/es/fastifyWebServer.js +67 -580
- package/dist/es/fastifyWebServer.js.map +1 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/models/IFastifyWebServerConfig.js.map +1 -1
- package/dist/es/models/IFastifyWebServerConstructorOptions.js.map +1 -1
- package/dist/types/fastifyWebServer.d.ts +31 -16
- package/dist/types/models/IFastifyWebServerConfig.d.ts +5 -2
- package/docs/changelog.md +21 -0
- package/docs/reference/classes/FastifyWebServer.md +671 -40
- package/docs/reference/interfaces/IFastifyWebServerConfig.md +8 -2
- package/locales/.validate-ignore +1 -3
- package/locales/en.json +1 -22
- package/package.json +9 -10
- package/dist/es/models/IRestProcessorChains.js +0 -2
- package/dist/es/models/IRestProcessorChains.js.map +0 -1
- package/dist/es/models/ISocketProcessorChains.js +0 -2
- package/dist/es/models/ISocketProcessorChains.js.map +0 -1
- package/dist/types/models/IRestProcessorChains.d.ts +0 -18
- package/dist/types/models/ISocketProcessorChains.d.ts +0 -26
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastifyWebServer.js","sourceRoot":"","sources":["../../src/fastifyWebServer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\ttype HealthApplicationCallback,\n\tHealthStatus,\n\tHttpBodyLimit,\n\tHttpContextIdKeys,\n\tHttpErrorHelper,\n\ttype IHealthProviderComponent,\n\ttype IHealth,\n\ttype IHttpRequest,\n\ttype IHttpRequestPathParams,\n\ttype IHttpRequestQuery,\n\ttype IHttpResponse,\n\ttype IHttpServerRequest,\n\ttype IMimeTypeProcessor,\n\ttype IRestRoute,\n\ttype IRestRouteProcessor,\n\ttype ISocketRoute,\n\ttype ISocketRouteProcessor,\n\ttype ISocketServerRequest,\n\ttype IWebServer,\n\ttype IWebServerOptions,\n\tHealthCategory\n} from \"@3sixty/api-models\";\nimport { JsonLdMimeTypeProcessor } from \"@3sixty/api-processors\";\nimport { ContextIdStore, type IContextIds } from \"@3sixty/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGeneralError,\n\ttype IError,\n\tIs,\n\tRandomHelper,\n\tStringHelper,\n\tUrl\n} from \"@3sixty/core\";\nimport type { ILoggingComponent } from \"@3sixty/logging-models\";\nimport { nameof } from \"@3sixty/nameof\";\nimport {\n\tHeaderTypes,\n\tHttpMethod,\n\tHttpStatusCode,\n\ttype IHttpHeaders,\n\tHeaderHelper,\n\tMimeTypes\n} from \"@3sixty/web\";\nimport FastifyCompress from \"@fastify/compress\";\nimport FastifyCors from \"@fastify/cors\";\nimport Fastify, {\n\ttype FastifyInstance,\n\ttype FastifyReply,\n\ttype FastifyRequest,\n\ttype FastifyServerOptions\n} from \"fastify\";\nimport type { Server, ServerOptions, Socket } from \"socket.io\";\nimport FastifySocketIO from \"./fastifySocketIo.js\";\nimport type { IFastifyWebServerConstructorOptions } from \"./models/IFastifyWebServerConstructorOptions.js\";\nimport type { IRestProcessorChains } from \"./models/IRestProcessorChains.js\";\nimport type { ISocketProcessorChains } from \"./models/ISocketProcessorChains.js\";\n\n/**\n * Implementation of the web server using Fastify.\n */\nexport class FastifyWebServer implements IWebServer<FastifyInstance>, IHealthProviderComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<FastifyWebServer>();\n\n\t/**\n\t * Default port for running the server.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_PORT: number = 3000;\n\n\t/**\n\t * Default host for running the server.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_HOST: string = \"localhost\";\n\n\t/**\n\t * Default named body size limits for routes.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_BODY_LIMITS: { [name: string]: number } = {\n\t\t[HttpBodyLimit.Default]: 1048576,\n\t\t[HttpBodyLimit.Large]: 26214400\n\t};\n\n\t/**\n\t * The logging component type.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponentType?: string;\n\n\t/**\n\t * The logging component.\n\t * @internal\n\t */\n\tprivate readonly _logging?: ILoggingComponent;\n\n\t/**\n\t * The options for the server.\n\t * @internal\n\t */\n\tprivate _options?: IWebServerOptions;\n\n\t/**\n\t * The Fastify instance.\n\t * @internal\n\t */\n\tprivate readonly _fastify: FastifyInstance;\n\n\t/**\n\t * The options for the socket server.\n\t * @internal\n\t */\n\tprivate readonly _socketConfig: Partial<ServerOptions>;\n\n\t/**\n\t * Whether the server has been started.\n\t * @internal\n\t */\n\tprivate _started: boolean;\n\n\t/**\n\t * The mime type processors.\n\t * @internal\n\t */\n\tprivate readonly _mimeTypeProcessors: IMimeTypeProcessor[];\n\n\t/**\n\t * Include the stack with errors.\n\t * @internal\n\t */\n\tprivate readonly _includeErrorStack: boolean;\n\n\t/**\n\t * The public origin of the server, used for constructing the request URL and for CORS.\n\t * @internal\n\t */\n\tprivate _publicOrigin?: string;\n\n\t/**\n\t * The local origin of the server, used for constructing the request URL and for CORS.\n\t * @internal\n\t */\n\tprivate _localOrigin?: string;\n\n\t/**\n\t * The REST processor chains resolved when the server is built.\n\t * @internal\n\t */\n\tprivate _restChains: IRestProcessorChains;\n\n\t/**\n\t * The socket processor chains resolved when the server is built.\n\t * @internal\n\t */\n\tprivate _socketChains: ISocketProcessorChains;\n\n\t/**\n\t * Create a new instance of FastifyWebServer.\n\t * @param options The options for the server.\n\t */\n\tconstructor(options?: IFastifyWebServerConstructorOptions) {\n\t\tthis._loggingComponentType = options?.loggingComponentType;\n\t\tthis._logging = ComponentFactory.getIfExists(options?.loggingComponentType);\n\t\tthis._fastify = Fastify({\n\t\t\trouterOptions: {\n\t\t\t\tmaxParamLength: 2000\n\t\t\t},\n\t\t\t...options?.config?.web\n\t\t\t// Need this cast for now as maxParamLength has moved in to routerOptions\n\t\t\t// but the TS defs has not been updated yet\n\t\t} as unknown as FastifyServerOptions);\n\t\tthis._socketConfig = {\n\t\t\tpath: \"/socket\",\n\t\t\t...options?.config?.socket\n\t\t};\n\t\tthis._started = false;\n\t\tthis._restChains = { pre: [], process: [], post: [] };\n\t\tthis._socketChains = { connected: [], disconnected: [], pre: [], process: [], post: [] };\n\n\t\tthis._mimeTypeProcessors = options?.mimeTypeProcessors ?? [];\n\n\t\tconst hasJsonLd = this._mimeTypeProcessors.some(processor =>\n\t\t\tprocessor.getTypes().includes(MimeTypes.JsonLd)\n\t\t);\n\t\tif (!hasJsonLd) {\n\t\t\tthis._mimeTypeProcessors.push(new JsonLdMimeTypeProcessor());\n\t\t}\n\n\t\tthis._includeErrorStack = options?.config?.includeErrorStack ?? false;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn FastifyWebServer.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the web server instance.\n\t * @returns The web server instance.\n\t */\n\tpublic getInstance(): FastifyInstance {\n\t\treturn this._fastify;\n\t}\n\n\t/**\n\t * Build the server.\n\t * @param restRouteProcessors The processors for incoming requests over REST.\n\t * @param restRoutes The REST routes.\n\t * @param socketRouteProcessors The processors for incoming requests over Sockets.\n\t * @param socketRoutes The socket routes.\n\t * @param options Options for building the server.\n\t * @returns A promise that resolves when the server is fully built and ready to start.\n\t */\n\tpublic async build(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[],\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[],\n\t\toptions?: IWebServerOptions\n\t): Promise<void> {\n\t\tif (Is.arrayValue(restRoutes) && !Is.arrayValue(restRouteProcessors)) {\n\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"noRestProcessors\");\n\t\t}\n\t\tif (Is.arrayValue(socketRoutes) && !Is.arrayValue(socketRouteProcessors)) {\n\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"noSocketProcessors\");\n\t\t}\n\t\tawait this._logging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tts: Date.now(),\n\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\tmessage: \"building\"\n\t\t});\n\n\t\tlet localHost = options?.host ?? \"127.0.0.1\";\n\t\tif (localHost === \"0.0.0.0\") {\n\t\t\tlocalHost = \"127.0.0.1\";\n\t\t}\n\n\t\tthis._localOrigin = `http://${localHost}:${options?.port ?? 3000}`;\n\n\t\tif (Is.stringValue(options?.publicOrigin)) {\n\t\t\tconst publicUrl = Url.tryParseExact(options.publicOrigin);\n\t\t\tif (!Is.empty(publicUrl)) {\n\t\t\t\tconst urlParts = publicUrl.parts();\n\t\t\t\tthis._publicOrigin = `${urlParts.schema}://${urlParts.host}${Is.integer(urlParts.port) ? `:${urlParts.port}` : \"\"}`;\n\t\t\t} else {\n\t\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"invalidPublicOrigin\", {\n\t\t\t\t\tpublicOrigin: options.publicOrigin\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis._options = options;\n\n\t\tawait this._fastify.register(FastifyCompress);\n\n\t\tif (Is.arrayValue(socketRoutes)) {\n\t\t\tawait this._fastify.register(FastifySocketIO, this._socketConfig);\n\t\t}\n\n\t\tif (Is.arrayValue(this._mimeTypeProcessors)) {\n\t\t\tfor (const contentTypeHandler of this._mimeTypeProcessors) {\n\t\t\t\tthis._fastify.addContentTypeParser(\n\t\t\t\t\tcontentTypeHandler.getTypes(),\n\t\t\t\t\t{ parseAs: \"buffer\" },\n\t\t\t\t\t(request, body, done) => {\n\t\t\t\t\t\t// Fastify does not handle this method correctly if it is async\n\t\t\t\t\t\t// so we have to use the callback method\n\t\t\t\t\t\tcontentTypeHandler\n\t\t\t\t\t\t\t.handle(body as Buffer)\n\t\t\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/no-callback-in-promise\n\t\t\t\t\t\t\t.then(processed => done(null, processed))\n\t\t\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/no-callback-in-promise\n\t\t\t\t\t\t\t.catch(err => done(BaseError.fromError(err)));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait this.initCors(options);\n\n\t\tthis._fastify.setNotFoundHandler({}, async (request, reply) =>\n\t\t\tthis.handleRequestRest(restRouteProcessors ?? [], request, reply)\n\t\t);\n\n\t\tthis._fastify.setErrorHandler(\n\t\t\tasync (\n\t\t\t\terror: Error & {\n\t\t\t\t\tcode?: number | string;\n\t\t\t\t\tstatusCode?: number | string;\n\t\t\t\t},\n\t\t\t\trequest,\n\t\t\t\treply\n\t\t\t) => {\n\t\t\t\t// If code property is set this is a fastify error\n\t\t\t\t// otherwise it's from our framework\n\t\t\t\tlet httpStatusCode: HttpStatusCode;\n\t\t\t\tlet err: IError;\n\t\t\t\tif (Is.number(error.code) || Is.string(error.code)) {\n\t\t\t\t\terr = {\n\t\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: `${error.code}: ${error.message}`\n\t\t\t\t\t};\n\t\t\t\t\thttpStatusCode = (error.statusCode as HttpStatusCode) ?? HttpStatusCode.badRequest;\n\t\t\t\t} else {\n\t\t\t\t\tconst errorAndCode = HttpErrorHelper.processError(error);\n\t\t\t\t\terr = errorAndCode.error;\n\t\t\t\t\thttpStatusCode = errorAndCode.httpStatusCode;\n\t\t\t\t}\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"badRequest\",\n\t\t\t\t\terror: err\n\t\t\t\t});\n\n\t\t\t\treturn reply.status(httpStatusCode).send({\n\t\t\t\t\terror: err\n\t\t\t\t});\n\t\t\t}\n\t\t);\n\n\t\tawait this.addRoutesRest(restRouteProcessors, restRoutes);\n\t\tawait this.addRoutesSocket(socketRouteProcessors, socketRoutes);\n\n\t\tthis.buildProcessorChains(restRouteProcessors, socketRouteProcessors);\n\t}\n\n\t/**\n\t * Start the server.\n\t * @returns A promise that resolves when the server is listening for connections.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tconst host = this._options?.host ?? FastifyWebServer._DEFAULT_HOST;\n\t\tconst port = this._options?.port ?? FastifyWebServer._DEFAULT_PORT;\n\n\t\tawait this._logging?.log({\n\t\t\tlevel: \"info\",\n\t\t\tts: Date.now(),\n\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\tmessage: \"starting\",\n\t\t\tdata: {\n\t\t\t\thost,\n\t\t\t\tport\n\t\t\t}\n\t\t});\n\n\t\tif (!this._started) {\n\t\t\ttry {\n\t\t\t\tawait this._fastify.listen({ port, host });\n\t\t\t\tconst addresses = this._fastify.addresses();\n\n\t\t\t\tconst protocol = Is.object(this._fastify.initialConfig.https) ? \"https://\" : \"http://\";\n\t\t\t\tconst normalizeAnyHost = (address: string): string => {\n\t\t\t\t\tif (address === \"0.0.0.0\") {\n\t\t\t\t\t\treturn \"127.0.0.1\";\n\t\t\t\t\t}\n\t\t\t\t\tif (address === \"::\") {\n\t\t\t\t\t\treturn \"::1\";\n\t\t\t\t\t}\n\n\t\t\t\t\treturn address;\n\t\t\t\t};\n\n\t\t\t\tconst formatAddress = (\n\t\t\t\t\taddress: string,\n\t\t\t\t\tfamily?: string,\n\t\t\t\t\tforceProtocol?: string\n\t\t\t\t): string => {\n\t\t\t\t\tconst displayAddress = normalizeAnyHost(address);\n\t\t\t\t\tconst isIPv6 =\n\t\t\t\t\t\tfamily === \"IPv6\" || (Is.stringValue(displayAddress) && displayAddress.includes(\":\"));\n\n\t\t\t\t\treturn `${forceProtocol ?? protocol}${isIPv6 ? \"[\" : \"\"}${displayAddress}${isIPv6 ? \"]\" : \"\"}`;\n\t\t\t\t};\n\n\t\t\t\tconst startupAddresses = addresses.map(a => {\n\t\t\t\t\tconst formatted = formatAddress(a.address, a.family, protocol);\n\n\t\t\t\t\treturn `${formatted}:${a.port}`;\n\t\t\t\t});\n\n\t\t\t\tfor (const origin of [this._localOrigin, this._publicOrigin]) {\n\t\t\t\t\tif (Is.stringValue(origin)) {\n\t\t\t\t\t\tconst originUrl = Url.tryParseExact(origin);\n\t\t\t\t\t\tif (!Is.empty(originUrl)) {\n\t\t\t\t\t\t\tconst originParts = originUrl.parts();\n\t\t\t\t\t\t\tconst formatted = formatAddress(\n\t\t\t\t\t\t\t\toriginParts.host,\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t`${originParts.schema}://`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tstartupAddresses.push(\n\t\t\t\t\t\t\t\t`${formatted}${Is.integer(originParts.port) ? `:${originParts.port}` : \"\"}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstartupAddresses.push(origin);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst distinctStartupAddresses = [...new Set(startupAddresses)];\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"started\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\taddresses: distinctStartupAddresses.join(\", \")\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._started = true;\n\t\t\t} catch (err) {\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"startFailed\",\n\t\t\t\t\terror: BaseError.fromError(err)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stop the server.\n\t * @returns A promise that resolves when the server has shut down all connections.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tif (this._started) {\n\t\t\tthis._started = false;\n\n\t\t\tawait this._fastify.close();\n\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tts: Date.now(),\n\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\tmessage: \"stopped\"\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Returns the health status of the component.\n\t * @returns The health status of the component, can return multiple entries for elements within the component.\n\t */\n\tpublic async health(): Promise<IHealth[]> {\n\t\tlet healthCheck: IHealth | undefined;\n\t\tif (this._fastify?.server?.listening) {\n\t\t\thealthCheck = {\n\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\tdescription: \"healthConnectivityDescription\",\n\t\t\t\tmessage: \"reachable\"\n\t\t\t};\n\t\t} else {\n\t\t\thealthCheck = {\n\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\tcategory: HealthCategory.Connectivity,\n\t\t\t\tdescription: \"healthConnectivityDescription\",\n\t\t\t\tmessage: \"unreachable\"\n\t\t\t};\n\t\t}\n\n\t\treturn [healthCheck];\n\t}\n\n\t/**\n\t * Verify the root endpoint is reachable and returns a body by making a real HTTP request.\n\t * Skipped when GET / is not registered on this server instance.\n\t * @param callback The callback to invoke when a deferred health result is ready.\n\t * @returns The application health status of the component.\n\t */\n\tpublic async healthApplication(\n\t\tcallback: HealthApplicationCallback\n\t): Promise<IHealth[] | undefined> {\n\t\tif (!this._fastify.hasRoute({ method: \"GET\", url: \"/\" })) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (!Is.stringValue(this._localOrigin)) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tcategory: HealthCategory.Application,\n\t\t\t\t\tdescription: \"healthApplicationDescription\",\n\t\t\t\t\tmessage: \"serverNotBuilt\"\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch(`${this._localOrigin}/`);\n\t\t\tconst body = await response.text();\n\n\t\t\tif (response.ok && Is.stringValue(body)) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\t\tstatus: HealthStatus.Ok,\n\t\t\t\t\t\tcategory: HealthCategory.Application,\n\t\t\t\t\t\tdescription: \"healthApplicationDescription\",\n\t\t\t\t\t\tmessage: \"rootEndpointReachable\"\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tcategory: HealthCategory.Application,\n\t\t\t\t\tdescription: \"healthApplicationDescription\",\n\t\t\t\t\tmessage: \"rootEndpointError\"\n\t\t\t\t}\n\t\t\t];\n\t\t} catch (error) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tstatus: HealthStatus.Error,\n\t\t\t\t\tcategory: HealthCategory.Application,\n\t\t\t\t\tdescription: \"healthApplicationDescription\",\n\t\t\t\t\terror: BaseError.fromError(error)\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * Add the REST routes to the server.\n\t * @param restRouteProcessors The processors for the incoming requests.\n\t * @param restRoutes The REST routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesRest(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[]\n\t): Promise<void> {\n\t\tif (Is.arrayValue(restRouteProcessors) && Is.arrayValue(restRoutes)) {\n\t\t\tconst bodyLimits = this.resolveBodyLimits();\n\t\t\tfor (const restRoute of restRoutes) {\n\t\t\t\tlet path = StringHelper.trimTrailingSlashes(restRoute.path);\n\t\t\t\tif (!path.startsWith(\"/\")) {\n\t\t\t\t\tpath = `/${path}`;\n\t\t\t\t}\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"restRouteAdded\",\n\t\t\t\t\tdata: { route: path, method: restRoute.method }\n\t\t\t\t});\n\t\t\t\tconst method = restRoute.method.toLowerCase() as\n\t\t\t\t\t\"get\" | \"post\" | \"put\" | \"patch\" | \"delete\" | \"options\" | \"head\";\n\n\t\t\t\tconst bodyLimitKey = Is.stringValue(restRoute.bodyLimit)\n\t\t\t\t\t? restRoute.bodyLimit\n\t\t\t\t\t: HttpBodyLimit.Default;\n\t\t\t\tconst bodyLimit = bodyLimits[bodyLimitKey];\n\t\t\t\tif (Is.empty(bodyLimit)) {\n\t\t\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"unknownBodyLimit\", {\n\t\t\t\t\t\troute: path,\n\t\t\t\t\t\tbodyLimit: bodyLimitKey\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis._fastify[method](path, { bodyLimit }, async (request, reply) =>\n\t\t\t\t\tthis.handleRequestRest(restRouteProcessors, request, reply, restRoute)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Merge the configured body limits over the built-in ones and validate them.\n\t * @returns The named body limits in bytes.\n\t * @throws GeneralError If a limit is not a positive integer.\n\t * @internal\n\t */\n\tprivate resolveBodyLimits(): { [name: string]: number } {\n\t\tconst bodyLimits = {\n\t\t\t...FastifyWebServer._DEFAULT_BODY_LIMITS,\n\t\t\t...this._options?.bodyLimits\n\t\t};\n\t\tfor (const name of Object.keys(bodyLimits)) {\n\t\t\tconst bodyLimit = bodyLimits[name];\n\t\t\tif (!Is.integer(bodyLimit) || bodyLimit <= 0) {\n\t\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"invalidBodyLimit\", {\n\t\t\t\t\tbodyLimit: name,\n\t\t\t\t\tvalue: bodyLimit\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn bodyLimits;\n\t}\n\n\t/**\n\t * Add the socket routes to the server.\n\t * @param socketRouteProcessors The processors for the incoming requests.\n\t * @param socketRoutes The socket routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesSocket(\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[]\n\t): Promise<void> {\n\t\tif (Is.arrayValue(socketRouteProcessors) && Is.arrayValue(socketRoutes)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst io: Server = (this._fastify as any).io;\n\n\t\t\tfor (const socketRoute of socketRoutes) {\n\t\t\t\tconst path = StringHelper.trimLeadingSlashes(\n\t\t\t\t\tStringHelper.trimTrailingSlashes(socketRoute.path)\n\t\t\t\t);\n\t\t\t\tconst pathParts = path.split(\"/\");\n\n\t\t\t\tconst namespace = `/${pathParts[0]}`;\n\t\t\t\tconst topic = pathParts.slice(1).join(\"/\");\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"socketRouteAdded\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\thandshakePath: this._socketConfig.path,\n\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\teventName: topic\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst socketNamespace = io.of(namespace);\n\n\t\t\t\tsocketNamespace.on(\"connection\", async socket => {\n\t\t\t\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\t\t\t\tmethod: HttpMethod.GET,\n\t\t\t\t\t\turl: socket.handshake.url,\n\t\t\t\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\t\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t\t\t\tsocketId: socket.id\n\t\t\t\t\t};\n\n\t\t\t\t\t// Pass the connected information on to any processors\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const socketRouteProcessor of socketRouteProcessors) {\n\t\t\t\t\t\t\tif (socketRouteProcessor.connected) {\n\t\t\t\t\t\t\t\tawait socketRouteProcessor.connected(\n\t\t\t\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\t\t\tthis._loggingComponentType\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\tHttpErrorHelper.buildResponse(response, error, httpStatusCode, this._includeErrorStack);\n\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t}\n\n\t\t\t\t\tsocket.on(\"disconnect\", async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// The socket disconnected so notify any processors\n\t\t\t\t\t\t\tfor (const socketRouteProcessor of socketRouteProcessors) {\n\t\t\t\t\t\t\t\tif (socketRouteProcessor.disconnected) {\n\t\t\t\t\t\t\t\t\tawait socketRouteProcessor.disconnected(\n\t\t\t\t\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\t\t\t\tthis._loggingComponentType\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// If something fails on a disconnect there is not much we can do with it\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// Handle any incoming messages\n\t\t\t\t\tsocket.on(topic, async data => {\n\t\t\t\t\t\t// The listener is async, so anything escaping it would surface as an unhandled\n\t\t\t\t\t\t// rejection and terminate the process, emit it on the topic instead\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.handleRequestSocket(\n\t\t\t\t\t\t\t\tsocketRouteProcessors,\n\t\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\t\tsocket,\n\t\t\t\t\t\t\t\t`/${pathParts.join(\"/\")}`,\n\t\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\t\tdata\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\t\tHttpErrorHelper.buildResponse(\n\t\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\thttpStatusCode,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle the incoming REST request.\n\t * @param restRouteProcessors The hooks to process the incoming requests.\n\t * @param request The incoming request.\n\t * @param reply The outgoing response.\n\t * @param restRoute The REST route to handle.\n\t * @returns The Fastify reply with the response.\n\t * @internal\n\t */\n\tprivate async handleRequestRest(\n\t\trestRouteProcessors: IRestRouteProcessor[],\n\t\trequest: FastifyRequest,\n\t\treply: FastifyReply,\n\t\trestRoute?: IRestRoute\n\t): Promise<FastifyReply> {\n\t\tconst port =\n\t\t\t(request.port === 80 && request.protocol === \"http\") ||\n\t\t\t(request.port === 443 && request.protocol === \"https\") ||\n\t\t\t!Is.integer(request.port)\n\t\t\t\t? \"\"\n\t\t\t\t: `:${request.port}`;\n\n\t\tconst requestOrigin = `${request.protocol}://${request.hostname}${port}`;\n\n\t\tconst httpServerRequest: IHttpServerRequest = {\n\t\t\tmethod: request.method.toUpperCase() as HttpMethod,\n\t\t\turl: `${requestOrigin}${request.url}`,\n\t\t\tbody: request.body,\n\t\t\tquery: request.query as IHttpRequestQuery,\n\t\t\tpathParams: request.params as IHttpRequestPathParams,\n\t\t\theaders: request.headers as IHttpHeaders\n\t\t};\n\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds: IContextIds = {\n\t\t\t[HttpContextIdKeys.IpAddress]: HeaderHelper.extractClientIps(httpServerRequest.headers).join(\n\t\t\t\t\"|\"\n\t\t\t),\n\t\t\t[HttpContextIdKeys.UserAgent]: HeaderHelper.extractUserAgent(httpServerRequest.headers),\n\t\t\t[HttpContextIdKeys.CorrelationId]: HeaderHelper.extractCorrelationId(\n\t\t\t\thttpServerRequest.headers\n\t\t\t),\n\t\t\t[HttpContextIdKeys.RemoteRequest]: RandomHelper.generateUuidV7(\"compact\"),\n\t\t\t[HttpContextIdKeys.LocalOrigin]: this._localOrigin,\n\t\t\t// This can be overridden by a processor if needed, for example a tenant processor\n\t\t\t[HttpContextIdKeys.PublicOrigin]: this._publicOrigin ?? requestOrigin ?? this._localOrigin\n\t\t};\n\t\tconst processorState = {};\n\n\t\tif (Is.object(httpServerRequest.pathParams)) {\n\t\t\tfor (const key of Object.keys(httpServerRequest.pathParams)) {\n\t\t\t\thttpServerRequest.pathParams[key] = decodeURIComponent(httpServerRequest.pathParams[key]);\n\t\t\t}\n\t\t}\n\t\tif (Is.object(httpServerRequest.query)) {\n\t\t\tfor (const key of Object.keys(httpServerRequest.query)) {\n\t\t\t\thttpServerRequest.query[key] = decodeURIComponent(httpServerRequest.query[key]);\n\t\t\t}\n\t\t}\n\n\t\tawait this.runProcessorsRest(\n\t\t\trestRouteProcessors,\n\t\t\trestRoute,\n\t\t\thttpServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState\n\t\t);\n\n\t\tif (!Is.empty(httpResponse.headers)) {\n\t\t\tfor (const header of Object.keys(httpResponse.headers)) {\n\t\t\t\treply.header(header, httpResponse.headers[header]);\n\t\t\t}\n\t\t}\n\t\treturn reply.status(httpResponse.statusCode ?? HttpStatusCode.ok).send(httpResponse.body);\n\t}\n\n\t/**\n\t * Run the REST processors for the route.\n\t * @param restRouteProcessors The processors to run.\n\t * @param restRoute The route to process.\n\t * @param httpServerRequest The incoming request.\n\t * @param httpResponse The outgoing response.\n\t * @param contextIds The context IDs of the request.\n\t * @internal\n\t */\n\tprivate async runProcessorsRest(\n\t\trestRouteProcessors: IRestRouteProcessor[],\n\t\trestRoute: IRestRoute | undefined,\n\t\thttpServerRequest: IHttpServerRequest,\n\t\thttpResponse: IHttpResponse,\n\t\tcontextIds: IContextIds,\n\t\tprocessorState: {\n\t\t\t[id: string]: unknown;\n\t\t}\n\t): Promise<void> {\n\t\tlet hasPreError = false;\n\n\t\ttry {\n\t\t\t// Run inside ContextIdStore.run so pre-processors can do tenant-scoped storage lookups.\n\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\tfor (const pre of this._restChains.pre) {\n\t\t\t\t\tawait pre(httpServerRequest, httpResponse, restRoute, contextIds, processorState, {\n\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(err, this._includeErrorStack);\n\t\t\tHttpErrorHelper.buildResponse(httpResponse, error, httpStatusCode, this._includeErrorStack);\n\t\t\thasPreError = true;\n\t\t}\n\n\t\t// A pre-processor may set an error response without throwing; treat that as halt.\n\t\tif (\n\t\t\t!hasPreError &&\n\t\t\tIs.integer(httpResponse.statusCode) &&\n\t\t\thttpResponse.statusCode >= HttpStatusCode.badRequest\n\t\t) {\n\t\t\thasPreError = true;\n\t\t}\n\n\t\t// Don't run the main processing if there was an error in the pre processing\n\t\t// As this is likely to perform tasks such as authentication which may have failed\n\t\tif (!hasPreError) {\n\t\t\ttry {\n\t\t\t\t// Run the processors within an async context\n\t\t\t\t// so that any services can access the context ids\n\t\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\t\tfor (const process of this._restChains.process) {\n\t\t\t\t\t\tawait process(httpServerRequest, httpResponse, restRoute, processorState, {\n\t\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\terr,\n\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t);\n\t\t\t\tHttpErrorHelper.buildResponse(httpResponse, error, httpStatusCode, this._includeErrorStack);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\t// Always run the post processors, even if there was an error earlier\n\t\t\t// as they may perform cleanup tasks, or logging etc\n\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\tfor (const post of this._restChains.post) {\n\t\t\t\t\tawait post(httpServerRequest, httpResponse, restRoute, contextIds, processorState, {\n\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// Just log post processor errors\n\t\t\tawait this._logging?.log({\n\t\t\t\tlevel: \"error\",\n\t\t\t\tts: Date.now(),\n\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\tmessage: \"postProcessorError\",\n\t\t\t\terror: BaseError.fromError(err),\n\t\t\t\tdata: {\n\t\t\t\t\troute: restRoute?.path ?? \"\"\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Handle the incoming socket request.\n\t * @param socketRouteProcessors The hooks to process the incoming requests.\n\t * @param socketRoute The socket route to handle.\n\t * @param socket The socket to handle.\n\t * @param fullPath The full path of the socket route.\n\t * @param emitTopic The topic to emit the response on.\n\t * @param request The incoming request.\n\t * @internal\n\t */\n\tprivate async handleRequestSocket(\n\t\tsocketRouteProcessors: ISocketRouteProcessor[],\n\t\tsocketRoute: ISocketRoute,\n\t\tsocket: Socket,\n\t\tfullPath: string,\n\t\temitTopic: string,\n\t\trequest: IHttpRequest | undefined\n\t): Promise<void> {\n\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: fullPath,\n\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t// The payload arrives straight off the wire, so it can be missing or any shape\n\t\t\tbody: Is.object(request) ? request.body : undefined,\n\t\t\tsocketId: socket.id\n\t\t};\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds: IContextIds = {};\n\t\tconst processorState = {};\n\n\t\tdelete socketServerRequest.query?.EIO;\n\t\tdelete socketServerRequest.query?.transport;\n\n\t\tawait this.runProcessorsSocket(\n\t\t\tsocketRouteProcessors,\n\t\t\tsocketRoute,\n\t\t\tsocketServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState,\n\t\t\temitTopic,\n\t\t\tasync (topic, response) => {\n\t\t\t\tsocket.emit(topic, response);\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Run the socket processors for the route.\n\t * @param socketRouteProcessors The processors to run.\n\t * @param socketRoute The route to process.\n\t * @param socketServerRequest The incoming request.\n\t * @param httpResponse The outgoing response.\n\t * @param contextIds The context IDs of the request.\n\t * @param processorState The state handed through the processors.\n\t * @param requestTopic The topic of the request.\n\t * @param responseEmitter The emitter to send the response on.\n\t * @internal\n\t */\n\tprivate async runProcessorsSocket(\n\t\tsocketRouteProcessors: ISocketRouteProcessor[],\n\t\tsocketRoute: ISocketRoute,\n\t\tsocketServerRequest: ISocketServerRequest,\n\t\thttpResponse: IHttpResponse,\n\t\tcontextIds: IContextIds,\n\t\tprocessorState: {\n\t\t\t[id: string]: unknown;\n\t\t},\n\t\trequestTopic: string,\n\t\tresponseEmitter: (topic: string, response: IHttpResponse) => Promise<void>\n\t): Promise<void> {\n\t\t// Custom emit method which will also call the post processors\n\t\tconst postProcessEmit = async (\n\t\t\ttopic: string,\n\t\t\tresponse: IHttpResponse,\n\t\t\tresponseProcessorState: {\n\t\t\t\t[id: string]: unknown;\n\t\t\t}\n\t\t): Promise<void> => {\n\t\t\tawait responseEmitter(topic, response);\n\n\t\t\ttry {\n\t\t\t\t// The post processors are called after the response has been emitted\n\t\t\t\tfor (const post of this._socketChains.post) {\n\t\t\t\t\tawait post(\n\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\tresponse,\n\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\tcontextIds,\n\t\t\t\t\t\tresponseProcessorState,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"postProcessorError\",\n\t\t\t\t\terror: BaseError.fromError(err),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\troute: socketRoute.path\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tfor (const pre of this._socketChains.pre) {\n\t\t\t\tawait pre(socketServerRequest, httpResponse, socketRoute, contextIds, processorState, {\n\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// We always call all the processors regardless of any response set by a previous processor.\n\t\t\t// But if a pre processor sets a status code, we will emit the response manually, as the pre\n\t\t\t// and post processors do not receive the emit method, they just populate the response object.\n\t\t\tif (!Is.empty(httpResponse.statusCode)) {\n\t\t\t\tawait postProcessEmit(requestTopic, httpResponse, processorState);\n\t\t\t}\n\n\t\t\tawait ContextIdStore.run(contextIds, async () => {\n\t\t\t\tfor (const process of this._socketChains.process) {\n\t\t\t\t\tawait process(\n\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\thttpResponse,\n\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\tprocessorState,\n\t\t\t\t\t\tasync (topic: string, processResponse: IHttpResponse) => {\n\t\t\t\t\t\t\tawait postProcessEmit(topic, processResponse, processorState);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthis._loggingComponentType\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// If the processors set the status to any kind of error then we should emit this manually\n\t\t\tif (\n\t\t\t\tIs.integer(httpResponse.statusCode) &&\n\t\t\t\thttpResponse.statusCode >= HttpStatusCode.badRequest\n\t\t\t) {\n\t\t\t\tawait postProcessEmit(requestTopic, httpResponse, processorState);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Emit any unhandled errors manually\n\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(err, this._includeErrorStack);\n\t\t\tHttpErrorHelper.buildResponse(httpResponse, error, httpStatusCode, this._includeErrorStack);\n\t\t\tawait postProcessEmit(requestTopic, httpResponse, processorState);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize the cors options.\n\t * @param options The web server options.\n\t * @internal\n\t */\n\tprivate async initCors(options?: IWebServerOptions): Promise<void> {\n\t\tlet origins: string[] = [\"*\"];\n\n\t\tif (Is.arrayValue(options?.corsOrigins)) {\n\t\t\torigins = options?.corsOrigins;\n\t\t} else if (Is.stringValue(options?.corsOrigins)) {\n\t\t\torigins = [options?.corsOrigins];\n\t\t}\n\n\t\tconst hasWildcardOrigin = origins.includes(\"*\");\n\n\t\tconst methods = options?.methods ?? [\n\t\t\tHttpMethod.GET,\n\t\t\tHttpMethod.PUT,\n\t\t\tHttpMethod.POST,\n\t\t\tHttpMethod.PATCH,\n\t\t\tHttpMethod.DELETE,\n\t\t\tHttpMethod.OPTIONS\n\t\t];\n\t\tconst allowedHeaders = [\n\t\t\t\"Access-Control-Allow-Origin\",\n\t\t\t\"Content-Encoding\",\n\t\t\t\"Accept-Encoding\",\n\t\t\tHeaderTypes.ContentType,\n\t\t\tHeaderTypes.Authorization,\n\t\t\tHeaderTypes.Accept\n\t\t];\n\t\tconst exposedHeaders: string[] = [HeaderTypes.ContentDisposition, HeaderTypes.Location];\n\n\t\tif (Is.arrayValue(options?.allowedHeaders)) {\n\t\t\tallowedHeaders.push(...options.allowedHeaders);\n\t\t}\n\t\tif (Is.arrayValue(options?.exposedHeaders)) {\n\t\t\texposedHeaders.push(...options.exposedHeaders);\n\t\t}\n\n\t\tawait this._fastify.register(FastifyCors, {\n\t\t\torigin: (origin, callback) => {\n\t\t\t\tcallback(null, hasWildcardOrigin ? true : origins.includes(origin as string));\n\t\t\t},\n\t\t\tmethods,\n\t\t\tallowedHeaders,\n\t\t\texposedHeaders,\n\t\t\tcredentials: true\n\t\t});\n\t}\n\n\t/**\n\t * Resolve the route processors in to per phase chains, so that the lookups and bindings\n\t * are performed once when the server is built instead of on every request.\n\t * @param restRouteProcessors The processors for the incoming REST requests.\n\t * @param socketRouteProcessors The processors for the incoming socket requests.\n\t * @internal\n\t */\n\tprivate buildProcessorChains(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[]\n\t): void {\n\t\tconst restChains: IRestProcessorChains = { pre: [], process: [], post: [] };\n\n\t\tfor (const routeProcessor of restRouteProcessors ?? []) {\n\t\t\tconst pre = routeProcessor.pre?.bind(routeProcessor);\n\t\t\tif (Is.function(pre)) {\n\t\t\t\trestChains.pre.push(pre);\n\t\t\t}\n\t\t\tconst process = routeProcessor.process?.bind(routeProcessor);\n\t\t\tif (Is.function(process)) {\n\t\t\t\trestChains.process.push(process);\n\t\t\t}\n\t\t\tconst post = routeProcessor.post?.bind(routeProcessor);\n\t\t\tif (Is.function(post)) {\n\t\t\t\trestChains.post.push(post);\n\t\t\t}\n\t\t}\n\n\t\tconst socketChains: ISocketProcessorChains = {\n\t\t\tconnected: [],\n\t\t\tdisconnected: [],\n\t\t\tpre: [],\n\t\t\tprocess: [],\n\t\t\tpost: []\n\t\t};\n\n\t\tfor (const routeProcessor of socketRouteProcessors ?? []) {\n\t\t\tconst connected = routeProcessor.connected?.bind(routeProcessor);\n\t\t\tif (Is.function(connected)) {\n\t\t\t\tsocketChains.connected.push(connected);\n\t\t\t}\n\t\t\tconst disconnected = routeProcessor.disconnected?.bind(routeProcessor);\n\t\t\tif (Is.function(disconnected)) {\n\t\t\t\tsocketChains.disconnected.push(disconnected);\n\t\t\t}\n\t\t\tconst pre = routeProcessor.pre?.bind(routeProcessor);\n\t\t\tif (Is.function(pre)) {\n\t\t\t\tsocketChains.pre.push(pre);\n\t\t\t}\n\t\t\tconst process = routeProcessor.process?.bind(routeProcessor);\n\t\t\tif (Is.function(process)) {\n\t\t\t\tsocketChains.process.push(process);\n\t\t\t}\n\t\t\tconst post = routeProcessor.post?.bind(routeProcessor);\n\t\t\tif (Is.function(post)) {\n\t\t\t\tsocketChains.post.push(post);\n\t\t\t}\n\t\t}\n\n\t\tthis._restChains = restChains;\n\t\tthis._socketChains = socketChains;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fastifyWebServer.js","sources":["../../src/fastifyWebServer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// Copyright 2026 3Sixty Trade Ltd.\n// SPDX-License-Identifier: Apache-2.0.\nimport { BaseServer } from \"@3sixty/api-core-server\";\nimport {\n\tHttpBodyLimit,\n\tHttpErrorHelper,\n\ttype IHttpRequest,\n\ttype IHttpRequestPathParams,\n\ttype IHttpRequestQuery,\n\ttype IHttpResponse,\n\ttype IRestRoute,\n\ttype IRestRouteProcessor,\n\ttype ISocketRoute,\n\ttype ISocketRouteProcessor,\n\ttype ISocketServerRequest,\n\ttype IWebServerOptions\n} from \"@3sixty/api-models\";\nimport type { IContextIds } from \"@3sixty/context\";\nimport { BaseError, GeneralError, type IError, Is, StringHelper } from \"@3sixty/core\";\n\nimport { HttpMethod, HttpStatusCode, type IHttpHeaders } from \"@3sixty/web\";\nimport FastifyCompress from \"@fastify/compress\";\nimport FastifyCors from \"@fastify/cors\";\nimport Fastify, {\n\ttype FastifyInstance,\n\ttype FastifyReply,\n\ttype FastifyRequest,\n\ttype FastifyServerOptions\n} from \"fastify\";\nimport type { Server, ServerOptions, Socket } from \"socket.io\";\nimport FastifySocketIO from \"./fastifySocketIo.js\";\nimport type { IFastifyWebServerConstructorOptions } from \"./models/IFastifyWebServerConstructorOptions.js\";\n\n/**\n * Implementation of the web server using Fastify.\n */\nexport class FastifyWebServer extends BaseServer<FastifyInstance> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = \"FastifyWebServer\";\n\n\t/**\n\t * The Fastify instance.\n\t * @internal\n\t */\n\tprivate readonly _fastify: FastifyInstance;\n\n\t/**\n\t * The options for the socket server.\n\t * @internal\n\t */\n\tprivate readonly _socketConfig: Partial<ServerOptions>;\n\n\t/**\n\t * Create a new instance of FastifyWebServer.\n\t * @param options The options for the server.\n\t */\n\tconstructor(options?: IFastifyWebServerConstructorOptions) {\n\t\tsuper({\n\t\t\tloggingComponentType: options?.loggingComponentType,\n\t\t\tmimeTypeProcessors: options?.mimeTypeProcessors,\n\t\t\tincludeErrorStack: options?.config?.includeErrorStack\n\t\t});\n\n\t\tthis._fastify = Fastify({\n\t\t\trouterOptions: {\n\t\t\t\tmaxParamLength: 2000\n\t\t\t},\n\t\t\t...options?.config?.web\n\t\t\t// Need this cast for now as maxParamLength has moved in to routerOptions\n\t\t\t// but the TS defs has not been updated yet\n\t\t} as unknown as FastifyServerOptions);\n\t\tthis._socketConfig = {\n\t\t\tpath: \"/socket\",\n\t\t\t...options?.config?.socket\n\t\t};\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn FastifyWebServer.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the web server instance.\n\t * @returns The web server instance.\n\t */\n\tpublic getInstance(): FastifyInstance {\n\t\treturn this._fastify;\n\t}\n\n\t/**\n\t * Build the server.\n\t * @param restRouteProcessors The processors for incoming requests over REST.\n\t * @param restRoutes The REST routes.\n\t * @param socketRouteProcessors The processors for incoming requests over Sockets.\n\t * @param socketRoutes The socket routes.\n\t * @param options Options for building the server.\n\t * @returns A promise that resolves when the server is fully built and ready to start.\n\t */\n\tpublic async build(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[],\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[],\n\t\toptions?: IWebServerOptions\n\t): Promise<void> {\n\t\tawait this.prepareBuild(\n\t\t\trestRouteProcessors,\n\t\t\trestRoutes,\n\t\t\tsocketRouteProcessors,\n\t\t\tsocketRoutes,\n\t\t\toptions\n\t\t);\n\n\t\tawait this._fastify.register(FastifyCompress);\n\n\t\tif (Is.arrayValue(socketRoutes)) {\n\t\t\tawait this._fastify.register(FastifySocketIO, this._socketConfig);\n\t\t}\n\n\t\tif (Is.arrayValue(this._mimeTypeProcessors)) {\n\t\t\tfor (const contentTypeHandler of this._mimeTypeProcessors) {\n\t\t\t\tthis._fastify.addContentTypeParser(\n\t\t\t\t\tcontentTypeHandler.getTypes(),\n\t\t\t\t\t{ parseAs: \"buffer\" },\n\t\t\t\t\t(request, body, done) => {\n\t\t\t\t\t\t// Fastify does not handle this method correctly if it is async\n\t\t\t\t\t\t// so we have to use the callback method\n\t\t\t\t\t\tcontentTypeHandler\n\t\t\t\t\t\t\t.handle(body as Buffer)\n\t\t\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/no-callback-in-promise\n\t\t\t\t\t\t\t.then(processed => done(null, processed))\n\t\t\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-then, promise/no-callback-in-promise\n\t\t\t\t\t\t\t.catch(err => done(BaseError.fromError(err)));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait this.initCors(options);\n\n\t\tthis._fastify.setNotFoundHandler({}, async (request, reply) =>\n\t\t\tthis.handleRequestRest(request, reply)\n\t\t);\n\n\t\tthis._fastify.setErrorHandler(\n\t\t\tasync (\n\t\t\t\terror: Error & {\n\t\t\t\t\tcode?: number | string;\n\t\t\t\t\tstatusCode?: number | string;\n\t\t\t\t},\n\t\t\t\trequest,\n\t\t\t\treply\n\t\t\t) => {\n\t\t\t\t// If code property is set this is a fastify error\n\t\t\t\t// otherwise it's from our framework\n\t\t\t\tlet httpStatusCode: HttpStatusCode;\n\t\t\t\tlet err: IError;\n\t\t\t\tif (Is.number(error.code) || Is.string(error.code)) {\n\t\t\t\t\terr = {\n\t\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\t\tname: error.name,\n\t\t\t\t\t\tmessage: `${error.code}: ${error.message}`\n\t\t\t\t\t};\n\t\t\t\t\thttpStatusCode = (error.statusCode as HttpStatusCode) ?? HttpStatusCode.badRequest;\n\t\t\t\t} else {\n\t\t\t\t\tconst errorAndCode = HttpErrorHelper.processError(error);\n\t\t\t\t\terr = errorAndCode.error;\n\t\t\t\t\thttpStatusCode = errorAndCode.httpStatusCode;\n\t\t\t\t}\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"badRequest\",\n\t\t\t\t\terror: err\n\t\t\t\t});\n\n\t\t\t\treturn reply.status(httpStatusCode).send({\n\t\t\t\t\terror: err\n\t\t\t\t});\n\t\t\t}\n\t\t);\n\n\t\tawait this.addRoutesRest(restRouteProcessors, restRoutes);\n\t\tawait this.addRoutesSocket(socketRouteProcessors, socketRoutes);\n\t}\n\n\t/**\n\t * Start listening for connections on the transport.\n\t * @param host The host to bind to.\n\t * @param port The port to bind to.\n\t * @returns A promise that resolves when the transport is listening.\n\t */\n\tprotected async serverListen(host: string, port: number): Promise<void> {\n\t\tawait this._fastify.listen({ port, host });\n\t}\n\n\t/**\n\t * Close the transport and all of its connections.\n\t * @returns A promise that resolves when the transport has closed.\n\t */\n\tprotected async serverClose(): Promise<void> {\n\t\tawait this._fastify.close();\n\t}\n\n\t/**\n\t * Get the addresses the transport is bound to.\n\t * @returns The bound addresses.\n\t */\n\tprotected serverAddresses(): { address: string; family?: string; port: number }[] {\n\t\treturn this._fastify.addresses();\n\t}\n\n\t/**\n\t * Whether the transport is serving over TLS.\n\t * @returns True if the transport is secure.\n\t */\n\tprotected serverIsSecure(): boolean {\n\t\t// Fastify reports the https option as true rather than the options object\n\t\tconst https: unknown = this._fastify.initialConfig.https;\n\t\treturn https === true || Is.object(https);\n\t}\n\n\t/**\n\t * Whether the transport is currently listening for connections.\n\t * @returns True if the transport is listening.\n\t */\n\tprotected serverIsListening(): boolean {\n\t\treturn this._fastify?.server?.listening ?? false;\n\t}\n\n\t/**\n\t * Whether a GET route is registered for the root path.\n\t * @returns True if the root route is registered.\n\t */\n\tprotected serverHasRootRoute(): boolean {\n\t\treturn this._fastify.hasRoute({ method: \"GET\", url: \"/\" });\n\t}\n\n\t/**\n\t * Add the REST routes to the server.\n\t * @param restRouteProcessors The processors for the incoming requests.\n\t * @param restRoutes The REST routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesRest(\n\t\trestRouteProcessors?: IRestRouteProcessor[],\n\t\trestRoutes?: IRestRoute[]\n\t): Promise<void> {\n\t\tif (Is.arrayValue(restRouteProcessors) && Is.arrayValue(restRoutes)) {\n\t\t\tconst bodyLimits = this.resolveBodyLimits();\n\t\t\tfor (const restRoute of restRoutes) {\n\t\t\t\tlet path = StringHelper.trimTrailingSlashes(restRoute.path);\n\t\t\t\tif (!path.startsWith(\"/\")) {\n\t\t\t\t\tpath = `/${path}`;\n\t\t\t\t}\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"restRouteAdded\",\n\t\t\t\t\tdata: { route: path, method: restRoute.method }\n\t\t\t\t});\n\t\t\t\tconst method = restRoute.method.toLowerCase() as\n\t\t\t\t\t\"get\" | \"post\" | \"put\" | \"patch\" | \"delete\" | \"options\" | \"head\";\n\n\t\t\t\tconst bodyLimitKey = Is.stringValue(restRoute.bodyLimit)\n\t\t\t\t\t? restRoute.bodyLimit\n\t\t\t\t\t: HttpBodyLimit.Default;\n\t\t\t\tconst bodyLimit = bodyLimits[bodyLimitKey];\n\t\t\t\tif (Is.empty(bodyLimit)) {\n\t\t\t\t\tthrow new GeneralError(FastifyWebServer.CLASS_NAME, \"unknownBodyLimit\", {\n\t\t\t\t\t\troute: path,\n\t\t\t\t\t\tbodyLimit: bodyLimitKey\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis._fastify[method](path, { bodyLimit }, async (request, reply) =>\n\t\t\t\t\tthis.handleRequestRest(request, reply, restRoute)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add the socket routes to the server.\n\t * @param socketRouteProcessors The processors for the incoming requests.\n\t * @param socketRoutes The socket routes to add.\n\t * @internal\n\t */\n\tprivate async addRoutesSocket(\n\t\tsocketRouteProcessors?: ISocketRouteProcessor[],\n\t\tsocketRoutes?: ISocketRoute[]\n\t): Promise<void> {\n\t\tif (Is.arrayValue(socketRouteProcessors) && Is.arrayValue(socketRoutes)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst io: Server = (this._fastify as any).io;\n\n\t\t\tfor (const socketRoute of socketRoutes) {\n\t\t\t\tconst path = StringHelper.trimLeadingSlashes(\n\t\t\t\t\tStringHelper.trimTrailingSlashes(socketRoute.path)\n\t\t\t\t);\n\t\t\t\tconst pathParts = path.split(\"/\");\n\n\t\t\t\tconst namespace = `/${pathParts[0]}`;\n\t\t\t\tconst topic = pathParts.slice(1).join(\"/\");\n\n\t\t\t\tawait this._logging?.log({\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tts: Date.now(),\n\t\t\t\t\tsource: FastifyWebServer.CLASS_NAME,\n\t\t\t\t\tmessage: \"socketRouteAdded\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\thandshakePath: this._socketConfig.path,\n\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\teventName: topic\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconst socketNamespace = io.of(namespace);\n\n\t\t\t\tsocketNamespace.on(\"connection\", async socket => {\n\t\t\t\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\t\t\t\tmethod: HttpMethod.GET,\n\t\t\t\t\t\turl: socket.handshake.url,\n\t\t\t\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\t\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t\t\t\tsocketId: socket.id\n\t\t\t\t\t};\n\n\t\t\t\t\t// Pass the connected information on to any processors\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor (const connected of this._socketChains.connected) {\n\t\t\t\t\t\t\tawait connected(socketServerRequest, socketRoute, this._loggingComponentType);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\tHttpErrorHelper.buildResponse(response, error, httpStatusCode, this._includeErrorStack);\n\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t}\n\n\t\t\t\t\tsocket.on(\"disconnect\", async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// The socket disconnected so notify any processors\n\t\t\t\t\t\t\tfor (const disconnected of this._socketChains.disconnected) {\n\t\t\t\t\t\t\t\tawait disconnected(socketServerRequest, socketRoute, this._loggingComponentType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// If something fails on a disconnect there is not much we can do with it\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// Handle any incoming messages\n\t\t\t\t\tsocket.on(topic, async data => {\n\t\t\t\t\t\t// The listener is async, so anything escaping it would surface as an unhandled\n\t\t\t\t\t\t// rejection and terminate the process, emit it on the topic instead\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.handleRequestSocket(\n\t\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\t\tsocket,\n\t\t\t\t\t\t\t\t`/${pathParts.join(\"/\")}`,\n\t\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\t\tdata\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconst { error, httpStatusCode } = HttpErrorHelper.processError(\n\t\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconst response: IHttpResponse = {};\n\t\t\t\t\t\t\tHttpErrorHelper.buildResponse(\n\t\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\thttpStatusCode,\n\t\t\t\t\t\t\t\tthis._includeErrorStack\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tsocket.emit(topic, response);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle the incoming REST request.\n\t * @param request The incoming request.\n\t * @param reply The outgoing response.\n\t * @param restRoute The REST route to handle.\n\t * @returns The Fastify reply with the response.\n\t * @internal\n\t */\n\tprivate async handleRequestRest(\n\t\trequest: FastifyRequest,\n\t\treply: FastifyReply,\n\t\trestRoute?: IRestRoute\n\t): Promise<FastifyReply> {\n\t\tconst port =\n\t\t\t(request.port === 80 && request.protocol === \"http\") ||\n\t\t\t(request.port === 443 && request.protocol === \"https\") ||\n\t\t\t!Is.integer(request.port)\n\t\t\t\t? \"\"\n\t\t\t\t: `:${request.port}`;\n\n\t\tconst requestOrigin = `${request.protocol}://${request.hostname}${port}`;\n\n\t\tconst httpServerRequest = this.buildServerRequest(\n\t\t\trequest.method.toUpperCase() as HttpMethod,\n\t\t\t`${requestOrigin}${request.url}`,\n\t\t\trequest.body,\n\t\t\trequest.query as IHttpRequestQuery,\n\t\t\t// The not found handler matches a wildcard, which is not a param of any route\n\t\t\tIs.empty(restRoute) ? {} : (request.params as IHttpRequestPathParams),\n\t\t\trequest.headers as IHttpHeaders\n\t\t);\n\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds = this.buildContextIds(requestOrigin, httpServerRequest.headers);\n\t\tconst processorState = {};\n\n\t\tawait this.runProcessorsRest(\n\t\t\trestRoute,\n\t\t\thttpServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState\n\t\t);\n\n\t\tthis.validateResponse(httpResponse);\n\n\t\tif (!Is.empty(httpResponse.headers)) {\n\t\t\tfor (const header of Object.keys(httpResponse.headers)) {\n\t\t\t\treply.header(header, httpResponse.headers[header]);\n\t\t\t}\n\t\t}\n\t\treturn reply.status(httpResponse.statusCode ?? HttpStatusCode.ok).send(httpResponse.body);\n\t}\n\n\t/**\n\t * Handle the incoming socket request.\n\t * @param socketRoute The socket route to handle.\n\t * @param socket The socket to handle.\n\t * @param fullPath The full path of the socket route.\n\t * @param emitTopic The topic to emit the response on.\n\t * @param request The incoming request.\n\t * @internal\n\t */\n\tprivate async handleRequestSocket(\n\t\tsocketRoute: ISocketRoute,\n\t\tsocket: Socket,\n\t\tfullPath: string,\n\t\temitTopic: string,\n\t\trequest: IHttpRequest | undefined\n\t): Promise<void> {\n\t\tconst socketServerRequest: ISocketServerRequest = {\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: fullPath,\n\t\t\tquery: socket.handshake.query as IHttpRequestQuery,\n\t\t\theaders: socket.handshake.headers as IHttpHeaders,\n\t\t\t// The payload arrives straight off the wire, so it can be missing or any shape\n\t\t\tbody: Is.object(request) ? request.body : undefined,\n\t\t\tsocketId: socket.id\n\t\t};\n\t\tconst httpResponse: IHttpResponse = {};\n\t\tconst contextIds: IContextIds = {};\n\t\tconst processorState = {};\n\n\t\tdelete socketServerRequest.query?.EIO;\n\t\tdelete socketServerRequest.query?.transport;\n\n\t\tawait this.runProcessorsSocket(\n\t\t\tsocketRoute,\n\t\t\tsocketServerRequest,\n\t\t\thttpResponse,\n\t\t\tcontextIds,\n\t\t\tprocessorState,\n\t\t\temitTopic,\n\t\t\tasync (topic, response) => {\n\t\t\t\tsocket.emit(topic, response);\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Initialize the cors options.\n\t * @param options The web server options.\n\t * @internal\n\t */\n\tprivate async initCors(options?: IWebServerOptions): Promise<void> {\n\t\tconst corsOptions = this.resolveCorsOptions(options);\n\n\t\tawait this._fastify.register(FastifyCors, {\n\t\t\torigin: (origin, callback) => {\n\t\t\t\tcallback(\n\t\t\t\t\tnull,\n\t\t\t\t\tcorsOptions.hasWildcardOrigin ? true : corsOptions.origins.includes(origin as string)\n\t\t\t\t);\n\t\t\t},\n\t\t\tmethods: corsOptions.methods,\n\t\t\tallowedHeaders: corsOptions.allowedHeaders,\n\t\t\texposedHeaders: corsOptions.exposedHeaders,\n\t\t\tcredentials: true\n\t\t});\n\t}\n}\n"]}
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qCAAqC,CAAC;AACpD,cAAc,iDAAiD,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./fastifyWebServer.js\";\nexport * from \"./models/IFastifyWebServerConfig.js\";\nexport * from \"./models/IFastifyWebServerConstructorOptions.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IFastifyWebServerConfig.js","
|
|
1
|
+
{"version":3,"file":"IFastifyWebServerConfig.js","sources":["../../../src/models/IFastifyWebServerConfig.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ServerOptions as HttpsServerOptions } from \"node:https\";\nimport type { FastifyServerOptions } from \"fastify\";\nimport type { ServerOptions } from \"socket.io\";\n\n/**\n * The configuration for the Fastify web server.\n */\nexport interface IFastifyWebServerConfig {\n\t/**\n\t * The web server options, providing the https options serves over HTTPS.\n\t */\n\tweb?: Partial<FastifyServerOptions> & { https?: HttpsServerOptions };\n\n\t/**\n\t * The socket server options.\n\t */\n\tsocket?: Partial<ServerOptions>;\n\n\t/**\n\t * Include the stack with errors.\n\t */\n\tincludeErrorStack?: boolean;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IFastifyWebServerConstructorOptions.js","
|
|
1
|
+
{"version":3,"file":"IFastifyWebServerConstructorOptions.js","sources":["../../../src/models/IFastifyWebServerConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IMimeTypeProcessor } from \"@3sixty/api-models\";\nimport type { IFastifyWebServerConfig } from \"./IFastifyWebServerConfig.js\";\n\n/**\n * The options for the Fastify web server constructor.\n */\nexport interface IFastifyWebServerConstructorOptions {\n\t/**\n\t * The type of the logging component to use, if undefined, no logging will happen.\n\t */\n\tloggingComponentType?: string;\n\n\t/**\n\t * Additional configuration for the server.\n\t */\n\tconfig?: IFastifyWebServerConfig;\n\n\t/**\n\t * Additional MIME type processors.\n\t */\n\tmimeTypeProcessors?: IMimeTypeProcessor[];\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseServer } from "@3sixty/api-core-server";
|
|
2
|
+
import { type IRestRoute, type IRestRouteProcessor, type ISocketRoute, type ISocketRouteProcessor, type IWebServerOptions } from "@3sixty/api-models";
|
|
2
3
|
import { type FastifyInstance } from "fastify";
|
|
3
4
|
import type { IFastifyWebServerConstructorOptions } from "./models/IFastifyWebServerConstructorOptions.js";
|
|
4
5
|
/**
|
|
5
6
|
* Implementation of the web server using Fastify.
|
|
6
7
|
*/
|
|
7
|
-
export declare class FastifyWebServer
|
|
8
|
+
export declare class FastifyWebServer extends BaseServer<FastifyInstance> {
|
|
8
9
|
/**
|
|
9
10
|
* Runtime name for the class.
|
|
10
11
|
*/
|
|
@@ -35,25 +36,39 @@ export declare class FastifyWebServer implements IWebServer<FastifyInstance>, IH
|
|
|
35
36
|
*/
|
|
36
37
|
build(restRouteProcessors?: IRestRouteProcessor[], restRoutes?: IRestRoute[], socketRouteProcessors?: ISocketRouteProcessor[], socketRoutes?: ISocketRoute[], options?: IWebServerOptions): Promise<void>;
|
|
37
38
|
/**
|
|
38
|
-
* Start the
|
|
39
|
-
* @
|
|
39
|
+
* Start listening for connections on the transport.
|
|
40
|
+
* @param host The host to bind to.
|
|
41
|
+
* @param port The port to bind to.
|
|
42
|
+
* @returns A promise that resolves when the transport is listening.
|
|
40
43
|
*/
|
|
41
|
-
|
|
44
|
+
protected serverListen(host: string, port: number): Promise<void>;
|
|
42
45
|
/**
|
|
43
|
-
*
|
|
44
|
-
* @returns A promise that resolves when the
|
|
46
|
+
* Close the transport and all of its connections.
|
|
47
|
+
* @returns A promise that resolves when the transport has closed.
|
|
45
48
|
*/
|
|
46
|
-
|
|
49
|
+
protected serverClose(): Promise<void>;
|
|
47
50
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @returns The
|
|
51
|
+
* Get the addresses the transport is bound to.
|
|
52
|
+
* @returns The bound addresses.
|
|
50
53
|
*/
|
|
51
|
-
|
|
54
|
+
protected serverAddresses(): {
|
|
55
|
+
address: string;
|
|
56
|
+
family?: string;
|
|
57
|
+
port: number;
|
|
58
|
+
}[];
|
|
52
59
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* @param callback The callback to invoke when a deferred health result is ready.
|
|
56
|
-
* @returns The application health status of the component.
|
|
60
|
+
* Whether the transport is serving over TLS.
|
|
61
|
+
* @returns True if the transport is secure.
|
|
57
62
|
*/
|
|
58
|
-
|
|
63
|
+
protected serverIsSecure(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the transport is currently listening for connections.
|
|
66
|
+
* @returns True if the transport is listening.
|
|
67
|
+
*/
|
|
68
|
+
protected serverIsListening(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Whether a GET route is registered for the root path.
|
|
71
|
+
* @returns True if the root route is registered.
|
|
72
|
+
*/
|
|
73
|
+
protected serverHasRootRoute(): boolean;
|
|
59
74
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ServerOptions as HttpsServerOptions } from "node:https";
|
|
1
2
|
import type { FastifyServerOptions } from "fastify";
|
|
2
3
|
import type { ServerOptions } from "socket.io";
|
|
3
4
|
/**
|
|
@@ -5,9 +6,11 @@ import type { ServerOptions } from "socket.io";
|
|
|
5
6
|
*/
|
|
6
7
|
export interface IFastifyWebServerConfig {
|
|
7
8
|
/**
|
|
8
|
-
* The web server options.
|
|
9
|
+
* The web server options, providing the https options serves over HTTPS.
|
|
9
10
|
*/
|
|
10
|
-
web?: Partial<FastifyServerOptions
|
|
11
|
+
web?: Partial<FastifyServerOptions> & {
|
|
12
|
+
https?: HttpsServerOptions;
|
|
13
|
+
};
|
|
11
14
|
/**
|
|
12
15
|
* The socket server options.
|
|
13
16
|
*/
|
package/docs/changelog.md
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.20.0-next.1](https://github.com/3sixtyglobal/api/compare/api-server-fastify-v0.20.0-next.0...api-server-fastify-v0.20.0-next.1) (2026-10-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* authorization ([#51](https://github.com/3sixtyglobal/api/issues/51)) ([023ef94](https://github.com/3sixtyglobal/api/commit/023ef94925114e88522cbe6f703d9b05a202bc6d))
|
|
9
|
+
* publish packages under the [@3sixty](https://github.com/3sixty) namespace ([91b1822](https://github.com/3sixtyglobal/api/commit/91b1822dba38f70692087ad4643572531d6634dc))
|
|
10
|
+
* updated ts compile ([d9a5c86](https://github.com/3sixtyglobal/api/commit/d9a5c86ec7dd1faf3045b5cd1e0d38a4b331313d))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
* The following workspace dependencies were updated
|
|
16
|
+
* dependencies
|
|
17
|
+
* @3sixty/api-core-server bumped from 0.20.0-next.0 to 0.20.0-next.1
|
|
18
|
+
* @3sixty/api-core bumped from 0.20.0-next.0 to 0.20.0-next.1
|
|
19
|
+
* @3sixty/api-models bumped from 0.20.0-next.0 to 0.20.0-next.1
|
|
20
|
+
* devDependencies
|
|
21
|
+
* @3sixty/api-processors bumped from 0.20.0-next.0 to 0.20.0-next.1
|