@ackplus/nest-seeder 1.1.16 → 2.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/CHANGELOG.md +64 -0
- package/MIGRATION.md +89 -0
- package/QUICKSTART.md +45 -162
- package/README.md +91 -537
- package/dist/cli.js +595 -235
- package/dist/cli.js.map +1 -1
- package/dist/index.d.mts +88 -0
- package/dist/index.d.ts +88 -8
- package/dist/index.js +417 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +390 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -7
- package/dist/cli.d.ts +0 -3
- package/dist/lib/decorators/factory.decorator.d.ts +0 -6
- package/dist/lib/decorators/factory.decorator.js +0 -17
- package/dist/lib/decorators/factory.decorator.js.map +0 -1
- package/dist/lib/factory/data.factory.d.ts +0 -6
- package/dist/lib/factory/data.factory.js +0 -57
- package/dist/lib/factory/data.factory.js.map +0 -1
- package/dist/lib/index.d.ts +0 -4
- package/dist/lib/index.js +0 -21
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/interfaces/factory.interface.d.ts +0 -4
- package/dist/lib/interfaces/factory.interface.js +0 -3
- package/dist/lib/interfaces/factory.interface.js.map +0 -1
- package/dist/lib/interfaces/index.d.ts +0 -2
- package/dist/lib/interfaces/index.js +0 -19
- package/dist/lib/interfaces/index.js.map +0 -1
- package/dist/lib/interfaces/property-metadata.interface.d.ts +0 -6
- package/dist/lib/interfaces/property-metadata.interface.js +0 -3
- package/dist/lib/interfaces/property-metadata.interface.js.map +0 -1
- package/dist/lib/interfaces/seeder-module-async-options.interface.d.ts +0 -10
- package/dist/lib/interfaces/seeder-module-async-options.interface.js +0 -3
- package/dist/lib/interfaces/seeder-module-async-options.interface.js.map +0 -1
- package/dist/lib/interfaces/seeder-options-factory.interface.d.ts +0 -4
- package/dist/lib/interfaces/seeder-options-factory.interface.js +0 -3
- package/dist/lib/interfaces/seeder-options-factory.interface.js.map +0 -1
- package/dist/lib/seeder/seeder.d.ts +0 -10
- package/dist/lib/seeder/seeder.interface.d.ts +0 -9
- package/dist/lib/seeder/seeder.interface.js +0 -3
- package/dist/lib/seeder/seeder.interface.js.map +0 -1
- package/dist/lib/seeder/seeder.js +0 -40
- package/dist/lib/seeder/seeder.js.map +0 -1
- package/dist/lib/seeder/seeder.module.d.ts +0 -17
- package/dist/lib/seeder/seeder.module.js +0 -80
- package/dist/lib/seeder/seeder.module.js.map +0 -1
- package/dist/lib/seeder/seeder.service.d.ts +0 -10
- package/dist/lib/seeder/seeder.service.js +0 -73
- package/dist/lib/seeder/seeder.service.js.map +0 -1
- package/dist/lib/storages/factory.metadata.storage.d.ts +0 -16
- package/dist/lib/storages/factory.metadata.storage.js +0 -17
- package/dist/lib/storages/factory.metadata.storage.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/lib/seeder/seeder.ts
|
|
13
|
+
import { NestFactory } from "@nestjs/core";
|
|
14
|
+
|
|
15
|
+
// src/lib/seeder/seeder.module.ts
|
|
16
|
+
import {
|
|
17
|
+
Module
|
|
18
|
+
} from "@nestjs/common";
|
|
19
|
+
|
|
20
|
+
// src/lib/seeder/seeder.service.ts
|
|
21
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
22
|
+
|
|
23
|
+
// src/lib/decorators/seeder.decorator.ts
|
|
24
|
+
var SEEDER_NAME = /* @__PURE__ */ Symbol.for("nest-seeder:name");
|
|
25
|
+
function SeederName(name) {
|
|
26
|
+
return (target) => {
|
|
27
|
+
Object.defineProperty(target, SEEDER_NAME, {
|
|
28
|
+
value: name,
|
|
29
|
+
enumerable: false,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: false
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getSeederName(seeder2) {
|
|
36
|
+
const ctor = typeof seeder2 === "function" ? seeder2 : seeder2?.constructor;
|
|
37
|
+
return ctor?.[SEEDER_NAME] || ctor?.seederName || ctor?.name || "UnknownSeeder";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/lib/seeder/seeder.service.ts
|
|
41
|
+
var SeederService = class {
|
|
42
|
+
constructor(seeders = [], options = {}) {
|
|
43
|
+
this.seeders = seeders;
|
|
44
|
+
this.options = options;
|
|
45
|
+
}
|
|
46
|
+
seeders;
|
|
47
|
+
options;
|
|
48
|
+
logger = new Logger("Seeder");
|
|
49
|
+
/**
|
|
50
|
+
* Runs the configured seeders. In `refresh` mode every selected seeder is
|
|
51
|
+
* dropped first (in reverse order to respect foreign-key dependencies),
|
|
52
|
+
* then all are seeded.
|
|
53
|
+
*/
|
|
54
|
+
async run() {
|
|
55
|
+
const seeders = this.getSeedersToRun();
|
|
56
|
+
if (seeders.length === 0) {
|
|
57
|
+
this.logger.warn("No seeders to run.");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (this.options.dryRun) {
|
|
61
|
+
this.logger.log("Dry run \u2014 the following seeders would execute:");
|
|
62
|
+
seeders.forEach((seeder2, index) => {
|
|
63
|
+
this.logger.log(` ${index + 1}. ${getSeederName(seeder2)}`);
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (this.options.refresh) {
|
|
68
|
+
await this.drop(seeders);
|
|
69
|
+
}
|
|
70
|
+
await this.seed(seeders);
|
|
71
|
+
}
|
|
72
|
+
/** Seeds the given seeders (defaults to the configured selection). */
|
|
73
|
+
async seed(seeders = this.getSeedersToRun()) {
|
|
74
|
+
for (const seeder2 of seeders) {
|
|
75
|
+
const name = getSeederName(seeder2);
|
|
76
|
+
try {
|
|
77
|
+
this.logger.log(`Seeding: ${name}`);
|
|
78
|
+
await seeder2.seed(this.options);
|
|
79
|
+
this.logger.log(`Completed: ${name}`);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
this.handleError(name, "seed", error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Drops the given seeders in reverse order (defaults to the selection). */
|
|
86
|
+
async drop(seeders = this.getSeedersToRun()) {
|
|
87
|
+
for (const seeder2 of [...seeders].reverse()) {
|
|
88
|
+
const name = getSeederName(seeder2);
|
|
89
|
+
if (typeof seeder2.drop !== "function") {
|
|
90
|
+
this.logger.debug(`Skipping drop for ${name} (no drop() defined)`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
this.logger.log(`Dropping: ${name}`);
|
|
95
|
+
await seeder2.drop(this.options);
|
|
96
|
+
this.logger.log(`Dropped: ${name}`);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
this.handleError(name, "drop", error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Resolves the seeders to run based on the `name` option. */
|
|
103
|
+
getSeedersToRun() {
|
|
104
|
+
const names = this.normalizeNames(this.options.name);
|
|
105
|
+
if (!names) {
|
|
106
|
+
if (this.seeders.length === 0) {
|
|
107
|
+
this.logger.warn(
|
|
108
|
+
'No seeders registered. Did you add them to the "seeders" array in your config?'
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return this.seeders;
|
|
112
|
+
}
|
|
113
|
+
const wanted = new Set(names.map((name) => name.toLowerCase()));
|
|
114
|
+
const matched = this.seeders.filter((seeder2) => {
|
|
115
|
+
const name = getSeederName(seeder2).toLowerCase();
|
|
116
|
+
return wanted.has(name) || wanted.has(name.replace(/seeder$/, ""));
|
|
117
|
+
});
|
|
118
|
+
if (matched.length === 0) {
|
|
119
|
+
const available = this.seeders.map((seeder2) => getSeederName(seeder2));
|
|
120
|
+
this.logger.warn(
|
|
121
|
+
`No seeders matched [${names.join(", ")}]. Available seeders: ${available.length ? available.join(", ") : "(none)"}`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return matched;
|
|
125
|
+
}
|
|
126
|
+
handleError(name, phase, error) {
|
|
127
|
+
const message = error?.message ?? error;
|
|
128
|
+
if (this.options.continueOnError) {
|
|
129
|
+
this.logger.error(`Seeder "${name}" failed during ${phase}: ${message}`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
normalizeNames(name) {
|
|
135
|
+
if (!name) {
|
|
136
|
+
return void 0;
|
|
137
|
+
}
|
|
138
|
+
const list = (Array.isArray(name) ? name : [name]).filter(Boolean);
|
|
139
|
+
return list.length ? list : void 0;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
SeederService = __decorateClass([
|
|
143
|
+
Injectable()
|
|
144
|
+
], SeederService);
|
|
145
|
+
|
|
146
|
+
// src/lib/seeder/seeder.module.ts
|
|
147
|
+
var SEEDER_MODULE_OPTIONS = "SEEDER_MODULE_OPTIONS";
|
|
148
|
+
var SeederModule = class {
|
|
149
|
+
static register(options) {
|
|
150
|
+
return {
|
|
151
|
+
module: SeederModule,
|
|
152
|
+
imports: options.imports || [],
|
|
153
|
+
providers: [
|
|
154
|
+
...options.providers || [],
|
|
155
|
+
...options.seeders || [],
|
|
156
|
+
{
|
|
157
|
+
provide: SeederService,
|
|
158
|
+
useFactory: (...seeders) => {
|
|
159
|
+
return new SeederService(seeders, options);
|
|
160
|
+
},
|
|
161
|
+
inject: options.seeders || []
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
static forRootAsync(options) {
|
|
167
|
+
return {
|
|
168
|
+
module: SeederModule,
|
|
169
|
+
global: options.isGlobal,
|
|
170
|
+
imports: options.imports || [],
|
|
171
|
+
providers: [
|
|
172
|
+
...this.createAsyncProviders(options),
|
|
173
|
+
{
|
|
174
|
+
provide: SeederService,
|
|
175
|
+
useFactory: (seederOptions, ...seeders) => {
|
|
176
|
+
return new SeederService(seeders, seederOptions);
|
|
177
|
+
},
|
|
178
|
+
inject: [SEEDER_MODULE_OPTIONS, ...options.inject || []]
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
static createAsyncProviders(options) {
|
|
184
|
+
if (options.useExisting || options.useFactory) {
|
|
185
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
186
|
+
}
|
|
187
|
+
return [
|
|
188
|
+
this.createAsyncOptionsProvider(options),
|
|
189
|
+
{
|
|
190
|
+
provide: options.useClass,
|
|
191
|
+
useClass: options.useClass
|
|
192
|
+
}
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
static createAsyncOptionsProvider(options) {
|
|
196
|
+
if (options.useFactory) {
|
|
197
|
+
return {
|
|
198
|
+
provide: SEEDER_MODULE_OPTIONS,
|
|
199
|
+
useFactory: options.useFactory,
|
|
200
|
+
inject: options.inject || []
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
provide: SEEDER_MODULE_OPTIONS,
|
|
205
|
+
useFactory: async (optionsFactory) => await optionsFactory.createSeederOptions(),
|
|
206
|
+
inject: [options.useExisting || options.useClass]
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
SeederModule = __decorateClass([
|
|
211
|
+
Module({})
|
|
212
|
+
], SeederModule);
|
|
213
|
+
|
|
214
|
+
// src/lib/seeder/seeder.ts
|
|
215
|
+
async function bootstrap(options) {
|
|
216
|
+
const app = await NestFactory.createApplicationContext(
|
|
217
|
+
SeederModule.register(options),
|
|
218
|
+
{ logger: ["error", "warn", "log"] }
|
|
219
|
+
);
|
|
220
|
+
try {
|
|
221
|
+
const seedersService = app.get(SeederService);
|
|
222
|
+
await seedersService.run();
|
|
223
|
+
} finally {
|
|
224
|
+
await app.close();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
var seeder = (options) => {
|
|
228
|
+
return {
|
|
229
|
+
run(extraOptions = {}) {
|
|
230
|
+
return bootstrap({
|
|
231
|
+
...options,
|
|
232
|
+
...extraOptions
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// src/lib/factory/data.factory.ts
|
|
239
|
+
import { faker } from "@faker-js/faker";
|
|
240
|
+
|
|
241
|
+
// src/lib/storages/factory.metadata.storage.ts
|
|
242
|
+
var FactoryMetadataStorageHost = class {
|
|
243
|
+
properties = [];
|
|
244
|
+
addPropertyMetadata(metadata) {
|
|
245
|
+
this.properties.push(metadata);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Returns the factory property metadata for a target class.
|
|
249
|
+
*
|
|
250
|
+
* The whole prototype chain is walked so that a factory which `extends`
|
|
251
|
+
* another factory inherits the parent's `@Factory` properties. Properties
|
|
252
|
+
* are returned base-class-first, in declaration order. When a subclass
|
|
253
|
+
* re-declares a property, the subclass definition wins but keeps the
|
|
254
|
+
* original position.
|
|
255
|
+
*/
|
|
256
|
+
getPropertyMetadatasByTarget(target) {
|
|
257
|
+
const chain = this.getPrototypeChain(target);
|
|
258
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
259
|
+
for (const ctor of chain) {
|
|
260
|
+
for (const property of this.properties) {
|
|
261
|
+
if (property.target === ctor) {
|
|
262
|
+
byKey.set(property.propertyKey, property);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return Array.from(byKey.values());
|
|
267
|
+
}
|
|
268
|
+
/** Removes all stored metadata. Primarily useful in tests. */
|
|
269
|
+
clear() {
|
|
270
|
+
this.properties = [];
|
|
271
|
+
}
|
|
272
|
+
getPrototypeChain(target) {
|
|
273
|
+
const chain = [];
|
|
274
|
+
let current = target;
|
|
275
|
+
while (typeof current === "function" && current !== Function.prototype && current !== Object) {
|
|
276
|
+
chain.unshift(current);
|
|
277
|
+
current = Object.getPrototypeOf(current);
|
|
278
|
+
}
|
|
279
|
+
return chain;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
var globalRef = global;
|
|
283
|
+
var FactoryMetadataStorage = globalRef.FactoryMetadataStorage || (globalRef.FactoryMetadataStorage = new FactoryMetadataStorageHost());
|
|
284
|
+
|
|
285
|
+
// src/lib/factory/data.factory.ts
|
|
286
|
+
var DataFactory = class _DataFactory {
|
|
287
|
+
/**
|
|
288
|
+
* Creates a factory for a class decorated with `@Factory` properties.
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* const factory = DataFactory.createForClass(UserFactory);
|
|
292
|
+
* const users = factory.generate(10);
|
|
293
|
+
* const admin = factory.generateOne({ role: 'admin' });
|
|
294
|
+
*/
|
|
295
|
+
static createForClass(target) {
|
|
296
|
+
if (!target) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
'A target class is required by "DataFactory.createForClass()" but received "undefined".'
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
const properties = FactoryMetadataStorage.getPropertyMetadatasByTarget(target);
|
|
302
|
+
return {
|
|
303
|
+
generate: (count, overrides = {}) => {
|
|
304
|
+
if (!Number.isInteger(count) || count < 0) {
|
|
305
|
+
throw new Error(
|
|
306
|
+
`"generate(count)" expects a non-negative integer but received "${count}".`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
const records = [];
|
|
310
|
+
for (let i = 0; i < count; i++) {
|
|
311
|
+
records.push(_DataFactory.generateOne(properties, overrides));
|
|
312
|
+
}
|
|
313
|
+
return records;
|
|
314
|
+
},
|
|
315
|
+
generateOne: (overrides = {}) => _DataFactory.generateOne(properties, overrides)
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
static generateOne(properties, overrides) {
|
|
319
|
+
const overrideValues = overrides ?? {};
|
|
320
|
+
const ctx = { ...overrideValues };
|
|
321
|
+
const result = { ...overrideValues };
|
|
322
|
+
const propertyByKey = /* @__PURE__ */ new Map();
|
|
323
|
+
for (const property of properties) {
|
|
324
|
+
propertyByKey.set(property.propertyKey, property);
|
|
325
|
+
}
|
|
326
|
+
const resolving = /* @__PURE__ */ new Set();
|
|
327
|
+
const ensure = (key) => {
|
|
328
|
+
if (key in ctx) {
|
|
329
|
+
return ctx[key];
|
|
330
|
+
}
|
|
331
|
+
const property = propertyByKey.get(key);
|
|
332
|
+
if (!property) {
|
|
333
|
+
return void 0;
|
|
334
|
+
}
|
|
335
|
+
if (resolving.has(key)) {
|
|
336
|
+
return void 0;
|
|
337
|
+
}
|
|
338
|
+
resolving.add(key);
|
|
339
|
+
const { generator, dependsOn } = property.arg;
|
|
340
|
+
if (Array.isArray(dependsOn)) {
|
|
341
|
+
for (const dependency of dependsOn) {
|
|
342
|
+
ensure(dependency);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
ctx[key] = typeof generator === "function" ? generator(faker, ctx) : generator;
|
|
346
|
+
resolving.delete(key);
|
|
347
|
+
return ctx[key];
|
|
348
|
+
};
|
|
349
|
+
for (const property of properties) {
|
|
350
|
+
const key = property.propertyKey;
|
|
351
|
+
if (key in overrideValues) {
|
|
352
|
+
ctx[key] = overrideValues[key];
|
|
353
|
+
result[key] = overrideValues[key];
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
result[key] = ensure(key);
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// src/lib/decorators/factory.decorator.ts
|
|
363
|
+
function Factory(generator, dependsOn) {
|
|
364
|
+
return (target, propertyKey) => {
|
|
365
|
+
FactoryMetadataStorage.addPropertyMetadata({
|
|
366
|
+
target: target.constructor,
|
|
367
|
+
propertyKey,
|
|
368
|
+
arg: {
|
|
369
|
+
generator,
|
|
370
|
+
dependsOn
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/lib/config/define-config.ts
|
|
377
|
+
function defineSeederConfig(config) {
|
|
378
|
+
return config;
|
|
379
|
+
}
|
|
380
|
+
export {
|
|
381
|
+
DataFactory,
|
|
382
|
+
Factory,
|
|
383
|
+
SeederModule,
|
|
384
|
+
SeederName,
|
|
385
|
+
SeederService,
|
|
386
|
+
defineSeederConfig,
|
|
387
|
+
getSeederName,
|
|
388
|
+
seeder
|
|
389
|
+
};
|
|
390
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/seeder/seeder.ts","../src/lib/seeder/seeder.module.ts","../src/lib/seeder/seeder.service.ts","../src/lib/decorators/seeder.decorator.ts","../src/lib/factory/data.factory.ts","../src/lib/storages/factory.metadata.storage.ts","../src/lib/decorators/factory.decorator.ts","../src/lib/config/define-config.ts"],"sourcesContent":["import {\n Provider,\n Type,\n DynamicModule,\n ForwardReference,\n} from '@nestjs/common';\nimport { NestFactory } from '@nestjs/core';\n\nimport {\n SeederModule,\n SeederModuleExtraOptions,\n SeederModuleOptions,\n} from './seeder.module';\nimport { SeederService } from './seeder.service';\n\n\nexport interface SeederOptions {\n imports?: Array<\n Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference\n >;\n providers?: Provider[];\n}\n\nexport interface SeederRunner {\n run(extraOptions?: SeederModuleExtraOptions): Promise<void>;\n}\n\nasync function bootstrap(options: SeederModuleOptions): Promise<void> {\n const app = await NestFactory.createApplicationContext(\n SeederModule.register(options),\n { logger: ['error', 'warn', 'log'] },\n );\n\n try {\n const seedersService = app.get(SeederService);\n await seedersService.run();\n } finally {\n await app.close();\n }\n}\n\n/**\n * Programmatic entry point. Prefer the `nest-seed` CLI for most workflows; use\n * this when you need to seed from your own script.\n *\n * @example\n * await seeder({ imports: [AppModule] }).run({ seeders: [UserSeeder], refresh: true });\n */\nexport const seeder = (options: SeederOptions): SeederRunner => {\n return {\n run(extraOptions: SeederModuleExtraOptions = {}): Promise<void> {\n return bootstrap({\n ...options,\n ...extraOptions,\n });\n },\n };\n};\n","import {\n Module,\n DynamicModule,\n Provider,\n Type,\n ForwardReference,\n} from '@nestjs/common';\n\nimport { Seeder, SeederServiceOptions } from './seeder.interface';\nimport { SeederService } from './seeder.service';\nimport { SeederModuleAsyncOptions } from '../interfaces/seeder-module-async-options.interface';\nimport { SeederOptionsFactory } from '../interfaces/seeder-options-factory.interface';\n\nexport interface SeederModuleExtraOptions extends SeederServiceOptions {\n seeders?: Provider<Seeder>[];\n plugins?: any[];\n}\n\nexport interface SeederModuleOptions extends SeederModuleExtraOptions {\n imports?: Array<\n Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference\n >;\n providers?: Provider[];\n}\n\nconst SEEDER_MODULE_OPTIONS = 'SEEDER_MODULE_OPTIONS';\n\n@Module({})\nexport class SeederModule {\n\n static register(options: SeederModuleOptions): DynamicModule {\n return {\n module: SeederModule,\n imports: options.imports || [],\n providers: [\n ...(options.providers || []),\n ...options.seeders || [],\n {\n provide: SeederService,\n useFactory: (...seeders: Seeder[]): SeederService => {\n return new SeederService(seeders, options);\n },\n inject: (options.seeders || []) as Type<any>[],\n },\n ],\n };\n }\n\n static forRootAsync(options: SeederModuleAsyncOptions): DynamicModule {\n return {\n module: SeederModule,\n global: options.isGlobal,\n imports: options.imports || [],\n providers: [\n ...this.createAsyncProviders(options),\n {\n provide: SeederService,\n useFactory: (seederOptions: SeederModuleOptions, ...seeders: Seeder[]): Promise<SeederService> | SeederService => {\n return new SeederService(seeders, seederOptions);\n },\n inject: [SEEDER_MODULE_OPTIONS, ...(options.inject || []) as Type<any>[]],\n },\n ],\n };\n }\n\n private static createAsyncProviders(options: SeederModuleAsyncOptions): Provider[] {\n if (options.useExisting || options.useFactory) {\n return [this.createAsyncOptionsProvider(options)];\n }\n\n return [\n this.createAsyncOptionsProvider(options),\n {\n provide: options.useClass!,\n useClass: options.useClass!,\n },\n ];\n }\n\n private static createAsyncOptionsProvider(options: SeederModuleAsyncOptions): Provider {\n if (options.useFactory) {\n return {\n provide: SEEDER_MODULE_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject || [],\n };\n }\n\n return {\n provide: SEEDER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: SeederOptionsFactory) =>\n await optionsFactory.createSeederOptions(),\n inject: [options.useExisting || options.useClass!],\n };\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\n\nimport { getSeederName } from '../decorators/seeder.decorator';\nimport type { Seeder, SeederServiceOptions } from './seeder.interface';\n\n\n@Injectable()\nexport class SeederService {\n\n private readonly logger = new Logger('Seeder');\n\n constructor(\n private readonly seeders: Seeder[] = [],\n private readonly options: SeederServiceOptions = {},\n ) {}\n\n /**\n * Runs the configured seeders. In `refresh` mode every selected seeder is\n * dropped first (in reverse order to respect foreign-key dependencies),\n * then all are seeded.\n */\n async run(): Promise<void> {\n const seeders = this.getSeedersToRun();\n\n if (seeders.length === 0) {\n this.logger.warn('No seeders to run.');\n return;\n }\n\n if (this.options.dryRun) {\n this.logger.log('Dry run — the following seeders would execute:');\n seeders.forEach((seeder, index) => {\n this.logger.log(` ${index + 1}. ${getSeederName(seeder)}`);\n });\n return;\n }\n\n if (this.options.refresh) {\n await this.drop(seeders);\n }\n\n await this.seed(seeders);\n }\n\n /** Seeds the given seeders (defaults to the configured selection). */\n async seed(seeders: Seeder[] = this.getSeedersToRun()): Promise<void> {\n for (const seeder of seeders) {\n const name = getSeederName(seeder);\n try {\n this.logger.log(`Seeding: ${name}`);\n await seeder.seed(this.options);\n this.logger.log(`Completed: ${name}`);\n } catch (error) {\n this.handleError(name, 'seed', error);\n }\n }\n }\n\n /** Drops the given seeders in reverse order (defaults to the selection). */\n async drop(seeders: Seeder[] = this.getSeedersToRun()): Promise<void> {\n for (const seeder of [...seeders].reverse()) {\n const name = getSeederName(seeder);\n if (typeof seeder.drop !== 'function') {\n this.logger.debug(`Skipping drop for ${name} (no drop() defined)`);\n continue;\n }\n try {\n this.logger.log(`Dropping: ${name}`);\n await seeder.drop(this.options);\n this.logger.log(`Dropped: ${name}`);\n } catch (error) {\n this.handleError(name, 'drop', error);\n }\n }\n }\n\n /** Resolves the seeders to run based on the `name` option. */\n getSeedersToRun(): Seeder[] {\n const names = this.normalizeNames(this.options.name);\n\n if (!names) {\n if (this.seeders.length === 0) {\n this.logger.warn(\n 'No seeders registered. Did you add them to the \"seeders\" array in your config?',\n );\n }\n return this.seeders;\n }\n\n const wanted = new Set(names.map((name) => name.toLowerCase()));\n const matched = this.seeders.filter((seeder) => {\n const name = getSeederName(seeder).toLowerCase();\n return wanted.has(name) || wanted.has(name.replace(/seeder$/, ''));\n });\n\n if (matched.length === 0) {\n const available = this.seeders.map((seeder) => getSeederName(seeder));\n this.logger.warn(\n `No seeders matched [${names.join(', ')}]. Available seeders: ${\n available.length ? available.join(', ') : '(none)'\n }`,\n );\n }\n\n return matched;\n }\n\n private handleError(name: string, phase: 'seed' | 'drop', error: any): void {\n const message = error?.message ?? error;\n if (this.options.continueOnError) {\n this.logger.error(`Seeder \"${name}\" failed during ${phase}: ${message}`);\n return;\n }\n throw error;\n }\n\n private normalizeNames(\n name?: string | string[],\n ): string[] | undefined {\n if (!name) {\n return undefined;\n }\n const list = (Array.isArray(name) ? name : [name]).filter(Boolean);\n return list.length ? list : undefined;\n }\n\n}\n","/**\n * Stable, minification-safe identifier for a seeder.\n *\n * By default the CLI selects seeders by their class name (`--name UserSeeder`).\n * That breaks when your build minifies class names. Decorate the seeder with\n * `@SeederName('users')` to give it a stable name that survives minification\n * and is nicer to type.\n *\n * @example\n * @Injectable()\n * @SeederName('users')\n * export class UserSeeder implements Seeder { ... }\n *\n * // then: nest-seed --name users\n */\nconst SEEDER_NAME = Symbol.for('nest-seeder:name');\n\nexport function SeederName(name: string): ClassDecorator {\n return (target: any): void => {\n Object.defineProperty(target, SEEDER_NAME, {\n value: name,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/**\n * Resolves the stable name of a seeder class or instance.\n *\n * Resolution order:\n * 1. `@SeederName('...')` decorator value\n * 2. a static `seederName` property\n * 3. the constructor name (default, not minification-safe)\n */\nexport function getSeederName(seeder: any): string {\n const ctor =\n typeof seeder === 'function' ? seeder : seeder?.constructor;\n\n return (\n ctor?.[SEEDER_NAME] ||\n ctor?.seederName ||\n ctor?.name ||\n 'UnknownSeeder'\n );\n}\n","import { faker } from '@faker-js/faker';\nimport { Type } from '@nestjs/common';\n\nimport { FactoryInstance, FactoryOverrides } from '../interfaces';\nimport {\n FactoryMetadataStorage,\n PropertyMetadataType,\n} from '../storages/factory.metadata.storage';\n\n\nexport class DataFactory {\n\n /**\n * Creates a factory for a class decorated with `@Factory` properties.\n *\n * @example\n * const factory = DataFactory.createForClass(UserFactory);\n * const users = factory.generate(10);\n * const admin = factory.generateOne({ role: 'admin' });\n */\n static createForClass<T = Record<string, any>>(\n target: Type<T>,\n ): FactoryInstance<T> {\n if (!target) {\n throw new Error(\n 'A target class is required by \"DataFactory.createForClass()\" but received \"undefined\".',\n );\n }\n\n const properties =\n FactoryMetadataStorage.getPropertyMetadatasByTarget(target as Type<unknown>);\n\n return {\n generate: (count: number, overrides: FactoryOverrides<T> = {}): T[] => {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n `\"generate(count)\" expects a non-negative integer but received \"${count}\".`,\n );\n }\n const records: T[] = [];\n for (let i = 0; i < count; i++) {\n records.push(DataFactory.generateOne<T>(properties, overrides));\n }\n return records;\n },\n generateOne: (overrides: FactoryOverrides<T> = {}): T =>\n DataFactory.generateOne<T>(properties, overrides),\n };\n }\n\n private static generateOne<T>(\n properties: PropertyMetadataType[],\n overrides: FactoryOverrides<T>,\n ): T {\n const overrideValues = (overrides ?? {}) as Record<string, any>;\n\n // The context seeds dependency resolution and starts from the\n // overrides so that generators can read passed-in values.\n const ctx: Record<string, any> = { ...overrideValues };\n\n // The result always includes overrides — even keys that are not\n // declared with `@Factory` (e.g. a foreign key set in a seeder).\n const result: Record<string, any> = { ...overrideValues };\n\n const propertyByKey = new Map<string, PropertyMetadataType>();\n for (const property of properties) {\n propertyByKey.set(property.propertyKey, property);\n }\n\n const resolving = new Set<string>();\n\n const ensure = (key: string): any => {\n if (key in ctx) {\n return ctx[key];\n }\n\n const property = propertyByKey.get(key);\n if (!property) {\n return undefined;\n }\n\n // Guard against circular `dependsOn` chains.\n if (resolving.has(key)) {\n return undefined;\n }\n resolving.add(key);\n\n const { generator, dependsOn } = property.arg;\n\n if (Array.isArray(dependsOn)) {\n for (const dependency of dependsOn) {\n ensure(dependency);\n }\n }\n\n ctx[key] =\n typeof generator === 'function' ? generator(faker, ctx) : generator;\n\n resolving.delete(key);\n return ctx[key];\n };\n\n for (const property of properties) {\n const key = property.propertyKey;\n\n // An explicit override always wins.\n if (key in overrideValues) {\n ctx[key] = overrideValues[key];\n result[key] = overrideValues[key];\n continue;\n }\n\n result[key] = ensure(key);\n }\n\n return result as T;\n }\n\n}\n","import { Type } from '@nestjs/common';\n\nimport {\n FactoryValue,\n FactoryValueGenerator,\n} from '../decorators/factory.decorator';\n\n\nexport type PropertyMetadataType = {\n target?: any;\n propertyKey?: any;\n arg: {\n generator: FactoryValueGenerator | FactoryValue;\n dependsOn?: string[];\n };\n};\n\nexport class FactoryMetadataStorageHost {\n\n private properties: PropertyMetadataType[] = [];\n\n addPropertyMetadata(metadata: PropertyMetadataType): void {\n this.properties.push(metadata);\n }\n\n /**\n * Returns the factory property metadata for a target class.\n *\n * The whole prototype chain is walked so that a factory which `extends`\n * another factory inherits the parent's `@Factory` properties. Properties\n * are returned base-class-first, in declaration order. When a subclass\n * re-declares a property, the subclass definition wins but keeps the\n * original position.\n */\n getPropertyMetadatasByTarget(\n target: Type<unknown>,\n ): PropertyMetadataType[] {\n const chain = this.getPrototypeChain(target);\n const byKey = new Map<string, PropertyMetadataType>();\n\n for (const ctor of chain) {\n for (const property of this.properties) {\n if (property.target === ctor) {\n byKey.set(property.propertyKey, property);\n }\n }\n }\n\n return Array.from(byKey.values());\n }\n\n /** Removes all stored metadata. Primarily useful in tests. */\n clear(): void {\n this.properties = [];\n }\n\n private getPrototypeChain(target: Type<unknown>): Array<Type<unknown>> {\n const chain: Array<Type<unknown>> = [];\n let current: any = target;\n\n while (\n typeof current === 'function' &&\n current !== Function.prototype &&\n current !== Object\n ) {\n chain.unshift(current); // base class first\n current = Object.getPrototypeOf(current);\n }\n\n return chain;\n }\n\n}\n\nconst globalRef = global as any;\n\nexport const FactoryMetadataStorage: FactoryMetadataStorageHost = globalRef.FactoryMetadataStorage ||\n (globalRef.FactoryMetadataStorage = new FactoryMetadataStorageHost());\n","import { Faker } from '@faker-js/faker';\n\nimport { FactoryMetadataStorage } from '../storages/factory.metadata.storage';\n\n\ntype BaseType = string | number | Date | Buffer | boolean | Record<string, any>;\n\nexport type FactoryValue = BaseType | Array<BaseType>;\n\n/**\n * A generator function invoked for each generated record.\n *\n * @param faker the shared Faker instance\n * @param ctx the partially-built record (override values + already-generated\n * fields), useful for derived values via `dependsOn`\n */\nexport type FactoryValueGenerator = (\n faker: Faker,\n ctx: Record<string, any>\n) => FactoryValue;\n\n/**\n * Marks a class property as a generated field.\n *\n * @param generator a generator function or a static value\n * @param dependsOn names of other factory properties that must be generated\n * before this one (resolved transitively)\n *\n * @example\n * class UserFactory {\n * @Factory((faker) => faker.person.firstName())\n * firstName: string;\n *\n * @Factory((faker, ctx) => `${ctx.firstName}@example.com`.toLowerCase(), ['firstName'])\n * email: string;\n * }\n */\nexport function Factory(\n generator: FactoryValueGenerator | FactoryValue,\n dependsOn?: string[],\n) {\n return (\n target: Record<string, any>,\n propertyKey: string | symbol,\n ): void => {\n FactoryMetadataStorage.addPropertyMetadata({\n target: target.constructor,\n propertyKey: propertyKey as string,\n arg: {\n generator,\n dependsOn,\n },\n });\n };\n}\n","import { SeederModuleOptions } from '../seeder/seeder.module';\n\n/**\n * The shape of a `seeder.config.ts` default export.\n */\nexport type SeederConfig = SeederModuleOptions;\n\n/**\n * Identity helper that gives you full type-checking and IntelliSense for your\n * seeder configuration. Using it is optional — a plain object works too — but\n * it catches typos and surfaces the available options as you type.\n *\n * @example\n * // seeder.config.ts\n * import { defineSeederConfig } from '@ackplus/nest-seeder';\n *\n * export default defineSeederConfig({\n * imports: [TypeOrmModule.forRoot({ ... }), TypeOrmModule.forFeature([User])],\n * seeders: [UserSeeder],\n * });\n */\nexport function defineSeederConfig(config: SeederConfig): SeederConfig {\n return config;\n}\n"],"mappings":"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","names":["seeder","seeder"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ackplus/nest-seeder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A powerful and flexible database seeding library for NestJS applications with support for factories, data generation using Faker.js, and CLI commands",
|
|
5
5
|
"author": "AckPlus",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.mjs",
|
|
8
9
|
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.mts",
|
|
14
|
+
"default": "./dist/index.mjs"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
9
23
|
"bin": {
|
|
10
24
|
"nest-seed": "dist/cli.js"
|
|
11
25
|
},
|
|
@@ -13,8 +27,13 @@
|
|
|
13
27
|
"dist",
|
|
14
28
|
"README.md",
|
|
15
29
|
"QUICKSTART.md",
|
|
30
|
+
"MIGRATION.md",
|
|
31
|
+
"CHANGELOG.md",
|
|
16
32
|
"LICENSE"
|
|
17
33
|
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
36
|
+
},
|
|
18
37
|
"keywords": [
|
|
19
38
|
"nestjs",
|
|
20
39
|
"seeder",
|
|
@@ -31,12 +50,12 @@
|
|
|
31
50
|
],
|
|
32
51
|
"repository": {
|
|
33
52
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/ack-solutions/nest-seeder"
|
|
53
|
+
"url": "git+https://github.com/ack-solutions/nest-seeder.git"
|
|
35
54
|
},
|
|
36
55
|
"bugs": {
|
|
37
56
|
"url": "https://github.com/ack-solutions/nest-seeder/issues"
|
|
38
57
|
},
|
|
39
|
-
"homepage": "https://
|
|
58
|
+
"homepage": "https://ack-solutions.github.io/nest-seeder/",
|
|
40
59
|
"peerDependencies": {
|
|
41
60
|
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
42
61
|
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
@@ -68,19 +87,21 @@
|
|
|
68
87
|
"@types/jest": "^30.0.0",
|
|
69
88
|
"@types/node": "^22.10.7",
|
|
70
89
|
"@types/supertest": "^6.0.2",
|
|
90
|
+
"@types/yargs": "^17.0.33",
|
|
71
91
|
"eslint": "^9.18.0",
|
|
72
92
|
"eslint-config-prettier": "^10.0.1",
|
|
73
93
|
"eslint-plugin-prettier": "^5.2.2",
|
|
74
94
|
"globals": "^16.0.0",
|
|
75
95
|
"jest": "^30.0.0",
|
|
76
96
|
"prettier": "^3.4.2",
|
|
97
|
+
"reflect-metadata": "^0.2.2",
|
|
77
98
|
"rxjs": "^7.8.1",
|
|
78
99
|
"source-map-support": "^0.5.21",
|
|
79
100
|
"supertest": "^7.0.0",
|
|
80
101
|
"ts-jest": "^29.2.5",
|
|
81
|
-
"ts-loader": "^9.5.2",
|
|
82
102
|
"ts-node": "^10.9.2",
|
|
83
103
|
"tsconfig-paths": "^4.2.0",
|
|
104
|
+
"tsup": "^8.3.5",
|
|
84
105
|
"typescript": "^5.7.3",
|
|
85
106
|
"typescript-eslint": "^8.20.0"
|
|
86
107
|
},
|
|
@@ -92,18 +113,28 @@
|
|
|
92
113
|
],
|
|
93
114
|
"rootDir": "src",
|
|
94
115
|
"testRegex": ".*\\.spec\\.ts$",
|
|
116
|
+
"setupFilesAfterEnv": [
|
|
117
|
+
"<rootDir>/test-setup.ts"
|
|
118
|
+
],
|
|
95
119
|
"transform": {
|
|
96
120
|
"^.+\\.(t|j)s$": "ts-jest"
|
|
97
121
|
},
|
|
98
122
|
"collectCoverageFrom": [
|
|
99
|
-
"**/*.(t|j)s"
|
|
123
|
+
"**/*.(t|j)s",
|
|
124
|
+
"!**/*.spec.ts",
|
|
125
|
+
"!test-setup.ts",
|
|
126
|
+
"!cli.ts"
|
|
100
127
|
],
|
|
101
128
|
"coverageDirectory": "../coverage",
|
|
102
129
|
"testEnvironment": "node"
|
|
103
130
|
},
|
|
104
131
|
"scripts": {
|
|
105
|
-
"clean": "rm -rf dist
|
|
106
|
-
"build": "
|
|
132
|
+
"clean": "rm -rf dist",
|
|
133
|
+
"build": "tsup",
|
|
134
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
135
|
+
"test": "jest",
|
|
136
|
+
"test:watch": "jest --watch",
|
|
137
|
+
"test:cov": "jest --coverage",
|
|
107
138
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
108
139
|
"lint": "eslint \"src/**/*.ts\" --fix"
|
|
109
140
|
}
|
package/dist/cli.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Faker } from '@faker-js/faker';
|
|
2
|
-
type BaseType = string | number | Date | Buffer | boolean | Record<string, any>;
|
|
3
|
-
export type FactoryValue = BaseType | Array<BaseType>;
|
|
4
|
-
export type FactoryValueGenerator = (faker?: Faker, ctx?: Record<string, any>) => FactoryValue;
|
|
5
|
-
export declare function Factory(generator: FactoryValueGenerator | FactoryValue, dependsOn?: string[]): (target: Record<string, any>, propertyKey: string | symbol) => void;
|
|
6
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Factory = Factory;
|
|
4
|
-
const factory_metadata_storage_1 = require("../storages/factory.metadata.storage");
|
|
5
|
-
function Factory(generator, dependsOn) {
|
|
6
|
-
return (target, propertyKey) => {
|
|
7
|
-
factory_metadata_storage_1.FactoryMetadataStorage.addPropertyMetadata({
|
|
8
|
-
target: target.constructor,
|
|
9
|
-
propertyKey: propertyKey,
|
|
10
|
-
arg: {
|
|
11
|
-
generator,
|
|
12
|
-
dependsOn,
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=factory.decorator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/factory.decorator.ts"],"names":[],"mappings":";;AAcA,0BAiBC;AA7BD,mFAA8E;AAY9E,SAAgB,OAAO,CACnB,SAA+C,EAC/C,SAAoB;IAEpB,OAAO,CACH,MAA2B,EAC3B,WAA4B,EACxB,EAAE;QACN,iDAAsB,CAAC,mBAAmB,CAAC;YACvC,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,WAAW,EAAE,WAAqB;YAClC,GAAG,EAAE;gBACD,SAAS;gBACT,SAAS;aACZ;SACJ,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DataFactory = void 0;
|
|
4
|
-
const faker_1 = require("@faker-js/faker");
|
|
5
|
-
const factory_metadata_storage_1 = require("../storages/factory.metadata.storage");
|
|
6
|
-
class DataFactory {
|
|
7
|
-
static createForClass(target) {
|
|
8
|
-
if (!target) {
|
|
9
|
-
throw new Error(`Target class "${target}" passed in to the "TemplateFactory#createForClass()" method is "undefined".`);
|
|
10
|
-
}
|
|
11
|
-
const properties = factory_metadata_storage_1.FactoryMetadataStorage.getPropertyMetadatasByTarget(target);
|
|
12
|
-
return {
|
|
13
|
-
generate: (count, values = {}) => {
|
|
14
|
-
const ret = [];
|
|
15
|
-
for (let i = 0; i < count; i++) {
|
|
16
|
-
ret.push(this.generate(properties, values));
|
|
17
|
-
}
|
|
18
|
-
return ret;
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
static generate(properties, values) {
|
|
23
|
-
const ctx = { ...values };
|
|
24
|
-
return properties.reduce((result, property) => {
|
|
25
|
-
const propertyKey = property.propertyKey;
|
|
26
|
-
const { generator, dependsOn } = property.arg;
|
|
27
|
-
if (ctx[propertyKey] !== undefined) {
|
|
28
|
-
return {
|
|
29
|
-
[propertyKey]: ctx[propertyKey],
|
|
30
|
-
...result,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
if (Array.isArray(dependsOn)) {
|
|
34
|
-
dependsOn.forEach((dependency) => {
|
|
35
|
-
if (ctx[dependency] === undefined) {
|
|
36
|
-
const dependentProperty = properties.find((p) => p.propertyKey === dependency);
|
|
37
|
-
if (dependentProperty) {
|
|
38
|
-
ctx[dependency] = typeof dependentProperty.arg.generator ===
|
|
39
|
-
'function' ?
|
|
40
|
-
dependentProperty.arg.generator(faker_1.faker, ctx) :
|
|
41
|
-
dependentProperty.arg;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
ctx[propertyKey] = typeof generator === 'function' ?
|
|
47
|
-
generator(faker_1.faker, ctx) :
|
|
48
|
-
generator;
|
|
49
|
-
return {
|
|
50
|
-
[propertyKey]: ctx[propertyKey],
|
|
51
|
-
...result,
|
|
52
|
-
};
|
|
53
|
-
}, {});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
exports.DataFactory = DataFactory;
|
|
57
|
-
//# sourceMappingURL=data.factory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data.factory.js","sourceRoot":"","sources":["../../../src/lib/factory/data.factory.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAKxC,mFAG8C;AAG9C,MAAa,WAAW;IAEpB,MAAM,CAAC,cAAc,CAAC,MAAqB;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACX,iBAAiB,MAAM,8EAA8E,CACxG,CAAC;QACN,CAAC;QAED,MAAM,UAAU,GAAG,iDAAsB,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC;QAE/E,OAAO;YACH,QAAQ,EAAE,CACN,KAAa,EACb,SAA8B,EAAE,EACF,EAAE;gBAChC,MAAM,GAAG,GAAmC,EAAE,CAAC;gBAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO,GAAG,CAAC;YACf,CAAC;SACJ,CAAC;IACN,CAAC;IAEO,MAAM,CAAC,QAAQ,CACnB,UAAkC,EAClC,MAA2B;QAE3B,MAAM,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;QAE1B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;YACzC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC;YAG9C,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;gBACjC,OAAO;oBACH,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC;oBAC/B,GAAG,MAAM;iBACZ,CAAC;YACN,CAAC;YAGD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,SAAS,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;oBAC7B,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,SAAS,EAAE,CAAC;wBAEhC,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,CACrC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,UAAU,CACtC,CAAC;wBACF,IAAI,iBAAiB,EAAE,CAAC;4BACpB,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,iBAAiB,CAAC,GAAG,CAAC,SAAS;gCACpD,UAAU,CAAC,CAAC;gCACZ,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAC3B,aAAK,EACL,GAAG,CACN,CAAC,CAAC;gCACH,iBAAiB,CAAC,GAAG,CAAC;wBAC9B,CAAC;oBACL,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;YAGD,GAAG,CAAC,WAAW,CAAC,GAAG,OAAO,SAAS,KAAK,UAAU,CAAC,CAAC;gBAChD,SAAS,CAAC,aAAK,EAAE,GAAG,CAAC,CAAC,CAAC;gBACvB,SAAS,CAAC;YAEd,OAAO;gBACH,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC;gBAC/B,GAAG,MAAM;aACZ,CAAC;QACN,CAAC,EAAE,EAAE,CAAC,CAAC;IASX,CAAC;CAEJ;AApFD,kCAoFC"}
|
package/dist/lib/index.d.ts
DELETED