saas-backend-kit 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
 
14
14
  </div>
15
15
 
16
+ **Drop-in Node.js/Express starter with JWT auth, rate limiting, Redis caching, and multi-tenant support — built for SaaS products.**
17
+
16
18
  ---
17
19
 
18
20
  ## ✨ Features
package/package.json CHANGED
@@ -1,7 +1,17 @@
1
1
  {
2
2
  "name": "saas-backend-kit",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Production-grade modular backend toolkit for building scalable SaaS applications",
5
+ "author": "Ashish Kumar Maurya",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/AshishK-M/saas-backend-kit"
9
+ },
10
+ "homepage": "https://github.com/AshishK-M/saas-backend-kit#readme",
11
+ "files": ["dist"],
12
+ "engines": {
13
+ "node": ">=18.0.0"
14
+ },
5
15
  "main": "dist/index.js",
6
16
  "module": "dist/index.mjs",
7
17
  "types": "dist/index.d.ts",
@@ -64,8 +74,10 @@
64
74
  "keywords": [
65
75
  "saas",
66
76
  "backend",
77
+ "nodejs",
67
78
  "express",
68
79
  "fastify",
80
+ "typescript",
69
81
  "auth",
70
82
  "jwt",
71
83
  "redis",
@@ -74,9 +86,11 @@
74
86
  "rate-limit",
75
87
  "s3",
76
88
  "upload",
77
- "aws"
89
+ "aws",
90
+ "boilerplate",
91
+ "starter",
92
+ "api"
78
93
  ],
79
- "author": "",
80
94
  "license": "MIT",
81
95
  "dependencies": {
82
96
  "@aws-sdk/client-s3": "^3.490.0",
package/CHANGELOG.md DELETED
@@ -1,31 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [1.0.0] - 2024-01-01
9
-
10
- ### Added
11
- - Authentication module with JWT support
12
- - Role-Based Access Control (RBAC)
13
- - Google OAuth integration
14
- - Task Queue System based on BullMQ
15
- - Notification Service (Email, SMS, Webhooks, Slack)
16
- - Structured Logger using Pino
17
- - Rate Limiting middleware
18
- - Config Manager with Zod validation
19
- - API Response Helpers
20
- - Plugin Architecture
21
- - Full TypeScript support
22
- - Tree-shakeable modules
23
- - Express and Fastify support
24
-
25
- ## [1.0.0-beta.1] - 2024-12-01
26
-
27
- ### Added
28
- - Initial beta release
29
- - Core authentication features
30
- - Basic queue implementation
31
- - Email notifications
package/PUBLISHING.md DELETED
@@ -1,133 +0,0 @@
1
- # npm Publishing Instructions
2
-
3
- ## Prerequisites
4
-
5
- 1. Node.js 18+ installed
6
- 2. npm account (https://www.npmjs.com)
7
- 3. Git repository initialized
8
-
9
- ## Preparation
10
-
11
- 1. Update `package.json`:
12
- - Update `version` (follow semver)
13
- - Update `author` field
14
- - Update `repository` field
15
- - Update `keywords`
16
-
17
- 2. Build the package:
18
- ```bash
19
- npm install
20
- npm run build
21
- ```
22
-
23
- 3. Test locally:
24
- ```bash
25
- npm link
26
- # In a test project
27
- npm link saas-backend-kit
28
- ```
29
-
30
- ## Publishing
31
-
32
- ### Option 1: Publish to npm (public)
33
-
34
- ```bash
35
- npm login
36
- npm publish --access public
37
- ```
38
-
39
- ### Option 2: Publish to npm (private - paid plan)
40
-
41
- ```bash
42
- npm login
43
- npm publish
44
- ```
45
-
46
- ### Option 3: Publish to GitHub Package Registry
47
-
48
- Add to `.npmrc`:
49
- ```
50
- @yourusername:registry=https://npm.pkg.github.com
51
- ```
52
-
53
- ```bash
54
- npm login --registry=https://npm.pkg.github.com
55
- npm publish
56
- ```
57
-
58
- ## Version Management
59
-
60
- Use semantic versioning:
61
-
62
- ```bash
63
- # Patch release
64
- npm version patch
65
-
66
- # Minor release
67
- npm version minor
68
-
69
- # Major release
70
- npm version major
71
- ```
72
-
73
- This will:
74
- 1. Update version in package.json
75
- 2. Create a git tag
76
- 3. Commit changes
77
-
78
- Then publish:
79
- ```bash
80
- git push && git push --tags
81
- npm publish
82
- ```
83
-
84
- ## After Publishing
85
-
86
- 1. Create a GitHub release with the new version tag
87
- 2. Update CHANGELOG.md
88
- 3. Announce on social media
89
-
90
- ## Automation with GitHub Actions
91
-
92
- Create `.github/workflows/publish.yml`:
93
-
94
- ```yaml
95
- name: Publish to npm
96
-
97
- on:
98
- release:
99
- types: [created]
100
-
101
- jobs:
102
- publish:
103
- runs-on: ubuntu-latest
104
- steps:
105
- - uses: actions/checkout@v4
106
-
107
- - uses: actions/setup-node@v4
108
- with:
109
- node-version: '20'
110
- registry-url: 'https://registry.npmjs.org'
111
-
112
- - run: npm ci
113
- - run: npm run build
114
- - run: npm test
115
-
116
- - run: npm publish --access public
117
- env:
118
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
119
- ```
120
-
121
- ## Troubleshooting
122
-
123
- ### Error: "You do not have permission to publish"
124
-
125
- - Make sure you're logged in to the correct npm account
126
- - Check if the package name is available
127
- - Verify your npm account has publishing rights for scoped packages
128
-
129
- ### Error: "Token not recognized"
130
-
131
- - Regenerate your npm token
132
- - Ensure the token has publish permissions
133
- - Check your `.npmrc` file for correct configuration
package/copy-dts.js DELETED
@@ -1,314 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const typeDefs = {
5
- 'auth/index.d.ts': `import { RequestHandler } from 'express';
6
-
7
- export type Role = string;
8
- export type Permission = string;
9
-
10
- export interface User {
11
- id: string;
12
- email: string;
13
- password?: string;
14
- role: Role;
15
- name?: string;
16
- picture?: string;
17
- }
18
-
19
- export interface JWTPayload {
20
- userId: string;
21
- email: string;
22
- role: Role;
23
- }
24
-
25
- export interface TokenPair {
26
- accessToken: string;
27
- refreshToken: string;
28
- }
29
-
30
- export interface AuthOptions {
31
- jwtSecret?: string;
32
- jwtExpiresIn?: string;
33
- refreshSecret?: string;
34
- refreshExpiresIn?: string;
35
- }
36
-
37
- export interface LoginCredentials {
38
- email: string;
39
- password: string;
40
- }
41
-
42
- export interface RegisterData extends LoginCredentials {
43
- name?: string;
44
- role?: Role;
45
- }
46
-
47
- export declare class AuthService {
48
- initialize(): Promise<void>;
49
- register(data: RegisterData): Promise<{ user: User; tokens: TokenPair }>;
50
- login(credentials: LoginCredentials): Promise<{ user: User; tokens: TokenPair }>;
51
- refresh(refreshToken: string): Promise<TokenPair>;
52
- getGoogleAuthUrl(state?: string): Promise<string>;
53
- handleGoogleCallback(code: string): Promise<{ user: User; tokens: TokenPair }>;
54
- getMiddleware(): RequestHandler;
55
- requireUser(): RequestHandler;
56
- requireRole(role: string): RequestHandler;
57
- requirePermission(permission: string): RequestHandler;
58
- }
59
-
60
- export declare function createAuth(options?: AuthOptions): AuthService;
61
- export declare function auth(): AuthService;
62
- export declare const Auth: { initialize: (options?: AuthOptions) => any };
63
- `,
64
- 'queue/index.d.ts': `export interface QueueOptions {
65
- name: string;
66
- defaultJobOptions?: any;
67
- }
68
-
69
- export interface JobData {
70
- [key: string]: unknown;
71
- }
72
-
73
- export type JobProcessor = (job: any) => Promise<unknown>;
74
-
75
- export interface Queue {
76
- add(name: string, data: JobData, opts?: any): Promise<any>;
77
- addBulk(jobs: any[]): Promise<any[]>;
78
- getJobCounts(): Promise<any>;
79
- getJobs(statuses: string[], start?: number, end?: number): Promise<any[]>;
80
- close(): Promise<void>;
81
- }
82
-
83
- export declare const createQueue: (name: string, options?: Partial<QueueOptions>) => Queue;
84
- export declare const addJob: (queueName: string, jobName: string, data: JobData, options?: any) => Promise<any>;
85
- export declare const processJob: (queueName: string, processor: JobProcessor, options?: any) => any;
86
- export declare const queue: {
87
- create: typeof createQueue;
88
- add: typeof addJob;
89
- process: typeof processJob;
90
- get: (name: string) => Queue | undefined;
91
- getJobCounts: (name: string) => Promise<any>;
92
- getJobs: (name: string, start?: number, end?: number) => Promise<any[]>;
93
- close: (name: string) => Promise<void>;
94
- closeAll: () => Promise<void>;
95
- setRedisOptions: (options: any) => void;
96
- };
97
- `,
98
- 'notifications/index.d.ts': `export interface EmailOptions {
99
- to: string | string[];
100
- subject: string;
101
- text?: string;
102
- html?: string;
103
- template?: string;
104
- templateData?: Record<string, unknown>;
105
- from?: string;
106
- }
107
-
108
- export interface SMSOptions {
109
- to: string;
110
- message: string;
111
- from?: string;
112
- }
113
-
114
- export interface WebhookOptions {
115
- url: string;
116
- method?: 'GET' | 'POST' | 'PUT' | 'PATCH';
117
- headers?: Record<string, string>;
118
- body?: unknown;
119
- timeout?: number;
120
- }
121
-
122
- export interface SlackOptions {
123
- text?: string;
124
- blocks?: any[];
125
- }
126
-
127
- export declare const notify: {
128
- email: (options: EmailOptions) => Promise<{ messageId: string }>;
129
- sms: (options: SMSOptions) => Promise<{ sid: string }>;
130
- webhook: (options: WebhookOptions) => Promise<{ status: number; body: unknown }>;
131
- slack: (options: SlackOptions) => Promise<{ ok: boolean }>;
132
- };
133
- `,
134
- 'logger/index.d.ts': `export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
135
-
136
- export interface LoggerConfig {
137
- level?: LogLevel;
138
- name?: string;
139
- }
140
-
141
- export interface Logger {
142
- info(message: string, ...args: any[]): void;
143
- warn(message: string, ...args: any[]): void;
144
- error(message: string, ...args: any[]): void;
145
- debug(message: string, ...args: any[]): void;
146
- trace(message: string, ...args: any[]): void;
147
- fatal(message: string, ...args: any[]): void;
148
- child(bindings: any, options?: { name?: string }): Logger;
149
- }
150
-
151
- export declare const logger: Logger;
152
- `,
153
- 'rate-limit/index.d.ts': `import { Request, Response } from 'express';
154
-
155
- export interface RateLimitOptions {
156
- window?: string;
157
- limit?: number;
158
- keyGenerator?: (req: Request) => string;
159
- handler?: (req: Request, res: Response) => void;
160
- skip?: (req: Request) => boolean;
161
- }
162
-
163
- export declare function rateLimit(options?: RateLimitOptions): (req: Request, res: Response, next: any) => void;
164
- `,
165
- 'config/index.d.ts': `export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
166
-
167
- export interface EnvConfig {
168
- NODE_ENV: 'development' | 'production' | 'test';
169
- PORT: string;
170
- DATABASE_URL?: string;
171
- REDIS_URL: string;
172
- JWT_SECRET?: string;
173
- JWT_EXPIRES_IN?: string;
174
- [key: string]: any;
175
- }
176
-
177
- export declare const config: {
178
- load: () => EnvConfig;
179
- get: <K extends keyof EnvConfig>(key: K) => EnvConfig[K];
180
- int: (key: keyof EnvConfig) => number;
181
- bool: (key: keyof EnvConfig) => boolean;
182
- isProduction: () => boolean;
183
- isDevelopment: () => boolean;
184
- isTest: () => boolean;
185
- getAll: () => EnvConfig;
186
- };
187
- `,
188
- 'response/index.d.ts': `import { Response } from 'express';
189
-
190
- export interface ApiResponse<T = any> {
191
- success: boolean;
192
- data?: T;
193
- error?: string;
194
- message?: string;
195
- }
196
-
197
- export interface PaginatedResponse<T> extends ApiResponse<T> {
198
- meta: { page: number; limit: number; total: number; totalPages: number };
199
- }
200
-
201
- export declare class ResponseHelper {
202
- static success<T>(res: Response, data?: T, message?: string, statusCode?: number): Response;
203
- static created<T>(res: Response, data?: T, message?: string): Response;
204
- static updated<T>(res: Response, data?: T, message?: string): Response;
205
- static deleted(res: Response, message?: string): Response;
206
- static error(res: Response, error: string, statusCode?: number): Response;
207
- static badRequest(res: Response, error?: string): Response;
208
- static unauthorized(res: Response, error?: string): Response;
209
- static forbidden(res: Response, error?: string): Response;
210
- static notFound(res: Response, error?: string): Response;
211
- static validationError(res: Response, error: string): Response;
212
- static internalError(res: Response, error?: string): Response;
213
- static paginated<T>(res: Response, data: T[], page: number, limit: number, total: number): Response;
214
- }
215
-
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
- }
275
- `,
276
- 'index.d.ts': `export * from './auth';
277
- export * from './queue';
278
- export * from './notifications';
279
- export * from './logger';
280
- export * from './rate-limit';
281
- export * from './config';
282
- export * from './response';
283
- export * from './upload';
284
-
285
- export interface AppOptions {
286
- framework?: 'express' | 'fastify';
287
- auth?: boolean | any;
288
- queue?: boolean | { redisUrl?: string };
289
- notifications?: boolean;
290
- rateLimit?: boolean | any;
291
- logger?: boolean | any;
292
- config?: boolean;
293
- }
294
-
295
- export interface Plugin {
296
- name: string;
297
- initialize: (app: any) => Promise<void> | void;
298
- }
299
-
300
- export declare function createApp(options?: AppOptions): any;
301
- export declare function createExpressApp(options?: AppOptions): any;
302
- `
303
- };
304
-
305
- for (const [filePath, content] of Object.entries(typeDefs)) {
306
- const fullPath = path.join('dist', filePath);
307
- const dir = path.dirname(fullPath);
308
- if (!fs.existsSync(dir)) {
309
- fs.mkdirSync(dir, { recursive: true });
310
- }
311
- fs.writeFileSync(fullPath, content);
312
- }
313
-
314
- console.log('Type definitions written successfully');
@@ -1,44 +0,0 @@
1
- NODE_ENV=development
2
- PORT=3000
3
-
4
- # JWT
5
- JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
6
- JWT_EXPIRES_IN=7d
7
- JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-in-production
8
- JWT_REFRESH_EXPIRES_IN=30d
9
-
10
- # Redis
11
- REDIS_URL=redis://localhost:6379
12
-
13
- # Database (PostgreSQL)
14
- DATABASE_URL=postgresql://user:password@localhost:5432/mydb
15
-
16
- # Database (MongoDB)
17
- MONGODB_URL=mongodb://user:password@localhost:27017/mydb
18
-
19
- # Google OAuth (optional)
20
- GOOGLE_CLIENT_ID=
21
- GOOGLE_CLIENT_SECRET=
22
- GOOGLE_REDIRECT_URI=http://localhost:3000/auth/google/callback
23
-
24
- # Email (SMTP) (optional)
25
- SMTP_HOST=smtp.example.com
26
- SMTP_PORT=587
27
- SMTP_USER=your-smtp-user
28
- SMTP_PASS=your-smtp-password
29
- SMTP_FROM=noreply@yourdomain.com
30
-
31
- # Twilio SMS (optional)
32
- TWILIO_ACCOUNT_SID=
33
- TWILIO_AUTH_TOKEN=
34
- TWILIO_PHONE_NUMBER=
35
-
36
- # Slack (optional)
37
- SLACK_WEBHOOK_URL=
38
-
39
- # Rate Limiting
40
- RATE_LIMIT_WINDOW=1m
41
- RATE_LIMIT_LIMIT=100
42
-
43
- # Logger
44
- LOG_LEVEL=info