saas-backend-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/PUBLISHING.md +133 -0
  3. package/README.md +459 -0
  4. package/copy-dts.js +255 -0
  5. package/dist/auth/index.d.ts +58 -0
  6. package/dist/auth/index.js +584 -0
  7. package/dist/auth/index.js.map +1 -0
  8. package/dist/auth/index.mjs +569 -0
  9. package/dist/auth/index.mjs.map +1 -0
  10. package/dist/config/index.d.ts +22 -0
  11. package/dist/config/index.js +106 -0
  12. package/dist/config/index.js.map +1 -0
  13. package/dist/config/index.mjs +100 -0
  14. package/dist/config/index.mjs.map +1 -0
  15. package/dist/index.d.ts +25 -0
  16. package/dist/index.js +1303 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/index.mjs +1281 -0
  19. package/dist/index.mjs.map +1 -0
  20. package/dist/logger/index.d.ts +18 -0
  21. package/dist/logger/index.js +188 -0
  22. package/dist/logger/index.js.map +1 -0
  23. package/dist/logger/index.mjs +178 -0
  24. package/dist/logger/index.mjs.map +1 -0
  25. package/dist/notifications/index.d.ts +35 -0
  26. package/dist/notifications/index.js +339 -0
  27. package/dist/notifications/index.js.map +1 -0
  28. package/dist/notifications/index.mjs +328 -0
  29. package/dist/notifications/index.mjs.map +1 -0
  30. package/dist/queue/index.d.ts +33 -0
  31. package/dist/queue/index.js +306 -0
  32. package/dist/queue/index.js.map +1 -0
  33. package/dist/queue/index.mjs +293 -0
  34. package/dist/queue/index.mjs.map +1 -0
  35. package/dist/rate-limit/index.d.ts +11 -0
  36. package/dist/rate-limit/index.js +290 -0
  37. package/dist/rate-limit/index.js.map +1 -0
  38. package/dist/rate-limit/index.mjs +286 -0
  39. package/dist/rate-limit/index.mjs.map +1 -0
  40. package/dist/response/index.d.ts +29 -0
  41. package/dist/response/index.js +120 -0
  42. package/dist/response/index.js.map +1 -0
  43. package/dist/response/index.mjs +114 -0
  44. package/dist/response/index.mjs.map +1 -0
  45. package/examples/express/.env.example +41 -0
  46. package/examples/express/app.ts +203 -0
  47. package/package.json +109 -0
  48. package/src/auth/express.ts +250 -0
  49. package/src/auth/fastify.ts +65 -0
  50. package/src/auth/index.ts +6 -0
  51. package/src/auth/jwt.ts +47 -0
  52. package/src/auth/oauth.ts +117 -0
  53. package/src/auth/rbac.ts +82 -0
  54. package/src/auth/types.ts +69 -0
  55. package/src/config/index.ts +120 -0
  56. package/src/index.ts +16 -0
  57. package/src/logger/index.ts +110 -0
  58. package/src/notifications/index.ts +262 -0
  59. package/src/plugin.ts +192 -0
  60. package/src/queue/index.ts +208 -0
  61. package/src/rate-limit/express.ts +144 -0
  62. package/src/rate-limit/fastify.ts +47 -0
  63. package/src/rate-limit/index.ts +2 -0
  64. package/src/response/index.ts +197 -0
  65. package/src/utils/index.ts +180 -0
  66. package/tsconfig.json +30 -0
  67. package/tsup.config.ts +24 -0
@@ -0,0 +1,286 @@
1
+ import { z } from 'zod';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
+ var envSchema, ConfigManager, globalConfig, config;
24
+ var init_config = __esm({
25
+ "src/config/index.ts"() {
26
+ envSchema = z.object({
27
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
28
+ PORT: z.string().default("3000"),
29
+ DATABASE_URL: z.string().optional(),
30
+ REDIS_URL: z.string().default("redis://localhost:6379"),
31
+ JWT_SECRET: z.string().min(32).optional(),
32
+ JWT_EXPIRES_IN: z.string().default("7d"),
33
+ JWT_REFRESH_SECRET: z.string().min(32).optional(),
34
+ JWT_REFRESH_EXPIRES_IN: z.string().default("30d"),
35
+ GOOGLE_CLIENT_ID: z.string().optional(),
36
+ GOOGLE_CLIENT_SECRET: z.string().optional(),
37
+ GOOGLE_REDIRECT_URI: z.string().optional(),
38
+ SMTP_HOST: z.string().optional(),
39
+ SMTP_PORT: z.string().default("587"),
40
+ SMTP_USER: z.string().optional(),
41
+ SMTP_PASS: z.string().optional(),
42
+ SMTP_FROM: z.string().optional(),
43
+ TWILIO_ACCOUNT_SID: z.string().optional(),
44
+ TWILIO_AUTH_TOKEN: z.string().optional(),
45
+ TWILIO_PHONE_NUMBER: z.string().optional(),
46
+ SLACK_WEBHOOK_URL: z.string().optional(),
47
+ RATE_LIMIT_WINDOW: z.string().default("1m"),
48
+ RATE_LIMIT_LIMIT: z.string().default("100"),
49
+ LOG_LEVEL: z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info")
50
+ });
51
+ ConfigManager = class {
52
+ config = null;
53
+ schema;
54
+ validate;
55
+ constructor(options = {}) {
56
+ this.schema = options.schema || envSchema;
57
+ this.validate = options.validate ?? true;
58
+ }
59
+ load() {
60
+ if (this.config) return this.config;
61
+ const env = {};
62
+ for (const key of Object.keys(this.schema.shape)) {
63
+ env[key] = process.env[key];
64
+ }
65
+ if (this.validate) {
66
+ const result = this.schema.safeParse(env);
67
+ if (!result.success) {
68
+ const errors = result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
69
+ throw new Error(`Config validation failed: ${errors}`);
70
+ }
71
+ this.config = result.data;
72
+ } else {
73
+ this.config = env;
74
+ }
75
+ return this.config;
76
+ }
77
+ get(key) {
78
+ if (!this.config) this.load();
79
+ return this.config[key];
80
+ }
81
+ int(key) {
82
+ const value = this.get(key);
83
+ if (typeof value === "string") return parseInt(value, 10);
84
+ return Number(value);
85
+ }
86
+ bool(key) {
87
+ const value = this.get(key);
88
+ if (typeof value === "boolean") return value;
89
+ if (typeof value === "string") return value.toLowerCase() === "true";
90
+ return Boolean(value);
91
+ }
92
+ isProduction() {
93
+ return this.get("NODE_ENV") === "production";
94
+ }
95
+ isDevelopment() {
96
+ return this.get("NODE_ENV") === "development";
97
+ }
98
+ isTest() {
99
+ return this.get("NODE_ENV") === "test";
100
+ }
101
+ getAll() {
102
+ if (!this.config) this.load();
103
+ return this.config;
104
+ }
105
+ };
106
+ globalConfig = new ConfigManager();
107
+ config = {
108
+ load: () => globalConfig.load(),
109
+ get: (key) => globalConfig.get(key),
110
+ int: (key) => globalConfig.int(key),
111
+ bool: (key) => globalConfig.bool(key),
112
+ isProduction: () => globalConfig.isProduction(),
113
+ isDevelopment: () => globalConfig.isDevelopment(),
114
+ isTest: () => globalConfig.isTest(),
115
+ getAll: () => globalConfig.getAll(),
116
+ create: (options) => new ConfigManager(options)
117
+ };
118
+ }
119
+ });
120
+
121
+ // src/rate-limit/express.ts
122
+ var express_exports = {};
123
+ __export(express_exports, {
124
+ createRateLimiter: () => createRateLimiter,
125
+ default: () => express_default,
126
+ rateLimit: () => rateLimit
127
+ });
128
+ function rateLimit(options = {}) {
129
+ const limiter = new RateLimiter(options);
130
+ return limiter.middleware();
131
+ }
132
+ function createRateLimiter(options) {
133
+ return new RateLimiter(options);
134
+ }
135
+ var InMemoryRateLimiter, RateLimiter, express_default;
136
+ var init_express = __esm({
137
+ "src/rate-limit/express.ts"() {
138
+ init_config();
139
+ InMemoryRateLimiter = class {
140
+ store = /* @__PURE__ */ new Map();
141
+ cleanupInterval;
142
+ constructor() {
143
+ this.cleanupInterval = setInterval(() => this.cleanup(), 6e4);
144
+ }
145
+ cleanup() {
146
+ const now = Date.now();
147
+ for (const [key, record] of this.store.entries()) {
148
+ if (record.resetTime < now) {
149
+ this.store.delete(key);
150
+ }
151
+ }
152
+ }
153
+ increment(key, windowMs) {
154
+ const now = Date.now();
155
+ const record = this.store.get(key);
156
+ if (!record || record.resetTime < now) {
157
+ const resetTime = now + windowMs;
158
+ this.store.set(key, { count: 1, resetTime });
159
+ return { count: 1, resetTime };
160
+ }
161
+ record.count++;
162
+ return record;
163
+ }
164
+ get(key) {
165
+ return this.store.get(key);
166
+ }
167
+ destroy() {
168
+ clearInterval(this.cleanupInterval);
169
+ }
170
+ };
171
+ RateLimiter = class {
172
+ options;
173
+ store;
174
+ constructor(options = {}) {
175
+ const defaultWindow = config.get("RATE_LIMIT_WINDOW") || "1m";
176
+ const defaultLimit = parseInt(config.get("RATE_LIMIT_LIMIT") || "100", 10);
177
+ this.options = {
178
+ window: options.window || defaultWindow,
179
+ limit: options.limit || defaultLimit,
180
+ keyGenerator: options.keyGenerator || ((req) => req.ip || "unknown"),
181
+ handler: options.handler || this.defaultHandler,
182
+ skipSuccessfulRequests: options.skipSuccessfulRequests || false,
183
+ skipFailedRequests: options.skipFailedRequests || false,
184
+ skip: options.skip || (() => false)
185
+ };
186
+ this.store = new InMemoryRateLimiter();
187
+ }
188
+ getWindowMs() {
189
+ const window = this.options.window;
190
+ const match = window.match(/^(\d+)(s|m|h|d)$/);
191
+ if (!match) return 6e4;
192
+ const value = parseInt(match[1], 10);
193
+ const unit = match[2];
194
+ switch (unit) {
195
+ case "s":
196
+ return value * 1e3;
197
+ case "m":
198
+ return value * 60 * 1e3;
199
+ case "h":
200
+ return value * 60 * 60 * 1e3;
201
+ case "d":
202
+ return value * 24 * 60 * 60 * 1e3;
203
+ default:
204
+ return 6e4;
205
+ }
206
+ }
207
+ defaultHandler(req, res) {
208
+ res.status(429).json({
209
+ error: "Too many requests",
210
+ message: `Rate limit exceeded. Please try again later.`
211
+ });
212
+ }
213
+ middleware() {
214
+ const windowMs = this.getWindowMs();
215
+ return (req, res, next) => {
216
+ if (this.options.skip(req)) {
217
+ return next();
218
+ }
219
+ const key = this.options.keyGenerator(req);
220
+ const record = this.store.increment(key, windowMs);
221
+ const remaining = Math.max(0, this.options.limit - record.count);
222
+ new Date(record.resetTime);
223
+ res.setHeader("X-RateLimit-Limit", this.options.limit);
224
+ res.setHeader("X-RateLimit-Remaining", remaining);
225
+ res.setHeader("X-RateLimit-Reset", Math.ceil(record.resetTime / 1e3));
226
+ if (record.count > this.options.limit) {
227
+ return this.options.handler(req, res);
228
+ }
229
+ next();
230
+ };
231
+ }
232
+ destroy() {
233
+ this.store.destroy();
234
+ }
235
+ };
236
+ express_default = rateLimit;
237
+ }
238
+ });
239
+
240
+ // src/rate-limit/index.ts
241
+ init_express();
242
+
243
+ // src/rate-limit/fastify.ts
244
+ function registerRateLimitPlugin(fastify, options = {}, done) {
245
+ const limiter = new (init_express(), __toCommonJS(express_exports)).createRateLimiter.constructor(options);
246
+ fastify.addHook("onRequest", async (request, reply) => {
247
+ const key = options.keyGenerator ? options.keyGenerator(request.raw) : request.ip || "unknown";
248
+ const windowMs = parseWindowMs(options.window || "1m");
249
+ const record = limiter.store.increment(key, windowMs);
250
+ const limit = options.limit || 100;
251
+ const remaining = Math.max(0, limit - record.count);
252
+ reply.header("X-RateLimit-Limit", limit);
253
+ reply.header("X-RateLimit-Remaining", remaining);
254
+ reply.header("X-RateLimit-Reset", Math.ceil(record.resetTime / 1e3));
255
+ if (record.count > limit) {
256
+ reply.status(429).send({
257
+ error: "Too many requests",
258
+ message: "Rate limit exceeded. Please try again later."
259
+ });
260
+ return reply;
261
+ }
262
+ });
263
+ done();
264
+ }
265
+ function parseWindowMs(window) {
266
+ const match = window.match(/^(\d+)(s|m|h|d)$/);
267
+ if (!match) return 6e4;
268
+ const value = parseInt(match[1], 10);
269
+ const unit = match[2];
270
+ switch (unit) {
271
+ case "s":
272
+ return value * 1e3;
273
+ case "m":
274
+ return value * 60 * 1e3;
275
+ case "h":
276
+ return value * 60 * 60 * 1e3;
277
+ case "d":
278
+ return value * 24 * 60 * 60 * 1e3;
279
+ default:
280
+ return 6e4;
281
+ }
282
+ }
283
+
284
+ export { createRateLimiter, rateLimit, registerRateLimitPlugin };
285
+ //# sourceMappingURL=index.mjs.map
286
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/index.ts","../../src/rate-limit/express.ts","../../src/rate-limit/index.ts","../../src/rate-limit/fastify.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from 'zod';\n\nexport const envSchema = z.object({\n NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n PORT: z.string().default('3000'),\n DATABASE_URL: z.string().optional(),\n REDIS_URL: z.string().default('redis://localhost:6379'),\n JWT_SECRET: z.string().min(32).optional(),\n JWT_EXPIRES_IN: z.string().default('7d'),\n JWT_REFRESH_SECRET: z.string().min(32).optional(),\n JWT_REFRESH_EXPIRES_IN: z.string().default('30d'),\n GOOGLE_CLIENT_ID: z.string().optional(),\n GOOGLE_CLIENT_SECRET: z.string().optional(),\n GOOGLE_REDIRECT_URI: z.string().optional(),\n SMTP_HOST: z.string().optional(),\n SMTP_PORT: z.string().default('587'),\n SMTP_USER: z.string().optional(),\n SMTP_PASS: z.string().optional(),\n SMTP_FROM: z.string().optional(),\n TWILIO_ACCOUNT_SID: z.string().optional(),\n TWILIO_AUTH_TOKEN: z.string().optional(),\n TWILIO_PHONE_NUMBER: z.string().optional(),\n SLACK_WEBHOOK_URL: z.string().optional(),\n RATE_LIMIT_WINDOW: z.string().default('1m'),\n RATE_LIMIT_LIMIT: z.string().default('100'),\n LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),\n});\n\nexport type EnvConfig = z.infer<typeof envSchema>;\n\nexport interface ConfigOptions {\n schema?: z.ZodSchema;\n envPath?: string;\n validate?: boolean;\n}\n\nclass ConfigManager {\n private config: EnvConfig | null = null;\n private schema: z.ZodSchema;\n private validate: boolean;\n\n constructor(options: ConfigOptions = {}) {\n this.schema = options.schema || envSchema;\n this.validate = options.validate ?? true;\n }\n\n load(): EnvConfig {\n if (this.config) return this.config;\n\n const env: Record<string, string | undefined> = {};\n \n for (const key of Object.keys(this.schema.shape)) {\n env[key] = process.env[key];\n }\n\n if (this.validate) {\n const result = this.schema.safeParse(env);\n if (!result.success) {\n const errors = result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');\n throw new Error(`Config validation failed: ${errors}`);\n }\n this.config = result.data;\n } else {\n this.config = env as EnvConfig;\n }\n\n return this.config;\n }\n\n get<K extends keyof EnvConfig>(key: K): EnvConfig[K] {\n if (!this.config) this.load();\n return this.config![key];\n }\n\n int(key: keyof EnvConfig): number {\n const value = this.get(key);\n if (typeof value === 'string') return parseInt(value, 10);\n return Number(value);\n }\n\n bool(key: keyof EnvConfig): boolean {\n const value = this.get(key);\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n isProduction(): boolean {\n return this.get('NODE_ENV') === 'production';\n }\n\n isDevelopment(): boolean {\n return this.get('NODE_ENV') === 'development';\n }\n\n isTest(): boolean {\n return this.get('NODE_ENV') === 'test';\n }\n\n getAll(): EnvConfig {\n if (!this.config) this.load();\n return this.config!;\n }\n}\n\nconst globalConfig = new ConfigManager();\n\nexport const config = {\n load: () => globalConfig.load(),\n get: <K extends keyof EnvConfig>(key: K) => globalConfig.get(key),\n int: (key: keyof EnvConfig) => globalConfig.int(key),\n bool: (key: keyof EnvConfig) => globalConfig.bool(key),\n isProduction: () => globalConfig.isProduction(),\n isDevelopment: () => globalConfig.isDevelopment(),\n isTest: () => globalConfig.isTest(),\n getAll: () => globalConfig.getAll(),\n create: (options?: ConfigOptions) => new ConfigManager(options),\n};\n\nexport default config;\n","import { Request, Response, NextFunction, RequestHandler } from 'express';\nimport { config } from '../config';\n\nexport interface RateLimitOptions {\n window?: string;\n limit?: number;\n keyGenerator?: (req: Request) => string;\n handler?: (req: Request, res: Response) => void;\n skipSuccessfulRequests?: boolean;\n skipFailedRequests?: boolean;\n skip?: (req: Request) => boolean;\n}\n\ninterface RateLimitRecord {\n count: number;\n resetTime: number;\n}\n\nclass InMemoryRateLimiter {\n private store: Map<string, RateLimitRecord> = new Map();\n private cleanupInterval: NodeJS.Timeout;\n\n constructor() {\n this.cleanupInterval = setInterval(() => this.cleanup(), 60000);\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, record] of this.store.entries()) {\n if (record.resetTime < now) {\n this.store.delete(key);\n }\n }\n }\n\n increment(key: string, windowMs: number): RateLimitRecord {\n const now = Date.now();\n const record = this.store.get(key);\n\n if (!record || record.resetTime < now) {\n const resetTime = now + windowMs;\n this.store.set(key, { count: 1, resetTime });\n return { count: 1, resetTime };\n }\n\n record.count++;\n return record;\n }\n\n get(key: string): RateLimitRecord | undefined {\n return this.store.get(key);\n }\n\n destroy(): void {\n clearInterval(this.cleanupInterval);\n }\n}\n\nclass RateLimiter {\n private options: Required<RateLimitOptions>;\n private store: InMemoryRateLimiter;\n\n constructor(options: RateLimitOptions = {}) {\n const defaultWindow = config.get('RATE_LIMIT_WINDOW') || '1m';\n const defaultLimit = parseInt(config.get('RATE_LIMIT_LIMIT') || '100', 10);\n\n this.options = {\n window: options.window || defaultWindow,\n limit: options.limit || defaultLimit,\n keyGenerator: options.keyGenerator || ((req: Request) => req.ip || 'unknown'),\n handler: options.handler || this.defaultHandler,\n skipSuccessfulRequests: options.skipSuccessfulRequests || false,\n skipFailedRequests: options.skipFailedRequests || false,\n skip: options.skip || (() => false),\n };\n\n this.store = new InMemoryRateLimiter();\n }\n\n private getWindowMs(): number {\n const window = this.options.window;\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n }\n\n private defaultHandler(req: Request, res: Response): void {\n res.status(429).json({\n error: 'Too many requests',\n message: `Rate limit exceeded. Please try again later.`,\n });\n }\n\n middleware(): RequestHandler {\n const windowMs = this.getWindowMs();\n\n return (req: Request, res: Response, next: NextFunction) => {\n if (this.options.skip(req)) {\n return next();\n }\n\n const key = this.options.keyGenerator(req);\n const record = this.store.increment(key, windowMs);\n\n const remaining = Math.max(0, this.options.limit - record.count);\n const resetTime = new Date(record.resetTime);\n\n res.setHeader('X-RateLimit-Limit', this.options.limit);\n res.setHeader('X-RateLimit-Remaining', remaining);\n res.setHeader('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > this.options.limit) {\n return this.options.handler(req, res);\n }\n\n next();\n };\n }\n\n destroy(): void {\n this.store.destroy();\n }\n}\n\nexport function rateLimit(options: RateLimitOptions = {}): RequestHandler {\n const limiter = new RateLimiter(options);\n return limiter.middleware();\n}\n\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\nexport default rateLimit;\n","export * from './express';\nexport * from './fastify';\n","import { FastifyInstance, FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';\nimport { RateLimitOptions, InMemoryRateLimiter } from './express';\n\nexport function registerRateLimitPlugin(fastify: FastifyInstance, options: RateLimitOptions = {}, done: HookHandlerDoneFunction) {\n const limiter = new (require('./express').createRateLimiter.constructor)(options);\n \n fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => {\n const key = options.keyGenerator \n ? options.keyGenerator(request.raw as any)\n : request.ip || 'unknown';\n \n const windowMs = parseWindowMs(options.window || '1m');\n const record = (limiter as any).store.increment(key, windowMs);\n const limit = options.limit || 100;\n const remaining = Math.max(0, limit - record.count);\n\n reply.header('X-RateLimit-Limit', limit);\n reply.header('X-RateLimit-Remaining', remaining);\n reply.header('X-RateLimit-Reset', Math.ceil(record.resetTime / 1000));\n\n if (record.count > limit) {\n reply.status(429).send({\n error: 'Too many requests',\n message: 'Rate limit exceeded. Please try again later.',\n });\n return reply;\n }\n });\n\n done();\n}\n\nfunction parseWindowMs(window: string): number {\n const match = window.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) return 60000;\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: return 60000;\n }\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import { Response } from 'express';
2
+
3
+ export interface ApiResponse<T = any> {
4
+ success: boolean;
5
+ data?: T;
6
+ error?: string;
7
+ message?: string;
8
+ }
9
+
10
+ export interface PaginatedResponse<T> extends ApiResponse<T> {
11
+ meta: { page: number; limit: number; total: number; totalPages: number };
12
+ }
13
+
14
+ export declare class ResponseHelper {
15
+ static success<T>(res: Response, data?: T, message?: string, statusCode?: number): Response;
16
+ static created<T>(res: Response, data?: T, message?: string): Response;
17
+ static updated<T>(res: Response, data?: T, message?: string): Response;
18
+ static deleted(res: Response, message?: string): Response;
19
+ static error(res: Response, error: string, statusCode?: number): Response;
20
+ static badRequest(res: Response, error?: string): Response;
21
+ static unauthorized(res: Response, error?: string): Response;
22
+ static forbidden(res: Response, error?: string): Response;
23
+ static notFound(res: Response, error?: string): Response;
24
+ static validationError(res: Response, error: string): Response;
25
+ static internalError(res: Response, error?: string): Response;
26
+ static paginated<T>(res: Response, data: T[], page: number, limit: number, total: number): Response;
27
+ }
28
+
29
+ export declare const response: typeof ResponseHelper;
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var express = require('express');
6
+
7
+ // src/response/index.ts
8
+ var ResponseHelper = class {
9
+ static success(res, data, message, statusCode = 200) {
10
+ const response2 = {
11
+ success: true,
12
+ data,
13
+ message
14
+ };
15
+ return res.status(statusCode).json(response2);
16
+ }
17
+ static created(res, data, message = "Resource created") {
18
+ return this.success(res, data, message, 201);
19
+ }
20
+ static updated(res, data, message = "Resource updated") {
21
+ return this.success(res, data, message, 200);
22
+ }
23
+ static deleted(res, message = "Resource deleted") {
24
+ return this.success(res, null, message, 200);
25
+ }
26
+ static error(res, error, statusCode = 400, code, details) {
27
+ const response2 = {
28
+ success: false,
29
+ error,
30
+ code,
31
+ ...details && { details }
32
+ };
33
+ return res.status(statusCode).json(response2);
34
+ }
35
+ static badRequest(res, error = "Bad request", code) {
36
+ return this.error(res, error, 400, code);
37
+ }
38
+ static unauthorized(res, error = "Unauthorized", code) {
39
+ return this.error(res, error, 401, code);
40
+ }
41
+ static forbidden(res, error = "Forbidden", code) {
42
+ return this.error(res, error, 403, code);
43
+ }
44
+ static notFound(res, error = "Resource not found", code) {
45
+ return this.error(res, error, 404, code);
46
+ }
47
+ static conflict(res, error = "Conflict", code) {
48
+ return this.error(res, error, 409, code);
49
+ }
50
+ static validationError(res, error, details) {
51
+ return this.error(res, error, 422, "VALIDATION_ERROR", details);
52
+ }
53
+ static internalError(res, error = "Internal server error") {
54
+ return this.error(res, error, 500, "INTERNAL_ERROR");
55
+ }
56
+ static paginated(res, data, page, limit, total) {
57
+ const totalPages = Math.ceil(total / limit);
58
+ const response2 = {
59
+ success: true,
60
+ data,
61
+ meta: {
62
+ page,
63
+ limit,
64
+ total,
65
+ totalPages
66
+ }
67
+ };
68
+ return res.status(200).json(response2);
69
+ }
70
+ static noContent(res) {
71
+ return res.status(204).send();
72
+ }
73
+ };
74
+ express.Response.prototype.success = function(data, message, statusCode = 200) {
75
+ return ResponseHelper.success(this, data, message, statusCode);
76
+ };
77
+ express.Response.prototype.created = function(data, message) {
78
+ return ResponseHelper.created(this, data, message);
79
+ };
80
+ express.Response.prototype.updated = function(data, message) {
81
+ return ResponseHelper.updated(this, data, message);
82
+ };
83
+ express.Response.prototype.deleted = function(message) {
84
+ return ResponseHelper.deleted(this, message);
85
+ };
86
+ express.Response.prototype.error = function(error, statusCode = 400, code, details) {
87
+ return ResponseHelper.error(this, error, statusCode, code, details);
88
+ };
89
+ express.Response.prototype.badRequest = function(error, code) {
90
+ return ResponseHelper.badRequest(this, error, code);
91
+ };
92
+ express.Response.prototype.unauthorized = function(error, code) {
93
+ return ResponseHelper.unauthorized(this, error, code);
94
+ };
95
+ express.Response.prototype.forbidden = function(error, code) {
96
+ return ResponseHelper.forbidden(this, error, code);
97
+ };
98
+ express.Response.prototype.notFound = function(error, code) {
99
+ return ResponseHelper.notFound(this, error, code);
100
+ };
101
+ express.Response.prototype.conflict = function(error, code) {
102
+ return ResponseHelper.conflict(this, error, code);
103
+ };
104
+ express.Response.prototype.validationError = function(error, details) {
105
+ return ResponseHelper.validationError(this, error, details);
106
+ };
107
+ express.Response.prototype.internalError = function(error) {
108
+ return ResponseHelper.internalError(this, error);
109
+ };
110
+ express.Response.prototype.paginated = function(data, page, limit, total) {
111
+ return ResponseHelper.paginated(this, data, page, limit, total);
112
+ };
113
+ var response = ResponseHelper;
114
+ var response_default = ResponseHelper;
115
+
116
+ exports.ResponseHelper = ResponseHelper;
117
+ exports.default = response_default;
118
+ exports.response = response;
119
+ //# sourceMappingURL=index.js.map
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/response/index.ts"],"names":["response","Response"],"mappings":"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","file":"index.js","sourcesContent":["import { Response } from 'express';\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n totalPages?: number;\n };\n}\n\nexport interface PaginatedResponse<T> extends ApiResponse<T> {\n meta: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface ErrorResponse {\n success: false;\n error: string;\n code?: string;\n details?: Record<string, unknown>;\n}\n\nexport class ResponseHelper {\n static success<T>(res: Response, data?: T, message?: string, statusCode: number = 200): Response {\n const response: ApiResponse<T> = {\n success: true,\n data,\n message,\n };\n return res.status(statusCode).json(response);\n }\n\n static created<T>(res: Response, data?: T, message: string = 'Resource created'): Response {\n return this.success(res, data, message, 201);\n }\n\n static updated<T>(res: Response, data?: T, message: string = 'Resource updated'): Response {\n return this.success(res, data, message, 200);\n }\n\n static deleted(res: Response, message: string = 'Resource deleted'): Response {\n return this.success(res, null, message, 200);\n }\n\n static error(\n res: Response,\n error: string,\n statusCode: number = 400,\n code?: string,\n details?: Record<string, unknown>\n ): Response {\n const response: ErrorResponse = {\n success: false,\n error,\n code,\n ...(details && { details }),\n };\n return res.status(statusCode).json(response);\n }\n\n static badRequest(res: Response, error: string = 'Bad request', code?: string): Response {\n return this.error(res, error, 400, code);\n }\n\n static unauthorized(res: Response, error: string = 'Unauthorized', code?: string): Response {\n return this.error(res, error, 401, code);\n }\n\n static forbidden(res: Response, error: string = 'Forbidden', code?: string): Response {\n return this.error(res, error, 403, code);\n }\n\n static notFound(res: Response, error: string = 'Resource not found', code?: string): Response {\n return this.error(res, error, 404, code);\n }\n\n static conflict(res: Response, error: string = 'Conflict', code?: string): Response {\n return this.error(res, error, 409, code);\n }\n\n static validationError(res: Response, error: string, details?: Record<string, unknown>): Response {\n return this.error(res, error, 422, 'VALIDATION_ERROR', details);\n }\n\n static internalError(res: Response, error: string = 'Internal server error'): Response {\n return this.error(res, error, 500, 'INTERNAL_ERROR');\n }\n\n static paginated<T>(\n res: Response,\n data: T[],\n page: number,\n limit: number,\n total: number\n ): Response<PaginatedResponse<T>> {\n const totalPages = Math.ceil(total / limit);\n const response: PaginatedResponse<T> = {\n success: true,\n data,\n meta: {\n page,\n limit,\n total,\n totalPages,\n },\n };\n return res.status(200).json(response);\n }\n\n static noContent(res: Response): Response {\n return res.status(204).send();\n }\n}\n\ndeclare global {\n namespace Express {\n interface Response {\n success<T>(data?: T, message?: string, statusCode?: number): Response;\n created<T>(data?: T, message?: string): Response;\n updated<T>(data?: T, message?: string): Response;\n deleted(message?: string): Response;\n error(error: string, statusCode?: number, code?: string, details?: Record<string, unknown>): Response;\n badRequest(error?: string, code?: string): Response;\n unauthorized(error?: string, code?: string): Response;\n forbidden(error?: string, code?: string): Response;\n notFound(error?: string, code?: string): Response;\n conflict(error?: string, code?: string): Response;\n validationError(error: string, details?: Record<string, unknown>): Response;\n internalError(error?: string): Response;\n paginated<T>(data: T[], page: number, limit: number, total: number): Response;\n }\n }\n}\n\nResponse.prototype.success = function <T>(data?: T, message?: string, statusCode: number = 200) {\n return ResponseHelper.success(this, data, message, statusCode);\n};\n\nResponse.prototype.created = function <T>(data?: T, message?: string) {\n return ResponseHelper.created(this, data, message);\n};\n\nResponse.prototype.updated = function <T>(data?: T, message?: string) {\n return ResponseHelper.updated(this, data, message);\n};\n\nResponse.prototype.deleted = function (message?: string) {\n return ResponseHelper.deleted(this, message);\n};\n\nResponse.prototype.error = function (error: string, statusCode: number = 400, code?: string, details?: Record<string, unknown>) {\n return ResponseHelper.error(this, error, statusCode, code, details);\n};\n\nResponse.prototype.badRequest = function (error?: string, code?: string) {\n return ResponseHelper.badRequest(this, error, code);\n};\n\nResponse.prototype.unauthorized = function (error?: string, code?: string) {\n return ResponseHelper.unauthorized(this, error, code);\n};\n\nResponse.prototype.forbidden = function (error?: string, code?: string) {\n return ResponseHelper.forbidden(this, error, code);\n};\n\nResponse.prototype.notFound = function (error?: string, code?: string) {\n return ResponseHelper.notFound(this, error, code);\n};\n\nResponse.prototype.conflict = function (error?: string, code?: string) {\n return ResponseHelper.conflict(this, error, code);\n};\n\nResponse.prototype.validationError = function (error: string, details?: Record<string, unknown>) {\n return ResponseHelper.validationError(this, error, details);\n};\n\nResponse.prototype.internalError = function (error?: string) {\n return ResponseHelper.internalError(this, error);\n};\n\nResponse.prototype.paginated = function <T>(data: T[], page: number, limit: number, total: number) {\n return ResponseHelper.paginated(this, data, page, limit, total);\n};\n\nexport const response = ResponseHelper;\nexport default ResponseHelper;\n"]}
@@ -0,0 +1,114 @@
1
+ import { Response } from 'express';
2
+
3
+ // src/response/index.ts
4
+ var ResponseHelper = class {
5
+ static success(res, data, message, statusCode = 200) {
6
+ const response2 = {
7
+ success: true,
8
+ data,
9
+ message
10
+ };
11
+ return res.status(statusCode).json(response2);
12
+ }
13
+ static created(res, data, message = "Resource created") {
14
+ return this.success(res, data, message, 201);
15
+ }
16
+ static updated(res, data, message = "Resource updated") {
17
+ return this.success(res, data, message, 200);
18
+ }
19
+ static deleted(res, message = "Resource deleted") {
20
+ return this.success(res, null, message, 200);
21
+ }
22
+ static error(res, error, statusCode = 400, code, details) {
23
+ const response2 = {
24
+ success: false,
25
+ error,
26
+ code,
27
+ ...details && { details }
28
+ };
29
+ return res.status(statusCode).json(response2);
30
+ }
31
+ static badRequest(res, error = "Bad request", code) {
32
+ return this.error(res, error, 400, code);
33
+ }
34
+ static unauthorized(res, error = "Unauthorized", code) {
35
+ return this.error(res, error, 401, code);
36
+ }
37
+ static forbidden(res, error = "Forbidden", code) {
38
+ return this.error(res, error, 403, code);
39
+ }
40
+ static notFound(res, error = "Resource not found", code) {
41
+ return this.error(res, error, 404, code);
42
+ }
43
+ static conflict(res, error = "Conflict", code) {
44
+ return this.error(res, error, 409, code);
45
+ }
46
+ static validationError(res, error, details) {
47
+ return this.error(res, error, 422, "VALIDATION_ERROR", details);
48
+ }
49
+ static internalError(res, error = "Internal server error") {
50
+ return this.error(res, error, 500, "INTERNAL_ERROR");
51
+ }
52
+ static paginated(res, data, page, limit, total) {
53
+ const totalPages = Math.ceil(total / limit);
54
+ const response2 = {
55
+ success: true,
56
+ data,
57
+ meta: {
58
+ page,
59
+ limit,
60
+ total,
61
+ totalPages
62
+ }
63
+ };
64
+ return res.status(200).json(response2);
65
+ }
66
+ static noContent(res) {
67
+ return res.status(204).send();
68
+ }
69
+ };
70
+ Response.prototype.success = function(data, message, statusCode = 200) {
71
+ return ResponseHelper.success(this, data, message, statusCode);
72
+ };
73
+ Response.prototype.created = function(data, message) {
74
+ return ResponseHelper.created(this, data, message);
75
+ };
76
+ Response.prototype.updated = function(data, message) {
77
+ return ResponseHelper.updated(this, data, message);
78
+ };
79
+ Response.prototype.deleted = function(message) {
80
+ return ResponseHelper.deleted(this, message);
81
+ };
82
+ Response.prototype.error = function(error, statusCode = 400, code, details) {
83
+ return ResponseHelper.error(this, error, statusCode, code, details);
84
+ };
85
+ Response.prototype.badRequest = function(error, code) {
86
+ return ResponseHelper.badRequest(this, error, code);
87
+ };
88
+ Response.prototype.unauthorized = function(error, code) {
89
+ return ResponseHelper.unauthorized(this, error, code);
90
+ };
91
+ Response.prototype.forbidden = function(error, code) {
92
+ return ResponseHelper.forbidden(this, error, code);
93
+ };
94
+ Response.prototype.notFound = function(error, code) {
95
+ return ResponseHelper.notFound(this, error, code);
96
+ };
97
+ Response.prototype.conflict = function(error, code) {
98
+ return ResponseHelper.conflict(this, error, code);
99
+ };
100
+ Response.prototype.validationError = function(error, details) {
101
+ return ResponseHelper.validationError(this, error, details);
102
+ };
103
+ Response.prototype.internalError = function(error) {
104
+ return ResponseHelper.internalError(this, error);
105
+ };
106
+ Response.prototype.paginated = function(data, page, limit, total) {
107
+ return ResponseHelper.paginated(this, data, page, limit, total);
108
+ };
109
+ var response = ResponseHelper;
110
+ var response_default = ResponseHelper;
111
+
112
+ export { ResponseHelper, response_default as default, response };
113
+ //# sourceMappingURL=index.mjs.map
114
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/response/index.ts"],"names":["response"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Response } from 'express';\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n meta?: {\n page?: number;\n limit?: number;\n total?: number;\n totalPages?: number;\n };\n}\n\nexport interface PaginatedResponse<T> extends ApiResponse<T> {\n meta: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface ErrorResponse {\n success: false;\n error: string;\n code?: string;\n details?: Record<string, unknown>;\n}\n\nexport class ResponseHelper {\n static success<T>(res: Response, data?: T, message?: string, statusCode: number = 200): Response {\n const response: ApiResponse<T> = {\n success: true,\n data,\n message,\n };\n return res.status(statusCode).json(response);\n }\n\n static created<T>(res: Response, data?: T, message: string = 'Resource created'): Response {\n return this.success(res, data, message, 201);\n }\n\n static updated<T>(res: Response, data?: T, message: string = 'Resource updated'): Response {\n return this.success(res, data, message, 200);\n }\n\n static deleted(res: Response, message: string = 'Resource deleted'): Response {\n return this.success(res, null, message, 200);\n }\n\n static error(\n res: Response,\n error: string,\n statusCode: number = 400,\n code?: string,\n details?: Record<string, unknown>\n ): Response {\n const response: ErrorResponse = {\n success: false,\n error,\n code,\n ...(details && { details }),\n };\n return res.status(statusCode).json(response);\n }\n\n static badRequest(res: Response, error: string = 'Bad request', code?: string): Response {\n return this.error(res, error, 400, code);\n }\n\n static unauthorized(res: Response, error: string = 'Unauthorized', code?: string): Response {\n return this.error(res, error, 401, code);\n }\n\n static forbidden(res: Response, error: string = 'Forbidden', code?: string): Response {\n return this.error(res, error, 403, code);\n }\n\n static notFound(res: Response, error: string = 'Resource not found', code?: string): Response {\n return this.error(res, error, 404, code);\n }\n\n static conflict(res: Response, error: string = 'Conflict', code?: string): Response {\n return this.error(res, error, 409, code);\n }\n\n static validationError(res: Response, error: string, details?: Record<string, unknown>): Response {\n return this.error(res, error, 422, 'VALIDATION_ERROR', details);\n }\n\n static internalError(res: Response, error: string = 'Internal server error'): Response {\n return this.error(res, error, 500, 'INTERNAL_ERROR');\n }\n\n static paginated<T>(\n res: Response,\n data: T[],\n page: number,\n limit: number,\n total: number\n ): Response<PaginatedResponse<T>> {\n const totalPages = Math.ceil(total / limit);\n const response: PaginatedResponse<T> = {\n success: true,\n data,\n meta: {\n page,\n limit,\n total,\n totalPages,\n },\n };\n return res.status(200).json(response);\n }\n\n static noContent(res: Response): Response {\n return res.status(204).send();\n }\n}\n\ndeclare global {\n namespace Express {\n interface Response {\n success<T>(data?: T, message?: string, statusCode?: number): Response;\n created<T>(data?: T, message?: string): Response;\n updated<T>(data?: T, message?: string): Response;\n deleted(message?: string): Response;\n error(error: string, statusCode?: number, code?: string, details?: Record<string, unknown>): Response;\n badRequest(error?: string, code?: string): Response;\n unauthorized(error?: string, code?: string): Response;\n forbidden(error?: string, code?: string): Response;\n notFound(error?: string, code?: string): Response;\n conflict(error?: string, code?: string): Response;\n validationError(error: string, details?: Record<string, unknown>): Response;\n internalError(error?: string): Response;\n paginated<T>(data: T[], page: number, limit: number, total: number): Response;\n }\n }\n}\n\nResponse.prototype.success = function <T>(data?: T, message?: string, statusCode: number = 200) {\n return ResponseHelper.success(this, data, message, statusCode);\n};\n\nResponse.prototype.created = function <T>(data?: T, message?: string) {\n return ResponseHelper.created(this, data, message);\n};\n\nResponse.prototype.updated = function <T>(data?: T, message?: string) {\n return ResponseHelper.updated(this, data, message);\n};\n\nResponse.prototype.deleted = function (message?: string) {\n return ResponseHelper.deleted(this, message);\n};\n\nResponse.prototype.error = function (error: string, statusCode: number = 400, code?: string, details?: Record<string, unknown>) {\n return ResponseHelper.error(this, error, statusCode, code, details);\n};\n\nResponse.prototype.badRequest = function (error?: string, code?: string) {\n return ResponseHelper.badRequest(this, error, code);\n};\n\nResponse.prototype.unauthorized = function (error?: string, code?: string) {\n return ResponseHelper.unauthorized(this, error, code);\n};\n\nResponse.prototype.forbidden = function (error?: string, code?: string) {\n return ResponseHelper.forbidden(this, error, code);\n};\n\nResponse.prototype.notFound = function (error?: string, code?: string) {\n return ResponseHelper.notFound(this, error, code);\n};\n\nResponse.prototype.conflict = function (error?: string, code?: string) {\n return ResponseHelper.conflict(this, error, code);\n};\n\nResponse.prototype.validationError = function (error: string, details?: Record<string, unknown>) {\n return ResponseHelper.validationError(this, error, details);\n};\n\nResponse.prototype.internalError = function (error?: string) {\n return ResponseHelper.internalError(this, error);\n};\n\nResponse.prototype.paginated = function <T>(data: T[], page: number, limit: number, total: number) {\n return ResponseHelper.paginated(this, data, page, limit, total);\n};\n\nexport const response = ResponseHelper;\nexport default ResponseHelper;\n"]}