@scpxl/nodejs-framework 1.0.20 → 1.0.24
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 +719 -66
- package/dist/application/base-application.d.ts.map +1 -1
- package/dist/application/base-application.interface.d.ts +1 -0
- package/dist/application/base-application.interface.d.ts.map +1 -1
- package/dist/application/base-application.js +4 -1
- package/dist/application/base-application.js.map +2 -2
- package/dist/application/command-application.d.ts.map +1 -1
- package/dist/application/command-application.js.map +2 -2
- package/dist/application/web-application.d.ts.map +1 -1
- package/dist/application/web-application.js +2 -0
- package/dist/application/web-application.js.map +2 -2
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +5655 -0
- package/dist/cli/index.js.map +7 -0
- package/dist/command/command.d.ts +1 -1
- package/dist/command/command.d.ts.map +1 -1
- package/dist/command/command.js.map +1 -1
- package/dist/config/schema.d.ts +40 -16
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +17 -7
- package/dist/config/schema.js.map +2 -2
- package/dist/event/manager.d.ts +2 -2
- package/dist/event/manager.d.ts.map +1 -1
- package/dist/event/manager.interface.d.ts +4 -1
- package/dist/event/manager.interface.d.ts.map +1 -1
- package/dist/event/manager.js.map +2 -2
- package/dist/lifecycle/lifecycle-manager.d.ts +1 -1
- package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -1
- package/dist/lifecycle/lifecycle-manager.js +6 -11
- package/dist/lifecycle/lifecycle-manager.js.map +2 -2
- package/dist/logger/logger.d.ts +4 -0
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.js +29 -2
- package/dist/logger/logger.js.map +2 -2
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.d.ts.map +1 -1
- package/dist/queue/index.js.map +1 -1
- package/dist/queue/job.interface.d.ts +4 -3
- package/dist/queue/job.interface.d.ts.map +1 -1
- package/dist/queue/manager.d.ts +14 -6
- package/dist/queue/manager.d.ts.map +1 -1
- package/dist/queue/manager.js +24 -12
- package/dist/queue/manager.js.map +2 -2
- package/dist/queue/processor/base.d.ts +6 -5
- package/dist/queue/processor/base.d.ts.map +1 -1
- package/dist/queue/processor/base.js.map +2 -2
- package/dist/queue/processor/processor.interface.d.ts +4 -3
- package/dist/queue/processor/processor.interface.d.ts.map +1 -1
- package/dist/redis/manager.d.ts.map +1 -1
- package/dist/redis/manager.js +13 -14
- package/dist/redis/manager.js.map +2 -2
- package/dist/services/aws/s3.js.map +2 -2
- package/dist/util/helper.d.ts +9 -10
- package/dist/util/helper.d.ts.map +1 -1
- package/dist/util/helper.js +73 -11
- package/dist/util/helper.js.map +2 -2
- package/dist/util/loader.d.ts +8 -6
- package/dist/util/loader.d.ts.map +1 -1
- package/dist/util/loader.js +5 -2
- package/dist/util/loader.js.map +2 -2
- package/dist/util/timing.interface.d.ts +1 -1
- package/dist/util/timing.interface.d.ts.map +1 -1
- package/dist/webserver/controller/base.d.ts +9 -9
- package/dist/webserver/controller/base.d.ts.map +1 -1
- package/dist/webserver/controller/base.interface.d.ts +12 -9
- package/dist/webserver/controller/base.interface.d.ts.map +1 -1
- package/dist/webserver/controller/base.js.map +2 -2
- package/dist/webserver/define-action.d.ts +26 -0
- package/dist/webserver/define-action.d.ts.map +1 -0
- package/dist/webserver/define-action.js +16 -0
- package/dist/webserver/define-action.js.map +7 -0
- package/dist/webserver/define-route.d.ts +53 -0
- package/dist/webserver/define-route.d.ts.map +1 -0
- package/dist/webserver/define-route.js +27 -0
- package/dist/webserver/define-route.js.map +7 -0
- package/dist/webserver/index.d.ts +4 -2
- package/dist/webserver/index.d.ts.map +1 -1
- package/dist/webserver/index.js +4 -0
- package/dist/webserver/index.js.map +2 -2
- package/dist/webserver/util.d.ts.map +1 -1
- package/dist/webserver/util.js +5 -2
- package/dist/webserver/util.js.map +2 -2
- package/dist/webserver/webserver.d.ts +20 -6
- package/dist/webserver/webserver.d.ts.map +1 -1
- package/dist/webserver/webserver.interface.d.ts +30 -4
- package/dist/webserver/webserver.interface.d.ts.map +1 -1
- package/dist/webserver/webserver.interface.js.map +2 -2
- package/dist/webserver/webserver.js +209 -57
- package/dist/webserver/webserver.js.map +2 -2
- package/dist/websocket/websocket-base.d.ts +6 -2
- package/dist/websocket/websocket-base.d.ts.map +1 -1
- package/dist/websocket/websocket-base.js.map +2 -2
- package/dist/websocket/websocket-client.js.map +1 -1
- package/dist/websocket/websocket-server.d.ts.map +1 -1
- package/dist/websocket/websocket-server.js +38 -14
- package/dist/websocket/websocket-server.js.map +2 -2
- package/dist/websocket/websocket.interface.d.ts +9 -4
- package/dist/websocket/websocket.interface.d.ts.map +1 -1
- package/dist/websocket/websocket.interface.js.map +2 -2
- package/package.json +14 -13
- package/pxl.js +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/redis/manager.ts"],
|
|
4
|
-
"sourcesContent": ["import { Redis, type RedisOptions } from 'ioredis';\nimport { EventEmitter } from 'node:events';\nimport type { RedisManagerConfig as RedisManagerOptions } from './manager.interface.js';\nimport RedisInstance from './instance.js';\nimport { Logger } from '../logger/index.js';\nimport { CachePerformanceWrapper } from '../performance/index.js';\n\nconst truthyPattern = /^(1|true|yes|on)$/i;\nconst scheduleMicrotask =\n typeof (globalThis as any).queueMicrotask === 'function'\n ? (globalThis as any).queueMicrotask.bind(globalThis)\n : (callback: () => void) => {\n void Promise.resolve().then(callback);\n };\n\ntype RedisCallback = (error: Error | null, result?: string) => void;\n\ninterface InMemoryRedisSharedState {\n store: Map<string, string | Buffer>;\n expirations: Map<string, NodeJS.Timeout>;\n subscriptions: Map<string, Set<InMemoryRedisClient>>;\n}\n\nclass InMemoryRedisClient extends EventEmitter {\n private shared: InMemoryRedisSharedState;\n\n constructor(shared: InMemoryRedisSharedState) {\n super();\n this.shared = shared;\n\n scheduleMicrotask(() => {\n this.emit('ready');\n });\n }\n\n private cleanupSubscriptions(): void {\n for (const subscribers of this.shared.subscriptions.values()) {\n subscribers.delete(this);\n }\n }\n\n private clearExpirationForKey(key: string): void {\n const timer = this.shared.expirations.get(key);\n if (timer) {\n clearTimeout(timer);\n this.shared.expirations.delete(key);\n }\n }\n\n public ping(callback?: RedisCallback): Promise<string> {\n if (callback) {\n callback(null, 'PONG');\n return Promise.resolve('PONG');\n }\n\n return Promise.resolve('PONG');\n }\n\n public async set(...args: any[]): Promise<'OK'> {\n const [key, value, mode, expiration] = args;\n const serializedValue: string | Buffer = value instanceof Buffer ? value : String(value);\n\n this.shared.store.set(key, serializedValue);\n this.clearExpirationForKey(key);\n\n if (typeof mode === 'string' && mode.toUpperCase() === 'EX' && typeof expiration === 'number') {\n const timer = setTimeout(() => {\n this.shared.store.delete(key);\n this.shared.expirations.delete(key);\n }, expiration * 1000);\n\n if (typeof timer.unref === 'function') {\n timer.unref();\n }\n\n this.shared.expirations.set(key, timer);\n }\n\n return 'OK';\n }\n\n public async get(key: string): Promise<string | null> {\n return (this.shared.store.get(key) as string | undefined) ?? null;\n }\n\n public async del(key: string): Promise<number> {\n const existed = this.shared.store.delete(key);\n this.clearExpirationForKey(key);\n return existed ? 1 : 0;\n }\n\n public async publish(channel: string, message: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers || subscribers.size === 0) {\n return 0;\n }\n\n for (const subscriber of subscribers) {\n scheduleMicrotask(() => {\n subscriber.emit('message', channel, message);\n });\n }\n\n return subscribers.size;\n }\n\n public async subscribe(channel: string): Promise<number> {\n let subscribers = this.shared.subscriptions.get(channel);\n if (!subscribers) {\n subscribers = new Set<InMemoryRedisClient>();\n this.shared.subscriptions.set(channel, subscribers);\n }\n subscribers.add(this);\n return subscribers.size;\n }\n\n public async unsubscribe(channel: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers) {\n return 0;\n }\n\n subscribers.delete(this);\n return subscribers.size;\n }\n\n public async quit(): Promise<'OK'> {\n this.cleanupSubscriptions();\n this.
|
|
5
|
-
"mappings": ";;AAAA,SAAS,aAAgC;AACzC,SAAS,oBAAoB;AAE7B,OAAO,mBAAmB;AAC1B,SAAS,cAAc;AACvB,SAAS,+BAA+B;AAExC,MAAM,gBAAgB;AACtB,MAAM,oBACJ,OAAQ,WAAmB,mBAAmB,aACzC,WAAmB,eAAe,KAAK,UAAU,IAClD,CAAC,aAAyB;AACxB,OAAK,QAAQ,QAAQ,EAAE,KAAK,QAAQ;AACtC;
|
|
4
|
+
"sourcesContent": ["import { Redis, type RedisOptions } from 'ioredis';\nimport { EventEmitter } from 'node:events';\nimport type { RedisManagerConfig as RedisManagerOptions } from './manager.interface.js';\nimport RedisInstance from './instance.js';\nimport { Logger } from '../logger/index.js';\nimport { CachePerformanceWrapper } from '../performance/index.js';\n\nconst truthyPattern = /^(1|true|yes|on)$/i;\nconst scheduleMicrotask =\n typeof (globalThis as any).queueMicrotask === 'function'\n ? (globalThis as any).queueMicrotask.bind(globalThis)\n : (callback: () => void) => {\n void Promise.resolve().then(callback);\n };\n\ntype RedisCallback = (error: Error | null, result?: string) => void;\n\ninterface InMemoryRedisSharedState {\n store: Map<string, string | Buffer>;\n expirations: Map<string, NodeJS.Timeout>;\n subscriptions: Map<string, Set<InMemoryRedisClient>>;\n}\n\n// Global singleton shared state for in-memory Redis\nlet globalInMemoryRedisState: InMemoryRedisSharedState | null = null;\n\nfunction getGlobalInMemoryRedisState(): InMemoryRedisSharedState {\n globalInMemoryRedisState ??= {\n store: new Map<string, string | Buffer>(),\n expirations: new Map<string, NodeJS.Timeout>(),\n subscriptions: new Map<string, Set<InMemoryRedisClient>>(),\n };\n return globalInMemoryRedisState;\n}\n\nclass InMemoryRedisClient extends EventEmitter {\n private shared: InMemoryRedisSharedState;\n\n constructor(shared: InMemoryRedisSharedState) {\n super();\n this.shared = shared;\n\n scheduleMicrotask(() => {\n this.emit('ready');\n });\n }\n\n private cleanupSubscriptions(): void {\n for (const subscribers of this.shared.subscriptions.values()) {\n subscribers.delete(this);\n }\n }\n\n private clearExpirationForKey(key: string): void {\n const timer = this.shared.expirations.get(key);\n if (timer) {\n clearTimeout(timer);\n this.shared.expirations.delete(key);\n }\n }\n\n public ping(callback?: RedisCallback): Promise<string> {\n if (callback) {\n callback(null, 'PONG');\n return Promise.resolve('PONG');\n }\n\n return Promise.resolve('PONG');\n }\n\n public async set(...args: any[]): Promise<'OK'> {\n const [key, value, mode, expiration] = args;\n const serializedValue: string | Buffer = value instanceof Buffer ? value : String(value);\n\n this.shared.store.set(key, serializedValue);\n this.clearExpirationForKey(key);\n\n if (typeof mode === 'string' && mode.toUpperCase() === 'EX' && typeof expiration === 'number') {\n const timer = setTimeout(() => {\n this.shared.store.delete(key);\n this.shared.expirations.delete(key);\n }, expiration * 1000);\n\n if (typeof timer.unref === 'function') {\n timer.unref();\n }\n\n this.shared.expirations.set(key, timer);\n }\n\n return 'OK';\n }\n\n public async get(key: string): Promise<string | null> {\n return (this.shared.store.get(key) as string | undefined) ?? null;\n }\n\n public async del(key: string): Promise<number> {\n const existed = this.shared.store.delete(key);\n this.clearExpirationForKey(key);\n return existed ? 1 : 0;\n }\n\n public async publish(channel: string, message: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers || subscribers.size === 0) {\n return 0;\n }\n\n for (const subscriber of subscribers) {\n scheduleMicrotask(() => {\n subscriber.emit('message', channel, message);\n });\n }\n\n return subscribers.size;\n }\n\n public async subscribe(channel: string): Promise<number> {\n let subscribers = this.shared.subscriptions.get(channel);\n if (!subscribers) {\n subscribers = new Set<InMemoryRedisClient>();\n this.shared.subscriptions.set(channel, subscribers);\n }\n subscribers.add(this);\n return subscribers.size;\n }\n\n public async unsubscribe(channel: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers) {\n return 0;\n }\n\n subscribers.delete(this);\n return subscribers.size;\n }\n\n public async quit(): Promise<'OK'> {\n this.cleanupSubscriptions();\n this.emit('end');\n this.removeAllListeners();\n return 'OK';\n }\n\n public disconnect(): void {\n this.cleanupSubscriptions();\n this.emit('end');\n this.removeAllListeners();\n }\n}\n\nexport default class RedisManager {\n private logger: typeof Logger = Logger;\n\n private options: RedisManagerOptions;\n\n public instances: RedisInstance[] = [];\n\n constructor(config: RedisManagerOptions) {\n this.options = config;\n }\n\n public async connect(): Promise<RedisInstance> {\n return CachePerformanceWrapper.monitorConnection(\n 'connect',\n async () => {\n const startTime = performance.now();\n\n const redisOptions: RedisOptions = {\n host: this.options.host,\n port: this.options.port,\n password: this.options.password,\n maxRetriesPerRequest: null, // Needed for bullmq\n };\n\n const useInMemoryRedis =\n truthyPattern.test(process.env.PXL_REDIS_IN_MEMORY ?? '') ||\n truthyPattern.test(process.env.REDIS_IN_MEMORY ?? '');\n\n const createClient = (): Redis => {\n if (useInMemoryRedis) {\n return new InMemoryRedisClient(getGlobalInMemoryRedisState()) as unknown as Redis;\n }\n\n return new Redis(redisOptions);\n };\n\n const client = createClient();\n const publisherClient = createClient();\n const subscriberClient = createClient();\n\n try {\n // Wait for all three clients to be ready\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n client.once('ready', () => resolve());\n client.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n publisherClient.once('ready', () => resolve());\n publisherClient.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n subscriberClient.once('ready', () => resolve());\n subscriberClient.once('error', (error: Error) => reject(error));\n }),\n ]);\n\n const redisInstance = new RedisInstance({\n redisManager: this,\n client,\n publisherClient,\n subscriberClient,\n });\n\n this.instances.push(redisInstance);\n\n const duration = performance.now() - startTime;\n const meta = {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Connected', meta);\n } else {\n this.logger.debug({ message: 'Redis connected', meta });\n }\n\n if (useInMemoryRedis) {\n this.logger.debug({ message: 'Using in-memory Redis stub' });\n }\n\n return redisInstance;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n // Clean up clients on error\n await Promise.allSettled([client.quit(), publisherClient.quit(), subscriberClient.quit()]);\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(String(error)),\n message: 'Redis connection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n public async disconnect(): Promise<void> {\n await CachePerformanceWrapper.monitorConnection(\n 'disconnect',\n async () => {\n const startTime = performance.now();\n const instanceCount = this.instances.length;\n\n try {\n await Promise.all(this.instances.map(instance => instance.disconnect()));\n\n const duration = performance.now() - startTime;\n\n if (instanceCount > 0) {\n const meta = {\n Instances: instanceCount,\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Disconnected all Redis instances', meta);\n } else {\n this.logger.debug({ message: 'Redis instances disconnected', meta });\n }\n }\n\n this.instances = [];\n } catch (error) {\n const duration = performance.now() - startTime;\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(String(error)),\n message: 'Redis disconnection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Instances: instanceCount,\n Duration: `${duration.toFixed(2)}ms`,\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n /**\n * Log Redis message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'redis', 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/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.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deep merge objects with defaults, preventing prototype pollution.
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
4
|
+
* This function:
|
|
5
|
+
* - Recursively merges source objects into the target
|
|
6
|
+
* - Preserves existing values in target (acts like defaults)
|
|
5
7
|
* - Sanitizes sources to remove dangerous keys (__proto__, constructor, prototype)
|
|
6
|
-
* -
|
|
7
|
-
* - Maintains backward compatibility with existing usage
|
|
8
|
+
* - Prevents prototype pollution attacks
|
|
8
9
|
*
|
|
9
10
|
* @param target - The target object to merge into
|
|
10
11
|
* @param sources - Source objects providing default values
|
|
@@ -16,14 +17,12 @@
|
|
|
16
17
|
* const merged = defaultsDeep(userConfig, defaults);
|
|
17
18
|
* // merged = { host: 'localhost', port: 3001 }
|
|
18
19
|
*/
|
|
19
|
-
declare function defaultsDeep(target:
|
|
20
|
+
declare function defaultsDeep<T extends object>(target: T, ...sources: Array<Partial<T>>): T;
|
|
20
21
|
/**
|
|
21
22
|
* Check if a value is an object.
|
|
22
23
|
*/
|
|
23
|
-
declare function isObject(item:
|
|
24
|
-
type AnyObject =
|
|
25
|
-
[key: string]: any;
|
|
26
|
-
};
|
|
24
|
+
declare function isObject(item: unknown): item is Record<string, unknown>;
|
|
25
|
+
type AnyObject = Record<string, unknown>;
|
|
27
26
|
/**
|
|
28
27
|
* Retrieves the value from an object using a dotted key path safely.
|
|
29
28
|
*
|
|
@@ -31,7 +30,7 @@ type AnyObject = {
|
|
|
31
30
|
* @param path - The dotted key path (e.g., 'user.email').
|
|
32
31
|
* @returns The value at the specified key path or undefined if not found.
|
|
33
32
|
*/
|
|
34
|
-
declare function getValueFromObject(obj: AnyObject, path: string):
|
|
33
|
+
declare function getValueFromObject(obj: AnyObject, path: string): unknown;
|
|
35
34
|
/**
|
|
36
35
|
* Retrieves the value from an array of objects using a dotted key path.
|
|
37
36
|
*
|
|
@@ -39,7 +38,7 @@ declare function getValueFromObject(obj: AnyObject, path: string): any;
|
|
|
39
38
|
* @param path - The dotted key path (e.g., 'user.email').
|
|
40
39
|
* @returns An array of values at the specified key path from each object.
|
|
41
40
|
*/
|
|
42
|
-
declare function getValueFromArray(arr: AnyObject[], path: string):
|
|
41
|
+
declare function getValueFromArray(arr: AnyObject[], path: string): unknown[];
|
|
43
42
|
declare function getScriptFileExtension(): string;
|
|
44
43
|
declare const _default: {
|
|
45
44
|
defaultsDeep: typeof defaultsDeep;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/util/helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/util/helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,iBAAS,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAgBnF;AA0HD;;GAEG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhE;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzC;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAWjE;AAED;;;;;;GAMG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAEpE;AAED,iBAAS,sBAAsB,IAAI,MAAM,CAExC;;;;;;;;AAED,wBAME"}
|
package/dist/util/helper.js
CHANGED
|
@@ -1,20 +1,82 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
import lodashDefaultsDeep from "lodash.defaultsdeep";
|
|
4
3
|
function defaultsDeep(target, ...sources) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
return
|
|
4
|
+
let result = target;
|
|
5
|
+
if (target === null || target === void 0) {
|
|
6
|
+
result = {};
|
|
7
|
+
}
|
|
8
|
+
for (const source of sources) {
|
|
9
|
+
if (!isObject(source) && !Array.isArray(source)) continue;
|
|
10
|
+
mergeObjects(result, source);
|
|
11
|
+
}
|
|
12
|
+
return result;
|
|
14
13
|
}
|
|
15
14
|
__name(defaultsDeep, "defaultsDeep");
|
|
15
|
+
function mergeObjects(target, source) {
|
|
16
|
+
if (Array.isArray(source)) {
|
|
17
|
+
if (!Array.isArray(target)) {
|
|
18
|
+
for (let i = 0; i < source.length; i++) {
|
|
19
|
+
const key = String(i);
|
|
20
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
21
|
+
const sourceValue = source[i];
|
|
22
|
+
const targetValue = target[key];
|
|
23
|
+
const keyExists = key in target;
|
|
24
|
+
if (keyExists && isObject(targetValue) && isObject(sourceValue)) {
|
|
25
|
+
mergeObjects(targetValue, sourceValue);
|
|
26
|
+
} else if (!keyExists || targetValue === void 0) {
|
|
27
|
+
target[key] = isObject(sourceValue) ? deepClone(sourceValue) : sourceValue;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (let i = 0; i < source.length; i++) {
|
|
33
|
+
const sourceValue = source[i];
|
|
34
|
+
const targetValue = target[i];
|
|
35
|
+
const indexExists = i in target;
|
|
36
|
+
if (indexExists && isObject(targetValue) && isObject(sourceValue)) {
|
|
37
|
+
mergeObjects(targetValue, sourceValue);
|
|
38
|
+
} else if (!indexExists || targetValue === void 0) {
|
|
39
|
+
target[i] = isObject(sourceValue) ? deepClone(sourceValue) : sourceValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
for (const key of Object.keys(source)) {
|
|
45
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (!Object.prototype.hasOwnProperty.call(source, key)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const sourceValue = source[key];
|
|
52
|
+
const targetValue = target[key];
|
|
53
|
+
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
|
|
54
|
+
mergeObjects(targetValue, sourceValue);
|
|
55
|
+
} else if (isObject(targetValue) && Array.isArray(sourceValue)) {
|
|
56
|
+
mergeObjects(targetValue, sourceValue);
|
|
57
|
+
} else if (targetValue !== void 0 && isObject(targetValue) && isObject(sourceValue)) {
|
|
58
|
+
mergeObjects(targetValue, sourceValue);
|
|
59
|
+
} else if (targetValue === void 0) {
|
|
60
|
+
target[key] = isObject(sourceValue) || Array.isArray(sourceValue) ? deepClone(sourceValue) : sourceValue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
__name(mergeObjects, "mergeObjects");
|
|
65
|
+
function deepClone(obj) {
|
|
66
|
+
if (!isObject(obj)) return obj;
|
|
67
|
+
const cloned = Array.isArray(obj) ? [] : {};
|
|
68
|
+
for (const key of Object.keys(obj)) {
|
|
69
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const value = obj[key];
|
|
73
|
+
cloned[key] = isObject(value) ? deepClone(value) : value;
|
|
74
|
+
}
|
|
75
|
+
return cloned;
|
|
76
|
+
}
|
|
77
|
+
__name(deepClone, "deepClone");
|
|
16
78
|
function isObject(item) {
|
|
17
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
79
|
+
return item !== null && typeof item === "object" && !Array.isArray(item);
|
|
18
80
|
}
|
|
19
81
|
__name(isObject, "isObject");
|
|
20
82
|
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": ["
|
|
5
|
-
"mappings": ";;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * Deep merge objects with defaults, preventing prototype pollution.\n *\n * This function:\n * - Recursively merges source objects into the target\n * - Preserves existing values in target (acts like defaults)\n * - Sanitizes sources to remove dangerous keys (__proto__, constructor, prototype)\n * - Prevents prototype pollution attacks\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 // Handle null/undefined target by converting to empty object\n let result = target;\n if (target === null || target === undefined) {\n result = {} as T;\n }\n\n // Process each source\n for (const source of sources) {\n if (!isObject(source) && !Array.isArray(source)) continue;\n\n // Recursively merge source into target\n mergeObjects(result, source);\n }\n\n return result;\n}\n\n/**\n * Recursively merge source into target, preserving target values.\n * This acts like defaultsDeep - only fills in missing values from source.\n */\nfunction mergeObjects(target: any, source: any): void {\n // Handle arrays specially - merge by index\n if (Array.isArray(source)) {\n // If target is not an array but source is, treat target as object with numeric keys\n if (!Array.isArray(target)) {\n // Merge array into object-like target\n for (let i = 0; i < source.length; i++) {\n const key = String(i);\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue;\n\n // eslint-disable-next-line security/detect-object-injection\n const sourceValue = source[i];\n // eslint-disable-next-line security/detect-object-injection\n const targetValue = target[key];\n\n // Check if key exists in target\n const keyExists = key in target;\n\n if (keyExists && isObject(targetValue) && isObject(sourceValue)) {\n mergeObjects(targetValue, sourceValue);\n } else if (!keyExists || targetValue === undefined) {\n // eslint-disable-next-line security/detect-object-injection\n target[key] = isObject(sourceValue) ? deepClone(sourceValue) : sourceValue;\n }\n }\n return;\n }\n\n // Both are arrays - merge by index\n for (let i = 0; i < source.length; i++) {\n // eslint-disable-next-line security/detect-object-injection\n const sourceValue = source[i];\n // eslint-disable-next-line security/detect-object-injection\n const targetValue = target[i];\n\n // Check if index exists in target (not just if value is undefined)\n const indexExists = i in target;\n\n // If index exists and both values are objects, merge them\n if (indexExists && isObject(targetValue) && isObject(sourceValue)) {\n mergeObjects(targetValue, sourceValue);\n }\n // If index doesn't exist or value is undefined, fill from source\n else if (!indexExists || targetValue === undefined) {\n // eslint-disable-next-line security/detect-object-injection\n target[i] = isObject(sourceValue) ? deepClone(sourceValue) : sourceValue;\n }\n // Otherwise, keep target's existing value\n }\n return;\n }\n\n // Regular object merging\n for (const key of Object.keys(source)) {\n // Block dangerous keys to prevent prototype pollution\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // Only use hasOwnProperty for safer property access\n if (!Object.prototype.hasOwnProperty.call(source, key)) {\n continue;\n }\n\n // Access guarded by ownProperty check and blocked prototype keys\n // eslint-disable-next-line security/detect-object-injection\n const sourceValue = source[key];\n\n // eslint-disable-next-line security/detect-object-injection\n const targetValue = target[key];\n\n // If both are arrays, merge them by index\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n mergeObjects(targetValue, sourceValue);\n }\n // If target is object and source is array, merge array into object by numeric keys\n else if (isObject(targetValue) && Array.isArray(sourceValue)) {\n mergeObjects(targetValue, sourceValue);\n }\n // If target value exists and both are objects (not arrays), recurse\n else if (targetValue !== undefined && isObject(targetValue) && isObject(sourceValue)) {\n mergeObjects(targetValue, sourceValue);\n }\n // If target doesn't have this key, set it from source\n else if (targetValue === undefined) {\n // eslint-disable-next-line security/detect-object-injection\n target[key] = isObject(sourceValue) || Array.isArray(sourceValue) ? deepClone(sourceValue) : sourceValue;\n }\n // Otherwise, keep target's existing value (defaultsDeep behavior)\n }\n}\n\n/**\n * Deep clone an object to avoid reference sharing.\n */\nfunction deepClone<T>(obj: T): T {\n if (!isObject(obj)) return obj;\n\n const cloned: any = Array.isArray(obj) ? [] : {};\n\n for (const key of Object.keys(obj)) {\n // Block dangerous keys\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n\n // eslint-disable-next-line security/detect-object-injection\n const value = (obj as any)[key];\n\n // eslint-disable-next-line security/detect-object-injection\n cloned[key] = isObject(value) ? deepClone(value) : value;\n }\n\n return cloned;\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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/util/loader.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
export interface ModuleMap<T = unknown> {
|
|
2
|
+
[key: string]: T;
|
|
3
|
+
}
|
|
4
|
+
export type EntityClass<T = unknown> = new (...args: unknown[]) => T;
|
|
1
5
|
declare const _default: {
|
|
2
|
-
loadModulesInDirectory: ({ directory, extensions, }: {
|
|
6
|
+
loadModulesInDirectory: <T = unknown>({ directory, extensions, }: {
|
|
3
7
|
directory: string;
|
|
4
8
|
extensions?: string[];
|
|
5
|
-
}) => Promise<
|
|
6
|
-
|
|
7
|
-
}>;
|
|
8
|
-
loadEntityModule: ({ entitiesDirectory, entityName, }: {
|
|
9
|
+
}) => Promise<ModuleMap<T>>;
|
|
10
|
+
loadEntityModule: <T = unknown>({ entitiesDirectory, entityName, }: {
|
|
9
11
|
entitiesDirectory: string;
|
|
10
12
|
entityName: string;
|
|
11
|
-
}) => Promise<
|
|
13
|
+
}) => Promise<EntityClass<T>>;
|
|
12
14
|
clearModuleCache: () => void;
|
|
13
15
|
getCacheStats: () => {
|
|
14
16
|
modulesCached: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/util/loader.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/util/loader.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC;CAClB;AAgFD,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;;6BAlE/B,CAAC,wCAGpC;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,KAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;uBA8DO,CAAC,gDAG9B;QACD,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;KACpB,KAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;4BAkCE,IAAI;yBAKP;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE;;AAO3E,wBAKE"}
|
package/dist/util/loader.js
CHANGED
|
@@ -41,10 +41,13 @@ const loadModulesInDirectory = /* @__PURE__ */ __name(async ({
|
|
|
41
41
|
}
|
|
42
42
|
const moduleName = path.basename(file, ext);
|
|
43
43
|
const filePath = path.join(directory, file);
|
|
44
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
45
|
+
const fileUrl = `file://${absolutePath.replace(/\\/g, "/")}`;
|
|
44
46
|
try {
|
|
45
|
-
const importedModule = await import(
|
|
47
|
+
const importedModule = await import(fileUrl);
|
|
46
48
|
if (moduleName !== "__proto__" && moduleName !== "constructor" && moduleName !== "prototype") {
|
|
47
|
-
|
|
49
|
+
const moduleExport = importedModule.default ?? importedModule;
|
|
50
|
+
Reflect.set(loadedModules, moduleName, moduleExport);
|
|
48
51
|
}
|
|
49
52
|
} catch (error) {
|
|
50
53
|
console.error(`Failed to import module ${filePath}:`, error);
|
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 // Convert to absolute path for ESM import\n const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n // Use file:// URL for Windows compatibility\n const fileUrl = `file://${absolutePath.replace(/\\\\/g, '/')}`;\n\n try {\n const importedModule = await import(fileUrl);\n\n // Use safe property assignment to prevent prototype pollution\n if (moduleName !== '__proto__' && moduleName !== 'constructor' && moduleName !== 'prototype') {\n // Prefer default export, but fall back to the entire module if no default\n const moduleExport = importedModule.default ?? importedModule;\n Reflect.set(loadedModules, moduleName, moduleExport);\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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.interface.d.ts","sourceRoot":"","sources":["../../src/util/timing.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,IAAI,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"timing.interface.d.ts","sourceRoot":"","sources":["../../src/util/timing.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,IAAI,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD"}
|
|
@@ -8,21 +8,21 @@ import type { ApplicationConfig } from '../../application/base-application.inter
|
|
|
8
8
|
import type EventManager from '../../event/manager.js';
|
|
9
9
|
import type { WebServerOptions } from '../webserver.interface.js';
|
|
10
10
|
import type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';
|
|
11
|
-
export interface AuthenticatedUser {
|
|
11
|
+
export interface AuthenticatedUser<TPayload = Record<string, unknown>> {
|
|
12
12
|
userId: number;
|
|
13
|
-
payload:
|
|
13
|
+
payload: TPayload;
|
|
14
14
|
}
|
|
15
|
-
export default abstract class BaseController {
|
|
15
|
+
export default abstract class BaseController<TQueueManager extends QueueManager = QueueManager, TRedisInstance extends RedisInstance = RedisInstance, TEventManager extends EventManager = EventManager, TDatabaseInstance extends DatabaseInstance = DatabaseInstance> {
|
|
16
16
|
protected workerId: number | undefined;
|
|
17
17
|
protected applicationConfig: ApplicationConfig;
|
|
18
18
|
protected webServerOptions: WebServerOptions;
|
|
19
|
-
protected redisInstance:
|
|
20
|
-
protected queueManager:
|
|
21
|
-
protected eventManager:
|
|
22
|
-
protected databaseInstance:
|
|
19
|
+
protected redisInstance: TRedisInstance;
|
|
20
|
+
protected queueManager: TQueueManager;
|
|
21
|
+
protected eventManager: TEventManager;
|
|
22
|
+
protected databaseInstance: TDatabaseInstance;
|
|
23
23
|
protected lifecycleManager: LifecycleManager;
|
|
24
|
-
constructor({ applicationConfig, webServerOptions, redisInstance, queueManager, eventManager, databaseInstance, lifecycleManager, }: WebServerBaseControllerConstructorParams);
|
|
25
|
-
protected sendSuccessResponse<T =
|
|
24
|
+
constructor({ applicationConfig, webServerOptions, redisInstance, queueManager, eventManager, databaseInstance, lifecycleManager, }: WebServerBaseControllerConstructorParams<TQueueManager, TRedisInstance, TEventManager, TDatabaseInstance>);
|
|
25
|
+
protected sendSuccessResponse<T = unknown>({ reply, data, statusCode, meta, }: {
|
|
26
26
|
reply: FastifyReply;
|
|
27
27
|
data: T;
|
|
28
28
|
statusCode?: StatusCodes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAE3G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAG7E,MAAM,WAAW,iBAAiB;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAE3G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAG7E,MAAM,WAAW,iBAAiB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc,CAC1C,aAAa,SAAS,YAAY,GAAG,YAAY,EACjD,cAAc,SAAS,aAAa,GAAG,aAAa,EACpD,aAAa,SAAS,YAAY,GAAG,YAAY,EACjD,iBAAiB,SAAS,gBAAgB,GAAG,gBAAgB;IAE7D,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAC/C,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE7C,SAAS,CAAC,aAAa,EAAE,cAAc,CAAC;IACxC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC;IACtC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC;IACtC,SAAS,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;IAC9C,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;gBAEjC,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,wCAAwC,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,CAAC;IAa5G,SAAS,CAAC,mBAAmB,CAAC,CAAC,GAAG,OAAO,EAAE,EACzC,KAAK,EACL,IAAI,EACJ,UAA2B,EAC3B,IAAI,GACL,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC;QACR,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;KAC/B;IAYD,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,GAAE,MAA6B;IAW1F,SAAS,CAAC,iBAAiB,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,UAAoC,EACpC,SAAS,GACV,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;KAC9B;IA6CD,OAAO,CAAC,YAAY;cAoBJ,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAwErH"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify';
|
|
1
2
|
import type { ApplicationConfig } from '../../application/base-application.interface.js';
|
|
2
3
|
import type { DatabaseInstance } from '../../database/index.js';
|
|
3
4
|
import type EventManager from '../../event/manager.js';
|
|
4
5
|
import type { QueueManager } from '../../queue/index.js';
|
|
5
6
|
import type { RedisInstance } from '../../redis/index.js';
|
|
6
|
-
import type { WebServerOptions } from '../webserver.interface.js';
|
|
7
|
+
import type { RouteHandler, RouteHandlerContext, RouteSchemaDefinition, WebServerOptions } from '../webserver.interface.js';
|
|
7
8
|
import type WebServerBaseController from './base.js';
|
|
8
9
|
import type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';
|
|
9
|
-
export interface WebServerBaseControllerConstructorParams {
|
|
10
|
+
export interface WebServerBaseControllerConstructorParams<TQueueManager extends QueueManager = QueueManager, TRedisInstance extends RedisInstance = RedisInstance, TEventManager extends EventManager = EventManager, TDatabaseInstance extends DatabaseInstance = DatabaseInstance> {
|
|
10
11
|
applicationConfig: ApplicationConfig;
|
|
11
12
|
webServerOptions: WebServerOptions;
|
|
12
|
-
redisInstance:
|
|
13
|
-
queueManager:
|
|
14
|
-
eventManager:
|
|
15
|
-
databaseInstance:
|
|
13
|
+
redisInstance: TRedisInstance;
|
|
14
|
+
queueManager: TQueueManager;
|
|
15
|
+
eventManager: TEventManager;
|
|
16
|
+
databaseInstance: TDatabaseInstance;
|
|
16
17
|
lifecycleManager: LifecycleManager;
|
|
17
18
|
}
|
|
18
|
-
export type WebServerBaseControllerType = new (params: WebServerBaseControllerConstructorParams) => WebServerBaseController
|
|
19
|
-
export
|
|
19
|
+
export type WebServerBaseControllerType<TQueueManager extends QueueManager = QueueManager, TRedisInstance extends RedisInstance = RedisInstance, TEventManager extends EventManager = EventManager, TDatabaseInstance extends DatabaseInstance = DatabaseInstance> = new (params: WebServerBaseControllerConstructorParams<TQueueManager, TRedisInstance, TEventManager, TDatabaseInstance>) => WebServerBaseController<TQueueManager, TRedisInstance, TEventManager, TDatabaseInstance>;
|
|
20
|
+
export type ControllerAction<Schema extends RouteSchemaDefinition | undefined = undefined> = RouteHandler<Schema>;
|
|
21
|
+
export type ControllerRequest<Schema extends RouteSchemaDefinition | undefined = undefined> = FastifyRequest<RouteHandlerContext<Schema>>;
|
|
22
|
+
export interface ApiResponse<T = unknown> {
|
|
20
23
|
data?: T;
|
|
21
24
|
meta?: {
|
|
22
25
|
pagination?: {
|
|
@@ -34,7 +37,7 @@ export interface ApiError {
|
|
|
34
37
|
message: string;
|
|
35
38
|
code?: string;
|
|
36
39
|
type: 'validation' | 'authentication' | 'authorization' | 'not_found' | 'server_error' | 'client_error';
|
|
37
|
-
details?:
|
|
40
|
+
details?: Record<string, unknown>;
|
|
38
41
|
timestamp: string;
|
|
39
42
|
requestId: string;
|
|
40
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.interface.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"base.interface.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.interface.ts"],"names":[],"mappings":"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"}
|