@flusys/nestjs-core 1.0.0-rc → 2.0.0-rc.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 +482 -73
- package/cjs/docs/docs.config.js +77 -3
- package/cjs/docs/index.js +0 -1
- package/cjs/migration/migration.runner.js +37 -65
- package/cjs/seeders/cli.js +65 -172
- package/cjs/seeders/data-generator.js +91 -139
- package/cjs/seeders/field-patterns.js +172 -0
- package/cjs/seeders/index.js +13 -4
- package/cjs/seeders/seed-runner.js +8 -14
- package/docs/docs.config.d.ts +7 -0
- package/docs/index.d.ts +0 -1
- package/fesm/docs/docs.config.js +68 -0
- package/fesm/docs/index.js +0 -1
- package/fesm/migration/migration.runner.js +37 -65
- package/fesm/seeders/cli.js +65 -182
- package/fesm/seeders/data-generator.js +91 -146
- package/fesm/seeders/field-patterns.js +143 -0
- package/fesm/seeders/index.js +1 -1
- package/fesm/seeders/seed-runner.js +8 -14
- package/package.json +1 -1
- package/seeders/data-generator.d.ts +1 -1
- package/seeders/field-patterns.d.ts +12 -0
- package/seeders/index.d.ts +1 -1
- package/seeders/seed-runner.d.ts +1 -0
- package/cjs/docs/docs.setup.js +0 -14
- package/cjs/seeders/template-generator.js +0 -297
- package/docs/docs.setup.d.ts +0 -3
- package/fesm/docs/docs.setup.js +0 -4
- package/fesm/seeders/template-generator.js +0 -257
- package/seeders/template-generator.d.ts +0 -16
package/README.md
CHANGED
|
@@ -1,70 +1,125 @@
|
|
|
1
1
|
# Core Package Guide
|
|
2
2
|
|
|
3
3
|
> **Package:** `@flusys/nestjs-core`
|
|
4
|
-
> **Type:**
|
|
4
|
+
> **Type:** Pure TypeScript foundation (zero NestJS dependencies)
|
|
5
5
|
|
|
6
|
-
Foundation layer providing type-safe configuration, database utilities, migration CLI, seeders, and Swagger setup.
|
|
6
|
+
Foundation layer providing type-safe configuration, database utilities, migration CLI, seeders with intelligent pattern detection, and Swagger setup.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Package Architecture](#package-architecture)
|
|
11
|
+
- [Environment Configuration](#environment-configuration)
|
|
12
|
+
- [Database Interfaces](#database-interfaces)
|
|
13
|
+
- [Migration System](#migration-system)
|
|
14
|
+
- [Seed System](#seed-system)
|
|
15
|
+
- [Field Pattern Detection](#field-pattern-detection)
|
|
16
|
+
- [Swagger Documentation](#swagger-documentation)
|
|
17
|
+
- [API Reference](#api-reference)
|
|
18
|
+
|
|
19
|
+
---
|
|
7
20
|
|
|
8
21
|
## Package Architecture
|
|
9
22
|
|
|
10
23
|
```
|
|
11
24
|
nestjs-core/src/
|
|
12
25
|
├── config/
|
|
13
|
-
│ └── env-config.service.ts
|
|
26
|
+
│ └── env-config.service.ts # Environment configuration singleton
|
|
14
27
|
├── constants/
|
|
15
|
-
│ └── database.constants.ts
|
|
28
|
+
│ └── database.constants.ts # MODULE_OPTIONS, DEFAULT_TENANT_HEADER
|
|
16
29
|
├── interfaces/
|
|
17
|
-
│ ├── app-config.interfaces.ts
|
|
18
|
-
│ ├── base-entity.interface.ts
|
|
19
|
-
│ ├── database.interface.ts
|
|
20
|
-
│ └── migration.interface.ts
|
|
30
|
+
│ ├── app-config.interfaces.ts # IBootstrapAppConfig, IDynamicModuleConfig
|
|
31
|
+
│ ├── base-entity.interface.ts # IBaseEntity, ISoftDeletable, ITimestampable
|
|
32
|
+
│ ├── database.interface.ts # IDatabaseConfig, ITenantDatabaseConfig
|
|
33
|
+
│ └── migration.interface.ts # IMigrationConfig, IMigrationResult
|
|
21
34
|
├── utils/
|
|
22
|
-
│ └── datasource-config.builder.ts
|
|
35
|
+
│ └── datasource-config.builder.ts # DataSource utilities
|
|
23
36
|
├── migration/
|
|
24
|
-
│ ├── cli.ts
|
|
37
|
+
│ ├── cli.ts # CLI entry point
|
|
38
|
+
│ ├── migration.cli.ts # Migration CLI commands
|
|
39
|
+
│ ├── datasource.factory.ts # DataSource factory
|
|
40
|
+
│ └── migration.runner.ts # Migration execution
|
|
25
41
|
├── seeders/
|
|
26
|
-
│ ├── cli.ts
|
|
27
|
-
│ ├──
|
|
42
|
+
│ ├── cli.ts # Seed CLI entry point
|
|
43
|
+
│ ├── base-seeder.ts # Abstract base seeder class
|
|
44
|
+
│ ├── seed-runner.ts # Seed orchestration
|
|
45
|
+
│ ├── seed-config.ts # Global seed configuration
|
|
46
|
+
│ ├── entity-reader.ts # TypeORM metadata extraction
|
|
47
|
+
│ ├── data-generator.ts # Faker.js data generation
|
|
48
|
+
│ ├── field-patterns.ts # Intelligent field pattern detection
|
|
49
|
+
│ └── template-generator.ts # Seeder template generation
|
|
28
50
|
├── docs/
|
|
29
|
-
│
|
|
51
|
+
│ └── docs.config.ts # Swagger setup utilities
|
|
30
52
|
└── index.ts
|
|
31
53
|
```
|
|
32
54
|
|
|
55
|
+
---
|
|
56
|
+
|
|
33
57
|
## Environment Configuration
|
|
34
58
|
|
|
35
59
|
```typescript
|
|
36
60
|
import { envConfig } from '@flusys/nestjs-core/config';
|
|
37
61
|
```
|
|
38
62
|
|
|
63
|
+
### Available Methods
|
|
64
|
+
|
|
39
65
|
| Method | Description |
|
|
40
66
|
|--------|-------------|
|
|
41
67
|
| `tryGetValue(key)` | Get env value (throws for restricted keys) |
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
68
|
+
| `getValue(key, throwOnMissing?)` | Raw string access |
|
|
69
|
+
| `getNumber(key, throwOnMissing?)` | Get env value as number |
|
|
70
|
+
| `getBoolean(key, throwOnMissing?)` | Get env value as boolean |
|
|
44
71
|
| `getPort()` | Get PORT (default: 3000) |
|
|
45
72
|
| `isProduction()` | Check if MODE !== 'DEV' |
|
|
46
73
|
| `getFrontendUrl()` | Get FRONTEND_URL |
|
|
47
|
-
| `getOrigins()` | Get ALLOW_ORIGINS as array |
|
|
74
|
+
| `getOrigins()` | Get ALLOW_ORIGINS as comma-separated array |
|
|
48
75
|
| `getTypeOrmConfig()` | Get database config |
|
|
49
|
-
| `getJwtConfig()` | Get JWT
|
|
50
|
-
| `getRedisUrl()` | Get Redis connection URL |
|
|
51
|
-
| `getMailConfig()` | Get mail configuration |
|
|
76
|
+
| `getJwtConfig()` | Get JWT secret + expiration |
|
|
77
|
+
| `getRedisUrl()` | Get Redis connection URL (default: redis://localhost:6379) |
|
|
78
|
+
| `getMailConfig()` | Get mail configuration (MAIL_FROM, MAIL_APP_PASSWORD) |
|
|
52
79
|
| `getTenantId()` | Get TENANT_ID |
|
|
53
80
|
| `useTenantMode()` | Check USE_TENANT_MODE |
|
|
54
81
|
| `getLogConfig()` | Get logging configuration |
|
|
55
82
|
| `getEnv()` | Get all env vars as Record |
|
|
56
83
|
|
|
84
|
+
### Restricted Keys
|
|
85
|
+
|
|
86
|
+
The following keys require using specific methods (prevents misuse):
|
|
87
|
+
|
|
88
|
+
| Key | Use Instead |
|
|
89
|
+
|-----|-------------|
|
|
90
|
+
| `FRONTEND_URL` | `getFrontendUrl()` |
|
|
91
|
+
| `ALLOW_ORIGINS` | `getOrigins()` |
|
|
92
|
+
| `PORT` | `getPort()` |
|
|
93
|
+
| `MODE` | `isProduction()` |
|
|
94
|
+
| `DB_HOST/PORT/USER/PASSWORD` | `getTypeOrmConfig()` |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
57
98
|
## Database Interfaces
|
|
58
99
|
|
|
100
|
+
### Core Interfaces
|
|
101
|
+
|
|
59
102
|
```typescript
|
|
103
|
+
type DatabaseType = 'mysql' | 'postgres' | 'mariadb' | 'sqlite' | 'mssql';
|
|
104
|
+
type DatabaseMode = 'single' | 'multi-tenant';
|
|
105
|
+
|
|
60
106
|
interface IDatabaseConfig {
|
|
61
|
-
type:
|
|
62
|
-
host?: string;
|
|
107
|
+
type: DatabaseType;
|
|
108
|
+
host?: string;
|
|
109
|
+
port?: number;
|
|
110
|
+
username?: string;
|
|
111
|
+
password?: string;
|
|
112
|
+
database?: string;
|
|
63
113
|
}
|
|
64
114
|
|
|
65
115
|
interface ITenantDatabaseConfig {
|
|
66
|
-
id: string;
|
|
67
|
-
|
|
116
|
+
id: string;
|
|
117
|
+
database: string;
|
|
118
|
+
name?: string;
|
|
119
|
+
host?: string;
|
|
120
|
+
port?: number;
|
|
121
|
+
username?: string;
|
|
122
|
+
password?: string;
|
|
68
123
|
enableCompanyFeature?: boolean;
|
|
69
124
|
permissionMode?: 'FULL' | 'RBAC' | 'DIRECT';
|
|
70
125
|
}
|
|
@@ -74,83 +129,332 @@ interface IBootstrapAppConfig {
|
|
|
74
129
|
enableCompanyFeature: boolean;
|
|
75
130
|
permissionMode?: 'FULL' | 'RBAC' | 'DIRECT';
|
|
76
131
|
}
|
|
132
|
+
```
|
|
77
133
|
|
|
78
|
-
|
|
79
|
-
|
|
134
|
+
### Entity Interfaces
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
interface IBaseEntity {
|
|
138
|
+
id: string;
|
|
139
|
+
createdAt: Date;
|
|
140
|
+
updatedAt: Date;
|
|
141
|
+
deletedAt?: Date | null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface ISoftDeletable {
|
|
145
|
+
deletedAt?: Date | null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
interface ITimestampable {
|
|
149
|
+
createdAt: Date;
|
|
150
|
+
updatedAt: Date;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface IOrderable {
|
|
154
|
+
serial?: number;
|
|
80
155
|
}
|
|
81
156
|
|
|
82
157
|
interface IMetadata {
|
|
83
158
|
metadata?: Record<string, any> | null;
|
|
84
159
|
}
|
|
160
|
+
|
|
161
|
+
interface ICompanyOwned {
|
|
162
|
+
companyId?: string | null;
|
|
163
|
+
}
|
|
85
164
|
```
|
|
86
165
|
|
|
87
|
-
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Migration System
|
|
169
|
+
|
|
170
|
+
### CLI Commands
|
|
88
171
|
|
|
89
172
|
```bash
|
|
90
|
-
npm run migration:generate --
|
|
91
|
-
npm run migration:run
|
|
92
|
-
npm run migration:revert
|
|
93
|
-
npm run migration:status
|
|
94
|
-
TENANT_ID=tenant1 npm run migration:run
|
|
95
|
-
npm run migration:run:all
|
|
173
|
+
npm run migration:generate -- -n CreateUsers # Generate migration
|
|
174
|
+
npm run migration:run # Run pending migrations
|
|
175
|
+
npm run migration:revert # Revert last migration
|
|
176
|
+
npm run migration:status # Show migration status
|
|
177
|
+
TENANT_ID=tenant1 npm run migration:run # Specific tenant
|
|
178
|
+
npm run migration:run:all # All tenants
|
|
179
|
+
npm run migration:revert:all # Revert all tenants
|
|
180
|
+
npm run migration:status:all # Status all tenants
|
|
96
181
|
```
|
|
97
182
|
|
|
183
|
+
### Migration Configuration
|
|
184
|
+
|
|
98
185
|
```typescript
|
|
99
|
-
import {
|
|
186
|
+
import { IMigrationConfig } from '@flusys/nestjs-core';
|
|
187
|
+
|
|
188
|
+
const migrationConfig: IMigrationConfig = {
|
|
189
|
+
defaultDatabaseConfig: {
|
|
190
|
+
type: 'postgres',
|
|
191
|
+
host: 'localhost',
|
|
192
|
+
port: 5432,
|
|
193
|
+
username: 'user',
|
|
194
|
+
password: 'password',
|
|
195
|
+
database: 'app_db',
|
|
196
|
+
},
|
|
197
|
+
bootstrapAppConfig: {
|
|
198
|
+
databaseMode: 'multi-tenant',
|
|
199
|
+
enableCompanyFeature: true,
|
|
200
|
+
},
|
|
201
|
+
tenants: [
|
|
202
|
+
{ id: 'tenant1', database: 'tenant1_db' },
|
|
203
|
+
{ id: 'tenant2', database: 'tenant2_db', host: 'different-server.com' },
|
|
204
|
+
],
|
|
205
|
+
migrationsPath: './src/persistence/migrations',
|
|
206
|
+
entities: (tenantConfig) => {
|
|
207
|
+
// Dynamic entity resolution per tenant
|
|
208
|
+
return tenantConfig?.enableCompanyFeature
|
|
209
|
+
? [UserWithCompany, RoleWithCompany]
|
|
210
|
+
: [User, Role];
|
|
211
|
+
},
|
|
212
|
+
migrationsTableName: 'typeorm_migrations',
|
|
213
|
+
};
|
|
100
214
|
```
|
|
101
215
|
|
|
216
|
+
### Core Functions
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import {
|
|
220
|
+
generateMigration,
|
|
221
|
+
runMigrations,
|
|
222
|
+
revertMigration,
|
|
223
|
+
migrationStatus,
|
|
224
|
+
runForAllTenants,
|
|
225
|
+
createMigrationDataSource,
|
|
226
|
+
} from '@flusys/nestjs-core/migration';
|
|
227
|
+
|
|
228
|
+
// Generate new migration
|
|
229
|
+
await generateMigration(config, 'CreateUsersTable', tenantId?);
|
|
230
|
+
|
|
231
|
+
// Run pending migrations
|
|
232
|
+
const result: IMigrationResult = await runMigrations(config, tenantId?);
|
|
233
|
+
|
|
234
|
+
// Revert last migration
|
|
235
|
+
const result: IMigrationResult = await revertMigration(config, tenantId?);
|
|
236
|
+
|
|
237
|
+
// Check status
|
|
238
|
+
await migrationStatus(config, tenantId?);
|
|
239
|
+
|
|
240
|
+
// Multi-tenant operations
|
|
241
|
+
const results: IMigrationResult[] = await runForAllTenants(config, 'run');
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
102
246
|
## Seed System
|
|
103
247
|
|
|
248
|
+
### CLI Commands
|
|
249
|
+
|
|
104
250
|
```bash
|
|
105
|
-
npm run seed:
|
|
106
|
-
npm run seed:run -- --entity=User --count=100
|
|
107
|
-
npm run seed:clear
|
|
108
|
-
npm run seed:
|
|
251
|
+
npm run seed:run # Seed all entities
|
|
252
|
+
npm run seed:run -- --entity=User --count=100 # Specific entity
|
|
253
|
+
npm run seed:run -- --count=50 --clear # Clear before seeding
|
|
254
|
+
npm run seed:clear # Clear all data
|
|
255
|
+
npm run seed:clear -- --hard # Hard delete
|
|
256
|
+
npm run seed:status # Show status
|
|
257
|
+
npm run seed:run:all # Multi-tenant
|
|
109
258
|
```
|
|
110
259
|
|
|
111
260
|
### Seed Configuration
|
|
112
261
|
|
|
113
262
|
```typescript
|
|
114
|
-
import { configureSeedConfig, seedConfig } from '@flusys/nestjs-core/seeders';
|
|
263
|
+
import { configureSeedConfig, seedConfig, ISeedConfig } from '@flusys/nestjs-core/seeders';
|
|
264
|
+
|
|
265
|
+
interface ISeedConfig {
|
|
266
|
+
counts: Record<string, number>; // Per-entity counts
|
|
267
|
+
order: string[]; // Preferred seeding order
|
|
268
|
+
skipEntities: string[]; // Entities to skip
|
|
269
|
+
locale: string; // Faker locale
|
|
270
|
+
respectSoftDelete: boolean; // Default clear behavior
|
|
271
|
+
}
|
|
115
272
|
|
|
116
273
|
// Configure before running seeders
|
|
117
274
|
configureSeedConfig({
|
|
118
|
-
counts: { User: 50, Product: 100 },
|
|
119
|
-
order: ['User', 'Product', 'Order'],
|
|
120
|
-
skipEntities: ['migrations', 'typeorm_metadata'],
|
|
275
|
+
counts: { User: 50, Product: 100, Order: 200 },
|
|
276
|
+
order: ['User', 'Company', 'Product', 'Order'],
|
|
277
|
+
skipEntities: ['migrations', 'typeorm_metadata', 'Migration'],
|
|
121
278
|
locale: 'en',
|
|
122
279
|
respectSoftDelete: true,
|
|
123
280
|
});
|
|
124
281
|
```
|
|
125
282
|
|
|
283
|
+
### SeedRunner
|
|
284
|
+
|
|
285
|
+
The main orchestrator for seed operations:
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { SeedRunner, ISeedOptions, ISeedResult } from '@flusys/nestjs-core/seeders';
|
|
289
|
+
|
|
290
|
+
const runner = new SeedRunner(dataSource, logger?);
|
|
291
|
+
|
|
292
|
+
// Register custom seeders (take precedence over generic)
|
|
293
|
+
runner.registerCustomSeeder('User', new UserSeeder(dataSource));
|
|
294
|
+
|
|
295
|
+
// Run all entities in dependency order
|
|
296
|
+
const results: ISeedResult[] = await runner.runAll({
|
|
297
|
+
count: 50, // Records per entity
|
|
298
|
+
clear: true, // Clear before seeding
|
|
299
|
+
skipIfExists: false, // Skip if data exists
|
|
300
|
+
dryRun: false, // Preview without executing
|
|
301
|
+
continueOnError: true, // Continue on failures
|
|
302
|
+
batchSize: 1000, // Batch size for bulk inserts
|
|
303
|
+
onProgress: (current, total, entity) => { },
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Run single entity
|
|
307
|
+
const result: ISeedResult = await runner.runSingle('User', options);
|
|
308
|
+
|
|
309
|
+
// Clear all data (reverse dependency order)
|
|
310
|
+
const results = await runner.clearAll(hard?, continueOnError?);
|
|
311
|
+
|
|
312
|
+
// Get status
|
|
313
|
+
const status = await runner.getStatus();
|
|
314
|
+
// Returns: [{ entity, tableName, count, isEmpty, hasSoftDelete }]
|
|
315
|
+
```
|
|
316
|
+
|
|
126
317
|
### Custom Seeders
|
|
127
318
|
|
|
128
319
|
```typescript
|
|
129
|
-
import { BaseSeeder,
|
|
320
|
+
import { BaseSeeder, DataGenerator } from '@flusys/nestjs-core/seeders';
|
|
130
321
|
|
|
131
322
|
class UserSeeder extends BaseSeeder<User> {
|
|
132
|
-
|
|
323
|
+
private generator: DataGenerator;
|
|
324
|
+
|
|
325
|
+
constructor(ds: DataSource) {
|
|
326
|
+
super(ds, User);
|
|
327
|
+
this.generator = new DataGenerator('en');
|
|
328
|
+
}
|
|
329
|
+
|
|
133
330
|
async generate(count: number): Promise<User[]> {
|
|
134
|
-
const users = [];
|
|
331
|
+
const users: User[] = [];
|
|
135
332
|
for (let i = 0; i < count; i++) {
|
|
136
|
-
users.push(this.repository.create({
|
|
333
|
+
users.push(this.repository.create({
|
|
334
|
+
email: faker.internet.email(),
|
|
335
|
+
name: faker.person.fullName(),
|
|
336
|
+
password: await bcrypt.hash('password123', 12),
|
|
337
|
+
}));
|
|
137
338
|
}
|
|
138
339
|
return this.repository.save(users);
|
|
139
340
|
}
|
|
140
341
|
}
|
|
141
342
|
|
|
343
|
+
// Register before running
|
|
142
344
|
const runner = new SeedRunner(dataSource);
|
|
143
345
|
runner.registerCustomSeeder('User', new UserSeeder(dataSource));
|
|
144
346
|
await runner.runAll({ count: 50, clear: true });
|
|
145
347
|
```
|
|
146
348
|
|
|
349
|
+
### EntityReader
|
|
350
|
+
|
|
351
|
+
Extracts TypeORM metadata for intelligent seeding:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { EntityReader, IEntityInfo, IColumnInfo } from '@flusys/nestjs-core/seeders';
|
|
355
|
+
|
|
356
|
+
const reader = new EntityReader(dataSource);
|
|
357
|
+
|
|
358
|
+
// Get all entities
|
|
359
|
+
const entities = reader.getAllEntities();
|
|
360
|
+
|
|
361
|
+
// Get detailed entity info
|
|
362
|
+
const info: IEntityInfo = reader.getEntityInfo('User');
|
|
363
|
+
// Returns: { name, tableName, columns, relations, hasSoftDelete, hasCompany }
|
|
364
|
+
|
|
365
|
+
// Get seeding order (topological sort by FK dependencies)
|
|
366
|
+
const order: string[] = reader.getSeedingOrder(skipEntities?);
|
|
367
|
+
// Independent entities first, then dependents
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### DataGenerator
|
|
371
|
+
|
|
372
|
+
Generates realistic sample data using Faker.js:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import { DataGenerator, IColumnInfo } from '@flusys/nestjs-core/seeders';
|
|
376
|
+
|
|
377
|
+
const generator = new DataGenerator('en');
|
|
378
|
+
|
|
379
|
+
// Generate value for a column
|
|
380
|
+
const value = generator.generateValue(columnInfo);
|
|
381
|
+
|
|
382
|
+
// Generate complete entity
|
|
383
|
+
const entity = generator.generateEntity(columns);
|
|
384
|
+
|
|
385
|
+
// Relation helpers
|
|
386
|
+
const relatedId = generator.generateRelationId(relatedEntities);
|
|
387
|
+
const relatedIds = generator.generateRelationIds(relatedEntities, min?, max?);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Field Pattern Detection
|
|
393
|
+
|
|
394
|
+
Intelligent field pattern detection for realistic data generation.
|
|
395
|
+
|
|
396
|
+
### Supported Patterns
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { detectFieldPattern, FieldPatternType } from '@flusys/nestjs-core/seeders';
|
|
400
|
+
|
|
401
|
+
// Pattern detection returns one of 58 patterns:
|
|
402
|
+
type FieldPatternType =
|
|
403
|
+
| 'skip' | 'null' | 'boolean' | 'token'
|
|
404
|
+
| 'firstName' | 'lastName' | 'fullName'
|
|
405
|
+
| 'email' | 'phone'
|
|
406
|
+
| 'address' | 'street' | 'city' | 'state' | 'country' | 'zipCode'
|
|
407
|
+
| 'url' | 'domain' | 'slug'
|
|
408
|
+
| 'description' | 'summary' | 'content' | 'title'
|
|
409
|
+
| 'username' | 'password'
|
|
410
|
+
| 'birthdate' | 'futureDate' | 'recentDateOrNull'
|
|
411
|
+
| 'serial' | 'company'
|
|
412
|
+
| /* ...more */;
|
|
413
|
+
|
|
414
|
+
// Detect pattern for a column
|
|
415
|
+
const pattern = detectFieldPattern(column);
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### System Fields
|
|
419
|
+
|
|
420
|
+
Automatically handled fields:
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import { SYSTEM_FIELDS, AUDIT_FIELDS, IDENTITY_FIELDS, BOOLEAN_KEYWORDS } from '@flusys/nestjs-core/seeders';
|
|
424
|
+
|
|
425
|
+
SYSTEM_FIELDS = ['id', 'createdAt', 'updatedAt', 'deletedAt', ...];
|
|
426
|
+
AUDIT_FIELDS = ['createdbyid', 'updatedbyid', 'deletedbyid'];
|
|
427
|
+
IDENTITY_FIELDS = ['id', 'createdat', 'updatedat', 'deletedat'];
|
|
428
|
+
BOOLEAN_KEYWORDS = ['verified', 'active', 'enabled', 'public', 'readonly', 'valid'];
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Type Category Detection
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import { detectTypeCategory, getStringLengthCategory } from '@flusys/nestjs-core/seeders';
|
|
435
|
+
|
|
436
|
+
// Categorize database type
|
|
437
|
+
const category = detectTypeCategory('varchar'); // 'string'
|
|
438
|
+
// Categories: string | integer | decimal | boolean | date | timestamp | time | uuid | json | array | unknown
|
|
439
|
+
|
|
440
|
+
// String length categorization
|
|
441
|
+
const lengthCategory = getStringLengthCategory(255); // 'sentence'
|
|
442
|
+
// ≤ 50 chars → 'word'
|
|
443
|
+
// ≤ 255 chars → 'sentence'
|
|
444
|
+
// > 255 chars → 'paragraph'
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
147
449
|
## Swagger Documentation
|
|
148
450
|
|
|
451
|
+
### Setup Functions
|
|
452
|
+
|
|
149
453
|
```typescript
|
|
150
|
-
import { setupSwaggerDocs, setupModuleSwaggerDocs } from '@flusys/nestjs-core/docs';
|
|
454
|
+
import { setupSwaggerDocs, setupModuleSwaggerDocs, IModuleSwaggerOptions } from '@flusys/nestjs-core/docs';
|
|
151
455
|
|
|
152
456
|
// Variadic API for multiple configs
|
|
153
|
-
setupSwaggerDocs(app, authConfig, adminConfig);
|
|
457
|
+
setupSwaggerDocs(app, authConfig, adminConfig, iamConfig);
|
|
154
458
|
|
|
155
459
|
// Array API for module docs
|
|
156
460
|
setupModuleSwaggerDocs(app, [
|
|
@@ -159,72 +463,177 @@ setupModuleSwaggerDocs(app, [
|
|
|
159
463
|
]);
|
|
160
464
|
```
|
|
161
465
|
|
|
466
|
+
### Configuration Options
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
interface IModuleSwaggerOptions {
|
|
470
|
+
modules?: Type<unknown>[]; // Include specific modules
|
|
471
|
+
title: string;
|
|
472
|
+
description: string;
|
|
473
|
+
version?: string; // Default: '1.0'
|
|
474
|
+
path: string; // Swagger UI path
|
|
475
|
+
bearerAuth?: boolean; // Add JWT auth
|
|
476
|
+
globalHeaders?: ISwaggerGlobalHeader[];
|
|
477
|
+
excludeTags?: string[]; // Hide endpoints by tag
|
|
478
|
+
excludeSchemaProperties?: ISchemaPropertyExclusion[];
|
|
479
|
+
excludeQueryParameters?: IQueryParameterExclusion[];
|
|
480
|
+
excludeExamples?: IExampleExclusion[];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
interface ISchemaPropertyExclusion {
|
|
484
|
+
schemaName: string;
|
|
485
|
+
properties: string[];
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
interface IQueryParameterExclusion {
|
|
489
|
+
pathPattern: string; // Supports wildcards: /iam/permissions/*
|
|
490
|
+
method?: string; // Optional: 'post', 'get', etc.
|
|
491
|
+
parameters: string[];
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
162
495
|
### Conditional Schema Exclusion
|
|
163
496
|
|
|
164
497
|
```typescript
|
|
165
498
|
setupModuleSwaggerDocs(app, [{
|
|
166
499
|
title: 'Auth API',
|
|
167
500
|
path: 'auth/docs',
|
|
501
|
+
bearerAuth: true,
|
|
168
502
|
excludeSchemaProperties: enableCompanyFeature ? undefined : [
|
|
169
503
|
{ schemaName: 'LoginResponseDto', properties: ['company', 'branch'] },
|
|
504
|
+
{ schemaName: 'UserDto', properties: ['companyId'] },
|
|
170
505
|
],
|
|
506
|
+
excludeTags: enableCompanyFeature ? undefined : ['Companies', 'Branches'],
|
|
171
507
|
}]);
|
|
172
508
|
```
|
|
173
509
|
|
|
510
|
+
---
|
|
511
|
+
|
|
174
512
|
## API Reference
|
|
175
513
|
|
|
514
|
+
### Interfaces
|
|
515
|
+
|
|
176
516
|
```typescript
|
|
177
|
-
// Interfaces
|
|
178
517
|
import {
|
|
179
|
-
IDatabaseConfig,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
518
|
+
IDatabaseConfig,
|
|
519
|
+
ITenantDatabaseConfig,
|
|
520
|
+
IBootstrapAppConfig,
|
|
521
|
+
IDynamicModuleConfig,
|
|
522
|
+
IDataSourceServiceOptions,
|
|
523
|
+
IModuleOptionsFactory,
|
|
524
|
+
IAsyncModuleOptions,
|
|
525
|
+
IMigrationConfig,
|
|
526
|
+
IMigrationResult,
|
|
527
|
+
IBaseEntity,
|
|
528
|
+
ISoftDeletable,
|
|
529
|
+
ITimestampable,
|
|
530
|
+
IOrderable,
|
|
531
|
+
ICompanyOwned,
|
|
532
|
+
IMetadata,
|
|
183
533
|
} from '@flusys/nestjs-core';
|
|
534
|
+
```
|
|
184
535
|
|
|
185
|
-
|
|
536
|
+
### Constants
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
186
539
|
import { MODULE_OPTIONS, DEFAULT_TENANT_HEADER } from '@flusys/nestjs-core';
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Config
|
|
187
543
|
|
|
188
|
-
|
|
544
|
+
```typescript
|
|
189
545
|
import { envConfig } from '@flusys/nestjs-core/config';
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Utils
|
|
190
549
|
|
|
191
|
-
|
|
550
|
+
```typescript
|
|
192
551
|
import {
|
|
193
|
-
buildDataSourceOptions,
|
|
194
|
-
|
|
552
|
+
buildDataSourceOptions,
|
|
553
|
+
getDatabaseForTenant,
|
|
554
|
+
resolveEntities,
|
|
555
|
+
getActiveTenants,
|
|
556
|
+
getMigrationsFolderPath,
|
|
557
|
+
getMigrationsGlobPattern,
|
|
195
558
|
} from '@flusys/nestjs-core/utils';
|
|
559
|
+
```
|
|
196
560
|
|
|
197
|
-
|
|
561
|
+
### Migration
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
198
564
|
import {
|
|
199
|
-
createMigrationDataSource,
|
|
200
|
-
|
|
201
|
-
|
|
565
|
+
createMigrationDataSource,
|
|
566
|
+
initializeDataSource,
|
|
567
|
+
runMigrationCli,
|
|
568
|
+
generateMigration,
|
|
569
|
+
runMigrations,
|
|
570
|
+
revertMigration,
|
|
571
|
+
migrationStatus,
|
|
572
|
+
runForAllTenants,
|
|
573
|
+
ensureMigrationsFolder,
|
|
202
574
|
} from '@flusys/nestjs-core/migration';
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Seeders
|
|
203
578
|
|
|
204
|
-
|
|
579
|
+
```typescript
|
|
205
580
|
import {
|
|
206
|
-
BaseSeeder,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
581
|
+
BaseSeeder,
|
|
582
|
+
SeedRunner,
|
|
583
|
+
EntityReader,
|
|
584
|
+
DataGenerator,
|
|
585
|
+
TemplateGenerator,
|
|
586
|
+
seedConfig,
|
|
587
|
+
ISeedConfig,
|
|
588
|
+
configureSeedConfig,
|
|
589
|
+
runSeedCli,
|
|
590
|
+
getEntityCount,
|
|
591
|
+
shouldSkipEntity,
|
|
592
|
+
getSeedingOrder,
|
|
593
|
+
ISeedResult,
|
|
594
|
+
ISeedOptions,
|
|
595
|
+
ISeederLogger,
|
|
596
|
+
defaultLogger,
|
|
597
|
+
IEntityInfo,
|
|
598
|
+
IColumnInfo,
|
|
599
|
+
IRelationInfo,
|
|
600
|
+
// Field patterns
|
|
601
|
+
detectFieldPattern,
|
|
602
|
+
detectTypeCategory,
|
|
603
|
+
getStringLengthCategory,
|
|
604
|
+
isSystemField,
|
|
605
|
+
getTokenLength,
|
|
606
|
+
FieldPatternType,
|
|
607
|
+
SYSTEM_FIELDS,
|
|
608
|
+
AUDIT_FIELDS,
|
|
609
|
+
IDENTITY_FIELDS,
|
|
610
|
+
BOOLEAN_KEYWORDS,
|
|
211
611
|
} from '@flusys/nestjs-core/seeders';
|
|
612
|
+
```
|
|
212
613
|
|
|
213
|
-
|
|
614
|
+
### Swagger
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
214
617
|
import {
|
|
215
|
-
setupSwaggerDocs,
|
|
216
|
-
|
|
217
|
-
|
|
618
|
+
setupSwaggerDocs,
|
|
619
|
+
setupModuleSwaggerDocs,
|
|
620
|
+
IModuleSwaggerOptions,
|
|
621
|
+
ISchemaPropertyExclusion,
|
|
622
|
+
IQueryParameterExclusion,
|
|
623
|
+
ISwaggerGlobalHeader,
|
|
624
|
+
IExampleExclusion,
|
|
218
625
|
} from '@flusys/nestjs-core/docs';
|
|
219
626
|
```
|
|
220
627
|
|
|
628
|
+
---
|
|
629
|
+
|
|
221
630
|
## Dependencies
|
|
222
631
|
|
|
223
632
|
- `dotenv` - Environment variable loading
|
|
224
|
-
- `typeorm` - Migration/seeder utilities
|
|
633
|
+
- `typeorm` - Migration/seeder utilities (DataSource, EntityMetadata)
|
|
225
634
|
- `@faker-js/faker` - Seed data generation
|
|
226
635
|
- `@nestjs/common`, `@nestjs/swagger` - Swagger documentation setup only
|
|
227
636
|
|
|
228
637
|
---
|
|
229
638
|
|
|
230
|
-
**Last Updated:** 2026-02-
|
|
639
|
+
**Last Updated:** 2026-02-21
|