@twin.org/api-server-fastify 0.0.2-next.1 → 0.0.2-next.11

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.
@@ -5,7 +5,6 @@ var FastifyCors = require('@fastify/cors');
5
5
  var apiModels = require('@twin.org/api-models');
6
6
  var apiProcessors = require('@twin.org/api-processors');
7
7
  var core = require('@twin.org/core');
8
- var loggingModels = require('@twin.org/logging-models');
9
8
  var web = require('@twin.org/web');
10
9
  var Fastify = require('fastify');
11
10
  var fp = require('fastify-plugin');
@@ -28,11 +27,6 @@ const fastifySocketIO = fp(async (fastify, opts) => {
28
27
  * Implementation of the web server using Fastify.
29
28
  */
30
29
  class FastifyWebServer {
31
- /**
32
- * Runtime name for the class in camel case.
33
- * @internal
34
- */
35
- static _CLASS_NAME_CAMEL_CASE = core.StringHelper.camelCase("FastifyWebServer");
36
30
  /**
37
31
  * Default port for running the server.
38
32
  * @internal
@@ -48,10 +42,15 @@ class FastifyWebServer {
48
42
  */
49
43
  CLASS_NAME = "FastifyWebServer";
50
44
  /**
51
- * The logging connector.
45
+ * The logging component type.
52
46
  * @internal
53
47
  */
54
- _loggingConnector;
48
+ _loggingComponentType;
49
+ /**
50
+ * The logging component.
51
+ * @internal
52
+ */
53
+ _logging;
55
54
  /**
56
55
  * The options for the server.
57
56
  * @internal
@@ -87,12 +86,15 @@ class FastifyWebServer {
87
86
  * @param options The options for the server.
88
87
  */
89
88
  constructor(options) {
90
- this._loggingConnector = core.Is.stringValue(options?.loggingConnectorType)
91
- ? loggingModels.LoggingConnectorFactory.get(options.loggingConnectorType)
92
- : undefined;
89
+ this._loggingComponentType = options?.loggingComponentType;
90
+ this._logging = core.ComponentFactory.getIfExists(options?.loggingComponentType ?? "logging");
93
91
  this._fastify = Fastify({
94
- maxParamLength: 2000,
92
+ routerOptions: {
93
+ maxParamLength: 2000
94
+ },
95
95
  ...options?.config?.web
96
+ // Need this cast for now as maxParamLength has moved in to routerOptions
97
+ // but the TS defs has not been updated yet
96
98
  });
97
99
  this._socketConfig = {
98
100
  path: "/socket",
@@ -129,11 +131,11 @@ class FastifyWebServer {
129
131
  if (core.Is.arrayValue(socketRoutes) && !core.Is.arrayValue(socketRouteProcessors)) {
130
132
  throw new core.GeneralError(this.CLASS_NAME, "noSocketProcessors");
131
133
  }
132
- await this._loggingConnector?.log({
134
+ await this._logging?.log({
133
135
  level: "info",
134
136
  ts: Date.now(),
135
137
  source: this.CLASS_NAME,
136
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.building`
138
+ message: `${"fastifyWebServer"}.building`
137
139
  });
138
140
  this._options = options;
139
141
  await this._fastify.register(FastifyCompress);
@@ -174,11 +176,11 @@ class FastifyWebServer {
174
176
  err = errorAndCode.error;
175
177
  httpStatusCode = errorAndCode.httpStatusCode;
176
178
  }
177
- await this._loggingConnector?.log({
179
+ await this._logging?.log({
178
180
  level: "error",
179
181
  ts: Date.now(),
180
182
  source: this.CLASS_NAME,
181
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.badRequest`,
183
+ message: `${"fastifyWebServer"}.badRequest`,
182
184
  error: err
183
185
  });
184
186
  return reply.status(httpStatusCode).send({
@@ -195,11 +197,11 @@ class FastifyWebServer {
195
197
  async start() {
196
198
  const host = this._options?.host ?? FastifyWebServer._DEFAULT_HOST;
197
199
  const port = this._options?.port ?? FastifyWebServer._DEFAULT_PORT;
198
- await this._loggingConnector?.log({
200
+ await this._logging?.log({
199
201
  level: "info",
200
202
  ts: Date.now(),
201
203
  source: this.CLASS_NAME,
202
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.starting`,
204
+ message: `${"fastifyWebServer"}.starting`,
203
205
  data: {
204
206
  host,
205
207
  port
@@ -210,11 +212,11 @@ class FastifyWebServer {
210
212
  await this._fastify.listen({ port, host });
211
213
  const addresses = this._fastify.addresses();
212
214
  const protocol = core.Is.object(this._fastify.initialConfig.https) ? "https://" : "http://";
213
- await this._loggingConnector?.log({
215
+ await this._logging?.log({
214
216
  level: "info",
215
217
  ts: Date.now(),
216
218
  source: this.CLASS_NAME,
217
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.started`,
219
+ message: `${"fastifyWebServer"}.started`,
218
220
  data: {
219
221
  addresses: addresses
220
222
  .map(a => `${protocol}${a.family === "IPv6" ? "[" : ""}${a.address}${a.family === "IPv6" ? "]" : ""}:${a.port}`)
@@ -224,11 +226,11 @@ class FastifyWebServer {
224
226
  this._started = true;
225
227
  }
226
228
  catch (err) {
227
- await this._loggingConnector?.log({
229
+ await this._logging?.log({
228
230
  level: "error",
229
231
  ts: Date.now(),
230
232
  source: this.CLASS_NAME,
231
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.startFailed`,
233
+ message: `${"fastifyWebServer"}.startFailed`,
232
234
  error: core.BaseError.fromError(err)
233
235
  });
234
236
  }
@@ -242,11 +244,11 @@ class FastifyWebServer {
242
244
  if (this._started) {
243
245
  this._started = false;
244
246
  await this._fastify.close();
245
- await this._loggingConnector?.log({
247
+ await this._logging?.log({
246
248
  level: "info",
247
249
  ts: Date.now(),
248
250
  source: this.CLASS_NAME,
249
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.stopped`
251
+ message: `${"fastifyWebServer"}.stopped`
250
252
  });
251
253
  }
252
254
  }
@@ -263,11 +265,11 @@ class FastifyWebServer {
263
265
  if (!path.startsWith("/")) {
264
266
  path = `/${path}`;
265
267
  }
266
- await this._loggingConnector?.log({
268
+ await this._logging?.log({
267
269
  level: "info",
268
270
  ts: Date.now(),
269
271
  source: this.CLASS_NAME,
270
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.restRouteAdded`,
272
+ message: `${"fastifyWebServer"}.restRouteAdded`,
271
273
  data: { route: path, method: restRoute.method }
272
274
  });
273
275
  const method = restRoute.method.toLowerCase();
@@ -288,30 +290,33 @@ class FastifyWebServer {
288
290
  for (const socketRoute of socketRoutes) {
289
291
  const path = core.StringHelper.trimLeadingSlashes(core.StringHelper.trimTrailingSlashes(socketRoute.path));
290
292
  const pathParts = path.split("/");
291
- await this._loggingConnector?.log({
293
+ const namespace = `/${pathParts[0]}`;
294
+ const topic = pathParts.slice(1).join("/");
295
+ await this._logging?.log({
292
296
  level: "info",
293
297
  ts: Date.now(),
294
298
  source: this.CLASS_NAME,
295
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.socketRouteAdded`,
296
- data: { route: `/${path}` }
299
+ message: `${"fastifyWebServer"}.socketRouteAdded`,
300
+ data: {
301
+ handshakePath: this._socketConfig.path,
302
+ namespace,
303
+ eventName: topic
304
+ }
297
305
  });
298
- const socketNamespace = io.of(`/${pathParts[0]}`);
299
- const topic = pathParts.slice(1).join("/");
306
+ const socketNamespace = io.of(namespace);
300
307
  socketNamespace.on("connection", async (socket) => {
301
- const httpServerRequest = {
308
+ const socketServerRequest = {
302
309
  method: web.HttpMethod.GET,
303
310
  url: socket.handshake.url,
304
311
  query: socket.handshake.query,
305
- headers: socket.handshake.headers
312
+ headers: socket.handshake.headers,
313
+ socketId: socket.id
306
314
  };
307
315
  // Pass the connected information on to any processors
308
316
  try {
309
- const processorState = {
310
- socketId: socket.id
311
- };
312
317
  for (const socketRouteProcessor of socketRouteProcessors) {
313
- if (core.Is.function(socketRouteProcessor.connected)) {
314
- await socketRouteProcessor.connected(httpServerRequest, socketRoute, processorState);
318
+ if (socketRouteProcessor.connected) {
319
+ await socketRouteProcessor.connected(socketServerRequest, socketRoute, this._loggingComponentType);
315
320
  }
316
321
  }
317
322
  }
@@ -323,13 +328,10 @@ class FastifyWebServer {
323
328
  }
324
329
  socket.on("disconnect", async () => {
325
330
  try {
326
- const processorState = {
327
- socketId: socket.id
328
- };
329
331
  // The socket disconnected so notify any processors
330
332
  for (const socketRouteProcessor of socketRouteProcessors) {
331
- if (core.Is.function(socketRouteProcessor.disconnected)) {
332
- await socketRouteProcessor.disconnected(httpServerRequest, socketRoute, processorState);
333
+ if (socketRouteProcessor.disconnected) {
334
+ await socketRouteProcessor.disconnected(socketServerRequest, socketRoute, this._loggingComponentType);
333
335
  }
334
336
  }
335
337
  }
@@ -386,19 +388,20 @@ class FastifyWebServer {
386
388
  */
387
389
  async runProcessorsRest(restRouteProcessors, restRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState) {
388
390
  try {
389
- for (const routeProcessor of restRouteProcessors) {
390
- if (core.Is.function(routeProcessor.pre)) {
391
- await routeProcessor.pre(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
391
+ const filteredProcessors = this.filterRouteProcessors(restRoute, restRouteProcessors);
392
+ for (const routeProcessor of filteredProcessors) {
393
+ if (routeProcessor.pre) {
394
+ await routeProcessor.pre(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
392
395
  }
393
396
  }
394
- for (const routeProcessor of restRouteProcessors) {
395
- if (core.Is.function(routeProcessor.process)) {
396
- await routeProcessor.process(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
397
+ for (const routeProcessor of filteredProcessors) {
398
+ if (routeProcessor.process) {
399
+ await routeProcessor.process(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
397
400
  }
398
401
  }
399
- for (const routeProcessor of restRouteProcessors) {
400
- if (core.Is.function(routeProcessor.post)) {
401
- await routeProcessor.post(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
402
+ for (const routeProcessor of filteredProcessors) {
403
+ if (routeProcessor.post) {
404
+ await routeProcessor.post(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
402
405
  }
403
406
  }
404
407
  }
@@ -407,6 +410,33 @@ class FastifyWebServer {
407
410
  apiModels.HttpErrorHelper.buildResponse(httpResponse, error, httpStatusCode);
408
411
  }
409
412
  }
413
+ /**
414
+ * Filter the route processors based on the requested features.
415
+ * @param route The route to process.
416
+ * @param routeProcessors The processors to filter.
417
+ * @returns The filtered list of route processor.
418
+ * @internal
419
+ */
420
+ filterRouteProcessors(route, routeProcessors) {
421
+ const requestedFeatures = route?.processorFeatures ?? [];
422
+ if (!core.Is.arrayValue(requestedFeatures)) {
423
+ // If there are no requested features, we just return all the processors
424
+ return routeProcessors;
425
+ }
426
+ // Reduce the list of route processors to just those in the requested features list
427
+ const reducedProcessors = routeProcessors.filter(routeProcessor => {
428
+ // Processors that do not define any features always get run
429
+ // If the route processor has features defined, then we only run it
430
+ // if the route has at least one of those features required
431
+ let runRouteProcessor = true;
432
+ if (routeProcessor.features) {
433
+ const routeProcessorFeatures = routeProcessor.features();
434
+ runRouteProcessor = routeProcessorFeatures.some(feature => requestedFeatures.includes(feature));
435
+ }
436
+ return runRouteProcessor;
437
+ });
438
+ return reducedProcessors;
439
+ }
410
440
  /**
411
441
  * Handle the incoming socket request.
412
442
  * @param socketRouteProcessors The hooks to process the incoming requests.
@@ -418,53 +448,54 @@ class FastifyWebServer {
418
448
  * @internal
419
449
  */
420
450
  async handleRequestSocket(socketRouteProcessors, socketRoute, socket, fullPath, emitTopic, request) {
421
- const httpServerRequest = {
451
+ const socketServerRequest = {
422
452
  method: web.HttpMethod.GET,
423
453
  url: fullPath,
424
454
  query: socket.handshake.query,
425
455
  headers: socket.handshake.headers,
426
- body: request.body
456
+ body: request.body,
457
+ socketId: socket.id
427
458
  };
428
459
  const httpResponse = {};
429
460
  const httpRequestIdentity = {};
430
- const processorState = {
431
- socketId: socket.id
432
- };
433
- delete httpServerRequest.query?.EIO;
434
- delete httpServerRequest.query?.transport;
435
- await this.runProcessorsSocket(socketRouteProcessors, socketRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState, emitTopic, async (topic, response) => {
461
+ const processorState = {};
462
+ delete socketServerRequest.query?.EIO;
463
+ delete socketServerRequest.query?.transport;
464
+ await this.runProcessorsSocket(socketRouteProcessors, socketRoute, socketServerRequest, httpResponse, httpRequestIdentity, processorState, emitTopic, async (topic, response) => {
436
465
  await socket.emit(topic, response);
437
466
  });
438
467
  }
439
468
  /**
440
469
  * Run the socket processors for the route.
470
+ * @param socketId The id of the socket.
441
471
  * @param socketRouteProcessors The processors to run.
442
472
  * @param socketRoute The route to process.
443
- * @param httpServerRequest The incoming request.
473
+ * @param socketServerRequest The incoming request.
444
474
  * @param httpResponse The outgoing response.
445
475
  * @param httpRequestIdentity The identity context for the request.
446
476
  * @param processorState The state handed through the processors.
447
477
  * @param requestTopic The topic of the request.
448
478
  * @internal
449
479
  */
450
- async runProcessorsSocket(socketRouteProcessors, socketRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState, requestTopic, responseEmitter) {
480
+ async runProcessorsSocket(socketRouteProcessors, socketRoute, socketServerRequest, httpResponse, httpRequestIdentity, processorState, requestTopic, responseEmitter) {
481
+ const filteredProcessors = this.filterRouteProcessors(socketRoute, socketRouteProcessors);
451
482
  // Custom emit method which will also call the post processors
452
483
  const postProcessEmit = async (topic, response, responseProcessorState) => {
453
484
  await responseEmitter(topic, response);
454
485
  try {
455
486
  // The post processors are called after the response has been emitted
456
- for (const postSocketRouteProcessor of socketRouteProcessors) {
457
- if (core.Is.function(postSocketRouteProcessor.post)) {
458
- await postSocketRouteProcessor.post(httpServerRequest, response, socketRoute, httpRequestIdentity, responseProcessorState);
487
+ for (const postSocketRouteProcessor of filteredProcessors) {
488
+ if (postSocketRouteProcessor.post) {
489
+ await postSocketRouteProcessor.post(socketServerRequest, response, socketRoute, httpRequestIdentity, responseProcessorState, this._loggingComponentType);
459
490
  }
460
491
  }
461
492
  }
462
493
  catch (err) {
463
- this._loggingConnector?.log({
494
+ this._logging?.log({
464
495
  level: "error",
465
496
  ts: Date.now(),
466
497
  source: this.CLASS_NAME,
467
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.postProcessorError`,
498
+ message: `${"fastifyWebServer"}.postProcessorError`,
468
499
  error: core.BaseError.fromError(err),
469
500
  data: {
470
501
  route: socketRoute.path
@@ -473,9 +504,9 @@ class FastifyWebServer {
473
504
  }
474
505
  };
475
506
  try {
476
- for (const socketRouteProcessor of socketRouteProcessors) {
477
- if (core.Is.function(socketRouteProcessor.pre)) {
478
- await socketRouteProcessor.pre(httpServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState);
507
+ for (const socketRouteProcessor of filteredProcessors) {
508
+ if (socketRouteProcessor.pre) {
509
+ await socketRouteProcessor.pre(socketServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, this._loggingComponentType);
479
510
  }
480
511
  }
481
512
  // We always call all the processors regardless of any response set by a previous processor.
@@ -484,11 +515,11 @@ class FastifyWebServer {
484
515
  if (!core.Is.empty(httpResponse.statusCode)) {
485
516
  await postProcessEmit(requestTopic, httpResponse, processorState);
486
517
  }
487
- for (const socketRouteProcessor of socketRouteProcessors) {
488
- if (core.Is.function(socketRouteProcessor.process)) {
489
- await socketRouteProcessor.process(httpServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, async (topic, processResponse) => {
518
+ for (const socketRouteProcessor of filteredProcessors) {
519
+ if (socketRouteProcessor.process) {
520
+ await socketRouteProcessor.process(socketServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, async (topic, processResponse) => {
490
521
  await postProcessEmit(topic, processResponse, processorState);
491
- });
522
+ }, this._loggingComponentType);
492
523
  }
493
524
  }
494
525
  // If the processors set the status to any kind of error then we should emit this manually
@@ -2,8 +2,7 @@ import FastifyCompress from '@fastify/compress';
2
2
  import FastifyCors from '@fastify/cors';
3
3
  import { HttpErrorHelper } from '@twin.org/api-models';
4
4
  import { JsonLdMimeTypeProcessor } from '@twin.org/api-processors';
5
- import { StringHelper, Is, GeneralError, BaseError } from '@twin.org/core';
6
- import { LoggingConnectorFactory } from '@twin.org/logging-models';
5
+ import { ComponentFactory, Is, GeneralError, BaseError, StringHelper } from '@twin.org/core';
7
6
  import { HttpStatusCode, HttpMethod, HeaderTypes } from '@twin.org/web';
8
7
  import Fastify from 'fastify';
9
8
  import fp from 'fastify-plugin';
@@ -26,11 +25,6 @@ const fastifySocketIO = fp(async (fastify, opts) => {
26
25
  * Implementation of the web server using Fastify.
27
26
  */
28
27
  class FastifyWebServer {
29
- /**
30
- * Runtime name for the class in camel case.
31
- * @internal
32
- */
33
- static _CLASS_NAME_CAMEL_CASE = StringHelper.camelCase("FastifyWebServer");
34
28
  /**
35
29
  * Default port for running the server.
36
30
  * @internal
@@ -46,10 +40,15 @@ class FastifyWebServer {
46
40
  */
47
41
  CLASS_NAME = "FastifyWebServer";
48
42
  /**
49
- * The logging connector.
43
+ * The logging component type.
50
44
  * @internal
51
45
  */
52
- _loggingConnector;
46
+ _loggingComponentType;
47
+ /**
48
+ * The logging component.
49
+ * @internal
50
+ */
51
+ _logging;
53
52
  /**
54
53
  * The options for the server.
55
54
  * @internal
@@ -85,12 +84,15 @@ class FastifyWebServer {
85
84
  * @param options The options for the server.
86
85
  */
87
86
  constructor(options) {
88
- this._loggingConnector = Is.stringValue(options?.loggingConnectorType)
89
- ? LoggingConnectorFactory.get(options.loggingConnectorType)
90
- : undefined;
87
+ this._loggingComponentType = options?.loggingComponentType;
88
+ this._logging = ComponentFactory.getIfExists(options?.loggingComponentType ?? "logging");
91
89
  this._fastify = Fastify({
92
- maxParamLength: 2000,
90
+ routerOptions: {
91
+ maxParamLength: 2000
92
+ },
93
93
  ...options?.config?.web
94
+ // Need this cast for now as maxParamLength has moved in to routerOptions
95
+ // but the TS defs has not been updated yet
94
96
  });
95
97
  this._socketConfig = {
96
98
  path: "/socket",
@@ -127,11 +129,11 @@ class FastifyWebServer {
127
129
  if (Is.arrayValue(socketRoutes) && !Is.arrayValue(socketRouteProcessors)) {
128
130
  throw new GeneralError(this.CLASS_NAME, "noSocketProcessors");
129
131
  }
130
- await this._loggingConnector?.log({
132
+ await this._logging?.log({
131
133
  level: "info",
132
134
  ts: Date.now(),
133
135
  source: this.CLASS_NAME,
134
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.building`
136
+ message: `${"fastifyWebServer"}.building`
135
137
  });
136
138
  this._options = options;
137
139
  await this._fastify.register(FastifyCompress);
@@ -172,11 +174,11 @@ class FastifyWebServer {
172
174
  err = errorAndCode.error;
173
175
  httpStatusCode = errorAndCode.httpStatusCode;
174
176
  }
175
- await this._loggingConnector?.log({
177
+ await this._logging?.log({
176
178
  level: "error",
177
179
  ts: Date.now(),
178
180
  source: this.CLASS_NAME,
179
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.badRequest`,
181
+ message: `${"fastifyWebServer"}.badRequest`,
180
182
  error: err
181
183
  });
182
184
  return reply.status(httpStatusCode).send({
@@ -193,11 +195,11 @@ class FastifyWebServer {
193
195
  async start() {
194
196
  const host = this._options?.host ?? FastifyWebServer._DEFAULT_HOST;
195
197
  const port = this._options?.port ?? FastifyWebServer._DEFAULT_PORT;
196
- await this._loggingConnector?.log({
198
+ await this._logging?.log({
197
199
  level: "info",
198
200
  ts: Date.now(),
199
201
  source: this.CLASS_NAME,
200
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.starting`,
202
+ message: `${"fastifyWebServer"}.starting`,
201
203
  data: {
202
204
  host,
203
205
  port
@@ -208,11 +210,11 @@ class FastifyWebServer {
208
210
  await this._fastify.listen({ port, host });
209
211
  const addresses = this._fastify.addresses();
210
212
  const protocol = Is.object(this._fastify.initialConfig.https) ? "https://" : "http://";
211
- await this._loggingConnector?.log({
213
+ await this._logging?.log({
212
214
  level: "info",
213
215
  ts: Date.now(),
214
216
  source: this.CLASS_NAME,
215
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.started`,
217
+ message: `${"fastifyWebServer"}.started`,
216
218
  data: {
217
219
  addresses: addresses
218
220
  .map(a => `${protocol}${a.family === "IPv6" ? "[" : ""}${a.address}${a.family === "IPv6" ? "]" : ""}:${a.port}`)
@@ -222,11 +224,11 @@ class FastifyWebServer {
222
224
  this._started = true;
223
225
  }
224
226
  catch (err) {
225
- await this._loggingConnector?.log({
227
+ await this._logging?.log({
226
228
  level: "error",
227
229
  ts: Date.now(),
228
230
  source: this.CLASS_NAME,
229
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.startFailed`,
231
+ message: `${"fastifyWebServer"}.startFailed`,
230
232
  error: BaseError.fromError(err)
231
233
  });
232
234
  }
@@ -240,11 +242,11 @@ class FastifyWebServer {
240
242
  if (this._started) {
241
243
  this._started = false;
242
244
  await this._fastify.close();
243
- await this._loggingConnector?.log({
245
+ await this._logging?.log({
244
246
  level: "info",
245
247
  ts: Date.now(),
246
248
  source: this.CLASS_NAME,
247
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.stopped`
249
+ message: `${"fastifyWebServer"}.stopped`
248
250
  });
249
251
  }
250
252
  }
@@ -261,11 +263,11 @@ class FastifyWebServer {
261
263
  if (!path.startsWith("/")) {
262
264
  path = `/${path}`;
263
265
  }
264
- await this._loggingConnector?.log({
266
+ await this._logging?.log({
265
267
  level: "info",
266
268
  ts: Date.now(),
267
269
  source: this.CLASS_NAME,
268
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.restRouteAdded`,
270
+ message: `${"fastifyWebServer"}.restRouteAdded`,
269
271
  data: { route: path, method: restRoute.method }
270
272
  });
271
273
  const method = restRoute.method.toLowerCase();
@@ -286,30 +288,33 @@ class FastifyWebServer {
286
288
  for (const socketRoute of socketRoutes) {
287
289
  const path = StringHelper.trimLeadingSlashes(StringHelper.trimTrailingSlashes(socketRoute.path));
288
290
  const pathParts = path.split("/");
289
- await this._loggingConnector?.log({
291
+ const namespace = `/${pathParts[0]}`;
292
+ const topic = pathParts.slice(1).join("/");
293
+ await this._logging?.log({
290
294
  level: "info",
291
295
  ts: Date.now(),
292
296
  source: this.CLASS_NAME,
293
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.socketRouteAdded`,
294
- data: { route: `/${path}` }
297
+ message: `${"fastifyWebServer"}.socketRouteAdded`,
298
+ data: {
299
+ handshakePath: this._socketConfig.path,
300
+ namespace,
301
+ eventName: topic
302
+ }
295
303
  });
296
- const socketNamespace = io.of(`/${pathParts[0]}`);
297
- const topic = pathParts.slice(1).join("/");
304
+ const socketNamespace = io.of(namespace);
298
305
  socketNamespace.on("connection", async (socket) => {
299
- const httpServerRequest = {
306
+ const socketServerRequest = {
300
307
  method: HttpMethod.GET,
301
308
  url: socket.handshake.url,
302
309
  query: socket.handshake.query,
303
- headers: socket.handshake.headers
310
+ headers: socket.handshake.headers,
311
+ socketId: socket.id
304
312
  };
305
313
  // Pass the connected information on to any processors
306
314
  try {
307
- const processorState = {
308
- socketId: socket.id
309
- };
310
315
  for (const socketRouteProcessor of socketRouteProcessors) {
311
- if (Is.function(socketRouteProcessor.connected)) {
312
- await socketRouteProcessor.connected(httpServerRequest, socketRoute, processorState);
316
+ if (socketRouteProcessor.connected) {
317
+ await socketRouteProcessor.connected(socketServerRequest, socketRoute, this._loggingComponentType);
313
318
  }
314
319
  }
315
320
  }
@@ -321,13 +326,10 @@ class FastifyWebServer {
321
326
  }
322
327
  socket.on("disconnect", async () => {
323
328
  try {
324
- const processorState = {
325
- socketId: socket.id
326
- };
327
329
  // The socket disconnected so notify any processors
328
330
  for (const socketRouteProcessor of socketRouteProcessors) {
329
- if (Is.function(socketRouteProcessor.disconnected)) {
330
- await socketRouteProcessor.disconnected(httpServerRequest, socketRoute, processorState);
331
+ if (socketRouteProcessor.disconnected) {
332
+ await socketRouteProcessor.disconnected(socketServerRequest, socketRoute, this._loggingComponentType);
331
333
  }
332
334
  }
333
335
  }
@@ -384,19 +386,20 @@ class FastifyWebServer {
384
386
  */
385
387
  async runProcessorsRest(restRouteProcessors, restRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState) {
386
388
  try {
387
- for (const routeProcessor of restRouteProcessors) {
388
- if (Is.function(routeProcessor.pre)) {
389
- await routeProcessor.pre(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
389
+ const filteredProcessors = this.filterRouteProcessors(restRoute, restRouteProcessors);
390
+ for (const routeProcessor of filteredProcessors) {
391
+ if (routeProcessor.pre) {
392
+ await routeProcessor.pre(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
390
393
  }
391
394
  }
392
- for (const routeProcessor of restRouteProcessors) {
393
- if (Is.function(routeProcessor.process)) {
394
- await routeProcessor.process(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
395
+ for (const routeProcessor of filteredProcessors) {
396
+ if (routeProcessor.process) {
397
+ await routeProcessor.process(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
395
398
  }
396
399
  }
397
- for (const routeProcessor of restRouteProcessors) {
398
- if (Is.function(routeProcessor.post)) {
399
- await routeProcessor.post(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState);
400
+ for (const routeProcessor of filteredProcessors) {
401
+ if (routeProcessor.post) {
402
+ await routeProcessor.post(httpServerRequest, httpResponse, restRoute, httpRequestIdentity, processorState, this._loggingComponentType);
400
403
  }
401
404
  }
402
405
  }
@@ -405,6 +408,33 @@ class FastifyWebServer {
405
408
  HttpErrorHelper.buildResponse(httpResponse, error, httpStatusCode);
406
409
  }
407
410
  }
411
+ /**
412
+ * Filter the route processors based on the requested features.
413
+ * @param route The route to process.
414
+ * @param routeProcessors The processors to filter.
415
+ * @returns The filtered list of route processor.
416
+ * @internal
417
+ */
418
+ filterRouteProcessors(route, routeProcessors) {
419
+ const requestedFeatures = route?.processorFeatures ?? [];
420
+ if (!Is.arrayValue(requestedFeatures)) {
421
+ // If there are no requested features, we just return all the processors
422
+ return routeProcessors;
423
+ }
424
+ // Reduce the list of route processors to just those in the requested features list
425
+ const reducedProcessors = routeProcessors.filter(routeProcessor => {
426
+ // Processors that do not define any features always get run
427
+ // If the route processor has features defined, then we only run it
428
+ // if the route has at least one of those features required
429
+ let runRouteProcessor = true;
430
+ if (routeProcessor.features) {
431
+ const routeProcessorFeatures = routeProcessor.features();
432
+ runRouteProcessor = routeProcessorFeatures.some(feature => requestedFeatures.includes(feature));
433
+ }
434
+ return runRouteProcessor;
435
+ });
436
+ return reducedProcessors;
437
+ }
408
438
  /**
409
439
  * Handle the incoming socket request.
410
440
  * @param socketRouteProcessors The hooks to process the incoming requests.
@@ -416,53 +446,54 @@ class FastifyWebServer {
416
446
  * @internal
417
447
  */
418
448
  async handleRequestSocket(socketRouteProcessors, socketRoute, socket, fullPath, emitTopic, request) {
419
- const httpServerRequest = {
449
+ const socketServerRequest = {
420
450
  method: HttpMethod.GET,
421
451
  url: fullPath,
422
452
  query: socket.handshake.query,
423
453
  headers: socket.handshake.headers,
424
- body: request.body
454
+ body: request.body,
455
+ socketId: socket.id
425
456
  };
426
457
  const httpResponse = {};
427
458
  const httpRequestIdentity = {};
428
- const processorState = {
429
- socketId: socket.id
430
- };
431
- delete httpServerRequest.query?.EIO;
432
- delete httpServerRequest.query?.transport;
433
- await this.runProcessorsSocket(socketRouteProcessors, socketRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState, emitTopic, async (topic, response) => {
459
+ const processorState = {};
460
+ delete socketServerRequest.query?.EIO;
461
+ delete socketServerRequest.query?.transport;
462
+ await this.runProcessorsSocket(socketRouteProcessors, socketRoute, socketServerRequest, httpResponse, httpRequestIdentity, processorState, emitTopic, async (topic, response) => {
434
463
  await socket.emit(topic, response);
435
464
  });
436
465
  }
437
466
  /**
438
467
  * Run the socket processors for the route.
468
+ * @param socketId The id of the socket.
439
469
  * @param socketRouteProcessors The processors to run.
440
470
  * @param socketRoute The route to process.
441
- * @param httpServerRequest The incoming request.
471
+ * @param socketServerRequest The incoming request.
442
472
  * @param httpResponse The outgoing response.
443
473
  * @param httpRequestIdentity The identity context for the request.
444
474
  * @param processorState The state handed through the processors.
445
475
  * @param requestTopic The topic of the request.
446
476
  * @internal
447
477
  */
448
- async runProcessorsSocket(socketRouteProcessors, socketRoute, httpServerRequest, httpResponse, httpRequestIdentity, processorState, requestTopic, responseEmitter) {
478
+ async runProcessorsSocket(socketRouteProcessors, socketRoute, socketServerRequest, httpResponse, httpRequestIdentity, processorState, requestTopic, responseEmitter) {
479
+ const filteredProcessors = this.filterRouteProcessors(socketRoute, socketRouteProcessors);
449
480
  // Custom emit method which will also call the post processors
450
481
  const postProcessEmit = async (topic, response, responseProcessorState) => {
451
482
  await responseEmitter(topic, response);
452
483
  try {
453
484
  // The post processors are called after the response has been emitted
454
- for (const postSocketRouteProcessor of socketRouteProcessors) {
455
- if (Is.function(postSocketRouteProcessor.post)) {
456
- await postSocketRouteProcessor.post(httpServerRequest, response, socketRoute, httpRequestIdentity, responseProcessorState);
485
+ for (const postSocketRouteProcessor of filteredProcessors) {
486
+ if (postSocketRouteProcessor.post) {
487
+ await postSocketRouteProcessor.post(socketServerRequest, response, socketRoute, httpRequestIdentity, responseProcessorState, this._loggingComponentType);
457
488
  }
458
489
  }
459
490
  }
460
491
  catch (err) {
461
- this._loggingConnector?.log({
492
+ this._logging?.log({
462
493
  level: "error",
463
494
  ts: Date.now(),
464
495
  source: this.CLASS_NAME,
465
- message: `${FastifyWebServer._CLASS_NAME_CAMEL_CASE}.postProcessorError`,
496
+ message: `${"fastifyWebServer"}.postProcessorError`,
466
497
  error: BaseError.fromError(err),
467
498
  data: {
468
499
  route: socketRoute.path
@@ -471,9 +502,9 @@ class FastifyWebServer {
471
502
  }
472
503
  };
473
504
  try {
474
- for (const socketRouteProcessor of socketRouteProcessors) {
475
- if (Is.function(socketRouteProcessor.pre)) {
476
- await socketRouteProcessor.pre(httpServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState);
505
+ for (const socketRouteProcessor of filteredProcessors) {
506
+ if (socketRouteProcessor.pre) {
507
+ await socketRouteProcessor.pre(socketServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, this._loggingComponentType);
477
508
  }
478
509
  }
479
510
  // We always call all the processors regardless of any response set by a previous processor.
@@ -482,11 +513,11 @@ class FastifyWebServer {
482
513
  if (!Is.empty(httpResponse.statusCode)) {
483
514
  await postProcessEmit(requestTopic, httpResponse, processorState);
484
515
  }
485
- for (const socketRouteProcessor of socketRouteProcessors) {
486
- if (Is.function(socketRouteProcessor.process)) {
487
- await socketRouteProcessor.process(httpServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, async (topic, processResponse) => {
516
+ for (const socketRouteProcessor of filteredProcessors) {
517
+ if (socketRouteProcessor.process) {
518
+ await socketRouteProcessor.process(socketServerRequest, httpResponse, socketRoute, httpRequestIdentity, processorState, async (topic, processResponse) => {
488
519
  await postProcessEmit(topic, processResponse, processorState);
489
- });
520
+ }, this._loggingComponentType);
490
521
  }
491
522
  }
492
523
  // If the processors set the status to any kind of error then we should emit this manually
@@ -5,9 +5,9 @@ import type { IFastifyWebServerConfig } from "./IFastifyWebServerConfig";
5
5
  */
6
6
  export interface IFastifyWebServerConstructorOptions {
7
7
  /**
8
- * The type of the logging connector to use, if undefined, no logging will happen.
8
+ * The type of the logging component to use, if undefined, no logging will happen.
9
9
  */
10
- loggingConnectorType?: string;
10
+ loggingComponentType?: string;
11
11
  /**
12
12
  * Additional configuration for the server.
13
13
  */
package/docs/changelog.md CHANGED
@@ -1,5 +1,170 @@
1
1
  # @twin.org/api-server-fastify - Changelog
2
2
 
3
+ ## [0.0.2-next.11](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.10...api-server-fastify-v0.0.2-next.11) (2025-09-29)
4
+
5
+
6
+ ### Features
7
+
8
+ * update IComponent signatures ([915ce37](https://github.com/twinfoundation/api/commit/915ce37712326ab4aa6869c350eabaa4622e8430))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/api-core bumped from 0.0.2-next.10 to 0.0.2-next.11
16
+ * @twin.org/api-models bumped from 0.0.2-next.10 to 0.0.2-next.11
17
+ * @twin.org/api-processors bumped from 0.0.2-next.10 to 0.0.2-next.11
18
+
19
+ ## [0.0.2-next.10](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.9...api-server-fastify-v0.0.2-next.10) (2025-09-23)
20
+
21
+
22
+ ### Features
23
+
24
+ * add authentication generators and process features option ([a67edf1](https://github.com/twinfoundation/api/commit/a67edf1df212bd8ab94a40cddf5338551155696f))
25
+
26
+
27
+ ### Dependencies
28
+
29
+ * The following workspace dependencies were updated
30
+ * dependencies
31
+ * @twin.org/api-core bumped from 0.0.2-next.9 to 0.0.2-next.10
32
+ * @twin.org/api-models bumped from 0.0.2-next.9 to 0.0.2-next.10
33
+ * @twin.org/api-processors bumped from 0.0.2-next.9 to 0.0.2-next.10
34
+
35
+ ## [0.0.2-next.9](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.8...api-server-fastify-v0.0.2-next.9) (2025-08-29)
36
+
37
+
38
+ ### Features
39
+
40
+ * eslint migration to flat config ([0dd5820](https://github.com/twinfoundation/api/commit/0dd5820e3af97350fd08b8d226f4a6c1a9246805))
41
+
42
+
43
+ ### Dependencies
44
+
45
+ * The following workspace dependencies were updated
46
+ * dependencies
47
+ * @twin.org/api-core bumped from 0.0.2-next.8 to 0.0.2-next.9
48
+ * @twin.org/api-models bumped from 0.0.2-next.8 to 0.0.2-next.9
49
+ * @twin.org/api-processors bumped from 0.0.2-next.8 to 0.0.2-next.9
50
+
51
+ ## [0.0.2-next.8](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.7...api-server-fastify-v0.0.2-next.8) (2025-08-21)
52
+
53
+
54
+ ### Features
55
+
56
+ * add root, favicon routes ([71da1c3](https://github.com/twinfoundation/api/commit/71da1c3a93c349588aff7084d1d8d6a29a277da8))
57
+
58
+
59
+ ### Dependencies
60
+
61
+ * The following workspace dependencies were updated
62
+ * dependencies
63
+ * @twin.org/api-core bumped from 0.0.2-next.7 to 0.0.2-next.8
64
+ * @twin.org/api-models bumped from 0.0.2-next.7 to 0.0.2-next.8
65
+ * @twin.org/api-processors bumped from 0.0.2-next.7 to 0.0.2-next.8
66
+
67
+ ## [0.0.2-next.7](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.6...api-server-fastify-v0.0.2-next.7) (2025-08-20)
68
+
69
+
70
+ ### Features
71
+
72
+ * logging naming consistency ([a4a6ef2](https://github.com/twinfoundation/api/commit/a4a6ef2de5049045589eb78b177ff62e744bde9d))
73
+
74
+
75
+ ### Dependencies
76
+
77
+ * The following workspace dependencies were updated
78
+ * dependencies
79
+ * @twin.org/api-core bumped from 0.0.2-next.6 to 0.0.2-next.7
80
+ * @twin.org/api-models bumped from 0.0.2-next.6 to 0.0.2-next.7
81
+ * @twin.org/api-processors bumped from 0.0.2-next.6 to 0.0.2-next.7
82
+
83
+ ## [0.0.2-next.6](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.5...api-server-fastify-v0.0.2-next.6) (2025-08-19)
84
+
85
+
86
+ ### Features
87
+
88
+ * update framework core ([d8eebf2](https://github.com/twinfoundation/api/commit/d8eebf267fa2a0abaa84e58590496e9d20490cfa))
89
+
90
+
91
+ ### Dependencies
92
+
93
+ * The following workspace dependencies were updated
94
+ * dependencies
95
+ * @twin.org/api-core bumped from 0.0.2-next.5 to 0.0.2-next.6
96
+ * @twin.org/api-models bumped from 0.0.2-next.5 to 0.0.2-next.6
97
+ * @twin.org/api-processors bumped from 0.0.2-next.5 to 0.0.2-next.6
98
+
99
+ ## [0.0.2-next.5](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.4...api-server-fastify-v0.0.2-next.5) (2025-07-25)
100
+
101
+
102
+ ### Features
103
+
104
+ * add json-ld mime type processor and auth admin component ([8861791](https://github.com/twinfoundation/api/commit/88617916e23bfbca023dbae1976fe421983a02ff))
105
+ * add logging component type to request contexts ([210de1b](https://github.com/twinfoundation/api/commit/210de1b9e1c91079b59a2b90ddd57569668d647d))
106
+ * add socket id, connect and disconnect ([20b0d0e](https://github.com/twinfoundation/api/commit/20b0d0ec279cab46141fee09de2c4a7087cdce16))
107
+ * improve socket route logging ([b8d9519](https://github.com/twinfoundation/api/commit/b8d95199f838ac6ba9f45c30ef7c4e613201ff53))
108
+ * update dependencies ([1171dc4](https://github.com/twinfoundation/api/commit/1171dc416a9481737f6a640e3cf30145768f37e9))
109
+ * use shared store mechanism ([#19](https://github.com/twinfoundation/api/issues/19)) ([32116df](https://github.com/twinfoundation/api/commit/32116df3b4380a30137f5056f242a5c99afa2df9))
110
+
111
+
112
+ ### Dependencies
113
+
114
+ * The following workspace dependencies were updated
115
+ * dependencies
116
+ * @twin.org/api-core bumped from 0.0.2-next.4 to 0.0.2-next.5
117
+ * @twin.org/api-models bumped from 0.0.2-next.4 to 0.0.2-next.5
118
+ * @twin.org/api-processors bumped from 0.0.2-next.4 to 0.0.2-next.5
119
+
120
+ ## [0.0.2-next.4](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.3...api-server-fastify-v0.0.2-next.4) (2025-07-25)
121
+
122
+
123
+ ### Features
124
+
125
+ * add logging component type to request contexts ([210de1b](https://github.com/twinfoundation/api/commit/210de1b9e1c91079b59a2b90ddd57569668d647d))
126
+
127
+
128
+ ### Dependencies
129
+
130
+ * The following workspace dependencies were updated
131
+ * dependencies
132
+ * @twin.org/api-core bumped from 0.0.2-next.3 to 0.0.2-next.4
133
+ * @twin.org/api-models bumped from 0.0.2-next.3 to 0.0.2-next.4
134
+ * @twin.org/api-processors bumped from 0.0.2-next.3 to 0.0.2-next.4
135
+
136
+ ## [0.0.2-next.3](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.2...api-server-fastify-v0.0.2-next.3) (2025-07-24)
137
+
138
+
139
+ ### Features
140
+
141
+ * add socket id, connect and disconnect ([20b0d0e](https://github.com/twinfoundation/api/commit/20b0d0ec279cab46141fee09de2c4a7087cdce16))
142
+
143
+
144
+ ### Dependencies
145
+
146
+ * The following workspace dependencies were updated
147
+ * dependencies
148
+ * @twin.org/api-core bumped from 0.0.2-next.2 to 0.0.2-next.3
149
+ * @twin.org/api-models bumped from 0.0.2-next.2 to 0.0.2-next.3
150
+ * @twin.org/api-processors bumped from 0.0.2-next.2 to 0.0.2-next.3
151
+
152
+ ## [0.0.2-next.2](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.1...api-server-fastify-v0.0.2-next.2) (2025-07-17)
153
+
154
+
155
+ ### Features
156
+
157
+ * improve socket route logging ([b8d9519](https://github.com/twinfoundation/api/commit/b8d95199f838ac6ba9f45c30ef7c4e613201ff53))
158
+
159
+
160
+ ### Dependencies
161
+
162
+ * The following workspace dependencies were updated
163
+ * dependencies
164
+ * @twin.org/api-core bumped from 0.0.2-next.1 to 0.0.2-next.2
165
+ * @twin.org/api-models bumped from 0.0.2-next.1 to 0.0.2-next.2
166
+ * @twin.org/api-processors bumped from 0.0.2-next.1 to 0.0.2-next.2
167
+
3
168
  ## [0.0.2-next.1](https://github.com/twinfoundation/api/compare/api-server-fastify-v0.0.2-next.0...api-server-fastify-v0.0.2-next.1) (2025-07-08)
4
169
 
5
170
 
@@ -4,11 +4,11 @@ The options for the Fastify web server constructor.
4
4
 
5
5
  ## Properties
6
6
 
7
- ### loggingConnectorType?
7
+ ### loggingComponentType?
8
8
 
9
- > `optional` **loggingConnectorType**: `string`
9
+ > `optional` **loggingComponentType**: `string`
10
10
 
11
- The type of the logging connector to use, if undefined, no logging will happen.
11
+ The type of the logging component to use, if undefined, no logging will happen.
12
12
 
13
13
  ***
14
14
 
package/locales/en.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "stopped": "The Web Server was stopped",
8
8
  "badRequest": "The web server could not handle the request",
9
9
  "restRouteAdded": "Added REST route \"{route}\" \"{method}\"",
10
- "socketRouteAdded": "Added socket route \"{route}\"",
10
+ "socketRouteAdded": "Added socket route: handshake path \"{handshakePath}\", namespace \"{namespace}\", event name \"{eventName}\"",
11
11
  "noRestProcessors": "You must configure at least one REST processor",
12
12
  "noSocketProcessors": "You must configure at least one socket processor",
13
13
  "postProcessorError": "There was a failure after in a post processor for route \"{route}\""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/api-server-fastify",
3
- "version": "0.0.2-next.1",
3
+ "version": "0.0.2-next.11",
4
4
  "description": "Use Fastify as the core web server for APIs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,16 +14,16 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@fastify/compress": "8.0.3",
18
- "@fastify/cors": "11.0.1",
19
- "@twin.org/api-core": "0.0.2-next.1",
20
- "@twin.org/api-models": "0.0.2-next.1",
21
- "@twin.org/api-processors": "0.0.2-next.1",
17
+ "@fastify/compress": "8.1.0",
18
+ "@fastify/cors": "11.1.0",
19
+ "@twin.org/api-core": "0.0.2-next.11",
20
+ "@twin.org/api-models": "0.0.2-next.11",
21
+ "@twin.org/api-processors": "0.0.2-next.11",
22
22
  "@twin.org/core": "next",
23
23
  "@twin.org/logging-models": "next",
24
24
  "@twin.org/nameof": "next",
25
25
  "@twin.org/web": "next",
26
- "fastify": "5.3.3",
26
+ "fastify": "5.6.1",
27
27
  "socket.io": "4.8.1"
28
28
  },
29
29
  "main": "./dist/cjs/index.cjs",