@scpxl/nodejs-framework 1.0.19 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +530 -67
- package/dist/application/base-application.js +1 -1
- package/dist/application/base-application.js.map +2 -2
- package/dist/application/command-application.js.map +2 -2
- package/dist/application/web-application.js +1 -0
- package/dist/application/web-application.js.map +2 -2
- package/dist/command/command.js.map +1 -1
- package/dist/config/schema.js +16 -6
- package/dist/config/schema.js.map +2 -2
- package/dist/event/manager.js.map +2 -2
- package/dist/lifecycle/lifecycle-manager.js.map +2 -2
- package/dist/logger/logger.js +21 -1
- package/dist/logger/logger.js.map +2 -2
- package/dist/queue/index.js.map +1 -1
- package/dist/queue/manager.js +24 -12
- package/dist/queue/manager.js.map +2 -2
- package/dist/queue/processor/base.js.map +2 -2
- package/dist/services/aws/s3.js.map +2 -2
- package/dist/util/helper.js +1 -1
- package/dist/util/helper.js.map +2 -2
- package/dist/util/loader.js.map +2 -2
- package/dist/webserver/controller/base.js.map +2 -2
- package/dist/webserver/define-route.js +22 -0
- package/dist/webserver/define-route.js.map +7 -0
- package/dist/webserver/index.js +2 -0
- package/dist/webserver/index.js.map +2 -2
- package/dist/webserver/webserver.interface.js.map +2 -2
- package/dist/webserver/webserver.js +211 -56
- package/dist/webserver/webserver.js.map +2 -2
- package/dist/websocket/websocket-base.js.map +2 -2
- package/dist/websocket/websocket-client.js.map +1 -1
- package/dist/websocket/websocket-server.js +5 -5
- package/dist/websocket/websocket-server.js.map +2 -2
- package/dist/websocket/websocket.interface.js.map +2 -2
- package/package.json +3 -2
- package/dist/api-requester/api-requester.d.ts +0 -32
- package/dist/api-requester/api-requester.d.ts.map +0 -1
- package/dist/api-requester/index.d.ts +0 -3
- package/dist/api-requester/index.d.ts.map +0 -1
- package/dist/application/base-application.d.ts +0 -106
- package/dist/application/base-application.d.ts.map +0 -1
- package/dist/application/base-application.interface.d.ts +0 -161
- package/dist/application/base-application.interface.d.ts.map +0 -1
- package/dist/application/command-application.d.ts +0 -18
- package/dist/application/command-application.d.ts.map +0 -1
- package/dist/application/command-application.interface.d.ts +0 -26
- package/dist/application/command-application.interface.d.ts.map +0 -1
- package/dist/application/index.d.ts +0 -5
- package/dist/application/index.d.ts.map +0 -1
- package/dist/application/web-application.d.ts +0 -43
- package/dist/application/web-application.d.ts.map +0 -1
- package/dist/application/web-application.interface.d.ts +0 -21
- package/dist/application/web-application.interface.d.ts.map +0 -1
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/jwt.d.ts +0 -25
- package/dist/auth/jwt.d.ts.map +0 -1
- package/dist/cache/index.d.ts +0 -2
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/manager.d.ts +0 -107
- package/dist/cache/manager.d.ts.map +0 -1
- package/dist/cluster/cluster-manager.d.ts +0 -15
- package/dist/cluster/cluster-manager.d.ts.map +0 -1
- package/dist/cluster/cluster-manager.interface.d.ts +0 -23
- package/dist/cluster/cluster-manager.interface.d.ts.map +0 -1
- package/dist/cluster/index.d.ts +0 -2
- package/dist/cluster/index.d.ts.map +0 -1
- package/dist/command/command-manager.d.ts +0 -19
- package/dist/command/command-manager.d.ts.map +0 -1
- package/dist/command/command.d.ts +0 -27
- package/dist/command/command.d.ts.map +0 -1
- package/dist/command/command.interface.d.ts +0 -11
- package/dist/command/command.interface.d.ts.map +0 -1
- package/dist/command/index.d.ts +0 -3
- package/dist/command/index.d.ts.map +0 -1
- package/dist/config/env.d.ts +0 -11
- package/dist/config/env.d.ts.map +0 -1
- package/dist/config/index.d.ts +0 -3
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/schema.d.ts +0 -408
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/database/dynamic-entity-form-decorators.d.ts +0 -31
- package/dist/database/dynamic-entity-form-decorators.d.ts.map +0 -1
- package/dist/database/dynamic-entity.d.ts +0 -15
- package/dist/database/dynamic-entity.d.ts.map +0 -1
- package/dist/database/index.d.ts +0 -5
- package/dist/database/index.d.ts.map +0 -1
- package/dist/database/instance.d.ts +0 -36
- package/dist/database/instance.d.ts.map +0 -1
- package/dist/database/instance.interface.d.ts +0 -5
- package/dist/database/instance.interface.d.ts.map +0 -1
- package/dist/database/manager.d.ts +0 -27
- package/dist/database/manager.d.ts.map +0 -1
- package/dist/database/manager.interface.d.ts +0 -18
- package/dist/database/manager.interface.d.ts.map +0 -1
- package/dist/error/error-reporter.d.ts +0 -96
- package/dist/error/error-reporter.d.ts.map +0 -1
- package/dist/error/error.interface.d.ts +0 -126
- package/dist/error/error.interface.d.ts.map +0 -1
- package/dist/error/framework-errors.d.ts +0 -113
- package/dist/error/framework-errors.d.ts.map +0 -1
- package/dist/error/index.d.ts +0 -6
- package/dist/error/index.d.ts.map +0 -1
- package/dist/event/controller/base.d.ts +0 -23
- package/dist/event/controller/base.d.ts.map +0 -1
- package/dist/event/controller/base.interface.d.ts +0 -11
- package/dist/event/controller/base.interface.d.ts.map +0 -1
- package/dist/event/index.d.ts +0 -5
- package/dist/event/index.d.ts.map +0 -1
- package/dist/event/manager.d.ts +0 -21
- package/dist/event/manager.d.ts.map +0 -1
- package/dist/event/manager.interface.d.ts +0 -134
- package/dist/event/manager.interface.d.ts.map +0 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +0 -1
- package/dist/lifecycle/exit.d.ts +0 -11
- package/dist/lifecycle/exit.d.ts.map +0 -1
- package/dist/lifecycle/index.d.ts +0 -7
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/lifecycle-manager.d.ts +0 -66
- package/dist/lifecycle/lifecycle-manager.d.ts.map +0 -1
- package/dist/lifecycle/shutdown-controller.d.ts +0 -15
- package/dist/lifecycle/shutdown-controller.d.ts.map +0 -1
- package/dist/lifecycle/types.d.ts +0 -28
- package/dist/lifecycle/types.d.ts.map +0 -1
- package/dist/logger/index.d.ts +0 -2
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/logger/logger.d.ts +0 -55
- package/dist/logger/logger.d.ts.map +0 -1
- package/dist/logger/logger.interface.d.ts +0 -2
- package/dist/logger/logger.interface.d.ts.map +0 -1
- package/dist/performance/cache-performance.d.ts +0 -64
- package/dist/performance/cache-performance.d.ts.map +0 -1
- package/dist/performance/database-performance.d.ts +0 -40
- package/dist/performance/database-performance.d.ts.map +0 -1
- package/dist/performance/index.d.ts +0 -8
- package/dist/performance/index.d.ts.map +0 -1
- package/dist/performance/performance-monitor.d.ts +0 -68
- package/dist/performance/performance-monitor.d.ts.map +0 -1
- package/dist/performance/performance-monitor.plugin.d.ts +0 -24
- package/dist/performance/performance-monitor.plugin.d.ts.map +0 -1
- package/dist/performance/queue-performance.d.ts +0 -46
- package/dist/performance/queue-performance.d.ts.map +0 -1
- package/dist/performance/webserver-performance.d.ts +0 -69
- package/dist/performance/webserver-performance.d.ts.map +0 -1
- package/dist/performance/websocket-performance.d.ts +0 -44
- package/dist/performance/websocket-performance.d.ts.map +0 -1
- package/dist/queue/index.d.ts +0 -6
- package/dist/queue/index.d.ts.map +0 -1
- package/dist/queue/index.interface.d.ts +0 -10
- package/dist/queue/index.interface.d.ts.map +0 -1
- package/dist/queue/job.interface.d.ts +0 -42
- package/dist/queue/job.interface.d.ts.map +0 -1
- package/dist/queue/manager.d.ts +0 -36
- package/dist/queue/manager.d.ts.map +0 -1
- package/dist/queue/manager.interface.d.ts +0 -18
- package/dist/queue/manager.interface.d.ts.map +0 -1
- package/dist/queue/processor/base.d.ts +0 -28
- package/dist/queue/processor/base.d.ts.map +0 -1
- package/dist/queue/processor/processor.interface.d.ts +0 -15
- package/dist/queue/processor/processor.interface.d.ts.map +0 -1
- package/dist/queue/worker.d.ts +0 -14
- package/dist/queue/worker.d.ts.map +0 -1
- package/dist/queue/worker.interface.d.ts +0 -13
- package/dist/queue/worker.interface.d.ts.map +0 -1
- package/dist/redis/index.d.ts +0 -3
- package/dist/redis/index.d.ts.map +0 -1
- package/dist/redis/instance.d.ts +0 -32
- package/dist/redis/instance.d.ts.map +0 -1
- package/dist/redis/instance.interface.d.ts +0 -9
- package/dist/redis/instance.interface.d.ts.map +0 -1
- package/dist/redis/manager.d.ts +0 -15
- package/dist/redis/manager.d.ts.map +0 -1
- package/dist/redis/manager.interface.d.ts +0 -8
- package/dist/redis/manager.interface.d.ts.map +0 -1
- package/dist/request-context/index.d.ts +0 -3
- package/dist/request-context/index.d.ts.map +0 -1
- package/dist/request-context/request-context.d.ts +0 -108
- package/dist/request-context/request-context.d.ts.map +0 -1
- package/dist/request-context/request-context.interface.d.ts +0 -46
- package/dist/request-context/request-context.interface.d.ts.map +0 -1
- package/dist/services/aws/index.d.ts +0 -2
- package/dist/services/aws/index.d.ts.map +0 -1
- package/dist/services/aws/s3.d.ts +0 -54
- package/dist/services/aws/s3.d.ts.map +0 -1
- package/dist/services/aws/s3.interface.d.ts +0 -14
- package/dist/services/aws/s3.interface.d.ts.map +0 -1
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.d.ts.map +0 -1
- package/dist/util/file.d.ts +0 -58
- package/dist/util/file.d.ts.map +0 -1
- package/dist/util/helper.d.ts +0 -52
- package/dist/util/helper.d.ts.map +0 -1
- package/dist/util/image.d.ts +0 -12
- package/dist/util/image.d.ts.map +0 -1
- package/dist/util/index.d.ts +0 -11
- package/dist/util/index.d.ts.map +0 -1
- package/dist/util/loader.d.ts +0 -19
- package/dist/util/loader.d.ts.map +0 -1
- package/dist/util/num.d.ts +0 -13
- package/dist/util/num.d.ts.map +0 -1
- package/dist/util/os.d.ts +0 -6
- package/dist/util/os.d.ts.map +0 -1
- package/dist/util/str.d.ts +0 -39
- package/dist/util/str.d.ts.map +0 -1
- package/dist/util/time.d.ts +0 -19
- package/dist/util/time.d.ts.map +0 -1
- package/dist/util/time.interface.d.ts +0 -12
- package/dist/util/time.interface.d.ts.map +0 -1
- package/dist/util/timing.d.ts +0 -36
- package/dist/util/timing.d.ts.map +0 -1
- package/dist/util/timing.interface.d.ts +0 -47
- package/dist/util/timing.interface.d.ts.map +0 -1
- package/dist/util/url.d.ts +0 -7
- package/dist/util/url.d.ts.map +0 -1
- package/dist/webserver/controller/auth-middleware.d.ts +0 -21
- package/dist/webserver/controller/auth-middleware.d.ts.map +0 -1
- package/dist/webserver/controller/base.d.ts +0 -41
- package/dist/webserver/controller/base.d.ts.map +0 -1
- package/dist/webserver/controller/base.interface.d.ts +0 -47
- package/dist/webserver/controller/base.interface.d.ts.map +0 -1
- package/dist/webserver/controller/entity.d.ts +0 -94
- package/dist/webserver/controller/entity.d.ts.map +0 -1
- package/dist/webserver/controller/example-auth.d.ts +0 -12
- package/dist/webserver/controller/example-auth.d.ts.map +0 -1
- package/dist/webserver/controller/health.d.ts +0 -15
- package/dist/webserver/controller/health.d.ts.map +0 -1
- package/dist/webserver/index.d.ts +0 -12
- package/dist/webserver/index.d.ts.map +0 -1
- package/dist/webserver/util.d.ts +0 -10
- package/dist/webserver/util.d.ts.map +0 -1
- package/dist/webserver/webserver.d.ts +0 -79
- package/dist/webserver/webserver.d.ts.map +0 -1
- package/dist/webserver/webserver.interface.d.ts +0 -155
- package/dist/webserver/webserver.interface.d.ts.map +0 -1
- package/dist/websocket/controller/client/base.d.ts +0 -12
- package/dist/websocket/controller/client/base.d.ts.map +0 -1
- package/dist/websocket/controller/client/base.interface.d.ts +0 -12
- package/dist/websocket/controller/client/base.interface.d.ts.map +0 -1
- package/dist/websocket/controller/server/base.d.ts +0 -13
- package/dist/websocket/controller/server/base.d.ts.map +0 -1
- package/dist/websocket/controller/server/base.interface.d.ts +0 -13
- package/dist/websocket/controller/server/base.interface.d.ts.map +0 -1
- package/dist/websocket/controllers/client/system.d.ts +0 -6
- package/dist/websocket/controllers/client/system.d.ts.map +0 -1
- package/dist/websocket/controllers/server/system.d.ts +0 -7
- package/dist/websocket/controllers/server/system.d.ts.map +0 -1
- package/dist/websocket/index.d.ts +0 -7
- package/dist/websocket/index.d.ts.map +0 -1
- package/dist/websocket/routes/client/system.d.ts +0 -3
- package/dist/websocket/routes/client/system.d.ts.map +0 -1
- package/dist/websocket/routes/server/system.d.ts +0 -3
- package/dist/websocket/routes/server/system.d.ts.map +0 -1
- package/dist/websocket/utils.d.ts +0 -9
- package/dist/websocket/utils.d.ts.map +0 -1
- package/dist/websocket/websocket-base.d.ts +0 -15
- package/dist/websocket/websocket-base.d.ts.map +0 -1
- package/dist/websocket/websocket-client-manager.d.ts +0 -53
- package/dist/websocket/websocket-client-manager.d.ts.map +0 -1
- package/dist/websocket/websocket-client-manager.interface.d.ts +0 -8
- package/dist/websocket/websocket-client-manager.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-client.d.ts +0 -35
- package/dist/websocket/websocket-client.d.ts.map +0 -1
- package/dist/websocket/websocket-client.interface.d.ts +0 -14
- package/dist/websocket/websocket-client.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-room-manager.d.ts +0 -32
- package/dist/websocket/websocket-room-manager.d.ts.map +0 -1
- package/dist/websocket/websocket-server.d.ts +0 -92
- package/dist/websocket/websocket-server.d.ts.map +0 -1
- package/dist/websocket/websocket-server.interface.d.ts +0 -16
- package/dist/websocket/websocket-server.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-service.d.ts +0 -44
- package/dist/websocket/websocket-service.d.ts.map +0 -1
- package/dist/websocket/websocket.interface.d.ts +0 -119
- package/dist/websocket/websocket.interface.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/logger/logger.ts"],
|
|
4
|
-
"sourcesContent": ["import * as Sentry from '@sentry/node';\nimport { nodeProfilingIntegration } from '@sentry/profiling-node';\nimport cluster from 'node:cluster';\nimport winston from 'winston';\nimport type { LogOptions } from '../websocket/utils.js';\nimport { getRequestId } from '../request-context/index.js';\n\nexport type LoggerLevels =\n | 'error'\n | 'warn'\n | 'info'\n | 'command'\n | 'database'\n | 'redis'\n | 'webServer'\n | 'webSocket'\n | 'queue'\n | 'queueJob'\n | 'event'\n | 'debug';\n\nexport class Logger {\n private static instance: Logger;\n private logger: winston.Logger;\n\n private environment: string | undefined;\n\n public isSentryInitialized = false;\n\n private constructor() {\n this.environment = process.env.NODE_ENV;\n\n const customFormat = this.getCustomFormat();\n\n const customLevels: winston.config.AbstractConfigSetLevels = {\n error: 0,\n warn: 1,\n info: 2,\n command: 3,\n database: 4,\n redis: 5,\n webServer: 6,\n webSocket: 7,\n queue: 8,\n queueJob: 9,\n event: 10,\n debug: 11,\n };\n\n const customColors: winston.config.AbstractConfigSetColors = {\n error: 'red',\n warn: 'yellow',\n info: 'blue',\n command: 'cyan',\n database: 'brightGreen',\n redis: 'brightYellow',\n webServer: 'brightBlue',\n webSocket: 'brightMagenta',\n queue: 'gray',\n queueJob: 'blue',\n event: 'brightGreen',\n debug: 'brightCyan',\n };\n\n winston.addColors(customColors);\n\n this.logger = winston.createLogger({\n levels: customLevels,\n level: this.environment === 'production' ? 'info' : 'debug',\n format: winston.format.combine(\n winston.format.timestamp({\n format: 'YYYY-MM-DD HH:mm:ss',\n }),\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n winston.format.json(),\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(winston.format.colorize(), customFormat),\n }),\n ],\n });\n }\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n\n return Logger.instance;\n }\n\n private getCustomFormat(): winston.Logform.Format {\n return winston.format.printf(({ level, message, timestamp, ...meta }) => {\n // Auto-inject request ID from AsyncLocalStorage context if available\n const requestId = getRequestId();\n if (requestId && !meta['requestId']) {\n meta['requestId'] = requestId;\n }\n\n if (cluster.isWorker && cluster.worker) {\n meta['Worker'] = cluster.worker.id; // .process.pid;\n }\n\n const metaString = Object.entries(meta)\n .map(([key, value]) => {\n return `${key}: ${value}`;\n })\n .join(' | ');\n\n if (level === 'error') {\n if (this.isSentryInitialized) {\n const errorMessage = typeof message === 'string' ? message : JSON.stringify(message);\n\n Sentry.captureException(new Error(errorMessage));\n }\n }\n\n return `[${timestamp}] ${level}: ${message}${metaString ? ` (${metaString})` : ''}`;\n });\n }\n\n public initSentry({ sentryDsn, environment }: { sentryDsn: string; environment: string }): void {\n if (!sentryDsn) {\n this.logger.warn('Missing Sentry DSN when initializing Sentry');\n\n return;\n }\n\n Sentry.init({\n dsn: sentryDsn,\n integrations: [nodeProfilingIntegration()],\n tracesSampleRate: 1.0,\n environment,\n });\n\n this.isSentryInitialized = true;\n }\n\n public log({\n level,\n message,\n meta,\n options: _options,\n }: {\n level: LoggerLevels;\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void {\n // if (options?.muteWorker) {\n // }\n\n if (message instanceof Error) {\n const errorMessage = message.stack ?? message.toString();\n this.logger.log(level, errorMessage, meta);\n } else if (typeof message === 'string') {\n this.logger.log(level, message, meta);\n } else {\n this.logger.log(level, JSON.stringify(message), meta);\n }\n }\n\n public debug({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public debug(message: unknown, meta?: Record<string, unknown>): void;\n public debug(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'debug', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'debug', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n public info({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public info(message: unknown, meta?: Record<string, unknown>): void;\n public info(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'info', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'info', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n public warn({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public warn(message: unknown, meta?: Record<string, unknown>): void;\n public warn(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'warn', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'warn', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n // Overload 1: Object signature (existing usage)\n public error(args: {\n error: Error | unknown;\n message?: string;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n // Overload 2: Positional signature (new usage)\n public error(error: Error | unknown, message?: string, meta?: Record<string, unknown>, options?: LogOptions): void;\n public error(\n arg1:\n | { error: Error | unknown; message?: string; meta?: Record<string, unknown>; options?: LogOptions }\n | (Error | unknown),\n message?: string,\n meta?: Record<string, unknown>,\n options?: LogOptions,\n ): void {\n // Support original object signature: Logger.error({ error, message?, meta?, options? })\n if (\n typeof arg1 === 'object' &&\n arg1 !== null &&\n 'error' in arg1 &&\n // If the caller passed a second positional arg, treat it as new signature\n message === undefined\n ) {\n const {\n error,\n message: objMessage,\n meta: objMeta,\n options: objOptions,\n } = arg1 as {\n error: Error | unknown;\n message?: string;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n };\n\n if (objMessage) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const combinedMessage = `${objMessage}: ${errorMessage}`;\n this.log({ level: 'error', message: combinedMessage, meta: objMeta, options: objOptions });\n if (error instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(error);\n }\n } else {\n this.log({ level: 'error', message: error, meta: objMeta, options: objOptions });\n if (error instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(error);\n }\n }\n return;\n }\n\n // New positional signature: Logger.error(error, message?, meta?, options?)\n const errorObj = arg1;\n if (message) {\n const errorMessage = errorObj instanceof Error ? errorObj.message : String(errorObj);\n const combinedMessage = `${message}: ${errorMessage}`;\n this.log({ level: 'error', message: combinedMessage, meta, options });\n } else {\n this.log({ level: 'error', message: errorObj, meta, options });\n }\n if (errorObj instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(errorObj);\n }\n }\n\n public custom({\n level,\n message,\n meta,\n options,\n }: {\n level: LoggerLevels;\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void {\n this.log({ level, message, meta, options });\n }\n}\n\nexport default Logger.getInstance();\n"],
|
|
5
|
-
"mappings": ";;AAAA,YAAY,YAAY;AACxB,SAAS,gCAAgC;AACzC,OAAO,aAAa;AACpB,OAAO,aAAa;AAEpB,SAAS,oBAAoB;AAgBtB,MAAM,OAAO;AAAA,EArBpB,OAqBoB;AAAA;AAAA;AAAA,EAClB,OAAe;AAAA,EACP;AAAA,EAEA;AAAA,EAED,sBAAsB;AAAA,EAErB,cAAc;AACpB,SAAK,cAAc,QAAQ,IAAI;AAE/B,UAAM,eAAe,KAAK,gBAAgB;AAE1C,UAAM,eAAuD;AAAA,MAC3D,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,MACX,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAEA,UAAM,eAAuD;AAAA,MAC3D,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,MACX,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU;AAAA,MACV,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAEA,YAAQ,UAAU,YAAY;AAE9B,SAAK,SAAS,QAAQ,aAAa;AAAA,MACjC,QAAQ;AAAA,MACR,OAAO,KAAK,gBAAgB,eAAe,SAAS;AAAA,MACpD,QAAQ,QAAQ,OAAO;AAAA,QACrB,QAAQ,OAAO,UAAU;AAAA,UACvB,QAAQ;AAAA,QACV,CAAC;AAAA,QACD,QAAQ,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,QACrC,QAAQ,OAAO,MAAM;AAAA,QACrB,QAAQ,OAAO,KAAK;AAAA,MACtB;AAAA,MACA,YAAY;AAAA,QACV,IAAI,QAAQ,WAAW,QAAQ;AAAA,UAC7B,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,OAAO,SAAS,GAAG,YAAY;AAAA,QACxE,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAc,cAAsB;AAClC,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO,WAAW,IAAI,OAAO;AAAA,IAC/B;AAEA,WAAO,OAAO;AAAA,EAChB;AAAA,EAEQ,kBAA0C;AAChD,WAAO,QAAQ,OAAO,OAAO,CAAC,EAAE,OAAO,SAAS,WAAW,GAAG,KAAK,MAAM;AAEvE,YAAM,YAAY,aAAa;AAC/B,UAAI,aAAa,CAAC,KAAK,WAAW,GAAG;AACnC,aAAK,WAAW,IAAI;AAAA,MACtB;AAEA,UAAI,QAAQ,YAAY,QAAQ,QAAQ;AACtC,aAAK,QAAQ,IAAI,QAAQ,OAAO;AAAA,MAClC;AAEA,YAAM,aAAa,OAAO,QAAQ,IAAI,EACnC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;
|
|
4
|
+
"sourcesContent": ["import * as Sentry from '@sentry/node';\nimport { nodeProfilingIntegration } from '@sentry/profiling-node';\nimport cluster from 'node:cluster';\nimport winston from 'winston';\nimport type { LogOptions } from '../websocket/utils.js';\nimport { getRequestId } from '../request-context/index.js';\n\nexport type LoggerLevels =\n | 'error'\n | 'warn'\n | 'info'\n | 'command'\n | 'database'\n | 'redis'\n | 'webServer'\n | 'webSocket'\n | 'queue'\n | 'queueJob'\n | 'event'\n | 'debug';\n\nexport class Logger {\n private static instance: Logger;\n private logger: winston.Logger;\n\n private environment: string | undefined;\n\n public isSentryInitialized = false;\n\n private constructor() {\n this.environment = process.env.NODE_ENV;\n\n const customFormat = this.getCustomFormat();\n\n const customLevels: winston.config.AbstractConfigSetLevels = {\n error: 0,\n warn: 1,\n info: 2,\n command: 3,\n database: 4,\n redis: 5,\n webServer: 6,\n webSocket: 7,\n queue: 8,\n queueJob: 9,\n event: 10,\n debug: 11,\n };\n\n const customColors: winston.config.AbstractConfigSetColors = {\n error: 'red',\n warn: 'yellow',\n info: 'blue',\n command: 'cyan',\n database: 'brightGreen',\n redis: 'brightYellow',\n webServer: 'brightBlue',\n webSocket: 'brightMagenta',\n queue: 'gray',\n queueJob: 'blue',\n event: 'brightGreen',\n debug: 'brightCyan',\n };\n\n winston.addColors(customColors);\n\n this.logger = winston.createLogger({\n levels: customLevels,\n level: this.environment === 'production' ? 'info' : 'debug',\n format: winston.format.combine(\n winston.format.timestamp({\n format: 'YYYY-MM-DD HH:mm:ss',\n }),\n winston.format.errors({ stack: true }),\n winston.format.splat(),\n winston.format.json(),\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(winston.format.colorize(), customFormat),\n }),\n ],\n });\n }\n\n public static getInstance(): Logger {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n\n return Logger.instance;\n }\n\n private getCustomFormat(): winston.Logform.Format {\n return winston.format.printf(({ level, message, timestamp, ...meta }) => {\n // Auto-inject request ID from AsyncLocalStorage context if available\n const requestId = getRequestId();\n if (requestId && !meta['requestId']) {\n meta['requestId'] = requestId;\n }\n\n if (cluster.isWorker && cluster.worker) {\n meta['Worker'] = cluster.worker.id; // .process.pid;\n }\n\n const metaString = Object.entries(meta)\n .map(([key, value]) => {\n // Safely convert value to string representation\n let stringValue: string;\n\n if (value === null) {\n stringValue = 'null';\n } else if (value === undefined) {\n stringValue = 'undefined';\n } else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n stringValue = String(value);\n } else if (value instanceof Error) {\n stringValue = value.message;\n } else if (value instanceof Promise) {\n stringValue = '[Promise]';\n } else if (typeof value === 'object') {\n try {\n // Attempt to JSON.stringify, but handle circular references\n stringValue = JSON.stringify(value);\n } catch {\n // Fallback for circular references or other issues\n stringValue = '[Object]';\n }\n } else {\n stringValue = String(value);\n }\n\n return `${key}: ${stringValue}`;\n })\n .join(' | ');\n\n if (level === 'error') {\n if (this.isSentryInitialized) {\n const errorMessage = typeof message === 'string' ? message : JSON.stringify(message);\n\n Sentry.captureException(new Error(errorMessage));\n }\n }\n\n return `[${timestamp}] ${level}: ${message}${metaString ? ` (${metaString})` : ''}`;\n });\n }\n\n public initSentry({ sentryDsn, environment }: { sentryDsn: string; environment: string }): void {\n if (!sentryDsn) {\n this.logger.warn('Missing Sentry DSN when initializing Sentry');\n\n return;\n }\n\n Sentry.init({\n dsn: sentryDsn,\n integrations: [nodeProfilingIntegration()],\n tracesSampleRate: 1.0,\n environment,\n });\n\n this.isSentryInitialized = true;\n }\n\n public log({\n level,\n message,\n meta,\n options: _options,\n }: {\n level: LoggerLevels;\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void {\n // if (options?.muteWorker) {\n // }\n\n if (message instanceof Error) {\n const errorMessage = message.stack ?? message.toString();\n this.logger.log(level, errorMessage, meta);\n } else if (typeof message === 'string') {\n this.logger.log(level, message, meta);\n } else {\n this.logger.log(level, JSON.stringify(message), meta);\n }\n }\n\n public debug({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public debug(message: unknown, meta?: Record<string, unknown>): void;\n public debug(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'debug', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'debug', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n public info({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public info(message: unknown, meta?: Record<string, unknown>): void;\n public info(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'info', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'info', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n public warn({\n message,\n meta,\n options,\n }: {\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n public warn(message: unknown, meta?: Record<string, unknown>): void;\n public warn(\n messageOrOptions: unknown | { message: unknown; meta?: Record<string, unknown>; options?: LogOptions },\n meta?: Record<string, unknown>,\n ): void {\n if (typeof messageOrOptions === 'object' && messageOrOptions !== null && 'message' in messageOrOptions) {\n const {\n message,\n meta: optionsMeta,\n options,\n } = messageOrOptions as { message: unknown; meta?: Record<string, unknown>; options?: LogOptions };\n this.log({ level: 'warn', message, meta: optionsMeta, options });\n } else {\n this.log({ level: 'warn', message: messageOrOptions, meta, options: undefined });\n }\n }\n\n // Overload 1: Object signature (existing usage)\n public error(args: {\n error: Error | unknown;\n message?: string;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void;\n // Overload 2: Positional signature (new usage)\n public error(error: Error | unknown, message?: string, meta?: Record<string, unknown>, options?: LogOptions): void;\n public error(\n arg1:\n | { error: Error | unknown; message?: string; meta?: Record<string, unknown>; options?: LogOptions }\n | (Error | unknown),\n message?: string,\n meta?: Record<string, unknown>,\n options?: LogOptions,\n ): void {\n // Support original object signature: Logger.error({ error, message?, meta?, options? })\n if (\n typeof arg1 === 'object' &&\n arg1 !== null &&\n 'error' in arg1 &&\n // If the caller passed a second positional arg, treat it as new signature\n message === undefined\n ) {\n const {\n error,\n message: objMessage,\n meta: objMeta,\n options: objOptions,\n } = arg1 as {\n error: Error | unknown;\n message?: string;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n };\n\n if (objMessage) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const combinedMessage = `${objMessage}: ${errorMessage}`;\n this.log({ level: 'error', message: combinedMessage, meta: objMeta, options: objOptions });\n if (error instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(error);\n }\n } else {\n this.log({ level: 'error', message: error, meta: objMeta, options: objOptions });\n if (error instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(error);\n }\n }\n return;\n }\n\n // New positional signature: Logger.error(error, message?, meta?, options?)\n const errorObj = arg1;\n if (message) {\n const errorMessage = errorObj instanceof Error ? errorObj.message : String(errorObj);\n const combinedMessage = `${message}: ${errorMessage}`;\n this.log({ level: 'error', message: combinedMessage, meta, options });\n } else {\n this.log({ level: 'error', message: errorObj, meta, options });\n }\n if (errorObj instanceof Error && this.isSentryInitialized) {\n Sentry.captureException(errorObj);\n }\n }\n\n public custom({\n level,\n message,\n meta,\n options,\n }: {\n level: LoggerLevels;\n message: unknown;\n meta?: Record<string, unknown>;\n options?: LogOptions;\n }): void {\n this.log({ level, message, meta, options });\n }\n}\n\nexport default Logger.getInstance();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/queue/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/queue/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { default as QueueManager } from './manager.js';\nexport type { QueueItem } from './index.interface.js';\nexport type { QueueJob, QueueJobData } from './job.interface.js';\nexport { default as BaseProcessor } from './processor/base.js';\nexport type { ProcessorConstructorParams, ProcessorConstructor } from './processor/processor.interface.js';\n"],
|
|
4
|
+
"sourcesContent": ["export { default as QueueManager } from './manager.js';\nexport type { QueueItem } from './index.interface.js';\nexport type { QueueJob, QueueJobData, QueueJobPayload } from './job.interface.js';\nexport { default as BaseProcessor } from './processor/base.js';\nexport type { ProcessorConstructorParams, ProcessorConstructor } from './processor/processor.interface.js';\n"],
|
|
5
5
|
"mappings": "AAAA,SAAoB,WAAXA,gBAA+B;AAGxC,SAAoB,WAAXA,gBAAgC;",
|
|
6
6
|
"names": ["default"]
|
|
7
7
|
}
|
package/dist/queue/manager.js
CHANGED
|
@@ -25,8 +25,11 @@ class QueueManager {
|
|
|
25
25
|
databaseInstance,
|
|
26
26
|
eventManager
|
|
27
27
|
}) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if (options) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
} else {
|
|
31
|
+
this.options = { processorsDirectory: "" };
|
|
32
|
+
}
|
|
30
33
|
this.applicationConfig = applicationConfig;
|
|
31
34
|
this.redisInstance = redisInstance;
|
|
32
35
|
this.databaseInstance = databaseInstance;
|
|
@@ -58,7 +61,10 @@ class QueueManager {
|
|
|
58
61
|
Logger.error({ error });
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
|
-
registerQueue({
|
|
64
|
+
registerQueue({
|
|
65
|
+
queue,
|
|
66
|
+
jobProcessorClasses
|
|
67
|
+
}) {
|
|
62
68
|
if (!queue.jobs) {
|
|
63
69
|
Logger.warn({
|
|
64
70
|
message: "No jobs found for queue, skip register",
|
|
@@ -153,7 +159,11 @@ class QueueManager {
|
|
|
153
159
|
onQueueRemoved = /* @__PURE__ */ __name((job) => {
|
|
154
160
|
this.log("Removed queue", { Queue: job.queueName, Job: job.id });
|
|
155
161
|
}, "onQueueRemoved");
|
|
156
|
-
addJobToQueue = /* @__PURE__ */ __name(async ({
|
|
162
|
+
addJobToQueue = /* @__PURE__ */ __name(async ({
|
|
163
|
+
queueId,
|
|
164
|
+
jobId,
|
|
165
|
+
data
|
|
166
|
+
}) => {
|
|
157
167
|
const queue = this.queues.get(queueId);
|
|
158
168
|
if (!queue) {
|
|
159
169
|
this.log("Queue not found", { "Queue ID": queueId });
|
|
@@ -209,14 +219,16 @@ class QueueManager {
|
|
|
209
219
|
const jobStates = ["active", "waiting", "completed", "failed", "delayed", "paused"];
|
|
210
220
|
const jobsDetailsPromises = jobStates.map(async (state) => {
|
|
211
221
|
const jobs = await queue.getJobs([state]);
|
|
212
|
-
return jobs.map(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
return jobs.map(
|
|
223
|
+
(job) => ({
|
|
224
|
+
id: job.id ?? "unknown",
|
|
225
|
+
name: job.name ?? "unknown",
|
|
226
|
+
queueName,
|
|
227
|
+
state,
|
|
228
|
+
attemptsMade: job.attemptsMade,
|
|
229
|
+
failedReason: job.failedReason
|
|
230
|
+
})
|
|
231
|
+
);
|
|
220
232
|
});
|
|
221
233
|
const results = await Promise.all(jobsDetailsPromises);
|
|
222
234
|
const flattenedResults = results.flat();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/queue/manager.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Job,
|
|
5
|
-
"mappings": ";;AAAA,
|
|
4
|
+
"sourcesContent": ["import { type Job, Queue, type QueueOptions, type WorkerOptions } from 'bullmq';\nimport path from 'path';\nimport type { QueueManagerConstructorParams, QueueManagerOptions } from './manager.interface.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { DatabaseInstance } from '../database/index.js';\nimport { Logger } from '../logger/index.js';\nimport QueueWorker from './worker.js';\nimport type BaseProcessor from './processor/base.js';\nimport { File, Helper, Loader, Time } from '../util/index.js';\nimport type { QueueJob, QueueJobData, QueueJobPayload } from './job.interface.js';\nimport type { ProcessorConstructor } from './processor/processor.interface.js';\nimport type { QueueItem } from './index.interface.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\n\nexport interface JobSummary {\n id: string;\n name: string;\n queueName: string;\n state: 'active' | 'waiting' | 'completed' | 'failed' | 'delayed' | 'paused';\n attemptsMade: number;\n failedReason?: string;\n}\n\nexport default class QueueManager {\n private logger: typeof Logger = Logger;\n\n private applicationConfig: ApplicationConfig;\n\n private options: QueueManagerOptions;\n\n private redisInstance: RedisInstance;\n private databaseInstance: DatabaseInstance | null;\n private eventManager?: EventManager;\n\n private queues: Map<string, Queue> = new Map();\n\n private jobProcessors: Map<string, BaseProcessor> = new Map();\n\n constructor({\n applicationConfig,\n options,\n queues: _queues,\n redisInstance,\n databaseInstance,\n eventManager,\n }: QueueManagerConstructorParams) {\n // Merge options with defaults if provided\n if (options) {\n this.options = options;\n } else {\n // This shouldn't happen, but handle the edge case\n this.options = { processorsDirectory: '' };\n }\n\n this.applicationConfig = applicationConfig;\n\n this.redisInstance = redisInstance;\n this.databaseInstance = databaseInstance;\n this.eventManager = eventManager;\n }\n\n public async registerQueues({ queues }: { queues: QueueItem[] }): Promise<void> {\n if (!queues) {\n return;\n }\n\n // Check if processors directory exists\n const processorsDirectoryExists = await File.pathExists(this.options.processorsDirectory);\n\n if (!processorsDirectoryExists) {\n return;\n }\n\n try {\n const jobProcessorClasses = await Loader.loadModulesInDirectory<ProcessorConstructor>({\n directory: this.options.processorsDirectory,\n extensions: ['.ts', '.js'],\n });\n\n for (const queue of queues) {\n this.registerQueue({ queue, jobProcessorClasses });\n }\n\n if (this.applicationConfig.queue.log?.queuesRegistered) {\n this.log('Registered queue', {\n 'Queue Count': queues.length,\n 'Job Count': this.jobProcessors.size,\n });\n }\n } catch (error) {\n Logger.error({ error });\n }\n }\n\n private registerQueue({\n queue,\n jobProcessorClasses,\n }: {\n queue: QueueItem;\n jobProcessorClasses: Record<string, ProcessorConstructor>;\n }): void {\n if (!queue.jobs) {\n Logger.warn({\n message: 'No jobs found for queue, skip register',\n meta: {\n Name: queue.name,\n },\n });\n\n return;\n }\n\n const queueOptions: QueueOptions = {\n connection: this.redisInstance.client,\n defaultJobOptions: {\n removeOnComplete: true,\n removeOnFail: true,\n },\n };\n\n const queueInstance = new Queue(queue.name, queueOptions);\n\n queueInstance.on('error', this.onQueueError);\n queueInstance.on('waiting', this.onQueueWaiting);\n queueInstance.on('progress', this.onQueueProgress);\n queueInstance.on('removed', this.onQueueRemoved);\n\n if (!queue.isExternal) {\n const workerOptions: WorkerOptions = {\n connection: this.redisInstance.client,\n autorun: true,\n };\n\n new QueueWorker({\n applicationConfig: this.applicationConfig,\n queueManager: this,\n name: queue.name,\n processor: this.workerProcessor,\n options: workerOptions,\n redisInstance: this.redisInstance,\n });\n }\n\n this.queues.set(queue.name, queueInstance);\n\n if (this.applicationConfig.queue.log?.queueRegistered) {\n this.log('Registered queue', { Name: queue.name });\n }\n\n // Register job processors\n this.registerJobProcessors({\n queue,\n jobs: queue.jobs,\n jobProcessorClasses,\n });\n }\n\n private registerJobProcessors({\n queue,\n jobs,\n jobProcessorClasses,\n }: {\n queue: QueueItem;\n jobs: QueueJob[];\n jobProcessorClasses: Record<string, ProcessorConstructor>;\n }): void {\n if (!jobs) {\n return;\n }\n\n const scriptFileExtension = Helper.getScriptFileExtension();\n\n for (const job of jobs) {\n if (!queue.isExternal) {\n const ProcessorClass = jobProcessorClasses[job.id];\n\n if (!ProcessorClass) {\n const jobPath = path.join(this.options.processorsDirectory, `${job.id}.${scriptFileExtension}`);\n\n throw new Error(`Processor class not found (Job ID: ${job.id} | Path: ${jobPath})`);\n }\n\n const processorInstance = new ProcessorClass(\n this,\n this.applicationConfig,\n this.redisInstance,\n this.databaseInstance,\n this.eventManager,\n );\n\n this.jobProcessors.set(job.id, processorInstance);\n }\n\n if (this.applicationConfig.queue.log?.jobRegistered) {\n this.log('Job registered', { ID: job.id });\n }\n }\n }\n\n private onQueueError = (error: Error): void => {\n Logger.error({ error });\n };\n\n private onQueueWaiting = (job: Job): void => {\n if (this.applicationConfig.queue.log?.queueWaiting) {\n this.log('Waiting...', { Queue: job.queueName, Job: job.id });\n }\n };\n\n private onQueueProgress = (job: Job, progress: number | object): void => {\n this.log('Progress update', {\n Queue: job.queueName,\n 'Job Name': job.name,\n 'Job ID': job.id,\n Progress: progress,\n });\n };\n\n private onQueueRemoved = (job: Job): void => {\n this.log('Removed queue', { Queue: job.queueName, Job: job.id });\n };\n\n public addJobToQueue = async <\n TPayload extends QueueJobPayload = QueueJobPayload,\n TMetadata extends Record<string, unknown> = Record<string, unknown>,\n TResult = unknown,\n TName extends string = string,\n >({\n queueId,\n jobId,\n data,\n }: {\n queueId: string;\n jobId: TName;\n data: QueueJobData<TPayload, TMetadata>;\n }): Promise<Job<QueueJobData<TPayload, TMetadata>, TResult, TName> | undefined> => {\n const queue = this.queues.get(queueId);\n\n if (!queue) {\n this.log('Queue not found', { 'Queue ID': queueId });\n\n return;\n }\n\n const job = (await queue.add(jobId, data)) as Job<QueueJobData<TPayload, TMetadata>, TResult, TName>;\n\n const dataStr = JSON.stringify(data);\n\n const maxLogDataStrLength = 50;\n const truncatedLogDataStr =\n dataStr.length > maxLogDataStrLength ? `${dataStr.substring(0, maxLogDataStrLength)}...` : dataStr;\n\n if (this.applicationConfig.queue.log?.jobAdded) {\n this.log('Job added', {\n Queue: queueId,\n 'Job ID': jobId,\n Data: truncatedLogDataStr,\n });\n }\n\n return job;\n };\n\n private workerProcessor = async (job: Job): Promise<unknown> => {\n if (!job) {\n return;\n }\n\n const startTime = Time.now();\n\n // Add start time to job data\n job.updateData({ ...job.data, startTime });\n\n this.log('Worker processing...', {\n Queue: job.queueName,\n 'Job Name': job.name,\n 'Job ID': job.id,\n });\n\n const processor = this.jobProcessors.get(job.name);\n\n if (!processor) {\n throw new Error(`No processor registered for job (Name: ${job.name})`);\n }\n\n try {\n const jobResult = await processor.process({ job });\n\n return jobResult;\n } catch (error) {\n Logger.warn({\n message: 'Queue worker processing error',\n meta: {\n Queue: job.queueName,\n 'Job Name': job.name,\n 'Job ID': job.id,\n Error: (error as Error).message,\n },\n });\n\n Logger.error({ error });\n }\n };\n\n public async listAllJobsWithStatus(): Promise<JobSummary[]> {\n const jobsSummary: JobSummary[] = [];\n\n for (const [queueName, queue] of this.queues) {\n const jobStates = ['active', 'waiting', 'completed', 'failed', 'delayed', 'paused'] as const;\n\n const jobsDetailsPromises = jobStates.map(async state => {\n const jobs = await queue.getJobs([state]);\n return jobs.map(\n (job): JobSummary => ({\n id: job.id ?? 'unknown',\n name: job.name ?? 'unknown',\n queueName,\n state,\n attemptsMade: job.attemptsMade,\n failedReason: job.failedReason,\n }),\n );\n });\n\n const results = await Promise.all(jobsDetailsPromises);\n const flattenedResults = results.flat();\n\n jobsSummary.push(...flattenedResults);\n }\n\n return jobsSummary;\n }\n\n /**\n * Log queue message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'queue', message, meta });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/queue/processor/base.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Job } from 'bullmq';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type EventManager from '../../event/manager.js';\n\nexport default abstract class BaseProcessor {\n private logger: typeof Logger = Logger;\n\n constructor(\n protected queueManager:
|
|
5
|
-
"mappings": ";;AAIA,SAAS,cAAc;
|
|
4
|
+
"sourcesContent": ["import type { Job } from 'bullmq';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type EventManager from '../../event/manager.js';\nimport type { QueueJobData } from '../job.interface.js';\n\nexport default abstract class BaseProcessor<\n TQueueManager extends QueueManager = QueueManager,\n TJobData extends QueueJobData = QueueJobData,\n TResult = unknown,\n> {\n private logger: typeof Logger = Logger;\n\n constructor(\n protected queueManager: TQueueManager,\n protected applicationConfig: ApplicationConfig,\n protected redisInstance: RedisInstance,\n protected databaseInstance: DatabaseInstance | null,\n protected eventManager?: EventManager,\n ) {}\n\n public abstract process({ job }: { job: Job<TJobData, TResult> }): Promise<TResult>;\n\n /**\n * Enhanced logger with structured methods\n */\n public log = {\n error: (error: Error | unknown, message?: string, meta?: Record<string, unknown>): void => {\n if (message) {\n const errorMeta = {\n ...(meta ?? {}),\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n this.logger.custom({ level: 'queueJob', message, meta: errorMeta });\n } else {\n this.logger.custom({ level: 'queueJob', message: error });\n }\n },\n\n info: (message: string, meta?: Record<string, unknown>): void => {\n this.logger.custom({ level: 'queueJob', message, meta });\n },\n\n warn: (message: string, meta?: Record<string, unknown>): void => {\n this.logger.custom({ level: 'queueJob', message, meta });\n },\n\n debug: (message: string, meta?: Record<string, unknown>): void => {\n this.logger.custom({ level: 'queueJob', message, meta });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;AAIA,SAAS,cAAc;AAKvB,MAAO,cAIL;AAAA,EAGA,YACY,cACA,mBACA,eACA,kBACA,cACV;AALU;AACA;AACA;AACA;AACA;AAAA,EACT;AAAA,EAtBL,OAaE;AAAA;AAAA;AAAA,EACQ,SAAwB;AAAA;AAAA;AAAA;AAAA,EAezB,MAAM;AAAA,IACX,OAAO,wBAAC,OAAwB,SAAkB,SAAyC;AACzF,UAAI,SAAS;AACX,cAAM,YAAY;AAAA,UAChB,GAAI,QAAQ,CAAC;AAAA,UACb,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ;AAAA,QAChD;AACA,aAAK,OAAO,OAAO,EAAE,OAAO,YAAY,SAAS,MAAM,UAAU,CAAC;AAAA,MACpE,OAAO;AACL,aAAK,OAAO,OAAO,EAAE,OAAO,YAAY,SAAS,MAAM,CAAC;AAAA,MAC1D;AAAA,IACF,GAXO;AAAA,IAaP,MAAM,wBAAC,SAAiB,SAAyC;AAC/D,WAAK,OAAO,OAAO,EAAE,OAAO,YAAY,SAAS,KAAK,CAAC;AAAA,IACzD,GAFM;AAAA,IAIN,MAAM,wBAAC,SAAiB,SAAyC;AAC/D,WAAK,OAAO,OAAO,EAAE,OAAO,YAAY,SAAS,KAAK,CAAC;AAAA,IACzD,GAFM;AAAA,IAIN,OAAO,wBAAC,SAAiB,SAAyC;AAChE,WAAK,OAAO,OAAO,EAAE,OAAO,YAAY,SAAS,KAAK,CAAC;AAAA,IACzD,GAFO;AAAA,EAGT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/aws/s3.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n CompleteMultipartUploadCommand,\n CreateMultipartUploadCommand,\n GetObjectCommand,\n PutObjectCommand,\n type PutObjectCommandInput,\n S3Client,\n type S3ClientConfig,\n UploadPartCommand,\n} from '@aws-sdk/client-s3';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { File, Helper } from '../../util/index.js';\nimport type { AwsS3ConstructorOptions } from './s3.interface.js';\nimport { createWriteStream } from 'fs';\nimport { Readable, pipeline } from 'stream';\nimport { promisify } from 'node:util';\nimport { Logger } from '../../logger/index.js';\nimport { dirname } from 'path';\n\nconst asyncPipeline = promisify(pipeline);\n\ninterface DownloadFileOptions {\n bucketName: string;\n key: string;\n destinationFilePath: string;\n}\n\nexport default class AwsS3 {\n public client: S3Client;\n\n private options: AwsS3ConstructorOptions;\n\n constructor(options: Partial<AwsS3ConstructorOptions>) {\n // Define default options\n const defaultOptions:
|
|
5
|
-
"mappings": ";;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,oBAAoB;AAC7B,SAAS,MAAM,cAAc;AAE7B,SAAS,yBAAyB;AAClC,SAAS,UAAU,gBAAgB;AACnC,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,eAAe;AAExB,MAAM,gBAAgB,UAAU,QAAQ;AAQxC,MAAO,MAAoB;AAAA,EA3B3B,OA2B2B;AAAA;AAAA;AAAA,EAClB;AAAA,EAEC;AAAA,EAER,YAAY,SAA2C;AAErD,UAAM,
|
|
4
|
+
"sourcesContent": ["import {\n CompleteMultipartUploadCommand,\n CreateMultipartUploadCommand,\n GetObjectCommand,\n PutObjectCommand,\n type PutObjectCommandInput,\n S3Client,\n type S3ClientConfig,\n UploadPartCommand,\n} from '@aws-sdk/client-s3';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { File, Helper } from '../../util/index.js';\nimport type { AwsS3ConstructorOptions } from './s3.interface.js';\nimport { createWriteStream } from 'fs';\nimport { Readable, pipeline } from 'stream';\nimport { promisify } from 'node:util';\nimport { Logger } from '../../logger/index.js';\nimport { dirname } from 'path';\n\nconst asyncPipeline = promisify(pipeline);\n\ninterface DownloadFileOptions {\n bucketName: string;\n key: string;\n destinationFilePath: string;\n}\n\nexport default class AwsS3 {\n public client: S3Client;\n\n private options: AwsS3ConstructorOptions;\n\n constructor(options: Partial<AwsS3ConstructorOptions>) {\n // Define default options\n const defaultOptions: AwsS3ConstructorOptions = {\n region: 'us-east-1',\n localstack: {\n enabled: false,\n port: 4566,\n },\n };\n\n this.options = Helper.defaultsDeep(options, defaultOptions) as AwsS3ConstructorOptions;\n\n const s3ClientConfig: S3ClientConfig = {\n region: this.options.region,\n };\n\n if (this.options.localstack.enabled) {\n s3ClientConfig.forcePathStyle = true;\n\n if (!this.options.endpoint) {\n throw new Error('Endpoint is required when using LocalStack');\n }\n\n // s3ClientConfig.endpoint = `http://s3.localhost.localstack.cloud:${this.options.localstack.port}`; // Works when the Node.js API is calling from within the Docker container\n // s3ClientConfig.endpoint = `http://localhost:${this.options.localstack.port}`; // works out side of the container (media generator example)\n\n s3ClientConfig.endpoint = this.options.endpoint;\n\n s3ClientConfig.credentials = {\n accessKeyId: 'test',\n secretAccessKey: 'test',\n };\n } else {\n if (this.options.credentials?.accessKeyId && this.options.credentials?.secretAccessKey) {\n s3ClientConfig.credentials = {\n accessKeyId: this.options.credentials.accessKeyId,\n secretAccessKey: this.options.credentials.secretAccessKey,\n };\n }\n }\n\n this.client = new S3Client(s3ClientConfig);\n }\n\n private getBucketUrl({ bucketName, path }: { bucketName: string; path: string }) {\n let url;\n\n if (this.options.localstack.enabled) {\n url = `http://localhost:${this.options.localstack.port}/${bucketName}/${path}`;\n } else {\n url = `https://${bucketName}.s3.amazonaws.com/${path}`;\n }\n\n return url;\n }\n\n public async uploadFile({\n bucketName,\n path,\n body,\n contentType,\n forceDownload,\n publicRead,\n }: {\n bucketName: string;\n path: string;\n body: Buffer;\n contentType?: string;\n forceDownload?: boolean;\n publicRead?: boolean;\n }): Promise<string> {\n let contentDisposition = forceDownload ? 'attachment' : 'inline';\n contentDisposition += `; filename=\"${path.split('/').pop()}\"`;\n\n const putObjectOptions: PutObjectCommandInput = {\n Bucket: bucketName,\n Key: path,\n Body: body,\n ContentDisposition: contentDisposition,\n ACL: publicRead ? 'public-read' : 'private',\n };\n\n if (contentType) {\n putObjectOptions.ContentType = contentType;\n }\n\n const command = new PutObjectCommand(putObjectOptions);\n\n await this.client.send(command);\n\n return this.getBucketUrl({ bucketName, path });\n }\n\n public async startMultipartUpload({\n bucketName,\n path,\n publicRead,\n }: {\n bucketName: string;\n path: string;\n publicRead?: boolean;\n }) {\n const command = new CreateMultipartUploadCommand({\n Bucket: bucketName,\n Key: path,\n ACL: publicRead ? 'public-read' : 'private',\n });\n\n const response = await this.client.send(command);\n\n return response.UploadId;\n }\n\n public async uploadPart({\n bucketName,\n path,\n partNumber,\n uploadId,\n body,\n }: {\n bucketName: string;\n path: string;\n partNumber: number;\n uploadId: string;\n body: any;\n }): Promise<string | undefined> {\n const command = new UploadPartCommand({\n Bucket: bucketName,\n Key: path,\n PartNumber: partNumber,\n UploadId: uploadId,\n Body: body,\n });\n\n const response = await this.client.send(command);\n\n return response.ETag;\n }\n\n public async completeMultipartUpload({\n bucketName,\n path,\n uploadId,\n parts,\n }: {\n bucketName: string;\n path: string;\n uploadId: string;\n parts: { PartNumber: number; ETag: string }[];\n }) {\n // Sort parts by PartNumber\n parts.sort((a, b) => a.PartNumber - b.PartNumber);\n\n const command = new CompleteMultipartUploadCommand({\n Bucket: bucketName,\n Key: path,\n UploadId: uploadId,\n MultipartUpload: {\n Parts: parts,\n },\n });\n\n const response = await this.client.send(command);\n\n if (!response.Location) {\n throw new Error('Failed to complete multipart upload');\n }\n\n // return response.Location;\n return this.getBucketUrl({\n bucketName,\n path,\n });\n }\n\n async downloadFile({\n bucketName,\n key,\n destinationFilePath,\n onStart,\n onProgress,\n onComplete,\n onError,\n }: DownloadFileOptions & {\n onStart?: () => void;\n onProgress?: (progress: number) => void;\n onComplete?: () => void;\n onError?: (error: Error) => void;\n }): Promise<void> {\n const decodedKey = decodeURIComponent(key);\n const bucketKey = decodedKey;\n\n Logger.info({\n message: 'Downloading file from S3',\n meta: {\n bucketName,\n Key: bucketKey,\n },\n });\n\n const getObjectParams = {\n Bucket: bucketName,\n Key: bucketKey,\n };\n\n try {\n const command = new GetObjectCommand(getObjectParams);\n\n const response = await this.client.send(command);\n\n if (!response.Body || !(response.Body instanceof Readable)) {\n throw new Error('Expected Body to be a readable stream!');\n }\n\n if (onStart) {\n onStart();\n }\n\n const directoryPath = dirname(destinationFilePath);\n\n // Ensure directory exists\n await File.ensureDir(directoryPath);\n\n const fileStream = createWriteStream(destinationFilePath);\n const totalSize = parseInt(response.ContentLength?.toString() ?? '0', 10);\n\n let bytesRead = 0;\n\n response.Body.on('data', (chunk: Buffer) => {\n bytesRead += chunk.length;\n\n if (onProgress && totalSize > 0) {\n const progress = Math.min((bytesRead / totalSize) * 100, 100);\n const formattedProgress = parseFloat(progress.toFixed(1));\n\n onProgress(formattedProgress);\n }\n });\n\n await asyncPipeline(response.Body, fileStream);\n\n // Verify file was written\n if (!(await File.pathExists(destinationFilePath))) {\n throw new Error(`Could not find downloaded file at ${destinationFilePath}`);\n }\n\n Logger.info({\n message: 'File successfully downloaded',\n meta: {\n Path: destinationFilePath,\n },\n });\n\n if (onComplete) {\n onComplete();\n }\n } catch (error) {\n Logger.error({ error });\n\n if (onError) {\n onError(error as Error);\n }\n\n throw error as Error;\n }\n }\n\n public async generateSignedUrl({ bucket, key }: { bucket: string; key: string }): Promise<string> {\n try {\n const command = new GetObjectCommand({\n Bucket: bucket,\n Key: key,\n });\n\n // Set the expiration for the signed URL to 1 hour\n const signedUrl = await getSignedUrl(this.client, command, {\n expiresIn: 3600,\n });\n\n // Log the signed URL\n Logger.info({\n message: 'Generated signed URL',\n meta: {\n URL: signedUrl,\n },\n });\n\n return signedUrl;\n } catch (error) {\n Logger.error({ error });\n\n throw error;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/util/helper.js
CHANGED
|
@@ -14,7 +14,7 @@ function defaultsDeep(target, ...sources) {
|
|
|
14
14
|
}
|
|
15
15
|
__name(defaultsDeep, "defaultsDeep");
|
|
16
16
|
function isObject(item) {
|
|
17
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
17
|
+
return item !== null && typeof item === "object" && !Array.isArray(item);
|
|
18
18
|
}
|
|
19
19
|
__name(isObject, "isObject");
|
|
20
20
|
function getValueFromObject(obj, path) {
|
package/dist/util/helper.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/util/helper.ts"],
|
|
4
|
-
"sourcesContent": ["import lodashDefaultsDeep from 'lodash.defaultsdeep';\n\n/**\n * Deep merge objects with defaults, preventing prototype pollution.\n *\n * This is a secure wrapper around lodash.defaultsdeep that:\n * - Sanitizes sources to remove dangerous keys (__proto__, constructor, prototype)\n * - Delegates to battle-tested lodash.defaultsdeep for merge logic\n * - Maintains backward compatibility with existing usage\n *\n * @param target - The target object to merge into\n * @param sources - Source objects providing default values\n * @returns The merged target object (mutated)\n *\n * @example\n * const userConfig = { host: 'localhost' };\n * const defaults = { host: '0.0.0.0', port: 3001 };\n * const merged = defaultsDeep(userConfig, defaults);\n * // merged = { host: 'localhost', port: 3001 }\n */\nfunction defaultsDeep(target:
|
|
5
|
-
"mappings": ";;AAAA,OAAO,wBAAwB;AAoB/B,SAAS,
|
|
4
|
+
"sourcesContent": ["import lodashDefaultsDeep from 'lodash.defaultsdeep';\n\n/**\n * Deep merge objects with defaults, preventing prototype pollution.\n *\n * This is a secure wrapper around lodash.defaultsdeep that:\n * - Sanitizes sources to remove dangerous keys (__proto__, constructor, prototype)\n * - Delegates to battle-tested lodash.defaultsdeep for merge logic\n * - Maintains backward compatibility with existing usage\n *\n * @param target - The target object to merge into\n * @param sources - Source objects providing default values\n * @returns The merged target object (mutated)\n *\n * @example\n * const userConfig = { host: 'localhost' };\n * const defaults = { host: '0.0.0.0', port: 3001 };\n * const merged = defaultsDeep(userConfig, defaults);\n * // merged = { host: 'localhost', port: 3001 }\n */\nfunction defaultsDeep<T extends object>(target: T, ...sources: Array<Partial<T>>): T {\n // Sanitize sources to prevent prototype pollution\n const sanitizedSources = sources.map(source => {\n if (!isObject(source)) return source;\n\n // Create a copy and remove dangerous properties\n const sanitized: Record<string, unknown> = { ...source };\n delete sanitized['__proto__'];\n delete sanitized['constructor'];\n delete sanitized['prototype'];\n return sanitized;\n });\n\n // Delegate to lodash.defaultsdeep with sanitized sources\n return lodashDefaultsDeep(target, ...sanitizedSources) as T;\n}\n\n/**\n * Check if a value is an object.\n */\nfunction isObject(item: unknown): item is Record<string, unknown> {\n return item !== null && typeof item === 'object' && !Array.isArray(item);\n}\n\ntype AnyObject = Record<string, unknown>;\n\n/**\n * Retrieves the value from an object using a dotted key path safely.\n *\n * @param obj - The object to retrieve the value from.\n * @param path - The dotted key path (e.g., 'user.email').\n * @returns The value at the specified key path or undefined if not found.\n */\nfunction getValueFromObject(obj: AnyObject, path: string): unknown {\n const parts = path.split('.');\n let current: any = obj;\n for (const part of parts) {\n if (part === '__proto__' || part === 'constructor' || part === 'prototype') return undefined;\n if (!current || !Object.prototype.hasOwnProperty.call(current, part)) return undefined;\n // Access guarded by ownProperty check and blocked prototype keys\n // eslint-disable-next-line security/detect-object-injection\n current = (current as Record<string, any>)[part];\n }\n return current;\n}\n\n/**\n * Retrieves the value from an array of objects using a dotted key path.\n *\n * @param arr - The array of objects.\n * @param path - The dotted key path (e.g., 'user.email').\n * @returns An array of values at the specified key path from each object.\n */\nfunction getValueFromArray(arr: AnyObject[], path: string): unknown[] {\n return arr.map(obj => getValueFromObject(obj, path));\n}\n\nfunction getScriptFileExtension(): string {\n return process.env.NODE_ENV === 'development' ? 'ts' : 'js';\n}\n\nexport default {\n defaultsDeep,\n isObject,\n getValueFromArray,\n getValueFromObject,\n getScriptFileExtension,\n};\n"],
|
|
5
|
+
"mappings": ";;AAAA,OAAO,wBAAwB;AAoB/B,SAAS,aAA+B,WAAc,SAA+B;AAEnF,QAAM,mBAAmB,QAAQ,IAAI,YAAU;AAC7C,QAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAG9B,UAAM,YAAqC,EAAE,GAAG,OAAO;AACvD,WAAO,UAAU,WAAW;AAC5B,WAAO,UAAU,aAAa;AAC9B,WAAO,UAAU,WAAW;AAC5B,WAAO;AAAA,EACT,CAAC;AAGD,SAAO,mBAAmB,QAAQ,GAAG,gBAAgB;AACvD;AAfS;AAoBT,SAAS,SAAS,MAAgD;AAChE,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;AACzE;AAFS;AAaT,SAAS,mBAAmB,KAAgB,MAAuB;AACjE,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,MAAI,UAAe;AACnB,aAAW,QAAQ,OAAO;AACxB,QAAI,SAAS,eAAe,SAAS,iBAAiB,SAAS,YAAa,QAAO;AACnF,QAAI,CAAC,WAAW,CAAC,OAAO,UAAU,eAAe,KAAK,SAAS,IAAI,EAAG,QAAO;AAG7E,cAAW,QAAgC,IAAI;AAAA,EACjD;AACA,SAAO;AACT;AAXS;AAoBT,SAAS,kBAAkB,KAAkB,MAAyB;AACpE,SAAO,IAAI,IAAI,SAAO,mBAAmB,KAAK,IAAI,CAAC;AACrD;AAFS;AAIT,SAAS,yBAAiC;AACxC,SAAO,QAAQ,IAAI,aAAa,gBAAgB,OAAO;AACzD;AAFS;AAIT,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/util/loader.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/util/loader.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'fs';\nimport path from 'path';\nimport { LRUCache } from 'lru-cache';\nimport { Helper } from './index.js';\n\n// Cache for loaded modules to avoid repeated imports\n// Using LRU cache to prevent unbounded memory growth in long-running processes\nconst moduleCache = new LRUCache<string,
|
|
5
|
-
"mappings": ";;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,cAAc;
|
|
4
|
+
"sourcesContent": ["import fs from 'fs';\nimport path from 'path';\nimport { LRUCache } from 'lru-cache';\nimport { Helper } from './index.js';\n\n// Type for a map of loaded modules\nexport interface ModuleMap<T = unknown> {\n [key: string]: T;\n}\n\n// Cache for loaded modules to avoid repeated imports\n// Using LRU cache to prevent unbounded memory growth in long-running processes\nconst moduleCache = new LRUCache<string, ModuleMap>({\n max: 100, // Max 100 directories cached\n ttl: 1000 * 60 * 10, // 10 minutes\n});\n\nconst entityCache = new LRUCache<string, EntityClass>({\n max: 500, // Max 500 entities cached (accessed more frequently than modules)\n ttl: 1000 * 60 * 10, // 10 minutes\n});\n\nconst loadModulesInDirectory = async <T = unknown>({\n directory,\n extensions,\n}: {\n directory: string;\n extensions?: string[];\n}): Promise<ModuleMap<T>> => {\n // Create cache key based on directory and extensions\n const cacheKey = `${directory}:${extensions?.join(',') ?? 'all'}`;\n\n // Check cache first\n if (moduleCache.has(cacheKey)) {\n const cachedModule = moduleCache.get(cacheKey);\n if (cachedModule) {\n return cachedModule as ModuleMap<T>;\n }\n }\n\n const loadedModules: ModuleMap<T> = {};\n\n // Use readdir with withFileTypes option to avoid separate stat calls\n const dirents = await fs.promises.readdir(directory, { withFileTypes: true });\n\n for (const dirent of dirents) {\n // Skip directories without needing stat call\n if (dirent.isDirectory()) {\n continue;\n }\n\n const file = dirent.name;\n const ext = path.extname(file);\n const isDeclarationFile = file.endsWith('.d.ts');\n\n // Skip files that are not in the specified extensions or are .d.ts files\n if ((extensions && extensions.length > 0 && !extensions.includes(ext)) || isDeclarationFile) {\n continue;\n }\n\n const moduleName = path.basename(file, ext);\n const filePath = path.join(directory, file);\n\n try {\n const importedModule = await import(filePath);\n\n // Use safe property assignment to prevent prototype pollution\n if (moduleName !== '__proto__' && moduleName !== 'constructor' && moduleName !== 'prototype') {\n Reflect.set(loadedModules, moduleName, importedModule.default);\n }\n } catch (error) {\n console.error(`Failed to import module ${filePath}:`, error);\n }\n }\n\n // Cache the results for future use\n moduleCache.set(cacheKey, loadedModules);\n\n return loadedModules;\n};\n\n// Type constraint for entity classes (must be constructable)\nexport type EntityClass<T = unknown> = new (...args: unknown[]) => T;\n\nconst loadEntityModule = async <T = unknown>({\n entitiesDirectory,\n entityName,\n}: {\n entitiesDirectory: string;\n entityName: string;\n}): Promise<EntityClass<T>> => {\n // Create cache key based on directory and entity name\n const cacheKey = `${entitiesDirectory}:${entityName}`;\n\n // Check cache first\n if (entityCache.has(cacheKey)) {\n return entityCache.get(cacheKey) as EntityClass<T>;\n }\n\n // Define entity module path\n const entityModulePath = path.join(entitiesDirectory, `${entityName}.${Helper.getScriptFileExtension()}`);\n\n // Import entity module\n const entityModule = await import(entityModulePath);\n\n // Safe property access to prevent prototype pollution\n if (entityName === '__proto__' || entityName === 'constructor' || entityName === 'prototype') {\n throw new Error(`Invalid entity name (Entity: ${entityName})`);\n }\n\n if (!entityModule || !Object.prototype.hasOwnProperty.call(entityModule, entityName)) {\n throw new Error(`Entity not found (Entity: ${entityName})`);\n }\n\n // Get entity class\n const EntityClass = Reflect.get(entityModule, entityName);\n\n // Cache the entity for future use\n entityCache.set(cacheKey, EntityClass);\n\n return EntityClass;\n};\n\n// Cache management functions for development/testing\nconst clearModuleCache = (): void => {\n moduleCache.clear();\n entityCache.clear();\n};\n\nconst getCacheStats = (): { modulesCached: number; entitiesCached: number } => {\n return {\n modulesCached: moduleCache.size,\n entitiesCached: entityCache.size,\n };\n};\n\nexport default {\n loadModulesInDirectory,\n loadEntityModule,\n clearModuleCache,\n getCacheStats,\n};\n"],
|
|
5
|
+
"mappings": ";;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,cAAc;AASvB,MAAM,cAAc,IAAI,SAA4B;AAAA,EAClD,KAAK;AAAA;AAAA,EACL,KAAK,MAAO,KAAK;AAAA;AACnB,CAAC;AAED,MAAM,cAAc,IAAI,SAA8B;AAAA,EACpD,KAAK;AAAA;AAAA,EACL,KAAK,MAAO,KAAK;AAAA;AACnB,CAAC;AAED,MAAM,yBAAyB,8BAAoB;AAAA,EACjD;AAAA,EACA;AACF,MAG6B;AAE3B,QAAM,WAAW,GAAG,SAAS,IAAI,YAAY,KAAK,GAAG,KAAK,KAAK;AAG/D,MAAI,YAAY,IAAI,QAAQ,GAAG;AAC7B,UAAM,eAAe,YAAY,IAAI,QAAQ;AAC7C,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,gBAA8B,CAAC;AAGrC,QAAM,UAAU,MAAM,GAAG,SAAS,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AAE5E,aAAW,UAAU,SAAS;AAE5B,QAAI,OAAO,YAAY,GAAG;AACxB;AAAA,IACF;AAEA,UAAM,OAAO,OAAO;AACpB,UAAM,MAAM,KAAK,QAAQ,IAAI;AAC7B,UAAM,oBAAoB,KAAK,SAAS,OAAO;AAG/C,QAAK,cAAc,WAAW,SAAS,KAAK,CAAC,WAAW,SAAS,GAAG,KAAM,mBAAmB;AAC3F;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,SAAS,MAAM,GAAG;AAC1C,UAAM,WAAW,KAAK,KAAK,WAAW,IAAI;AAE1C,QAAI;AACF,YAAM,iBAAiB,MAAM,OAAO;AAGpC,UAAI,eAAe,eAAe,eAAe,iBAAiB,eAAe,aAAa;AAC5F,gBAAQ,IAAI,eAAe,YAAY,eAAe,OAAO;AAAA,MAC/D;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,2BAA2B,QAAQ,KAAK,KAAK;AAAA,IAC7D;AAAA,EACF;AAGA,cAAY,IAAI,UAAU,aAAa;AAEvC,SAAO;AACT,GAzD+B;AA8D/B,MAAM,mBAAmB,8BAAoB;AAAA,EAC3C;AAAA,EACA;AACF,MAG+B;AAE7B,QAAM,WAAW,GAAG,iBAAiB,IAAI,UAAU;AAGnD,MAAI,YAAY,IAAI,QAAQ,GAAG;AAC7B,WAAO,YAAY,IAAI,QAAQ;AAAA,EACjC;AAGA,QAAM,mBAAmB,KAAK,KAAK,mBAAmB,GAAG,UAAU,IAAI,OAAO,uBAAuB,CAAC,EAAE;AAGxG,QAAM,eAAe,MAAM,OAAO;AAGlC,MAAI,eAAe,eAAe,eAAe,iBAAiB,eAAe,aAAa;AAC5F,UAAM,IAAI,MAAM,gCAAgC,UAAU,GAAG;AAAA,EAC/D;AAEA,MAAI,CAAC,gBAAgB,CAAC,OAAO,UAAU,eAAe,KAAK,cAAc,UAAU,GAAG;AACpF,UAAM,IAAI,MAAM,6BAA6B,UAAU,GAAG;AAAA,EAC5D;AAGA,QAAM,cAAc,QAAQ,IAAI,cAAc,UAAU;AAGxD,cAAY,IAAI,UAAU,WAAW;AAErC,SAAO;AACT,GArCyB;AAwCzB,MAAM,mBAAmB,6BAAY;AACnC,cAAY,MAAM;AAClB,cAAY,MAAM;AACpB,GAHyB;AAKzB,MAAM,gBAAgB,6BAAyD;AAC7E,SAAO;AAAA,IACL,eAAe,YAAY;AAAA,IAC3B,gBAAgB,YAAY;AAAA,EAC9B;AACF,GALsB;AAOtB,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/webserver/controller/base.ts"],
|
|
4
|
-
"sourcesContent": ["import { StatusCodes } from 'http-status-codes';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { ApiError, ApiResponse, WebServerBaseControllerConstructorParams } from './base.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport type EventManager from '../../event/manager.js';\nimport cluster from 'cluster';\nimport type { WebServerOptions } from '../webserver.interface.js';\nimport type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';\nimport Jwt from '../../auth/jwt.js';\n\nexport interface AuthenticatedUser {\n userId: number;\n payload:
|
|
5
|
-
"mappings": ";;AAAA,SAAS,mBAAmB;AAM5B,SAAS,cAAc;AAGvB,OAAO,aAAa;AAGpB,OAAO,SAAS;AAOhB,MAAO,
|
|
4
|
+
"sourcesContent": ["import { StatusCodes } from 'http-status-codes';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { ApiError, ApiResponse, WebServerBaseControllerConstructorParams } from './base.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport type EventManager from '../../event/manager.js';\nimport cluster from 'cluster';\nimport type { WebServerOptions } from '../webserver.interface.js';\nimport type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';\nimport Jwt from '../../auth/jwt.js';\n\nexport interface AuthenticatedUser<TPayload = Record<string, unknown>> {\n userId: number;\n payload: TPayload;\n}\n\nexport default abstract class BaseController<\n TQueueManager extends QueueManager = QueueManager,\n TRedisInstance extends RedisInstance = RedisInstance,\n TEventManager extends EventManager = EventManager,\n TDatabaseInstance extends DatabaseInstance = DatabaseInstance,\n> {\n protected workerId: number | undefined;\n\n protected applicationConfig: ApplicationConfig;\n protected webServerOptions: WebServerOptions;\n\n protected redisInstance: TRedisInstance;\n protected queueManager: TQueueManager;\n protected eventManager: TEventManager;\n protected databaseInstance: TDatabaseInstance;\n protected lifecycleManager: LifecycleManager;\n\n constructor({\n applicationConfig,\n webServerOptions,\n redisInstance,\n queueManager,\n eventManager,\n databaseInstance,\n lifecycleManager,\n }: WebServerBaseControllerConstructorParams<TQueueManager, TRedisInstance, TEventManager, TDatabaseInstance>) {\n this.workerId = cluster.worker?.id;\n\n this.applicationConfig = applicationConfig;\n this.webServerOptions = webServerOptions;\n\n this.redisInstance = redisInstance;\n this.queueManager = queueManager;\n this.eventManager = eventManager;\n this.databaseInstance = databaseInstance;\n this.lifecycleManager = lifecycleManager;\n }\n\n protected sendSuccessResponse<T = unknown>({\n reply,\n data,\n statusCode = StatusCodes.OK,\n meta,\n }: {\n reply: FastifyReply;\n data: T;\n statusCode?: StatusCodes;\n meta?: ApiResponse<T>['meta'];\n }) {\n const response: ApiResponse<T> = {\n data,\n meta: {\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...meta,\n },\n };\n reply.status(statusCode).send(response);\n }\n\n protected sendNotFoundResponse(reply: FastifyReply, message: string = 'Resource not found') {\n const error: ApiError = {\n message,\n type: 'not_found',\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n };\n const response: ApiResponse = { error };\n reply.status(StatusCodes.NOT_FOUND).send(response);\n }\n\n protected sendErrorResponse({\n reply,\n error,\n statusCode = StatusCodes.BAD_REQUEST,\n errorType,\n }: {\n reply: FastifyReply;\n error: unknown;\n statusCode?: StatusCodes;\n errorType?: ApiError['type'];\n }) {\n let publicErrorMessage: string;\n let errorDetails: Record<string, unknown> | undefined = undefined;\n\n if (this.webServerOptions.errors?.verbose === true) {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n } else {\n if (process.env.NODE_ENV === 'production') {\n if (error instanceof Error) {\n publicErrorMessage = 'Something went wrong';\n } else if (typeof error === 'string') {\n publicErrorMessage = error;\n } else {\n publicErrorMessage = 'An unknown error occurred';\n }\n } else {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n }\n }\n\n Logger.custom({ level: 'webServer', message: error });\n console.error(error);\n\n const apiError: ApiError = {\n message: publicErrorMessage,\n type: errorType ?? this.getErrorType(statusCode),\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...(errorDetails && { details: errorDetails }),\n };\n\n const response: ApiResponse = { error: apiError };\n reply.status(statusCode).send(response);\n }\n\n private getErrorType(statusCode: StatusCodes): ApiError['type'] {\n switch (statusCode) {\n case StatusCodes.UNAUTHORIZED:\n return 'authentication';\n case StatusCodes.FORBIDDEN:\n return 'authorization';\n case StatusCodes.NOT_FOUND:\n return 'not_found';\n case StatusCodes.BAD_REQUEST:\n case StatusCodes.UNPROCESSABLE_ENTITY:\n return 'validation';\n case StatusCodes.INTERNAL_SERVER_ERROR:\n case StatusCodes.BAD_GATEWAY:\n case StatusCodes.SERVICE_UNAVAILABLE:\n return 'server_error';\n default:\n return 'client_error';\n }\n }\n\n protected async authenticateRequest(request: FastifyRequest, reply: FastifyReply): Promise<AuthenticatedUser | null> {\n // Get JWT secret key from application config\n const jwtSecretKey = this.applicationConfig.auth?.jwtSecretKey;\n\n if (!jwtSecretKey) {\n this.sendErrorResponse({\n reply,\n error: 'Authentication not configured.',\n statusCode: StatusCodes.INTERNAL_SERVER_ERROR,\n errorType: 'server_error',\n });\n return null;\n }\n\n const authHeader = request.headers.authorization;\n\n if (!authHeader) {\n this.sendErrorResponse({\n reply,\n error: 'No token provided.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n if (!authHeader.startsWith('Bearer ')) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n try {\n const importedJwtSecretKey = await Jwt.importJwtSecretKey({\n jwtSecretKey,\n });\n\n // Remove \"Bearer \" from token\n const jwtAccessToken = authHeader.substring(7);\n\n const { payload } = await Jwt.jwtVerify(jwtAccessToken, importedJwtSecretKey);\n\n if (!payload.sub) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token payload.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n const userId = parseInt(payload.sub);\n\n return {\n userId,\n payload,\n };\n } catch {\n this.sendErrorResponse({\n reply,\n error: 'Invalid or expired token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
import {
|
|
4
|
+
WebServerRouteType
|
|
5
|
+
} from "./webserver.interface.js";
|
|
6
|
+
function defineRoute({ method, path, schema, handler }) {
|
|
7
|
+
const route = {
|
|
8
|
+
type: WebServerRouteType.Default,
|
|
9
|
+
method,
|
|
10
|
+
path,
|
|
11
|
+
handler
|
|
12
|
+
};
|
|
13
|
+
if (schema) {
|
|
14
|
+
route.schema = schema;
|
|
15
|
+
}
|
|
16
|
+
return route;
|
|
17
|
+
}
|
|
18
|
+
__name(defineRoute, "defineRoute");
|
|
19
|
+
export {
|
|
20
|
+
defineRoute
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=define-route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/webserver/define-route.ts"],
|
|
4
|
+
"sourcesContent": ["import type { HTTPMethods } from 'fastify';\nimport {\n type AnyRouteSchemaDefinition,\n type RouteSchemaDefinition,\n type WebServerRoute,\n WebServerRouteType,\n} from './webserver.interface.js';\nimport type { ControllerAction } from './controller/base.interface.js';\n\nexport interface DefineRouteConfig<\n Schema extends RouteSchemaDefinition<any, any, any, any, any> | undefined,\n Handler extends ControllerAction<Schema>,\n> {\n method: HTTPMethods | HTTPMethods[];\n path: string;\n schema?: Schema;\n handler: Handler;\n}\n\nexport function defineRoute<\n Schema extends RouteSchemaDefinition<any, any, any, any, any> | undefined,\n Handler extends ControllerAction<Schema>,\n>({ method, path, schema, handler }: DefineRouteConfig<Schema, Handler>): WebServerRoute {\n const route: WebServerRoute = {\n type: WebServerRouteType.Default,\n method,\n path,\n handler: handler as ControllerAction<any>,\n };\n\n if (schema) {\n route.schema = schema as AnyRouteSchemaDefinition;\n }\n\n return route;\n}\n\nexport type DefineRoute = typeof defineRoute;\n"],
|
|
5
|
+
"mappings": ";;AACA;AAAA,EAIE;AAAA,OACK;AAaA,SAAS,YAGd,EAAE,QAAQ,MAAM,QAAQ,QAAQ,GAAuD;AACvF,QAAM,QAAwB;AAAA,IAC5B,MAAM,mBAAmB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ;AACV,UAAM,SAAS;AAAA,EACjB;AAEA,SAAO;AACT;AAhBgB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/webserver/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { default as default5 } from "./controller/entity.js";
|
|
|
6
6
|
import { default as default6 } from "./controller/example-auth.js";
|
|
7
7
|
import { default as default7 } from "./util.js";
|
|
8
8
|
import { withAuth } from "./controller/auth-middleware.js";
|
|
9
|
+
import { defineRoute } from "./define-route.js";
|
|
9
10
|
export {
|
|
10
11
|
default6 as ExampleAuthController,
|
|
11
12
|
default7 as RouteUtil,
|
|
@@ -14,6 +15,7 @@ export {
|
|
|
14
15
|
default5 as WebServerEntityController,
|
|
15
16
|
default4 as WebServerHealthController,
|
|
16
17
|
WebServerRouteType,
|
|
18
|
+
defineRoute,
|
|
17
19
|
withAuth
|
|
18
20
|
};
|
|
19
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/webserver/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { default as WebServer } from './webserver.js';\nexport type { WebServerConstructorParams
|
|
5
|
-
"mappings": "AAAA,SAAoB,WAAXA,gBAA4B;
|
|
4
|
+
"sourcesContent": ["export { default as WebServer } from './webserver.js';\nexport type {\n RouteHandler as TypedRouteHandler,\n RouteHandlerContext,\n RouteSchemaDefinition,\n WebServerConstructorParams,\n WebServerOptions,\n WebServerRoute,\n} from './webserver.interface.js';\nexport { WebServerRouteType } from './webserver.interface.js';\nexport { default as WebServerBaseController } from './controller/base.js';\nexport type {\n ControllerAction,\n ControllerRequest,\n WebServerBaseControllerConstructorParams,\n} from './controller/base.interface.js';\nexport { default as WebServerHealthController } from './controller/health.js';\nexport { default as WebServerEntityController } from './controller/entity.js';\nexport { default as ExampleAuthController } from './controller/example-auth.js';\nexport { default as RouteUtil } from './util.js';\nexport type {\n AuthenticatedUser,\n AuthenticatedRequest,\n AuthenticatedRouteHandler,\n RouteHandler,\n} from './controller/auth-middleware.js';\nexport { withAuth } from './controller/auth-middleware.js';\nexport { defineRoute } from './define-route.js';\n"],
|
|
5
|
+
"mappings": "AAAA,SAAoB,WAAXA,gBAA4B;AASrC,SAAS,0BAA0B;AACnC,SAAoB,WAAXA,gBAA0C;AAMnD,SAAoB,WAAXA,gBAA4C;AACrD,SAAoB,WAAXA,gBAA4C;AACrD,SAAoB,WAAXA,gBAAwC;AACjD,SAAoB,WAAXA,gBAA4B;AAOrC,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;",
|
|
6
6
|
"names": ["default"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/webserver/webserver.interface.ts"],
|
|
4
|
-
"sourcesContent": ["import type { HTTPMethods } from 'fastify';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { QueueManager } from '../queue/index.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\nimport type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';\n\nexport interface WebServerConstructorParams {\n /** Application configuration */\n applicationConfig: ApplicationConfig;\n\n /** Web server options */\n options: WebServerOptions;\n\n /** Web server routes */\n routes: WebServerRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Event manager */\n eventManager: EventManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n\n /** Lifecycle manager */\n lifecycleManager: LifecycleManager;\n}\n\nexport enum WebServerRouteType {\n Default = 'default',\n Entity = 'entity',\n}\n\nexport interface BaseWebServerRoute {\n /** Route type */\n type?: WebServerRouteType;\n\n /** Route path */\n path: string;\n\n /** Route controller name */\n controllerName?: string;\n\n /** Route controller */\n controller?: WebServerBaseControllerType;\n\n /** Route validation */\n validation?: {\n /** Validation type */\n type: 'body' | 'query' | 'params';\n\n /** Validation schema */\n schema: { [key: string]: any };\n };\n}\n\nexport interface DefaultWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Default;\n\n /** Route method */\n method: HTTPMethods | HTTPMethods[];\n\n /** Route action */\n action
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { FastifyReply, FastifyRequest, HTTPMethods, RouteGenericInterface } from 'fastify';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { QueueManager } from '../queue/index.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { ControllerAction, WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\nimport type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';\nimport type { z } from 'zod';\n\nexport interface RouteSchemaDefinition<\n TParams extends z.ZodTypeAny | undefined = undefined,\n TQuery extends z.ZodTypeAny | undefined = undefined,\n TBody extends z.ZodTypeAny | undefined = undefined,\n TReply extends Record<number | `${number}`, z.ZodTypeAny> | undefined = undefined,\n THeaders extends z.ZodTypeAny | undefined = undefined,\n> {\n params?: TParams;\n querystring?: TQuery;\n body?: TBody;\n response?: TReply;\n headers?: THeaders;\n}\n\ntype InferOrDefault<TZod extends z.ZodTypeAny | undefined, TFallback> = TZod extends z.ZodTypeAny\n ? z.input<TZod>\n : TFallback;\n\ntype InferResponse<TResponse> =\n TResponse extends Record<number | `${number}`, z.ZodTypeAny>\n ? z.output<TResponse[keyof TResponse]>\n : RouteGenericInterface['Reply'];\n\nexport interface RouteHandlerContext<Schema extends RouteSchemaDefinition | undefined = undefined>\n extends RouteGenericInterface {\n Params?: Schema extends RouteSchemaDefinition<infer TParams, any, any, any, any>\n ? InferOrDefault<TParams, RouteGenericInterface['Params']>\n : RouteGenericInterface['Params'];\n Querystring?: Schema extends RouteSchemaDefinition<any, infer TQuery, any, any, any>\n ? InferOrDefault<TQuery, RouteGenericInterface['Querystring']>\n : RouteGenericInterface['Querystring'];\n Body?: Schema extends RouteSchemaDefinition<any, any, infer TBody, any, any>\n ? InferOrDefault<TBody, RouteGenericInterface['Body']>\n : RouteGenericInterface['Body'];\n Headers?: Schema extends RouteSchemaDefinition<any, any, any, any, infer THeaders>\n ? InferOrDefault<THeaders, RouteGenericInterface['Headers']>\n : RouteGenericInterface['Headers'];\n Reply?: Schema extends RouteSchemaDefinition<any, any, any, infer TReply, any>\n ? InferResponse<TReply>\n : RouteGenericInterface['Reply'];\n}\n\nexport type AnyRouteSchemaDefinition = RouteSchemaDefinition<\n z.ZodTypeAny | undefined,\n z.ZodTypeAny | undefined,\n z.ZodTypeAny | undefined,\n Record<number | `${number}`, z.ZodTypeAny> | undefined,\n z.ZodTypeAny | undefined\n>;\n\nexport type RouteHandler<Schema extends RouteSchemaDefinition | undefined = undefined> = (\n request: FastifyRequest<RouteHandlerContext<Schema>>,\n reply: FastifyReply,\n) => Promise<RouteHandlerContext<Schema>['Reply'] | void> | RouteHandlerContext<Schema>['Reply'] | void;\n\nexport interface WebServerConstructorParams {\n /** Application configuration */\n applicationConfig: ApplicationConfig;\n\n /** Web server options */\n options: WebServerOptions;\n\n /** Web server routes */\n routes: WebServerRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Event manager */\n eventManager: EventManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n\n /** Lifecycle manager */\n lifecycleManager: LifecycleManager;\n}\n\nexport enum WebServerRouteType {\n Default = 'default',\n Entity = 'entity',\n}\n\nexport interface BaseWebServerRoute {\n /** Route type */\n type?: WebServerRouteType;\n\n /** Route path */\n path: string;\n\n /** Route controller name */\n controllerName?: string;\n\n /** Route controller */\n controller?: WebServerBaseControllerType;\n\n /** Typed route handler */\n handler?: ControllerAction<any>;\n\n /** Route validation */\n validation?: {\n /** Validation type */\n type: 'body' | 'query' | 'params';\n\n /** Validation schema */\n schema: { [key: string]: any };\n };\n\n /** Zod-based schema definition */\n schema?: AnyRouteSchemaDefinition;\n}\n\nexport interface DefaultWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Default;\n\n /** Route method */\n method: HTTPMethods | HTTPMethods[];\n\n /** Route action */\n action?: string;\n}\n\nexport interface EntityWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Entity;\n\n /** Entity name */\n entityName: string;\n}\n\nexport type WebServerRoute = DefaultWebServerRoute | EntityWebServerRoute;\n\nexport interface RouteValidationSchema {\n type: 'body' | 'query' | 'params';\n schema: {\n type: 'object';\n properties: { [key: string]: any };\n required: string[];\n };\n}\n\nexport interface EntityRouteDefinition {\n path: string;\n method: HTTPMethods | HTTPMethods[];\n action: string;\n validationSchema?: RouteValidationSchema;\n}\n\nexport interface WebServerLogConfig {\n startUp?: boolean;\n}\n\nexport interface WebServerDebugOptions {\n printRoutes?: boolean;\n simulateSlowConnection?: {\n enabled?: boolean;\n delay?: number;\n };\n}\n\nexport interface WebServerCorsBaseOptions {\n /** Whether CORS is enabled */\n enabled: boolean;\n}\n\nexport interface WebServerCorsDisabledOptionsBase {\n enabled: false;\n}\n\nexport interface WebServerCorsEnabledOptionsBase {\n enabled: true;\n}\n\nexport interface WebServerCorsEnabledOptions extends WebServerCorsEnabledOptionsBase {\n urls: string[];\n}\n\nexport type WebServerCorsOptions = WebServerCorsDisabledOptionsBase | WebServerCorsEnabledOptions;\n\nexport interface WebServerErrorsOptions {\n verbose: boolean;\n}\n\nexport interface WebServerSecurityHelmetOptions {\n enabled?: boolean;\n contentSecurityPolicy?: boolean;\n crossOriginEmbedderPolicy?: boolean;\n crossOriginOpenerPolicy?: boolean;\n crossOriginResourcePolicy?: boolean;\n dnsPrefetchControl?: boolean;\n frameguard?: boolean;\n hidePoweredBy?: boolean;\n hsts?: boolean;\n ieNoOpen?: boolean;\n noSniff?: boolean;\n originAgentCluster?: boolean;\n permittedCrossDomainPolicies?: boolean;\n referrerPolicy?: boolean;\n xssFilter?: boolean;\n}\n\nexport interface WebServerSecurityRateLimitOptions {\n enabled?: boolean;\n max?: number;\n timeWindow?: string;\n ban?: number;\n cache?: number;\n}\n\nexport interface WebServerSecurityOptions {\n helmet?: WebServerSecurityHelmetOptions;\n rateLimit?: WebServerSecurityRateLimitOptions;\n}\n\nexport interface WebServerOptions {\n /** Web server host */\n host: string;\n\n /** Web server port */\n port: number;\n\n /** Maximum request body size in bytes (default: 100MB) */\n bodyLimit?: number;\n\n /** Connection timeout in milliseconds (default: 30s) */\n connectionTimeout?: number;\n\n /** Web server CORS options */\n cors?: WebServerCorsOptions;\n\n /** Web server error options */\n errors?: WebServerErrorsOptions;\n\n /** Web server controllers directory */\n controllersDirectory: string;\n\n /** Optional directory containing route definition files */\n routesDirectory?: string;\n\n log?: WebServerLogConfig;\n\n /** Web server security options (helmet, rate limiting) */\n security?: WebServerSecurityOptions;\n\n /** Web server debug options */\n debug?: WebServerDebugOptions;\n}\n\n// export interface WebServerLogParams {\n// /** Method */\n// Method: string;\n\n// /** Path */\n// Path: string;\n\n// /** Status code */\n// Status: number;\n\n// /** IP address */\n// IP?: string;\n\n// /** Execution time */\n// Time?: string;\n\n// [key: string]: unknown;\n// }\n"],
|
|
5
|
+
"mappings": "AA2FO,IAAK,qBAAL,kBAAKA,wBAAL;AACL,EAAAA,oBAAA,aAAU;AACV,EAAAA,oBAAA,YAAS;AAFC,SAAAA;AAAA,GAAA;",
|
|
6
6
|
"names": ["WebServerRouteType"]
|
|
7
7
|
}
|