@flusys/nestjs-core 1.1.0 → 1.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +113 -581
  2. package/cjs/config/env-config.service.js +13 -9
  3. package/cjs/docs/docs.config.js +25 -15
  4. package/cjs/index.js +0 -1
  5. package/config/env-config.service.d.ts +3 -1
  6. package/docs/docs.config.d.ts +1 -0
  7. package/fesm/config/env-config.service.js +13 -9
  8. package/fesm/docs/docs.config.js +27 -21
  9. package/fesm/index.js +0 -2
  10. package/index.d.ts +0 -1
  11. package/interfaces/base-entity.interface.d.ts +0 -3
  12. package/interfaces/database.interface.d.ts +1 -1
  13. package/package.json +8 -8
  14. package/cjs/seeders/base-seeder.js +0 -76
  15. package/cjs/seeders/cli.js +0 -291
  16. package/cjs/seeders/data-generator.js +0 -215
  17. package/cjs/seeders/entity-reader.js +0 -151
  18. package/cjs/seeders/field-patterns.js +0 -176
  19. package/cjs/seeders/index.js +0 -85
  20. package/cjs/seeders/seed-config.js +0 -62
  21. package/cjs/seeders/seed-runner.js +0 -314
  22. package/fesm/seeders/base-seeder.js +0 -66
  23. package/fesm/seeders/cli.js +0 -249
  24. package/fesm/seeders/data-generator.js +0 -210
  25. package/fesm/seeders/entity-reader.js +0 -153
  26. package/fesm/seeders/field-patterns.js +0 -147
  27. package/fesm/seeders/index.js +0 -7
  28. package/fesm/seeders/seed-config.js +0 -35
  29. package/fesm/seeders/seed-runner.js +0 -317
  30. package/seeders/base-seeder.d.ts +0 -14
  31. package/seeders/cli.d.ts +0 -3
  32. package/seeders/data-generator.d.ts +0 -15
  33. package/seeders/entity-reader.d.ts +0 -44
  34. package/seeders/field-patterns.d.ts +0 -12
  35. package/seeders/index.d.ts +0 -7
  36. package/seeders/seed-config.d.ts +0 -12
  37. package/seeders/seed-runner.d.ts +0 -48
@@ -1,147 +0,0 @@
1
- /** System fields that should be skipped during generation */ export const SYSTEM_FIELDS = [
2
- 'id',
3
- 'createdAt',
4
- 'updatedAt',
5
- 'deletedAt',
6
- 'createdById',
7
- 'updatedById',
8
- 'deletedById'
9
- ];
10
- /** Audit fields that return null */ export const AUDIT_FIELDS = [
11
- 'createdbyid',
12
- 'updatedbyid',
13
- 'deletedbyid'
14
- ];
15
- /** Identity fields that are skipped */ export const IDENTITY_FIELDS = [
16
- 'id',
17
- 'createdat',
18
- 'updatedat',
19
- 'deletedat'
20
- ];
21
- /** Boolean indicator keywords */ export const BOOLEAN_KEYWORDS = [
22
- 'verified',
23
- 'active',
24
- 'enabled',
25
- 'public',
26
- 'readonly',
27
- 'valid'
28
- ];
29
- /**
30
- * Detect field pattern from column name
31
- */ export function detectFieldPattern(column) {
32
- const nameLower = column.propertyName.toLowerCase();
33
- const typeLower = column.type.toLowerCase();
34
- // Identity fields (skip)
35
- if (IDENTITY_FIELDS.includes(nameLower)) return 'skip';
36
- // Audit fields (null)
37
- if (AUDIT_FIELDS.includes(nameLower)) return 'null';
38
- // Boolean fields with specific keywords
39
- if ((typeLower === 'boolean' || typeLower === 'bool') && BOOLEAN_KEYWORDS.some((k)=>nameLower.includes(k))) {
40
- return 'boolean';
41
- }
42
- // Token fields
43
- if (nameLower.includes('token')) return 'token';
44
- // Name fields
45
- if (nameLower.includes('firstname')) return 'firstName';
46
- if (nameLower.includes('lastname')) return 'lastName';
47
- if (nameLower.includes('fullname') || nameLower === 'name') return 'fullName';
48
- // Contact fields
49
- if (nameLower.includes('email') && typeLower !== 'boolean') return 'email';
50
- if (nameLower.includes('phone') || nameLower.includes('mobile')) return 'phone';
51
- // Location fields
52
- if (nameLower.includes('address')) return 'address';
53
- if (nameLower.includes('street')) return 'street';
54
- if (nameLower.includes('city')) return 'city';
55
- if (nameLower.includes('state')) return 'state';
56
- if (nameLower.includes('country')) return 'country';
57
- if (nameLower.includes('zipcode') || nameLower.includes('postalcode')) return 'zipCode';
58
- // URL/Web fields
59
- if (nameLower.includes('url') || nameLower.includes('website')) return 'url';
60
- if (nameLower.includes('domain')) return 'domain';
61
- if (nameLower.includes('slug')) return 'slug';
62
- // Text fields
63
- if (nameLower.includes('description')) return 'description';
64
- if (nameLower.includes('summary')) return 'summary';
65
- if (nameLower.includes('content')) return 'content';
66
- if (nameLower.includes('title')) return 'title';
67
- // User fields
68
- if (nameLower.includes('username')) return 'username';
69
- if (nameLower.includes('password')) return 'password';
70
- // Boolean status fields (fallback)
71
- if (nameLower.includes('isactive') || nameLower.includes('isenabled') || nameLower.includes('ispublic') || nameLower.includes('isverified')) {
72
- return 'boolean';
73
- }
74
- // Date fields
75
- if (nameLower.includes('birthdate') || nameLower.includes('dateofbirth')) return 'birthdate';
76
- if (nameLower.includes('expiresat') || nameLower.includes('expirydate')) return 'futureDate';
77
- if (nameLower.includes('verifiedat')) return 'recentDateOrNull';
78
- // Serial/Order fields
79
- if (nameLower.includes('serial') || nameLower.includes('order')) return 'serial';
80
- // Company
81
- if (nameLower.includes('company') && !nameLower.includes('id')) return 'company';
82
- // Email provider type
83
- if (nameLower === 'provider' || nameLower === 'emailprovider') return 'emailProvider';
84
- // Form access type
85
- if (nameLower === 'accesstype' || nameLower === 'access_type') return 'formAccessType';
86
- return undefined;
87
- }
88
- /**
89
- * Detect column type category
90
- */ export function detectTypeCategory(type) {
91
- const typeLower = type.toLowerCase();
92
- if ([
93
- 'varchar',
94
- 'character varying',
95
- 'text',
96
- 'string'
97
- ].includes(typeLower)) return 'string';
98
- if ([
99
- 'int',
100
- 'integer',
101
- 'smallint',
102
- 'bigint'
103
- ].includes(typeLower)) return 'integer';
104
- if ([
105
- 'decimal',
106
- 'numeric',
107
- 'float',
108
- 'double',
109
- 'real'
110
- ].includes(typeLower)) return 'decimal';
111
- if ([
112
- 'boolean',
113
- 'bool'
114
- ].includes(typeLower)) return 'boolean';
115
- if (typeLower === 'date') return 'date';
116
- if ([
117
- 'timestamp',
118
- 'datetime'
119
- ].includes(typeLower)) return 'timestamp';
120
- if (typeLower === 'time') return 'time';
121
- if (typeLower === 'uuid') return 'uuid';
122
- if ([
123
- 'json',
124
- 'jsonb'
125
- ].includes(typeLower)) return 'json';
126
- if (typeLower === 'array') return 'array';
127
- return 'unknown';
128
- }
129
- /**
130
- * Get string length category for faker generation
131
- */ export function getStringLengthCategory(length) {
132
- const maxLength = typeof length === 'number' ? length : 255;
133
- if (maxLength <= 50) return 'word';
134
- if (maxLength <= 255) return 'sentence';
135
- return 'paragraph';
136
- }
137
- /**
138
- * Check if field is a system field
139
- */ export function isSystemField(fieldName) {
140
- return SYSTEM_FIELDS.includes(fieldName);
141
- }
142
- /**
143
- * Get token max length respecting column constraints
144
- */ export function getTokenLength(column) {
145
- const maxLength = typeof column.length === 'number' ? column.length : 64;
146
- return Math.min(maxLength, 32);
147
- }
@@ -1,7 +0,0 @@
1
- export { BaseSeeder } from './base-seeder';
2
- export { EntityReader, IEntityInfo, IColumnInfo, IRelationInfo } from './entity-reader';
3
- export { DataGenerator } from './data-generator';
4
- export { SeedRunner, ISeedResult, ISeedOptions, ISeederLogger, defaultLogger } from './seed-runner';
5
- export { seedConfig, ISeedConfig, getEntityCount, shouldSkipEntity, getSeedingOrder, configureSeedConfig } from './seed-config';
6
- export { SYSTEM_FIELDS, isSystemField, detectFieldPattern, detectTypeCategory } from './field-patterns';
7
- export { runSeedCli } from './cli';
@@ -1,35 +0,0 @@
1
- export const seedConfig = {
2
- counts: {},
3
- order: [],
4
- skipEntities: [
5
- 'migrations',
6
- 'typeorm_metadata',
7
- 'Migration',
8
- 'Typeorm_Metadata'
9
- ],
10
- locale: 'en',
11
- respectSoftDelete: true
12
- };
13
- export function configureSeedConfig(config) {
14
- Object.assign(seedConfig, config);
15
- }
16
- export function getEntityCount(entityName, config = seedConfig) {
17
- return config.counts[entityName] || 10;
18
- }
19
- export function shouldSkipEntity(entityName, config = seedConfig) {
20
- return config.skipEntities.some((skip)=>skip.toLowerCase() === entityName.toLowerCase());
21
- }
22
- export function getSeedingOrder(availableEntities, config = seedConfig) {
23
- const ordered = [];
24
- for (const entityName of config.order){
25
- if (availableEntities.includes(entityName) && !shouldSkipEntity(entityName, config)) {
26
- ordered.push(entityName);
27
- }
28
- }
29
- for (const entityName of availableEntities){
30
- if (!ordered.includes(entityName) && !shouldSkipEntity(entityName, config)) {
31
- ordered.push(entityName);
32
- }
33
- }
34
- return ordered;
35
- }
@@ -1,317 +0,0 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- import { EntityReader } from './entity-reader';
15
- import { DataGenerator } from './data-generator';
16
- import { BaseSeeder } from './base-seeder';
17
- import { seedConfig, getEntityCount, shouldSkipEntity, getSeedingOrder } from './seed-config';
18
- /**
19
- * Default console logger implementation
20
- */ export const defaultLogger = {
21
- log: (message)=>console.log(message),
22
- error: (message)=>console.error(message)
23
- };
24
- /**
25
- * Seed Runner Service
26
- *
27
- * Orchestrates seed data generation across all entities.
28
- * Handles dependency order, transactions, and error reporting.
29
- *
30
- * Usage:
31
- * ```typescript
32
- * const runner = new SeedRunner(dataSource);
33
- * await runner.runAll();
34
- * await runner.runSingle('User', { count: 50 });
35
- * await runner.clearAll();
36
- *
37
- * // With custom logger
38
- * const runner = new SeedRunner(dataSource, customLogger);
39
- *
40
- * // With custom seeder
41
- * runner.registerCustomSeeder('User', new UserSeeder(dataSource));
42
- * ```
43
- */ export class SeedRunner {
44
- /**
45
- * Register a custom seeder for specific entity
46
- * Custom seeders take precedence over generic seeders
47
- * @param entityName Entity name
48
- * @param seeder Custom seeder instance
49
- */ registerCustomSeeder(entityName, seeder) {
50
- this.customSeeders.set(entityName, seeder);
51
- }
52
- /**
53
- * Unregister a custom seeder
54
- * @param entityName Entity name
55
- */ unregisterCustomSeeder(entityName) {
56
- this.customSeeders.delete(entityName);
57
- }
58
- /**
59
- * Check if entity has custom seeder registered
60
- * @param entityName Entity name
61
- */ hasCustomSeeder(entityName) {
62
- return this.customSeeders.has(entityName);
63
- }
64
- getSeeder(entityName, entity, dataSource, entityInfo, batchSize) {
65
- if (this.customSeeders.has(entityName)) {
66
- return this.customSeeders.get(entityName);
67
- }
68
- return new GenericSeeder(dataSource, entity, this.dataGenerator, entityInfo, batchSize);
69
- }
70
- /**
71
- * Run seeds for all entities
72
- * @param options Seeding options
73
- * @returns Array of seed results
74
- */ async runAll(options = {}) {
75
- const results = [];
76
- const continueOnError = options.continueOnError ?? true;
77
- // Get all entities
78
- const allEntities = this.entityReader.getAllEntities();
79
- const entityNames = allEntities.map((e)=>e.name).filter((name)=>!shouldSkipEntity(name));
80
- // Get seeding order
81
- const orderedNames = getSeedingOrder(entityNames);
82
- const mode = options.dryRun ? 'Previewing' : 'Seeding';
83
- this.logger.log(`\n🌱 ${mode} ${orderedNames.length} entities...\n`);
84
- for(let i = 0; i < orderedNames.length; i++){
85
- const entityName = orderedNames[i];
86
- // Call progress callback
87
- options.onProgress?.(i + 1, orderedNames.length, entityName);
88
- const result = await this.runSingle(entityName, options);
89
- results.push(result);
90
- // Log result
91
- if (result.success) {
92
- if (result.dryRun) {
93
- this.logger.log(`✓ ${entityName}: ${result.count} records (dry run)`);
94
- } else if (result.skipped) {
95
- this.logger.log(`⊘ ${entityName}: skipped (already has data)`);
96
- } else {
97
- this.logger.log(`✓ ${entityName}: ${result.count} records`);
98
- }
99
- } else {
100
- this.logger.error(`✗ ${entityName}: ${result.error}`);
101
- // Fail-fast if continueOnError is false
102
- if (!continueOnError) {
103
- this.logger.error(`\n❌ Seeding failed at ${entityName}, stopping...\n`);
104
- break;
105
- }
106
- }
107
- }
108
- const successCount = results.filter((r)=>r.success).length;
109
- const failedCount = results.length - successCount;
110
- if (failedCount > 0) {
111
- this.logger.log(`\n⚠️ Completed with errors: ${successCount}/${results.length} entities seeded (${failedCount} failed)\n`);
112
- } else {
113
- this.logger.log(`\n✓ Completed: ${successCount}/${results.length} entities seeded\n`);
114
- }
115
- return results;
116
- }
117
- /**
118
- * Run seed for a single entity
119
- * @param entityName Entity name to seed
120
- * @param options Seeding options
121
- * @returns Seed result
122
- */ async runSingle(entityName, options = {}) {
123
- const queryRunner = this.dataSource.createQueryRunner();
124
- await queryRunner.connect();
125
- await queryRunner.startTransaction();
126
- try {
127
- // Get entity info
128
- const entityInfo = this.entityReader.getEntityInfo(entityName);
129
- // Find entity target
130
- const entity = this.dataSource.entityMetadatas.find((e)=>e.name === entityName)?.target;
131
- if (!entity) {
132
- throw new Error(`Entity ${entityName} not found`);
133
- }
134
- const seeder = this.getSeeder(entityName, entity, queryRunner.manager.connection, entityInfo, options.batchSize);
135
- // Dry run mode - preview without executing
136
- if (options.dryRun) {
137
- const count = options.count ?? getEntityCount(entityName);
138
- await queryRunner.rollbackTransaction();
139
- return {
140
- entity: entityName,
141
- success: true,
142
- count,
143
- dryRun: true
144
- };
145
- }
146
- // Skip if exists
147
- if (options.skipIfExists) {
148
- const existingCount = await seeder.count();
149
- if (existingCount > 0) {
150
- await queryRunner.rollbackTransaction();
151
- return {
152
- entity: entityName,
153
- success: true,
154
- count: 0,
155
- skipped: true
156
- };
157
- }
158
- }
159
- // Clear if requested
160
- if (options.clear) {
161
- await seeder.clear(options.respectSoftDelete ?? seedConfig.respectSoftDelete);
162
- }
163
- // Generate data
164
- const count = options.count ?? getEntityCount(entityName);
165
- const entities = await seeder.generate(count);
166
- // Commit transaction
167
- await queryRunner.commitTransaction();
168
- return {
169
- entity: entityName,
170
- success: true,
171
- count: entities.length
172
- };
173
- } catch (error) {
174
- // Rollback on error
175
- await queryRunner.rollbackTransaction();
176
- return {
177
- entity: entityName,
178
- success: false,
179
- count: 0,
180
- error: error instanceof Error ? error.message : String(error)
181
- };
182
- } finally{
183
- await queryRunner.release();
184
- }
185
- }
186
- /**
187
- * Clear all seeded data
188
- * @param hard If true, hard delete (ignore soft delete)
189
- * @param continueOnError If true, continue even if an entity fails (default: true)
190
- * @returns Array of clear results
191
- */ async clearAll(hard = false, continueOnError = true) {
192
- const results = [];
193
- // Get all entities
194
- const allEntities = this.entityReader.getAllEntities();
195
- const entityNames = allEntities.map((e)=>e.name).filter((name)=>!shouldSkipEntity(name));
196
- // Reverse order for clearing (delete children before parents)
197
- const orderedNames = getSeedingOrder(entityNames).reverse();
198
- const mode = hard ? 'Hard deleting' : 'Clearing';
199
- this.logger.log(`\n🗑️ ${mode} ${orderedNames.length} entities...\n`);
200
- for (const entityName of orderedNames){
201
- try {
202
- const entity = this.dataSource.entityMetadatas.find((e)=>e.name === entityName)?.target;
203
- if (!entity) {
204
- throw new Error(`Entity ${entityName} not found`);
205
- }
206
- const seeder = this.getSeeder(entityName, entity, this.dataSource, this.entityReader.getEntityInfo(entityName));
207
- const countBefore = await seeder.count(true);
208
- // Skip if already empty
209
- if (countBefore === 0) {
210
- results.push({
211
- entity: entityName,
212
- success: true,
213
- count: 0
214
- });
215
- this.logger.log(`⊘ ${entityName}: already empty`);
216
- continue;
217
- }
218
- await seeder.clear(hard);
219
- const countAfter = await seeder.count(true);
220
- results.push({
221
- entity: entityName,
222
- success: true,
223
- count: countBefore - countAfter
224
- });
225
- this.logger.log(`✓ ${entityName}: ${countBefore - countAfter} records cleared`);
226
- } catch (error) {
227
- const errorMessage = error instanceof Error ? error.message : String(error);
228
- results.push({
229
- entity: entityName,
230
- success: false,
231
- count: 0,
232
- error: errorMessage
233
- });
234
- this.logger.error(`✗ ${entityName}: ${errorMessage}`);
235
- // Fail-fast if continueOnError is false
236
- if (!continueOnError) {
237
- this.logger.error(`\n❌ Clearing failed at ${entityName}, stopping...\n`);
238
- break;
239
- }
240
- }
241
- }
242
- const successCount = results.filter((r)=>r.success).length;
243
- const failedCount = results.length - successCount;
244
- if (failedCount > 0) {
245
- this.logger.log(`\n⚠️ Completed with errors: ${successCount}/${results.length} entities cleared (${failedCount} failed)\n`);
246
- } else {
247
- this.logger.log(`\n✓ Completed: ${successCount}/${results.length} entities cleared\n`);
248
- }
249
- return results;
250
- }
251
- /**
252
- * Get status for all entities
253
- * @returns Array of entity status
254
- */ async getStatus() {
255
- const allEntities = this.entityReader.getAllEntities();
256
- const status = [];
257
- for (const metadata of allEntities){
258
- if (shouldSkipEntity(metadata.name)) {
259
- continue;
260
- }
261
- const repo = this.dataSource.getRepository(metadata.target);
262
- const count = await repo.count();
263
- const isEmpty = count === 0;
264
- const hasSoftDelete = metadata.deleteDateColumn !== undefined;
265
- status.push({
266
- entity: metadata.name,
267
- tableName: metadata.tableName,
268
- count,
269
- isEmpty,
270
- hasSoftDelete
271
- });
272
- }
273
- return status;
274
- }
275
- constructor(dataSource, logger){
276
- _define_property(this, "dataSource", void 0);
277
- _define_property(this, "entityReader", void 0);
278
- _define_property(this, "dataGenerator", void 0);
279
- _define_property(this, "logger", void 0);
280
- _define_property(this, "customSeeders", void 0);
281
- this.dataSource = dataSource;
282
- this.customSeeders = new Map();
283
- this.entityReader = new EntityReader(dataSource);
284
- this.dataGenerator = new DataGenerator(seedConfig.locale);
285
- this.logger = logger ?? defaultLogger;
286
- }
287
- }
288
- /**
289
- * Generic Seeder Implementation
290
- *
291
- * Used by SeedRunner for entities without custom seeders.
292
- * Generates data based on entity metadata with batch processing support.
293
- */ let GenericSeeder = class GenericSeeder extends BaseSeeder {
294
- async generate(count) {
295
- const allSaved = [];
296
- // Process in batches to optimize memory usage for large datasets
297
- for(let offset = 0; offset < count; offset += this.batchSize){
298
- const currentBatchSize = Math.min(this.batchSize, count - offset);
299
- const batch = [];
300
- for(let i = 0; i < currentBatchSize; i++){
301
- const data = this.generator.generateEntity(this.entityInfo.columns);
302
- // TypeORM's create method returns T, but TypeScript needs explicit type assertion
303
- const entity = this.repository.create(data);
304
- batch.push(entity);
305
- }
306
- // TypeORM's save method has overloads for T and T[]
307
- // We need to explicitly cast to handle the generic type resolution
308
- const saved = await this.repository.save(batch);
309
- allSaved.push(...saved);
310
- }
311
- return allSaved;
312
- }
313
- constructor(dataSource, entity, generator, entityInfo, batchSize){
314
- super(dataSource, entity), _define_property(this, "generator", void 0), _define_property(this, "entityInfo", void 0), _define_property(this, "batchSize", void 0), this.generator = generator, this.entityInfo = entityInfo;
315
- this.batchSize = batchSize ?? 1000; // Default batch size
316
- }
317
- };
@@ -1,14 +0,0 @@
1
- import { DataSource, Repository, EntityTarget, EntityMetadata, ObjectLiteral } from 'typeorm';
2
- export declare abstract class BaseSeeder<T extends ObjectLiteral> {
3
- protected dataSource: DataSource;
4
- protected entity: EntityTarget<T>;
5
- protected repository: Repository<T>;
6
- protected metadata: EntityMetadata;
7
- constructor(dataSource: DataSource, entity: EntityTarget<T>);
8
- abstract generate(count: number): Promise<T[]>;
9
- clear(hard?: boolean): Promise<void>;
10
- count(includeDeleted?: boolean): Promise<number>;
11
- isEmpty(): Promise<boolean>;
12
- getEntityName(): string;
13
- protected withTransaction<R>(operation: (repository: Repository<T>) => Promise<R>): Promise<R>;
14
- }
package/seeders/cli.d.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- declare function main(): Promise<void>;
3
- export { main as runSeedCli };
@@ -1,15 +0,0 @@
1
- import { IColumnInfo } from './entity-reader';
2
- export declare class DataGenerator {
3
- constructor(locale?: string);
4
- generateValue(column: IColumnInfo): any;
5
- generateEntity(columns: IColumnInfo[]): Record<string, any>;
6
- private generateByPattern;
7
- private generateByType;
8
- private generateString;
9
- generateRelationId<T extends {
10
- id: string;
11
- }>(relatedEntities: T[]): string | null;
12
- generateRelationIds<T extends {
13
- id: string;
14
- }>(relatedEntities: T[], min?: number, max?: number): string[];
15
- }
@@ -1,44 +0,0 @@
1
- import { DataSource, EntityMetadata } from 'typeorm';
2
- export interface IColumnInfo {
3
- name: string;
4
- propertyName: string;
5
- type: string;
6
- length?: number | string;
7
- isNullable: boolean;
8
- isUnique: boolean;
9
- isPrimary: boolean;
10
- isGenerated: boolean;
11
- default?: any;
12
- enum?: any[];
13
- precision?: number;
14
- scale?: number;
15
- }
16
- export interface IRelationInfo {
17
- propertyName: string;
18
- type: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';
19
- targetEntity: string;
20
- isNullable: boolean;
21
- joinColumnName?: string;
22
- }
23
- export interface IEntityInfo {
24
- name: string;
25
- tableName: string;
26
- columns: IColumnInfo[];
27
- relations: IRelationInfo[];
28
- hasSoftDelete: boolean;
29
- hasCompany: boolean;
30
- }
31
- export declare class EntityReader {
32
- private readonly dataSource;
33
- constructor(dataSource: DataSource);
34
- getAllEntities(): EntityMetadata[];
35
- getEntityInfo(entityName: string): IEntityInfo;
36
- getSeedingOrder(skipEntities?: string[]): string[];
37
- private findEntityMetadata;
38
- private extractColumns;
39
- private extractRelations;
40
- private hasCompanyColumn;
41
- private getColumnTypeString;
42
- private buildDependencyGraph;
43
- private topologicalSort;
44
- }
@@ -1,12 +0,0 @@
1
- import { IColumnInfo } from './entity-reader';
2
- export declare const SYSTEM_FIELDS: string[];
3
- export declare const AUDIT_FIELDS: string[];
4
- export declare const IDENTITY_FIELDS: string[];
5
- export declare const BOOLEAN_KEYWORDS: string[];
6
- export type FieldPatternType = 'skip' | 'null' | 'boolean' | 'token' | 'firstName' | 'lastName' | 'fullName' | 'email' | 'phone' | 'address' | 'street' | 'city' | 'state' | 'country' | 'zipCode' | 'url' | 'domain' | 'slug' | 'description' | 'summary' | 'content' | 'title' | 'username' | 'password' | 'birthdate' | 'futureDate' | 'recentDateOrNull' | 'serial' | 'company' | 'emailProvider' | 'formAccessType';
7
- export type ColumnTypeCategory = 'string' | 'integer' | 'decimal' | 'boolean' | 'date' | 'timestamp' | 'time' | 'uuid' | 'json' | 'array' | 'unknown';
8
- export declare function detectFieldPattern(column: IColumnInfo): FieldPatternType | undefined;
9
- export declare function detectTypeCategory(type: string): ColumnTypeCategory;
10
- export declare function getStringLengthCategory(length: number | string | undefined): 'word' | 'sentence' | 'paragraph';
11
- export declare function isSystemField(fieldName: string): boolean;
12
- export declare function getTokenLength(column: IColumnInfo): number;
@@ -1,7 +0,0 @@
1
- export { BaseSeeder } from './base-seeder';
2
- export { EntityReader, IEntityInfo, IColumnInfo, IRelationInfo } from './entity-reader';
3
- export { DataGenerator } from './data-generator';
4
- export { SeedRunner, ISeedResult, ISeedOptions, ISeederLogger, defaultLogger } from './seed-runner';
5
- export { seedConfig, ISeedConfig, getEntityCount, shouldSkipEntity, getSeedingOrder, configureSeedConfig } from './seed-config';
6
- export { SYSTEM_FIELDS, isSystemField, detectFieldPattern, detectTypeCategory } from './field-patterns';
7
- export { runSeedCli } from './cli';
@@ -1,12 +0,0 @@
1
- export interface ISeedConfig {
2
- counts: Record<string, number>;
3
- order: string[];
4
- skipEntities: string[];
5
- locale: string;
6
- respectSoftDelete: boolean;
7
- }
8
- export declare const seedConfig: ISeedConfig;
9
- export declare function configureSeedConfig(config: Partial<ISeedConfig>): void;
10
- export declare function getEntityCount(entityName: string, config?: ISeedConfig): number;
11
- export declare function shouldSkipEntity(entityName: string, config?: ISeedConfig): boolean;
12
- export declare function getSeedingOrder(availableEntities: string[], config?: ISeedConfig): string[];
@@ -1,48 +0,0 @@
1
- import { DataSource } from 'typeorm';
2
- import { BaseSeeder } from './base-seeder';
3
- export interface ISeederLogger {
4
- log(message: string): void;
5
- error(message: string): void;
6
- }
7
- export declare const defaultLogger: ISeederLogger;
8
- export interface ISeedResult {
9
- entity: string;
10
- success: boolean;
11
- count: number;
12
- error?: string;
13
- dryRun?: boolean;
14
- skipped?: boolean;
15
- }
16
- export interface ISeedOptions {
17
- count?: number;
18
- clear?: boolean;
19
- entity?: string;
20
- respectSoftDelete?: boolean;
21
- dryRun?: boolean;
22
- skipIfExists?: boolean;
23
- continueOnError?: boolean;
24
- onProgress?: (current: number, total: number, entityName: string) => void;
25
- batchSize?: number;
26
- }
27
- export declare class SeedRunner {
28
- private readonly dataSource;
29
- private entityReader;
30
- private dataGenerator;
31
- private logger;
32
- private customSeeders;
33
- constructor(dataSource: DataSource, logger?: ISeederLogger);
34
- registerCustomSeeder(entityName: string, seeder: BaseSeeder<any>): void;
35
- unregisterCustomSeeder(entityName: string): void;
36
- hasCustomSeeder(entityName: string): boolean;
37
- private getSeeder;
38
- runAll(options?: ISeedOptions): Promise<ISeedResult[]>;
39
- runSingle(entityName: string, options?: ISeedOptions): Promise<ISeedResult>;
40
- clearAll(hard?: boolean, continueOnError?: boolean): Promise<ISeedResult[]>;
41
- getStatus(): Promise<Array<{
42
- entity: string;
43
- tableName: string;
44
- count: number;
45
- isEmpty: boolean;
46
- hasSoftDelete: boolean;
47
- }>>;
48
- }