@exyconn/common 2.3.4 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/http/index.js +1 -3
- package/dist/client/http/index.js.map +1 -1
- package/dist/client/http/index.mjs +1 -3
- package/dist/client/http/index.mjs.map +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/logger/index.js +3 -1
- package/dist/client/logger/index.js.map +1 -1
- package/dist/client/logger/index.mjs +3 -1
- package/dist/client/logger/index.mjs.map +1 -1
- package/dist/client/utils/index.js +3 -3
- package/dist/client/utils/index.js.map +1 -1
- package/dist/client/utils/index.mjs +3 -3
- package/dist/client/utils/index.mjs.map +1 -1
- package/dist/{index-Ckhm_HaX.d.mts → index-B8O4iu6q.d.mts} +7 -2
- package/dist/{index-br6POSyA.d.ts → index-MpV0UNTq.d.ts} +7 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +171 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +168 -17
- package/dist/index.mjs.map +1 -1
- package/dist/server/configs/index.js +3 -0
- package/dist/server/configs/index.js.map +1 -1
- package/dist/server/configs/index.mjs +3 -0
- package/dist/server/configs/index.mjs.map +1 -1
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +161 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +156 -8
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/middleware/index.js +3 -3
- package/dist/server/middleware/index.js.map +1 -1
- package/dist/server/middleware/index.mjs +3 -3
- package/dist/server/middleware/index.mjs.map +1 -1
- package/dist/server/utils/index.d.mts +99 -1
- package/dist/server/utils/index.d.ts +99 -1
- package/dist/server/utils/index.js +154 -0
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs +148 -3
- package/dist/server/utils/index.mjs.map +1 -1
- package/package.json +25 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/configs/cors.config.ts","../../../src/server/configs/rate-limiter.config.ts","../../../src/server/configs/server.config.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// =============================================================================\r\n// Dynamic CORS Configuration\r\n// Configurable for multiple projects\r\n// =============================================================================\r\n\r\nimport type { CorsOptions } from 'cors';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * CORS configuration options\r\n */\r\nexport interface CorsConfig {\r\n /** Allowed production origins */\r\n productionOrigins?: string[];\r\n /** Allowed development origins */\r\n developmentOrigins?: string[];\r\n /** Subdomain patterns to allow (e.g., '.exyconn.com') */\r\n allowedSubdomains?: string[];\r\n /** Regex patterns for origin matching */\r\n originPatterns?: RegExp[];\r\n /** Allow requests with no origin (mobile apps, curl) */\r\n allowNoOrigin?: boolean;\r\n /** Allow all origins in development */\r\n allowAllInDev?: boolean;\r\n /** Custom origin validator */\r\n customValidator?: (origin: string) => boolean;\r\n /** Enable credentials */\r\n credentials?: boolean;\r\n /** Allowed HTTP methods */\r\n methods?: string[];\r\n /** Allowed headers */\r\n allowedHeaders?: string[];\r\n /** Exposed headers */\r\n exposedHeaders?: string[];\r\n /** Preflight cache duration in seconds */\r\n maxAge?: number;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIG\r\n// =============================================================================\r\n\r\n/**\r\n * Default CORS configuration\r\n */\r\nexport const DEFAULT_CORS_CONFIG: Required<Omit<CorsConfig, 'customValidator'>> & { customValidator?: (origin: string) => boolean } = {\r\n productionOrigins: [],\r\n developmentOrigins: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:5000',\r\n 'http://localhost:5173',\r\n 'http://localhost:8080',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5000',\r\n 'http://127.0.0.1:5173',\r\n 'http://127.0.0.1:8080',\r\n ],\r\n allowedSubdomains: [],\r\n originPatterns: [],\r\n allowNoOrigin: true,\r\n allowAllInDev: true,\r\n credentials: true,\r\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'],\r\n allowedHeaders: [\r\n 'Content-Type',\r\n 'Authorization',\r\n 'X-Requested-With',\r\n 'Accept',\r\n 'Origin',\r\n 'X-API-Key',\r\n 'X-Organization-Id',\r\n 'X-Request-Id',\r\n ],\r\n exposedHeaders: [\r\n 'Content-Range',\r\n 'X-Content-Range',\r\n 'X-Total-Count',\r\n 'X-Request-Id',\r\n ],\r\n maxAge: 86400, // 24 hours\r\n};\r\n\r\n// =============================================================================\r\n// CORS BUILDER\r\n// =============================================================================\r\n\r\n/**\r\n * Create CORS options with custom configuration\r\n * @param config - CORS configuration options\r\n * @returns Express CORS options object\r\n * \r\n * @example\r\n * ```typescript\r\n * // Basic usage with production origins\r\n * const cors = createCorsOptions({\r\n * productionOrigins: ['https://example.com'],\r\n * allowedSubdomains: ['.example.com'],\r\n * });\r\n * \r\n * // With custom validator\r\n * const cors = createCorsOptions({\r\n * customValidator: (origin) => origin.includes('trusted'),\r\n * });\r\n * ```\r\n */\r\nexport const createCorsOptions = (config: CorsConfig = {}): CorsOptions => {\r\n const finalConfig = { ...DEFAULT_CORS_CONFIG, ...config };\r\n \r\n const {\r\n productionOrigins,\r\n developmentOrigins,\r\n allowedSubdomains,\r\n originPatterns,\r\n allowNoOrigin,\r\n allowAllInDev,\r\n customValidator,\r\n credentials,\r\n methods,\r\n allowedHeaders,\r\n exposedHeaders,\r\n maxAge,\r\n } = finalConfig;\r\n\r\n // Combine all static origins\r\n const allOrigins = new Set([...productionOrigins, ...developmentOrigins]);\r\n\r\n const originHandler = (\r\n origin: string | undefined,\r\n callback: (err: Error | null, allow?: boolean) => void\r\n ): void => {\r\n // Allow requests with no origin (mobile apps, curl, server-to-server)\r\n if (!origin) {\r\n callback(null, allowNoOrigin);\r\n return;\r\n }\r\n\r\n // Check static allowed origins\r\n if (allOrigins.has(origin)) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check subdomain patterns\r\n if (allowedSubdomains.some((subdomain) => origin.endsWith(subdomain))) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check regex patterns\r\n if (originPatterns.some((pattern) => pattern.test(origin))) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check custom validator\r\n if (customValidator && customValidator(origin)) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // In development, allow all if configured\r\n if (process.env.NODE_ENV !== 'production' && allowAllInDev) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Reject in production\r\n if (process.env.NODE_ENV === 'production') {\r\n callback(new Error(`Origin ${origin} not allowed by CORS`));\r\n return;\r\n }\r\n\r\n // Default allow in non-production\r\n callback(null, true);\r\n };\r\n\r\n return {\r\n origin: originHandler,\r\n credentials,\r\n methods,\r\n allowedHeaders,\r\n exposedHeaders,\r\n maxAge,\r\n };\r\n};\r\n\r\n/**\r\n * Create CORS options for a specific project/brand\r\n * @param brandDomain - Primary domain (e.g., 'exyconn.com')\r\n * @param additionalConfig - Additional configuration\r\n */\r\nexport const createBrandCorsOptions = (\r\n brandDomain: string,\r\n additionalConfig: Partial<CorsConfig> = {}\r\n): CorsOptions => {\r\n const productionOrigins = [\r\n `https://${brandDomain}`,\r\n `https://www.${brandDomain}`,\r\n ];\r\n\r\n const allowedSubdomains = [`.${brandDomain}`];\r\n\r\n return createCorsOptions({\r\n productionOrigins,\r\n allowedSubdomains,\r\n ...additionalConfig,\r\n });\r\n};\r\n\r\n/**\r\n * Create CORS options for multiple projects\r\n * @param domains - Array of primary domains\r\n * @param additionalConfig - Additional configuration\r\n */\r\nexport const createMultiBrandCorsOptions = (\r\n domains: string[],\r\n additionalConfig: Partial<CorsConfig> = {}\r\n): CorsOptions => {\r\n const productionOrigins = domains.flatMap((domain) => [\r\n `https://${domain}`,\r\n `https://www.${domain}`,\r\n ]);\r\n\r\n const allowedSubdomains = domains.map((domain) => `.${domain}`);\r\n\r\n return createCorsOptions({\r\n productionOrigins,\r\n allowedSubdomains,\r\n ...additionalConfig,\r\n });\r\n};\r\n\r\n// =============================================================================\r\n// PRESET CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Exyconn preset CORS configuration\r\n */\r\nexport const EXYCONN_CORS_CONFIG: CorsConfig = {\r\n productionOrigins: [\r\n 'https://exyconn.com',\r\n 'https://www.exyconn.com',\r\n 'https://botify.life',\r\n 'https://www.botify.life',\r\n 'https://partywings.fun',\r\n 'https://www.partywings.fun',\r\n 'https://sibera.work',\r\n 'https://www.sibera.work',\r\n 'https://spentiva.com',\r\n 'https://www.spentiva.com',\r\n ],\r\n allowedSubdomains: [\r\n '.exyconn.com',\r\n '.botify.life',\r\n '.partywings.fun',\r\n '.sibera.work',\r\n '.spentiva.com',\r\n ],\r\n developmentOrigins: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:4001',\r\n 'http://localhost:4002',\r\n 'http://localhost:4003',\r\n 'http://localhost:4004',\r\n 'http://localhost:4005',\r\n 'http://localhost:5173',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5173',\r\n ],\r\n};\r\n\r\n/**\r\n * Strict CORS configuration (production only)\r\n */\r\nexport const STRICT_CORS_CONFIG: CorsConfig = {\r\n allowNoOrigin: false,\r\n allowAllInDev: false,\r\n methods: ['GET', 'POST', 'PUT', 'DELETE'],\r\n};\r\n\r\n/**\r\n * Permissive CORS configuration (development/testing)\r\n */\r\nexport const PERMISSIVE_CORS_CONFIG: CorsConfig = {\r\n allowNoOrigin: true,\r\n allowAllInDev: true,\r\n originPatterns: [/localhost/, /127\\.0\\.0\\.1/],\r\n};\r\n\r\n// =============================================================================\r\n// LEGACY EXPORTS (backward compatibility)\r\n// =============================================================================\r\n\r\n/**\r\n * @deprecated Use createCorsOptions() instead\r\n */\r\nexport const corsOptions: CorsOptions = createCorsOptions(EXYCONN_CORS_CONFIG);\r\n\r\nexport default {\r\n createCorsOptions,\r\n createBrandCorsOptions,\r\n createMultiBrandCorsOptions,\r\n DEFAULT_CORS_CONFIG,\r\n EXYCONN_CORS_CONFIG,\r\n STRICT_CORS_CONFIG,\r\n PERMISSIVE_CORS_CONFIG,\r\n corsOptions,\r\n};\r\n","// =============================================================================\r\n// Dynamic Rate Limiter Configuration\r\n// Configurable for multiple projects\r\n// =============================================================================\r\n\r\nimport rateLimit from 'express-rate-limit';\r\nimport type { Options, RateLimitRequestHandler } from 'express-rate-limit';\r\nimport type { Request } from 'express';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Rate limit tier configuration\r\n */\r\nexport interface RateLimitTierConfig {\r\n /** Window duration in milliseconds */\r\n windowMs: number;\r\n /** Maximum requests allowed in window */\r\n maxRequests: number;\r\n /** Error message to return */\r\n message: string;\r\n /** Skip successful requests */\r\n skipSuccessfulRequests?: boolean;\r\n /** Skip failed requests */\r\n skipFailedRequests?: boolean;\r\n}\r\n\r\n/**\r\n * Rate limiter configuration options\r\n */\r\nexport interface RateLimiterConfig {\r\n /** Standard tier - general API endpoints */\r\n standard?: Partial<RateLimitTierConfig>;\r\n /** Strict tier - sensitive endpoints (login, signup) */\r\n strict?: Partial<RateLimitTierConfig>;\r\n /** DDoS tier - global protection */\r\n ddos?: Partial<RateLimitTierConfig>;\r\n /** Custom tiers */\r\n custom?: Record<string, RateLimitTierConfig>;\r\n /** Use standard headers */\r\n standardHeaders?: boolean;\r\n /** Use legacy headers */\r\n legacyHeaders?: boolean;\r\n /** Custom key generator */\r\n keyGenerator?: (req: Request) => string;\r\n /** Skip certain requests */\r\n skip?: (req: Request) => boolean;\r\n /** Handler for when rate limit is exceeded */\r\n handler?: Options['handler'];\r\n}\r\n\r\n/**\r\n * Rate limit response format\r\n */\r\nexport interface RateLimitResponse {\r\n status: string;\r\n statusCode: number;\r\n message: string;\r\n retryAfter?: number;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Default rate limit tier configurations\r\n */\r\nexport const DEFAULT_RATE_LIMIT_TIERS = {\r\n STANDARD: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 100,\r\n message: 'Too many requests, please try again later.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n STRICT: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 20,\r\n message: 'Too many requests, please try again later.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n DDOS: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 60,\r\n message: 'Rate limit exceeded. Please slow down.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n // Additional presets\r\n VERY_STRICT: {\r\n windowMs: 60 * 60 * 1000, // 1 hour\r\n maxRequests: 5,\r\n message: 'Too many attempts. Please try again in an hour.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n RELAXED: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 500,\r\n message: 'Rate limit exceeded.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n API: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 30,\r\n message: 'API rate limit exceeded.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n} as const;\r\n\r\n// =============================================================================\r\n// KEY GENERATORS\r\n// =============================================================================\r\n\r\n/**\r\n * Default IP-based key generator\r\n */\r\nexport const defaultKeyGenerator = (req: Request): string => {\r\n const forwarded = req.headers['x-forwarded-for'];\r\n const ip = forwarded \r\n ? (Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0].trim())\r\n : req.ip || req.socket.remoteAddress || 'unknown';\r\n return ip;\r\n};\r\n\r\n/**\r\n * Create key generator with custom prefix\r\n */\r\nexport const createPrefixedKeyGenerator = (prefix: string) => (req: Request): string => {\r\n return `${prefix}:${defaultKeyGenerator(req)}`;\r\n};\r\n\r\n/**\r\n * Create key generator based on user ID (for authenticated routes)\r\n */\r\nexport const createUserKeyGenerator = (getUserId: (req: Request) => string | undefined) => (req: Request): string => {\r\n const userId = getUserId(req);\r\n return userId || defaultKeyGenerator(req);\r\n};\r\n\r\n/**\r\n * Create key generator based on API key\r\n */\r\nexport const createApiKeyGenerator = (headerName: string = 'x-api-key') => (req: Request): string => {\r\n const apiKey = req.headers[headerName.toLowerCase()] as string | undefined;\r\n return apiKey || defaultKeyGenerator(req);\r\n};\r\n\r\n// =============================================================================\r\n// RATE LIMITER FACTORY\r\n// =============================================================================\r\n\r\n/**\r\n * Create rate limiter response object\r\n */\r\nconst createRateLimitResponse = (message: string, retryAfter?: number): RateLimitResponse => ({\r\n status: 'error',\r\n statusCode: 429,\r\n message,\r\n ...(retryAfter && { retryAfter }),\r\n});\r\n\r\n/**\r\n * Create a rate limiter with custom configuration\r\n * @param tierConfig - Tier configuration\r\n * @param options - Additional options\r\n * @returns Express rate limit middleware\r\n * \r\n * @example\r\n * ```typescript\r\n * // Create custom rate limiter\r\n * const apiLimiter = createRateLimiter({\r\n * windowMs: 60 * 1000, // 1 minute\r\n * maxRequests: 30,\r\n * message: 'API rate limit exceeded',\r\n * });\r\n * \r\n * // Use with user-based limiting\r\n * const userLimiter = createRateLimiter(\r\n * { windowMs: 60000, maxRequests: 10, message: 'Slow down!' },\r\n * { keyGenerator: createUserKeyGenerator((req) => req.userId) }\r\n * );\r\n * ```\r\n */\r\nexport const createRateLimiter = (\r\n tierConfig: RateLimitTierConfig,\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const {\r\n standardHeaders = true,\r\n legacyHeaders = false,\r\n keyGenerator = defaultKeyGenerator,\r\n skip,\r\n handler,\r\n } = options;\r\n\r\n return rateLimit({\r\n windowMs: tierConfig.windowMs,\r\n max: tierConfig.maxRequests,\r\n message: createRateLimitResponse(tierConfig.message),\r\n standardHeaders,\r\n legacyHeaders,\r\n keyGenerator,\r\n skip,\r\n handler,\r\n skipSuccessfulRequests: tierConfig.skipSuccessfulRequests,\r\n skipFailedRequests: tierConfig.skipFailedRequests,\r\n });\r\n};\r\n\r\n/**\r\n * Create standard rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createStandardRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STANDARD, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create strict rate limiter (for sensitive endpoints)\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createStrictRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STRICT, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create DDoS protection rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createDdosRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.DDOS, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create API rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createApiRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.API, ...config };\r\n return createRateLimiter(tierConfig, {\r\n keyGenerator: createApiKeyGenerator(),\r\n ...options,\r\n });\r\n};\r\n\r\n// =============================================================================\r\n// RATE LIMITER BUILDER CLASS\r\n// =============================================================================\r\n\r\n/**\r\n * Rate limiter builder for complex configurations\r\n */\r\nexport class RateLimiterBuilder {\r\n private config: RateLimitTierConfig;\r\n private options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>>;\r\n\r\n constructor(preset: keyof typeof DEFAULT_RATE_LIMIT_TIERS = 'STANDARD') {\r\n const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];\r\n this.config = {\r\n windowMs: presetConfig.windowMs,\r\n maxRequests: presetConfig.maxRequests,\r\n message: presetConfig.message,\r\n skipSuccessfulRequests: presetConfig.skipSuccessfulRequests ?? false,\r\n skipFailedRequests: presetConfig.skipFailedRequests ?? false,\r\n };\r\n this.options = {};\r\n }\r\n\r\n /**\r\n * Set window duration\r\n */\r\n windowMs(ms: number): this {\r\n this.config.windowMs = ms;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set window duration in minutes\r\n */\r\n windowMinutes(minutes: number): this {\r\n this.config.windowMs = minutes * 60 * 1000;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set window duration in hours\r\n */\r\n windowHours(hours: number): this {\r\n this.config.windowMs = hours * 60 * 60 * 1000;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set maximum requests\r\n */\r\n max(requests: number): this {\r\n this.config.maxRequests = requests;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set error message\r\n */\r\n message(msg: string): this {\r\n this.config.message = msg;\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip successful requests\r\n */\r\n skipSuccessful(skip: boolean = true): this {\r\n this.config.skipSuccessfulRequests = skip;\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip failed requests\r\n */\r\n skipFailed(skip: boolean = true): this {\r\n this.config.skipFailedRequests = skip;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set key generator\r\n */\r\n keyBy(generator: (req: Request) => string): this {\r\n this.options.keyGenerator = generator;\r\n return this;\r\n }\r\n\r\n /**\r\n * Key by IP (default)\r\n */\r\n keyByIp(): this {\r\n this.options.keyGenerator = defaultKeyGenerator;\r\n return this;\r\n }\r\n\r\n /**\r\n * Key by API key\r\n */\r\n keyByApiKey(headerName?: string): this {\r\n this.options.keyGenerator = createApiKeyGenerator(headerName);\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip certain requests\r\n */\r\n skipWhen(predicate: (req: Request) => boolean): this {\r\n this.options.skip = predicate;\r\n return this;\r\n }\r\n\r\n /**\r\n * Build the rate limiter\r\n */\r\n build(): RateLimitRequestHandler {\r\n return createRateLimiter(this.config, this.options);\r\n }\r\n}\r\n\r\n/**\r\n * Create a new rate limiter builder\r\n */\r\nexport const rateLimiter = (preset?: keyof typeof DEFAULT_RATE_LIMIT_TIERS): RateLimiterBuilder => {\r\n return new RateLimiterBuilder(preset);\r\n};\r\n\r\n// =============================================================================\r\n// LEGACY EXPORTS (backward compatibility)\r\n// =============================================================================\r\n\r\n/**\r\n * @deprecated Use DEFAULT_RATE_LIMIT_TIERS instead\r\n */\r\nexport const RATE_LIMIT_CONFIG = {\r\n STANDARD: DEFAULT_RATE_LIMIT_TIERS.STANDARD,\r\n STRICT: DEFAULT_RATE_LIMIT_TIERS.STRICT,\r\n DDOS: DEFAULT_RATE_LIMIT_TIERS.DDOS,\r\n} as const;\r\n\r\n/**\r\n * @deprecated Use createStandardRateLimiter() instead\r\n */\r\nexport const standardRateLimiter = createStandardRateLimiter();\r\n\r\n/**\r\n * @deprecated Use createStrictRateLimiter() instead\r\n */\r\nexport const strictRateLimiter = createStrictRateLimiter();\r\n\r\n/**\r\n * @deprecated Use createDdosRateLimiter() instead\r\n */\r\nexport const ddosProtectionLimiter = createDdosRateLimiter();\r\n\r\nexport default {\r\n // Factory functions\r\n createRateLimiter,\r\n createStandardRateLimiter,\r\n createStrictRateLimiter,\r\n createDdosRateLimiter,\r\n createApiRateLimiter,\r\n // Builder\r\n rateLimiter,\r\n RateLimiterBuilder,\r\n // Key generators\r\n defaultKeyGenerator,\r\n createPrefixedKeyGenerator,\r\n createUserKeyGenerator,\r\n createApiKeyGenerator,\r\n // Constants\r\n DEFAULT_RATE_LIMIT_TIERS,\r\n RATE_LIMIT_CONFIG,\r\n // Legacy\r\n standardRateLimiter,\r\n strictRateLimiter,\r\n ddosProtectionLimiter,\r\n};\r\n","// =============================================================================\r\n// Dynamic Server Configuration\r\n// Use this to create project-specific server configs\r\n// =============================================================================\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Environment type\r\n */\r\nexport type Environment = 'development' | 'production' | 'test' | 'staging';\r\n\r\n/**\r\n * Log level type\r\n */\r\nexport type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'debug';\r\n\r\n/**\r\n * Server configuration interface\r\n */\r\nexport interface ServerConfig {\r\n /** Server name/identifier */\r\n name: string;\r\n /** Server version */\r\n version: string;\r\n /** Current environment */\r\n environment: Environment;\r\n /** Server port */\r\n port: number;\r\n /** Host binding */\r\n host: string;\r\n /** Base API path */\r\n basePath: string;\r\n /** Enable debug mode */\r\n debug: boolean;\r\n /** Trusted proxy settings */\r\n trustProxy: boolean | string | number;\r\n}\r\n\r\n/**\r\n * Database configuration interface\r\n */\r\nexport interface DatabaseConfig {\r\n /** MongoDB connection URI */\r\n uri: string;\r\n /** Database name */\r\n name: string;\r\n /** Max connection pool size */\r\n maxPoolSize: number;\r\n /** Min connection pool size */\r\n minPoolSize: number;\r\n /** Socket timeout in ms */\r\n socketTimeoutMS: number;\r\n /** Server selection timeout in ms */\r\n serverSelectionTimeoutMS: number;\r\n /** Max idle time in ms */\r\n maxIdleTimeMS: number;\r\n /** Enable retry writes */\r\n retryWrites: boolean;\r\n /** Enable retry reads */\r\n retryReads: boolean;\r\n /** Write concern */\r\n writeConcern: 'majority' | number;\r\n}\r\n\r\n/**\r\n * JWT/Auth configuration interface\r\n */\r\nexport interface AuthConfig {\r\n /** JWT secret key */\r\n jwtSecret: string;\r\n /** JWT expiration (e.g., '7d', '24h', '30m') */\r\n jwtExpiresIn: string;\r\n /** Refresh token expiration */\r\n refreshTokenExpiresIn: string;\r\n /** Enable refresh tokens */\r\n enableRefreshTokens: boolean;\r\n /** API key header name */\r\n apiKeyHeader: string;\r\n /** Organization header name */\r\n orgHeader: string;\r\n}\r\n\r\n/**\r\n * Logging configuration interface\r\n */\r\nexport interface LoggingConfig {\r\n /** Log level */\r\n level: LogLevel;\r\n /** Logs directory */\r\n logsDir: string;\r\n /** Max log file size */\r\n maxSize: string;\r\n /** Max days to keep logs */\r\n maxFiles: string;\r\n /** Max days to keep error logs */\r\n errorMaxFiles: string;\r\n /** Enable console logging */\r\n console: boolean;\r\n /** Enable file logging */\r\n file: boolean;\r\n /** Enable JSON format */\r\n json: boolean;\r\n}\r\n\r\n/**\r\n * CORS origins configuration\r\n */\r\nexport interface CorsOriginsConfig {\r\n /** Production domains */\r\n production: string[];\r\n /** Development domains */\r\n development: string[];\r\n /** Custom domain patterns (regex strings) */\r\n patterns: string[];\r\n}\r\n\r\n/**\r\n * Rate limit tier configuration\r\n */\r\nexport interface RateLimitTier {\r\n /** Window duration in ms */\r\n windowMs: number;\r\n /** Max requests in window */\r\n maxRequests: number;\r\n /** Error message */\r\n message: string;\r\n /** Skip successful requests */\r\n skipSuccessfulRequests?: boolean;\r\n /** Skip failed requests */\r\n skipFailedRequests?: boolean;\r\n}\r\n\r\n/**\r\n * Rate limiting configuration\r\n */\r\nexport interface RateLimitConfig {\r\n /** Enable rate limiting */\r\n enabled: boolean;\r\n /** Standard tier */\r\n standard: RateLimitTier;\r\n /** Strict tier (auth endpoints) */\r\n strict: RateLimitTier;\r\n /** DDoS protection tier */\r\n ddos: RateLimitTier;\r\n /** Custom tiers */\r\n custom?: Record<string, RateLimitTier>;\r\n}\r\n\r\n/**\r\n * Complete application configuration\r\n */\r\nexport interface AppConfig {\r\n server: ServerConfig;\r\n database: DatabaseConfig;\r\n auth: AuthConfig;\r\n logging: LoggingConfig;\r\n cors: CorsOriginsConfig;\r\n rateLimit: RateLimitConfig;\r\n /** Custom configuration */\r\n custom?: Record<string, unknown>;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Default server configuration\r\n */\r\nexport const DEFAULT_SERVER_CONFIG: ServerConfig = {\r\n name: 'app-server',\r\n version: '1.0.0',\r\n environment: (process.env.NODE_ENV as Environment) || 'development',\r\n port: parseInt(process.env.PORT || '3000', 10),\r\n host: process.env.HOST || '0.0.0.0',\r\n basePath: '/api',\r\n debug: process.env.DEBUG === 'true',\r\n trustProxy: true,\r\n};\r\n\r\n/**\r\n * Default database configuration\r\n */\r\nexport const DEFAULT_DATABASE_CONFIG: DatabaseConfig = {\r\n uri: process.env.DATABASE_URL || process.env.MONGODB_URI || '',\r\n name: process.env.DATABASE_NAME || 'app_db',\r\n maxPoolSize: process.env.NODE_ENV === 'production' ? 50 : 10,\r\n minPoolSize: process.env.NODE_ENV === 'production' ? 10 : 5,\r\n socketTimeoutMS: 45000,\r\n serverSelectionTimeoutMS: 10000,\r\n maxIdleTimeMS: 10000,\r\n retryWrites: true,\r\n retryReads: true,\r\n writeConcern: 'majority',\r\n};\r\n\r\n/**\r\n * Default auth configuration\r\n */\r\nexport const DEFAULT_AUTH_CONFIG: AuthConfig = {\r\n jwtSecret: process.env.JWT_SECRET || '',\r\n jwtExpiresIn: process.env.JWT_EXPIRES_IN || '7d',\r\n refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || '30d',\r\n enableRefreshTokens: true,\r\n apiKeyHeader: 'x-api-key',\r\n orgHeader: 'x-organization-id',\r\n};\r\n\r\n/**\r\n * Default logging configuration\r\n */\r\nexport const DEFAULT_LOGGING_CONFIG: LoggingConfig = {\r\n level: (process.env.LOG_LEVEL as LogLevel) || 'info',\r\n logsDir: process.env.LOGS_DIR || 'logs',\r\n maxSize: '20m',\r\n maxFiles: '14d',\r\n errorMaxFiles: '30d',\r\n console: true,\r\n file: process.env.NODE_ENV === 'production',\r\n json: process.env.NODE_ENV === 'production',\r\n};\r\n\r\n/**\r\n * Default CORS origins configuration\r\n */\r\nexport const DEFAULT_CORS_ORIGINS: CorsOriginsConfig = {\r\n production: [],\r\n development: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:5173',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5173',\r\n ],\r\n patterns: [],\r\n};\r\n\r\n/**\r\n * Default rate limit configuration\r\n */\r\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\r\n enabled: true,\r\n standard: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 100,\r\n message: 'Too many requests, please try again later.',\r\n },\r\n strict: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 20,\r\n message: 'Too many requests, please try again later.',\r\n },\r\n ddos: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 60,\r\n message: 'Rate limit exceeded. Please slow down.',\r\n skipSuccessfulRequests: false,\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// CONFIG BUILDER\r\n// =============================================================================\r\n\r\n/**\r\n * Create a deep merge of two objects\r\n */\r\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\r\n const result = { ...target } as T;\r\n \r\n for (const key in source) {\r\n if (Object.prototype.hasOwnProperty.call(source, key)) {\r\n const sourceValue = source[key as keyof T];\r\n const targetValue = target[key as keyof T];\r\n \r\n if (\r\n sourceValue !== undefined &&\r\n typeof sourceValue === 'object' &&\r\n sourceValue !== null &&\r\n !Array.isArray(sourceValue) &&\r\n typeof targetValue === 'object' &&\r\n targetValue !== null &&\r\n !Array.isArray(targetValue)\r\n ) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (result as any)[key] = deepMerge(\r\n targetValue as object,\r\n sourceValue as object\r\n );\r\n } else if (sourceValue !== undefined) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (result as any)[key] = sourceValue;\r\n }\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Configuration builder for creating project-specific configs\r\n */\r\nexport class ConfigBuilder {\r\n private config: AppConfig;\r\n\r\n constructor() {\r\n this.config = {\r\n server: { ...DEFAULT_SERVER_CONFIG },\r\n database: { ...DEFAULT_DATABASE_CONFIG },\r\n auth: { ...DEFAULT_AUTH_CONFIG },\r\n logging: { ...DEFAULT_LOGGING_CONFIG },\r\n cors: { ...DEFAULT_CORS_ORIGINS },\r\n rateLimit: { ...DEFAULT_RATE_LIMIT_CONFIG },\r\n };\r\n }\r\n\r\n /**\r\n * Set server configuration\r\n */\r\n setServer(config: Partial<ServerConfig>): this {\r\n this.config.server = deepMerge(this.config.server, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set database configuration\r\n */\r\n setDatabase(config: Partial<DatabaseConfig>): this {\r\n this.config.database = deepMerge(this.config.database, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set auth configuration\r\n */\r\n setAuth(config: Partial<AuthConfig>): this {\r\n this.config.auth = deepMerge(this.config.auth, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set logging configuration\r\n */\r\n setLogging(config: Partial<LoggingConfig>): this {\r\n this.config.logging = deepMerge(this.config.logging, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set CORS origins\r\n */\r\n setCorsOrigins(config: Partial<CorsOriginsConfig>): this {\r\n this.config.cors = deepMerge(this.config.cors, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS production origin\r\n */\r\n addProductionOrigin(origin: string): this {\r\n if (!this.config.cors.production.includes(origin)) {\r\n this.config.cors.production.push(origin);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS development origin\r\n */\r\n addDevelopmentOrigin(origin: string): this {\r\n if (!this.config.cors.development.includes(origin)) {\r\n this.config.cors.development.push(origin);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS pattern\r\n */\r\n addCorsPattern(pattern: string): this {\r\n if (!this.config.cors.patterns.includes(pattern)) {\r\n this.config.cors.patterns.push(pattern);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Set rate limit configuration\r\n */\r\n setRateLimit(config: Partial<RateLimitConfig>): this {\r\n this.config.rateLimit = deepMerge(this.config.rateLimit, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Add custom rate limit tier\r\n */\r\n addRateLimitTier(name: string, tier: RateLimitTier): this {\r\n if (!this.config.rateLimit.custom) {\r\n this.config.rateLimit.custom = {};\r\n }\r\n this.config.rateLimit.custom[name] = tier;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set custom configuration\r\n */\r\n setCustom(key: string, value: unknown): this {\r\n if (!this.config.custom) {\r\n this.config.custom = {};\r\n }\r\n this.config.custom[key] = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * Load configuration from environment variables\r\n */\r\n loadFromEnv(): this {\r\n // Server\r\n if (process.env.SERVER_NAME) this.config.server.name = process.env.SERVER_NAME;\r\n if (process.env.SERVER_VERSION) this.config.server.version = process.env.SERVER_VERSION;\r\n if (process.env.PORT) this.config.server.port = parseInt(process.env.PORT, 10);\r\n if (process.env.HOST) this.config.server.host = process.env.HOST;\r\n if (process.env.BASE_PATH) this.config.server.basePath = process.env.BASE_PATH;\r\n \r\n // Database\r\n if (process.env.DATABASE_URL) this.config.database.uri = process.env.DATABASE_URL;\r\n if (process.env.MONGODB_URI) this.config.database.uri = process.env.MONGODB_URI;\r\n if (process.env.DATABASE_NAME) this.config.database.name = process.env.DATABASE_NAME;\r\n \r\n // Auth\r\n if (process.env.JWT_SECRET) this.config.auth.jwtSecret = process.env.JWT_SECRET;\r\n if (process.env.JWT_EXPIRES_IN) this.config.auth.jwtExpiresIn = process.env.JWT_EXPIRES_IN;\r\n \r\n // Logging\r\n if (process.env.LOG_LEVEL) this.config.logging.level = process.env.LOG_LEVEL as LogLevel;\r\n if (process.env.LOGS_DIR) this.config.logging.logsDir = process.env.LOGS_DIR;\r\n \r\n // CORS origins from env (comma-separated)\r\n if (process.env.CORS_ORIGINS) {\r\n const origins = process.env.CORS_ORIGINS.split(',').map(o => o.trim());\r\n this.config.cors.production.push(...origins);\r\n }\r\n \r\n return this;\r\n }\r\n\r\n /**\r\n * Validate configuration\r\n */\r\n validate(): { valid: boolean; errors: string[] } {\r\n const errors: string[] = [];\r\n \r\n // Validate server config\r\n if (!this.config.server.name) errors.push('Server name is required');\r\n if (this.config.server.port < 1 || this.config.server.port > 65535) {\r\n errors.push('Server port must be between 1 and 65535');\r\n }\r\n \r\n // Validate auth config in production\r\n if (this.config.server.environment === 'production') {\r\n if (!this.config.auth.jwtSecret || this.config.auth.jwtSecret.length < 32) {\r\n errors.push('JWT secret must be at least 32 characters in production');\r\n }\r\n }\r\n \r\n return { valid: errors.length === 0, errors };\r\n }\r\n\r\n /**\r\n * Build the final configuration\r\n */\r\n build(): AppConfig {\r\n return { ...this.config };\r\n }\r\n}\r\n\r\n/**\r\n * Create a new configuration builder\r\n */\r\nexport const createConfig = (): ConfigBuilder => {\r\n return new ConfigBuilder();\r\n};\r\n\r\n/**\r\n * Create config from partial object\r\n */\r\nexport const buildConfig = (partial: Partial<AppConfig> = {}): AppConfig => {\r\n const builder = createConfig().loadFromEnv();\r\n \r\n if (partial.server) builder.setServer(partial.server);\r\n if (partial.database) builder.setDatabase(partial.database);\r\n if (partial.auth) builder.setAuth(partial.auth);\r\n if (partial.logging) builder.setLogging(partial.logging);\r\n if (partial.cors) builder.setCorsOrigins(partial.cors);\r\n if (partial.rateLimit) builder.setRateLimit(partial.rateLimit);\r\n \r\n return builder.build();\r\n};\r\n\r\n// =============================================================================\r\n// HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Check if current environment is production\r\n */\r\nexport const isProduction = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'production';\r\n};\r\n\r\n/**\r\n * Check if current environment is development\r\n */\r\nexport const isDevelopment = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'development';\r\n};\r\n\r\n/**\r\n * Check if current environment is test\r\n */\r\nexport const isTest = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'test';\r\n};\r\n\r\n/**\r\n * Get database options for mongoose connect\r\n */\r\nexport const getDatabaseOptions = (config: DatabaseConfig): Record<string, unknown> => {\r\n return {\r\n maxPoolSize: config.maxPoolSize,\r\n minPoolSize: config.minPoolSize,\r\n socketTimeoutMS: config.socketTimeoutMS,\r\n serverSelectionTimeoutMS: config.serverSelectionTimeoutMS,\r\n maxIdleTimeMS: config.maxIdleTimeMS,\r\n retryWrites: config.retryWrites,\r\n retryReads: config.retryReads,\r\n w: config.writeConcern,\r\n };\r\n};\r\n\r\nexport default {\r\n ConfigBuilder,\r\n createConfig,\r\n buildConfig,\r\n isProduction,\r\n isDevelopment,\r\n isTest,\r\n getDatabaseOptions,\r\n DEFAULT_SERVER_CONFIG,\r\n DEFAULT_DATABASE_CONFIG,\r\n DEFAULT_AUTH_CONFIG,\r\n DEFAULT_LOGGING_CONFIG,\r\n DEFAULT_CORS_ORIGINS,\r\n DEFAULT_RATE_LIMIT_CONFIG,\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/configs/cors.config.ts","../../../src/server/configs/rate-limiter.config.ts","../../../src/server/configs/server.config.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// =============================================================================\r\n// Dynamic CORS Configuration\r\n// Configurable for multiple projects\r\n// =============================================================================\r\n\r\nimport type { CorsOptions } from 'cors';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * CORS configuration options\r\n */\r\nexport interface CorsConfig {\r\n /** Allowed production origins */\r\n productionOrigins?: string[];\r\n /** Allowed development origins */\r\n developmentOrigins?: string[];\r\n /** Subdomain patterns to allow (e.g., '.exyconn.com') */\r\n allowedSubdomains?: string[];\r\n /** Regex patterns for origin matching */\r\n originPatterns?: RegExp[];\r\n /** Allow requests with no origin (mobile apps, curl) */\r\n allowNoOrigin?: boolean;\r\n /** Allow all origins in development */\r\n allowAllInDev?: boolean;\r\n /** Custom origin validator */\r\n customValidator?: (origin: string) => boolean;\r\n /** Enable credentials */\r\n credentials?: boolean;\r\n /** Allowed HTTP methods */\r\n methods?: string[];\r\n /** Allowed headers */\r\n allowedHeaders?: string[];\r\n /** Exposed headers */\r\n exposedHeaders?: string[];\r\n /** Preflight cache duration in seconds */\r\n maxAge?: number;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIG\r\n// =============================================================================\r\n\r\n/**\r\n * Default CORS configuration\r\n */\r\nexport const DEFAULT_CORS_CONFIG: Required<Omit<CorsConfig, 'customValidator'>> & { customValidator?: (origin: string) => boolean } = {\r\n productionOrigins: [],\r\n developmentOrigins: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:5000',\r\n 'http://localhost:5173',\r\n 'http://localhost:8080',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5000',\r\n 'http://127.0.0.1:5173',\r\n 'http://127.0.0.1:8080',\r\n ],\r\n allowedSubdomains: [],\r\n originPatterns: [],\r\n allowNoOrigin: true,\r\n allowAllInDev: true,\r\n credentials: true,\r\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'],\r\n allowedHeaders: [\r\n 'Content-Type',\r\n 'Authorization',\r\n 'X-Requested-With',\r\n 'Accept',\r\n 'Origin',\r\n 'X-API-Key',\r\n 'X-Organization-Id',\r\n 'X-Request-Id',\r\n ],\r\n exposedHeaders: [\r\n 'Content-Range',\r\n 'X-Content-Range',\r\n 'X-Total-Count',\r\n 'X-Request-Id',\r\n ],\r\n maxAge: 86400, // 24 hours\r\n};\r\n\r\n// =============================================================================\r\n// CORS BUILDER\r\n// =============================================================================\r\n\r\n/**\r\n * Create CORS options with custom configuration\r\n * @param config - CORS configuration options\r\n * @returns Express CORS options object\r\n * \r\n * @example\r\n * ```typescript\r\n * // Basic usage with production origins\r\n * const cors = createCorsOptions({\r\n * productionOrigins: ['https://example.com'],\r\n * allowedSubdomains: ['.example.com'],\r\n * });\r\n * \r\n * // With custom validator\r\n * const cors = createCorsOptions({\r\n * customValidator: (origin) => origin.includes('trusted'),\r\n * });\r\n * ```\r\n */\r\nexport const createCorsOptions = (config: CorsConfig = {}): CorsOptions => {\r\n const finalConfig = { ...DEFAULT_CORS_CONFIG, ...config };\r\n \r\n const {\r\n productionOrigins,\r\n developmentOrigins,\r\n allowedSubdomains,\r\n originPatterns,\r\n allowNoOrigin,\r\n allowAllInDev,\r\n customValidator,\r\n credentials,\r\n methods,\r\n allowedHeaders,\r\n exposedHeaders,\r\n maxAge,\r\n } = finalConfig;\r\n\r\n // Combine all static origins\r\n const allOrigins = new Set([...productionOrigins, ...developmentOrigins]);\r\n\r\n const originHandler = (\r\n origin: string | undefined,\r\n callback: (err: Error | null, allow?: boolean) => void\r\n ): void => {\r\n // Allow requests with no origin (mobile apps, curl, server-to-server)\r\n if (!origin) {\r\n callback(null, allowNoOrigin);\r\n return;\r\n }\r\n\r\n // Check static allowed origins\r\n if (allOrigins.has(origin)) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check subdomain patterns\r\n if (allowedSubdomains.some((subdomain) => origin.endsWith(subdomain))) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check regex patterns\r\n if (originPatterns.some((pattern) => pattern.test(origin))) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Check custom validator\r\n if (customValidator && customValidator(origin)) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // In development, allow all if configured\r\n if (process.env.NODE_ENV !== 'production' && allowAllInDev) {\r\n callback(null, true);\r\n return;\r\n }\r\n\r\n // Reject in production\r\n if (process.env.NODE_ENV === 'production') {\r\n callback(new Error(`Origin ${origin} not allowed by CORS`));\r\n return;\r\n }\r\n\r\n // Default allow in non-production\r\n callback(null, true);\r\n };\r\n\r\n return {\r\n origin: originHandler,\r\n credentials,\r\n methods,\r\n allowedHeaders,\r\n exposedHeaders,\r\n maxAge,\r\n };\r\n};\r\n\r\n/**\r\n * Create CORS options for a specific project/brand\r\n * @param brandDomain - Primary domain (e.g., 'exyconn.com')\r\n * @param additionalConfig - Additional configuration\r\n */\r\nexport const createBrandCorsOptions = (\r\n brandDomain: string,\r\n additionalConfig: Partial<CorsConfig> = {}\r\n): CorsOptions => {\r\n const productionOrigins = [\r\n `https://${brandDomain}`,\r\n `https://www.${brandDomain}`,\r\n ];\r\n\r\n const allowedSubdomains = [`.${brandDomain}`];\r\n\r\n return createCorsOptions({\r\n productionOrigins,\r\n allowedSubdomains,\r\n ...additionalConfig,\r\n });\r\n};\r\n\r\n/**\r\n * Create CORS options for multiple projects\r\n * @param domains - Array of primary domains\r\n * @param additionalConfig - Additional configuration\r\n */\r\nexport const createMultiBrandCorsOptions = (\r\n domains: string[],\r\n additionalConfig: Partial<CorsConfig> = {}\r\n): CorsOptions => {\r\n const productionOrigins = domains.flatMap((domain) => [\r\n `https://${domain}`,\r\n `https://www.${domain}`,\r\n ]);\r\n\r\n const allowedSubdomains = domains.map((domain) => `.${domain}`);\r\n\r\n return createCorsOptions({\r\n productionOrigins,\r\n allowedSubdomains,\r\n ...additionalConfig,\r\n });\r\n};\r\n\r\n// =============================================================================\r\n// PRESET CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Exyconn preset CORS configuration\r\n */\r\nexport const EXYCONN_CORS_CONFIG: CorsConfig = {\r\n productionOrigins: [\r\n 'https://exyconn.com',\r\n 'https://www.exyconn.com',\r\n 'https://botify.life',\r\n 'https://www.botify.life',\r\n 'https://partywings.fun',\r\n 'https://www.partywings.fun',\r\n 'https://sibera.work',\r\n 'https://www.sibera.work',\r\n 'https://spentiva.com',\r\n 'https://www.spentiva.com',\r\n ],\r\n allowedSubdomains: [\r\n '.exyconn.com',\r\n '.botify.life',\r\n '.partywings.fun',\r\n '.sibera.work',\r\n '.spentiva.com',\r\n ],\r\n developmentOrigins: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:4001',\r\n 'http://localhost:4002',\r\n 'http://localhost:4003',\r\n 'http://localhost:4004',\r\n 'http://localhost:4005',\r\n 'http://localhost:5173',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5173',\r\n ],\r\n};\r\n\r\n/**\r\n * Strict CORS configuration (production only)\r\n */\r\nexport const STRICT_CORS_CONFIG: CorsConfig = {\r\n allowNoOrigin: false,\r\n allowAllInDev: false,\r\n methods: ['GET', 'POST', 'PUT', 'DELETE'],\r\n};\r\n\r\n/**\r\n * Permissive CORS configuration (development/testing)\r\n */\r\nexport const PERMISSIVE_CORS_CONFIG: CorsConfig = {\r\n allowNoOrigin: true,\r\n allowAllInDev: true,\r\n originPatterns: [/localhost/, /127\\.0\\.0\\.1/],\r\n};\r\n\r\n// =============================================================================\r\n// LEGACY EXPORTS (backward compatibility)\r\n// =============================================================================\r\n\r\n/**\r\n * @deprecated Use createCorsOptions() instead\r\n */\r\nexport const corsOptions: CorsOptions = createCorsOptions(EXYCONN_CORS_CONFIG);\r\n\r\nexport default {\r\n createCorsOptions,\r\n createBrandCorsOptions,\r\n createMultiBrandCorsOptions,\r\n DEFAULT_CORS_CONFIG,\r\n EXYCONN_CORS_CONFIG,\r\n STRICT_CORS_CONFIG,\r\n PERMISSIVE_CORS_CONFIG,\r\n corsOptions,\r\n};\r\n","// =============================================================================\r\n// Dynamic Rate Limiter Configuration\r\n// Configurable for multiple projects\r\n// =============================================================================\r\n\r\nimport rateLimit from 'express-rate-limit';\r\nimport type { Options, RateLimitRequestHandler } from 'express-rate-limit';\r\nimport type { Request } from 'express';\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Rate limit tier configuration\r\n */\r\nexport interface RateLimitTierConfig {\r\n /** Window duration in milliseconds */\r\n windowMs: number;\r\n /** Maximum requests allowed in window */\r\n maxRequests: number;\r\n /** Error message to return */\r\n message: string;\r\n /** Skip successful requests */\r\n skipSuccessfulRequests?: boolean;\r\n /** Skip failed requests */\r\n skipFailedRequests?: boolean;\r\n}\r\n\r\n/**\r\n * Rate limiter configuration options\r\n */\r\nexport interface RateLimiterConfig {\r\n /** Standard tier - general API endpoints */\r\n standard?: Partial<RateLimitTierConfig>;\r\n /** Strict tier - sensitive endpoints (login, signup) */\r\n strict?: Partial<RateLimitTierConfig>;\r\n /** DDoS tier - global protection */\r\n ddos?: Partial<RateLimitTierConfig>;\r\n /** Custom tiers */\r\n custom?: Record<string, RateLimitTierConfig>;\r\n /** Use standard headers */\r\n standardHeaders?: boolean;\r\n /** Use legacy headers */\r\n legacyHeaders?: boolean;\r\n /** Custom key generator */\r\n keyGenerator?: (req: Request) => string;\r\n /** Skip certain requests */\r\n skip?: (req: Request) => boolean;\r\n /** Handler for when rate limit is exceeded */\r\n handler?: Options['handler'];\r\n}\r\n\r\n/**\r\n * Rate limit response format\r\n */\r\nexport interface RateLimitResponse {\r\n status: string;\r\n statusCode: number;\r\n message: string;\r\n retryAfter?: number;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Default rate limit tier configurations\r\n */\r\nexport const DEFAULT_RATE_LIMIT_TIERS = {\r\n STANDARD: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 100,\r\n message: 'Too many requests, please try again later.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n STRICT: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 20,\r\n message: 'Too many requests, please try again later.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n DDOS: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 60,\r\n message: 'Rate limit exceeded. Please slow down.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n // Additional presets\r\n VERY_STRICT: {\r\n windowMs: 60 * 60 * 1000, // 1 hour\r\n maxRequests: 5,\r\n message: 'Too many attempts. Please try again in an hour.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n RELAXED: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 500,\r\n message: 'Rate limit exceeded.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n API: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 30,\r\n message: 'API rate limit exceeded.',\r\n skipSuccessfulRequests: false,\r\n skipFailedRequests: false,\r\n },\r\n} as const;\r\n\r\n// =============================================================================\r\n// KEY GENERATORS\r\n// =============================================================================\r\n\r\n/**\r\n * Default IP-based key generator\r\n */\r\nexport const defaultKeyGenerator = (req: Request): string => {\r\n const forwarded = req.headers['x-forwarded-for'];\r\n const ip = forwarded \r\n ? (Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0].trim())\r\n : req.ip || req.socket.remoteAddress || 'unknown';\r\n return ip;\r\n};\r\n\r\n/**\r\n * Create key generator with custom prefix\r\n */\r\nexport const createPrefixedKeyGenerator = (prefix: string) => (req: Request): string => {\r\n return `${prefix}:${defaultKeyGenerator(req)}`;\r\n};\r\n\r\n/**\r\n * Create key generator based on user ID (for authenticated routes)\r\n */\r\nexport const createUserKeyGenerator = (getUserId: (req: Request) => string | undefined) => (req: Request): string => {\r\n const userId = getUserId(req);\r\n return userId || defaultKeyGenerator(req);\r\n};\r\n\r\n/**\r\n * Create key generator based on API key\r\n */\r\nexport const createApiKeyGenerator = (headerName: string = 'x-api-key') => (req: Request): string => {\r\n const apiKey = req.headers[headerName.toLowerCase()] as string | undefined;\r\n return apiKey || defaultKeyGenerator(req);\r\n};\r\n\r\n// =============================================================================\r\n// RATE LIMITER FACTORY\r\n// =============================================================================\r\n\r\n/**\r\n * Create rate limiter response object\r\n */\r\nconst createRateLimitResponse = (message: string, retryAfter?: number): RateLimitResponse => ({\r\n status: 'error',\r\n statusCode: 429,\r\n message,\r\n ...(retryAfter && { retryAfter }),\r\n});\r\n\r\n/**\r\n * Create a rate limiter with custom configuration\r\n * @param tierConfig - Tier configuration\r\n * @param options - Additional options\r\n * @returns Express rate limit middleware\r\n * \r\n * @example\r\n * ```typescript\r\n * // Create custom rate limiter\r\n * const apiLimiter = createRateLimiter({\r\n * windowMs: 60 * 1000, // 1 minute\r\n * maxRequests: 30,\r\n * message: 'API rate limit exceeded',\r\n * });\r\n * \r\n * // Use with user-based limiting\r\n * const userLimiter = createRateLimiter(\r\n * { windowMs: 60000, maxRequests: 10, message: 'Slow down!' },\r\n * { keyGenerator: createUserKeyGenerator((req) => req.userId) }\r\n * );\r\n * ```\r\n */\r\nexport const createRateLimiter = (\r\n tierConfig: RateLimitTierConfig,\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const {\r\n standardHeaders = true,\r\n legacyHeaders = false,\r\n keyGenerator = defaultKeyGenerator,\r\n skip,\r\n handler,\r\n } = options;\r\n\r\n return rateLimit({\r\n windowMs: tierConfig.windowMs,\r\n max: tierConfig.maxRequests,\r\n message: createRateLimitResponse(tierConfig.message),\r\n standardHeaders,\r\n legacyHeaders,\r\n keyGenerator,\r\n skip,\r\n handler,\r\n skipSuccessfulRequests: tierConfig.skipSuccessfulRequests,\r\n skipFailedRequests: tierConfig.skipFailedRequests,\r\n });\r\n};\r\n\r\n/**\r\n * Create standard rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createStandardRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STANDARD, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create strict rate limiter (for sensitive endpoints)\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createStrictRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.STRICT, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create DDoS protection rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createDdosRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.DDOS, ...config };\r\n return createRateLimiter(tierConfig, options);\r\n};\r\n\r\n/**\r\n * Create API rate limiter\r\n * @param config - Optional custom configuration\r\n */\r\nexport const createApiRateLimiter = (\r\n config: Partial<RateLimitTierConfig> = {},\r\n options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>> = {}\r\n): RateLimitRequestHandler => {\r\n const tierConfig = { ...DEFAULT_RATE_LIMIT_TIERS.API, ...config };\r\n return createRateLimiter(tierConfig, {\r\n keyGenerator: createApiKeyGenerator(),\r\n ...options,\r\n });\r\n};\r\n\r\n// =============================================================================\r\n// RATE LIMITER BUILDER CLASS\r\n// =============================================================================\r\n\r\n/**\r\n * Rate limiter builder for complex configurations\r\n */\r\nexport class RateLimiterBuilder {\r\n private config: RateLimitTierConfig;\r\n private options: Partial<Omit<RateLimiterConfig, 'standard' | 'strict' | 'ddos' | 'custom'>>;\r\n\r\n constructor(preset: keyof typeof DEFAULT_RATE_LIMIT_TIERS = 'STANDARD') {\r\n const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];\r\n this.config = {\r\n windowMs: presetConfig.windowMs,\r\n maxRequests: presetConfig.maxRequests,\r\n message: presetConfig.message,\r\n skipSuccessfulRequests: presetConfig.skipSuccessfulRequests ?? false,\r\n skipFailedRequests: presetConfig.skipFailedRequests ?? false,\r\n };\r\n this.options = {};\r\n }\r\n\r\n /**\r\n * Set window duration\r\n */\r\n windowMs(ms: number): this {\r\n this.config.windowMs = ms;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set window duration in minutes\r\n */\r\n windowMinutes(minutes: number): this {\r\n this.config.windowMs = minutes * 60 * 1000;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set window duration in hours\r\n */\r\n windowHours(hours: number): this {\r\n this.config.windowMs = hours * 60 * 60 * 1000;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set maximum requests\r\n */\r\n max(requests: number): this {\r\n this.config.maxRequests = requests;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set error message\r\n */\r\n message(msg: string): this {\r\n this.config.message = msg;\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip successful requests\r\n */\r\n skipSuccessful(skip: boolean = true): this {\r\n this.config.skipSuccessfulRequests = skip;\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip failed requests\r\n */\r\n skipFailed(skip: boolean = true): this {\r\n this.config.skipFailedRequests = skip;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set key generator\r\n */\r\n keyBy(generator: (req: Request) => string): this {\r\n this.options.keyGenerator = generator;\r\n return this;\r\n }\r\n\r\n /**\r\n * Key by IP (default)\r\n */\r\n keyByIp(): this {\r\n this.options.keyGenerator = defaultKeyGenerator;\r\n return this;\r\n }\r\n\r\n /**\r\n * Key by API key\r\n */\r\n keyByApiKey(headerName?: string): this {\r\n this.options.keyGenerator = createApiKeyGenerator(headerName);\r\n return this;\r\n }\r\n\r\n /**\r\n * Skip certain requests\r\n */\r\n skipWhen(predicate: (req: Request) => boolean): this {\r\n this.options.skip = predicate;\r\n return this;\r\n }\r\n\r\n /**\r\n * Build the rate limiter\r\n */\r\n build(): RateLimitRequestHandler {\r\n return createRateLimiter(this.config, this.options);\r\n }\r\n}\r\n\r\n/**\r\n * Create a new rate limiter builder\r\n */\r\nexport const rateLimiter = (preset?: keyof typeof DEFAULT_RATE_LIMIT_TIERS): RateLimiterBuilder => {\r\n return new RateLimiterBuilder(preset);\r\n};\r\n\r\n// =============================================================================\r\n// LEGACY EXPORTS (backward compatibility)\r\n// =============================================================================\r\n\r\n/**\r\n * @deprecated Use DEFAULT_RATE_LIMIT_TIERS instead\r\n */\r\nexport const RATE_LIMIT_CONFIG = {\r\n STANDARD: DEFAULT_RATE_LIMIT_TIERS.STANDARD,\r\n STRICT: DEFAULT_RATE_LIMIT_TIERS.STRICT,\r\n DDOS: DEFAULT_RATE_LIMIT_TIERS.DDOS,\r\n} as const;\r\n\r\n/**\r\n * @deprecated Use createStandardRateLimiter() instead\r\n */\r\nexport const standardRateLimiter = createStandardRateLimiter();\r\n\r\n/**\r\n * @deprecated Use createStrictRateLimiter() instead\r\n */\r\nexport const strictRateLimiter = createStrictRateLimiter();\r\n\r\n/**\r\n * @deprecated Use createDdosRateLimiter() instead\r\n */\r\nexport const ddosProtectionLimiter = createDdosRateLimiter();\r\n\r\nexport default {\r\n // Factory functions\r\n createRateLimiter,\r\n createStandardRateLimiter,\r\n createStrictRateLimiter,\r\n createDdosRateLimiter,\r\n createApiRateLimiter,\r\n // Builder\r\n rateLimiter,\r\n RateLimiterBuilder,\r\n // Key generators\r\n defaultKeyGenerator,\r\n createPrefixedKeyGenerator,\r\n createUserKeyGenerator,\r\n createApiKeyGenerator,\r\n // Constants\r\n DEFAULT_RATE_LIMIT_TIERS,\r\n RATE_LIMIT_CONFIG,\r\n // Legacy\r\n standardRateLimiter,\r\n strictRateLimiter,\r\n ddosProtectionLimiter,\r\n};\r\n","// =============================================================================\r\n// Dynamic Server Configuration\r\n// Use this to create project-specific server configs\r\n// =============================================================================\r\n\r\n// =============================================================================\r\n// TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Environment type\r\n */\r\nexport type Environment = 'development' | 'production' | 'test' | 'staging';\r\n\r\n/**\r\n * Log level type\r\n */\r\nexport type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'debug';\r\n\r\n/**\r\n * Server configuration interface\r\n */\r\nexport interface ServerConfig {\r\n /** Server name/identifier */\r\n name: string;\r\n /** Server version */\r\n version: string;\r\n /** Current environment */\r\n environment: Environment;\r\n /** Server port */\r\n port: number;\r\n /** Host binding */\r\n host: string;\r\n /** Base API path */\r\n basePath: string;\r\n /** Enable debug mode */\r\n debug: boolean;\r\n /** Trusted proxy settings */\r\n trustProxy: boolean | string | number;\r\n}\r\n\r\n/**\r\n * Database configuration interface\r\n */\r\nexport interface DatabaseConfig {\r\n /** MongoDB connection URI */\r\n uri: string;\r\n /** Database name */\r\n name: string;\r\n /** Max connection pool size */\r\n maxPoolSize: number;\r\n /** Min connection pool size */\r\n minPoolSize: number;\r\n /** Socket timeout in ms */\r\n socketTimeoutMS: number;\r\n /** Server selection timeout in ms */\r\n serverSelectionTimeoutMS: number;\r\n /** Max idle time in ms */\r\n maxIdleTimeMS: number;\r\n /** Enable retry writes */\r\n retryWrites: boolean;\r\n /** Enable retry reads */\r\n retryReads: boolean;\r\n /** Write concern */\r\n writeConcern: 'majority' | number;\r\n}\r\n\r\n/**\r\n * JWT/Auth configuration interface\r\n */\r\nexport interface AuthConfig {\r\n /** JWT secret key */\r\n jwtSecret: string;\r\n /** JWT expiration (e.g., '7d', '24h', '30m') */\r\n jwtExpiresIn: string;\r\n /** Refresh token expiration */\r\n refreshTokenExpiresIn: string;\r\n /** Enable refresh tokens */\r\n enableRefreshTokens: boolean;\r\n /** API key header name */\r\n apiKeyHeader: string;\r\n /** Organization header name */\r\n orgHeader: string;\r\n}\r\n\r\n/**\r\n * Logging configuration interface\r\n */\r\nexport interface LoggingConfig {\r\n /** Log level */\r\n level: LogLevel;\r\n /** Logs directory */\r\n logsDir: string;\r\n /** Max log file size */\r\n maxSize: string;\r\n /** Max days to keep logs */\r\n maxFiles: string;\r\n /** Max days to keep error logs */\r\n errorMaxFiles: string;\r\n /** Enable console logging */\r\n console: boolean;\r\n /** Enable file logging */\r\n file: boolean;\r\n /** Enable JSON format */\r\n json: boolean;\r\n}\r\n\r\n/**\r\n * CORS origins configuration\r\n */\r\nexport interface CorsOriginsConfig {\r\n /** Production domains */\r\n production: string[];\r\n /** Development domains */\r\n development: string[];\r\n /** Custom domain patterns (regex strings) */\r\n patterns: string[];\r\n}\r\n\r\n/**\r\n * Rate limit tier configuration\r\n */\r\nexport interface RateLimitTier {\r\n /** Window duration in ms */\r\n windowMs: number;\r\n /** Max requests in window */\r\n maxRequests: number;\r\n /** Error message */\r\n message: string;\r\n /** Skip successful requests */\r\n skipSuccessfulRequests?: boolean;\r\n /** Skip failed requests */\r\n skipFailedRequests?: boolean;\r\n}\r\n\r\n/**\r\n * Rate limiting configuration\r\n */\r\nexport interface RateLimitConfig {\r\n /** Enable rate limiting */\r\n enabled: boolean;\r\n /** Standard tier */\r\n standard: RateLimitTier;\r\n /** Strict tier (auth endpoints) */\r\n strict: RateLimitTier;\r\n /** DDoS protection tier */\r\n ddos: RateLimitTier;\r\n /** Custom tiers */\r\n custom?: Record<string, RateLimitTier>;\r\n}\r\n\r\n/**\r\n * Complete application configuration\r\n */\r\nexport interface AppConfig {\r\n server: ServerConfig;\r\n database: DatabaseConfig;\r\n auth: AuthConfig;\r\n logging: LoggingConfig;\r\n cors: CorsOriginsConfig;\r\n rateLimit: RateLimitConfig;\r\n /** Custom configuration */\r\n custom?: Record<string, unknown>;\r\n}\r\n\r\n// =============================================================================\r\n// DEFAULT CONFIGURATIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Default server configuration\r\n */\r\nexport const DEFAULT_SERVER_CONFIG: ServerConfig = {\r\n name: 'app-server',\r\n version: '1.0.0',\r\n environment: (process.env.NODE_ENV as Environment) || 'development',\r\n port: parseInt(process.env.PORT || '3000', 10),\r\n host: process.env.HOST || '0.0.0.0',\r\n basePath: '/api',\r\n debug: process.env.DEBUG === 'true',\r\n trustProxy: true,\r\n};\r\n\r\n/**\r\n * Default database configuration\r\n */\r\nexport const DEFAULT_DATABASE_CONFIG: DatabaseConfig = {\r\n uri: process.env.DATABASE_URL || process.env.MONGODB_URI || '',\r\n name: process.env.DATABASE_NAME || 'app_db',\r\n maxPoolSize: process.env.NODE_ENV === 'production' ? 50 : 10,\r\n minPoolSize: process.env.NODE_ENV === 'production' ? 10 : 5,\r\n socketTimeoutMS: 45000,\r\n serverSelectionTimeoutMS: 10000,\r\n maxIdleTimeMS: 10000,\r\n retryWrites: true,\r\n retryReads: true,\r\n writeConcern: 'majority',\r\n};\r\n\r\n/**\r\n * Default auth configuration\r\n */\r\nexport const DEFAULT_AUTH_CONFIG: AuthConfig = {\r\n jwtSecret: process.env.JWT_SECRET || '',\r\n jwtExpiresIn: process.env.JWT_EXPIRES_IN || '7d',\r\n refreshTokenExpiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || '30d',\r\n enableRefreshTokens: true,\r\n apiKeyHeader: 'x-api-key',\r\n orgHeader: 'x-organization-id',\r\n};\r\n\r\n/**\r\n * Default logging configuration\r\n */\r\nexport const DEFAULT_LOGGING_CONFIG: LoggingConfig = {\r\n level: (process.env.LOG_LEVEL as LogLevel) || 'info',\r\n logsDir: process.env.LOGS_DIR || 'logs',\r\n maxSize: '20m',\r\n maxFiles: '14d',\r\n errorMaxFiles: '30d',\r\n console: true,\r\n file: process.env.NODE_ENV === 'production',\r\n json: process.env.NODE_ENV === 'production',\r\n};\r\n\r\n/**\r\n * Default CORS origins configuration\r\n */\r\nexport const DEFAULT_CORS_ORIGINS: CorsOriginsConfig = {\r\n production: [],\r\n development: [\r\n 'http://localhost:3000',\r\n 'http://localhost:4000',\r\n 'http://localhost:5173',\r\n 'http://127.0.0.1:3000',\r\n 'http://127.0.0.1:4000',\r\n 'http://127.0.0.1:5173',\r\n ],\r\n patterns: [],\r\n};\r\n\r\n/**\r\n * Default rate limit configuration\r\n */\r\nexport const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig = {\r\n enabled: true,\r\n standard: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 100,\r\n message: 'Too many requests, please try again later.',\r\n },\r\n strict: {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n maxRequests: 20,\r\n message: 'Too many requests, please try again later.',\r\n },\r\n ddos: {\r\n windowMs: 60 * 1000, // 1 minute\r\n maxRequests: 60,\r\n message: 'Rate limit exceeded. Please slow down.',\r\n skipSuccessfulRequests: false,\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// CONFIG BUILDER\r\n// =============================================================================\r\n\r\n/**\r\n * Create a deep merge of two objects\r\n */\r\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\r\n const result = { ...target } as T;\r\n \r\n for (const key in source) {\r\n if (Object.prototype.hasOwnProperty.call(source, key)) {\r\n const sourceValue = source[key as keyof T];\r\n const targetValue = target[key as keyof T];\r\n \r\n if (\r\n sourceValue !== undefined &&\r\n typeof sourceValue === 'object' &&\r\n sourceValue !== null &&\r\n !Array.isArray(sourceValue) &&\r\n typeof targetValue === 'object' &&\r\n targetValue !== null &&\r\n !Array.isArray(targetValue)\r\n ) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (result as any)[key] = deepMerge(\r\n targetValue as object,\r\n sourceValue as object\r\n );\r\n } else if (sourceValue !== undefined) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (result as any)[key] = sourceValue;\r\n }\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Configuration builder for creating project-specific configs\r\n */\r\nexport class ConfigBuilder {\r\n private config: AppConfig;\r\n\r\n constructor() {\r\n this.config = {\r\n server: { ...DEFAULT_SERVER_CONFIG },\r\n database: { ...DEFAULT_DATABASE_CONFIG },\r\n auth: { ...DEFAULT_AUTH_CONFIG },\r\n logging: { ...DEFAULT_LOGGING_CONFIG },\r\n cors: { ...DEFAULT_CORS_ORIGINS },\r\n rateLimit: { ...DEFAULT_RATE_LIMIT_CONFIG },\r\n };\r\n }\r\n\r\n /**\r\n * Set server configuration\r\n */\r\n setServer(config: Partial<ServerConfig>): this {\r\n this.config.server = deepMerge(this.config.server, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set database configuration\r\n */\r\n setDatabase(config: Partial<DatabaseConfig>): this {\r\n this.config.database = deepMerge(this.config.database, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set auth configuration\r\n */\r\n setAuth(config: Partial<AuthConfig>): this {\r\n this.config.auth = deepMerge(this.config.auth, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set logging configuration\r\n */\r\n setLogging(config: Partial<LoggingConfig>): this {\r\n this.config.logging = deepMerge(this.config.logging, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Set CORS origins\r\n */\r\n setCorsOrigins(config: Partial<CorsOriginsConfig>): this {\r\n this.config.cors = deepMerge(this.config.cors, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS production origin\r\n */\r\n addProductionOrigin(origin: string): this {\r\n if (!this.config.cors.production.includes(origin)) {\r\n this.config.cors.production.push(origin);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS development origin\r\n */\r\n addDevelopmentOrigin(origin: string): this {\r\n if (!this.config.cors.development.includes(origin)) {\r\n this.config.cors.development.push(origin);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Add CORS pattern\r\n */\r\n addCorsPattern(pattern: string): this {\r\n if (!this.config.cors.patterns.includes(pattern)) {\r\n this.config.cors.patterns.push(pattern);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Set rate limit configuration\r\n */\r\n setRateLimit(config: Partial<RateLimitConfig>): this {\r\n this.config.rateLimit = deepMerge(this.config.rateLimit, config);\r\n return this;\r\n }\r\n\r\n /**\r\n * Add custom rate limit tier\r\n */\r\n addRateLimitTier(name: string, tier: RateLimitTier): this {\r\n if (!this.config.rateLimit.custom) {\r\n this.config.rateLimit.custom = {};\r\n }\r\n this.config.rateLimit.custom[name] = tier;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set custom configuration\r\n */\r\n setCustom(key: string, value: unknown): this {\r\n if (!this.config.custom) {\r\n this.config.custom = {};\r\n }\r\n this.config.custom[key] = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * Load configuration from environment variables\r\n */\r\n loadFromEnv(): this {\r\n // Server\r\n if (process.env.SERVER_NAME) this.config.server.name = process.env.SERVER_NAME;\r\n if (process.env.SERVER_VERSION) this.config.server.version = process.env.SERVER_VERSION;\r\n if (process.env.PORT) this.config.server.port = parseInt(process.env.PORT, 10);\r\n if (process.env.HOST) this.config.server.host = process.env.HOST;\r\n if (process.env.BASE_PATH) this.config.server.basePath = process.env.BASE_PATH;\r\n \r\n // Database\r\n if (process.env.DATABASE_URL) this.config.database.uri = process.env.DATABASE_URL;\r\n if (process.env.MONGODB_URI) this.config.database.uri = process.env.MONGODB_URI;\r\n if (process.env.DATABASE_NAME) this.config.database.name = process.env.DATABASE_NAME;\r\n \r\n // Auth\r\n if (process.env.JWT_SECRET) this.config.auth.jwtSecret = process.env.JWT_SECRET;\r\n if (process.env.JWT_EXPIRES_IN) this.config.auth.jwtExpiresIn = process.env.JWT_EXPIRES_IN;\r\n \r\n // Logging\r\n if (process.env.LOG_LEVEL) this.config.logging.level = process.env.LOG_LEVEL as LogLevel;\r\n if (process.env.LOGS_DIR) this.config.logging.logsDir = process.env.LOGS_DIR;\r\n \r\n // CORS origins from env (comma-separated)\r\n if (process.env.CORS_ORIGINS) {\r\n const origins = process.env.CORS_ORIGINS.split(',').map(o => o.trim());\r\n this.config.cors.production.push(...origins);\r\n }\r\n \r\n return this;\r\n }\r\n\r\n /**\r\n * Validate configuration\r\n */\r\n validate(): { valid: boolean; errors: string[] } {\r\n const errors: string[] = [];\r\n \r\n // Validate server config\r\n if (!this.config.server.name) errors.push('Server name is required');\r\n if (this.config.server.port < 1 || this.config.server.port > 65535) {\r\n errors.push('Server port must be between 1 and 65535');\r\n }\r\n \r\n // Validate auth config in production\r\n if (this.config.server.environment === 'production') {\r\n if (!this.config.auth.jwtSecret || this.config.auth.jwtSecret.length < 32) {\r\n errors.push('JWT secret must be at least 32 characters in production');\r\n }\r\n }\r\n \r\n return { valid: errors.length === 0, errors };\r\n }\r\n\r\n /**\r\n * Build the final configuration\r\n */\r\n build(): AppConfig {\r\n return { ...this.config };\r\n }\r\n}\r\n\r\n/**\r\n * Create a new configuration builder\r\n */\r\nexport const createConfig = (): ConfigBuilder => {\r\n return new ConfigBuilder();\r\n};\r\n\r\n/**\r\n * Create config from partial object\r\n */\r\nexport const buildConfig = (partial: Partial<AppConfig> = {}): AppConfig => {\r\n const builder = createConfig().loadFromEnv();\r\n \r\n if (partial.server) builder.setServer(partial.server);\r\n if (partial.database) builder.setDatabase(partial.database);\r\n if (partial.auth) builder.setAuth(partial.auth);\r\n if (partial.logging) builder.setLogging(partial.logging);\r\n if (partial.cors) builder.setCorsOrigins(partial.cors);\r\n if (partial.rateLimit) builder.setRateLimit(partial.rateLimit);\r\n \r\n return builder.build();\r\n};\r\n\r\n// =============================================================================\r\n// HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Check if current environment is production\r\n */\r\nexport const isProduction = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'production';\r\n};\r\n\r\n/**\r\n * Check if current environment is development\r\n */\r\nexport const isDevelopment = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'development';\r\n};\r\n\r\n/**\r\n * Check if current environment is test\r\n */\r\nexport const isTest = (config?: ServerConfig): boolean => {\r\n return (config?.environment || process.env.NODE_ENV) === 'test';\r\n};\r\n\r\n/**\r\n * Get database options for mongoose connect\r\n */\r\nexport const getDatabaseOptions = (config: DatabaseConfig): Record<string, unknown> => {\r\n return {\r\n maxPoolSize: config.maxPoolSize,\r\n minPoolSize: config.minPoolSize,\r\n socketTimeoutMS: config.socketTimeoutMS,\r\n serverSelectionTimeoutMS: config.serverSelectionTimeoutMS,\r\n maxIdleTimeMS: config.maxIdleTimeMS,\r\n retryWrites: config.retryWrites,\r\n retryReads: config.retryReads,\r\n w: config.writeConcern,\r\n };\r\n};\r\n\r\nexport default {\r\n ConfigBuilder,\r\n createConfig,\r\n buildConfig,\r\n isProduction,\r\n isDevelopment,\r\n isTest,\r\n getDatabaseOptions,\r\n DEFAULT_SERVER_CONFIG,\r\n DEFAULT_DATABASE_CONFIG,\r\n DEFAULT_AUTH_CONFIG,\r\n DEFAULT_LOGGING_CONFIG,\r\n DEFAULT_CORS_ORIGINS,\r\n DEFAULT_RATE_LIMIT_CONFIG,\r\n};\r\n"]}
|
package/dist/server/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ export { StatusCode, StatusMessage, statusCode, statusMessage } from './enums/in
|
|
|
3
3
|
export { LoggerConfig, createLogger, createMorganStream, logger, simpleLogger, stream } from './logger/index.mjs';
|
|
4
4
|
export { DbConnectionOptions, connectDB, disconnectDB, getConnectionStatus } from './db/index.mjs';
|
|
5
5
|
export { AuthRequest, BulkDeleteRequest, ColumnMeta, CrudConfig, JWTPayload, OrgRequest, PaginatedRequest, PaginatedResponse, PaginatedResult, PaginationMeta, ParsedQuery, SortConfig, SortOrder, authenticateApiKey, authenticateJWT, buildDeleteFilter, createBulkDeleteHandler, createCrudControllers, createPaginationMiddleware, extractOrganization, extractSchemaMeta, optionalAuthenticateJWT, parseBulkDelete, queryPagination, queryParser, requireOrganization } from './middleware/index.mjs';
|
|
6
|
-
export { FilterOptions, PackageCheckResult, PackageJson, PackageVersion, PaginationOptions, PaginationResult, buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, formatPackageCheckResult, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser } from './utils/index.mjs';
|
|
6
|
+
export { FilterOptions, HealthConfig, HealthResponse, PackageCheckResult, PackageJson, PackageVersion, PaginationOptions, PaginationResult, buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, createHealthHandler, createRootHandler, formatPackageCheckResult, generateHealthResponse, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser } from './utils/index.mjs';
|
|
7
7
|
export { AppConfig, AuthConfig, ConfigBuilder, CorsConfig, CorsOriginsConfig, DEFAULT_AUTH_CONFIG, DEFAULT_CORS_CONFIG, DEFAULT_CORS_ORIGINS, DEFAULT_DATABASE_CONFIG, DEFAULT_LOGGING_CONFIG, DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RATE_LIMIT_TIERS, DEFAULT_SERVER_CONFIG, DatabaseConfig, EXYCONN_CORS_CONFIG, Environment, LogLevel, LoggingConfig, PERMISSIVE_CORS_CONFIG, RATE_LIMIT_CONFIG, RateLimitConfig, RateLimitResponse, RateLimitTier, RateLimitTierConfig, RateLimiterBuilder, RateLimiterConfig, STRICT_CORS_CONFIG, ServerConfig, buildConfig, corsOptions, createApiKeyGenerator, createApiRateLimiter, createBrandCorsOptions, createConfig, createCorsOptions, createDdosRateLimiter, createMultiBrandCorsOptions, createPrefixedKeyGenerator, createRateLimiter, createStandardRateLimiter, createStrictRateLimiter, createUserKeyGenerator, ddosProtectionLimiter, defaultKeyGenerator, getDatabaseOptions, isDevelopment, isProduction, isTest, rateLimiter, standardRateLimiter, strictRateLimiter } from './configs/index.mjs';
|
|
8
8
|
import 'express';
|
|
9
9
|
import 'winston';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { StatusCode, StatusMessage, statusCode, statusMessage } from './enums/in
|
|
|
3
3
|
export { LoggerConfig, createLogger, createMorganStream, logger, simpleLogger, stream } from './logger/index.js';
|
|
4
4
|
export { DbConnectionOptions, connectDB, disconnectDB, getConnectionStatus } from './db/index.js';
|
|
5
5
|
export { AuthRequest, BulkDeleteRequest, ColumnMeta, CrudConfig, JWTPayload, OrgRequest, PaginatedRequest, PaginatedResponse, PaginatedResult, PaginationMeta, ParsedQuery, SortConfig, SortOrder, authenticateApiKey, authenticateJWT, buildDeleteFilter, createBulkDeleteHandler, createCrudControllers, createPaginationMiddleware, extractOrganization, extractSchemaMeta, optionalAuthenticateJWT, parseBulkDelete, queryPagination, queryParser, requireOrganization } from './middleware/index.js';
|
|
6
|
-
export { FilterOptions, PackageCheckResult, PackageJson, PackageVersion, PaginationOptions, PaginationResult, buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, formatPackageCheckResult, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser } from './utils/index.js';
|
|
6
|
+
export { FilterOptions, HealthConfig, HealthResponse, PackageCheckResult, PackageJson, PackageVersion, PaginationOptions, PaginationResult, buildFilter, buildPagination, buildPaginationMeta, checkPackageServer, createHealthHandler, createRootHandler, formatPackageCheckResult, generateHealthResponse, generateNcuCommand, omitFields, packageCheckServer, pickFields, printPackageCheckSummary, sanitizeDocument, sanitizeUser } from './utils/index.js';
|
|
7
7
|
export { AppConfig, AuthConfig, ConfigBuilder, CorsConfig, CorsOriginsConfig, DEFAULT_AUTH_CONFIG, DEFAULT_CORS_CONFIG, DEFAULT_CORS_ORIGINS, DEFAULT_DATABASE_CONFIG, DEFAULT_LOGGING_CONFIG, DEFAULT_RATE_LIMIT_CONFIG, DEFAULT_RATE_LIMIT_TIERS, DEFAULT_SERVER_CONFIG, DatabaseConfig, EXYCONN_CORS_CONFIG, Environment, LogLevel, LoggingConfig, PERMISSIVE_CORS_CONFIG, RATE_LIMIT_CONFIG, RateLimitConfig, RateLimitResponse, RateLimitTier, RateLimitTierConfig, RateLimiterBuilder, RateLimiterConfig, STRICT_CORS_CONFIG, ServerConfig, buildConfig, corsOptions, createApiKeyGenerator, createApiRateLimiter, createBrandCorsOptions, createConfig, createCorsOptions, createDdosRateLimiter, createMultiBrandCorsOptions, createPrefixedKeyGenerator, createRateLimiter, createStandardRateLimiter, createStrictRateLimiter, createUserKeyGenerator, ddosProtectionLimiter, defaultKeyGenerator, getDatabaseOptions, isDevelopment, isProduction, isTest, rateLimiter, standardRateLimiter, strictRateLimiter } from './configs/index.js';
|
|
8
8
|
import 'express';
|
|
9
9
|
import 'winston';
|
package/dist/server/index.js
CHANGED
|
@@ -2,19 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
var winston = require('winston');
|
|
4
4
|
var DailyRotateFile = require('winston-daily-rotate-file');
|
|
5
|
-
var
|
|
5
|
+
var path2 = require('path');
|
|
6
6
|
var mongoose = require('mongoose');
|
|
7
7
|
var jwt = require('jsonwebtoken');
|
|
8
8
|
var fs = require('fs');
|
|
9
|
+
var os = require('os');
|
|
9
10
|
var rateLimit = require('express-rate-limit');
|
|
10
11
|
|
|
11
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
13
|
|
|
13
14
|
var winston__default = /*#__PURE__*/_interopDefault(winston);
|
|
14
15
|
var DailyRotateFile__default = /*#__PURE__*/_interopDefault(DailyRotateFile);
|
|
15
|
-
var
|
|
16
|
+
var path2__default = /*#__PURE__*/_interopDefault(path2);
|
|
16
17
|
var mongoose__default = /*#__PURE__*/_interopDefault(mongoose);
|
|
17
18
|
var jwt__default = /*#__PURE__*/_interopDefault(jwt);
|
|
19
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
20
|
+
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
18
21
|
var rateLimit__default = /*#__PURE__*/_interopDefault(rateLimit);
|
|
19
22
|
|
|
20
23
|
// src/server/enums/status.ts
|
|
@@ -227,7 +230,7 @@ var createLogger = (config = {}) => {
|
|
|
227
230
|
}),
|
|
228
231
|
// Combined logs (all levels)
|
|
229
232
|
new DailyRotateFile__default.default({
|
|
230
|
-
filename:
|
|
233
|
+
filename: path2__default.default.join(finalConfig.logsDir, "combined-%DATE%.log"),
|
|
231
234
|
datePattern: "YYYY-MM-DD",
|
|
232
235
|
maxSize: finalConfig.maxSize,
|
|
233
236
|
maxFiles: finalConfig.maxFiles,
|
|
@@ -235,7 +238,7 @@ var createLogger = (config = {}) => {
|
|
|
235
238
|
}),
|
|
236
239
|
// Error logs only
|
|
237
240
|
new DailyRotateFile__default.default({
|
|
238
|
-
filename:
|
|
241
|
+
filename: path2__default.default.join(finalConfig.logsDir, "error-%DATE%.log"),
|
|
239
242
|
datePattern: "YYYY-MM-DD",
|
|
240
243
|
level: "error",
|
|
241
244
|
maxSize: finalConfig.maxSize,
|
|
@@ -696,7 +699,7 @@ function createCrudControllers(config) {
|
|
|
696
699
|
};
|
|
697
700
|
const getById = async (req, res, _next) => {
|
|
698
701
|
try {
|
|
699
|
-
const
|
|
702
|
+
const id = req.params.id;
|
|
700
703
|
if (!id || !mongoose.Types.ObjectId.isValid(id)) {
|
|
701
704
|
badRequestResponse(res, "Invalid ID format");
|
|
702
705
|
return;
|
|
@@ -771,7 +774,7 @@ function createCrudControllers(config) {
|
|
|
771
774
|
};
|
|
772
775
|
const update = async (req, res, _next) => {
|
|
773
776
|
try {
|
|
774
|
-
const
|
|
777
|
+
const id = req.params.id;
|
|
775
778
|
if (!id || !mongoose.Types.ObjectId.isValid(id)) {
|
|
776
779
|
badRequestResponse(res, "Invalid ID format");
|
|
777
780
|
return;
|
|
@@ -815,7 +818,7 @@ function createCrudControllers(config) {
|
|
|
815
818
|
};
|
|
816
819
|
const deleteOne = async (req, res, _next) => {
|
|
817
820
|
try {
|
|
818
|
-
const
|
|
821
|
+
const id = req.params.id;
|
|
819
822
|
if (!id || !mongoose.Types.ObjectId.isValid(id)) {
|
|
820
823
|
badRequestResponse(res, "Invalid ID format");
|
|
821
824
|
return;
|
|
@@ -1190,7 +1193,7 @@ async function loadPackageJson(source) {
|
|
|
1190
1193
|
}
|
|
1191
1194
|
return response.json();
|
|
1192
1195
|
}
|
|
1193
|
-
const filePath =
|
|
1196
|
+
const filePath = path2.resolve(source);
|
|
1194
1197
|
if (!fs.existsSync(filePath)) {
|
|
1195
1198
|
throw new Error(`File not found: ${filePath}`);
|
|
1196
1199
|
}
|
|
@@ -1344,6 +1347,150 @@ var packageCheckServer = {
|
|
|
1344
1347
|
generateNcuCommand,
|
|
1345
1348
|
print: printPackageCheckSummary
|
|
1346
1349
|
};
|
|
1350
|
+
var serverStartTime = Date.now();
|
|
1351
|
+
function getTimezoneOffset() {
|
|
1352
|
+
const offset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
1353
|
+
const hours = Math.floor(Math.abs(offset) / 60);
|
|
1354
|
+
const minutes = Math.abs(offset) % 60;
|
|
1355
|
+
const sign = offset <= 0 ? "+" : "-";
|
|
1356
|
+
return `${sign}${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
|
|
1357
|
+
}
|
|
1358
|
+
function getTimezoneName() {
|
|
1359
|
+
try {
|
|
1360
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
1361
|
+
} catch {
|
|
1362
|
+
return "UTC";
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
function getPackageInfo(criticalPackages = []) {
|
|
1366
|
+
try {
|
|
1367
|
+
const possiblePaths = [
|
|
1368
|
+
path2__default.default.join(process.cwd(), "package.json"),
|
|
1369
|
+
path2__default.default.join(__dirname, "..", "..", "..", "..", "package.json"),
|
|
1370
|
+
path2__default.default.join(__dirname, "..", "..", "package.json")
|
|
1371
|
+
];
|
|
1372
|
+
for (const pkgPath of possiblePaths) {
|
|
1373
|
+
if (fs__default.default.existsSync(pkgPath)) {
|
|
1374
|
+
const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf-8"));
|
|
1375
|
+
const deps = pkg.dependencies || {};
|
|
1376
|
+
const devDeps = pkg.devDependencies || {};
|
|
1377
|
+
const total = Object.keys(deps).length + Object.keys(devDeps).length;
|
|
1378
|
+
const critical = {};
|
|
1379
|
+
for (const pkgName of criticalPackages) {
|
|
1380
|
+
if (deps[pkgName]) {
|
|
1381
|
+
critical[pkgName] = deps[pkgName].replace("^", "").replace("~", "");
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return { total, critical };
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
} catch {
|
|
1388
|
+
}
|
|
1389
|
+
return { total: 0, critical: {} };
|
|
1390
|
+
}
|
|
1391
|
+
async function generateHealthResponse(config) {
|
|
1392
|
+
const startTime = Date.now();
|
|
1393
|
+
const now = /* @__PURE__ */ new Date();
|
|
1394
|
+
let dependencies = {};
|
|
1395
|
+
if (config.checkDependencies) {
|
|
1396
|
+
try {
|
|
1397
|
+
dependencies = await config.checkDependencies();
|
|
1398
|
+
} catch {
|
|
1399
|
+
dependencies = { error: "DOWN" };
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const hasDownDep = Object.values(dependencies).includes("DOWN");
|
|
1403
|
+
const status = hasDownDep ? "DEGRADED" : "UP";
|
|
1404
|
+
const defaultCriticalPackages = ["express", "mongoose", "cors", "dotenv"];
|
|
1405
|
+
const packageInfo = getPackageInfo(config.criticalPackages || defaultCriticalPackages);
|
|
1406
|
+
const totalMem = os__default.default.totalmem();
|
|
1407
|
+
const freeMem = os__default.default.freemem();
|
|
1408
|
+
const usedMem = totalMem - freeMem;
|
|
1409
|
+
const isProduction2 = process.env.NODE_ENV === "production";
|
|
1410
|
+
const serverUrl = isProduction2 ? `https://${config.domain}` : `http://localhost:${config.port}`;
|
|
1411
|
+
const response = {
|
|
1412
|
+
status,
|
|
1413
|
+
app: config.name,
|
|
1414
|
+
env: process.env.NODE_ENV || "development",
|
|
1415
|
+
version: config.version,
|
|
1416
|
+
urls: {
|
|
1417
|
+
...config.uiUrl && { ui: config.uiUrl },
|
|
1418
|
+
server: config.serverUrl || serverUrl,
|
|
1419
|
+
health: `${config.serverUrl || serverUrl}/health`
|
|
1420
|
+
},
|
|
1421
|
+
time: {
|
|
1422
|
+
serverTime: now.toISOString(),
|
|
1423
|
+
timezone: getTimezoneName(),
|
|
1424
|
+
offset: getTimezoneOffset(),
|
|
1425
|
+
epoch: Math.floor(now.getTime() / 1e3)
|
|
1426
|
+
},
|
|
1427
|
+
uptimeSec: Math.floor((Date.now() - serverStartTime) / 1e3),
|
|
1428
|
+
node: {
|
|
1429
|
+
version: process.version,
|
|
1430
|
+
platform: os__default.default.platform(),
|
|
1431
|
+
arch: os__default.default.arch()
|
|
1432
|
+
},
|
|
1433
|
+
system: {
|
|
1434
|
+
hostname: os__default.default.hostname(),
|
|
1435
|
+
memoryUsedMB: Math.round(usedMem / 1024 / 1024),
|
|
1436
|
+
memoryTotalMB: Math.round(totalMem / 1024 / 1024),
|
|
1437
|
+
memoryFreePercent: Math.round(freeMem / totalMem * 100),
|
|
1438
|
+
cpuLoad: os__default.default.loadavg().map((l) => Math.round(l * 100) / 100),
|
|
1439
|
+
cpuCount: os__default.default.cpus().length
|
|
1440
|
+
},
|
|
1441
|
+
packages: {
|
|
1442
|
+
appVersion: config.version,
|
|
1443
|
+
totalDependencies: packageInfo.total,
|
|
1444
|
+
critical: packageInfo.critical
|
|
1445
|
+
},
|
|
1446
|
+
dependencies,
|
|
1447
|
+
...config.infra && { infra: config.infra },
|
|
1448
|
+
responseTimeMs: Date.now() - startTime
|
|
1449
|
+
};
|
|
1450
|
+
return response;
|
|
1451
|
+
}
|
|
1452
|
+
function createHealthHandler(config) {
|
|
1453
|
+
return async (_req, res) => {
|
|
1454
|
+
try {
|
|
1455
|
+
const health = await generateHealthResponse(config);
|
|
1456
|
+
const statusCode2 = health.status === "UP" ? 200 : health.status === "DEGRADED" ? 200 : 503;
|
|
1457
|
+
res.status(statusCode2).json(health);
|
|
1458
|
+
} catch (error) {
|
|
1459
|
+
res.status(503).json({
|
|
1460
|
+
status: "DOWN",
|
|
1461
|
+
app: config.name,
|
|
1462
|
+
env: process.env.NODE_ENV || "development",
|
|
1463
|
+
version: config.version,
|
|
1464
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
1465
|
+
time: {
|
|
1466
|
+
serverTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1467
|
+
timezone: getTimezoneName(),
|
|
1468
|
+
offset: getTimezoneOffset(),
|
|
1469
|
+
epoch: Math.floor(Date.now() / 1e3)
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
function createRootHandler(config) {
|
|
1476
|
+
return async (_req, res) => {
|
|
1477
|
+
try {
|
|
1478
|
+
const health = await generateHealthResponse(config);
|
|
1479
|
+
res.json({
|
|
1480
|
+
message: `Welcome to ${config.name}`,
|
|
1481
|
+
description: config.description || `${config.name} API Server`,
|
|
1482
|
+
...config.endpoints && { endpoints: config.endpoints },
|
|
1483
|
+
...health
|
|
1484
|
+
});
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
res.status(503).json({
|
|
1487
|
+
status: "DOWN",
|
|
1488
|
+
app: config.name,
|
|
1489
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1347
1494
|
|
|
1348
1495
|
// src/server/configs/cors.config.ts
|
|
1349
1496
|
var DEFAULT_CORS_CONFIG = {
|
|
@@ -1625,6 +1772,8 @@ var createApiRateLimiter = (config = {}, options = {}) => {
|
|
|
1625
1772
|
});
|
|
1626
1773
|
};
|
|
1627
1774
|
var RateLimiterBuilder = class {
|
|
1775
|
+
config;
|
|
1776
|
+
options;
|
|
1628
1777
|
constructor(preset = "STANDARD") {
|
|
1629
1778
|
const presetConfig = DEFAULT_RATE_LIMIT_TIERS[preset];
|
|
1630
1779
|
this.config = {
|
|
@@ -1826,6 +1975,7 @@ function deepMerge(target, source) {
|
|
|
1826
1975
|
return result;
|
|
1827
1976
|
}
|
|
1828
1977
|
var ConfigBuilder = class {
|
|
1978
|
+
config;
|
|
1829
1979
|
constructor() {
|
|
1830
1980
|
this.config = {
|
|
1831
1981
|
server: { ...DEFAULT_SERVER_CONFIG },
|
|
@@ -2041,12 +2191,14 @@ exports.createConfig = createConfig;
|
|
|
2041
2191
|
exports.createCorsOptions = createCorsOptions;
|
|
2042
2192
|
exports.createCrudControllers = createCrudControllers;
|
|
2043
2193
|
exports.createDdosRateLimiter = createDdosRateLimiter;
|
|
2194
|
+
exports.createHealthHandler = createHealthHandler;
|
|
2044
2195
|
exports.createLogger = createLogger;
|
|
2045
2196
|
exports.createMorganStream = createMorganStream;
|
|
2046
2197
|
exports.createMultiBrandCorsOptions = createMultiBrandCorsOptions;
|
|
2047
2198
|
exports.createPaginationMiddleware = createPaginationMiddleware;
|
|
2048
2199
|
exports.createPrefixedKeyGenerator = createPrefixedKeyGenerator;
|
|
2049
2200
|
exports.createRateLimiter = createRateLimiter;
|
|
2201
|
+
exports.createRootHandler = createRootHandler;
|
|
2050
2202
|
exports.createStandardRateLimiter = createStandardRateLimiter;
|
|
2051
2203
|
exports.createStrictRateLimiter = createStrictRateLimiter;
|
|
2052
2204
|
exports.createUserKeyGenerator = createUserKeyGenerator;
|
|
@@ -2060,6 +2212,7 @@ exports.extractOrganization = extractOrganization;
|
|
|
2060
2212
|
exports.extractSchemaMeta = extractSchemaMeta;
|
|
2061
2213
|
exports.forbiddenResponse = forbiddenResponse;
|
|
2062
2214
|
exports.formatPackageCheckResult = formatPackageCheckResult;
|
|
2215
|
+
exports.generateHealthResponse = generateHealthResponse;
|
|
2063
2216
|
exports.generateNcuCommand = generateNcuCommand;
|
|
2064
2217
|
exports.getConnectionStatus = getConnectionStatus;
|
|
2065
2218
|
exports.getDatabaseOptions = getDatabaseOptions;
|