saas-backend-kit 1.0.0 → 1.0.2

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 (58) hide show
  1. package/README.md +123 -344
  2. package/copy-dts.js +59 -0
  3. package/dist/auth/index.js +7 -2
  4. package/dist/auth/index.js.map +1 -1
  5. package/dist/auth/index.mjs +7 -2
  6. package/dist/auth/index.mjs.map +1 -1
  7. package/dist/config/index.js +6 -1
  8. package/dist/config/index.js.map +1 -1
  9. package/dist/config/index.mjs +6 -1
  10. package/dist/config/index.mjs.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +232 -41
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +231 -42
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/logger/index.js +6 -1
  17. package/dist/logger/index.js.map +1 -1
  18. package/dist/logger/index.mjs +6 -1
  19. package/dist/logger/index.mjs.map +1 -1
  20. package/dist/notifications/index.js +6 -1
  21. package/dist/notifications/index.js.map +1 -1
  22. package/dist/notifications/index.mjs +6 -1
  23. package/dist/notifications/index.mjs.map +1 -1
  24. package/dist/queue/index.js +6 -1
  25. package/dist/queue/index.js.map +1 -1
  26. package/dist/queue/index.mjs +6 -1
  27. package/dist/queue/index.mjs.map +1 -1
  28. package/dist/rate-limit/index.js +7 -1
  29. package/dist/rate-limit/index.js.map +1 -1
  30. package/dist/rate-limit/index.mjs +7 -1
  31. package/dist/rate-limit/index.mjs.map +1 -1
  32. package/dist/response/index.js +51 -40
  33. package/dist/response/index.js.map +1 -1
  34. package/dist/response/index.mjs +51 -40
  35. package/dist/response/index.mjs.map +1 -1
  36. package/dist/upload/index.d.ts +57 -0
  37. package/dist/upload/index.js +344 -0
  38. package/dist/upload/index.js.map +1 -0
  39. package/dist/upload/index.mjs +334 -0
  40. package/dist/upload/index.mjs.map +1 -0
  41. package/jest-output.json +72 -0
  42. package/jest.config.js +19 -0
  43. package/package.json +20 -8
  44. package/saas-banner.svg +239 -0
  45. package/src/auth/jwt.ts +1 -1
  46. package/src/config/index.ts +5 -0
  47. package/src/index.ts +2 -0
  48. package/src/rate-limit/express.ts +1 -0
  49. package/src/response/index.ts +49 -40
  50. package/src/upload/index.ts +268 -0
  51. package/tests/auth.test.ts +134 -0
  52. package/tests/config.test.ts +36 -0
  53. package/tests/logger.test.ts +47 -0
  54. package/tests/notifications.test.ts +19 -0
  55. package/tests/rate-limit.test.ts +50 -0
  56. package/tests/upload.test.ts +33 -0
  57. package/tsconfig.test.json +14 -0
  58. package/tsup.config.ts +2 -1
package/README.md CHANGED
@@ -1,376 +1,213 @@
1
- # SaaS Backend Kit
2
-
3
- <p align="center">
4
- <a href="https://www.npmjs.com/package/saas-backend-kit">
5
- <img src="https://img.shields.io/npm/v/saas-backend-kit.svg" alt="npm version">
6
- </a>
7
- <a href="https://www.npmjs.com/package/saas-backend-kit">
8
- <img src="https://img.shields.io/npm/dt/saas-backend-kit.svg" alt="npm downloads">
9
- </a>
10
- <a href="https://opensource.org/licenses/MIT">
11
- <img src="https://img.shields.io/npm/l/saas-backend-kit.svg" alt="MIT License">
12
- </a>
13
- <a href="https://github.com/yourusername/saas-backend-kit/actions">
14
- <img src="https://github.com/yourusername/saas-backend-kit/workflows/CI/badge.svg" alt="CI">
15
- </a>
16
- </p>
17
-
18
- > Production-grade modular backend toolkit for building scalable SaaS applications with Node.js
19
-
20
- ## Features
21
-
22
- - **Authentication Module** - JWT authentication, RBAC, Google OAuth
23
- - **Task Queue System** - Redis-based job queue (BullMQ)
24
- - **Notification Service** - Email, SMS (Twilio), Webhooks, Slack
25
- - **Logger** - Structured JSON logging with Pino
26
- - **Rate Limiting** - Configurable API rate limiting
27
- - **Config Manager** - Environment variable validation with Zod
28
- - **API Response Helpers** - Standardized response format
29
- - **Plugin Architecture** - Modular enable/disable features
30
-
31
- ## Installation
1
+ <div align="center">
2
+
3
+ <!-- ANIMATED PIPELINE BANNER -->
4
+ <img src="./saas-banner.svg" width="100%" alt="saas-backend-kit — Production-grade modular backend toolkit for Node.js, Express, Fastify"/>
5
+
6
+ <br/>
7
+
8
+ [![npm version](https://img.shields.io/npm/v/saas-backend-kit.svg?style=for-the-badge&logo=npm&logoColor=white&color=cb3837)](https://www.npmjs.com/package/saas-backend-kit)
9
+ [![npm downloads](https://img.shields.io/npm/dt/saas-backend-kit.svg?style=for-the-badge&logo=npm&logoColor=white&color=26d97f)](https://www.npmjs.com/package/saas-backend-kit)
10
+ [![License: MIT](https://img.shields.io/npm/l/saas-backend-kit.svg?style=for-the-badge&color=3178c6)](https://opensource.org/licenses/MIT)
11
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-3178c6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
12
+ [![Node.js](https://img.shields.io/badge/Node.js-18+-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## Features
19
+
20
+ | Module | Description | Powered By |
21
+ |--------|-------------|------------|
22
+ | 🔐 **Authentication** | JWT auth, RBAC, Google OAuth | jsonwebtoken, Passport |
23
+ | **Task Queue** | Redis-based background jobs | BullMQ |
24
+ | 🔔 **Notifications** | Email, SMS, Webhooks, Slack | Nodemailer, Twilio |
25
+ | ☁️ **File Upload** | Images, videos, docs to S3 | AWS SDK v3 |
26
+ | 📋 **Logger** | Structured JSON logging | Pino |
27
+ | 🛡️ **Rate Limiting** | Configurable API rate limiting | express-rate-limit |
28
+ | ⚙️ **Config Manager** | Env variable validation | Zod |
29
+ | 📦 **API Responses** | Standardized response format | Built-in |
30
+
31
+ ---
32
+
33
+ ## 📦 Installation
32
34
 
33
35
  ```bash
34
36
  npm install saas-backend-kit
35
37
  ```
36
38
 
37
- ## Quick Start
39
+ ---
40
+
41
+ ## 🚀 Quick Start
38
42
 
39
43
  ```typescript
40
44
  import express from 'express';
41
- import { auth, rateLimit, logger, config, queue, notify, response, createApp } from 'saas-backend-kit';
45
+ import { auth, rateLimit, logger, config } from 'saas-backend-kit';
42
46
 
43
47
  config.load();
44
48
 
45
49
  const app = express();
46
50
  app.use(express.json());
47
51
 
48
- // Initialize auth
49
- const authMiddleware = auth.initialize({
50
- jwtSecret: process.env.JWT_SECRET,
51
- jwtExpiresIn: '7d',
52
- });
53
- app.use(authMiddleware);
54
-
55
- // Apply rate limiting
52
+ app.use(auth.initialize({ jwtSecret: 'your-secret-key' }));
56
53
  app.use(rateLimit({ window: '1m', limit: 100 }));
57
54
 
58
- // Protected route
59
55
  app.get('/dashboard', auth.requireUser(), (req, res) => {
60
- res.success({ message: 'Welcome to your dashboard', user: req.user });
56
+ res.success({ message: 'Welcome!', user: req.user });
61
57
  });
62
58
 
63
59
  app.listen(3000, () => logger.info('Server running'));
64
60
  ```
65
61
 
66
- ## Modules
62
+ ---
67
63
 
68
- ### Authentication
64
+ ## 🔐 Authentication
69
65
 
70
66
  ```typescript
71
- import { auth } from 'saas-backend-kit';
72
-
73
- const authMiddleware = auth.initialize({
67
+ app.use(auth.initialize({
74
68
  jwtSecret: 'your-secret-key',
75
- jwtExpiresIn: '7d',
76
- refreshExpiresIn: '30d',
77
- });
78
-
79
- app.use(authMiddleware);
80
-
81
- // Registration
82
- app.post('/auth/register', async (req, res) => {
83
- const { email, password, name } = req.body;
84
- const result = await auth().register({ email, password, name });
85
- res.success(result.tokens, 'Registration successful');
86
- });
87
-
88
- // Login
89
- app.post('/auth/login', async (req, res) => {
90
- const { email, password } = req.body;
91
- const result = await auth().login({ email, password });
92
- res.success(result.tokens, 'Login successful');
93
- });
94
-
95
- // Route protection
96
- app.get('/dashboard', auth.requireUser(), (req, res) => {
97
- res.success({ user: req.user });
98
- });
99
-
100
- app.get('/admin', auth.requireRole('admin'), (req, res) => {
101
- res.success({ message: 'Admin area' });
102
- });
103
-
104
- app.get('/protected', auth.requirePermission('read'), (req, res) => {
105
- res.success({ message: 'Access granted' });
106
- });
107
- ```
108
-
109
- ### Role-Based Access Control (RBAC)
110
-
111
- ```typescript
112
- import { rbacService } from 'saas-backend-kit/auth';
69
+ jwtExpiresIn: '7d'
70
+ }));
113
71
 
114
- rbacService.setPermissions({
115
- admin: ['*'],
116
- manager: ['read', 'write', 'delete:own'],
117
- user: ['read', 'write:own'],
118
- guest: ['read:public'],
119
- });
72
+ await auth().register({ email, password, name });
73
+ await auth().login({ email, password });
120
74
 
121
- // Check permissions
122
- if (rbacService.hasPermission(user.role, 'write:own')) {
123
- // Allow action
124
- }
75
+ auth.requireUser();
76
+ auth.requireRole('admin');
77
+ auth.requirePermission('read');
125
78
  ```
126
79
 
127
- ### Google OAuth
128
-
129
- ```typescript
130
- // Get Google auth URL
131
- app.get('/auth/google', async (req, res) => {
132
- const url = await auth().getGoogleAuthUrl();
133
- res.redirect(url);
134
- });
135
-
136
- // Handle callback
137
- app.get('/auth/google/callback', async (req, res) => {
138
- const { code } = req.query;
139
- const result = await auth().handleGoogleCallback(code as string);
140
- res.success(result.tokens);
141
- });
142
- ```
80
+ ---
143
81
 
144
- ### Task Queue
82
+ ## Task Queue
145
83
 
146
84
  ```typescript
147
85
  import { queue } from 'saas-backend-kit';
148
86
 
149
- // Create a queue
150
- const emailQueue = queue.create('email', {
151
- defaultJobOptions: {
152
- attempts: 3,
153
- backoff: { type: 'exponential', delay: 1000 },
154
- },
155
- });
156
-
157
- // Add jobs
158
- await emailQueue.add('sendWelcomeEmail', { userId: '123', email: 'user@example.com' });
159
-
160
- // Delayed job
161
- await emailQueue.add('sendReminder', { userId: '123' }, { delay: 3600000 });
87
+ const emailQueue = queue.create('email');
88
+ await emailQueue.add('sendEmail', { to: 'user@example.com' });
162
89
 
163
- // Process jobs
164
90
  queue.process('email', async (job) => {
165
- logger.info(`Processing ${job.name}`, { jobId: job.id });
166
- await notify.email({
167
- to: job.data.email,
168
- subject: 'Welcome!',
169
- template: 'welcome',
170
- templateData: { name: 'User' },
171
- });
172
- return { sent: true };
91
+ await notify.email({ to: job.data.to, subject: 'Hello' });
173
92
  }, { concurrency: 5 });
174
93
  ```
175
94
 
176
- ### Notifications
95
+ ---
96
+
97
+ ## 🔔 Notifications
177
98
 
178
99
  ```typescript
179
100
  import { notify } from 'saas-backend-kit';
180
101
 
181
- // Email
182
- await notify.email({
183
- to: 'user@example.com',
184
- subject: 'Welcome',
185
- template: 'welcome',
186
- templateData: { name: 'John', appName: 'MyApp' },
187
- });
102
+ await notify.email({ to: 'user@example.com', subject: 'Welcome' });
103
+ await notify.sms({ to: '+1234567890', message: 'Your code is 123456' });
104
+ await notify.slack({ text: 'New user registered!' });
105
+ ```
188
106
 
189
- // SMS
190
- await notify.sms({
191
- to: '+1234567890',
192
- message: 'Your verification code is 123456',
193
- });
107
+ ---
194
108
 
195
- // Webhook
196
- await notify.webhook({
197
- url: 'https://api.example.com/webhook',
198
- method: 'POST',
199
- body: { event: 'user.created', data: { id: '123' } },
200
- });
109
+ ## ☁️ File Upload (S3)
201
110
 
202
- // Slack
203
- await notify.slack({
204
- text: 'New user registered!',
205
- blocks: [
206
- {
207
- type: 'section',
208
- text: { type: 'mrkdwn', text: 'New user registered: *john@example.com*' }
209
- }
210
- ]
111
+ ```typescript
112
+ import { upload } from 'saas-backend-kit';
113
+
114
+ upload.initialize({
115
+ region: 'us-east-1',
116
+ accessKeyId: 'your-access-key',
117
+ secretAccessKey: 'your-secret-key',
118
+ bucket: 'your-bucket-name'
211
119
  });
120
+
121
+ const result = await upload.file(fileBuffer, { key: 'documents/file.pdf' });
122
+ const image = await upload.image(fileBuffer, 'photo.jpg');
123
+ const video = await upload.video(fileBuffer, 'video.mp4');
124
+ const signedUrl = await upload.getSignedUrl('path/to/file');
125
+
126
+ await upload.delete('path/to/file');
212
127
  ```
213
128
 
214
- ### Logger
129
+ ---
130
+
131
+ ## 📋 Logger
215
132
 
216
133
  ```typescript
217
134
  import { logger } from 'saas-backend-kit';
218
135
 
219
136
  logger.info('Server started', { port: 3000 });
220
- logger.error('Connection failed', { error: err.message });
221
- logger.warn('Rate limit approaching', { ip: req.ip });
137
+ logger.error('Failed', { error: err.message });
222
138
 
223
- // Child logger
224
- const childLogger = logger.child({ module: 'auth' });
225
- childLogger.info('User logged in', { userId: '123' });
139
+ const child = logger.child({ module: 'auth' });
140
+ child.info('User logged in');
226
141
  ```
227
142
 
228
- ### Rate Limiting
229
-
230
- ```typescript
231
- import { rateLimit } from 'saas-backend-kit';
232
-
233
- // Global rate limit
234
- app.use(rateLimit({
235
- window: '1m',
236
- limit: 100,
237
- }));
143
+ ---
238
144
 
239
- // Per-route rate limit
240
- app.get('/api/expensive', rateLimit({ window: '1m', limit: 10 }), (req, res) => {
241
- res.success({ data: 'expensive operation' });
242
- });
145
+ ## 🛡️ Rate Limiting
243
146
 
244
- // Custom key generator
245
- app.use(rateLimit({
246
- window: '1m',
247
- limit: 100,
248
- keyGenerator: (req) => req.user?.id || req.ip,
249
- }));
147
+ ```typescript
148
+ app.use(rateLimit({ window: '1m', limit: 100 }));
149
+ app.use(rateLimit({ window: '1m', limit: 10, keyGenerator: (req) => req.user?.id }));
250
150
  ```
251
151
 
252
- ### Config Manager
152
+ ---
253
153
 
254
- ```typescript
255
- import { config } from 'saas-backend-kit';
154
+ ## ⚙️ Config
256
155
 
257
- // Load and validate env vars
156
+ ```typescript
258
157
  config.load();
259
-
260
- // Get values
261
- const port = config.int('PORT');
158
+ const port = config.int('PORT');
262
159
  const isProduction = config.isProduction();
263
- const dbUrl = config.get('DATABASE_URL');
264
-
265
- // Custom schema
266
- const customConfig = config.create({
267
- schema: z.object({
268
- API_KEY: z.string(),
269
- MAX_CONNECTIONS: z.number().default(100),
270
- }),
271
- validate: true,
272
- });
273
160
  ```
274
161
 
275
- ### API Response Helpers
276
-
277
- ```typescript
278
- // Success responses
279
- res.success({ user }, 'User found');
280
- res.created({ id: '123' }, 'User created');
281
- res.updated(user, 'User updated');
282
- res.deleted Paginated response('User deleted');
283
-
284
- //
285
- res.pag, limit, total);
286
-
287
- // Error responses
288
- inated(users, pageres.badInvalid inputauthorized('Please');
289
- res.unRequest(' login');
290
- res.forbidden('Access denied');
291
- res.notFound('User not found');
292
- res failed', { fields.validationError('Validation: errors('Something });
293
- res.internalError went wrong');
294
- ```
162
+ ---
295
163
 
296
- ### Plugin Architecture
164
+ ## 📦 API Responses
297
165
 
298
166
  ```typescript
299
- import { createApp, Plugin } from 'saas-backend-kit';
300
-
301
- const myPlugin: Plugin = {
302
- name: 'my-plugin',
303
- initialize: (app) => {
304
- console.log('Plugin initialized');
305
- },
306
- };
307
-
308
- const app = createApp({
309
- auth: true,
310
- queue: { redisUrl: 'redis://localhost:6379' },
311
- notifications: true,
312
- rateLimit: { window: '1m', limit: 100 },
313
- })
314
- .use(myPlugin);
315
-
316
- await app.initialize(expressApp);
167
+ res.success({ user });
168
+ res.created(user, 'Created');
169
+ res.paginated(users, page, limit, total);
170
+ res.error('Error message');
317
171
  ```
318
172
 
319
- ## Framework Support
320
-
321
- ### Express
322
-
323
- All examples above use Express. The library automatically extends the Response object with helper methods.
324
-
325
- ### Fastify
326
-
327
- ```typescript
328
- import Fastify from 'fastify';
329
- import { registerAuthPlugin, registerRateLimitPlugin, auth } from 'saas-backend-kit';
330
-
331
- const fastify = Fastify();
332
-
333
- fastify.register(registerAuthPlugin, { authService: auth() });
334
- fastify.register(registerRateLimitPlugin, { window: '1m', limit: 100 });
335
-
336
- fastify.get('/dashboard', { preHandler: [fastify.authenticate] }, async (request, reply) => {
337
- return { user: request.user };
338
- });
339
- ```
173
+ ---
340
174
 
341
- ## Environment Variables
175
+ ## 🔧 Environment Variables
342
176
 
343
177
  ```env
344
178
  NODE_ENV=development
345
179
  PORT=3000
346
180
 
347
181
  # JWT
348
- JWT_SECRET=your-secret-key-min-32-chars
182
+ JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
349
183
  JWT_EXPIRES_IN=7d
350
- JWT_REFRESH_SECRET=your-refresh-secret
184
+ JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-in-production
351
185
  JWT_REFRESH_EXPIRES_IN=30d
352
186
 
353
187
  # Redis
354
188
  REDIS_URL=redis://localhost:6379
355
189
 
356
- # Google OAuth
190
+ # Database (optional)
191
+ DATABASE_URL=postgresql://user:password@localhost:5432/mydb
192
+
193
+ # Google OAuth (optional)
357
194
  GOOGLE_CLIENT_ID=
358
195
  GOOGLE_CLIENT_SECRET=
359
196
  GOOGLE_REDIRECT_URI=http://localhost:3000/auth/google/callback
360
197
 
361
- # SMTP
198
+ # Email (SMTP) (optional)
362
199
  SMTP_HOST=smtp.example.com
363
200
  SMTP_PORT=587
364
- SMTP_USER=
365
- SMTP_PASS=
366
- SMTP_FROM=noreply@domain.com
201
+ SMTP_USER=your-smtp-user
202
+ SMTP_PASS=your-smtp-password
203
+ SMTP_FROM=noreply@yourdomain.com
367
204
 
368
- # Twilio
205
+ # Twilio SMS (optional)
369
206
  TWILIO_ACCOUNT_SID=
370
207
  TWILIO_AUTH_TOKEN=
371
208
  TWILIO_PHONE_NUMBER=
372
209
 
373
- # Slack
210
+ # Slack (optional)
374
211
  SLACK_WEBHOOK_URL=
375
212
 
376
213
  # Rate Limiting
@@ -379,81 +216,23 @@ RATE_LIMIT_LIMIT=100
379
216
 
380
217
  # Logger
381
218
  LOG_LEVEL=info
382
- ```
383
-
384
- ## Project Structure
385
-
386
- ```
387
- saas-backend-kit/
388
- ├── src/
389
- │ ├── auth/ # Authentication module
390
- │ │ ├── types.ts
391
- │ │ ├── jwt.ts
392
- │ │ ├── rbac.ts
393
- │ │ ├── oauth.ts
394
- │ │ ├── express.ts
395
- │ │ ├── fastify.ts
396
- │ │ └── index.ts
397
- │ ├── queue/ # Task queue (BullMQ)
398
- │ ├── notifications/ # Email, SMS, Webhooks, Slack
399
- │ ├── logger/ # Pino logger
400
- │ ├── rate-limit/ # Rate limiting
401
- │ ├── config/ # Config manager
402
- │ ├── response/ # Response helpers
403
- │ ├── utils/ # Utilities
404
- │ ├── plugin.ts # Plugin architecture
405
- │ └── index.ts # Main exports
406
- ├── examples/
407
- │ └── express/
408
- ├── package.json
409
- ├── tsconfig.json
410
- └── tsup.config.ts
411
- ```
412
-
413
- ## TypeScript
414
-
415
- This library is written in TypeScript and provides full type definitions out of the box.
416
-
417
- ## Tree Shaking
418
-
419
- All modules are exported separately for optimal tree shaking:
420
219
 
421
- ```typescript
422
- import { auth } from 'saas-backend-kit/auth';
423
- import { queue } from 'saas-backend-kit/queue';
424
- import { logger } from 'saas-backend-kit/logger';
425
- ```
426
-
427
- ## Testing
428
-
429
- ```bash
430
- npm test
431
- npm run test:watch
432
- ```
433
-
434
- ## Linting
435
-
436
- ```bash
437
- npm run lint
438
- npm run typecheck
439
220
  ```
440
221
 
441
- ## Building
222
+ ---
442
223
 
443
- ```bash
444
- npm run build
445
- ```
224
+ ## 🤝 Contributing
446
225
 
447
- ## License
226
+ Contributions, issues, and feature requests are welcome! Feel free to open a PR or issue.
448
227
 
449
- MIT License - see [LICENSE](LICENSE) for details.
228
+ ---
450
229
 
451
- ## Contributing
230
+ <div align="center">
452
231
 
453
- Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) first.
232
+ **Built with ❤️ by [Ashish Kumar Maurya](https://github.com/AshishK-M)**
233
+ Senior Full-Stack Developer · Dubai, UAE
234
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-0A66C2?style=flat-square&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/ashish-kumar-maurya-fullstack/)
454
235
 
455
- ---
236
+ <sub>saas-backend-kit · MIT License · Node.js · Express · Fastify · TypeScript · BullMQ · AWS S3 · Pino · Zod</sub>
456
237
 
457
- Built with ❤️ for the SaaS community
458
- # saas-backend-kit
459
-
238
+ </div>
package/copy-dts.js CHANGED
@@ -214,6 +214,64 @@ export declare class ResponseHelper {
214
214
  }
215
215
 
216
216
  export declare const response: typeof ResponseHelper;
217
+ `,
218
+ 'upload/index.d.ts': `export interface S3Config {
219
+ region?: string;
220
+ accessKeyId?: string;
221
+ secretAccessKey?: string;
222
+ bucket: string;
223
+ endpoint?: string;
224
+ forcePathStyle?: boolean;
225
+ }
226
+
227
+ export interface UploadOptions {
228
+ key?: string;
229
+ contentType?: string;
230
+ expiresIn?: number;
231
+ metadata?: Record<string, string>;
232
+ }
233
+
234
+ export interface UploadResult {
235
+ key: string;
236
+ url: string;
237
+ bucket: string;
238
+ contentType?: string;
239
+ size?: number;
240
+ }
241
+
242
+ export interface SignedUrlOptions {
243
+ expiresIn?: number;
244
+ }
245
+
246
+ export interface FileObject {
247
+ key: string;
248
+ lastModified?: Date;
249
+ size?: number;
250
+ contentType?: string;
251
+ }
252
+
253
+ export declare const upload: {
254
+ initialize: (config: S3Config) => void;
255
+ file: (file: Buffer | Uint8Array | string, options?: UploadOptions) => Promise<UploadResult>;
256
+ image: (file: Buffer | Uint8Array | string, filename: string, options?: UploadOptions) => Promise<UploadResult>;
257
+ video: (file: Buffer | Uint8Array | string, filename: string, options?: UploadOptions) => Promise<UploadResult>;
258
+ delete: (key: string) => Promise<void>;
259
+ getSignedUrl: (key: string, options?: SignedUrlOptions) => Promise<string>;
260
+ getPublicUrl: (key: string) => Promise<string>;
261
+ listFiles: (prefix?: string, maxKeys?: number) => Promise<FileObject[]>;
262
+ };
263
+
264
+ export declare class S3Service {
265
+ initialize(config: S3Config): void;
266
+ isInitialized(): boolean;
267
+ upload(file: Buffer | Uint8Array | string, options?: UploadOptions): Promise<UploadResult>;
268
+ uploadImage(file: Buffer | Uint8Array | string, filename: string, options?: UploadOptions): Promise<UploadResult>;
269
+ uploadVideo(file: Buffer | Uint8Array | string, filename: string, options?: UploadOptions): Promise<UploadResult>;
270
+ delete(key: string): Promise<void>;
271
+ getSignedUrl(key: string, options?: SignedUrlOptions): Promise<string>;
272
+ getPublicUrl(key: string): Promise<string>;
273
+ listFiles(prefix?: string, maxKeys?: number): Promise<FileObject[]>;
274
+ }
217
275
  `,
218
276
  'index.d.ts': `export * from './auth';
219
277
  export * from './queue';
@@ -222,6 +280,7 @@ export * from './logger';
222
280
  export * from './rate-limit';
223
281
  export * from './config';
224
282
  export * from './response';
283
+ export * from './upload';
225
284
 
226
285
  export interface AppOptions {
227
286
  framework?: 'express' | 'fastify';
@@ -130,7 +130,12 @@ var envSchema = zod.z.object({
130
130
  SLACK_WEBHOOK_URL: zod.z.string().optional(),
131
131
  RATE_LIMIT_WINDOW: zod.z.string().default("1m"),
132
132
  RATE_LIMIT_LIMIT: zod.z.string().default("100"),
133
- LOG_LEVEL: zod.z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info")
133
+ LOG_LEVEL: zod.z.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info"),
134
+ AWS_REGION: zod.z.string().default("us-east-1"),
135
+ AWS_ACCESS_KEY_ID: zod.z.string().optional(),
136
+ AWS_SECRET_ACCESS_KEY: zod.z.string().optional(),
137
+ AWS_S3_BUCKET: zod.z.string().optional(),
138
+ AWS_ENDPOINT: zod.z.string().optional()
134
139
  });
135
140
  var ConfigManager = class {
136
141
  config = null;
@@ -231,7 +236,7 @@ var JWTService = class {
231
236
  return jwt__default.default.verify(token, this.refreshSecret);
232
237
  }
233
238
  refreshTokens(refreshToken) {
234
- const payload = this.verifyRefreshToken(refreshToken);
239
+ const { iat, exp, nbf, ...payload } = this.verifyRefreshToken(refreshToken);
235
240
  return this.generateTokenPair(payload);
236
241
  }
237
242
  };