@twin.org/api-server-fastify 0.9.3 → 0.10.1-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/fastifyWebServer.js +94 -72
- package/dist/es/fastifyWebServer.js.map +1 -1
- package/dist/es/models/IRestProcessorChains.js +2 -0
- package/dist/es/models/IRestProcessorChains.js.map +1 -0
- package/dist/es/models/ISocketProcessorChains.js +2 -0
- package/dist/es/models/ISocketProcessorChains.js.map +1 -0
- package/dist/types/models/IRestProcessorChains.d.ts +18 -0
- package/dist/types/models/ISocketProcessorChains.d.ts +26 -0
- package/docs/changelog.md +74 -0
- package/package.json +9 -9
|
@@ -85,6 +85,16 @@ export class FastifyWebServer {
|
|
|
85
85
|
* @internal
|
|
86
86
|
*/
|
|
87
87
|
_localOrigin;
|
|
88
|
+
/**
|
|
89
|
+
* The REST processor chains resolved when the server is built.
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
_restChains;
|
|
93
|
+
/**
|
|
94
|
+
* The socket processor chains resolved when the server is built.
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
_socketChains;
|
|
88
98
|
/**
|
|
89
99
|
* Create a new instance of FastifyWebServer.
|
|
90
100
|
* @param options The options for the server.
|
|
@@ -105,6 +115,8 @@ export class FastifyWebServer {
|
|
|
105
115
|
...options?.config?.socket
|
|
106
116
|
};
|
|
107
117
|
this._started = false;
|
|
118
|
+
this._restChains = { pre: [], process: [], post: [] };
|
|
119
|
+
this._socketChains = { connected: [], disconnected: [], pre: [], process: [], post: [] };
|
|
108
120
|
this._mimeTypeProcessors = options?.mimeTypeProcessors ?? [];
|
|
109
121
|
const hasJsonLd = this._mimeTypeProcessors.some(processor => processor.getTypes().includes(MimeTypes.JsonLd));
|
|
110
122
|
if (!hasJsonLd) {
|
|
@@ -217,6 +229,7 @@ export class FastifyWebServer {
|
|
|
217
229
|
});
|
|
218
230
|
await this.addRoutesRest(restRouteProcessors, restRoutes);
|
|
219
231
|
await this.addRoutesSocket(socketRouteProcessors, socketRoutes);
|
|
232
|
+
this.buildProcessorChains(restRouteProcessors, socketRouteProcessors);
|
|
220
233
|
}
|
|
221
234
|
/**
|
|
222
235
|
* Start the server.
|
|
@@ -555,7 +568,7 @@ export class FastifyWebServer {
|
|
|
555
568
|
// This can be overridden by a processor if needed, for example a tenant processor
|
|
556
569
|
[HttpContextIdKeys.PublicOrigin]: this._publicOrigin ?? requestOrigin ?? this._localOrigin
|
|
557
570
|
};
|
|
558
|
-
const processorState =
|
|
571
|
+
const processorState = {};
|
|
559
572
|
if (Is.object(httpServerRequest.pathParams)) {
|
|
560
573
|
for (const key of Object.keys(httpServerRequest.pathParams)) {
|
|
561
574
|
httpServerRequest.pathParams[key] = decodeURIComponent(httpServerRequest.pathParams[key]);
|
|
@@ -585,17 +598,13 @@ export class FastifyWebServer {
|
|
|
585
598
|
*/
|
|
586
599
|
async runProcessorsRest(restRouteProcessors, restRoute, httpServerRequest, httpResponse, contextIds, processorState) {
|
|
587
600
|
let hasPreError = false;
|
|
588
|
-
const filteredProcessors = this.filterRouteProcessors(restRoute, restRouteProcessors);
|
|
589
601
|
try {
|
|
590
602
|
// Run inside ContextIdStore.run so pre-processors can do tenant-scoped storage lookups.
|
|
591
603
|
await ContextIdStore.run(contextIds, async () => {
|
|
592
|
-
for (const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
loggingComponentType: this._loggingComponentType
|
|
597
|
-
});
|
|
598
|
-
}
|
|
604
|
+
for (const pre of this._restChains.pre) {
|
|
605
|
+
await pre(httpServerRequest, httpResponse, restRoute, contextIds, processorState, {
|
|
606
|
+
loggingComponentType: this._loggingComponentType
|
|
607
|
+
});
|
|
599
608
|
}
|
|
600
609
|
});
|
|
601
610
|
}
|
|
@@ -617,13 +626,10 @@ export class FastifyWebServer {
|
|
|
617
626
|
// Run the processors within an async context
|
|
618
627
|
// so that any services can access the context ids
|
|
619
628
|
await ContextIdStore.run(contextIds, async () => {
|
|
620
|
-
for (const
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
loggingComponentType: this._loggingComponentType
|
|
625
|
-
});
|
|
626
|
-
}
|
|
629
|
+
for (const process of this._restChains.process) {
|
|
630
|
+
await process(httpServerRequest, httpResponse, restRoute, processorState, {
|
|
631
|
+
loggingComponentType: this._loggingComponentType
|
|
632
|
+
});
|
|
627
633
|
}
|
|
628
634
|
});
|
|
629
635
|
}
|
|
@@ -636,13 +642,10 @@ export class FastifyWebServer {
|
|
|
636
642
|
// Always run the post processors, even if there was an error earlier
|
|
637
643
|
// as they may perform cleanup tasks, or logging etc
|
|
638
644
|
await ContextIdStore.run(contextIds, async () => {
|
|
639
|
-
for (const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
loggingComponentType: this._loggingComponentType
|
|
644
|
-
});
|
|
645
|
-
}
|
|
645
|
+
for (const post of this._restChains.post) {
|
|
646
|
+
await post(httpServerRequest, httpResponse, restRoute, contextIds, processorState, {
|
|
647
|
+
loggingComponentType: this._loggingComponentType
|
|
648
|
+
});
|
|
646
649
|
}
|
|
647
650
|
});
|
|
648
651
|
}
|
|
@@ -660,33 +663,6 @@ export class FastifyWebServer {
|
|
|
660
663
|
});
|
|
661
664
|
}
|
|
662
665
|
}
|
|
663
|
-
/**
|
|
664
|
-
* Filter the route processors based on the requested features.
|
|
665
|
-
* @param route The route to process.
|
|
666
|
-
* @param routeProcessors The processors to filter.
|
|
667
|
-
* @returns The filtered list of route processor.
|
|
668
|
-
* @internal
|
|
669
|
-
*/
|
|
670
|
-
filterRouteProcessors(route, routeProcessors) {
|
|
671
|
-
const requestedFeatures = route?.processorFeatures ?? [];
|
|
672
|
-
if (!Is.arrayValue(requestedFeatures)) {
|
|
673
|
-
// If there are no requested features, we just return all the processors
|
|
674
|
-
return routeProcessors;
|
|
675
|
-
}
|
|
676
|
-
// Reduce the list of route processors to just those in the requested features list
|
|
677
|
-
const reducedProcessors = routeProcessors.filter(routeProcessor => {
|
|
678
|
-
// Processors that do not define any features always get run
|
|
679
|
-
// If the route processor has features defined, then we only run it
|
|
680
|
-
// if the route has at least one of those features required
|
|
681
|
-
let runRouteProcessor = true;
|
|
682
|
-
if (routeProcessor.features) {
|
|
683
|
-
const routeProcessorFeatures = routeProcessor.features();
|
|
684
|
-
runRouteProcessor = routeProcessorFeatures.some(feature => requestedFeatures.includes(feature));
|
|
685
|
-
}
|
|
686
|
-
return runRouteProcessor;
|
|
687
|
-
});
|
|
688
|
-
return reducedProcessors;
|
|
689
|
-
}
|
|
690
666
|
/**
|
|
691
667
|
* Handle the incoming socket request.
|
|
692
668
|
* @param socketRouteProcessors The hooks to process the incoming requests.
|
|
@@ -728,19 +704,15 @@ export class FastifyWebServer {
|
|
|
728
704
|
* @internal
|
|
729
705
|
*/
|
|
730
706
|
async runProcessorsSocket(socketRouteProcessors, socketRoute, socketServerRequest, httpResponse, contextIds, processorState, requestTopic, responseEmitter) {
|
|
731
|
-
const filteredProcessors = this.filterRouteProcessors(socketRoute, socketRouteProcessors);
|
|
732
707
|
// Custom emit method which will also call the post processors
|
|
733
708
|
const postProcessEmit = async (topic, response, responseProcessorState) => {
|
|
734
709
|
await responseEmitter(topic, response);
|
|
735
710
|
try {
|
|
736
711
|
// The post processors are called after the response has been emitted
|
|
737
|
-
for (const
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
loggingComponentType: this._loggingComponentType
|
|
742
|
-
});
|
|
743
|
-
}
|
|
712
|
+
for (const post of this._socketChains.post) {
|
|
713
|
+
await post(socketServerRequest, response, socketRoute, contextIds, responseProcessorState, {
|
|
714
|
+
loggingComponentType: this._loggingComponentType
|
|
715
|
+
});
|
|
744
716
|
}
|
|
745
717
|
}
|
|
746
718
|
catch (err) {
|
|
@@ -757,13 +729,10 @@ export class FastifyWebServer {
|
|
|
757
729
|
}
|
|
758
730
|
};
|
|
759
731
|
try {
|
|
760
|
-
for (const
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
loggingComponentType: this._loggingComponentType
|
|
765
|
-
});
|
|
766
|
-
}
|
|
732
|
+
for (const pre of this._socketChains.pre) {
|
|
733
|
+
await pre(socketServerRequest, httpResponse, socketRoute, contextIds, processorState, {
|
|
734
|
+
loggingComponentType: this._loggingComponentType
|
|
735
|
+
});
|
|
767
736
|
}
|
|
768
737
|
// We always call all the processors regardless of any response set by a previous processor.
|
|
769
738
|
// But if a pre processor sets a status code, we will emit the response manually, as the pre
|
|
@@ -772,13 +741,10 @@ export class FastifyWebServer {
|
|
|
772
741
|
await postProcessEmit(requestTopic, httpResponse, processorState);
|
|
773
742
|
}
|
|
774
743
|
await ContextIdStore.run(contextIds, async () => {
|
|
775
|
-
for (const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
await postProcessEmit(topic, processResponse, processorState);
|
|
780
|
-
}, this._loggingComponentType);
|
|
781
|
-
}
|
|
744
|
+
for (const process of this._socketChains.process) {
|
|
745
|
+
await process(socketServerRequest, httpResponse, socketRoute, processorState, async (topic, processResponse) => {
|
|
746
|
+
await postProcessEmit(topic, processResponse, processorState);
|
|
747
|
+
}, this._loggingComponentType);
|
|
782
748
|
}
|
|
783
749
|
});
|
|
784
750
|
// If the processors set the status to any kind of error then we should emit this manually
|
|
@@ -812,6 +778,7 @@ export class FastifyWebServer {
|
|
|
812
778
|
HttpMethod.GET,
|
|
813
779
|
HttpMethod.PUT,
|
|
814
780
|
HttpMethod.POST,
|
|
781
|
+
HttpMethod.PATCH,
|
|
815
782
|
HttpMethod.DELETE,
|
|
816
783
|
HttpMethod.OPTIONS
|
|
817
784
|
];
|
|
@@ -840,5 +807,60 @@ export class FastifyWebServer {
|
|
|
840
807
|
credentials: true
|
|
841
808
|
});
|
|
842
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* Resolve the route processors in to per phase chains, so that the lookups and bindings
|
|
812
|
+
* are performed once when the server is built instead of on every request.
|
|
813
|
+
* @param restRouteProcessors The processors for the incoming REST requests.
|
|
814
|
+
* @param socketRouteProcessors The processors for the incoming socket requests.
|
|
815
|
+
* @internal
|
|
816
|
+
*/
|
|
817
|
+
buildProcessorChains(restRouteProcessors, socketRouteProcessors) {
|
|
818
|
+
const restChains = { pre: [], process: [], post: [] };
|
|
819
|
+
for (const routeProcessor of restRouteProcessors ?? []) {
|
|
820
|
+
const pre = routeProcessor.pre?.bind(routeProcessor);
|
|
821
|
+
if (Is.function(pre)) {
|
|
822
|
+
restChains.pre.push(pre);
|
|
823
|
+
}
|
|
824
|
+
const process = routeProcessor.process?.bind(routeProcessor);
|
|
825
|
+
if (Is.function(process)) {
|
|
826
|
+
restChains.process.push(process);
|
|
827
|
+
}
|
|
828
|
+
const post = routeProcessor.post?.bind(routeProcessor);
|
|
829
|
+
if (Is.function(post)) {
|
|
830
|
+
restChains.post.push(post);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
const socketChains = {
|
|
834
|
+
connected: [],
|
|
835
|
+
disconnected: [],
|
|
836
|
+
pre: [],
|
|
837
|
+
process: [],
|
|
838
|
+
post: []
|
|
839
|
+
};
|
|
840
|
+
for (const routeProcessor of socketRouteProcessors ?? []) {
|
|
841
|
+
const connected = routeProcessor.connected?.bind(routeProcessor);
|
|
842
|
+
if (Is.function(connected)) {
|
|
843
|
+
socketChains.connected.push(connected);
|
|
844
|
+
}
|
|
845
|
+
const disconnected = routeProcessor.disconnected?.bind(routeProcessor);
|
|
846
|
+
if (Is.function(disconnected)) {
|
|
847
|
+
socketChains.disconnected.push(disconnected);
|
|
848
|
+
}
|
|
849
|
+
const pre = routeProcessor.pre?.bind(routeProcessor);
|
|
850
|
+
if (Is.function(pre)) {
|
|
851
|
+
socketChains.pre.push(pre);
|
|
852
|
+
}
|
|
853
|
+
const process = routeProcessor.process?.bind(routeProcessor);
|
|
854
|
+
if (Is.function(process)) {
|
|
855
|
+
socketChains.process.push(process);
|
|
856
|
+
}
|
|
857
|
+
const post = routeProcessor.post?.bind(routeProcessor);
|
|
858
|
+
if (Is.function(post)) {
|
|
859
|
+
socketChains.post.push(post);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
this._restChains = restChains;
|
|
863
|
+
this._socketChains = socketChains;
|
|
864
|
+
}
|
|
843
865
|
}
|
|
844
866
|
//# sourceMappingURL=fastifyWebServer.js.map
|
|
@@ -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 FastifyCompress from \"@fastify/compress\";\nimport FastifyCors from \"@fastify/cors\";\nimport {\n\ttype HealthApplicationCallback,\n\tHealthStatus,\n\tHttpBodyLimit,\n\tHttpContextIdKeys,\n\tHttpErrorHelper,\n\ttype IHealthProviderComponent,\n\ttype IBaseRoute,\n\ttype IBaseRouteProcessor,\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 \"@twin.org/api-models\";\nimport { JsonLdMimeTypeProcessor } from \"@twin.org/api-processors\";\nimport { ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGeneralError,\n\ttype IError,\n\tIs,\n\tRandomHelper,\n\tStringHelper,\n\tUrl\n} from \"@twin.org/core\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport {\n\tHeaderTypes,\n\tHttpMethod,\n\tHttpStatusCode,\n\ttype IHttpHeaders,\n\tHeaderHelper,\n\tMimeTypes\n} from \"@twin.org/web\";\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 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 * 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\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\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\tawait this.handleRequestSocket(\n\t\t\t\t\t\t\tsocketRouteProcessors,\n\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\tsocket,\n\t\t\t\t\t\t\t`/${pathParts.join(\"/\")}`,\n\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\tdata\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 = restRoute?.processorData ?? {};\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\t\tconst filteredProcessors = this.filterRouteProcessors(restRoute, restRouteProcessors);\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 routeProcessor of filteredProcessors) {\n\t\t\t\t\tconst pre = routeProcessor.pre?.bind(routeProcessor);\n\t\t\t\t\tif (Is.function(pre)) {\n\t\t\t\t\t\tawait pre(httpServerRequest, httpResponse, restRoute, contextIds, 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});\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 routeProcessor of filteredProcessors) {\n\t\t\t\t\t\tconst process = routeProcessor.process?.bind(routeProcessor);\n\t\t\t\t\t\tif (Is.function(process)) {\n\t\t\t\t\t\t\tawait process(httpServerRequest, httpResponse, restRoute, processorState, {\n\t\t\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t\t\t});\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 routeProcessor of filteredProcessors) {\n\t\t\t\t\tconst post = routeProcessor.post?.bind(routeProcessor);\n\t\t\t\t\tif (Is.function(post)) {\n\t\t\t\t\t\tawait post(httpServerRequest, httpResponse, restRoute, contextIds, 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});\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 * Filter the route processors based on the requested features.\n\t * @param route The route to process.\n\t * @param routeProcessors The processors to filter.\n\t * @returns The filtered list of route processor.\n\t * @internal\n\t */\n\tprivate filterRouteProcessors<T extends IBaseRouteProcessor>(\n\t\troute: IBaseRoute | undefined,\n\t\trouteProcessors: T[]\n\t): T[] {\n\t\tconst requestedFeatures = route?.processorFeatures ?? [];\n\n\t\tif (!Is.arrayValue(requestedFeatures)) {\n\t\t\t// If there are no requested features, we just return all the processors\n\t\t\treturn routeProcessors;\n\t\t}\n\n\t\t// Reduce the list of route processors to just those in the requested features list\n\t\tconst reducedProcessors = routeProcessors.filter(routeProcessor => {\n\t\t\t// Processors that do not define any features always get run\n\t\t\t// If the route processor has features defined, then we only run it\n\t\t\t// if the route has at least one of those features required\n\t\t\tlet runRouteProcessor = true;\n\t\t\tif (routeProcessor.features) {\n\t\t\t\tconst routeProcessorFeatures = routeProcessor.features();\n\t\t\t\trunRouteProcessor = routeProcessorFeatures.some(feature =>\n\t\t\t\t\trequestedFeatures.includes(feature)\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn runRouteProcessor;\n\t\t});\n\n\t\treturn reducedProcessors;\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\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\tbody: request.body,\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\tconst filteredProcessors = this.filterRouteProcessors(socketRoute, socketRouteProcessors);\n\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 postSocketRouteProcessor of filteredProcessors) {\n\t\t\t\t\tconst post = postSocketRouteProcessor.post?.bind(postSocketRouteProcessor);\n\t\t\t\t\tif (Is.function(post)) {\n\t\t\t\t\t\tawait post(\n\t\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\tcontextIds,\n\t\t\t\t\t\t\tresponseProcessorState,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tloggingComponentType: this._loggingComponentType\n\t\t\t\t\t\t\t}\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 socketRouteProcessor of filteredProcessors) {\n\t\t\t\tconst pre = socketRouteProcessor.pre?.bind(socketRouteProcessor);\n\t\t\t\tif (Is.function(pre)) {\n\t\t\t\t\tawait pre(socketServerRequest, httpResponse, socketRoute, 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\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 socketRouteProcessor of filteredProcessors) {\n\t\t\t\t\tconst process = socketRouteProcessor.process?.bind(socketRouteProcessor);\n\t\t\t\t\tif (Is.function(process)) {\n\t\t\t\t\t\tawait process(\n\t\t\t\t\t\t\tsocketServerRequest,\n\t\t\t\t\t\t\thttpResponse,\n\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\tprocessorState,\n\t\t\t\t\t\t\tasync (topic: string, processResponse: IHttpResponse) => {\n\t\t\t\t\t\t\t\tawait postProcessEmit(topic, processResponse, processorState);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tthis._loggingComponentType\n\t\t\t\t\t\t);\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.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"]}
|
|
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 FastifyCompress from \"@fastify/compress\";\nimport FastifyCors from \"@fastify/cors\";\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 \"@twin.org/api-models\";\nimport { JsonLdMimeTypeProcessor } from \"@twin.org/api-processors\";\nimport { ContextIdStore, type IContextIds } from \"@twin.org/context\";\nimport {\n\tBaseError,\n\tComponentFactory,\n\tGeneralError,\n\ttype IError,\n\tIs,\n\tRandomHelper,\n\tStringHelper,\n\tUrl\n} from \"@twin.org/core\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport {\n\tHeaderTypes,\n\tHttpMethod,\n\tHttpStatusCode,\n\ttype IHttpHeaders,\n\tHeaderHelper,\n\tMimeTypes\n} from \"@twin.org/web\";\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\tawait this.handleRequestSocket(\n\t\t\t\t\t\t\tsocketRouteProcessors,\n\t\t\t\t\t\t\tsocketRoute,\n\t\t\t\t\t\t\tsocket,\n\t\t\t\t\t\t\t`/${pathParts.join(\"/\")}`,\n\t\t\t\t\t\t\ttopic,\n\t\t\t\t\t\t\tdata\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\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\tbody: request.body,\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IRestProcessorChains.js","sourceRoot":"","sources":["../../../src/models/IRestProcessorChains.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IRestRouteProcessor } from \"@twin.org/api-models\";\n\n/**\n * The REST processor phase chains, bound to their processors when the server is built.\n */\nexport interface IRestProcessorChains {\n\t/**\n\t * The pre processing phase.\n\t */\n\tpre: NonNullable<IRestRouteProcessor[\"pre\"]>[];\n\n\t/**\n\t * The main processing phase.\n\t */\n\tprocess: NonNullable<IRestRouteProcessor[\"process\"]>[];\n\n\t/**\n\t * The post processing phase.\n\t */\n\tpost: NonNullable<IRestRouteProcessor[\"post\"]>[];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISocketProcessorChains.js","sourceRoot":"","sources":["../../../src/models/ISocketProcessorChains.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ISocketRouteProcessor } from \"@twin.org/api-models\";\n\n/**\n * The socket processor phase chains, bound to their processors when the server is built.\n */\nexport interface ISocketProcessorChains {\n\t/**\n\t * The socket connected phase.\n\t */\n\tconnected: NonNullable<ISocketRouteProcessor[\"connected\"]>[];\n\n\t/**\n\t * The socket disconnected phase.\n\t */\n\tdisconnected: NonNullable<ISocketRouteProcessor[\"disconnected\"]>[];\n\n\t/**\n\t * The pre processing phase.\n\t */\n\tpre: NonNullable<ISocketRouteProcessor[\"pre\"]>[];\n\n\t/**\n\t * The main processing phase.\n\t */\n\tprocess: NonNullable<ISocketRouteProcessor[\"process\"]>[];\n\n\t/**\n\t * The post processing phase.\n\t */\n\tpost: NonNullable<ISocketRouteProcessor[\"post\"]>[];\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IRestRouteProcessor } from "@twin.org/api-models";
|
|
2
|
+
/**
|
|
3
|
+
* The REST processor phase chains, bound to their processors when the server is built.
|
|
4
|
+
*/
|
|
5
|
+
export interface IRestProcessorChains {
|
|
6
|
+
/**
|
|
7
|
+
* The pre processing phase.
|
|
8
|
+
*/
|
|
9
|
+
pre: NonNullable<IRestRouteProcessor["pre"]>[];
|
|
10
|
+
/**
|
|
11
|
+
* The main processing phase.
|
|
12
|
+
*/
|
|
13
|
+
process: NonNullable<IRestRouteProcessor["process"]>[];
|
|
14
|
+
/**
|
|
15
|
+
* The post processing phase.
|
|
16
|
+
*/
|
|
17
|
+
post: NonNullable<IRestRouteProcessor["post"]>[];
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ISocketRouteProcessor } from "@twin.org/api-models";
|
|
2
|
+
/**
|
|
3
|
+
* The socket processor phase chains, bound to their processors when the server is built.
|
|
4
|
+
*/
|
|
5
|
+
export interface ISocketProcessorChains {
|
|
6
|
+
/**
|
|
7
|
+
* The socket connected phase.
|
|
8
|
+
*/
|
|
9
|
+
connected: NonNullable<ISocketRouteProcessor["connected"]>[];
|
|
10
|
+
/**
|
|
11
|
+
* The socket disconnected phase.
|
|
12
|
+
*/
|
|
13
|
+
disconnected: NonNullable<ISocketRouteProcessor["disconnected"]>[];
|
|
14
|
+
/**
|
|
15
|
+
* The pre processing phase.
|
|
16
|
+
*/
|
|
17
|
+
pre: NonNullable<ISocketRouteProcessor["pre"]>[];
|
|
18
|
+
/**
|
|
19
|
+
* The main processing phase.
|
|
20
|
+
*/
|
|
21
|
+
process: NonNullable<ISocketRouteProcessor["process"]>[];
|
|
22
|
+
/**
|
|
23
|
+
* The post processing phase.
|
|
24
|
+
*/
|
|
25
|
+
post: NonNullable<ISocketRouteProcessor["post"]>[];
|
|
26
|
+
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.1-next.1](https://github.com/iotaledger/twin-api/compare/api-server-fastify-v0.10.1-next.0...api-server-fastify-v0.10.1-next.1) (2026-09-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add authentication generators and process features option ([a67edf1](https://github.com/iotaledger/twin-api/commit/a67edf1df212bd8ab94a40cddf5338551155696f))
|
|
9
|
+
* add context id features ([#42](https://github.com/iotaledger/twin-api/issues/42)) ([0186055](https://github.com/iotaledger/twin-api/commit/0186055c48afde842a4254b4df9ac9249c40fe40))
|
|
10
|
+
* add hardcoded keys ([296a6a3](https://github.com/iotaledger/twin-api/commit/296a6a3ae55d29b54526defdf28ab774735243c9))
|
|
11
|
+
* add json-ld mime type processor and auth admin component ([8861791](https://github.com/iotaledger/twin-api/commit/88617916e23bfbca023dbae1976fe421983a02ff))
|
|
12
|
+
* add logging component type to request contexts ([210de1b](https://github.com/iotaledger/twin-api/commit/210de1b9e1c91079b59a2b90ddd57569668d647d))
|
|
13
|
+
* add root, favicon routes ([71da1c3](https://github.com/iotaledger/twin-api/commit/71da1c3a93c349588aff7084d1d8d6a29a277da8))
|
|
14
|
+
* add socket id, connect and disconnect ([20b0d0e](https://github.com/iotaledger/twin-api/commit/20b0d0ec279cab46141fee09de2c4a7087cdce16))
|
|
15
|
+
* add validate-locales ([cdba610](https://github.com/iotaledger/twin-api/commit/cdba610a0acb5022d2e3ce729732e6646a297e5e))
|
|
16
|
+
* async socket closedown ([e35f628](https://github.com/iotaledger/twin-api/commit/e35f62874c75f6c8dc175bd9713db9c2d062f697))
|
|
17
|
+
* auth enhancements ([#93](https://github.com/iotaledger/twin-api/issues/93)) ([921a50c](https://github.com/iotaledger/twin-api/commit/921a50cd89d26e530a6be6174a5a803060fa0eb6))
|
|
18
|
+
* configurable request body limits per route ([#266](https://github.com/iotaledger/twin-api/issues/266)) ([50bfca5](https://github.com/iotaledger/twin-api/commit/50bfca5238c25af6c687a1cd003ca3d70a97d477))
|
|
19
|
+
* decodeURIComponent for query and path params ([ead68a2](https://github.com/iotaledger/twin-api/commit/ead68a257425c10dd912497f7edd473c469ca132))
|
|
20
|
+
* eslint migration to flat config ([0dd5820](https://github.com/iotaledger/twin-api/commit/0dd5820e3af97350fd08b8d226f4a6c1a9246805))
|
|
21
|
+
* health application checks ([#240](https://github.com/iotaledger/twin-api/issues/240)) ([68ec8b2](https://github.com/iotaledger/twin-api/commit/68ec8b29dae396928aa874826565efa6ad5d18c9))
|
|
22
|
+
* health updates ([#243](https://github.com/iotaledger/twin-api/issues/243)) ([8360945](https://github.com/iotaledger/twin-api/commit/836094547839f63f2309d4bcd8c4d19128c73883))
|
|
23
|
+
* hosting service ([#109](https://github.com/iotaledger/twin-api/issues/109)) ([985bf1f](https://github.com/iotaledger/twin-api/commit/985bf1f5c07b09ecb800df7120bc2422ac7a6d25))
|
|
24
|
+
* improve socket route logging ([b8d9519](https://github.com/iotaledger/twin-api/commit/b8d95199f838ac6ba9f45c30ef7c4e613201ff53))
|
|
25
|
+
* logging naming consistency ([a4a6ef2](https://github.com/iotaledger/twin-api/commit/a4a6ef2de5049045589eb78b177ff62e744bde9d))
|
|
26
|
+
* organization identifiers ([#158](https://github.com/iotaledger/twin-api/issues/158)) ([ce13244](https://github.com/iotaledger/twin-api/commit/ce13244aaacbf82d9e5f87d905e283b36ad63bbf))
|
|
27
|
+
* prebuild routes ([#286](https://github.com/iotaledger/twin-api/issues/286)) ([aa283be](https://github.com/iotaledger/twin-api/commit/aa283bec5d7074772860f6e7830236103bd43f8f))
|
|
28
|
+
* public base url ([#70](https://github.com/iotaledger/twin-api/issues/70)) ([5b958cd](https://github.com/iotaledger/twin-api/commit/5b958cd91e8a38cdae2835ff5f2356c7e48d37c3))
|
|
29
|
+
* remove hosting component ([#170](https://github.com/iotaledger/twin-api/issues/170)) ([e78c1e8](https://github.com/iotaledger/twin-api/commit/e78c1e87d2747bf58da02b6b77680708ff681122))
|
|
30
|
+
* separate service responsibilities ([#116](https://github.com/iotaledger/twin-api/issues/116)) ([2234648](https://github.com/iotaledger/twin-api/commit/2234648de4a2de5b7356aadde328f40470bc12e3))
|
|
31
|
+
* typescript 6 update ([78d2aa0](https://github.com/iotaledger/twin-api/commit/78d2aa00902f79b61973079b798b87ec05f18a8b))
|
|
32
|
+
* update dependencies ([32b8cd2](https://github.com/iotaledger/twin-api/commit/32b8cd20353119dd1998e293d54063cf4d9ecc29))
|
|
33
|
+
* update dependencies ([1171dc4](https://github.com/iotaledger/twin-api/commit/1171dc416a9481737f6a640e3cf30145768f37e9))
|
|
34
|
+
* update framework core ([d8eebf2](https://github.com/iotaledger/twin-api/commit/d8eebf267fa2a0abaa84e58590496e9d20490cfa))
|
|
35
|
+
* update health format ([cfbfbbb](https://github.com/iotaledger/twin-api/commit/cfbfbbb2e9afbd2574ffd2446ad51e4217437951))
|
|
36
|
+
* update IComponent signatures ([915ce37](https://github.com/iotaledger/twin-api/commit/915ce37712326ab4aa6869c350eabaa4622e8430))
|
|
37
|
+
* use shared store mechanism ([#19](https://github.com/iotaledger/twin-api/issues/19)) ([32116df](https://github.com/iotaledger/twin-api/commit/32116df3b4380a30137f5056f242a5c99afa2df9))
|
|
38
|
+
* user admin service ([#77](https://github.com/iotaledger/twin-api/issues/77)) ([c8491df](https://github.com/iotaledger/twin-api/commit/c8491df7b07c1f45560c8a78c6adc806d0ececbb))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Bug Fixes
|
|
42
|
+
|
|
43
|
+
* change logout and refresh routes from GET to POST ([#111](https://github.com/iotaledger/twin-api/issues/111)) ([cb8b64b](https://github.com/iotaledger/twin-api/commit/cb8b64b6507f9991baa78a663de2e84269695c82))
|
|
44
|
+
* error handling make sure primary error takes precedence ([84b61f2](https://github.com/iotaledger/twin-api/commit/84b61f27fe5e4919c0c9f9a1edc8ff46dc45c1f7))
|
|
45
|
+
* import ([4cf7344](https://github.com/iotaledger/twin-api/commit/4cf734410d4cd0d51c537775f51de1ee32dcb8c8))
|
|
46
|
+
* locales ([1b84d8e](https://github.com/iotaledger/twin-api/commit/1b84d8eb4dbe2302897e184e6389892b7ba12608))
|
|
47
|
+
* missing port in server request url ([#71](https://github.com/iotaledger/twin-api/issues/71)) ([21d1bb5](https://github.com/iotaledger/twin-api/commit/21d1bb57e7dac5c737266876b7521130db1df975))
|
|
48
|
+
* preserve error stack in error responses when includeErrorStack is enabled ([#238](https://github.com/iotaledger/twin-api/issues/238)) ([7abc9b7](https://github.com/iotaledger/twin-api/commit/7abc9b79d07724abb68b2c06467cbdb54c880083))
|
|
49
|
+
* prevent error body masking 4xx as 500, run pre-processors in context scope ([#102](https://github.com/iotaledger/twin-api/issues/102)) ([5fbe14c](https://github.com/iotaledger/twin-api/commit/5fbe14c98e11e77a30e16704dcb8bfba7705926b))
|
|
50
|
+
* resolve local origin context by organization routing param ([#180](https://github.com/iotaledger/twin-api/issues/180)) ([bceb9f1](https://github.com/iotaledger/twin-api/commit/bceb9f1b5b68382b7e2f9743ee7b4ea0e3a33f55))
|
|
51
|
+
* socket.io cleanup ([554324c](https://github.com/iotaledger/twin-api/commit/554324c0349a79b6722e32f042fc0a77572b4c9b))
|
|
52
|
+
* use correct format for log messaging ([6b62a18](https://github.com/iotaledger/twin-api/commit/6b62a185e1da1150bb1e4331337e2799294b83c4))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Dependencies
|
|
56
|
+
|
|
57
|
+
* The following workspace dependencies were updated
|
|
58
|
+
* dependencies
|
|
59
|
+
* @twin.org/api-core bumped from 0.10.1-next.0 to 0.10.1-next.1
|
|
60
|
+
* @twin.org/api-models bumped from 0.10.1-next.0 to 0.10.1-next.1
|
|
61
|
+
* @twin.org/api-processors bumped from 0.10.1-next.0 to 0.10.1-next.1
|
|
62
|
+
|
|
63
|
+
## [0.10.0](https://github.com/iotaledger/twin-api/compare/api-server-fastify-v0.10.0...api-server-fastify-v0.10.0) (2026-09-16)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Features
|
|
67
|
+
|
|
68
|
+
* release to production ([70ee2d5](https://github.com/iotaledger/twin-api/commit/70ee2d56a1dc9537d7c9c154d4cb78a235678a3a))
|
|
69
|
+
* release to production ([#195](https://github.com/iotaledger/twin-api/issues/195)) ([a3f5c1f](https://github.com/iotaledger/twin-api/commit/a3f5c1fc35a748762af7efa4f7f95776004d1309))
|
|
70
|
+
* release to production ([#197](https://github.com/iotaledger/twin-api/issues/197)) ([f04c156](https://github.com/iotaledger/twin-api/commit/f04c1567f801cde36c5ec8595f9b9369109d9e42))
|
|
71
|
+
* release to production ([#201](https://github.com/iotaledger/twin-api/issues/201)) ([e1c46fd](https://github.com/iotaledger/twin-api/commit/e1c46fd02c1f4d44d5393e2f49a24f1e4468f240))
|
|
72
|
+
* release to production ([#224](https://github.com/iotaledger/twin-api/issues/224)) ([dffaf08](https://github.com/iotaledger/twin-api/commit/dffaf082b7dccc6f57a5b7cd20b95d24bb8ec2f3))
|
|
73
|
+
* release to production ([#273](https://github.com/iotaledger/twin-api/issues/273)) ([618f07e](https://github.com/iotaledger/twin-api/commit/618f07e3c999af1d93fb1eb6164db7c5f91adf9e))
|
|
74
|
+
* release to production ([#294](https://github.com/iotaledger/twin-api/issues/294)) ([4332032](https://github.com/iotaledger/twin-api/commit/43320322ae4f1548419a3192f3f484b7c80e8142))
|
|
75
|
+
* release to production [skip ci] ([#299](https://github.com/iotaledger/twin-api/issues/299)) ([a3b657b](https://github.com/iotaledger/twin-api/commit/a3b657b40e94f9fef98f1e0dba273aba670b63d0))
|
|
76
|
+
|
|
3
77
|
## [0.9.3](https://github.com/iotaledger/twin-api/compare/api-server-fastify-v0.9.3...api-server-fastify-v0.9.3) (2026-09-14)
|
|
4
78
|
|
|
5
79
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/api-server-fastify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1-next.1",
|
|
4
4
|
"description": "Fastify web server integration for exposing API routes with consistent runtime behaviour.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@fastify/compress": "9.1.1",
|
|
18
18
|
"@fastify/cors": "11.3.0",
|
|
19
|
-
"@twin.org/api-core": "
|
|
20
|
-
"@twin.org/api-models": "
|
|
21
|
-
"@twin.org/api-processors": "
|
|
22
|
-
"@twin.org/context": "
|
|
23
|
-
"@twin.org/core": "
|
|
24
|
-
"@twin.org/logging-models": "
|
|
25
|
-
"@twin.org/nameof": "
|
|
26
|
-
"@twin.org/web": "
|
|
19
|
+
"@twin.org/api-core": "0.10.1-next.1",
|
|
20
|
+
"@twin.org/api-models": "0.10.1-next.1",
|
|
21
|
+
"@twin.org/api-processors": "0.10.1-next.1",
|
|
22
|
+
"@twin.org/context": "next",
|
|
23
|
+
"@twin.org/core": "next",
|
|
24
|
+
"@twin.org/logging-models": "next",
|
|
25
|
+
"@twin.org/nameof": "next",
|
|
26
|
+
"@twin.org/web": "next",
|
|
27
27
|
"fastify": "5.11.2",
|
|
28
28
|
"fastify-plugin": "6.0.0",
|
|
29
29
|
"socket.io": "4.8.3"
|