@scpxl/nodejs-framework 1.0.30 → 1.0.42

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.
Files changed (56) hide show
  1. package/README.md +1 -0
  2. package/dist/application/base-application.d.ts +7 -7
  3. package/dist/application/base-application.d.ts.map +1 -1
  4. package/dist/application/base-application.interface.d.ts +1 -1
  5. package/dist/application/base-application.interface.d.ts.map +1 -1
  6. package/dist/application/base-application.js +122 -14
  7. package/dist/application/base-application.js.map +2 -2
  8. package/dist/application/web-application.d.ts.map +1 -1
  9. package/dist/application/web-application.js +2 -4
  10. package/dist/application/web-application.js.map +2 -2
  11. package/dist/cache/manager.d.ts +1 -0
  12. package/dist/cache/manager.d.ts.map +1 -1
  13. package/dist/cache/manager.js +11 -2
  14. package/dist/cache/manager.js.map +2 -2
  15. package/dist/cli/index.js +24 -10
  16. package/dist/cli/index.js.map +2 -2
  17. package/dist/config/schema.d.ts +2 -63
  18. package/dist/config/schema.d.ts.map +1 -1
  19. package/dist/config/schema.js +1 -7
  20. package/dist/config/schema.js.map +2 -2
  21. package/dist/event/manager.js +2 -2
  22. package/dist/event/manager.js.map +2 -2
  23. package/dist/logger/logger.js +0 -1
  24. package/dist/logger/logger.js.map +2 -2
  25. package/dist/queue/manager.d.ts.map +1 -1
  26. package/dist/queue/manager.js +19 -7
  27. package/dist/queue/manager.js.map +2 -2
  28. package/dist/redis/instance.d.ts.map +1 -1
  29. package/dist/redis/instance.js +9 -1
  30. package/dist/redis/instance.js.map +2 -2
  31. package/dist/redis/manager.d.ts.map +1 -1
  32. package/dist/redis/manager.js +26 -16
  33. package/dist/redis/manager.js.map +3 -3
  34. package/dist/webserver/controller/entity.js +1 -1
  35. package/dist/webserver/controller/entity.js.map +2 -2
  36. package/dist/webserver/controller/health.js.map +1 -1
  37. package/dist/webserver/util.d.ts +1 -1
  38. package/dist/webserver/util.d.ts.map +1 -1
  39. package/dist/webserver/util.js +5 -23
  40. package/dist/webserver/util.js.map +2 -2
  41. package/dist/webserver/webserver.d.ts +2 -13
  42. package/dist/webserver/webserver.d.ts.map +1 -1
  43. package/dist/webserver/webserver.interface.d.ts +1 -21
  44. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  45. package/dist/webserver/webserver.interface.js.map +1 -1
  46. package/dist/webserver/webserver.js +34 -36
  47. package/dist/webserver/webserver.js.map +2 -2
  48. package/dist/websocket/utils.d.ts.map +1 -1
  49. package/dist/websocket/utils.js +5 -1
  50. package/dist/websocket/utils.js.map +2 -2
  51. package/dist/websocket/websocket-base.d.ts.map +1 -1
  52. package/dist/websocket/websocket-base.js +9 -1
  53. package/dist/websocket/websocket-base.js.map +2 -2
  54. package/dist/websocket/websocket-server.d.ts.map +1 -1
  55. package/dist/websocket/websocket-server.js.map +2 -2
  56. package/package.json +5 -6
@@ -23,6 +23,7 @@ class WebServer {
23
23
  applicationConfig;
24
24
  options;
25
25
  routes;
26
+ explicitRoutesConfigured;
26
27
  redisInstance;
27
28
  queueManager;
28
29
  eventManager;
@@ -54,7 +55,9 @@ class WebServer {
54
55
  const mergedOptions = Helper.defaultsDeep(params.options, defaultOptions);
55
56
  this.applicationConfig = params.applicationConfig;
56
57
  this.options = mergedOptions;
57
- this.routes = [...params.routes ?? []];
58
+ const staticRoutes = Array.isArray(params.routes) ? params.routes : [];
59
+ this.explicitRoutesConfigured = Array.isArray(params.routes);
60
+ this.routes = [...staticRoutes];
58
61
  this.redisInstance = params.redisInstance;
59
62
  this.queueManager = params.queueManager;
60
63
  this.eventManager = params.eventManager;
@@ -226,6 +229,11 @@ class WebServer {
226
229
  * Configure routes.
227
230
  */
228
231
  async configureRoutes() {
232
+ if (this.options.routesDirectory && this.explicitRoutesConfigured) {
233
+ const baseMessage = 'Invalid web server configuration: choose either "routesDirectory" for automatic discovery or provide a "routes" array.';
234
+ const guidance = this.routes.length === 0 ? ' Remove the empty routes array when using "routesDirectory".' : " Remove one of these options so only a single routes source is configured.";
235
+ throw new Error(`${baseMessage}${guidance}`);
236
+ }
229
237
  await this.loadRoutesFromDirectory();
230
238
  const controllersDirectoryExists = await File.pathExists(this.options.controllersDirectory ?? "");
231
239
  if (!controllersDirectoryExists) {
@@ -270,7 +278,7 @@ class WebServer {
270
278
  if (!("method" in route)) {
271
279
  throw new Error("Handler-only routes require an HTTP method");
272
280
  }
273
- const schema = this.buildFastifySchema(route.schema) ?? this.buildLegacySchema(route.validation);
281
+ const schema = this.buildFastifySchema(route.schema);
274
282
  this.fastifyServer.route({
275
283
  method: route.method,
276
284
  url: route.path,
@@ -324,27 +332,40 @@ class WebServer {
324
332
  routePath,
325
333
  routeAction,
326
334
  routeSchema: route.schema,
327
- handlerOverride: route.handler?.bind(controllerInstance),
328
- legacyValidation: route.validation
335
+ handlerOverride: route.handler?.bind(controllerInstance)
329
336
  });
330
337
  break;
331
338
  }
332
339
  case WebServerRouteType.Entity: {
333
- if (this.applicationConfig.database && this.applicationConfig.database.enabled === true) {
340
+ if (this.applicationConfig.database?.enabled === true) {
334
341
  const entityModel = await Loader.loadEntityModule({
335
342
  entitiesDirectory: this.applicationConfig.database.entitiesDirectory,
336
343
  entityName: route.entityName
337
344
  });
338
- const entityValidationSchema = entityModel.schema?.describe();
339
- const formattedEntityValidationSchema = entityValidationSchema ? {
345
+ const entitySchemaSource = entityModel.schema;
346
+ if (entitySchemaSource && typeof entitySchemaSource.describe !== "function") {
347
+ const reportedType = typeof entitySchemaSource === "object" ? entitySchemaSource?.constructor?.name ?? "object" : typeof entitySchemaSource;
348
+ throw new Error(
349
+ `Entity route auto-validation requires a Joi schema with a describe() method. Entity "${route.entityName}" provided a ${reportedType}. If you're using Zod (schema/schemaUpdate) for this entity, migrate to the new DynamicEntity helpers or attach typed route validators instead of relying on WebServerRouteType.Entity auto-validation.`
350
+ );
351
+ }
352
+ const entitySchemaDescription = typeof entitySchemaSource?.describe === "function" ? entitySchemaSource.describe() : void 0;
353
+ if (entitySchemaSource && (entitySchemaDescription === void 0 || typeof entitySchemaDescription !== "object" || !("keys" in entitySchemaDescription))) {
354
+ const detectedType = entitySchemaDescription && typeof entitySchemaDescription === "object" ? entitySchemaDescription.constructor?.name ?? "object" : typeof entitySchemaDescription;
355
+ throw new Error(
356
+ `Entity route auto-validation expected Joi.describe() output with a "keys" map, but entity "${route.entityName}" returned ${detectedType}. This usually means the entity uses Zod schemas. Switch the entity to use DynamicEntity.defineSchemas or provide Joi-based validation for "${route.path}".`
357
+ );
358
+ }
359
+ const schemaKeys = entitySchemaDescription?.keys;
360
+ const formattedEntityValidationSchema = entitySchemaDescription && schemaKeys ? {
340
361
  type: "object",
341
362
  properties: Object.fromEntries(
342
- Object.entries(entityValidationSchema.keys).map(([key, value]) => [key, { type: value.type }])
363
+ Object.entries(schemaKeys).map(([key, value]) => [key, { type: value.type }])
343
364
  ),
344
- required: Object.keys(entityValidationSchema.keys).filter(
365
+ required: Object.keys(schemaKeys).filter(
345
366
  // Dynamic schema inspection of joi describe output; keys are from trusted entity definitions
346
367
  // eslint-disable-next-line security/detect-object-injection
347
- (key) => entityValidationSchema.keys[key].flags?.presence === "required"
368
+ (key) => schemaKeys[key].flags?.presence === "required"
348
369
  )
349
370
  } : {};
350
371
  const entityRouteDefinitions = WebServerUtil.getEntityRouteDefinitions({
@@ -359,8 +380,7 @@ class WebServer {
359
380
  routePath: entityRouteDefinition.path,
360
381
  routeAction: entityRouteDefinition.action,
361
382
  routeSchema: route.schema,
362
- handlerOverride: route.handler?.bind(controllerInstance),
363
- legacyValidation: entityRouteDefinition.validationSchema
383
+ handlerOverride: route.handler?.bind(controllerInstance)
364
384
  });
365
385
  }
366
386
  }
@@ -476,8 +496,7 @@ ${this.fastifyServer.printRoutes()}`);
476
496
  routePath,
477
497
  routeAction,
478
498
  routeSchema,
479
- handlerOverride,
480
- legacyValidation
499
+ handlerOverride
481
500
  }) {
482
501
  let handler = handlerOverride;
483
502
  if (!handler) {
@@ -500,7 +519,7 @@ ${this.fastifyServer.printRoutes()}`);
500
519
  }
501
520
  handler = controllerHandler.bind(controllerInstance);
502
521
  }
503
- const fastifySchema = this.buildFastifySchema(routeSchema) ?? this.buildLegacySchema(legacyValidation);
522
+ const fastifySchema = this.buildFastifySchema(routeSchema);
504
523
  if (!handler) {
505
524
  throw new Error("Route handler could not be resolved");
506
525
  }
@@ -555,27 +574,6 @@ ${this.fastifyServer.printRoutes()}`);
555
574
  }
556
575
  return schema;
557
576
  }
558
- buildLegacySchema(legacyValidation) {
559
- if (!legacyValidation) {
560
- return void 0;
561
- }
562
- const schema = {};
563
- const validations = Array.isArray(legacyValidation) ? legacyValidation : [legacyValidation];
564
- for (const validation of validations) {
565
- switch (validation.type) {
566
- case "body":
567
- schema.body = validation.schema;
568
- break;
569
- case "query":
570
- schema.querystring = validation.schema;
571
- break;
572
- case "params":
573
- schema.params = validation.schema;
574
- break;
575
- }
576
- }
577
- return schema;
578
- }
579
577
  /**
580
578
  * Check if web server is ready to accept traffic.
581
579
  */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/webserver/webserver.ts"],
4
- "sourcesContent": ["import crypto from 'node:crypto';\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n type FastifySchema,\n type HTTPMethods,\n} from 'fastify';\nimport cors from '@fastify/cors';\nimport helmet from '@fastify/helmet';\nimport rateLimit from '@fastify/rate-limit';\nimport multipart from '@fastify/multipart';\nimport {\n type AnyRouteSchemaDefinition,\n type WebServerConstructorParams,\n type WebServerOptions,\n type WebServerRoute,\n WebServerRouteType,\n} from './webserver.interface.js';\nimport { Logger } from '../logger/index.js';\nimport { File, Helper, Loader, Time } from '../util/index.js';\nimport WebServerUtil from './util.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { ControllerAction, WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { QueueManager } from '../queue/index.js';\nimport { WebServerHealthController } from '../index.js';\nimport type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\nimport { enterRequestContext } from '../request-context/index.js';\nimport { type ZodTypeProvider, serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n startTime?: number;\n requestId?: string;\n }\n}\n\nclass WebServer {\n private logger: typeof Logger = Logger;\n\n private applicationConfig: ApplicationConfig;\n\n private options: WebServerOptions;\n private routes: WebServerRoute[];\n\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private eventManager: EventManager;\n private databaseInstance: DatabaseInstance;\n\n public fastifyServer: FastifyInstance<any, any, any, any, ZodTypeProvider>;\n\n private lifecycleManager: LifecycleManager;\n private _isReady = false;\n\n constructor(params: WebServerConstructorParams & { lifecycleManager: LifecycleManager }) {\n // Define default options\n const defaultOptions: Partial<WebServerOptions> = {\n host: '0.0.0.0',\n port: 3001,\n cors: {\n enabled: false,\n },\n errors: {\n verbose: false,\n },\n debug: {\n printRoutes: false,\n simulateSlowConnection: {\n enabled: false,\n delay: 250,\n },\n },\n log: {\n startUp: true,\n },\n };\n\n // Merge default options\n const mergedOptions = Helper.defaultsDeep(params.options, defaultOptions);\n\n this.applicationConfig = params.applicationConfig;\n\n this.options = mergedOptions;\n this.routes = [...(params.routes ?? [])];\n\n this.redisInstance = params.redisInstance;\n this.queueManager = params.queueManager;\n this.eventManager = params.eventManager;\n this.databaseInstance = params.databaseInstance;\n this.lifecycleManager = params.lifecycleManager;\n\n // Create Fastify server\n const defaultBodyLimit = 25 * 1024 * 1024; // 25MB (safer default)\n const defaultConnectionTimeout = 10 * 1000; // 10 seconds (safer default)\n\n this.fastifyServer = Fastify({\n logger: false,\n bodyLimit: this.options.bodyLimit ?? defaultBodyLimit,\n connectionTimeout: this.options.connectionTimeout ?? defaultConnectionTimeout,\n }).withTypeProvider<ZodTypeProvider>();\n\n // Set up Zod validators and serializers for automatic schema validation\n this.fastifyServer.setValidatorCompiler(validatorCompiler);\n this.fastifyServer.setSerializerCompiler(serializerCompiler);\n }\n\n /**\n * Load web server.\n */\n public async load(): Promise<void> {\n // Configure security (helmet, rate limiting)\n await this.configureSecurity();\n\n // Configure hooks\n this.configureHooks();\n\n // Configure CORS\n this.configureCORS();\n\n // Configure multipart uploads\n this.configureMultipartUploads();\n\n // Configure routes\n await this.configureRoutes();\n }\n\n /**\n * Configure security features (Helmet, Rate Limiting)\n */\n private async configureSecurity(): Promise<void> {\n const security = this.options.security ?? {};\n\n // Configure Helmet for security headers\n const helmetConfig = security.helmet ?? { enabled: true };\n if (helmetConfig.enabled !== false) {\n await this.fastifyServer.register(helmet, {\n contentSecurityPolicy: helmetConfig.contentSecurityPolicy !== false,\n crossOriginEmbedderPolicy: helmetConfig.crossOriginEmbedderPolicy !== false,\n crossOriginOpenerPolicy: helmetConfig.crossOriginOpenerPolicy !== false,\n crossOriginResourcePolicy: helmetConfig.crossOriginResourcePolicy !== false,\n dnsPrefetchControl: helmetConfig.dnsPrefetchControl !== false,\n frameguard: helmetConfig.frameguard !== false,\n hidePoweredBy: helmetConfig.hidePoweredBy !== false,\n hsts: helmetConfig.hsts !== false,\n ieNoOpen: helmetConfig.ieNoOpen !== false,\n noSniff: helmetConfig.noSniff !== false,\n originAgentCluster: helmetConfig.originAgentCluster !== false,\n permittedCrossDomainPolicies: helmetConfig.permittedCrossDomainPolicies !== false,\n referrerPolicy: helmetConfig.referrerPolicy !== false,\n xssFilter: helmetConfig.xssFilter !== false,\n });\n }\n\n // Configure rate limiting\n const rateLimitConfig = security.rateLimit ?? { enabled: true };\n if (rateLimitConfig.enabled !== false) {\n await this.fastifyServer.register(rateLimit, {\n max: rateLimitConfig.max ?? 1000,\n timeWindow: rateLimitConfig.timeWindow ?? '1 minute',\n ban: rateLimitConfig.ban,\n cache: rateLimitConfig.cache ?? 5000,\n });\n }\n\n // Warn about wildcard CORS in production\n if (process.env.NODE_ENV === 'production' && this.options.cors?.enabled) {\n const corsConfig = this.options.cors as { enabled: true; urls: string[] };\n if (corsConfig.urls?.includes('*')) {\n this.logger.warn({\n message: 'Wildcard CORS (*) is enabled in production - this is a security risk',\n meta: {\n recommendation: 'Specify allowed origins explicitly',\n },\n });\n }\n }\n }\n\n /**\n * Configure hooks.\n */\n private configureHooks(): void {\n this.fastifyServer.addHook('onListen', async () => this.onListen());\n this.fastifyServer.addHook('onRequest', async request => this.onRequest(request));\n this.fastifyServer.addHook('onResponse', async (request, reply) => this.onResponse(request, reply));\n this.fastifyServer.addHook('onError', async (request, reply, error) => this.onError(request, reply, error));\n this.fastifyServer.addHook('onClose', async () => this.onClose());\n\n // if (process.env.NODE_ENV === 'local') {\n // this.fastifyServer.addHook('onSend', (request, reply, payload, done) => {\n // reply.header('Cache-Control', 'no-store');\n // done();\n // });\n // }\n }\n\n private async onListen(): Promise<void> {\n const address = this.fastifyServer.server.address();\n const port = typeof address === 'string' ? address : address?.port;\n\n if (this.options.log?.startUp) {\n this.log('Started', {\n Host: this.options.host,\n Port: port,\n // CORS: this.options.cors?.enabled && this.options.cors?..length > 0 ? this.options.corsUrls.join(', ') : 'Disabled',\n CORS: this.options.cors?.enabled ? this.options.cors.urls.join(', ') : 'Disabled',\n 'Fastify Version': this.fastifyServer.version,\n });\n }\n }\n\n private async onRequest(request: FastifyRequest): Promise<void> {\n if (\n this.options.debug?.simulateSlowConnection?.enabled &&\n this.options.debug?.simulateSlowConnection?.delay &&\n this.options.debug?.simulateSlowConnection?.delay > 0\n ) {\n await new Promise(resolve => setTimeout(resolve, this.options.debug?.simulateSlowConnection?.delay));\n }\n\n // Generate or use existing request ID for correlation\n const requestId = (request.headers['x-request-id'] as string | undefined) ?? crypto.randomUUID();\n request.requestId = requestId;\n\n const pathsToIgnore = ['/health/live', '/health/ready'];\n\n if (pathsToIgnore.includes(request.url) || request.method === 'OPTIONS') {\n // ...\n } else {\n const startTime = Time.now();\n request.startTime = startTime;\n\n // Initialize AsyncLocalStorage context for this request\n // Using enterWith() to set context for the current async execution\n enterRequestContext({ requestId, startTime });\n }\n }\n\n private async onResponse(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n // Add request ID to response headers for client-side correlation\n if (request.requestId) {\n reply.header('X-Request-ID', request.requestId);\n }\n\n if (!request.startTime) {\n return;\n }\n\n const executionTime = Time.calculateElapsedTimeMs({\n startTime: request.startTime,\n });\n const formattedExecutionTime = Time.formatTime({\n time: executionTime,\n numDecimals: 3,\n });\n\n const ip = request.headers['x-forwarded-for'] ?? request.ip;\n\n const logParams: Record<string, unknown> = {\n Method: request.method,\n Path: request.url,\n Status: reply.statusCode,\n };\n\n if (process.env.NODE_ENV !== 'development') {\n logParams.IP = ip.toString();\n }\n\n logParams.Time = formattedExecutionTime;\n\n // if (cluster.isWorker && cluster.worker) {\n // logParams.Worker = cluster.worker.id;\n // }\n\n this.log('API Request', logParams);\n }\n\n private async onError(request: FastifyRequest, reply: FastifyReply, error: Error): Promise<void> {\n // Adjusted for Fastify types\n Logger.error({ error });\n // Implement any additional logic here\n }\n\n private async onClose(): Promise<void> {\n this.log('Stopped');\n }\n\n private configureCORS(): void {\n if (!this.options.cors?.enabled) {\n return;\n }\n\n // Handle wildcard origin for development\n const origin = this.options.cors.urls.includes('*') ? true : this.options.cors.urls;\n\n this.fastifyServer.register(cors, {\n origin,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n preflightContinue: false,\n optionsSuccessStatus: 204,\n // credentials: true,\n });\n }\n\n private configureMultipartUploads(): void {\n this.fastifyServer.register(multipart, {\n // attachFieldsToBody: true,\n limits: {\n fieldNameSize: 100,\n fieldSize: 1024 * 1024 * 10,\n fields: 10,\n fileSize: 1024 * 1024 * 1024 * 10, // 10GB file size limit\n files: 1,\n headerPairs: 2000,\n },\n });\n }\n\n /**\n * Configure routes.\n */\n private async configureRoutes(): Promise<void> {\n await this.loadRoutesFromDirectory();\n\n // Check if controllers directory exists\n const controllersDirectoryExists = await File.pathExists(this.options.controllersDirectory ?? '');\n\n if (!controllersDirectoryExists) {\n const routesRequiringControllers = this.routes.length === 0 || this.routes.some(route => !route.handler);\n\n if (routesRequiringControllers) {\n Logger.warn({\n message: 'Web server controllers directory not found',\n meta: {\n Directory: this.options.controllersDirectory,\n },\n });\n\n return;\n }\n }\n\n // Load controllers\n const controllers = controllersDirectoryExists\n ? await Loader.loadModulesInDirectory({\n directory: this.options.controllersDirectory,\n extensions: ['.ts', '.js'],\n })\n : {};\n\n // Add health check routes\n this.routes.push(\n {\n type: WebServerRouteType.Default,\n method: 'GET',\n path: '/health/live',\n controller: WebServerHealthController,\n action: 'live',\n },\n {\n type: WebServerRouteType.Default,\n method: 'GET',\n path: '/health/ready',\n controller: WebServerHealthController,\n action: 'ready',\n },\n );\n\n // Go through each route\n for (const route of this.routes) {\n let ControllerClass: WebServerBaseControllerType;\n\n let controllerName;\n\n if (route.handler && !route.controller && !route.controllerName) {\n if (route.type && route.type !== WebServerRouteType.Default) {\n throw new Error('Handler-only routes are only supported for default route type');\n }\n\n if (!('method' in route)) {\n throw new Error('Handler-only routes require an HTTP method');\n }\n\n const schema = this.buildFastifySchema(route.schema) ?? this.buildLegacySchema(route.validation);\n\n this.fastifyServer.route({\n method: route.method,\n url: route.path,\n handler: route.handler,\n ...(schema ? { schema } : {}),\n });\n\n continue;\n }\n\n if (route.controller) {\n ControllerClass = route.controller;\n\n controllerName = ControllerClass.name;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as WebServerBaseControllerType;\n\n controllerName = route.controllerName;\n } else {\n throw new Error('Web server controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n const controllerPath = `${this.options.controllersDirectory}/${route.controllerName}.ts`;\n\n Logger.warn({\n message: 'Web server controller not found',\n meta: {\n Controller: route.controllerName,\n Path: controllerPath,\n Route: `${route.path}`,\n },\n });\n\n continue;\n }\n\n // Initialize controller instance\n const controllerInstance = new ControllerClass({\n applicationConfig: this.applicationConfig,\n webServerOptions: this.options,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n eventManager: this.eventManager,\n databaseInstance: this.databaseInstance,\n lifecycleManager: this.lifecycleManager,\n });\n\n let routeMethod;\n let routeAction;\n let routePath;\n\n switch (route.type) {\n case WebServerRouteType.Default: {\n routeMethod = route.method;\n routeAction = route.action;\n routePath = route.path;\n\n this.defineRoute({\n controllerInstance,\n controllerName,\n routeMethod,\n routePath,\n routeAction,\n routeSchema: route.schema,\n handlerOverride: route.handler?.bind(controllerInstance),\n legacyValidation: route.validation,\n });\n\n break;\n }\n case WebServerRouteType.Entity: {\n if (this.applicationConfig.database && this.applicationConfig.database.enabled === true) {\n const entityModel = await Loader.loadEntityModule({\n entitiesDirectory: this.applicationConfig.database.entitiesDirectory,\n entityName: route.entityName,\n });\n\n const entityValidationSchema = (\n entityModel as { schema?: { describe: () => unknown } }\n ).schema?.describe() as\n | {\n keys: Record<string, { type: string; flags?: { presence?: string }; [key: string]: unknown }>;\n [key: string]: unknown;\n }\n | undefined;\n\n const formattedEntityValidationSchema = entityValidationSchema\n ? {\n type: 'object',\n properties: Object.fromEntries(\n Object.entries(entityValidationSchema.keys).map(([key, value]) => [key, { type: value.type }]),\n ),\n required: Object.keys(entityValidationSchema.keys).filter(\n // Dynamic schema inspection of joi describe output; keys are from trusted entity definitions\n // eslint-disable-next-line security/detect-object-injection\n key => entityValidationSchema.keys[key].flags?.presence === 'required',\n ),\n }\n : {};\n\n const entityRouteDefinitions = WebServerUtil.getEntityRouteDefinitions({\n basePath: route.path,\n entityValidationSchema: formattedEntityValidationSchema,\n });\n\n for (const entityRouteDefinition of entityRouteDefinitions) {\n this.defineRoute({\n controllerInstance,\n controllerName,\n routeMethod: entityRouteDefinition.method,\n routePath: entityRouteDefinition.path,\n routeAction: entityRouteDefinition.action,\n routeSchema: route.schema,\n handlerOverride: route.handler?.bind(controllerInstance),\n legacyValidation: entityRouteDefinition.validationSchema,\n });\n }\n }\n\n break;\n }\n }\n }\n\n if (this.options.debug?.printRoutes) {\n this.log(`Routes:\\n${this.fastifyServer.printRoutes()}`);\n }\n }\n\n private async loadRoutesFromDirectory(): Promise<void> {\n const { routesDirectory } = this.options;\n\n if (!routesDirectory) {\n return;\n }\n\n const directoryExists = await File.pathExists(routesDirectory);\n\n if (!directoryExists) {\n this.logger.warn({\n message: 'Web server routes directory not found',\n meta: {\n Directory: routesDirectory,\n },\n });\n\n return;\n }\n\n const routeModules = await Loader.loadModulesInDirectory<\n WebServerRoute | WebServerRoute[] | { routes?: WebServerRoute[] }\n >({\n directory: routesDirectory,\n extensions: ['.ts', '.js'],\n });\n\n const loadedRoutes: WebServerRoute[] = [];\n\n for (const [moduleName, exportedRoutes] of Object.entries(routeModules)) {\n const normalizedRoutes = this.normalizeRouteExport(exportedRoutes, moduleName);\n\n if (normalizedRoutes.length === 0) {\n continue;\n }\n\n loadedRoutes.push(...normalizedRoutes);\n }\n\n if (loadedRoutes.length > 0) {\n this.routes.push(...loadedRoutes);\n }\n }\n\n private normalizeRouteExport(exportedValue: unknown, moduleName: string): WebServerRoute[] {\n const ensureRouteArray = (value: unknown): WebServerRoute[] => {\n if (Array.isArray(value)) {\n return value;\n }\n\n if (value && typeof value === 'object') {\n const maybeRoute = value as { routes?: unknown };\n\n if (Array.isArray(maybeRoute.routes)) {\n return maybeRoute.routes as WebServerRoute[];\n }\n }\n\n return value ? [value as WebServerRoute] : [];\n };\n\n const routeCandidates = ensureRouteArray(exportedValue);\n const validRoutes: WebServerRoute[] = [];\n\n for (const [index, candidate] of routeCandidates.entries()) {\n if (this.isValidRoute(candidate)) {\n validRoutes.push(candidate);\n } else {\n this.logger.warn({\n message: 'Invalid web server route definition skipped',\n meta: {\n Module: moduleName,\n Index: index,\n },\n });\n }\n }\n\n if (validRoutes.length === 0 && routeCandidates.length > 0) {\n this.logger.warn({\n message: 'No valid routes exported from module',\n meta: {\n Module: moduleName,\n },\n });\n }\n\n return validRoutes;\n }\n\n private isValidRoute(route: unknown): route is WebServerRoute {\n if (!route || typeof route !== 'object') {\n return false;\n }\n\n const candidate = route as Record<string, unknown>;\n const routePath = candidate.path;\n\n if (typeof routePath !== 'string' || routePath.length === 0) {\n return false;\n }\n\n const routeType = candidate.type ?? WebServerRouteType.Default;\n\n const controllerProvided =\n typeof candidate.controller === 'function' || typeof candidate.controllerName === 'string';\n const handlerProvided = typeof candidate.handler === 'function';\n\n if (routeType === WebServerRouteType.Entity || routeType === 'entity') {\n return controllerProvided && typeof candidate.entityName === 'string' && candidate.entityName.length > 0;\n }\n\n // For default routes, either controller+action OR handler must be provided\n if (!controllerProvided && !handlerProvided) {\n return false;\n }\n\n const method = candidate.method;\n\n const isValidMethod =\n typeof method === 'string' ||\n (Array.isArray(method) && method.length > 0 && method.every(m => typeof m === 'string'));\n\n // If handler is provided, we don't need action\n if (handlerProvided) {\n return isValidMethod;\n }\n\n // If controller is provided, we need action\n const action = candidate.action;\n const isValidAction = typeof action === 'string' && action.length > 0;\n\n return isValidMethod && isValidAction;\n }\n\n public async defineRoute({\n controllerInstance,\n controllerName,\n routeMethod,\n routePath,\n routeAction,\n routeSchema,\n handlerOverride,\n legacyValidation,\n }: {\n controllerInstance: any;\n controllerName: string;\n routeMethod: HTTPMethods | HTTPMethods[];\n routePath: string;\n routeAction?: string;\n routeSchema?: AnyRouteSchemaDefinition;\n handlerOverride?: ControllerAction<any>;\n legacyValidation?:\n | {\n type: 'body' | 'query' | 'params';\n schema: { [key: string]: any };\n }\n | Array<{\n type: 'body' | 'query' | 'params';\n schema: { [key: string]: any };\n }>;\n }): Promise<void> {\n let handler = handlerOverride;\n\n if (!handler) {\n if (!routeAction) {\n throw new Error('Route action is required when handler override is not provided');\n }\n\n if (!/^[A-Za-z0-9_]+$/.test(routeAction) || ['__proto__', 'prototype', 'constructor'].includes(routeAction)) {\n throw new Error('Invalid controller action name');\n }\n\n const controllerHandler = controllerInstance[routeAction as keyof typeof controllerInstance];\n\n if (!controllerHandler) {\n Logger.warn({\n message: 'Web server controller action not found',\n meta: {\n Controller: controllerName,\n Action: routeAction,\n },\n });\n\n throw new Error('Web server controller action not found');\n }\n\n handler = controllerHandler.bind(controllerInstance) as ControllerAction<any>;\n }\n\n const fastifySchema = this.buildFastifySchema(routeSchema) ?? this.buildLegacySchema(legacyValidation);\n\n if (!handler) {\n throw new Error('Route handler could not be resolved');\n }\n\n this.fastifyServer.route({\n method: routeMethod,\n url: routePath,\n handler: handler as unknown as (request: FastifyRequest, reply: FastifyReply) => unknown,\n ...(fastifySchema ? { schema: fastifySchema } : {}),\n });\n }\n\n /**\n * Start web server.\n */\n public async start(): Promise<void> {\n try {\n await this.fastifyServer.listen({\n host: this.options.host,\n port: this.options.port,\n });\n this._isReady = true;\n } catch (error) {\n Logger.error({ error });\n throw error;\n }\n }\n\n /**\n * Stop web server.\n */\n public async stop(): Promise<void> {\n this._isReady = false;\n // Close Fastify server\n await this.fastifyServer.close();\n }\n\n private buildFastifySchema(routeSchema?: AnyRouteSchemaDefinition): FastifySchema | undefined {\n if (!routeSchema) {\n return undefined;\n }\n\n const schema: FastifySchema = {};\n\n // With ZodTypeProvider, we can pass Zod schemas directly\n // The type provider handles validation automatically\n if (routeSchema.params) {\n schema.params = routeSchema.params;\n }\n\n if (routeSchema.querystring) {\n schema.querystring = routeSchema.querystring;\n }\n\n if (routeSchema.body) {\n schema.body = routeSchema.body;\n }\n\n if (routeSchema.headers) {\n schema.headers = routeSchema.headers;\n }\n\n if (routeSchema.response) {\n schema.response = routeSchema.response;\n }\n\n return schema;\n }\n\n private buildLegacySchema(\n legacyValidation?:\n | {\n type: 'body' | 'query' | 'params';\n schema: { [key: string]: any };\n }\n | Array<{\n type: 'body' | 'query' | 'params';\n schema: { [key: string]: any };\n }>,\n ): FastifySchema | undefined {\n if (!legacyValidation) {\n return undefined;\n }\n\n const schema: FastifySchema = {};\n\n // Handle both single validation schema and array of validation schemas\n const validations = Array.isArray(legacyValidation) ? legacyValidation : [legacyValidation];\n\n for (const validation of validations) {\n switch (validation.type) {\n case 'body':\n schema.body = validation.schema;\n break;\n case 'query':\n schema.querystring = validation.schema;\n break;\n case 'params':\n schema.params = validation.schema;\n break;\n }\n }\n\n return schema;\n }\n\n /**\n * Check if web server is ready to accept traffic.\n */\n public isReady(): boolean {\n return this._isReady && this.fastifyServer.server?.listening === true;\n }\n\n /**\n * Log web server message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'webServer', message, meta });\n }\n}\n\nexport default WebServer;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import crypto from 'node:crypto';\nimport Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n type FastifySchema,\n type HTTPMethods,\n} from 'fastify';\nimport cors from '@fastify/cors';\nimport helmet from '@fastify/helmet';\nimport rateLimit from '@fastify/rate-limit';\nimport multipart from '@fastify/multipart';\nimport {\n type AnyRouteSchemaDefinition,\n type WebServerConstructorParams,\n type WebServerOptions,\n type WebServerRoute,\n WebServerRouteType,\n} from './webserver.interface.js';\nimport { Logger } from '../logger/index.js';\nimport { File, Helper, Loader, Time } from '../util/index.js';\nimport WebServerUtil from './util.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { ControllerAction, WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { QueueManager } from '../queue/index.js';\nimport { WebServerHealthController } from '../index.js';\nimport type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\nimport { enterRequestContext } from '../request-context/index.js';\nimport { type ZodTypeProvider, serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n startTime?: number;\n requestId?: string;\n }\n}\n\nclass WebServer {\n private logger: typeof Logger = Logger;\n\n private applicationConfig: ApplicationConfig;\n\n private options: WebServerOptions;\n private routes: WebServerRoute[];\n private readonly explicitRoutesConfigured: boolean;\n\n private redisInstance: RedisInstance;\n private queueManager: QueueManager;\n private eventManager: EventManager;\n private databaseInstance: DatabaseInstance;\n\n public fastifyServer: FastifyInstance<any, any, any, any, ZodTypeProvider>;\n\n private lifecycleManager: LifecycleManager;\n private _isReady = false;\n\n constructor(params: WebServerConstructorParams & { lifecycleManager: LifecycleManager }) {\n // Define default options\n const defaultOptions: Partial<WebServerOptions> = {\n host: '0.0.0.0',\n port: 3001,\n cors: {\n enabled: false,\n },\n errors: {\n verbose: false,\n },\n debug: {\n printRoutes: false,\n simulateSlowConnection: {\n enabled: false,\n delay: 250,\n },\n },\n log: {\n startUp: true,\n },\n };\n\n // Merge default options\n const mergedOptions = Helper.defaultsDeep(params.options, defaultOptions);\n\n this.applicationConfig = params.applicationConfig;\n\n this.options = mergedOptions;\n\n const staticRoutes = Array.isArray(params.routes) ? params.routes : [];\n this.explicitRoutesConfigured = Array.isArray(params.routes);\n this.routes = [...staticRoutes];\n\n this.redisInstance = params.redisInstance;\n this.queueManager = params.queueManager;\n this.eventManager = params.eventManager;\n this.databaseInstance = params.databaseInstance;\n this.lifecycleManager = params.lifecycleManager;\n\n // Create Fastify server\n const defaultBodyLimit = 25 * 1024 * 1024; // 25MB (safer default)\n const defaultConnectionTimeout = 10 * 1000; // 10 seconds (safer default)\n\n this.fastifyServer = Fastify({\n logger: false,\n bodyLimit: this.options.bodyLimit ?? defaultBodyLimit,\n connectionTimeout: this.options.connectionTimeout ?? defaultConnectionTimeout,\n }).withTypeProvider<ZodTypeProvider>();\n\n // Set up Zod validators and serializers for automatic schema validation\n this.fastifyServer.setValidatorCompiler(validatorCompiler);\n this.fastifyServer.setSerializerCompiler(serializerCompiler);\n }\n\n /**\n * Load web server.\n */\n public async load(): Promise<void> {\n // Configure security (helmet, rate limiting)\n await this.configureSecurity();\n\n // Configure hooks\n this.configureHooks();\n\n // Configure CORS\n this.configureCORS();\n\n // Configure multipart uploads\n this.configureMultipartUploads();\n\n // Configure routes\n await this.configureRoutes();\n }\n\n /**\n * Configure security features (Helmet, Rate Limiting)\n */\n private async configureSecurity(): Promise<void> {\n const security = this.options.security ?? {};\n\n // Configure Helmet for security headers\n const helmetConfig = security.helmet ?? { enabled: true };\n if (helmetConfig.enabled !== false) {\n await this.fastifyServer.register(helmet, {\n contentSecurityPolicy: helmetConfig.contentSecurityPolicy !== false,\n crossOriginEmbedderPolicy: helmetConfig.crossOriginEmbedderPolicy !== false,\n crossOriginOpenerPolicy: helmetConfig.crossOriginOpenerPolicy !== false,\n crossOriginResourcePolicy: helmetConfig.crossOriginResourcePolicy !== false,\n dnsPrefetchControl: helmetConfig.dnsPrefetchControl !== false,\n frameguard: helmetConfig.frameguard !== false,\n hidePoweredBy: helmetConfig.hidePoweredBy !== false,\n hsts: helmetConfig.hsts !== false,\n ieNoOpen: helmetConfig.ieNoOpen !== false,\n noSniff: helmetConfig.noSniff !== false,\n originAgentCluster: helmetConfig.originAgentCluster !== false,\n permittedCrossDomainPolicies: helmetConfig.permittedCrossDomainPolicies !== false,\n referrerPolicy: helmetConfig.referrerPolicy !== false,\n xssFilter: helmetConfig.xssFilter !== false,\n });\n }\n\n // Configure rate limiting\n const rateLimitConfig = security.rateLimit ?? { enabled: true };\n if (rateLimitConfig.enabled !== false) {\n await this.fastifyServer.register(rateLimit, {\n max: rateLimitConfig.max ?? 1000,\n timeWindow: rateLimitConfig.timeWindow ?? '1 minute',\n ban: rateLimitConfig.ban,\n cache: rateLimitConfig.cache ?? 5000,\n });\n }\n\n // Warn about wildcard CORS in production\n if (process.env.NODE_ENV === 'production' && this.options.cors?.enabled) {\n const corsConfig = this.options.cors as { enabled: true; urls: string[] };\n if (corsConfig.urls?.includes('*')) {\n this.logger.warn({\n message: 'Wildcard CORS (*) is enabled in production - this is a security risk',\n meta: {\n recommendation: 'Specify allowed origins explicitly',\n },\n });\n }\n }\n }\n\n /**\n * Configure hooks.\n */\n private configureHooks(): void {\n this.fastifyServer.addHook('onListen', async () => this.onListen());\n this.fastifyServer.addHook('onRequest', async request => this.onRequest(request));\n this.fastifyServer.addHook('onResponse', async (request, reply) => this.onResponse(request, reply));\n this.fastifyServer.addHook('onError', async (request, reply, error) => this.onError(request, reply, error));\n this.fastifyServer.addHook('onClose', async () => this.onClose());\n\n // if (process.env.NODE_ENV === 'local') {\n // this.fastifyServer.addHook('onSend', (request, reply, payload, done) => {\n // reply.header('Cache-Control', 'no-store');\n // done();\n // });\n // }\n }\n\n private async onListen(): Promise<void> {\n const address = this.fastifyServer.server.address();\n const port = typeof address === 'string' ? address : address?.port;\n\n if (this.options.log?.startUp) {\n this.log('Started', {\n Host: this.options.host,\n Port: port,\n // CORS: this.options.cors?.enabled && this.options.cors?..length > 0 ? this.options.corsUrls.join(', ') : 'Disabled',\n CORS: this.options.cors?.enabled ? this.options.cors.urls.join(', ') : 'Disabled',\n 'Fastify Version': this.fastifyServer.version,\n });\n }\n }\n\n private async onRequest(request: FastifyRequest): Promise<void> {\n if (\n this.options.debug?.simulateSlowConnection?.enabled &&\n this.options.debug?.simulateSlowConnection?.delay &&\n this.options.debug?.simulateSlowConnection?.delay > 0\n ) {\n await new Promise(resolve => setTimeout(resolve, this.options.debug?.simulateSlowConnection?.delay));\n }\n\n // Generate or use existing request ID for correlation\n const requestId = (request.headers['x-request-id'] as string | undefined) ?? crypto.randomUUID();\n request.requestId = requestId;\n\n const pathsToIgnore = ['/health/live', '/health/ready'];\n\n if (pathsToIgnore.includes(request.url) || request.method === 'OPTIONS') {\n // ...\n } else {\n const startTime = Time.now();\n request.startTime = startTime;\n\n // Initialize AsyncLocalStorage context for this request\n // Using enterWith() to set context for the current async execution\n enterRequestContext({ requestId, startTime });\n }\n }\n\n private async onResponse(request: FastifyRequest, reply: FastifyReply): Promise<void> {\n // Add request ID to response headers for client-side correlation\n if (request.requestId) {\n reply.header('X-Request-ID', request.requestId);\n }\n\n if (!request.startTime) {\n return;\n }\n\n const executionTime = Time.calculateElapsedTimeMs({\n startTime: request.startTime,\n });\n const formattedExecutionTime = Time.formatTime({\n time: executionTime,\n numDecimals: 3,\n });\n\n const ip = request.headers['x-forwarded-for'] ?? request.ip;\n\n const logParams: Record<string, unknown> = {\n Method: request.method,\n Path: request.url,\n Status: reply.statusCode,\n };\n\n if (process.env.NODE_ENV !== 'development') {\n logParams.IP = ip.toString();\n }\n\n logParams.Time = formattedExecutionTime;\n\n // if (cluster.isWorker && cluster.worker) {\n // logParams.Worker = cluster.worker.id;\n // }\n\n this.log('API Request', logParams);\n }\n\n private async onError(request: FastifyRequest, reply: FastifyReply, error: Error): Promise<void> {\n // Adjusted for Fastify types\n Logger.error({ error });\n // Implement any additional logic here\n }\n\n private async onClose(): Promise<void> {\n this.log('Stopped');\n }\n\n private configureCORS(): void {\n if (!this.options.cors?.enabled) {\n return;\n }\n\n // Handle wildcard origin for development\n const origin = this.options.cors.urls.includes('*') ? true : this.options.cors.urls;\n\n this.fastifyServer.register(cors, {\n origin,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n preflightContinue: false,\n optionsSuccessStatus: 204,\n // credentials: true,\n });\n }\n\n private configureMultipartUploads(): void {\n this.fastifyServer.register(multipart, {\n // attachFieldsToBody: true,\n limits: {\n fieldNameSize: 100,\n fieldSize: 1024 * 1024 * 10,\n fields: 10,\n fileSize: 1024 * 1024 * 1024 * 10, // 10GB file size limit\n files: 1,\n headerPairs: 2000,\n },\n });\n }\n\n /**\n * Configure routes.\n */\n private async configureRoutes(): Promise<void> {\n if (this.options.routesDirectory && this.explicitRoutesConfigured) {\n const baseMessage =\n 'Invalid web server configuration: choose either \"routesDirectory\" for automatic discovery or provide a \"routes\" array.';\n const guidance =\n this.routes.length === 0\n ? ' Remove the empty routes array when using \"routesDirectory\".'\n : ' Remove one of these options so only a single routes source is configured.';\n\n throw new Error(`${baseMessage}${guidance}`);\n }\n\n await this.loadRoutesFromDirectory();\n\n // Check if controllers directory exists\n const controllersDirectoryExists = await File.pathExists(this.options.controllersDirectory ?? '');\n\n if (!controllersDirectoryExists) {\n const routesRequiringControllers = this.routes.length === 0 || this.routes.some(route => !route.handler);\n\n if (routesRequiringControllers) {\n Logger.warn({\n message: 'Web server controllers directory not found',\n meta: {\n Directory: this.options.controllersDirectory,\n },\n });\n\n return;\n }\n }\n\n // Load controllers\n const controllers = controllersDirectoryExists\n ? await Loader.loadModulesInDirectory({\n directory: this.options.controllersDirectory,\n extensions: ['.ts', '.js'],\n })\n : {};\n\n // Add health check routes\n this.routes.push(\n {\n type: WebServerRouteType.Default,\n method: 'GET',\n path: '/health/live',\n controller: WebServerHealthController,\n action: 'live',\n },\n {\n type: WebServerRouteType.Default,\n method: 'GET',\n path: '/health/ready',\n controller: WebServerHealthController,\n action: 'ready',\n },\n );\n\n // Go through each route\n for (const route of this.routes) {\n let ControllerClass: WebServerBaseControllerType;\n\n let controllerName;\n\n if (route.handler && !route.controller && !route.controllerName) {\n if (route.type && route.type !== WebServerRouteType.Default) {\n throw new Error('Handler-only routes are only supported for default route type');\n }\n\n if (!('method' in route)) {\n throw new Error('Handler-only routes require an HTTP method');\n }\n\n const schema = this.buildFastifySchema(route.schema);\n\n this.fastifyServer.route({\n method: route.method,\n url: route.path,\n handler: route.handler,\n ...(schema ? { schema } : {}),\n });\n\n continue;\n }\n\n if (route.controller) {\n ControllerClass = route.controller;\n\n controllerName = ControllerClass.name;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as WebServerBaseControllerType;\n\n controllerName = route.controllerName;\n } else {\n throw new Error('Web server controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n const controllerPath = `${this.options.controllersDirectory}/${route.controllerName}.ts`;\n\n Logger.warn({\n message: 'Web server controller not found',\n meta: {\n Controller: route.controllerName,\n Path: controllerPath,\n Route: `${route.path}`,\n },\n });\n\n continue;\n }\n\n // Initialize controller instance\n const controllerInstance = new ControllerClass({\n applicationConfig: this.applicationConfig,\n webServerOptions: this.options,\n redisInstance: this.redisInstance,\n queueManager: this.queueManager,\n eventManager: this.eventManager,\n databaseInstance: this.databaseInstance,\n lifecycleManager: this.lifecycleManager,\n });\n\n let routeMethod;\n let routeAction;\n let routePath;\n\n switch (route.type) {\n case WebServerRouteType.Default: {\n routeMethod = route.method;\n routeAction = route.action;\n routePath = route.path;\n\n this.defineRoute({\n controllerInstance,\n controllerName,\n routeMethod,\n routePath,\n routeAction,\n routeSchema: route.schema,\n handlerOverride: route.handler?.bind(controllerInstance),\n });\n\n break;\n }\n case WebServerRouteType.Entity: {\n if (this.applicationConfig.database?.enabled === true) {\n const entityModel = await Loader.loadEntityModule({\n entitiesDirectory: this.applicationConfig.database.entitiesDirectory,\n entityName: route.entityName,\n });\n\n const entitySchemaSource = (entityModel as { schema?: { describe?: () => unknown } }).schema;\n\n if (entitySchemaSource && typeof entitySchemaSource.describe !== 'function') {\n const reportedType =\n typeof entitySchemaSource === 'object'\n ? (entitySchemaSource?.constructor?.name ?? 'object')\n : typeof entitySchemaSource;\n\n throw new Error(\n `Entity route auto-validation requires a Joi schema with a describe() method. ` +\n `Entity \"${route.entityName}\" provided a ${reportedType}. ` +\n `If you're using Zod (schema/schemaUpdate) for this entity, migrate to the new DynamicEntity helpers or ` +\n `attach typed route validators instead of relying on WebServerRouteType.Entity auto-validation.`,\n );\n }\n\n const entitySchemaDescription =\n typeof entitySchemaSource?.describe === 'function'\n ? (entitySchemaSource.describe() as\n | {\n keys?: Record<string, { type: string; flags?: { presence?: string }; [key: string]: unknown }>;\n [key: string]: unknown;\n }\n | undefined)\n : undefined;\n\n if (\n entitySchemaSource &&\n (entitySchemaDescription === undefined ||\n typeof entitySchemaDescription !== 'object' ||\n !('keys' in entitySchemaDescription))\n ) {\n const detectedType =\n entitySchemaDescription && typeof entitySchemaDescription === 'object'\n ? (entitySchemaDescription.constructor?.name ?? 'object')\n : typeof entitySchemaDescription;\n\n throw new Error(\n `Entity route auto-validation expected Joi.describe() output with a \"keys\" map, ` +\n `but entity \"${route.entityName}\" returned ${detectedType}. ` +\n `This usually means the entity uses Zod schemas. ` +\n `Switch the entity to use DynamicEntity.defineSchemas or provide Joi-based validation for \"${route.path}\".`,\n );\n }\n\n const schemaKeys = entitySchemaDescription?.keys;\n\n const formattedEntityValidationSchema =\n entitySchemaDescription && schemaKeys\n ? {\n type: 'object',\n properties: Object.fromEntries(\n Object.entries(schemaKeys).map(([key, value]) => [key, { type: value.type }]),\n ),\n required: Object.keys(schemaKeys).filter(\n // Dynamic schema inspection of joi describe output; keys are from trusted entity definitions\n // eslint-disable-next-line security/detect-object-injection\n key => schemaKeys[key].flags?.presence === 'required',\n ),\n }\n : {};\n\n const entityRouteDefinitions = WebServerUtil.getEntityRouteDefinitions({\n basePath: route.path,\n entityValidationSchema: formattedEntityValidationSchema,\n });\n\n for (const entityRouteDefinition of entityRouteDefinitions) {\n this.defineRoute({\n controllerInstance,\n controllerName,\n routeMethod: entityRouteDefinition.method,\n routePath: entityRouteDefinition.path,\n routeAction: entityRouteDefinition.action,\n routeSchema: route.schema,\n handlerOverride: route.handler?.bind(controllerInstance),\n });\n }\n }\n\n break;\n }\n }\n }\n\n if (this.options.debug?.printRoutes) {\n this.log(`Routes:\\n${this.fastifyServer.printRoutes()}`);\n }\n }\n\n private async loadRoutesFromDirectory(): Promise<void> {\n const { routesDirectory } = this.options;\n\n if (!routesDirectory) {\n return;\n }\n\n const directoryExists = await File.pathExists(routesDirectory);\n\n if (!directoryExists) {\n this.logger.warn({\n message: 'Web server routes directory not found',\n meta: {\n Directory: routesDirectory,\n },\n });\n\n return;\n }\n\n const routeModules = await Loader.loadModulesInDirectory<\n WebServerRoute | WebServerRoute[] | { routes?: WebServerRoute[] }\n >({\n directory: routesDirectory,\n extensions: ['.ts', '.js'],\n });\n\n const loadedRoutes: WebServerRoute[] = [];\n\n for (const [moduleName, exportedRoutes] of Object.entries(routeModules)) {\n const normalizedRoutes = this.normalizeRouteExport(exportedRoutes, moduleName);\n\n if (normalizedRoutes.length === 0) {\n continue;\n }\n\n loadedRoutes.push(...normalizedRoutes);\n }\n\n if (loadedRoutes.length > 0) {\n this.routes.push(...loadedRoutes);\n }\n }\n\n private normalizeRouteExport(exportedValue: unknown, moduleName: string): WebServerRoute[] {\n const ensureRouteArray = (value: unknown): WebServerRoute[] => {\n if (Array.isArray(value)) {\n return value;\n }\n\n if (value && typeof value === 'object') {\n const maybeRoute = value as { routes?: unknown };\n\n if (Array.isArray(maybeRoute.routes)) {\n return maybeRoute.routes as WebServerRoute[];\n }\n }\n\n return value ? [value as WebServerRoute] : [];\n };\n\n const routeCandidates = ensureRouteArray(exportedValue);\n const validRoutes: WebServerRoute[] = [];\n\n for (const [index, candidate] of routeCandidates.entries()) {\n if (this.isValidRoute(candidate)) {\n validRoutes.push(candidate);\n } else {\n this.logger.warn({\n message: 'Invalid web server route definition skipped',\n meta: {\n Module: moduleName,\n Index: index,\n },\n });\n }\n }\n\n if (validRoutes.length === 0 && routeCandidates.length > 0) {\n this.logger.warn({\n message: 'No valid routes exported from module',\n meta: {\n Module: moduleName,\n },\n });\n }\n\n return validRoutes;\n }\n\n private isValidRoute(route: unknown): route is WebServerRoute {\n if (!route || typeof route !== 'object') {\n return false;\n }\n\n const candidate = route as Record<string, unknown>;\n const routePath = candidate.path;\n\n if (typeof routePath !== 'string' || routePath.length === 0) {\n return false;\n }\n\n const routeType = candidate.type ?? WebServerRouteType.Default;\n\n const controllerProvided =\n typeof candidate.controller === 'function' || typeof candidate.controllerName === 'string';\n const handlerProvided = typeof candidate.handler === 'function';\n\n if (routeType === WebServerRouteType.Entity || routeType === 'entity') {\n return controllerProvided && typeof candidate.entityName === 'string' && candidate.entityName.length > 0;\n }\n\n // For default routes, either controller+action OR handler must be provided\n if (!controllerProvided && !handlerProvided) {\n return false;\n }\n\n const method = candidate.method;\n\n const isValidMethod =\n typeof method === 'string' ||\n (Array.isArray(method) && method.length > 0 && method.every(m => typeof m === 'string'));\n\n // If handler is provided, we don't need action\n if (handlerProvided) {\n return isValidMethod;\n }\n\n // If controller is provided, we need action\n const action = candidate.action;\n const isValidAction = typeof action === 'string' && action.length > 0;\n\n return isValidMethod && isValidAction;\n }\n\n public async defineRoute({\n controllerInstance,\n controllerName,\n routeMethod,\n routePath,\n routeAction,\n routeSchema,\n handlerOverride,\n }: {\n controllerInstance: any;\n controllerName: string;\n routeMethod: HTTPMethods | HTTPMethods[];\n routePath: string;\n routeAction?: string;\n routeSchema?: AnyRouteSchemaDefinition;\n handlerOverride?: ControllerAction<any>;\n }): Promise<void> {\n let handler = handlerOverride;\n\n if (!handler) {\n if (!routeAction) {\n throw new Error('Route action is required when handler override is not provided');\n }\n\n if (!/^[A-Za-z0-9_]+$/.test(routeAction) || ['__proto__', 'prototype', 'constructor'].includes(routeAction)) {\n throw new Error('Invalid controller action name');\n }\n\n const controllerHandler = controllerInstance[routeAction as keyof typeof controllerInstance];\n\n if (!controllerHandler) {\n Logger.warn({\n message: 'Web server controller action not found',\n meta: {\n Controller: controllerName,\n Action: routeAction,\n },\n });\n\n throw new Error('Web server controller action not found');\n }\n\n handler = controllerHandler.bind(controllerInstance) as ControllerAction<any>;\n }\n\n const fastifySchema = this.buildFastifySchema(routeSchema);\n\n if (!handler) {\n throw new Error('Route handler could not be resolved');\n }\n\n this.fastifyServer.route({\n method: routeMethod,\n url: routePath,\n handler: handler as unknown as (request: FastifyRequest, reply: FastifyReply) => unknown,\n ...(fastifySchema ? { schema: fastifySchema } : {}),\n });\n }\n\n /**\n * Start web server.\n */\n public async start(): Promise<void> {\n try {\n await this.fastifyServer.listen({\n host: this.options.host,\n port: this.options.port,\n });\n this._isReady = true;\n } catch (error) {\n Logger.error({ error });\n throw error;\n }\n }\n\n /**\n * Stop web server.\n */\n public async stop(): Promise<void> {\n this._isReady = false;\n // Close Fastify server\n await this.fastifyServer.close();\n }\n\n private buildFastifySchema(routeSchema?: AnyRouteSchemaDefinition): FastifySchema | undefined {\n if (!routeSchema) {\n return undefined;\n }\n\n const schema: FastifySchema = {};\n\n // With ZodTypeProvider, we can pass Zod schemas directly\n // The type provider handles validation automatically\n if (routeSchema.params) {\n schema.params = routeSchema.params;\n }\n\n if (routeSchema.querystring) {\n schema.querystring = routeSchema.querystring;\n }\n\n if (routeSchema.body) {\n schema.body = routeSchema.body;\n }\n\n if (routeSchema.headers) {\n schema.headers = routeSchema.headers;\n }\n\n if (routeSchema.response) {\n schema.response = routeSchema.response;\n }\n\n return schema;\n }\n\n /**\n * Check if web server is ready to accept traffic.\n */\n public isReady(): boolean {\n return this._isReady && this.fastifyServer.server?.listening === true;\n }\n\n /**\n * Log web server message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'webServer', message, meta });\n }\n}\n\nexport default WebServer;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/websocket/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAE/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBnF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/websocket/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAE/F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBnF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhE"}
@@ -1,8 +1,12 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import crypto from "node:crypto";
3
4
  import { Logger } from "../logger/index.js";
4
5
  function generateClientId() {
5
- return Math.random().toString(36).substr(2, 9);
6
+ if (typeof crypto.randomUUID === "function") {
7
+ return crypto.randomUUID().replace(/-/g, "");
8
+ }
9
+ return crypto.randomBytes(16).toString("hex");
6
10
  }
7
11
  __name(generateClientId, "generateClientId");
8
12
  function log(message, meta, options) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/utils.ts"],
4
- "sourcesContent": ["import type WebSocket from 'ws';\nimport { Logger } from '../logger/index.js';\n\nexport interface LogOptions {\n muteWorker?: boolean;\n}\n\nexport function generateClientId(): string {\n return Math.random().toString(36).substr(2, 9);\n}\n\nexport function log(message: string, meta?: Record<string, unknown>, options?: LogOptions): void {\n Logger.custom({ level: 'webSocket', message, meta, options });\n}\n\nexport function parseServerMessage(message: WebSocket.Data): Record<string, unknown> {\n let parsedMessage;\n\n try {\n parsedMessage = JSON.parse(message.toString());\n } catch {\n throw new Error('Failed to parse JSON');\n }\n\n if (!parsedMessage) {\n throw new Error('Invalid WebSocket message');\n } else if (!parsedMessage.type) {\n throw new Error('Missing WebSocket message type');\n } else if (!parsedMessage.action) {\n throw new Error('Missing WebSocket message action');\n }\n\n return parsedMessage;\n}\n\nexport function getRouteKey(type: string, action: string): string {\n return `${type}:${action}`;\n}\n"],
5
- "mappings": ";;AACA,SAAS,cAAc;AAMhB,SAAS,mBAA2B;AACzC,SAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC;AAC/C;AAFgB;AAIT,SAAS,IAAI,SAAiB,MAAgC,SAA4B;AAC/F,SAAO,OAAO,EAAE,OAAO,aAAa,SAAS,MAAM,QAAQ,CAAC;AAC9D;AAFgB;AAIT,SAAS,mBAAmB,SAAkD;AACnF,MAAI;AAEJ,MAAI;AACF,oBAAgB,KAAK,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AACN,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C,WAAW,CAAC,cAAc,MAAM;AAC9B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD,WAAW,CAAC,cAAc,QAAQ;AAChC,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,SAAO;AACT;AAlBgB;AAoBT,SAAS,YAAY,MAAc,QAAwB;AAChE,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;AAFgB;",
4
+ "sourcesContent": ["import crypto from 'node:crypto';\nimport type WebSocket from 'ws';\nimport { Logger } from '../logger/index.js';\n\nexport interface LogOptions {\n muteWorker?: boolean;\n}\n\nexport function generateClientId(): string {\n if (typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID().replace(/-/g, '');\n }\n\n return crypto.randomBytes(16).toString('hex');\n}\n\nexport function log(message: string, meta?: Record<string, unknown>, options?: LogOptions): void {\n Logger.custom({ level: 'webSocket', message, meta, options });\n}\n\nexport function parseServerMessage(message: WebSocket.Data): Record<string, unknown> {\n let parsedMessage;\n\n try {\n parsedMessage = JSON.parse(message.toString());\n } catch {\n throw new Error('Failed to parse JSON');\n }\n\n if (!parsedMessage) {\n throw new Error('Invalid WebSocket message');\n } else if (!parsedMessage.type) {\n throw new Error('Missing WebSocket message type');\n } else if (!parsedMessage.action) {\n throw new Error('Missing WebSocket message action');\n }\n\n return parsedMessage;\n}\n\nexport function getRouteKey(type: string, action: string): string {\n return `${type}:${action}`;\n}\n"],
5
+ "mappings": ";;AAAA,OAAO,YAAY;AAEnB,SAAS,cAAc;AAMhB,SAAS,mBAA2B;AACzC,MAAI,OAAO,OAAO,eAAe,YAAY;AAC3C,WAAO,OAAO,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAC7C;AAEA,SAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAC9C;AANgB;AAQT,SAAS,IAAI,SAAiB,MAAgC,SAA4B;AAC/F,SAAO,OAAO,EAAE,OAAO,aAAa,SAAS,MAAM,QAAQ,CAAC;AAC9D;AAFgB;AAIT,SAAS,mBAAmB,SAAkD;AACnF,MAAI;AAEJ,MAAI;AACF,oBAAgB,KAAK,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC/C,QAAQ;AACN,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AAEA,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C,WAAW,CAAC,cAAc,MAAM;AAC9B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD,WAAW,CAAC,cAAc,QAAQ;AAChC,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,SAAO;AACT;AAlBgB;AAoBT,SAAS,YAAY,MAAc,QAAwB;AAChE,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;AAFgB;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-base.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIvG,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,aAAa;IACzC,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,CAAM;IACxC,SAAS,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAa;IAE1E,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAAM;IAE/C,aAAoB,IAAI,IAAI,aAAa,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,OAAO;IAC/C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;cAE5D,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAwEtF,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,SAAS,CAAC,IAAI,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAuDxE,SAAS,CAAC,WAAW,IAAI,IAAI;CAiB9B"}
1
+ {"version":3,"file":"websocket-base.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIvG,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAGhC,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,aAAa;IACzC,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,CAAM;IACxC,SAAS,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAa;IAE1E,SAAS,CAAC,aAAa,EAAE,cAAc,EAAE,CAAM;IAE/C,aAAoB,IAAI,IAAI,aAAa,CAAC;IAE1C,SAAS,CAAC,QAAQ,CAAC,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,iBAAiB,IAAI,OAAO;IAC/C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;cAE5D,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cAiFtF,mBAAmB,CACjC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,SAAS,CAAC,IAAI,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAuDxE,SAAS,CAAC,WAAW,IAAI,IAAI;CAiB9B"}
@@ -46,7 +46,15 @@ class WebSocketBase {
46
46
  const controllerInstance = new ControllerClass(controllerDependencies);
47
47
  const controllerHandler = controllerInstance[route.action];
48
48
  const routeKey = getRouteKey(route.type, route.action);
49
- this.routeHandlers.set(routeKey, controllerHandler);
49
+ if (typeof controllerHandler !== "function") {
50
+ log("Controller action not found", {
51
+ Controller: route.controllerName ?? ControllerClass.name,
52
+ Action: route.action,
53
+ RouteKey: routeKey
54
+ });
55
+ continue;
56
+ }
57
+ this.routeHandlers.set(routeKey, controllerHandler.bind(controllerInstance));
50
58
  }
51
59
  if (this.shouldPrintRoutes()) {
52
60
  log("Routes:", { Type: this.type });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/websocket/websocket-base.ts"],
4
- "sourcesContent": ["import type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';\nimport { getRouteKey, log, parseServerMessage } from './utils.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\nimport type WebSocket from 'ws';\nimport { File, Helper, Loader } from '../util/index.js';\n\nexport default abstract class WebSocketBase {\n protected routes: WebSocketRoute[] = [];\n protected routeHandlers: Map<string, WebSocketMessageHandler> = new Map();\n\n protected defaultRoutes: WebSocketRoute[] = [];\n\n public abstract get type(): WebSocketType;\n\n protected abstract getControllerDependencies(): Record<string, unknown>;\n protected abstract shouldPrintRoutes(): boolean;\n protected abstract handleMessageError(clientId: string, error: string): void;\n\n protected async configureRoutes(routes: WebSocketRoute[], controllersDirectory: string): Promise<void> {\n // log ('Configuring routes', { Type: this.type, 'Controllers Directory': controllersDirectory });\n\n const controllersDirectoryExists = await File.pathExists(controllersDirectory);\n\n if (!controllersDirectoryExists) {\n log('Controllers directory not found', {\n Directory: controllersDirectory,\n });\n\n return;\n }\n\n const scriptFileExtension = Helper.getScriptFileExtension();\n\n // Load controllers\n const controllers = await Loader.loadModulesInDirectory({\n directory: controllersDirectory,\n // NOTE:\n // When getting \"system\", it gets /app/node_modules/@scpxl/nodejs-framework/dist/websocket/controllers/server\n // Therefor .js is needed also\n // Fix so only .ts vs .js is needed\n extensions: ['.ts', '.js'],\n });\n\n for (const route of routes) {\n let ControllerClass: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n // log('Registering route', {\n // Type: route.type,\n // Controller: route.controller ? route.controller.toString() : route.controllerName,\n // Action: route.action,\n // });\n\n if (route.controller) {\n ControllerClass = route.controller;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as\n | WebSocketServerBaseControllerType\n | WebSocketClientBaseControllerType;\n } else {\n throw new Error('WebSocket controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n log('Controller not found', {\n Controller: route.controllerName,\n Path: `${controllersDirectory}/${route.controllerName}.${scriptFileExtension}`,\n });\n\n continue;\n }\n\n const controllerDependencies = this.getControllerDependencies();\n\n const controllerInstance = new ControllerClass(controllerDependencies as any);\n\n const controllerHandler = controllerInstance[\n route.action as keyof typeof controllerInstance\n ] as WebSocketMessageHandler;\n const routeKey = getRouteKey(route.type, route.action);\n\n this.routeHandlers.set(routeKey, controllerHandler);\n }\n\n if (this.shouldPrintRoutes()) {\n log('Routes:', { Type: this.type });\n\n this.printRoutes();\n }\n }\n\n protected async handleServerMessage(\n ws: WebSocket,\n message: WebSocket.Data,\n clientId: string,\n ): Promise<{ type: unknown; action: unknown; response: unknown } | void> {\n try {\n const parsedMessage = parseServerMessage(message);\n const type = parsedMessage.type;\n const action = parsedMessage.action;\n\n log('Incoming message', {\n 'Client ID': clientId,\n Type: type ?? '-',\n Action: action ?? '-',\n });\n\n const routeKey = getRouteKey(parsedMessage.type as string, parsedMessage.action as string);\n\n const messageHandler = this.routeHandlers.get(routeKey);\n\n if (messageHandler) {\n const messageResponse = await messageHandler(ws, clientId, parsedMessage.data);\n\n return {\n type,\n action,\n response: messageResponse,\n };\n }\n // throw new Error(`Route handler not found (Route Key: ${routeKey} | Type: ${type} | Action: ${action})`);\n\n log('Route handler not found', {\n RouteKey: routeKey,\n Type: type,\n Action: action,\n });\n\n // if (\n // typeof this.applicationConfig.webSocket\n // ?.serverMessageHandler === 'function'\n // ) {\n // // Execute custom application subscriber event handler\n // this.applicationConfig.webSocket.serverMessageHandler(\n // {\n // ws,\n // clientId,\n // parsedMessage,\n // },\n // );\n // }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n log(errorMessage);\n\n this.handleMessageError(clientId, errorMessage);\n }\n }\n\n protected printRoutes(): void {\n let routesString = '';\n\n const routeKeys = Array.from(this.routeHandlers.keys());\n\n routeKeys.forEach((routeKey, index) => {\n const [type, action] = routeKey.split(':');\n\n routesString += `Type: ${type} -> Action: ${action}`;\n\n if (index !== routeKeys.length - 1) {\n routesString += '\\n';\n }\n });\n\n log(routesString);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { WebSocketMessageHandler, WebSocketRoute, WebSocketType } from './websocket.interface.js';\nimport { getRouteKey, log, parseServerMessage } from './utils.js';\nimport type { WebSocketServerBaseControllerType } from './controller/server/base.interface.js';\nimport type { WebSocketClientBaseControllerType } from './controller/client/base.interface.js';\nimport type WebSocket from 'ws';\nimport { File, Helper, Loader } from '../util/index.js';\n\nexport default abstract class WebSocketBase {\n protected routes: WebSocketRoute[] = [];\n protected routeHandlers: Map<string, WebSocketMessageHandler> = new Map();\n\n protected defaultRoutes: WebSocketRoute[] = [];\n\n public abstract get type(): WebSocketType;\n\n protected abstract getControllerDependencies(): Record<string, unknown>;\n protected abstract shouldPrintRoutes(): boolean;\n protected abstract handleMessageError(clientId: string, error: string): void;\n\n protected async configureRoutes(routes: WebSocketRoute[], controllersDirectory: string): Promise<void> {\n // log ('Configuring routes', { Type: this.type, 'Controllers Directory': controllersDirectory });\n\n const controllersDirectoryExists = await File.pathExists(controllersDirectory);\n\n if (!controllersDirectoryExists) {\n log('Controllers directory not found', {\n Directory: controllersDirectory,\n });\n\n return;\n }\n\n const scriptFileExtension = Helper.getScriptFileExtension();\n\n // Load controllers\n const controllers = await Loader.loadModulesInDirectory({\n directory: controllersDirectory,\n // NOTE:\n // When getting \"system\", it gets /app/node_modules/@scpxl/nodejs-framework/dist/websocket/controllers/server\n // Therefor .js is needed also\n // Fix so only .ts vs .js is needed\n extensions: ['.ts', '.js'],\n });\n\n for (const route of routes) {\n let ControllerClass: WebSocketServerBaseControllerType | WebSocketClientBaseControllerType;\n\n // log('Registering route', {\n // Type: route.type,\n // Controller: route.controller ? route.controller.toString() : route.controllerName,\n // Action: route.action,\n // });\n\n if (route.controller) {\n ControllerClass = route.controller;\n } else if (route.controllerName) {\n ControllerClass = controllers[route.controllerName] as\n | WebSocketServerBaseControllerType\n | WebSocketClientBaseControllerType;\n } else {\n throw new Error('WebSocket controller config not found');\n }\n\n if (typeof ControllerClass !== 'function') {\n log('Controller not found', {\n Controller: route.controllerName,\n Path: `${controllersDirectory}/${route.controllerName}.${scriptFileExtension}`,\n });\n\n continue;\n }\n\n const controllerDependencies = this.getControllerDependencies();\n\n const controllerInstance = new ControllerClass(controllerDependencies as any);\n\n const controllerHandler = controllerInstance[route.action as keyof typeof controllerInstance] as\n | WebSocketMessageHandler\n | undefined;\n const routeKey = getRouteKey(route.type, route.action);\n\n if (typeof controllerHandler !== 'function') {\n log('Controller action not found', {\n Controller: route.controllerName ?? ControllerClass.name,\n Action: route.action,\n RouteKey: routeKey,\n });\n continue;\n }\n\n this.routeHandlers.set(routeKey, controllerHandler.bind(controllerInstance));\n }\n\n if (this.shouldPrintRoutes()) {\n log('Routes:', { Type: this.type });\n\n this.printRoutes();\n }\n }\n\n protected async handleServerMessage(\n ws: WebSocket,\n message: WebSocket.Data,\n clientId: string,\n ): Promise<{ type: unknown; action: unknown; response: unknown } | void> {\n try {\n const parsedMessage = parseServerMessage(message);\n const type = parsedMessage.type;\n const action = parsedMessage.action;\n\n log('Incoming message', {\n 'Client ID': clientId,\n Type: type ?? '-',\n Action: action ?? '-',\n });\n\n const routeKey = getRouteKey(parsedMessage.type as string, parsedMessage.action as string);\n\n const messageHandler = this.routeHandlers.get(routeKey);\n\n if (messageHandler) {\n const messageResponse = await messageHandler(ws, clientId, parsedMessage.data);\n\n return {\n type,\n action,\n response: messageResponse,\n };\n }\n // throw new Error(`Route handler not found (Route Key: ${routeKey} | Type: ${type} | Action: ${action})`);\n\n log('Route handler not found', {\n RouteKey: routeKey,\n Type: type,\n Action: action,\n });\n\n // if (\n // typeof this.applicationConfig.webSocket\n // ?.serverMessageHandler === 'function'\n // ) {\n // // Execute custom application subscriber event handler\n // this.applicationConfig.webSocket.serverMessageHandler(\n // {\n // ws,\n // clientId,\n // parsedMessage,\n // },\n // );\n // }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n log(errorMessage);\n\n this.handleMessageError(clientId, errorMessage);\n }\n }\n\n protected printRoutes(): void {\n let routesString = '';\n\n const routeKeys = Array.from(this.routeHandlers.keys());\n\n routeKeys.forEach((routeKey, index) => {\n const [type, action] = routeKey.split(':');\n\n routesString += `Type: ${type} -> Action: ${action}`;\n\n if (index !== routeKeys.length - 1) {\n routesString += '\\n';\n }\n });\n\n log(routesString);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-server.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"websocket-server.d.ts","sourceRoot":"","sources":["../../src/websocket/websocket-server.ts"],"names":[],"mappings":"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"}