@m16khb/nestjs-sidequest 0.1.0
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/README.ko.md +402 -0
- package/README.md +402 -0
- package/dist/index.cjs +1037 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +900 -0
- package/dist/index.d.ts +900 -0
- package/dist/index.js +1014 -0
- package/dist/index.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/core/sidequest.adapter.ts","../src/services/sidequest-engine.service.ts","../src/services/queue-registry.service.ts","../src/services/cls-integration.service.ts","../src/services/processor-registry.service.ts","../src/explorers/processor.explorer.ts","../src/modules/sidequest.module.ts","../src/decorators/processor.decorator.ts","../src/decorators/on-job.decorator.ts","../src/decorators/retry.decorator.ts","../src/decorators/inject-queue.decorator.ts","../src/decorators/on-job-complete.decorator.ts","../src/decorators/on-job-failed.decorator.ts"],"names":["SIDEQUEST_MODULE_OPTIONS","Symbol","SIDEQUEST_ENGINE","PROCESSOR_METADATA_KEY","ON_JOB_METADATA_KEY","RETRY_OPTIONS_METADATA_KEY","ON_JOB_COMPLETE_METADATA_KEY","ON_JOB_FAILED_METADATA_KEY","QUEUE_TOKEN_PREFIX","getQueueToken","queueName","DEFAULT_QUEUE_NAME","DEFAULT_MAX_ATTEMPTS","DEFAULT_TIMEOUT","DEFAULT_CONCURRENCY","SidequestAdapter","logger","Logger","name","isStarted","registeredJobs","Map","start","options","warn","log","config","backend","driver","queues","map","q","concurrency","priority","state","maxConcurrentJobs","undefined","minThreads","maxThreads","jobPollingInterval","releaseStaleJobsIntervalMin","cleanupFinishedJobsIntervalMin","level","json","dashboard","Sidequest","error","shutdown","stop","registerJob","jobName","JobClass","set","debug","addJob","args","get","Error","builder","build","queue","maxAttempts","timeout","scheduledAt","availableAt","retryDelay","backoffStrategy","uniqueKey","unique","jobData","enqueue","jobId","String","id","Date","now","addBulkJobs","jobs","jobIds","push","getJob","numericId","parseInt","isNaN","job","attempt","max_attempts","insertedAt","inserted_at","attemptedAt","attempted_at","completedAt","completed_at","result","errors","started","getRegisteredJob","getAllRegisteredJobs","SidequestEngineService","adapter","onModuleInit","onModuleDestroy","gracefulShutdown","enabled","getAdapter","QueueRegistryService","queueServices","initializeQueues","queueConfig","registerQueue","has","queueService","createQueueService","getQueue","getQueueOrThrow","getAllQueues","add","addWithOptions","addScheduled","addBulk","bulkJobs","ClsIntegrationService","clsService","enableCls","runInContext","metadata","callback","Promise","resolve","reject","run","key","value","Object","entries","then","catch","getTraceId","setTraceId","traceId","isEnabled","ProcessorRegistryService","processors","register","processor","metatype","getProcessor","getAllProcessors","getJobHandler","handlers","getCompleteHandler","completeHandlers","getFailedHandler","failedHandlers","dispatch","handler","instance","method","methodName","executeJob","apply","completeHandlerName","completeHandler","failedHandlerName","failedHandler","ProcessorExplorer","discoveryService","metadataScanner","reflector","processorRegistry","explore","providers","getProviders","wrapper","processWrapper","processorMetadata","scanHandlers","scanCompleteHandlers","scanFailedHandlers","registeredProcessor","size","_metatype","prototype","getPrototypeOf","methodNames","getAllMethodNames","methodRef","onJobMetadata","retryOptions","SidequestModule","forRoot","isGlobal","queueProviders","createQueueProviders","module","global","imports","DiscoveryModule","provide","useValue","exports","p","forRootAsync","asyncOptions","createAsyncProviders","useFactory","inject","registry","useClass","optionsFactory","createSidequestOptions","useExisting","Processor","target","SetMetadata","Injectable","OnJob","propertyKey","descriptor","Retry","InjectQueue","Inject","OnJobComplete","OnJobFailed"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SidequestModule 상수\n */\n\n// DI 토큰\nexport const SIDEQUEST_MODULE_OPTIONS = Symbol('SIDEQUEST_MODULE_OPTIONS');\nexport const SIDEQUEST_ENGINE = Symbol('SIDEQUEST_ENGINE');\n\n// 메타데이터 키\nexport const PROCESSOR_METADATA_KEY = Symbol('sidequest:processor');\nexport const ON_JOB_METADATA_KEY = Symbol('sidequest:on-job');\nexport const RETRY_OPTIONS_METADATA_KEY = Symbol('sidequest:retry');\nexport const ON_JOB_COMPLETE_METADATA_KEY = Symbol('sidequest:on-job-complete');\nexport const ON_JOB_FAILED_METADATA_KEY = Symbol('sidequest:on-job-failed');\n\n// Queue 토큰 프리픽스\nexport const QUEUE_TOKEN_PREFIX = 'SIDEQUEST_QUEUE_';\n\n/**\n * Queue DI 토큰 생성\n */\nexport function getQueueToken(queueName: string): string {\n return `${QUEUE_TOKEN_PREFIX}${queueName}`;\n}\n\n// 기본값\nexport const DEFAULT_QUEUE_NAME = 'default';\nexport const DEFAULT_MAX_ATTEMPTS = 3;\nexport const DEFAULT_TIMEOUT = 30000;\nexport const DEFAULT_CONCURRENCY = 10;\n\n// Log messages\nexport const LOG_MESSAGES = {\n ENGINE_STARTING: 'Starting Sidequest engine...',\n ENGINE_STARTED: 'Sidequest engine started',\n ENGINE_STOPPING: 'Stopping Sidequest engine...',\n ENGINE_STOPPED: 'Sidequest engine stopped',\n QUEUE_REGISTERED: (name: string) => `Queue '${name}' registered`,\n PROCESSOR_REGISTERED: (name: string) => `Processor '${name}' registered`,\n JOB_HANDLER_REGISTERED: (jobName: string, queueName: string) =>\n `Job handler '${jobName}' (Queue: ${queueName}) registered`,\n} as const;\n","import {Injectable, Logger} from '@nestjs/common';\nimport {Sidequest, Job, JobBuilder} from 'sidequest';\nimport type {SidequestModuleOptions} from '../interfaces/module-options.interface.js';\nimport type {JobAddOptions, JobInfo, JobState, ErrorData} from '../interfaces/queue.interface.js';\n\n// Job 클래스 타입\ntype JobClassType = new (...args: unknown[]) => Job;\n\n/**\n * Sidequest.js API Adapter\n *\n * Sidequest.js의 API를 NestJS와 통합합니다.\n * 실제 sidequest 패키지를 사용하여 Job 처리를 수행합니다.\n */\n@Injectable()\nexport class SidequestAdapter {\n private readonly logger = new Logger(SidequestAdapter.name);\n private isStarted = false;\n private readonly registeredJobs = new Map<string, JobClassType>();\n\n /**\n * Sidequest 엔진 시작\n */\n async start(options: SidequestModuleOptions): Promise<void> {\n if (this.isStarted) {\n this.logger.warn('Sidequest engine is already started');\n return;\n }\n\n this.logger.log('Starting Sidequest engine...');\n\n try {\n // Sidequest 설정 구성\n const config: Record<string, unknown> = {\n backend: {\n driver: options.backend.driver,\n config: options.backend.config,\n },\n };\n\n // 큐 설정\n if (options.queues) {\n config.queues = options.queues.map(q => ({\n name: q.name,\n concurrency: q.concurrency,\n priority: q.priority,\n state: q.state,\n }));\n }\n\n // 엔진 설정\n if (options.maxConcurrentJobs !== undefined) {\n config.maxConcurrentJobs = options.maxConcurrentJobs;\n }\n if (options.minThreads !== undefined) {\n config.minThreads = options.minThreads;\n }\n if (options.maxThreads !== undefined) {\n config.maxThreads = options.maxThreads;\n }\n if (options.jobPollingInterval !== undefined) {\n config.jobPollingInterval = options.jobPollingInterval;\n }\n if (options.releaseStaleJobsIntervalMin !== undefined) {\n config.releaseStaleJobsIntervalMin = options.releaseStaleJobsIntervalMin;\n }\n if (options.cleanupFinishedJobsIntervalMin !== undefined) {\n config.cleanupFinishedJobsIntervalMin = options.cleanupFinishedJobsIntervalMin;\n }\n\n // 로거 설정\n if (options.logger) {\n config.logger = {\n level: options.logger.level ?? 'info',\n json: options.logger.json ?? false,\n };\n }\n\n // 대시보드 설정\n if (options.dashboard) {\n config.dashboard = options.dashboard;\n }\n\n // Sidequest 엔진 시작\n await Sidequest.start(config as Parameters<typeof Sidequest.start>[0]);\n\n this.isStarted = true;\n this.logger.log('Sidequest engine started');\n } catch (error) {\n this.logger.error('Failed to start Sidequest engine', error);\n throw error;\n }\n }\n\n /**\n * Sidequest 엔진 종료\n */\n async shutdown(): Promise<void> {\n if (!this.isStarted) {\n return;\n }\n\n this.logger.log('Stopping Sidequest engine...');\n\n try {\n await Sidequest.stop();\n this.isStarted = false;\n this.logger.log('Sidequest engine stopped');\n } catch (error) {\n this.logger.error('Failed to stop Sidequest engine', error);\n throw error;\n }\n }\n\n /**\n * Job 클래스 등록\n */\n registerJob(jobName: string, JobClass: JobClassType): void {\n this.registeredJobs.set(jobName, JobClass);\n this.logger.debug(`Job '${jobName}' registered`);\n }\n\n /**\n * Job 추가\n */\n async addJob(\n queueName: string,\n jobName: string,\n args: unknown[],\n options?: JobAddOptions,\n ): Promise<string> {\n const JobClass = this.registeredJobs.get(jobName);\n if (!JobClass) {\n throw new Error(`Job class '${jobName}' not found. Make sure it's registered.`);\n }\n\n let builder: JobBuilder<JobClassType> = Sidequest.build(JobClass)\n .queue(queueName);\n\n // 옵션 적용\n if (options?.maxAttempts !== undefined) {\n builder = builder.maxAttempts(options.maxAttempts);\n }\n if (options?.timeout !== undefined) {\n builder = builder.timeout(options.timeout);\n }\n if (options?.priority !== undefined) {\n // priority는 queue 레벨에서 설정됨\n }\n if (options?.scheduledAt !== undefined) {\n builder = builder.availableAt(options.scheduledAt);\n }\n if (options?.retryDelay !== undefined) {\n builder = builder.retryDelay(options.retryDelay);\n }\n if (options?.backoffStrategy !== undefined) {\n builder = builder.backoffStrategy(options.backoffStrategy);\n }\n if (options?.uniqueKey !== undefined) {\n builder = builder.unique(true);\n }\n\n // Job 실행 (enqueue)\n const jobData = await builder.enqueue(...args);\n const jobId = String(jobData?.id ?? `job_${Date.now()}`);\n\n this.logger.debug(`Job '${jobName}' (ID: ${jobId}) added to Queue '${queueName}'`);\n\n return jobId;\n }\n\n /**\n * Bulk Job 추가\n */\n async addBulkJobs(\n queueName: string,\n jobs: Array<{jobName: string; args: unknown[]; options?: JobAddOptions}>,\n ): Promise<string[]> {\n const jobIds: string[] = [];\n\n for (const {jobName, args, options} of jobs) {\n const jobId = await this.addJob(queueName, jobName, args, options);\n jobIds.push(jobId);\n }\n\n return jobIds;\n }\n\n /**\n * Job 조회\n */\n async getJob(jobId: string | number): Promise<JobInfo | undefined> {\n try {\n const numericId = typeof jobId === 'string' ? parseInt(jobId, 10) : jobId;\n if (isNaN(numericId)) {\n return undefined;\n }\n\n const job = await Sidequest.job.get(numericId);\n if (!job) {\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jobData = job as any;\n\n return {\n id: String(job.id),\n name: jobData.name as string | undefined,\n queue: job.queue,\n state: job.state as JobState,\n attempt: job.attempt,\n maxAttempts: job.max_attempts,\n insertedAt: job.inserted_at,\n attemptedAt: job.attempted_at ?? undefined,\n completedAt: job.completed_at ?? undefined,\n result: job.result,\n errors: job.errors as ErrorData[] | null | undefined,\n };\n } catch {\n return undefined;\n }\n }\n\n /**\n * 엔진 시작 여부\n */\n get started(): boolean {\n return this.isStarted;\n }\n\n /**\n * 등록된 Job 클래스 반환\n */\n getRegisteredJob(jobName: string): JobClassType | undefined {\n return this.registeredJobs.get(jobName);\n }\n\n /**\n * 모든 등록된 Job 클래스 반환\n */\n getAllRegisteredJobs(): Map<string, JobClassType> {\n return this.registeredJobs;\n }\n}\n\n// Job 베이스 클래스 re-export\nexport {Job} from 'sidequest';\n","import {Inject, Injectable, Logger, OnModuleDestroy, OnModuleInit} from '@nestjs/common';\nimport {SIDEQUEST_MODULE_OPTIONS} from '../constants.js';\nimport {SidequestAdapter} from '../core/sidequest.adapter.js';\nimport type {SidequestModuleOptions} from '../interfaces/module-options.interface.js';\n\n/**\n * Sidequest 엔진 관리 서비스\n *\n * Sidequest.js 엔진의 라이프사이클을 관리합니다.\n * 모듈 초기화 시 엔진을 시작하고, 종료 시 graceful shutdown을 수행합니다.\n */\n@Injectable()\nexport class SidequestEngineService implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(SidequestEngineService.name);\n\n constructor(\n @Inject(SIDEQUEST_MODULE_OPTIONS)\n private readonly options: SidequestModuleOptions,\n private readonly adapter: SidequestAdapter,\n ) {}\n\n /**\n * 모듈 초기화 시 엔진 시작\n */\n async onModuleInit(): Promise<void> {\n this.logger.log('Initializing Sidequest engine...');\n await this.adapter.start(this.options);\n this.logger.log('Sidequest engine initialized');\n }\n\n /**\n * 모듈 종료 시 엔진 종료\n */\n async onModuleDestroy(): Promise<void> {\n const gracefulShutdown = this.options.gracefulShutdown ?? {enabled: true, timeout: 30000};\n\n if (gracefulShutdown.enabled) {\n this.logger.log(\n `Sidequest engine graceful shutdown (timeout: ${gracefulShutdown.timeout}ms)`,\n );\n }\n\n await this.adapter.shutdown();\n this.logger.log('Sidequest engine stopped');\n }\n\n /**\n * 엔진 시작 여부\n */\n get isStarted(): boolean {\n return this.adapter.started;\n }\n\n /**\n * Adapter 인스턴스 반환\n */\n getAdapter(): SidequestAdapter {\n return this.adapter;\n }\n}\n","import {Inject, Injectable, Logger} from '@nestjs/common';\nimport {SIDEQUEST_MODULE_OPTIONS} from '../constants.js';\nimport {SidequestAdapter} from '../core/sidequest.adapter.js';\nimport type {SidequestModuleOptions, QueueConfig} from '../interfaces/module-options.interface.js';\nimport type {IQueueService, JobAddOptions} from '../interfaces/queue.interface.js';\n\n/**\n * Queue 레지스트리 서비스\n *\n * 큐 인스턴스를 관리하고 @InjectQueue()를 위한 DI 프로바이더를 제공합니다.\n */\n@Injectable()\nexport class QueueRegistryService {\n private readonly logger = new Logger(QueueRegistryService.name);\n private readonly queueServices = new Map<string, IQueueService>();\n\n constructor(\n @Inject(SIDEQUEST_MODULE_OPTIONS)\n private readonly options: SidequestModuleOptions,\n private readonly adapter: SidequestAdapter,\n ) {\n this.initializeQueues();\n }\n\n /**\n * 설정된 큐 초기화\n */\n private initializeQueues(): void {\n const queues = this.options.queues ?? [];\n\n for (const queueConfig of queues) {\n this.registerQueue(queueConfig);\n }\n\n // 기본 큐가 없으면 생성\n if (!this.queueServices.has('default')) {\n this.registerQueue({name: 'default'});\n }\n }\n\n /**\n * 큐 등록\n */\n registerQueue(config: QueueConfig): void {\n const queueService = this.createQueueService(config.name);\n this.queueServices.set(config.name, queueService);\n this.logger.log(`Queue '${config.name}' registered`);\n }\n\n /**\n * 큐 서비스 조회\n */\n getQueue(name: string): IQueueService | undefined {\n return this.queueServices.get(name);\n }\n\n /**\n * 큐 서비스 조회 (없으면 에러)\n */\n getQueueOrThrow(name: string): IQueueService {\n const queue = this.getQueue(name);\n if (!queue) {\n throw new Error(\n `Queue '${name}' not found. Make sure it is registered in SidequestModule.forRoot().`,\n );\n }\n return queue;\n }\n\n /**\n * 모든 큐 조회\n */\n getAllQueues(): Map<string, IQueueService> {\n return this.queueServices;\n }\n\n /**\n * 큐 서비스 인스턴스 생성\n */\n private createQueueService(queueName: string): IQueueService {\n const adapter = this.adapter;\n\n return {\n name: queueName,\n\n async add<T>(JobClass: new (...args: unknown[]) => T, ...args: unknown[]): Promise<string> {\n const jobName = JobClass.name;\n return adapter.addJob(queueName, jobName, args);\n },\n\n async addWithOptions<T>(\n JobClass: new (...args: unknown[]) => T,\n options: JobAddOptions,\n ...args: unknown[]\n ): Promise<string> {\n const jobName = JobClass.name;\n return adapter.addJob(queueName, jobName, args, options);\n },\n\n async addScheduled<T>(\n JobClass: new (...args: unknown[]) => T,\n scheduledAt: Date,\n ...args: unknown[]\n ): Promise<string> {\n const jobName = JobClass.name;\n return adapter.addJob(queueName, jobName, args, {scheduledAt});\n },\n\n async addBulk<T>(\n jobs: Array<{\n JobClass: new (...args: unknown[]) => T;\n args: unknown[];\n options?: JobAddOptions;\n }>,\n ): Promise<string[]> {\n const bulkJobs = jobs.map(job => {\n const result: {jobName: string; args: unknown[]; options?: JobAddOptions} = {\n jobName: job.JobClass.name,\n args: job.args,\n };\n if (job.options !== undefined) {\n result.options = job.options;\n }\n return result;\n });\n return adapter.addBulkJobs(queueName, bulkJobs);\n },\n };\n }\n}\n","import {Injectable, Logger, Optional, Inject} from '@nestjs/common';\nimport {SIDEQUEST_MODULE_OPTIONS} from '../constants.js';\nimport type {SidequestModuleOptions} from '../interfaces/module-options.interface.js';\n\n// nestjs-cls 타입 (optional dependency)\ninterface ClsService {\n getId(): string | undefined;\n get<T>(key: string): T | undefined;\n set<T>(key: string, value: T): void;\n run<T>(callback: () => T): T;\n}\n\n/**\n * CLS(Continuation Local Storage) 통합 서비스\n *\n * nestjs-cls가 설치되어 있을 경우 Job 실행 시 context를 전파합니다.\n * nestjs-cls가 없으면 no-op으로 동작합니다.\n */\n@Injectable()\nexport class ClsIntegrationService {\n private readonly logger = new Logger(ClsIntegrationService.name);\n private readonly enabled: boolean;\n private clsService: ClsService | null = null;\n\n constructor(\n @Inject(SIDEQUEST_MODULE_OPTIONS)\n options: SidequestModuleOptions,\n @Optional() @Inject('ClsService') clsService?: ClsService,\n ) {\n this.enabled = options.enableCls ?? false;\n this.clsService = clsService ?? null;\n\n if (this.enabled && !this.clsService) {\n this.logger.warn(\n 'CLS integration is enabled but nestjs-cls is not installed. ' +\n 'Install nestjs-cls to enable context propagation.',\n );\n }\n }\n\n /**\n * CLS context 내에서 콜백 실행\n */\n async runInContext<T>(\n metadata: Record<string, unknown>,\n callback: () => Promise<T>,\n ): Promise<T> {\n if (!this.enabled || !this.clsService) {\n return callback();\n }\n\n // nestjs-cls의 run 메서드를 사용하여 새 context에서 실행\n return new Promise((resolve, reject) => {\n try {\n this.clsService!.run(() => {\n // 메타데이터를 CLS에 설정\n for (const [key, value] of Object.entries(metadata)) {\n this.clsService!.set(key, value);\n }\n\n callback().then(resolve).catch(reject);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 현재 traceId 조회\n */\n getTraceId(): string | undefined {\n if (!this.enabled || !this.clsService) {\n return undefined;\n }\n\n return this.clsService.get<string>('traceId');\n }\n\n /**\n * traceId 설정\n */\n setTraceId(traceId: string): void {\n if (!this.enabled || !this.clsService) {\n return;\n }\n\n this.clsService.set('traceId', traceId);\n }\n\n /**\n * CLS에서 값 조회\n */\n get<T>(key: string): T | undefined {\n if (!this.enabled || !this.clsService) {\n return undefined;\n }\n\n return this.clsService.get<T>(key);\n }\n\n /**\n * CLS에 값 설정\n */\n set<T>(key: string, value: T): void {\n if (!this.enabled || !this.clsService) {\n return;\n }\n\n this.clsService.set(key, value);\n }\n\n /**\n * CLS 통합 활성화 여부\n */\n isEnabled(): boolean {\n return this.enabled && this.clsService !== null;\n }\n}\n","import {Injectable, Logger, Optional} from '@nestjs/common';\nimport type {RegisteredProcessor, RegisteredHandler} from '../interfaces/processor.interface.js';\nimport {ClsIntegrationService} from './cls-integration.service.js';\n\n/**\n * Processor 레지스트리 서비스\n *\n * @Processor 데코레이터로 등록된 프로세서와 핸들러를 관리합니다.\n */\n@Injectable()\nexport class ProcessorRegistryService {\n private readonly logger = new Logger(ProcessorRegistryService.name);\n private readonly processors = new Map<string, RegisteredProcessor>();\n\n constructor(\n @Optional() private readonly clsService?: ClsIntegrationService,\n ) {}\n\n /**\n * 프로세서 등록\n */\n register(processor: RegisteredProcessor): void {\n this.processors.set(processor.queueName, processor);\n this.logger.log(\n `Processor '${processor.metatype.name}' (Queue: ${processor.queueName}) registered`,\n );\n }\n\n /**\n * 프로세서 조회\n */\n getProcessor(queueName: string): RegisteredProcessor | undefined {\n return this.processors.get(queueName);\n }\n\n /**\n * 모든 프로세서 조회\n */\n getAllProcessors(): Map<string, RegisteredProcessor> {\n return this.processors;\n }\n\n /**\n * Job 핸들러 조회\n */\n getJobHandler(queueName: string, jobName: string): RegisteredHandler | undefined {\n const processor = this.processors.get(queueName);\n if (!processor) {\n return undefined;\n }\n return processor.handlers.get(jobName);\n }\n\n /**\n * Job 완료 핸들러 조회\n */\n getCompleteHandler(queueName: string, jobName: string): string | undefined {\n const processor = this.processors.get(queueName);\n if (!processor) {\n return undefined;\n }\n return processor.completeHandlers.get(jobName) ?? processor.completeHandlers.get('*');\n }\n\n /**\n * Job 실패 핸들러 조회\n */\n getFailedHandler(queueName: string, jobName: string): string | undefined {\n const processor = this.processors.get(queueName);\n if (!processor) {\n return undefined;\n }\n return processor.failedHandlers.get(jobName) ?? processor.failedHandlers.get('*');\n }\n\n /**\n * Job 디스패치 (실행)\n *\n * @param queueName - 큐 이름\n * @param jobName - Job 이름\n * @param args - Job 인자\n * @param metadata - Job 메타데이터 (traceId 등)\n */\n async dispatch(\n queueName: string,\n jobName: string,\n args: unknown[],\n metadata?: Record<string, unknown>,\n ): Promise<unknown> {\n const processor = this.processors.get(queueName);\n if (!processor) {\n throw new Error(`Processor not found for Queue '${queueName}'`);\n }\n\n const handler = processor.handlers.get(jobName);\n if (!handler) {\n throw new Error(`Handler not found for Job '${jobName}' (Queue: ${queueName})`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const instance = processor.instance as Record<string, Function>;\n const method = instance[handler.methodName];\n\n if (typeof method !== 'function') {\n throw new Error(`Handler method '${handler.methodName}' not found`);\n }\n\n // CLS context에서 실행\n const executeJob = async (): Promise<unknown> => {\n try {\n const result = await method.apply(processor.instance, args);\n\n // 완료 핸들러 호출\n const completeHandlerName = this.getCompleteHandler(queueName, jobName);\n if (completeHandlerName) {\n const completeHandler = instance[completeHandlerName];\n if (typeof completeHandler === 'function') {\n await completeHandler.apply(processor.instance, [{jobName, args, result}]);\n }\n }\n\n return result;\n } catch (error) {\n // 실패 핸들러 호출\n const failedHandlerName = this.getFailedHandler(queueName, jobName);\n if (failedHandlerName) {\n const failedHandler = instance[failedHandlerName];\n if (typeof failedHandler === 'function') {\n await failedHandler.apply(processor.instance, [{jobName, args, error}]);\n }\n }\n\n throw error;\n }\n };\n\n // CLS 통합이 활성화되어 있으면 context 내에서 실행\n if (this.clsService?.isEnabled() && metadata) {\n return this.clsService.runInContext(metadata, executeJob);\n }\n\n return executeJob();\n }\n}\n","import {Injectable, Logger, OnModuleInit} from '@nestjs/common';\nimport {DiscoveryService, MetadataScanner, Reflector} from '@nestjs/core';\nimport {InstanceWrapper} from '@nestjs/core/injector/instance-wrapper';\nimport {\n PROCESSOR_METADATA_KEY,\n ON_JOB_METADATA_KEY,\n RETRY_OPTIONS_METADATA_KEY,\n ON_JOB_COMPLETE_METADATA_KEY,\n ON_JOB_FAILED_METADATA_KEY,\n} from '../constants.js';\nimport {ProcessorRegistryService} from '../services/processor-registry.service.js';\nimport type {\n ProcessorMetadata,\n OnJobMetadata,\n RetryOptions,\n RegisteredHandler,\n RegisteredProcessor,\n} from '../interfaces/processor.interface.js';\n\n/**\n * Processor Explorer\n *\n * 애플리케이션 시작 시 @Processor 데코레이터가 붙은 클래스를 스캔하고,\n * @OnJob, @Retry, @OnJobComplete, @OnJobFailed 메타데이터를 수집하여\n * ProcessorRegistry에 등록합니다.\n */\n@Injectable()\nexport class ProcessorExplorer implements OnModuleInit {\n private readonly logger = new Logger(ProcessorExplorer.name);\n\n constructor(\n private readonly discoveryService: DiscoveryService,\n private readonly metadataScanner: MetadataScanner,\n private readonly reflector: Reflector,\n private readonly processorRegistry: ProcessorRegistryService,\n ) {}\n\n /**\n * 모듈 초기화 시 프로세서 스캔\n */\n async onModuleInit(): Promise<void> {\n this.logger.log('Scanning for processors...');\n await this.explore();\n this.logger.log('Processor scan completed');\n }\n\n /**\n * 모든 프로바이더를 스캔하여 @Processor 클래스 찾기\n */\n async explore(): Promise<void> {\n const providers = this.discoveryService.getProviders();\n\n for (const wrapper of providers) {\n await this.processWrapper(wrapper);\n }\n }\n\n /**\n * 프로바이더 래퍼 처리\n */\n private async processWrapper(wrapper: InstanceWrapper): Promise<void> {\n const {instance, metatype} = wrapper;\n\n // 인스턴스와 메타타입이 없으면 스킵\n if (!instance || !metatype) {\n return;\n }\n\n // @Processor 메타데이터 확인\n const processorMetadata = this.reflector.get<ProcessorMetadata>(\n PROCESSOR_METADATA_KEY,\n metatype,\n );\n\n if (!processorMetadata) {\n return;\n }\n\n // 핸들러 스캔\n const handlers = this.scanHandlers(instance, metatype);\n const completeHandlers = this.scanCompleteHandlers(instance, metatype);\n const failedHandlers = this.scanFailedHandlers(instance, metatype);\n\n // 프로세서 등록\n const registeredProcessor: RegisteredProcessor = {\n queueName: processorMetadata.queueName,\n instance,\n metatype,\n handlers,\n completeHandlers,\n failedHandlers,\n };\n\n this.processorRegistry.register(registeredProcessor);\n\n this.logger.log(\n `Processor '${metatype.name}' registered (Queue: ${processorMetadata.queueName}, Handlers: ${handlers.size})`,\n );\n }\n\n /**\n * @OnJob 메서드 스캔\n */\n private scanHandlers(instance: unknown, _metatype: object): Map<string, RegisteredHandler> {\n const handlers = new Map<string, RegisteredHandler>();\n const prototype = Object.getPrototypeOf(instance);\n const methodNames = this.metadataScanner.getAllMethodNames(prototype);\n\n for (const methodName of methodNames) {\n const methodRef = prototype[methodName];\n\n // @OnJob 메타데이터 확인\n const onJobMetadata = this.reflector.get<OnJobMetadata>(ON_JOB_METADATA_KEY, methodRef);\n\n if (!onJobMetadata) {\n continue;\n }\n\n // @Retry 메타데이터 확인\n const retryOptions = this.reflector.get<RetryOptions>(RETRY_OPTIONS_METADATA_KEY, methodRef);\n\n const handler: RegisteredHandler = {\n methodName,\n jobName: onJobMetadata.jobName,\n options: onJobMetadata.options,\n retryOptions,\n };\n\n handlers.set(onJobMetadata.jobName, handler);\n\n this.logger.debug(` - Job '${onJobMetadata.jobName}' -> ${methodName}()`);\n }\n\n return handlers;\n }\n\n /**\n * @OnJobComplete 메서드 스캔\n */\n private scanCompleteHandlers(instance: unknown, _metatype: object): Map<string, string> {\n const handlers = new Map<string, string>();\n const prototype = Object.getPrototypeOf(instance);\n const methodNames = this.metadataScanner.getAllMethodNames(prototype);\n\n for (const methodName of methodNames) {\n const methodRef = prototype[methodName];\n\n // @OnJobComplete 메타데이터 확인\n const jobName = this.reflector.get<string | undefined>(\n ON_JOB_COMPLETE_METADATA_KEY,\n methodRef,\n );\n\n if (jobName !== undefined) {\n // jobName이 빈 문자열이면 모든 Job에 대해 호출 ('*')\n const key = jobName || '*';\n handlers.set(key, methodName);\n this.logger.debug(` - OnJobComplete '${key}' -> ${methodName}()`);\n }\n }\n\n return handlers;\n }\n\n /**\n * @OnJobFailed 메서드 스캔\n */\n private scanFailedHandlers(instance: unknown, _metatype: object): Map<string, string> {\n const handlers = new Map<string, string>();\n const prototype = Object.getPrototypeOf(instance);\n const methodNames = this.metadataScanner.getAllMethodNames(prototype);\n\n for (const methodName of methodNames) {\n const methodRef = prototype[methodName];\n\n // @OnJobFailed 메타데이터 확인\n const jobName = this.reflector.get<string | undefined>(ON_JOB_FAILED_METADATA_KEY, methodRef);\n\n if (jobName !== undefined) {\n // jobName이 빈 문자열이면 모든 Job에 대해 호출 ('*')\n const key = jobName || '*';\n handlers.set(key, methodName);\n this.logger.debug(` - OnJobFailed '${key}' -> ${methodName}()`);\n }\n }\n\n return handlers;\n }\n}\n","import {DynamicModule, Global, Module, Provider} from '@nestjs/common';\nimport {DiscoveryModule} from '@nestjs/core';\nimport {SIDEQUEST_MODULE_OPTIONS, getQueueToken} from '../constants.js';\nimport {SidequestAdapter} from '../core/sidequest.adapter.js';\nimport type {\n SidequestModuleOptions,\n SidequestModuleAsyncOptions,\n SidequestOptionsFactory,\n} from '../interfaces/module-options.interface.js';\nimport {SidequestEngineService} from '../services/sidequest-engine.service.js';\nimport {QueueRegistryService} from '../services/queue-registry.service.js';\nimport {ProcessorRegistryService} from '../services/processor-registry.service.js';\nimport {ClsIntegrationService} from '../services/cls-integration.service.js';\nimport {ProcessorExplorer} from '../explorers/processor.explorer.js';\n\n/**\n * SidequestModule\n *\n * NestJS에서 Sidequest.js를 사용하기 위한 메인 모듈입니다.\n *\n * @example\n * ```typescript\n * // 동기 설정\n * @Module({\n * imports: [\n * SidequestModule.forRoot({\n * backend: {\n * driver: '@sidequest/postgres-backend',\n * config: process.env.DATABASE_URL,\n * },\n * queues: [\n * { name: 'email', concurrency: 5 },\n * { name: 'report', concurrency: 2 },\n * ],\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * // 비동기 설정 (ConfigService 사용)\n * @Module({\n * imports: [\n * SidequestModule.forRootAsync({\n * imports: [ConfigModule],\n * useFactory: (config: ConfigService) => ({\n * backend: {\n * driver: '@sidequest/postgres-backend',\n * config: config.get('DATABASE_URL'),\n * },\n * queues: [{ name: 'default' }],\n * }),\n * inject: [ConfigService],\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\n@Global()\n@Module({})\nexport class SidequestModule {\n /**\n * 동기 설정으로 모듈 등록\n */\n static forRoot(options: SidequestModuleOptions): DynamicModule {\n const isGlobal = options.isGlobal ?? true;\n const queueProviders = this.createQueueProviders(options);\n\n return {\n module: SidequestModule,\n global: isGlobal,\n imports: [DiscoveryModule],\n providers: [\n {\n provide: SIDEQUEST_MODULE_OPTIONS,\n useValue: options,\n },\n SidequestAdapter,\n SidequestEngineService,\n QueueRegistryService,\n ProcessorRegistryService,\n ClsIntegrationService,\n ProcessorExplorer,\n ...queueProviders,\n ],\n exports: [\n SIDEQUEST_MODULE_OPTIONS,\n SidequestAdapter,\n SidequestEngineService,\n QueueRegistryService,\n ProcessorRegistryService,\n ClsIntegrationService,\n ...queueProviders.map(p => (p as {provide: symbol | string}).provide),\n ],\n };\n }\n\n /**\n * 비동기 설정으로 모듈 등록\n */\n static forRootAsync(asyncOptions: SidequestModuleAsyncOptions): DynamicModule {\n const isGlobal = asyncOptions.isGlobal ?? true;\n\n return {\n module: SidequestModule,\n global: isGlobal,\n imports: [DiscoveryModule, ...(asyncOptions.imports || [])],\n providers: [\n ...this.createAsyncProviders(asyncOptions),\n SidequestAdapter,\n SidequestEngineService,\n QueueRegistryService,\n ProcessorRegistryService,\n ClsIntegrationService,\n ProcessorExplorer,\n // 동적 큐 프로바이더 - options에서 queues를 읽어 생성\n {\n provide: 'SIDEQUEST_QUEUE_PROVIDERS_INIT',\n useFactory: () => {\n // QueueRegistryService가 자동으로 큐를 초기화하므로 별도 처리 불필요\n return true;\n },\n inject: [QueueRegistryService],\n },\n ],\n exports: [\n SIDEQUEST_MODULE_OPTIONS,\n SidequestAdapter,\n SidequestEngineService,\n QueueRegistryService,\n ProcessorRegistryService,\n ClsIntegrationService,\n ],\n };\n }\n\n /**\n * 큐별 DI 프로바이더 생성\n */\n private static createQueueProviders(options: SidequestModuleOptions): Provider[] {\n const queues = options.queues ?? [{name: 'default'}];\n\n return queues.map(queue => ({\n provide: getQueueToken(queue.name),\n useFactory: (registry: QueueRegistryService) => registry.getQueueOrThrow(queue.name),\n inject: [QueueRegistryService],\n }));\n }\n\n /**\n * 비동기 프로바이더 생성\n */\n private static createAsyncProviders(asyncOptions: SidequestModuleAsyncOptions): Provider[] {\n if (asyncOptions.useFactory) {\n return [\n {\n provide: SIDEQUEST_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n },\n ];\n }\n\n if (asyncOptions.useClass) {\n return [\n {\n provide: asyncOptions.useClass,\n useClass: asyncOptions.useClass,\n },\n {\n provide: SIDEQUEST_MODULE_OPTIONS,\n useFactory: async (optionsFactory: SidequestOptionsFactory) =>\n optionsFactory.createSidequestOptions(),\n inject: [asyncOptions.useClass],\n },\n ];\n }\n\n if (asyncOptions.useExisting) {\n return [\n {\n provide: SIDEQUEST_MODULE_OPTIONS,\n useFactory: async (optionsFactory: SidequestOptionsFactory) =>\n optionsFactory.createSidequestOptions(),\n inject: [asyncOptions.useExisting],\n },\n ];\n }\n\n return [\n {\n provide: SIDEQUEST_MODULE_OPTIONS,\n useValue: {},\n },\n ];\n }\n}\n","import {Injectable, SetMetadata} from '@nestjs/common';\nimport {PROCESSOR_METADATA_KEY} from '../constants.js';\nimport type {ProcessorOptions, ProcessorMetadata} from '../interfaces/processor.interface.js';\n\n/**\n * 클래스를 Sidequest Job Processor로 지정합니다.\n *\n * @Processor 데코레이터가 붙은 클래스는 모듈 초기화 시 자동으로 스캔되어\n * 해당 큐의 Job 핸들러로 등록됩니다.\n *\n * @param queueName - 처리할 큐 이름\n * @param options - 프로세서 옵션\n *\n * @example\n * ```typescript\n * @Processor('email')\n * export class EmailProcessor {\n * @OnJob('send-welcome-email')\n * async handleWelcomeEmail(job: JobContext) {\n * const { to, subject, body } = job.data;\n * await this.mailer.send({ to, subject, body });\n * }\n * }\n *\n * // 동시성 설정과 함께\n * @Processor('report', { concurrency: 2 })\n * export class ReportProcessor {\n * @OnJob('generate-daily-report')\n * async handleDailyReport(job: JobContext) {\n * // 리포트 생성 로직\n * }\n * }\n * ```\n */\nexport function Processor(queueName: string, options?: ProcessorOptions): ClassDecorator {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n return (target: Function): void => {\n const metadata: ProcessorMetadata = {\n queueName,\n options,\n };\n\n // 메타데이터 설정\n SetMetadata(PROCESSOR_METADATA_KEY, metadata)(target);\n\n // @Injectable() 자동 적용\n Injectable()(target);\n };\n}\n","import {SetMetadata} from '@nestjs/common';\nimport {ON_JOB_METADATA_KEY} from '../constants.js';\nimport type {OnJobOptions, OnJobMetadata} from '../interfaces/processor.interface.js';\n\n/**\n * 메서드를 특정 Job 타입의 핸들러로 지정합니다.\n *\n * @Processor 데코레이터가 붙은 클래스 내부에서 사용합니다.\n * 해당 Job이 큐에서 처리될 때 이 메서드가 호출됩니다.\n *\n * @param jobName - Job 이름 (일반적으로 Job 클래스명)\n * @param options - Job 실행 옵션 (우선순위, 타임아웃 등)\n *\n * @example\n * ```typescript\n * @Processor('email')\n * export class EmailProcessor {\n * @OnJob('SendWelcomeEmailJob')\n * async handleWelcomeEmail(job: JobContext) {\n * const { to, subject, body } = job.data;\n * await this.mailer.send({ to, subject, body });\n * }\n *\n * // 우선순위와 타임아웃 설정\n * @OnJob('SendPriorityEmailJob', { priority: 100, timeout: 5000 })\n * async handlePriorityEmail(job: JobContext) {\n * // 우선순위가 높은 이메일 처리\n * }\n * }\n * ```\n */\nexport function OnJob(jobName: string, options?: OnJobOptions): MethodDecorator {\n return (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor => {\n const metadata: OnJobMetadata = {\n jobName,\n options,\n };\n\n SetMetadata(ON_JOB_METADATA_KEY, metadata)(target, propertyKey, descriptor);\n\n return descriptor;\n };\n}\n","import {SetMetadata} from '@nestjs/common';\nimport {RETRY_OPTIONS_METADATA_KEY} from '../constants.js';\nimport type {RetryOptions} from '../interfaces/processor.interface.js';\n\n/**\n * Job 재시도 정책을 설정합니다.\n *\n * @OnJob 데코레이터와 함께 사용하여 Job 실패 시 재시도 동작을 정의합니다.\n *\n * @param options - 재시도 옵션\n *\n * @example\n * ```typescript\n * @Processor('payment')\n * export class PaymentProcessor {\n * // 고정 지연 재시도\n * @OnJob('ProcessPaymentJob')\n * @Retry({ maxAttempts: 3, delay: 1000 })\n * async handlePayment(job: JobContext) {\n * // 결제 처리 로직\n * }\n *\n * // 지수 백오프 재시도\n * @OnJob('RefundJob')\n * @Retry({ maxAttempts: 5, delay: 500, backoff: 'exponential' })\n * async handleRefund(job: JobContext) {\n * // 환불 처리 로직\n * }\n * }\n * ```\n */\nexport function Retry(options: RetryOptions): MethodDecorator {\n return (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor => {\n SetMetadata(RETRY_OPTIONS_METADATA_KEY, options)(target, propertyKey, descriptor);\n return descriptor;\n };\n}\n","import {Inject} from '@nestjs/common';\nimport {getQueueToken} from '../constants.js';\n\n/**\n * Queue 인스턴스를 주입합니다.\n *\n * SidequestModule.forRoot()에서 등록된 큐를 서비스에 주입받아 사용할 수 있습니다.\n *\n * @param queueName - 주입받을 큐 이름\n *\n * @example\n * ```typescript\n * @Injectable()\n * export class UserService {\n * constructor(\n * @InjectQueue('email') private emailQueue: IQueueService,\n * @InjectQueue('notification') private notificationQueue: IQueueService,\n * ) {}\n *\n * async createUser(email: string, name: string) {\n * // 사용자 생성 로직...\n *\n * // 환영 이메일 발송\n * await this.emailQueue.add(SendWelcomeEmailJob, email, `Welcome, ${name}!`);\n *\n * // 알림 발송\n * await this.notificationQueue.add(SendNotificationJob, email, 'new-user');\n * }\n * }\n * ```\n */\nexport function InjectQueue(queueName: string): ParameterDecorator {\n return Inject(getQueueToken(queueName));\n}\n","import {SetMetadata} from '@nestjs/common';\nimport {ON_JOB_COMPLETE_METADATA_KEY} from '../constants.js';\n\n/**\n * Job 완료 이벤트 핸들러를 지정합니다.\n *\n * @Processor 클래스 내부에서 사용하며, Job이 성공적으로 완료되면 호출됩니다.\n *\n * @param jobName - 대상 Job 이름 (생략 시 모든 Job에 대해 호출)\n *\n * @example\n * ```typescript\n * @Processor('email')\n * export class EmailProcessor {\n * @OnJob('SendWelcomeEmailJob')\n * async handleWelcomeEmail(job: JobContext) {\n * await this.mailer.send(job.data);\n * }\n *\n * // 특정 Job 완료 이벤트\n * @OnJobComplete('SendWelcomeEmailJob')\n * async onWelcomeEmailComplete(event: JobCompleteEvent) {\n * this.logger.log(`환영 이메일 발송 완료: ${event.result}`);\n * await this.analytics.track('email_sent', { type: 'welcome' });\n * }\n *\n * // 모든 Job 완료 이벤트 (jobName 생략)\n * @OnJobComplete()\n * async onAnyJobComplete(event: JobCompleteEvent) {\n * this.logger.log(`Job 완료: ${event.jobName}`);\n * }\n * }\n * ```\n */\nexport function OnJobComplete(jobName?: string): MethodDecorator {\n return (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor => {\n // jobName이 undefined면 빈 문자열로 저장 (모든 Job에 대해 호출)\n SetMetadata(ON_JOB_COMPLETE_METADATA_KEY, jobName ?? '')(target, propertyKey, descriptor);\n return descriptor;\n };\n}\n\n/**\n * Job 완료 이벤트 데이터\n */\nexport interface JobCompleteEvent {\n /** Job 이름 */\n jobName: string;\n\n /** Job 실행 인자 */\n args: unknown[];\n\n /** Job 실행 결과 */\n result: unknown;\n}\n","import {SetMetadata} from '@nestjs/common';\nimport {ON_JOB_FAILED_METADATA_KEY} from '../constants.js';\n\n/**\n * Job 실패 이벤트 핸들러를 지정합니다.\n *\n * @Processor 클래스 내부에서 사용하며, Job 실행이 실패하면 호출됩니다.\n * 재시도 횟수를 모두 소진한 후 최종 실패 시에만 호출됩니다.\n *\n * @param jobName - 대상 Job 이름 (생략 시 모든 Job에 대해 호출)\n *\n * @example\n * ```typescript\n * @Processor('payment')\n * export class PaymentProcessor {\n * @OnJob('ProcessPaymentJob')\n * @Retry({ maxAttempts: 3 })\n * async handlePayment(job: JobContext) {\n * await this.paymentService.process(job.data);\n * }\n *\n * // 특정 Job 실패 이벤트\n * @OnJobFailed('ProcessPaymentJob')\n * async onPaymentFailed(event: JobFailedEvent) {\n * this.logger.error(`결제 처리 실패: ${event.error.message}`);\n * await this.alertService.notify('payment-failure', {\n * orderId: event.args[0],\n * error: event.error.message,\n * });\n * }\n *\n * // 모든 Job 실패 이벤트 (jobName 생략)\n * @OnJobFailed()\n * async onAnyJobFailed(event: JobFailedEvent) {\n * this.logger.error(`Job 실패: ${event.jobName}`, event.error);\n * }\n * }\n * ```\n */\nexport function OnJobFailed(jobName?: string): MethodDecorator {\n return (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n ): PropertyDescriptor => {\n // jobName이 undefined면 빈 문자열로 저장 (모든 Job에 대해 호출)\n SetMetadata(ON_JOB_FAILED_METADATA_KEY, jobName ?? '')(target, propertyKey, descriptor);\n return descriptor;\n };\n}\n\n/**\n * Job 실패 이벤트 데이터\n */\nexport interface JobFailedEvent {\n /** Job 이름 */\n jobName: string;\n\n /** Job 실행 인자 */\n args: unknown[];\n\n /** 발생한 에러 */\n error: Error;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@m16khb/nestjs-sidequest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "NestJS integration for Sidequest.js - Database-native background job processing",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest --watch",
|
|
26
|
+
"test:coverage": "vitest run --coverage",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"clean": "rm -rf dist .turbo"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"nestjs",
|
|
32
|
+
"sidequest",
|
|
33
|
+
"background-jobs",
|
|
34
|
+
"job-queue",
|
|
35
|
+
"database",
|
|
36
|
+
"postgresql",
|
|
37
|
+
"mysql",
|
|
38
|
+
"mongodb",
|
|
39
|
+
"sqlite",
|
|
40
|
+
"worker",
|
|
41
|
+
"typescript"
|
|
42
|
+
],
|
|
43
|
+
"author": "m16khb",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/m16khb/npm-library.git",
|
|
48
|
+
"directory": "packages/nestjs-sidequest"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/m16khb/npm-library/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/m16khb/npm-library/tree/main/packages/nestjs-sidequest#readme",
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@nestjs/common": "^10.0.0",
|
|
56
|
+
"@nestjs/core": "^10.0.0",
|
|
57
|
+
"@nestjs/testing": "^10.0.0",
|
|
58
|
+
"@swc/core": "^1.15.3",
|
|
59
|
+
"reflect-metadata": "^0.2.0",
|
|
60
|
+
"rxjs": "^7.8.0",
|
|
61
|
+
"tsup": "^8.0.0",
|
|
62
|
+
"typescript": "^5.7.0",
|
|
63
|
+
"unplugin-swc": "^1.5.9",
|
|
64
|
+
"vitest": "^2.0.0"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"sidequest": "^1.13.0"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
71
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
72
|
+
"rxjs": "^7.0.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependenciesMeta": {
|
|
75
|
+
"nestjs-cls": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=22.6.0"
|
|
81
|
+
},
|
|
82
|
+
"publishConfig": {
|
|
83
|
+
"access": "public"
|
|
84
|
+
}
|
|
85
|
+
}
|