@flusys/nestjs-core 1.1.0-beta → 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 +505 -63
- package/cjs/config/env-config.service.js +1 -1
- package/cjs/docs/docs.config.js +77 -3
- package/cjs/docs/index.js +0 -1
- package/cjs/interfaces/base-entity.interface.js +5 -3
- package/cjs/interfaces/database.interface.js +1 -3
- package/cjs/migration/datasource.factory.js +1 -3
- package/cjs/migration/index.js +0 -12
- package/cjs/migration/migration.cli.js +1 -17
- package/cjs/migration/migration.runner.js +37 -65
- package/cjs/seeders/base-seeder.js +6 -25
- package/cjs/seeders/cli.js +65 -172
- package/cjs/seeders/data-generator.js +96 -142
- package/cjs/seeders/entity-reader.js +0 -17
- package/cjs/seeders/field-patterns.js +172 -0
- package/cjs/seeders/index.js +16 -8
- package/cjs/seeders/seed-config.js +9 -48
- package/cjs/seeders/seed-runner.js +8 -14
- package/cjs/utils/datasource-config.builder.js +2 -14
- package/docs/docs.config.d.ts +7 -0
- package/docs/index.d.ts +0 -1
- package/fesm/config/env-config.service.js +1 -1
- package/fesm/docs/docs.config.js +68 -0
- package/fesm/docs/index.js +0 -1
- package/fesm/interfaces/app-config.interfaces.js +1 -3
- package/fesm/interfaces/base-entity.interface.js +5 -5
- package/fesm/interfaces/database.interface.js +1 -5
- package/fesm/migration/cli.js +1 -20
- package/fesm/migration/datasource.factory.js +3 -20
- package/fesm/migration/index.js +0 -14
- package/fesm/migration/migration.cli.js +1 -17
- package/fesm/migration/migration.runner.js +43 -132
- package/fesm/seeders/base-seeder.js +7 -51
- package/fesm/seeders/cli.js +65 -182
- package/fesm/seeders/data-generator.js +96 -149
- package/fesm/seeders/entity-reader.js +0 -17
- package/fesm/seeders/field-patterns.js +143 -0
- package/fesm/seeders/index.js +3 -7
- package/fesm/seeders/seed-config.js +9 -59
- package/fesm/seeders/seed-runner.js +8 -14
- package/fesm/utils/datasource-config.builder.js +2 -13
- package/interfaces/base-entity.interface.d.ts +3 -0
- package/package.json +2 -2
- package/seeders/data-generator.d.ts +1 -1
- package/seeders/entity-reader.d.ts +0 -1
- package/seeders/field-patterns.d.ts +12 -0
- package/seeders/index.d.ts +3 -3
- package/seeders/seed-config.d.ts +1 -0
- package/seeders/seed-runner.d.ts +1 -0
- package/utils/datasource-config.builder.d.ts +0 -1
- 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:** Pure TypeScript
|
|
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
|
}
|
|
@@ -76,122 +131,509 @@ interface IBootstrapAppConfig {
|
|
|
76
131
|
}
|
|
77
132
|
```
|
|
78
133
|
|
|
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;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
interface IMetadata {
|
|
158
|
+
metadata?: Record<string, any> | null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
interface ICompanyOwned {
|
|
162
|
+
companyId?: string | null;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Migration System
|
|
169
|
+
|
|
170
|
+
### CLI Commands
|
|
80
171
|
|
|
81
172
|
```bash
|
|
82
|
-
npm run migration:generate --
|
|
83
|
-
npm run migration:run
|
|
84
|
-
npm run migration:revert
|
|
85
|
-
npm run migration:status
|
|
86
|
-
TENANT_ID=tenant1 npm run migration:run
|
|
87
|
-
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
|
|
88
181
|
```
|
|
89
182
|
|
|
183
|
+
### Migration Configuration
|
|
184
|
+
|
|
90
185
|
```typescript
|
|
91
|
-
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
|
+
};
|
|
92
214
|
```
|
|
93
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
|
+
|
|
94
246
|
## Seed System
|
|
95
247
|
|
|
248
|
+
### CLI Commands
|
|
249
|
+
|
|
96
250
|
```bash
|
|
97
|
-
npm run seed:
|
|
98
|
-
npm run seed:run -- --entity=User --count=100
|
|
99
|
-
npm run seed:clear
|
|
100
|
-
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
|
|
101
258
|
```
|
|
102
259
|
|
|
260
|
+
### Seed Configuration
|
|
261
|
+
|
|
103
262
|
```typescript
|
|
104
|
-
import {
|
|
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
|
+
}
|
|
272
|
+
|
|
273
|
+
// Configure before running seeders
|
|
274
|
+
configureSeedConfig({
|
|
275
|
+
counts: { User: 50, Product: 100, Order: 200 },
|
|
276
|
+
order: ['User', 'Company', 'Product', 'Order'],
|
|
277
|
+
skipEntities: ['migrations', 'typeorm_metadata', 'Migration'],
|
|
278
|
+
locale: 'en',
|
|
279
|
+
respectSoftDelete: true,
|
|
280
|
+
});
|
|
281
|
+
```
|
|
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
|
+
|
|
317
|
+
### Custom Seeders
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { BaseSeeder, DataGenerator } from '@flusys/nestjs-core/seeders';
|
|
105
321
|
|
|
106
322
|
class UserSeeder extends BaseSeeder<User> {
|
|
107
|
-
|
|
323
|
+
private generator: DataGenerator;
|
|
324
|
+
|
|
325
|
+
constructor(ds: DataSource) {
|
|
326
|
+
super(ds, User);
|
|
327
|
+
this.generator = new DataGenerator('en');
|
|
328
|
+
}
|
|
329
|
+
|
|
108
330
|
async generate(count: number): Promise<User[]> {
|
|
109
|
-
const users = [];
|
|
331
|
+
const users: User[] = [];
|
|
110
332
|
for (let i = 0; i < count; i++) {
|
|
111
|
-
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
|
+
}));
|
|
112
338
|
}
|
|
113
339
|
return this.repository.save(users);
|
|
114
340
|
}
|
|
115
341
|
}
|
|
116
342
|
|
|
343
|
+
// Register before running
|
|
117
344
|
const runner = new SeedRunner(dataSource);
|
|
118
345
|
runner.registerCustomSeeder('User', new UserSeeder(dataSource));
|
|
119
346
|
await runner.runAll({ count: 50, clear: true });
|
|
120
347
|
```
|
|
121
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
|
+
|
|
122
449
|
## Swagger Documentation
|
|
123
450
|
|
|
451
|
+
### Setup Functions
|
|
452
|
+
|
|
124
453
|
```typescript
|
|
125
|
-
import { setupSwaggerDocs, setupModuleSwaggerDocs } from '@flusys/nestjs-core/docs';
|
|
454
|
+
import { setupSwaggerDocs, setupModuleSwaggerDocs, IModuleSwaggerOptions } from '@flusys/nestjs-core/docs';
|
|
455
|
+
|
|
456
|
+
// Variadic API for multiple configs
|
|
457
|
+
setupSwaggerDocs(app, authConfig, adminConfig, iamConfig);
|
|
126
458
|
|
|
459
|
+
// Array API for module docs
|
|
127
460
|
setupModuleSwaggerDocs(app, [
|
|
128
461
|
{ title: 'Auth API', path: 'auth/docs', bearerAuth: true },
|
|
129
462
|
{ title: 'Admin API', path: 'admin/docs', excludeTags: ['public'] },
|
|
130
463
|
]);
|
|
131
464
|
```
|
|
132
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
|
+
|
|
133
495
|
### Conditional Schema Exclusion
|
|
134
496
|
|
|
135
497
|
```typescript
|
|
136
498
|
setupModuleSwaggerDocs(app, [{
|
|
137
499
|
title: 'Auth API',
|
|
138
500
|
path: 'auth/docs',
|
|
501
|
+
bearerAuth: true,
|
|
139
502
|
excludeSchemaProperties: enableCompanyFeature ? undefined : [
|
|
140
503
|
{ schemaName: 'LoginResponseDto', properties: ['company', 'branch'] },
|
|
504
|
+
{ schemaName: 'UserDto', properties: ['companyId'] },
|
|
141
505
|
],
|
|
506
|
+
excludeTags: enableCompanyFeature ? undefined : ['Companies', 'Branches'],
|
|
142
507
|
}]);
|
|
143
508
|
```
|
|
144
509
|
|
|
510
|
+
---
|
|
511
|
+
|
|
145
512
|
## API Reference
|
|
146
513
|
|
|
514
|
+
### Interfaces
|
|
515
|
+
|
|
147
516
|
```typescript
|
|
148
|
-
// Interfaces
|
|
149
517
|
import {
|
|
150
|
-
IDatabaseConfig,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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,
|
|
154
533
|
} from '@flusys/nestjs-core';
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Constants
|
|
155
537
|
|
|
156
|
-
|
|
538
|
+
```typescript
|
|
157
539
|
import { MODULE_OPTIONS, DEFAULT_TENANT_HEADER } from '@flusys/nestjs-core';
|
|
540
|
+
```
|
|
158
541
|
|
|
159
|
-
|
|
542
|
+
### Config
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
160
545
|
import { envConfig } from '@flusys/nestjs-core/config';
|
|
546
|
+
```
|
|
161
547
|
|
|
162
|
-
|
|
548
|
+
### Utils
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
163
551
|
import {
|
|
164
|
-
buildDataSourceOptions,
|
|
165
|
-
|
|
552
|
+
buildDataSourceOptions,
|
|
553
|
+
getDatabaseForTenant,
|
|
554
|
+
resolveEntities,
|
|
555
|
+
getActiveTenants,
|
|
556
|
+
getMigrationsFolderPath,
|
|
557
|
+
getMigrationsGlobPattern,
|
|
166
558
|
} from '@flusys/nestjs-core/utils';
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Migration
|
|
167
562
|
|
|
168
|
-
|
|
563
|
+
```typescript
|
|
169
564
|
import {
|
|
170
|
-
createMigrationDataSource,
|
|
171
|
-
|
|
565
|
+
createMigrationDataSource,
|
|
566
|
+
initializeDataSource,
|
|
567
|
+
runMigrationCli,
|
|
568
|
+
generateMigration,
|
|
569
|
+
runMigrations,
|
|
570
|
+
revertMigration,
|
|
571
|
+
migrationStatus,
|
|
572
|
+
runForAllTenants,
|
|
573
|
+
ensureMigrationsFolder,
|
|
172
574
|
} from '@flusys/nestjs-core/migration';
|
|
575
|
+
```
|
|
173
576
|
|
|
174
|
-
|
|
577
|
+
### Seeders
|
|
578
|
+
|
|
579
|
+
```typescript
|
|
175
580
|
import {
|
|
176
|
-
BaseSeeder,
|
|
177
|
-
|
|
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,
|
|
178
611
|
} from '@flusys/nestjs-core/seeders';
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Swagger
|
|
179
615
|
|
|
180
|
-
|
|
616
|
+
```typescript
|
|
181
617
|
import {
|
|
182
|
-
setupSwaggerDocs,
|
|
183
|
-
|
|
618
|
+
setupSwaggerDocs,
|
|
619
|
+
setupModuleSwaggerDocs,
|
|
620
|
+
IModuleSwaggerOptions,
|
|
621
|
+
ISchemaPropertyExclusion,
|
|
622
|
+
IQueryParameterExclusion,
|
|
623
|
+
ISwaggerGlobalHeader,
|
|
624
|
+
IExampleExclusion,
|
|
184
625
|
} from '@flusys/nestjs-core/docs';
|
|
185
626
|
```
|
|
186
627
|
|
|
628
|
+
---
|
|
629
|
+
|
|
187
630
|
## Dependencies
|
|
188
631
|
|
|
189
632
|
- `dotenv` - Environment variable loading
|
|
190
|
-
- `typeorm` - Migration/seeder utilities
|
|
633
|
+
- `typeorm` - Migration/seeder utilities (DataSource, EntityMetadata)
|
|
191
634
|
- `@faker-js/faker` - Seed data generation
|
|
192
|
-
|
|
193
|
-
**No NestJS dependencies** - Can be used in any TypeScript project.
|
|
635
|
+
- `@nestjs/common`, `@nestjs/swagger` - Swagger documentation setup only
|
|
194
636
|
|
|
195
637
|
---
|
|
196
638
|
|
|
197
|
-
**Last Updated:** 2026-02-
|
|
639
|
+
**Last Updated:** 2026-02-21
|