saas-backend-kit 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +205 -6
  2. package/dist/auth/index.js +2 -1
  3. package/dist/auth/index.js.map +1 -1
  4. package/dist/auth/index.mjs +2 -1
  5. package/dist/auth/index.mjs.map +1 -1
  6. package/dist/config/index.js +1 -0
  7. package/dist/config/index.js.map +1 -1
  8. package/dist/config/index.mjs +1 -0
  9. package/dist/config/index.mjs.map +1 -1
  10. package/dist/index.js +124 -41
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +122 -42
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/logger/index.js +1 -0
  15. package/dist/logger/index.js.map +1 -1
  16. package/dist/logger/index.mjs +1 -0
  17. package/dist/logger/index.mjs.map +1 -1
  18. package/dist/notifications/index.js +1 -0
  19. package/dist/notifications/index.js.map +1 -1
  20. package/dist/notifications/index.mjs +1 -0
  21. package/dist/notifications/index.mjs.map +1 -1
  22. package/dist/queue/index.js +1 -0
  23. package/dist/queue/index.js.map +1 -1
  24. package/dist/queue/index.mjs +1 -0
  25. package/dist/queue/index.mjs.map +1 -1
  26. package/dist/rate-limit/index.js +2 -0
  27. package/dist/rate-limit/index.js.map +1 -1
  28. package/dist/rate-limit/index.mjs +2 -0
  29. package/dist/rate-limit/index.mjs.map +1 -1
  30. package/dist/response/index.js +51 -40
  31. package/dist/response/index.js.map +1 -1
  32. package/dist/response/index.mjs +51 -40
  33. package/dist/response/index.mjs.map +1 -1
  34. package/dist/upload/index.js +1 -0
  35. package/dist/upload/index.js.map +1 -1
  36. package/dist/upload/index.mjs +1 -0
  37. package/dist/upload/index.mjs.map +1 -1
  38. package/examples/express/.env.example +4 -1
  39. package/jest-output.json +72 -0
  40. package/jest.config.js +19 -0
  41. package/package.json +10 -7
  42. package/src/auth/jwt.ts +1 -1
  43. package/src/config/index.ts +1 -0
  44. package/src/database/index.ts +102 -0
  45. package/src/index.ts +1 -0
  46. package/src/rate-limit/express.ts +1 -0
  47. package/src/response/index.ts +49 -40
  48. package/tests/auth.test.ts +134 -0
  49. package/tests/config.test.ts +36 -0
  50. package/tests/logger.test.ts +47 -0
  51. package/tests/notifications.test.ts +19 -0
  52. package/tests/rate-limit.test.ts +50 -0
  53. package/tests/upload.test.ts +33 -0
  54. package/tsconfig.test.json +14 -0
  55. package/tsup.config.ts +2 -1
@@ -7,6 +7,7 @@ var envSchema = z.object({
7
7
  NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
8
8
  PORT: z.string().default("3000"),
9
9
  DATABASE_URL: z.string().optional(),
10
+ MONGODB_URL: z.string().optional(),
10
11
  REDIS_URL: z.string().default("redis://localhost:6379"),
11
12
  JWT_SECRET: z.string().min(32).optional(),
12
13
  JWT_EXPIRES_IN: z.string().default("7d"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/index.ts","../../src/logger/index.ts","../../src/queue/index.ts"],"names":["logger","queue"],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import pino, { Logger, LoggerOptions, Bindings } from 'pino';\nimport { config } from '../config';\n\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\nexport interface LoggerConfig extends Partial<LoggerOptions> {\n level?: LogLevel;\n name?: string;\n prettyPrint?: boolean;\n}\n\nexport interface RequestLoggerOptions {\n logLevel?: LogLevel;\n autoLogging?: boolean;\n}\n\nclass LoggerManager {\n private loggers: Map<string, Logger> = new Map();\n private defaultLogger: Logger;\n\n constructor() {\n const level = (config.get('LOG_LEVEL') as LogLevel) || 'info';\n this.defaultLogger = pino({\n level,\n name: 'saas-backend-kit',\n formatters: {\n bindings: (bindings: Bindings) => ({\n ...bindings,\n service: 'saas-backend-kit',\n }),\n },\n });\n }\n\n createLogger(options: LoggerConfig = {}): Logger {\n const name = options.name || 'default';\n \n if (this.loggers.has(name)) {\n return this.loggers.get(name)!;\n }\n\n const level = options.level || (config.get('LOG_LEVEL') as LogLevel) || 'info';\n \n const logger = pino({\n level,\n name: options.name,\n ...options,\n });\n\n this.loggers.set(name, logger);\n return logger;\n }\n\n getLogger(name?: string): Logger {\n if (name) {\n return this.loggers.get(name) || this.defaultLogger;\n }\n return this.defaultLogger;\n }\n\n child(bindings: Bindings, options?: { name?: string }): Logger {\n const name = options?.name || 'child';\n const parent = options?.name ? this.getLogger(name) : this.defaultLogger;\n return parent.child(bindings);\n }\n}\n\nconst loggerManager = new LoggerManager();\n\nexport const logger = {\n info: (message: string, ...args: unknown[]) => loggerManager.getLogger().info(message, ...args),\n warn: (message: string, ...args: unknown[]) => loggerManager.getLogger().warn(message, ...args),\n error: (message: string, ...args: unknown[]) => loggerManager.getLogger().error(message, ...args),\n debug: (message: string, ...args: unknown[]) => loggerManager.getLogger().debug(message, ...args),\n trace: (message: string, ...args: unknown[]) => loggerManager.getLogger().trace(message, ...args),\n fatal: (message: string, ...args: unknown[]) => loggerManager.getLogger().fatal(message, ...args),\n child: (bindings: Bindings, options?: { name?: string }) => loggerManager.child(bindings, options),\n create: (options?: LoggerConfig) => loggerManager.createLogger(options),\n get: (name?: string) => loggerManager.getLogger(name),\n};\n\nexport function createRequestLogger(options: RequestLoggerOptions = {}) {\n const logLevel = options.logLevel || 'info';\n const logger = loggerManager.getLogger('http');\n\n return function requestLogger(\n req: { method: string; url: string; headers: Record<string, string | string[] | undefined> },\n res: { statusCode: number; statusMessage?: string },\n elapsed: number\n ) {\n const log = logger.child({\n method: req.method,\n url: req.url,\n status: res.statusCode,\n responseTime: elapsed,\n ip: req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || 'unknown',\n userAgent: req.headers['user-agent'],\n });\n\n if (res.statusCode >= 500) {\n log.error(`Request completed`);\n } else if (res.statusCode >= 400) {\n log.warn(`Request completed`);\n } else {\n log.info(`Request completed`);\n }\n };\n}\n\nexport default logger;\n","import { Queue, Worker, Job, JobsOptions, WorkerOptions } from 'bullmq';\nimport { config } from '../config';\nimport { logger } from '../logger';\n\nexport interface QueueOptions {\n name: string;\n defaultJobOptions?: JobsOptions;\n}\n\nexport interface RedisOptions {\n host?: string;\n port?: number;\n password?: string;\n db?: number;\n url?: string;\n}\n\nexport interface JobData {\n [key: string]: unknown;\n}\n\nexport type JobProcessor = (job: Job<JobData>) => Promise<unknown>;\n\nclass QueueManager {\n private queues: Map<string, Queue> = new Map();\n private workers: Map<string, Worker> = new Map();\n private redisOptions: RedisOptions;\n\n constructor() {\n const redisUrl = config.get('REDIS_URL');\n if (redisUrl) {\n this.redisOptions = { url: redisUrl };\n } else {\n this.redisOptions = {\n host: 'localhost',\n port: 6379,\n };\n }\n }\n\n setRedisOptions(options: RedisOptions): void {\n this.redisOptions = options;\n }\n\n createQueue(name: string, options?: Partial<QueueOptions>): Queue {\n if (this.queues.has(name)) {\n return this.queues.get(name)!;\n }\n\n const queue = new Queue(name, {\n connection: this.redisOptions as any,\n defaultJobOptions: options?.defaultJobOptions || {\n removeOnComplete: 100,\n removeOnFail: 100,\n },\n });\n\n this.queues.set(name, queue);\n logger.info(`Queue \"${name}\" created`);\n\n return queue;\n }\n\n getQueue(name: string): Queue | undefined {\n return this.queues.get(name);\n }\n\n async addJob(\n queueName: string,\n jobName: string,\n data: JobData,\n options?: JobsOptions\n ): Promise<Job> {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n const job = await queue.add(jobName, data, options);\n logger.debug(`Job \"${jobName}\" added to queue \"${queueName}\"`, { jobId: job.id });\n return job;\n }\n\n async addBulkJobs(\n queueName: string,\n jobs: Array<{ name: string; data: JobData; options?: JobsOptions }>\n ): Promise<Job[]> {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n const bulkJobs = jobs.map(job => ({\n name: job.name,\n data: job.data,\n ...job.options,\n }));\n const result = await queue.addBulk(bulkJobs);\n logger.debug(`${jobs.length} jobs added to queue \"${queueName}\"`);\n return result;\n }\n\n processJob(\n queueName: string,\n processor: JobProcessor,\n options?: WorkerOptions\n ): Worker {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n \n const worker = new Worker(queueName, async (job) => {\n logger.debug(`Processing job \"${job.name}\"`, { jobId: job.id, queue: queueName });\n return await processor(job);\n }, {\n connection: this.redisOptions as any,\n concurrency: options?.concurrency || 1,\n ...options,\n });\n\n worker.on('completed', (job) => {\n logger.debug(`Job completed`, { jobId: job.id, queue: queueName });\n });\n\n worker.on('failed', (job, err) => {\n logger.error(`Job failed`, { jobId: job?.id, queue: queueName, error: err.message });\n });\n\n worker.on('error', (err) => {\n logger.error(`Worker error`, { queue: queueName, error: err.message });\n });\n\n this.workers.set(queueName, worker);\n logger.info(`Worker started for queue \"${queueName}\"`);\n\n return worker;\n }\n\n async getJobCounts(queueName: string): Promise<Record<string, number>> {\n const queue = this.getQueue(queueName);\n if (!queue) {\n return { waiting: 0, active: 0, completed: 0, failed: 0, delayed: 0 };\n }\n return await queue.getJobCounts();\n }\n\n async getJobs(queueName: string, start: number = 0, end: number = 10): Promise<Job[]> {\n const queue = this.getQueue(queueName);\n if (!queue) return [];\n return await queue.getJobs(['waiting', 'active', 'completed', 'failed'], start, end);\n }\n\n async closeQueue(name: string): Promise<void> {\n const queue = this.queues.get(name);\n if (queue) {\n await queue.close();\n this.queues.delete(name);\n logger.info(`Queue \"${name}\" closed`);\n }\n }\n\n async closeWorker(name: string): Promise<void> {\n const worker = this.workers.get(name);\n if (worker) {\n await worker.close();\n this.workers.delete(name);\n logger.info(`Worker for queue \"${name}\" closed`);\n }\n }\n\n async closeAll(): Promise<void> {\n await Promise.all([\n ...Array.from(this.queues.values()).map(q => q.close()),\n ...Array.from(this.workers.values()).map(w => w.close()),\n ]);\n this.queues.clear();\n this.workers.clear();\n logger.info('All queues and workers closed');\n }\n}\n\nconst queueManager = new QueueManager();\n\nexport const createQueue = (name: string, options?: Partial<QueueOptions>): Queue => {\n return queueManager.createQueue(name, options);\n};\n\nexport const addJob = (\n queueName: string,\n jobName: string,\n data: JobData,\n options?: JobsOptions\n): Promise<Job> => {\n return queueManager.addJob(queueName, jobName, data, options);\n};\n\nexport const processJob = (\n queueName: string,\n processor: JobProcessor,\n options?: WorkerOptions\n): Worker => {\n return queueManager.processJob(queueName, processor, options);\n};\n\nexport const queue = {\n create: createQueue,\n add: addJob,\n process: processJob,\n get: (name: string) => queueManager.getQueue(name),\n getJobCounts: (name: string) => queueManager.getJobCounts(name),\n getJobs: (name: string, start?: number, end?: number) => queueManager.getJobs(name, start, end),\n close: (name: string) => queueManager.closeQueue(name),\n closeAll: () => queueManager.closeAll(),\n setRedisOptions: (options: RedisOptions) => queueManager.setRedisOptions(options),\n};\n\nexport { QueueManager };\nexport default queue;\n"]}
1
+ {"version":3,"sources":["../../src/config/index.ts","../../src/logger/index.ts","../../src/queue/index.ts"],"names":["logger","queue"],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n MONGODB_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import pino, { Logger, LoggerOptions, Bindings } from 'pino';\nimport { config } from '../config';\n\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\nexport interface LoggerConfig extends Partial<LoggerOptions> {\n level?: LogLevel;\n name?: string;\n prettyPrint?: boolean;\n}\n\nexport interface RequestLoggerOptions {\n logLevel?: LogLevel;\n autoLogging?: boolean;\n}\n\nclass LoggerManager {\n private loggers: Map<string, Logger> = new Map();\n private defaultLogger: Logger;\n\n constructor() {\n const level = (config.get('LOG_LEVEL') as LogLevel) || 'info';\n this.defaultLogger = pino({\n level,\n name: 'saas-backend-kit',\n formatters: {\n bindings: (bindings: Bindings) => ({\n ...bindings,\n service: 'saas-backend-kit',\n }),\n },\n });\n }\n\n createLogger(options: LoggerConfig = {}): Logger {\n const name = options.name || 'default';\n \n if (this.loggers.has(name)) {\n return this.loggers.get(name)!;\n }\n\n const level = options.level || (config.get('LOG_LEVEL') as LogLevel) || 'info';\n \n const logger = pino({\n level,\n name: options.name,\n ...options,\n });\n\n this.loggers.set(name, logger);\n return logger;\n }\n\n getLogger(name?: string): Logger {\n if (name) {\n return this.loggers.get(name) || this.defaultLogger;\n }\n return this.defaultLogger;\n }\n\n child(bindings: Bindings, options?: { name?: string }): Logger {\n const name = options?.name || 'child';\n const parent = options?.name ? this.getLogger(name) : this.defaultLogger;\n return parent.child(bindings);\n }\n}\n\nconst loggerManager = new LoggerManager();\n\nexport const logger = {\n info: (message: string, ...args: unknown[]) => loggerManager.getLogger().info(message, ...args),\n warn: (message: string, ...args: unknown[]) => loggerManager.getLogger().warn(message, ...args),\n error: (message: string, ...args: unknown[]) => loggerManager.getLogger().error(message, ...args),\n debug: (message: string, ...args: unknown[]) => loggerManager.getLogger().debug(message, ...args),\n trace: (message: string, ...args: unknown[]) => loggerManager.getLogger().trace(message, ...args),\n fatal: (message: string, ...args: unknown[]) => loggerManager.getLogger().fatal(message, ...args),\n child: (bindings: Bindings, options?: { name?: string }) => loggerManager.child(bindings, options),\n create: (options?: LoggerConfig) => loggerManager.createLogger(options),\n get: (name?: string) => loggerManager.getLogger(name),\n};\n\nexport function createRequestLogger(options: RequestLoggerOptions = {}) {\n const logLevel = options.logLevel || 'info';\n const logger = loggerManager.getLogger('http');\n\n return function requestLogger(\n req: { method: string; url: string; headers: Record<string, string | string[] | undefined> },\n res: { statusCode: number; statusMessage?: string },\n elapsed: number\n ) {\n const log = logger.child({\n method: req.method,\n url: req.url,\n status: res.statusCode,\n responseTime: elapsed,\n ip: req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || 'unknown',\n userAgent: req.headers['user-agent'],\n });\n\n if (res.statusCode >= 500) {\n log.error(`Request completed`);\n } else if (res.statusCode >= 400) {\n log.warn(`Request completed`);\n } else {\n log.info(`Request completed`);\n }\n };\n}\n\nexport default logger;\n","import { Queue, Worker, Job, JobsOptions, WorkerOptions } from 'bullmq';\nimport { config } from '../config';\nimport { logger } from '../logger';\n\nexport interface QueueOptions {\n name: string;\n defaultJobOptions?: JobsOptions;\n}\n\nexport interface RedisOptions {\n host?: string;\n port?: number;\n password?: string;\n db?: number;\n url?: string;\n}\n\nexport interface JobData {\n [key: string]: unknown;\n}\n\nexport type JobProcessor = (job: Job<JobData>) => Promise<unknown>;\n\nclass QueueManager {\n private queues: Map<string, Queue> = new Map();\n private workers: Map<string, Worker> = new Map();\n private redisOptions: RedisOptions;\n\n constructor() {\n const redisUrl = config.get('REDIS_URL');\n if (redisUrl) {\n this.redisOptions = { url: redisUrl };\n } else {\n this.redisOptions = {\n host: 'localhost',\n port: 6379,\n };\n }\n }\n\n setRedisOptions(options: RedisOptions): void {\n this.redisOptions = options;\n }\n\n createQueue(name: string, options?: Partial<QueueOptions>): Queue {\n if (this.queues.has(name)) {\n return this.queues.get(name)!;\n }\n\n const queue = new Queue(name, {\n connection: this.redisOptions as any,\n defaultJobOptions: options?.defaultJobOptions || {\n removeOnComplete: 100,\n removeOnFail: 100,\n },\n });\n\n this.queues.set(name, queue);\n logger.info(`Queue \"${name}\" created`);\n\n return queue;\n }\n\n getQueue(name: string): Queue | undefined {\n return this.queues.get(name);\n }\n\n async addJob(\n queueName: string,\n jobName: string,\n data: JobData,\n options?: JobsOptions\n ): Promise<Job> {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n const job = await queue.add(jobName, data, options);\n logger.debug(`Job \"${jobName}\" added to queue \"${queueName}\"`, { jobId: job.id });\n return job;\n }\n\n async addBulkJobs(\n queueName: string,\n jobs: Array<{ name: string; data: JobData; options?: JobsOptions }>\n ): Promise<Job[]> {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n const bulkJobs = jobs.map(job => ({\n name: job.name,\n data: job.data,\n ...job.options,\n }));\n const result = await queue.addBulk(bulkJobs);\n logger.debug(`${jobs.length} jobs added to queue \"${queueName}\"`);\n return result;\n }\n\n processJob(\n queueName: string,\n processor: JobProcessor,\n options?: WorkerOptions\n ): Worker {\n const queue = this.getQueue(queueName) || this.createQueue(queueName);\n \n const worker = new Worker(queueName, async (job) => {\n logger.debug(`Processing job \"${job.name}\"`, { jobId: job.id, queue: queueName });\n return await processor(job);\n }, {\n connection: this.redisOptions as any,\n concurrency: options?.concurrency || 1,\n ...options,\n });\n\n worker.on('completed', (job) => {\n logger.debug(`Job completed`, { jobId: job.id, queue: queueName });\n });\n\n worker.on('failed', (job, err) => {\n logger.error(`Job failed`, { jobId: job?.id, queue: queueName, error: err.message });\n });\n\n worker.on('error', (err) => {\n logger.error(`Worker error`, { queue: queueName, error: err.message });\n });\n\n this.workers.set(queueName, worker);\n logger.info(`Worker started for queue \"${queueName}\"`);\n\n return worker;\n }\n\n async getJobCounts(queueName: string): Promise<Record<string, number>> {\n const queue = this.getQueue(queueName);\n if (!queue) {\n return { waiting: 0, active: 0, completed: 0, failed: 0, delayed: 0 };\n }\n return await queue.getJobCounts();\n }\n\n async getJobs(queueName: string, start: number = 0, end: number = 10): Promise<Job[]> {\n const queue = this.getQueue(queueName);\n if (!queue) return [];\n return await queue.getJobs(['waiting', 'active', 'completed', 'failed'], start, end);\n }\n\n async closeQueue(name: string): Promise<void> {\n const queue = this.queues.get(name);\n if (queue) {\n await queue.close();\n this.queues.delete(name);\n logger.info(`Queue \"${name}\" closed`);\n }\n }\n\n async closeWorker(name: string): Promise<void> {\n const worker = this.workers.get(name);\n if (worker) {\n await worker.close();\n this.workers.delete(name);\n logger.info(`Worker for queue \"${name}\" closed`);\n }\n }\n\n async closeAll(): Promise<void> {\n await Promise.all([\n ...Array.from(this.queues.values()).map(q => q.close()),\n ...Array.from(this.workers.values()).map(w => w.close()),\n ]);\n this.queues.clear();\n this.workers.clear();\n logger.info('All queues and workers closed');\n }\n}\n\nconst queueManager = new QueueManager();\n\nexport const createQueue = (name: string, options?: Partial<QueueOptions>): Queue => {\n return queueManager.createQueue(name, options);\n};\n\nexport const addJob = (\n queueName: string,\n jobName: string,\n data: JobData,\n options?: JobsOptions\n): Promise<Job> => {\n return queueManager.addJob(queueName, jobName, data, options);\n};\n\nexport const processJob = (\n queueName: string,\n processor: JobProcessor,\n options?: WorkerOptions\n): Worker => {\n return queueManager.processJob(queueName, processor, options);\n};\n\nexport const queue = {\n create: createQueue,\n add: addJob,\n process: processJob,\n get: (name: string) => queueManager.getQueue(name),\n getJobCounts: (name: string) => queueManager.getJobCounts(name),\n getJobs: (name: string, start?: number, end?: number) => queueManager.getJobs(name, start, end),\n close: (name: string) => queueManager.closeQueue(name),\n closeAll: () => queueManager.closeAll(),\n setRedisOptions: (options: RedisOptions) => queueManager.setRedisOptions(options),\n};\n\nexport { QueueManager };\nexport default queue;\n"]}
@@ -29,6 +29,7 @@ var init_config = __esm({
29
29
  NODE_ENV: zod.z.enum(["development", "production", "test"]).default("development"),
30
30
  PORT: zod.z.string().default("3000"),
31
31
  DATABASE_URL: zod.z.string().optional(),
32
+ MONGODB_URL: zod.z.string().optional(),
32
33
  REDIS_URL: zod.z.string().default("redis://localhost:6379"),
33
34
  JWT_SECRET: zod.z.string().min(32).optional(),
34
35
  JWT_EXPIRES_IN: zod.z.string().default("7d"),
@@ -148,6 +149,7 @@ var init_express = __esm({
148
149
  cleanupInterval;
149
150
  constructor() {
150
151
  this.cleanupInterval = setInterval(() => this.cleanup(), 6e4);
152
+ this.cleanupInterval.unref();
151
153
  }
152
154
  cleanup() {
153
155
  const now = Date.now();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/index.ts","../../src/rate-limit/express.ts","../../src/rate-limit/index.ts","../../src/rate-limit/fastify.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { config } from '../config';\n\nexport interface RateLimitOptions {\n window?: string;\n limit?: number;\n keyGenerator?: (req: Request) => string;\n handler?: (req: Request, res: Response) => void;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n skip?: (req: Request) => boolean;\n}\n\ninterface RateLimitRecord {\n count: number;\n resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n private store: Map<string, RateLimitRecord> = new Map();\n private cleanupInterval: NodeJS.Timeout;\n\n constructor() {\n this.cleanupInterval = setInterval(() => this.cleanup(), 60000);\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, record] of this.store.entries()) {\n if (record.resetTime < now) {\n this.store.delete(key);\n }\n }\n }\n\n increment(key: string, windowMs: number): RateLimitRecord {\n const now = Date.now();\n const record = this.store.get(key);\n\n if (!record || record.resetTime < now) {\n const resetTime = now + windowMs;\n this.store.set(key, { count: 1, resetTime });\n return { count: 1, resetTime };\n }\n\n record.count++;\n return record;\n }\n\n get(key: string): RateLimitRecord | undefined {\n return this.store.get(key);\n }\n\n destroy(): void {\n clearInterval(this.cleanupInterval);\n }\n}\n\nclass RateLimiter {\n private options: Required<RateLimitOptions>;\n private store: InMemoryRateLimiter;\n\n constructor(options: RateLimitOptions = {}) {\n const defaultWindow = config.get('RATE_LIMIT_WINDOW') || '1m';\n const defaultLimit = parseInt(config.get('RATE_LIMIT_LIMIT') || '100', 10);\n\n this.options = {\n window: options.window || defaultWindow,\n limit: options.limit || defaultLimit,\n keyGenerator: options.keyGenerator || ((req: Request) => req.ip || 'unknown'),\n handler: options.handler || this.defaultHandler,\n skipSuccessfulRequests: options.skipSuccessfulRequests || false,\n skipFailedRequests: options.skipFailedRequests || false,\n skip: options.skip || (() => false),\n };\n\n this.store = new InMemoryRateLimiter();\n }\n\n private getWindowMs(): number {\n const window = this.options.window;\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n }\n\n private defaultHandler(req: Request, res: Response): void {\n res.status(429).json({\n error: 'Too many requests',\n message: `Rate limit exceeded. Please try again later.`,\n });\n }\n\n middleware(): RequestHandler {\n const windowMs = this.getWindowMs();\n\n return (req: Request, res: Response, next: NextFunction) => {\n if (this.options.skip(req)) {\n return next();\n }\n\n const key = this.options.keyGenerator(req);\n const record = this.store.increment(key, windowMs);\n\n const remaining = Math.max(0, this.options.limit - record.count);\n const resetTime = new Date(record.resetTime);\n\n res.setHeader('X-RateLimit-Limit', this.options.limit);\n res.setHeader('X-RateLimit-Remaining', remaining);\n res.setHeader('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > this.options.limit) {\n return this.options.handler(req, res);\n }\n\n next();\n };\n }\n\n destroy(): void {\n this.store.destroy();\n }\n}\n\nexport function rateLimit(options: RateLimitOptions = {}): RequestHandler {\n const limiter = new RateLimiter(options);\n return limiter.middleware();\n}\n\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\nexport default rateLimit;\n","export * from './express';\nexport * from './fastify';\n","import { FastifyInstance, FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';\nimport { RateLimitOptions, InMemoryRateLimiter } from './express';\n\nexport function registerRateLimitPlugin(fastify: FastifyInstance, options: RateLimitOptions = {}, done: HookHandlerDoneFunction) {\n const limiter = new (require('./express').createRateLimiter.constructor)(options);\n \n fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const key = options.keyGenerator \n ? options.keyGenerator(request.raw as any)\n : request.ip || 'unknown';\n \n const windowMs = parseWindowMs(options.window || '1m');\n const record = (limiter as any).store.increment(key, windowMs);\n const limit = options.limit || 100;\n const remaining = Math.max(0, limit - record.count);\n\n reply.header('X-RateLimit-Limit', limit);\n reply.header('X-RateLimit-Remaining', remaining);\n reply.header('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > limit) {\n reply.status(429).send({\n error: 'Too many requests',\n message: 'Rate limit exceeded. Please try again later.',\n });\n return reply;\n }\n });\n\n done();\n}\n\nfunction parseWindowMs(window: string): number {\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/config/index.ts","../../src/rate-limit/express.ts","../../src/rate-limit/index.ts","../../src/rate-limit/fastify.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n MONGODB_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { config } from '../config';\n\nexport interface RateLimitOptions {\n window?: string;\n limit?: number;\n keyGenerator?: (req: Request) => string;\n handler?: (req: Request, res: Response) => void;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n skip?: (req: Request) => boolean;\n}\n\ninterface RateLimitRecord {\n count: number;\n resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n private store: Map<string, RateLimitRecord> = new Map();\n private cleanupInterval: NodeJS.Timeout;\n\n constructor() {\n this.cleanupInterval = setInterval(() => this.cleanup(), 60000);\n this.cleanupInterval.unref();\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, record] of this.store.entries()) {\n if (record.resetTime < now) {\n this.store.delete(key);\n }\n }\n }\n\n increment(key: string, windowMs: number): RateLimitRecord {\n const now = Date.now();\n const record = this.store.get(key);\n\n if (!record || record.resetTime < now) {\n const resetTime = now + windowMs;\n this.store.set(key, { count: 1, resetTime });\n return { count: 1, resetTime };\n }\n\n record.count++;\n return record;\n }\n\n get(key: string): RateLimitRecord | undefined {\n return this.store.get(key);\n }\n\n destroy(): void {\n clearInterval(this.cleanupInterval);\n }\n}\n\nclass RateLimiter {\n private options: Required<RateLimitOptions>;\n private store: InMemoryRateLimiter;\n\n constructor(options: RateLimitOptions = {}) {\n const defaultWindow = config.get('RATE_LIMIT_WINDOW') || '1m';\n const defaultLimit = parseInt(config.get('RATE_LIMIT_LIMIT') || '100', 10);\n\n this.options = {\n window: options.window || defaultWindow,\n limit: options.limit || defaultLimit,\n keyGenerator: options.keyGenerator || ((req: Request) => req.ip || 'unknown'),\n handler: options.handler || this.defaultHandler,\n skipSuccessfulRequests: options.skipSuccessfulRequests || false,\n skipFailedRequests: options.skipFailedRequests || false,\n skip: options.skip || (() => false),\n };\n\n this.store = new InMemoryRateLimiter();\n }\n\n private getWindowMs(): number {\n const window = this.options.window;\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n }\n\n private defaultHandler(req: Request, res: Response): void {\n res.status(429).json({\n error: 'Too many requests',\n message: `Rate limit exceeded. Please try again later.`,\n });\n }\n\n middleware(): RequestHandler {\n const windowMs = this.getWindowMs();\n\n return (req: Request, res: Response, next: NextFunction) => {\n if (this.options.skip(req)) {\n return next();\n }\n\n const key = this.options.keyGenerator(req);\n const record = this.store.increment(key, windowMs);\n\n const remaining = Math.max(0, this.options.limit - record.count);\n const resetTime = new Date(record.resetTime);\n\n res.setHeader('X-RateLimit-Limit', this.options.limit);\n res.setHeader('X-RateLimit-Remaining', remaining);\n res.setHeader('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > this.options.limit) {\n return this.options.handler(req, res);\n }\n\n next();\n };\n }\n\n destroy(): void {\n this.store.destroy();\n }\n}\n\nexport function rateLimit(options: RateLimitOptions = {}): RequestHandler {\n const limiter = new RateLimiter(options);\n return limiter.middleware();\n}\n\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\nexport default rateLimit;\n","export * from './express';\nexport * from './fastify';\n","import { FastifyInstance, FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';\nimport { RateLimitOptions, InMemoryRateLimiter } from './express';\n\nexport function registerRateLimitPlugin(fastify: FastifyInstance, options: RateLimitOptions = {}, done: HookHandlerDoneFunction) {\n const limiter = new (require('./express').createRateLimiter.constructor)(options);\n \n fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const key = options.keyGenerator \n ? options.keyGenerator(request.raw as any)\n : request.ip || 'unknown';\n \n const windowMs = parseWindowMs(options.window || '1m');\n const record = (limiter as any).store.increment(key, windowMs);\n const limit = options.limit || 100;\n const remaining = Math.max(0, limit - record.count);\n\n reply.header('X-RateLimit-Limit', limit);\n reply.header('X-RateLimit-Remaining', remaining);\n reply.header('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > limit) {\n reply.status(429).send({\n error: 'Too many requests',\n message: 'Rate limit exceeded. Please try again later.',\n });\n return reply;\n }\n });\n\n done();\n}\n\nfunction parseWindowMs(window: string): number {\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n}\n"]}
@@ -27,6 +27,7 @@ var init_config = __esm({
27
27
  NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
28
28
  PORT: z.string().default("3000"),
29
29
  DATABASE_URL: z.string().optional(),
30
+ MONGODB_URL: z.string().optional(),
30
31
  REDIS_URL: z.string().default("redis://localhost:6379"),
31
32
  JWT_SECRET: z.string().min(32).optional(),
32
33
  JWT_EXPIRES_IN: z.string().default("7d"),
@@ -146,6 +147,7 @@ var init_express = __esm({
146
147
  cleanupInterval;
147
148
  constructor() {
148
149
  this.cleanupInterval = setInterval(() => this.cleanup(), 6e4);
150
+ this.cleanupInterval.unref();
149
151
  }
150
152
  cleanup() {
151
153
  const now = Date.now();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/index.ts","../../src/rate-limit/express.ts","../../src/rate-limit/index.ts","../../src/rate-limit/fastify.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { config } from '../config';\n\nexport interface RateLimitOptions {\n window?: string;\n limit?: number;\n keyGenerator?: (req: Request) => string;\n handler?: (req: Request, res: Response) => void;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n skip?: (req: Request) => boolean;\n}\n\ninterface RateLimitRecord {\n count: number;\n resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n private store: Map<string, RateLimitRecord> = new Map();\n private cleanupInterval: NodeJS.Timeout;\n\n constructor() {\n this.cleanupInterval = setInterval(() => this.cleanup(), 60000);\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, record] of this.store.entries()) {\n if (record.resetTime < now) {\n this.store.delete(key);\n }\n }\n }\n\n increment(key: string, windowMs: number): RateLimitRecord {\n const now = Date.now();\n const record = this.store.get(key);\n\n if (!record || record.resetTime < now) {\n const resetTime = now + windowMs;\n this.store.set(key, { count: 1, resetTime });\n return { count: 1, resetTime };\n }\n\n record.count++;\n return record;\n }\n\n get(key: string): RateLimitRecord | undefined {\n return this.store.get(key);\n }\n\n destroy(): void {\n clearInterval(this.cleanupInterval);\n }\n}\n\nclass RateLimiter {\n private options: Required<RateLimitOptions>;\n private store: InMemoryRateLimiter;\n\n constructor(options: RateLimitOptions = {}) {\n const defaultWindow = config.get('RATE_LIMIT_WINDOW') || '1m';\n const defaultLimit = parseInt(config.get('RATE_LIMIT_LIMIT') || '100', 10);\n\n this.options = {\n window: options.window || defaultWindow,\n limit: options.limit || defaultLimit,\n keyGenerator: options.keyGenerator || ((req: Request) => req.ip || 'unknown'),\n handler: options.handler || this.defaultHandler,\n skipSuccessfulRequests: options.skipSuccessfulRequests || false,\n skipFailedRequests: options.skipFailedRequests || false,\n skip: options.skip || (() => false),\n };\n\n this.store = new InMemoryRateLimiter();\n }\n\n private getWindowMs(): number {\n const window = this.options.window;\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n }\n\n private defaultHandler(req: Request, res: Response): void {\n res.status(429).json({\n error: 'Too many requests',\n message: `Rate limit exceeded. Please try again later.`,\n });\n }\n\n middleware(): RequestHandler {\n const windowMs = this.getWindowMs();\n\n return (req: Request, res: Response, next: NextFunction) => {\n if (this.options.skip(req)) {\n return next();\n }\n\n const key = this.options.keyGenerator(req);\n const record = this.store.increment(key, windowMs);\n\n const remaining = Math.max(0, this.options.limit - record.count);\n const resetTime = new Date(record.resetTime);\n\n res.setHeader('X-RateLimit-Limit', this.options.limit);\n res.setHeader('X-RateLimit-Remaining', remaining);\n res.setHeader('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > this.options.limit) {\n return this.options.handler(req, res);\n }\n\n next();\n };\n }\n\n destroy(): void {\n this.store.destroy();\n }\n}\n\nexport function rateLimit(options: RateLimitOptions = {}): RequestHandler {\n const limiter = new RateLimiter(options);\n return limiter.middleware();\n}\n\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\nexport default rateLimit;\n","export * from './express';\nexport * from './fastify';\n","import { FastifyInstance, FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';\nimport { RateLimitOptions, InMemoryRateLimiter } from './express';\n\nexport function registerRateLimitPlugin(fastify: FastifyInstance, options: RateLimitOptions = {}, done: HookHandlerDoneFunction) {\n const limiter = new (require('./express').createRateLimiter.constructor)(options);\n \n fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const key = options.keyGenerator \n ? options.keyGenerator(request.raw as any)\n : request.ip || 'unknown';\n \n const windowMs = parseWindowMs(options.window || '1m');\n const record = (limiter as any).store.increment(key, windowMs);\n const limit = options.limit || 100;\n const remaining = Math.max(0, limit - record.count);\n\n reply.header('X-RateLimit-Limit', limit);\n reply.header('X-RateLimit-Remaining', remaining);\n reply.header('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > limit) {\n reply.status(429).send({\n error: 'Too many requests',\n message: 'Rate limit exceeded. Please try again later.',\n });\n return reply;\n }\n });\n\n done();\n}\n\nfunction parseWindowMs(window: string): number {\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/config/index.ts","../../src/rate-limit/express.ts","../../src/rate-limit/index.ts","../../src/rate-limit/fastify.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,IAEa,SAAA,EAwCP,eAqEA,YAAA,EAEO,MAAA;AAjHb,IAAA,WAAA,GAAA,KAAA,CAAA;AAAA,EAAA,qBAAA,GAAA;AAEO,IAAM,SAAA,GAAY,EAAE,MAAA,CAAO;AAAA,MAChC,QAAA,EAAU,CAAA,CAAE,IAAA,CAAK,CAAC,aAAA,EAAe,cAAc,MAAM,CAAC,CAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,MAC7E,IAAA,EAAM,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,MAAM,CAAA;AAAA,MAC/B,YAAA,EAAc,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAClC,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACjC,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,wBAAwB,CAAA;AAAA,MACtD,YAAY,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,EAAE,EAAE,QAAA,EAAS;AAAA,MACxC,cAAA,EAAgB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,IAAI,CAAA;AAAA,MACvC,oBAAoB,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,EAAE,EAAE,QAAA,EAAS;AAAA,MAChD,sBAAA,EAAwB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,KAAK,CAAA;AAAA,MAChD,gBAAA,EAAkB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACtC,oBAAA,EAAsB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC1C,mBAAA,EAAqB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACzC,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC/B,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,KAAK,CAAA;AAAA,MACnC,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC/B,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC/B,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC/B,kBAAA,EAAoB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACxC,iBAAA,EAAmB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACvC,mBAAA,EAAqB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACzC,iBAAA,EAAmB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACvC,iBAAA,EAAmB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,IAAI,CAAA;AAAA,MAC1C,gBAAA,EAAkB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,KAAK,CAAA;AAAA,MAC1C,SAAA,EAAW,CAAA,CAAE,IAAA,CAAK,CAAC,OAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAC,CAAA,CAAE,QAAQ,MAAM,CAAA;AAAA,MACtF,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAQ,WAAW,CAAA;AAAA,MAC1C,iBAAA,EAAmB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACvC,qBAAA,EAAuB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MAC3C,aAAA,EAAe,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,MACnC,YAAA,EAAc,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,KACnC,CAAA;AAUD,IAAM,gBAAN,MAAoB;AAAA,MACV,MAAA,GAA2B,IAAA;AAAA,MAC3B,MAAA;AAAA,MACA,QAAA;AAAA,MAER,WAAA,CAAY,OAAA,GAAyB,EAAC,EAAG;AACvC,QAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,SAAA;AAChC,QAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AAAA,MACtC;AAAA,MAEA,IAAA,GAAkB;AAChB,QAAA,IAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA,CAAK,MAAA;AAE7B,QAAA,MAAM,MAA0C,EAAC;AAEjD,QAAA,KAAA,MAAW,OAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AAChD,UAAA,GAAA,CAAI,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAAA,QAC5B;AAEA,QAAA,IAAI,KAAK,QAAA,EAAU;AACjB,UAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,GAAG,CAAA;AACxC,UAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,YAAA,MAAM,SAAS,MAAA,CAAO,KAAA,CAAM,OAAO,GAAA,CAAI,CAAA,CAAA,KAAK,GAAG,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAC1F,YAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,MAAM,CAAA,CAAE,CAAA;AAAA,UACvD;AACA,UAAA,IAAA,CAAK,SAAS,MAAA,CAAO,IAAA;AAAA,QACvB,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,MAAA,GAAS,GAAA;AAAA,QAChB;AAEA,QAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACd;AAAA,MAEA,IAA+B,GAAA,EAAsB;AACnD,QAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAK;AAC5B,QAAA,OAAO,IAAA,CAAK,OAAQ,GAAG,CAAA;AAAA,MACzB;AAAA,MAEA,IAAI,GAAA,EAA8B;AAChC,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAC1B,QAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,QAAA,CAAS,OAAO,EAAE,CAAA;AACxD,QAAA,OAAO,OAAO,KAAK,CAAA;AAAA,MACrB;AAAA,MAEA,KAAK,GAAA,EAA+B;AAClC,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAC1B,QAAA,IAAI,OAAO,KAAA,KAAU,SAAA,EAAW,OAAO,KAAA;AACvC,QAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA,CAAM,aAAY,KAAM,MAAA;AAC9D,QAAA,OAAO,QAAQ,KAAK,CAAA;AAAA,MACtB;AAAA,MAEA,YAAA,GAAwB;AACtB,QAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,KAAM,YAAA;AAAA,MAClC;AAAA,MAEA,aAAA,GAAyB;AACvB,QAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,KAAM,aAAA;AAAA,MAClC;AAAA,MAEA,MAAA,GAAkB;AAChB,QAAA,OAAO,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA,KAAM,MAAA;AAAA,MAClC;AAAA,MAEA,MAAA,GAAoB;AAClB,QAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,IAAA,EAAK;AAC5B,QAAA,OAAO,IAAA,CAAK,MAAA;AAAA,MACd;AAAA,KACF;AAEA,IAAM,YAAA,GAAe,IAAI,aAAA,EAAc;AAEhC,IAAM,MAAA,GAAS;AAAA,MACpB,IAAA,EAAM,MAAM,YAAA,CAAa,IAAA,EAAK;AAAA,MAC9B,GAAA,EAAK,CAA4B,GAAA,KAAW,YAAA,CAAa,IAAI,GAAG,CAAA;AAAA,MAChE,GAAA,EAAK,CAAC,GAAA,KAAyB,YAAA,CAAa,IAAI,GAAG,CAAA;AAAA,MACnD,IAAA,EAAM,CAAC,GAAA,KAAyB,YAAA,CAAa,KAAK,GAAG,CAAA;AAAA,MACrD,YAAA,EAAc,MAAM,YAAA,CAAa,YAAA,EAAa;AAAA,MAC9C,aAAA,EAAe,MAAM,YAAA,CAAa,aAAA,EAAc;AAAA,MAChD,MAAA,EAAQ,MAAM,YAAA,CAAa,MAAA,EAAO;AAAA,MAClC,MAAA,EAAQ,MAAM,YAAA,CAAa,MAAA,EAAO;AAAA,MAClC,MAAA,EAAQ,CAAC,OAAA,KAA4B,IAAI,cAAc,OAAO;AAAA,KAChE;AAAA,EAAA;AAAA,CAAA,CAAA;;;AC3HA,IAAA,eAAA,GAAA,EAAA;AAAA,QAAA,CAAA,eAAA,EAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,OAAA,EAAA,MAAA,eAAA;AAAA,EAAA,SAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAuIO,SAAS,SAAA,CAAU,OAAA,GAA4B,EAAC,EAAmB;AACxE,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,CAAY,OAAO,CAAA;AACvC,EAAA,OAAO,QAAQ,UAAA,EAAW;AAC5B;AAEO,SAAS,kBAAkB,OAAA,EAAwC;AACxE,EAAA,OAAO,IAAI,YAAY,OAAO,CAAA;AAChC;AA9IA,IAkBM,qBAyCA,WAAA,EAqFC,eAAA;AAhJP,IAAA,YAAA,GAAA,KAAA,CAAA;AAAA,EAAA,2BAAA,GAAA;AACA,IAAA,WAAA,EAAA;AAiBA,IAAM,sBAAN,MAA0B;AAAA,MAChB,KAAA,uBAA0C,GAAA,EAAI;AAAA,MAC9C,eAAA;AAAA,MAER,WAAA,GAAc;AACZ,QAAA,IAAA,CAAK,kBAAkB,WAAA,CAAY,MAAM,IAAA,CAAK,OAAA,IAAW,GAAK,CAAA;AAC9D,QAAA,IAAA,CAAK,gBAAgB,KAAA,EAAM;AAAA,MAC7B;AAAA,MAEQ,OAAA,GAAgB;AACtB,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,QAAA,KAAA,MAAW,CAAC,GAAA,EAAK,MAAM,KAAK,IAAA,CAAK,KAAA,CAAM,SAAQ,EAAG;AAChD,UAAA,IAAI,MAAA,CAAO,YAAY,GAAA,EAAK;AAC1B,YAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAA,CAAU,KAAa,QAAA,EAAmC;AACxD,QAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAEjC,QAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,SAAA,GAAY,GAAA,EAAK;AACrC,UAAA,MAAM,YAAY,GAAA,GAAM,QAAA;AACxB,UAAA,IAAA,CAAK,MAAM,GAAA,CAAI,GAAA,EAAK,EAAE,KAAA,EAAO,CAAA,EAAG,WAAW,CAAA;AAC3C,UAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,SAAA,EAAU;AAAA,QAC/B;AAEA,QAAA,MAAA,CAAO,KAAA,EAAA;AACP,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,MAEA,IAAI,GAAA,EAA0C;AAC5C,QAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AAAA,MAC3B;AAAA,MAEA,OAAA,GAAgB;AACd,QAAA,aAAA,CAAc,KAAK,eAAe,CAAA;AAAA,MACpC;AAAA,KACF;AAEA,IAAM,cAAN,MAAkB;AAAA,MACR,OAAA;AAAA,MACA,KAAA;AAAA,MAER,WAAA,CAAY,OAAA,GAA4B,EAAC,EAAG;AAC1C,QAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,GAAA,CAAI,mBAAmB,CAAA,IAAK,IAAA;AACzD,QAAA,MAAM,eAAe,QAAA,CAAS,MAAA,CAAO,IAAI,kBAAkB,CAAA,IAAK,OAAO,EAAE,CAAA;AAEzE,QAAA,IAAA,CAAK,OAAA,GAAU;AAAA,UACb,MAAA,EAAQ,QAAQ,MAAA,IAAU,aAAA;AAAA,UAC1B,KAAA,EAAO,QAAQ,KAAA,IAAS,YAAA;AAAA,UACxB,cAAc,OAAA,CAAQ,YAAA,KAAiB,CAAC,GAAA,KAAiB,IAAI,EAAA,IAAM,SAAA,CAAA;AAAA,UACnE,OAAA,EAAS,OAAA,CAAQ,OAAA,IAAW,IAAA,CAAK,cAAA;AAAA,UACjC,sBAAA,EAAwB,QAAQ,sBAAA,IAA0B,KAAA;AAAA,UAC1D,kBAAA,EAAoB,QAAQ,kBAAA,IAAsB,KAAA;AAAA,UAClD,IAAA,EAAM,OAAA,CAAQ,IAAA,KAAS,MAAM,KAAA;AAAA,SAC/B;AAEA,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,mBAAA,EAAoB;AAAA,MACvC;AAAA,MAEQ,WAAA,GAAsB;AAC5B,QAAA,MAAM,MAAA,GAAS,KAAK,OAAA,CAAQ,MAAA;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,kBAAkB,CAAA;AAC7C,QAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AAEnB,QAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACnC,QAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AAEpB,QAAA,QAAQ,IAAA;AAAM,UACZ,KAAK,GAAA;AAAK,YAAA,OAAO,KAAA,GAAQ,GAAA;AAAA,UACzB,KAAK,GAAA;AAAK,YAAA,OAAO,QAAQ,EAAA,GAAK,GAAA;AAAA,UAC9B,KAAK,GAAA;AAAK,YAAA,OAAO,KAAA,GAAQ,KAAK,EAAA,GAAK,GAAA;AAAA,UACnC,KAAK,GAAA;AAAK,YAAA,OAAO,KAAA,GAAQ,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAA;AAAA,UACxC;AAAS,YAAA,OAAO,GAAA;AAAA;AAClB,MACF;AAAA,MAEQ,cAAA,CAAe,KAAc,GAAA,EAAqB;AACxD,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,UACnB,KAAA,EAAO,mBAAA;AAAA,UACP,OAAA,EAAS,CAAA,4CAAA;AAAA,SACV,CAAA;AAAA,MACH;AAAA,MAEA,UAAA,GAA6B;AAC3B,QAAA,MAAM,QAAA,GAAW,KAAK,WAAA,EAAY;AAElC,QAAA,OAAO,CAAC,GAAA,EAAc,GAAA,EAAe,IAAA,KAAuB;AAC1D,UAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,EAAG;AAC1B,YAAA,OAAO,IAAA,EAAK;AAAA,UACd;AAEA,UAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,YAAA,CAAa,GAAG,CAAA;AACzC,UAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAEjD,UAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,OAAA,CAAQ,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC/D,UAAkB,IAAI,IAAA,CAAK,MAAA,CAAO,SAAS;AAE3C,UAAA,GAAA,CAAI,SAAA,CAAU,mBAAA,EAAqB,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AACrD,UAAA,GAAA,CAAI,SAAA,CAAU,yBAAyB,SAAS,CAAA;AAChD,UAAA,GAAA,CAAI,UAAU,mBAAA,EAAqB,IAAA,CAAK,KAAK,MAAA,CAAO,SAAA,GAAY,GAAI,CAAC,CAAA;AAErE,UAAA,IAAI,MAAA,CAAO,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO;AACrC,YAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAA;AAAA,UACtC;AAEA,UAAA,IAAA,EAAK;AAAA,QACP,CAAA;AAAA,MACF;AAAA,MAEA,OAAA,GAAgB;AACd,QAAA,IAAA,CAAK,MAAM,OAAA,EAAQ;AAAA,MACrB;AAAA,KACF;AAWA,IAAO,eAAA,GAAQ,SAAA;AAAA,EAAA;AAAA,CAAA,CAAA;;;AChJf,YAAA,EAAA;;;ACGO,SAAS,uBAAA,CAAwB,OAAA,EAA0B,OAAA,GAA4B,IAAI,IAAA,EAA+B;AAC/H,EAAA,MAAM,OAAA,GAAU,IAAK,CAAA,YAAA,EAAA,EAAA,YAAA,CAAA,eAAA,CAAA,EAAqB,iBAAA,CAAkB,YAAa,OAAO,CAAA;AAEhF,EAAA,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,OAAO,OAAA,EAAyB,KAAA,KAAwB;AACnF,IAAA,MAAM,GAAA,GAAM,QAAQ,YAAA,GAChB,OAAA,CAAQ,aAAa,OAAA,CAAQ,GAAU,CAAA,GACvC,OAAA,CAAQ,EAAA,IAAM,SAAA;AAElB,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,OAAA,CAAQ,MAAA,IAAU,IAAI,CAAA;AACrD,IAAA,MAAM,MAAA,GAAU,OAAA,CAAgB,KAAA,CAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAC7D,IAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,GAAA;AAC/B,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,OAAO,KAAK,CAAA;AAElD,IAAA,KAAA,CAAM,MAAA,CAAO,qBAAqB,KAAK,CAAA;AACvC,IAAA,KAAA,CAAM,MAAA,CAAO,yBAAyB,SAAS,CAAA;AAC/C,IAAA,KAAA,CAAM,OAAO,mBAAA,EAAqB,IAAA,CAAK,KAAK,MAAA,CAAO,SAAA,GAAY,GAAI,CAAC,CAAA;AAEpE,IAAA,IAAI,MAAA,CAAO,QAAQ,KAAA,EAAO;AACxB,MAAA,KAAA,CAAM,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,QACrB,KAAA,EAAO,mBAAA;AAAA,QACP,OAAA,EAAS;AAAA,OACV,CAAA;AACD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAA,EAAK;AACP;AAEA,SAAS,cAAc,MAAA,EAAwB;AAC7C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,kBAAkB,CAAA;AAC7C,EAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AAEnB,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACnC,EAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AAEpB,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,GAAA;AAAK,MAAA,OAAO,KAAA,GAAQ,GAAA;AAAA,IACzB,KAAK,GAAA;AAAK,MAAA,OAAO,QAAQ,EAAA,GAAK,GAAA;AAAA,IAC9B,KAAK,GAAA;AAAK,MAAA,OAAO,KAAA,GAAQ,KAAK,EAAA,GAAK,GAAA;AAAA,IACnC,KAAK,GAAA;AAAK,MAAA,OAAO,KAAA,GAAQ,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAA;AAAA,IACxC;AAAS,MAAA,OAAO,GAAA;AAAA;AAEpB","file":"index.mjs","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n MONGODB_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n AWS_REGION: z.string().default('us-east-1'),\n AWS_ACCESS_KEY_ID: z.string().optional(),\n AWS_SECRET_ACCESS_KEY: z.string().optional(),\n AWS_S3_BUCKET: z.string().optional(),\n AWS_ENDPOINT: z.string().optional(),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { config } from '../config';\n\nexport interface RateLimitOptions {\n window?: string;\n limit?: number;\n keyGenerator?: (req: Request) => string;\n handler?: (req: Request, res: Response) => void;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n skip?: (req: Request) => boolean;\n}\n\ninterface RateLimitRecord {\n count: number;\n resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n private store: Map<string, RateLimitRecord> = new Map();\n private cleanupInterval: NodeJS.Timeout;\n\n constructor() {\n this.cleanupInterval = setInterval(() => this.cleanup(), 60000);\n this.cleanupInterval.unref();\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, record] of this.store.entries()) {\n if (record.resetTime < now) {\n this.store.delete(key);\n }\n }\n }\n\n increment(key: string, windowMs: number): RateLimitRecord {\n const now = Date.now();\n const record = this.store.get(key);\n\n if (!record || record.resetTime < now) {\n const resetTime = now + windowMs;\n this.store.set(key, { count: 1, resetTime });\n return { count: 1, resetTime };\n }\n\n record.count++;\n return record;\n }\n\n get(key: string): RateLimitRecord | undefined {\n return this.store.get(key);\n }\n\n destroy(): void {\n clearInterval(this.cleanupInterval);\n }\n}\n\nclass RateLimiter {\n private options: Required<RateLimitOptions>;\n private store: InMemoryRateLimiter;\n\n constructor(options: RateLimitOptions = {}) {\n const defaultWindow = config.get('RATE_LIMIT_WINDOW') || '1m';\n const defaultLimit = parseInt(config.get('RATE_LIMIT_LIMIT') || '100', 10);\n\n this.options = {\n window: options.window || defaultWindow,\n limit: options.limit || defaultLimit,\n keyGenerator: options.keyGenerator || ((req: Request) => req.ip || 'unknown'),\n handler: options.handler || this.defaultHandler,\n skipSuccessfulRequests: options.skipSuccessfulRequests || false,\n skipFailedRequests: options.skipFailedRequests || false,\n skip: options.skip || (() => false),\n };\n\n this.store = new InMemoryRateLimiter();\n }\n\n private getWindowMs(): number {\n const window = this.options.window;\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n }\n\n private defaultHandler(req: Request, res: Response): void {\n res.status(429).json({\n error: 'Too many requests',\n message: `Rate limit exceeded. Please try again later.`,\n });\n }\n\n middleware(): RequestHandler {\n const windowMs = this.getWindowMs();\n\n return (req: Request, res: Response, next: NextFunction) => {\n if (this.options.skip(req)) {\n return next();\n }\n\n const key = this.options.keyGenerator(req);\n const record = this.store.increment(key, windowMs);\n\n const remaining = Math.max(0, this.options.limit - record.count);\n const resetTime = new Date(record.resetTime);\n\n res.setHeader('X-RateLimit-Limit', this.options.limit);\n res.setHeader('X-RateLimit-Remaining', remaining);\n res.setHeader('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > this.options.limit) {\n return this.options.handler(req, res);\n }\n\n next();\n };\n }\n\n destroy(): void {\n this.store.destroy();\n }\n}\n\nexport function rateLimit(options: RateLimitOptions = {}): RequestHandler {\n const limiter = new RateLimiter(options);\n return limiter.middleware();\n}\n\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\nexport default rateLimit;\n","export * from './express';\nexport * from './fastify';\n","import { FastifyInstance, FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';\nimport { RateLimitOptions, InMemoryRateLimiter } from './express';\n\nexport function registerRateLimitPlugin(fastify: FastifyInstance, options: RateLimitOptions = {}, done: HookHandlerDoneFunction) {\n const limiter = new (require('./express').createRateLimiter.constructor)(options);\n \n fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const key = options.keyGenerator \n ? options.keyGenerator(request.raw as any)\n : request.ip || 'unknown';\n \n const windowMs = parseWindowMs(options.window || '1m');\n const record = (limiter as any).store.increment(key, windowMs);\n const limit = options.limit || 100;\n const remaining = Math.max(0, limit - record.count);\n\n reply.header('X-RateLimit-Limit', limit);\n reply.header('X-RateLimit-Remaining', remaining);\n reply.header('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > limit) {\n reply.status(429).send({\n error: 'Too many requests',\n message: 'Rate limit exceeded. Please try again later.',\n });\n return reply;\n }\n });\n\n done();\n}\n\nfunction parseWindowMs(window: string): number {\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n}\n"]}
@@ -2,7 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var express = require('express');
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
6
11
 
7
12
  // src/response/index.ts
8
13
  var ResponseHelper = class {
@@ -71,45 +76,51 @@ var ResponseHelper = class {
71
76
  return res.status(204).send();
72
77
  }
73
78
  };
74
- express.Response.prototype.success = function(data, message, statusCode = 200) {
75
- return ResponseHelper.success(this, data, message, statusCode);
76
- };
77
- express.Response.prototype.created = function(data, message) {
78
- return ResponseHelper.created(this, data, message);
79
- };
80
- express.Response.prototype.updated = function(data, message) {
81
- return ResponseHelper.updated(this, data, message);
82
- };
83
- express.Response.prototype.deleted = function(message) {
84
- return ResponseHelper.deleted(this, message);
85
- };
86
- express.Response.prototype.error = function(error, statusCode = 400, code, details) {
87
- return ResponseHelper.error(this, error, statusCode, code, details);
88
- };
89
- express.Response.prototype.badRequest = function(error, code) {
90
- return ResponseHelper.badRequest(this, error, code);
91
- };
92
- express.Response.prototype.unauthorized = function(error, code) {
93
- return ResponseHelper.unauthorized(this, error, code);
94
- };
95
- express.Response.prototype.forbidden = function(error, code) {
96
- return ResponseHelper.forbidden(this, error, code);
97
- };
98
- express.Response.prototype.notFound = function(error, code) {
99
- return ResponseHelper.notFound(this, error, code);
100
- };
101
- express.Response.prototype.conflict = function(error, code) {
102
- return ResponseHelper.conflict(this, error, code);
103
- };
104
- express.Response.prototype.validationError = function(error, details) {
105
- return ResponseHelper.validationError(this, error, details);
106
- };
107
- express.Response.prototype.internalError = function(error) {
108
- return ResponseHelper.internalError(this, error);
109
- };
110
- express.Response.prototype.paginated = function(data, page, limit, total) {
111
- return ResponseHelper.paginated(this, data, page, limit, total);
112
- };
79
+ try {
80
+ const proto = __require("express").response;
81
+ if (proto) {
82
+ proto.success = function(data, message, statusCode = 200) {
83
+ return ResponseHelper.success(this, data, message, statusCode);
84
+ };
85
+ proto.created = function(data, message) {
86
+ return ResponseHelper.created(this, data, message);
87
+ };
88
+ proto.updated = function(data, message) {
89
+ return ResponseHelper.updated(this, data, message);
90
+ };
91
+ proto.deleted = function(message) {
92
+ return ResponseHelper.deleted(this, message);
93
+ };
94
+ proto.error = function(error, statusCode = 400, code, details) {
95
+ return ResponseHelper.error(this, error, statusCode, code, details);
96
+ };
97
+ proto.badRequest = function(error, code) {
98
+ return ResponseHelper.badRequest(this, error, code);
99
+ };
100
+ proto.unauthorized = function(error, code) {
101
+ return ResponseHelper.unauthorized(this, error, code);
102
+ };
103
+ proto.forbidden = function(error, code) {
104
+ return ResponseHelper.forbidden(this, error, code);
105
+ };
106
+ proto.notFound = function(error, code) {
107
+ return ResponseHelper.notFound(this, error, code);
108
+ };
109
+ proto.conflict = function(error, code) {
110
+ return ResponseHelper.conflict(this, error, code);
111
+ };
112
+ proto.validationError = function(error, details) {
113
+ return ResponseHelper.validationError(this, error, details);
114
+ };
115
+ proto.internalError = function(error) {
116
+ return ResponseHelper.internalError(this, error);
117
+ };
118
+ proto.paginated = function(data, page, limit, total) {
119
+ return ResponseHelper.paginated(this, data, page, limit, total);
120
+ };
121
+ }
122
+ } catch {
123
+ }
113
124
  var response = ResponseHelper;
114
125
  var response_default = ResponseHelper;
115
126
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/response/index.ts"],"names":["response","Response"],"mappings":"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","file":"index.js","sourcesContent":["import { Response } from 'express';\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n totalPages?: number;\n };\n}\n\nexport interface PaginatedResponse<T> extends ApiResponse<T> {\n meta: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface ErrorResponse {\n success: false;\n error: string;\n code?: string;\n details?: Record<string, unknown>;\n}\n\nexport class ResponseHelper {\n static success<T>(res: Response, data?: T, message?: string, statusCode: number = 200): Response {\n const response: ApiResponse<T> = {\n success: true,\n data,\n message,\n };\n return res.status(statusCode).json(response);\n }\n\n static created<T>(res: Response, data?: T, message: string = 'Resource created'): Response {\n return this.success(res, data, message, 201);\n }\n\n static updated<T>(res: Response, data?: T, message: string = 'Resource updated'): Response {\n return this.success(res, data, message, 200);\n }\n\n static deleted(res: Response, message: string = 'Resource deleted'): Response {\n return this.success(res, null, message, 200);\n }\n\n static error(\n res: Response,\n error: string,\n statusCode: number = 400,\n code?: string,\n details?: Record<string, unknown>\n ): Response {\n const response: ErrorResponse = {\n success: false,\n error,\n code,\n ...(details && { details }),\n };\n return res.status(statusCode).json(response);\n }\n\n static badRequest(res: Response, error: string = 'Bad request', code?: string): Response {\n return this.error(res, error, 400, code);\n }\n\n static unauthorized(res: Response, error: string = 'Unauthorized', code?: string): Response {\n return this.error(res, error, 401, code);\n }\n\n static forbidden(res: Response, error: string = 'Forbidden', code?: string): Response {\n return this.error(res, error, 403, code);\n }\n\n static notFound(res: Response, error: string = 'Resource not found', code?: string): Response {\n return this.error(res, error, 404, code);\n }\n\n static conflict(res: Response, error: string = 'Conflict', code?: string): Response {\n return this.error(res, error, 409, code);\n }\n\n static validationError(res: Response, error: string, details?: Record<string, unknown>): Response {\n return this.error(res, error, 422, 'VALIDATION_ERROR', details);\n }\n\n static internalError(res: Response, error: string = 'Internal server error'): Response {\n return this.error(res, error, 500, 'INTERNAL_ERROR');\n }\n\n static paginated<T>(\n res: Response,\n data: T[],\n page: number,\n limit: number,\n total: number\n ): Response<PaginatedResponse<T>> {\n const totalPages = Math.ceil(total / limit);\n const response: PaginatedResponse<T> = {\n success: true,\n data,\n meta: {\n page,\n limit,\n total,\n totalPages,\n },\n };\n return res.status(200).json(response);\n }\n\n static noContent(res: Response): Response {\n return res.status(204).send();\n }\n}\n\ndeclare global {\n namespace Express {\n interface Response {\n success<T>(data?: T, message?: string, statusCode?: number): Response;\n created<T>(data?: T, message?: string): Response;\n updated<T>(data?: T, message?: string): Response;\n deleted(message?: string): Response;\n error(error: string, statusCode?: number, code?: string, details?: Record<string, unknown>): Response;\n badRequest(error?: string, code?: string): Response;\n unauthorized(error?: string, code?: string): Response;\n forbidden(error?: string, code?: string): Response;\n notFound(error?: string, code?: string): Response;\n conflict(error?: string, code?: string): Response;\n validationError(error: string, details?: Record<string, unknown>): Response;\n internalError(error?: string): Response;\n paginated<T>(data: T[], page: number, limit: number, total: number): Response;\n }\n }\n}\n\nResponse.prototype.success = function <T>(data?: T, message?: string, statusCode: number = 200) {\n return ResponseHelper.success(this, data, message, statusCode);\n};\n\nResponse.prototype.created = function <T>(data?: T, message?: string) {\n return ResponseHelper.created(this, data, message);\n};\n\nResponse.prototype.updated = function <T>(data?: T, message?: string) {\n return ResponseHelper.updated(this, data, message);\n};\n\nResponse.prototype.deleted = function (message?: string) {\n return ResponseHelper.deleted(this, message);\n};\n\nResponse.prototype.error = function (error: string, statusCode: number = 400, code?: string, details?: Record<string, unknown>) {\n return ResponseHelper.error(this, error, statusCode, code, details);\n};\n\nResponse.prototype.badRequest = function (error?: string, code?: string) {\n return ResponseHelper.badRequest(this, error, code);\n};\n\nResponse.prototype.unauthorized = function (error?: string, code?: string) {\n return ResponseHelper.unauthorized(this, error, code);\n};\n\nResponse.prototype.forbidden = function (error?: string, code?: string) {\n return ResponseHelper.forbidden(this, error, code);\n};\n\nResponse.prototype.notFound = function (error?: string, code?: string) {\n return ResponseHelper.notFound(this, error, code);\n};\n\nResponse.prototype.conflict = function (error?: string, code?: string) {\n return ResponseHelper.conflict(this, error, code);\n};\n\nResponse.prototype.validationError = function (error: string, details?: Record<string, unknown>) {\n return ResponseHelper.validationError(this, error, details);\n};\n\nResponse.prototype.internalError = function (error?: string) {\n return ResponseHelper.internalError(this, error);\n};\n\nResponse.prototype.paginated = function <T>(data: T[], page: number, limit: number, total: number) {\n return ResponseHelper.paginated(this, data, page, limit, total);\n};\n\nexport const response = ResponseHelper;\nexport default ResponseHelper;\n"]}
1
+ {"version":3,"sources":["../../src/response/index.ts"],"names":["response"],"mappings":"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","file":"index.js","sourcesContent":["import { Response } from 'express';\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n totalPages?: number;\n };\n}\n\nexport interface PaginatedResponse<T> extends Omit<ApiResponse<T[]>, 'data'> {\n data: T[];\n meta: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface ErrorResponse {\n success: false;\n error: string;\n code?: string;\n details?: Record<string, unknown>;\n}\n\nexport class ResponseHelper {\n static success<T>(res: Response, data?: T, message?: string, statusCode: number = 200): Response {\n const response: ApiResponse<T> = {\n success: true,\n data,\n message,\n };\n return res.status(statusCode).json(response);\n }\n\n static created<T>(res: Response, data?: T, message: string = 'Resource created'): Response {\n return this.success(res, data, message, 201);\n }\n\n static updated<T>(res: Response, data?: T, message: string = 'Resource updated'): Response {\n return this.success(res, data, message, 200);\n }\n\n static deleted(res: Response, message: string = 'Resource deleted'): Response {\n return this.success(res, null, message, 200);\n }\n\n static error(\n res: Response,\n error: string,\n statusCode: number = 400,\n code?: string,\n details?: Record<string, unknown>\n ): Response {\n const response: ErrorResponse = {\n success: false,\n error,\n code,\n ...(details && { details }),\n };\n return res.status(statusCode).json(response);\n }\n\n static badRequest(res: Response, error: string = 'Bad request', code?: string): Response {\n return this.error(res, error, 400, code);\n }\n\n static unauthorized(res: Response, error: string = 'Unauthorized', code?: string): Response {\n return this.error(res, error, 401, code);\n }\n\n static forbidden(res: Response, error: string = 'Forbidden', code?: string): Response {\n return this.error(res, error, 403, code);\n }\n\n static notFound(res: Response, error: string = 'Resource not found', code?: string): Response {\n return this.error(res, error, 404, code);\n }\n\n static conflict(res: Response, error: string = 'Conflict', code?: string): Response {\n return this.error(res, error, 409, code);\n }\n\n static validationError(res: Response, error: string, details?: Record<string, unknown>): Response {\n return this.error(res, error, 422, 'VALIDATION_ERROR', details);\n }\n\n static internalError(res: Response, error: string = 'Internal server error'): Response {\n return this.error(res, error, 500, 'INTERNAL_ERROR');\n }\n\n static paginated<T>(\n res: Response,\n data: T[],\n page: number,\n limit: number,\n total: number\n ): Response<PaginatedResponse<T>> {\n const totalPages = Math.ceil(total / limit);\n const response: PaginatedResponse<T> = {\n success: true,\n data,\n meta: {\n page,\n limit,\n total,\n totalPages,\n },\n };\n return res.status(200).json(response);\n }\n\n static noContent(res: Response): Response {\n return res.status(204).send();\n }\n}\n\ndeclare global {\n namespace Express {\n interface Response {\n success<T>(data?: T, message?: string, statusCode?: number): Response;\n created<T>(data?: T, message?: string): Response;\n updated<T>(data?: T, message?: string): Response;\n deleted(message?: string): Response;\n error(error: string, statusCode?: number, code?: string, details?: Record<string, unknown>): Response;\n badRequest(error?: string, code?: string): Response;\n unauthorized(error?: string, code?: string): Response;\n forbidden(error?: string, code?: string): Response;\n notFound(error?: string, code?: string): Response;\n conflict(error?: string, code?: string): Response;\n validationError(error: string, details?: Record<string, unknown>): Response;\n internalError(error?: string): Response;\n paginated<T>(data: T[], page: number, limit: number, total: number): Response;\n }\n }\n}\n\ntry {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const proto = require('express').response;\n if (proto) {\n proto.success = function <T>(this: Response, data?: T, message?: string, statusCode: number = 200) {\n return ResponseHelper.success(this, data, message, statusCode);\n };\n\n proto.created = function <T>(this: Response, data?: T, message?: string) {\n return ResponseHelper.created(this, data, message);\n };\n\n proto.updated = function <T>(this: Response, data?: T, message?: string) {\n return ResponseHelper.updated(this, data, message);\n };\n\n proto.deleted = function (this: Response, message?: string) {\n return ResponseHelper.deleted(this, message);\n };\n\n proto.error = function (this: Response, error: string, statusCode: number = 400, code?: string, details?: Record<string, unknown>) {\n return ResponseHelper.error(this, error, statusCode, code, details);\n };\n\n proto.badRequest = function (this: Response, error?: string, code?: string) {\n return ResponseHelper.badRequest(this, error, code);\n };\n\n proto.unauthorized = function (this: Response, error?: string, code?: string) {\n return ResponseHelper.unauthorized(this, error, code);\n };\n\n proto.forbidden = function (this: Response, error?: string, code?: string) {\n return ResponseHelper.forbidden(this, error, code);\n };\n\n proto.notFound = function (this: Response, error?: string, code?: string) {\n return ResponseHelper.notFound(this, error, code);\n };\n\n proto.conflict = function (this: Response, error?: string, code?: string) {\n return ResponseHelper.conflict(this, error, code);\n };\n\n proto.validationError = function (this: Response, error: string, details?: Record<string, unknown>) {\n return ResponseHelper.validationError(this, error, details);\n };\n\n proto.internalError = function (this: Response, error?: string) {\n return ResponseHelper.internalError(this, error);\n };\n\n proto.paginated = function <T>(this: Response, data: T[], page: number, limit: number, total: number) {\n return ResponseHelper.paginated(this, data, page, limit, total);\n };\n }\n} catch {\n // express not available at runtime\n}\n\nexport const response = ResponseHelper;\nexport default ResponseHelper;\n"]}