@flusys/nestjs-core 4.1.0 → 5.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.
package/README.md CHANGED
@@ -1,92 +1,9 @@
1
1
  # @flusys/nestjs-core
2
2
 
3
- > Foundation infrastructure for NestJS applications — type-safe environment configuration, TypeORM migration CLI, intelligent data seeding, and modular Swagger documentation.
3
+ Foundation infrastructure for NestJS applications — environment config, TypeORM migrations, and Swagger setup.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@flusys/nestjs-core.svg)](https://www.npmjs.com/package/@flusys/nestjs-core)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![NestJS](https://img.shields.io/badge/NestJS-11.x-red.svg)](https://nestjs.com/)
8
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
9
- [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18.x-green.svg)](https://nodejs.org/)
10
-
11
- ---
12
-
13
- ## Table of Contents
14
-
15
- - [Overview](#overview)
16
- - [Features](#features)
17
- - [Architecture](#architecture)
18
- - [Compatibility](#compatibility)
19
- - [Installation](#installation)
20
- - [Environment Setup](#environment-setup)
21
- - [Quick Start](#quick-start)
22
- - [EnvConfigService](#envconfigservice)
23
- - [Migration CLI](#migration-cli)
24
- - [Migration Config File](#migration-config-file)
25
- - [CLI Commands](#cli-commands)
26
- - [Programmatic API](#programmatic-api)
27
- - [Seed System](#seed-system)
28
- - [BaseSeeder](#baseseeder)
29
- - [SeedRunner](#seedrunner)
30
- - [DataGenerator](#datagenerator)
31
- - [Seed CLI](#seed-cli)
32
- - [Swagger Documentation](#swagger-documentation)
33
- - [setupSwaggerDocs](#setupswaggerdocs)
34
- - [setupModuleSwaggerDocs](#setupmoduleswaggerdocs)
35
- - [Database Utilities](#database-utilities)
36
- - [Core Interfaces](#core-interfaces)
37
- - [Injection Tokens & Constants](#injection-tokens--constants)
38
- - [Multi-Tenant Support](#multi-tenant-support)
39
- - [Troubleshooting](#troubleshooting)
40
- - [License](#license)
41
-
42
- ---
43
-
44
- ## Overview
45
-
46
- `@flusys/nestjs-core` is the lowest-level dependency in the FLUSYS NestJS monorepo. Every other package depends on it.
47
-
48
- **Key design decision:** This package is **pure TypeScript with zero NestJS runtime dependencies** (except the isolated `docs/` module). The migration and seed CLIs run as standalone Node.js processes — no NestJS app bootstrap required. This makes it usable in CI pipelines, build scripts, and non-NestJS tools.
49
-
50
- ---
51
-
52
- ## Features
53
-
54
- - **Type-safe environment config** — Strongly typed `process.env` access with restricted key protection and validation
55
- - **Migration CLI** — Full CLI and programmatic API for TypeORM migrations, including multi-tenant (run-for-all-tenants)
56
- - **Data seeder** — Metadata-driven test data generation with Faker.js, topological sort for dependency resolution, and custom seeder support
57
- - **Swagger setup** — Modular API documentation with advanced filtering by tags, schemas, parameters, and examples
58
- - **DataSource utilities** — TypeORM DataSource configuration builders for single and multi-tenant setups
59
- - **Core interfaces** — Contract definitions (entities, config, database, migrations) used by all feature modules
60
- - **SnakeNamingStrategy** — All columns use `snake_case` by default via `typeorm-naming-strategies`
61
-
62
- ---
63
-
64
- ## Architecture
65
-
66
- ```
67
- @flusys/nestjs-core ← THIS PACKAGE (pure TypeScript)
68
-
69
- @flusys/nestjs-shared ← NestJS shared infrastructure
70
-
71
- auth | iam | storage | email | form-builder | event-manager | notification | localization
72
- ```
73
-
74
- `nestjs-core` is the only FLUSYS package with no upstream FLUSYS dependencies. All other packages depend on it.
75
-
76
- ---
77
-
78
- ## Compatibility
79
-
80
- | Package | Version |
81
- |---------|---------|
82
- | `typeorm` | `^0.3.0` |
83
- | `typeorm-naming-strategies` | `^4.1.0` |
84
- | `@faker-js/faker` | `^8.0.0` |
85
- | `dotenv` | `^16.0.0` |
86
- | `@nestjs/common` | `^11.0.0` *(docs/ only)* |
87
- | `@nestjs/swagger` | `^8.0.0` *(docs/ only)* |
88
- | Node.js | `>= 18.x` |
89
- | TypeScript | `>= 5.0` |
90
7
 
91
8
  ---
92
9
 
@@ -94,549 +11,161 @@ auth | iam | storage | email | form-builder | event-manager | notification | loc
94
11
 
95
12
  ```bash
96
13
  npm install @flusys/nestjs-core
97
- ```
98
-
99
- ```bash
100
- # Peer dependencies
101
- npm install typeorm typeorm-naming-strategies @faker-js/faker dotenv
102
-
103
- # For migration and seed CLIs
14
+ npm install typeorm typeorm-naming-strategies dotenv
104
15
  npm install -D ts-node tsconfig-paths
105
-
106
- # For Swagger (docs/ module only)
107
- npm install @nestjs/common @nestjs/swagger
108
16
  ```
109
17
 
110
18
  ---
111
19
 
112
- ## Environment Setup
113
-
114
- Create a `.env` file in your project root:
115
-
116
- ```env
117
- PORT=2002
118
- MODE=dev
119
- FRONTEND_URL=http://localhost:2001
120
- ALLOW_ORIGINS=http://localhost:2001,http://localhost:3000
121
-
122
- # Database
123
- DB_HOST=localhost
124
- DB_PORT=5432
125
- DB_USER=postgres
126
- DB_PASSWORD=password
127
- DB_NAME=myapp
128
-
129
- # JWT
130
- JWT_SECRET=your-jwt-secret-min-32-chars
131
- JWT_EXPIRATION=15m
132
- REFRESH_TOKEN_SECRET=your-refresh-secret
133
- REFRESH_TOKEN_EXPIRATION=7d
134
-
135
- # Cache
136
- REDIS_URL=redis://localhost:6379
137
-
138
- # Email
139
- MAIL_FROM=noreply@example.com
140
- MAIL_APP_PASSWORD=app-password
141
-
142
- # Multi-tenant (optional)
143
- TENANT_ID=
144
- USE_TENANT_MODE=false
145
-
146
- # Logging
147
- LOG_DIR=logs
148
- LOG_LEVEL=debug
149
- LOG_MAX_SIZE=20m
150
- LOG_MAX_FILES=14d
151
- DISABLE_HTTP_LOGGING=false
152
- ```
20
+ ## 1. Environment Config
153
21
 
154
- ---
155
-
156
- ## Quick Start
157
-
158
- ### Environment Config
22
+ Access typed environment variables via the `envConfig` singleton — no class instantiation needed.
159
23
 
160
24
  ```typescript
161
25
  import { envConfig } from '@flusys/nestjs-core';
162
26
 
163
- const port = envConfig.getPort(); // number (default: 3000)
164
- const isProd = envConfig.isProduction(); // boolean
165
- const db = envConfig.getTypeOrmConfig(); // { host, port, username, password }
166
- const jwt = envConfig.getJwtConfig(); // { secret, expiration, refreshSecret, refreshExpiration }
167
- const origins = envConfig.getOrigins(); // string[] from ALLOW_ORIGINS
168
- const redis = envConfig.getRedisUrl(); // string
169
- const mail = envConfig.getMailConfig(); // { MAIL_FROM, MAIL_APP_PASSWORD }
170
- const logConfig = envConfig.getLogConfig(); // { dir, level, maxSize, maxFiles, disableHttpLogging }
171
- const tenantId = envConfig.getTenantId(); // string | null
172
- const multiTenant = envConfig.useTenantMode(); // boolean
173
-
174
- // Custom variable (throws if missing when throwOnMissing: true)
175
- const myVar = envConfig.tryGetValue('MY_CUSTOM_VAR', true);
176
- ```
177
-
178
- ### Add Migration Scripts to package.json
179
-
180
- ```json
181
- {
182
- "scripts": {
183
- "migration:generate": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli generate",
184
- "migration:run": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli run",
185
- "migration:revert": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli revert",
186
- "migration:status": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli status",
187
- "migration:run:all": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli run:all",
188
- "seed:run": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/seeders/cli run",
189
- "seed:clear": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/seeders/cli clear",
190
- "seed:status": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/seeders/cli status"
191
- }
192
- }
193
- ```
194
-
195
- ### Setup Swagger
196
-
197
- ```typescript
198
- import { NestFactory } from '@nestjs/core';
199
- import { setupSwaggerDocs } from '@flusys/nestjs-core/docs';
200
-
201
- async function bootstrap() {
202
- const app = await NestFactory.create(AppModule);
203
- setupSwaggerDocs(app, { title: 'My API', version: '1.0' });
204
- await app.listen(3000);
205
- }
27
+ const port = envConfig.getPort(); // number
28
+ const db = envConfig.getTypeOrmConfig(); // { host, port, username, password, database }
29
+ const jwt = envConfig.getJwtConfig(); // { secret, expiration, refreshSecret, ... }
30
+ const origins = envConfig.getOrigins(); // string[]
31
+ const isProd = envConfig.isProduction(); // boolean
32
+ public tryGetValue(key: string, throwOnMissing = false): string // get env value
206
33
  ```
207
34
 
208
35
  ---
209
36
 
210
- ## EnvConfigService
211
-
212
- A singleton pre-instantiated as `envConfig`. Loads `.env` on import via `dotenv`.
213
-
214
- ### Restricted Keys
37
+ ## 2. Migrations
215
38
 
216
- The following keys cannot be accessed via `tryGetValue()` — use their dedicated typed methods instead:
39
+ ### Create `src/persistence/migration.config.ts`
217
40
 
218
- `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `JWT_SECRET`, `JWT_EXPIRATION`, `REFRESH_TOKEN_SECRET`, `REFRESH_TOKEN_EXPIRATION`, `MAIL_FROM`, `MAIL_APP_PASSWORD`, `REDIS_URL`
219
-
220
- ### Method Reference
221
-
222
- | Method | Returns | Description |
223
- |--------|---------|-------------|
224
- | `tryGetValue(key, throwOnMissing?)` | `string` | Get any non-restricted env var |
225
- | `getNumber(key, throwOnMissing?)` | `number` | Get env var as number |
226
- | `getBoolean(key, throwOnMissing?)` | `boolean` | Get env var as boolean |
227
- | `getPort()` | `number` | `PORT` (default: 3000) |
228
- | `isProduction()` | `boolean` | `MODE !== 'DEV'` (case-insensitive) |
229
- | `getFrontendUrl()` | `string` | `FRONTEND_URL` |
230
- | `getOrigins()` | `string[]` | `ALLOW_ORIGINS` split by comma |
231
- | `getTypeOrmConfig()` | `IDatabaseConfig` | DB connection config |
232
- | `getJwtConfig()` | `IJwtConfig` | JWT secrets and expirations |
233
- | `getRedisUrl()` | `string` | `REDIS_URL` (default: `redis://localhost:6379`) |
234
- | `getMailConfig()` | `IMailConfig` | `MAIL_FROM`, `MAIL_APP_PASSWORD` |
235
- | `getTenantId()` | `string \| null` | `TENANT_ID` or null |
236
- | `useTenantMode()` | `boolean` | `USE_TENANT_MODE` |
237
- | `getLogConfig()` | `ILogConfig` | Logging configuration |
238
- | `getEnv()` | `Record<string, string>` | Full `process.env` snapshot |
239
-
240
- ---
241
-
242
- ## Migration CLI
243
-
244
- ### Migration Config File
41
+ ```typescript
42
+ import { createMigrationDataSource, IMigrationConfig } from '@flusys/nestjs-core';
43
+ import { envConfig } from '@flusys/nestjs-core/config';
44
+ import { getAuthEntitiesByConfig } from '@flusys/nestjs-auth';
45
+ import { getIAMEntitiesByConfig } from '@flusys/nestjs-iam';
245
46
 
246
- Create `migration.config.ts` in your project root:
47
+ const bootstrapConfig = {
48
+ databaseMode: 'single' as const,
49
+ enableCompanyFeature: true,
50
+ permissionMode: 'FULL' as const,
51
+ };
247
52
 
248
- ```typescript
249
- import { IMigrationConfig } from '@flusys/nestjs-core';
250
- import { AuthModule } from '@flusys/nestjs-auth';
251
- import { IAMModule } from '@flusys/nestjs-iam';
252
-
253
- const config: IMigrationConfig = {
254
- defaultDatabaseConfig: {
255
- type: 'postgres',
256
- host: process.env.DB_HOST ?? 'localhost',
257
- port: Number(process.env.DB_PORT ?? 5432),
258
- username: process.env.DB_USER ?? 'postgres',
259
- password: process.env.DB_PASSWORD ?? '',
260
- database: process.env.DB_NAME ?? 'myapp',
261
- },
53
+ export const migrationConfig: IMigrationConfig = {
54
+ defaultDatabaseConfig: envConfig.getTypeOrmConfig(),
55
+ bootstrapAppConfig: bootstrapConfig,
56
+ migrationsPath: `${__dirname}/migrations`,
57
+ migrationsTableName: 'migrations',
262
58
  entities: [
263
- ...AuthModule.getEntities({ enableCompanyFeature: true, enableEmailVerification: true }),
264
- ...IAMModule.getEntities({ enableCompanyFeature: true, permissionMode: 'FULL' }),
265
- // ... other module entities
59
+ ...getAuthEntitiesByConfig(bootstrapConfig),
60
+ ...getIAMEntitiesByConfig(bootstrapConfig),
266
61
  ],
267
- migrationsPath: 'src/migrations',
268
- migrationsTableName: 'migrations',
269
62
  };
270
63
 
271
- export default config;
272
- ```
273
-
274
- ### CLI Commands
275
-
276
- ```bash
277
- # Generate a new migration (compares entities to current DB schema)
278
- npm run migration:generate -- -n CreateUsersTable
279
-
280
- # Run all pending migrations
281
- npm run migration:run
282
-
283
- # Revert the last applied migration
284
- npm run migration:revert
285
-
286
- # Show migration status (which are applied, which are pending)
287
- npm run migration:status
288
-
289
- # Multi-tenant: run migrations for all tenants
290
- npm run migration:run:all
291
- ```
292
-
293
- ### Programmatic API
294
-
295
- ```typescript
296
- import {
297
- createMigrationDataSource,
298
- runMigrations,
299
- revertMigration,
300
- migrationStatus,
301
- generateMigration,
302
- runForAllTenants,
303
- } from '@flusys/nestjs-core';
304
-
305
- // Create a DataSource for migration operations
306
- const dataSource = await createMigrationDataSource(config, tenantId);
307
-
308
- // Run pending migrations
309
- await runMigrations(dataSource);
310
-
311
- // Revert last migration
312
- await revertMigration(dataSource);
313
-
314
- // Check status
315
- const status = await migrationStatus(dataSource);
316
-
317
- // Generate a new migration file
318
- await generateMigration(config, 'MigrationName');
319
-
320
- // Multi-tenant: run for all configured tenants
321
- await runForAllTenants(config, runMigrations);
64
+ // Required for TypeORM CLI
65
+ export default createMigrationDataSource({
66
+ config: migrationConfig,
67
+ tenantId: process.env.TENANT_ID,
68
+ });
322
69
  ```
323
70
 
324
- ---
325
-
326
- ## Seed System
327
-
328
- ### BaseSeeder
329
-
330
- Extend `BaseSeeder` to create custom seeders:
71
+ ### Add scripts to `package.json`
331
72
 
332
- ```typescript
333
- import { BaseSeeder, SeedRunner } from '@flusys/nestjs-core';
334
- import { DataSource } from 'typeorm';
335
-
336
- export class UserSeeder extends BaseSeeder {
337
- name = 'UserSeeder';
338
- order = 1; // Lower runs first (topological sort by dependencies)
339
- dependencies = []; // Seeder names this depends on
340
-
341
- async run(dataSource: DataSource): Promise<void> {
342
- const repo = dataSource.getRepository(User);
343
- await repo.save([
344
- { email: 'admin@example.com', name: 'Admin User' },
345
- ]);
346
- }
347
-
348
- async clear(dataSource: DataSource): Promise<void> {
349
- await dataSource.getRepository(User).delete({});
73
+ ```json
74
+ {
75
+ "scripts": {
76
+ "migration": "ts-node -r tsconfig-paths/register ./node_modules/@flusys/nestjs-core/migration/cli --config=src/persistence/migration.config.ts",
77
+ "migration:generate": "npm run migration -- generate",
78
+ "migration:run": "npm run migration -- run",
79
+ "migration:revert": "npm run migration -- revert",
80
+ "migration:status": "npm run migration -- status",
81
+ "migration:run:all": "npm run migration -- run:all",
82
+ "migration:revert:all": "npm run migration -- revert:all",
83
+ "migration:status:all": "npm run migration -- status:all"
350
84
  }
351
85
  }
352
86
  ```
353
87
 
354
- ### SeedRunner
355
-
356
- ```typescript
357
- import { SeedRunner, seedConfig } from '@flusys/nestjs-core';
358
-
359
- // Register seeders
360
- seedConfig.register([UserSeeder, RoleSeeder, PermissionSeeder]);
361
-
362
- // Run all seeders (respects order and dependencies)
363
- const runner = new SeedRunner(dataSource);
364
- const result = await runner.run();
365
- console.log(`Seeded ${result.count} records`);
366
-
367
- // Clear all seeded data (in reverse order)
368
- await runner.clear();
369
-
370
- // Check seeder status
371
- const status = await runner.status();
372
- ```
373
-
374
- ### DataGenerator
375
-
376
- Generates realistic test data from TypeORM entity metadata using Faker.js:
377
-
378
- ```typescript
379
- import { DataGenerator } from '@flusys/nestjs-core';
380
-
381
- const generator = new DataGenerator(dataSource);
382
-
383
- // Auto-detect field types and generate appropriate data
384
- const fakeUser = generator.generate(User, {
385
- overrides: { email: 'specific@email.com' },
386
- count: 10, // generate 10 records
387
- });
388
- ```
389
-
390
- **Automatic field pattern detection:**
391
-
392
- | Pattern | Generated value |
393
- |---------|----------------|
394
- | `email` | `faker.internet.email()` |
395
- | `name`, `title` | `faker.person.fullName()` |
396
- | `phone` | `faker.phone.number()` |
397
- | `address` | `faker.location.streetAddress()` |
398
- | `url`, `website` | `faker.internet.url()` |
399
- | `description`, `text` | `faker.lorem.paragraph()` |
400
- | `slug` | `faker.helpers.slugify()` |
401
- | `uuid`, `id` | `faker.string.uuid()` |
402
- | `boolean`, `isActive` | `faker.datatype.boolean()` |
403
- | `date`, `createdAt` | `faker.date.recent()` |
404
- | `number`, `price` | `faker.number.int()` |
405
-
406
- ### Seed CLI
88
+ ### Run
407
89
 
408
90
  ```bash
409
- # Run all seeders
410
- npm run seed:run
411
-
412
- # Clear all seeded data
413
- npm run seed:clear
414
-
415
- # Show seeder status
416
- npm run seed:status
417
- ```
418
-
419
- ---
420
-
421
- ## Swagger Documentation
422
-
423
- ### setupSwaggerDocs
424
-
425
- Sets up a single global Swagger UI for the whole application:
426
-
427
- ```typescript
428
- import { setupSwaggerDocs } from '@flusys/nestjs-core/docs';
429
-
430
- setupSwaggerDocs(app, {
431
- title: 'My API',
432
- description: 'API documentation',
433
- version: '1.0.0',
434
- path: 'api/docs', // default: 'api/docs'
435
- bearerAuthEnabled: true, // default: true
436
- persistAuthorization: true, // default: true
437
- });
438
- ```
439
-
440
- ### setupModuleSwaggerDocs
441
-
442
- Sets up module-scoped Swagger documentation at separate URLs — one per feature module:
443
-
444
- ```typescript
445
- import { setupModuleSwaggerDocs } from '@flusys/nestjs-core/docs';
446
-
447
- setupModuleSwaggerDocs(app, [
448
- {
449
- title: 'Authentication API',
450
- description: 'Auth endpoints',
451
- version: '1.0.0',
452
- path: 'api/docs/auth',
453
- includeTags: ['Authentication', 'Users', 'Companies'],
454
- },
455
- {
456
- title: 'IAM API',
457
- description: 'Permissions and roles',
458
- version: '1.0.0',
459
- path: 'api/docs/iam',
460
- includeTags: ['Roles', 'Actions', 'Permissions'],
461
- },
462
- {
463
- title: 'Storage API',
464
- description: 'File management',
465
- version: '1.0.0',
466
- path: 'api/docs/storage',
467
- includeTags: ['Files', 'Folders'],
468
- },
469
- ]);
470
- ```
471
-
472
- ### IModuleSwaggerOptions
473
-
474
- ```typescript
475
- interface IModuleSwaggerOptions {
476
- title: string;
477
- description?: string;
478
- version?: string;
479
- path: string;
480
- includeTags?: string[]; // Whitelist specific controller tags
481
- excludeTags?: string[]; // Blacklist specific controller tags
482
- includeSchemas?: string[]; // Whitelist specific DTO schemas
483
- excludeSchemas?: string[]; // Blacklist specific DTO schemas
484
- bearerAuthEnabled?: boolean;
485
- persistAuthorization?: boolean;
486
- }
487
- ```
488
-
489
- ---
490
-
491
- ## Database Utilities
492
-
493
- ```typescript
494
- import { buildDataSourceOptions, getMigrationsFolderPath, getActiveTenants } from '@flusys/nestjs-core';
495
-
496
- // Build a TypeORM DataSourceOptions object
497
- const options = buildDataSourceOptions({
498
- config: databaseConfig,
499
- entities: [...authEntities, ...iamEntities],
500
- migrationsPath: 'src/migrations',
501
- migrationsTableName: 'migrations',
502
- });
503
-
504
- // Get migrations folder path (supports tenant-specific subdirectories)
505
- const migrationsPath = getMigrationsFolderPath('src/migrations', 'tenant-1');
506
-
507
- // Get all active tenant configs
508
- const tenants = getActiveTenants(migrationConfig);
509
- ```
510
-
511
- ---
512
-
513
- ## Core Interfaces
514
-
515
- These interfaces are used as contracts across all FLUSYS feature modules:
516
-
517
- ```typescript
518
- // Entity contracts
519
- interface IIdentity { id: string; createdAt: Date; updatedAt: Date; deletedAt?: Date | null; }
520
-
521
- // Bootstrap configuration (fixed at startup)
522
- interface IBootstrapAppConfig {
523
- databaseMode: 'single' | 'multi-tenant';
524
- enableCompanyFeature: boolean;
525
- enableEmailVerification?: boolean;
526
- permissionMode?: 'FULL' | 'RBAC' | 'DIRECT';
527
- }
528
-
529
- // DataSource configuration
530
- interface IDatabaseConfig {
531
- type: 'postgres' | 'mysql' | 'mariadb' | 'sqlite' | 'mssql';
532
- host: string;
533
- port: number;
534
- username: string;
535
- password: string;
536
- database: string;
537
- }
538
-
539
- // Multi-tenant config
540
- interface ITenantDatabaseConfig extends IDatabaseConfig { id: string; }
541
-
542
- // Module options for dynamic modules
543
- interface IDynamicModuleConfig {
544
- global?: boolean;
545
- includeController?: boolean;
546
- }
547
-
548
- // DataSource service options (base for all module configs)
549
- interface IDataSourceServiceOptions {
550
- defaultDatabaseConfig?: IDatabaseConfig;
551
- tenantDefaultDatabaseConfig?: IDatabaseConfig;
552
- tenants?: ITenantDatabaseConfig[];
553
- }
554
- ```
555
-
556
- ---
557
-
558
- ## Injection Tokens & Constants
559
-
560
- ```typescript
561
- import {
562
- MIGRATION_CONFIG_TOKEN,
563
- SEED_CONFIG_TOKEN,
564
- DATASOURCE_TOKEN,
565
- } from '@flusys/nestjs-core';
566
- ```
567
-
568
- ---
569
-
570
- ## Multi-Tenant Support
571
-
572
- `nestjs-core` provides the foundation for multi-tenant architectures:
573
-
574
- ```typescript
575
- import { buildDataSourceOptions, getDatabaseForTenant, getActiveTenants } from '@flusys/nestjs-core';
576
-
577
- // Get database config for a specific tenant
578
- const tenantDb = getDatabaseForTenant(migrationConfig, 'tenant-id');
91
+ # Single database
92
+ npm run migration:generate -- --name=CreateUsersTable
93
+ npm run migration:run
94
+ npm run migration:revert
95
+ npm run migration:status
579
96
 
580
- // Build a DataSource for that tenant
581
- const dsOptions = buildDataSourceOptions({
582
- config: tenantDb,
583
- entities: [...allEntities],
584
- migrationsPath: getMigrationsFolderPath('src/migrations', 'tenant-id'),
585
- });
97
+ # Tenant-specific (prefix with TENANT_ID)
98
+ TENANT_ID=tenant-1 npm run migration:generate -- --name=CreateUsersTable
99
+ TENANT_ID=tenant-1 npm run migration:run
100
+ TENANT_ID=tenant-1 npm run migration:revert
101
+ TENANT_ID=tenant-1 npm run migration:status
586
102
 
587
- // Run migrations for all configured tenants
588
- await runForAllTenants(migrationConfig, async (dataSource) => {
589
- await runMigrations(dataSource);
590
- });
103
+ # All tenants at once
104
+ npm run migration:run:all
105
+ npm run migration:revert:all
106
+ npm run migration:status:all
591
107
  ```
592
108
 
593
109
  ---
594
110
 
595
- ## Troubleshooting
596
-
597
- **`Cannot find migration config file`**
598
-
599
- Ensure `migration.config.ts` exists at the project root and exports a default `IMigrationConfig` object. The CLI looks for it relative to the current working directory.
600
-
601
- ---
602
-
603
- **`RESTRICTED_KEY` error from `tryGetValue`**
111
+ ## 3. Swagger
604
112
 
605
- You are trying to access a sensitive key (DB credentials, JWT secrets) via the generic accessor. Use the typed method instead:
113
+ `setupSwaggerDocs` and `setupModuleSwaggerDocs` accept the same `IModuleSwaggerOptions` shape.
606
114
 
607
115
  ```typescript
608
- // Wrong
609
- envConfig.tryGetValue('JWT_SECRET') // throws RestrictedKeyError
610
-
611
- // Correct
612
- envConfig.getJwtConfig().secret
613
- ```
614
-
615
- ---
616
-
617
- **`SnakeNamingStrategy` column name mismatch**
618
-
619
- All columns use `snake_case` by default. A TypeScript property `createdAt` maps to column `created_at`. If your existing schema uses camelCase, override the naming strategy in `buildDataSourceOptions`.
620
-
621
- ---
116
+ import { NestFactory } from '@nestjs/core';
117
+ import { setupSwaggerDocs, setupModuleSwaggerDocs } from '@flusys/nestjs-core/docs';
118
+ import { AuthModule } from '@flusys/nestjs-auth';
622
119
 
623
- **Seeder runs out of order**
120
+ async function bootstrap() {
121
+ const app = await NestFactory.create(AppModule);
624
122
 
625
- Set explicit `order` numbers or use `dependencies` to declare which seeders must run before yours:
123
+ // All available options (one entry showing every field)
124
+ setupModuleSwaggerDocs(app, [
125
+ {
126
+ title: 'Auth API', // required
127
+ description: 'Auth endpoints', // required
128
+ version: '1.0', // optional, default '1.0'
129
+ path: 'api/docs/auth', // required — URL where docs are served
130
+ bearerAuth: true, // adds Authorization header to Swagger UI
131
+ modules: [AuthModule], // scope to specific NestJS modules only
132
+
133
+ // Exclude controllers by @ApiTags name
134
+ excludeTags: ['Internal', 'Health'],
135
+
136
+ // Exclude specific paths (supports * and ** wildcards)
137
+ excludePaths: ['/api/auth/internal/*', '/api/health'],
138
+
139
+ // Exclude properties from a DTO schema
140
+ excludeSchemaProperties: [
141
+ { schemaName: 'CreateUserDto', properties: ['passwordHash', 'salt'] },
142
+ ],
143
+
144
+ // Exclude query parameters from specific endpoints
145
+ excludeQueryParameters: [
146
+ { pathPattern: '/api/auth/*', method: 'post', parameters: ['debug'] },
147
+ ],
148
+
149
+ // Exclude named examples from responses
150
+ excludeExamples: [
151
+ { pathPattern: '/api/auth/login', examples: ['AdminExample'] },
152
+ ],
153
+
154
+ // Add a custom header to every request in Swagger UI
155
+ globalHeaders: [
156
+ { name: 'x-tenant-id', description: 'Tenant identifier', required: false, example: 'tenant-1' },
157
+ ],
158
+ },
159
+
160
+ // Minimal entry
161
+ { title: 'IAM API', description: 'Roles and permissions', path: 'api/docs/iam' },
162
+ ]);
626
163
 
627
- ```typescript
628
- export class ProductSeeder extends BaseSeeder {
629
- name = 'ProductSeeder';
630
- dependencies = ['CategorySeeder']; // CategorySeeder must run first
164
+ await app.listen(3000);
631
165
  }
632
166
  ```
633
167
 
634
- ---
635
168
 
636
169
  ## License
637
170
 
638
171
  MIT © FLUSYS
639
-
640
- ---
641
-
642
- > Part of the **FLUSYS** framework — a full-stack monorepo powering Angular 21 + NestJS 11 applications.