@veloxts/cli 0.4.2 → 0.4.4
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/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/db.d.ts +12 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +18 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +29 -3
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/procedures.d.ts +12 -0
- package/dist/commands/procedures.d.ts.map +1 -0
- package/dist/commands/procedures.js +153 -0
- package/dist/commands/procedures.js.map +1 -0
- package/dist/dev/hmr-runner.d.ts +52 -0
- package/dist/dev/hmr-runner.d.ts.map +1 -0
- package/dist/dev/hmr-runner.js +153 -0
- package/dist/dev/hmr-runner.js.map +1 -0
- package/dist/dev/index.d.ts +6 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +6 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/watch-config.d.ts +32 -0
- package/dist/dev/watch-config.d.ts.map +1 -0
- package/dist/dev/watch-config.js +74 -0
- package/dist/dev/watch-config.js.map +1 -0
- package/dist/generators/generators/factory.d.ts +36 -0
- package/dist/generators/generators/factory.d.ts.map +1 -0
- package/dist/generators/generators/factory.js +85 -0
- package/dist/generators/generators/factory.js.map +1 -0
- package/dist/generators/generators/index.d.ts +2 -0
- package/dist/generators/generators/index.d.ts.map +1 -1
- package/dist/generators/generators/index.js +8 -0
- package/dist/generators/generators/index.js.map +1 -1
- package/dist/generators/generators/seeder.d.ts +36 -0
- package/dist/generators/generators/seeder.d.ts.map +1 -0
- package/dist/generators/generators/seeder.js +99 -0
- package/dist/generators/generators/seeder.js.map +1 -0
- package/dist/generators/templates/factory.d.ts +26 -0
- package/dist/generators/templates/factory.d.ts.map +1 -0
- package/dist/generators/templates/factory.js +125 -0
- package/dist/generators/templates/factory.js.map +1 -0
- package/dist/generators/templates/seeder.d.ts +34 -0
- package/dist/generators/templates/seeder.d.ts.map +1 -0
- package/dist/generators/templates/seeder.js +129 -0
- package/dist/generators/templates/seeder.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/seeding/commands/seed.d.ts +11 -0
- package/dist/seeding/commands/seed.d.ts.map +1 -0
- package/dist/seeding/commands/seed.js +268 -0
- package/dist/seeding/commands/seed.js.map +1 -0
- package/dist/seeding/errors.d.ts +119 -0
- package/dist/seeding/errors.d.ts.map +1 -0
- package/dist/seeding/errors.js +191 -0
- package/dist/seeding/errors.js.map +1 -0
- package/dist/seeding/factory.d.ts +162 -0
- package/dist/seeding/factory.d.ts.map +1 -0
- package/dist/seeding/factory.js +250 -0
- package/dist/seeding/factory.js.map +1 -0
- package/dist/seeding/index.d.ts +31 -0
- package/dist/seeding/index.d.ts.map +1 -0
- package/dist/seeding/index.js +41 -0
- package/dist/seeding/index.js.map +1 -0
- package/dist/seeding/loader.d.ts +41 -0
- package/dist/seeding/loader.d.ts.map +1 -0
- package/dist/seeding/loader.js +210 -0
- package/dist/seeding/loader.js.map +1 -0
- package/dist/seeding/registry.d.ts +116 -0
- package/dist/seeding/registry.d.ts.map +1 -0
- package/dist/seeding/registry.js +298 -0
- package/dist/seeding/registry.js.map +1 -0
- package/dist/seeding/runner.d.ts +88 -0
- package/dist/seeding/runner.d.ts.map +1 -0
- package/dist/seeding/runner.js +254 -0
- package/dist/seeding/runner.js.map +1 -0
- package/dist/seeding/types.d.ts +247 -0
- package/dist/seeding/types.d.ts.map +1 -0
- package/dist/seeding/types.js +7 -0
- package/dist/seeding/types.js.map +1 -0
- package/dist/utils/output.d.ts +12 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +21 -0
- package/dist/utils/output.js.map +1 -1
- package/package.json +18 -17
- package/LICENSE +0 -21
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeder Registry
|
|
3
|
+
*
|
|
4
|
+
* Manages seeder registration and dependency resolution with topological sorting.
|
|
5
|
+
*/
|
|
6
|
+
import { circularDependency, dependencyNotFound, seederNotFound } from './errors.js';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Seeder Registry
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Registry for managing seeders with dependency resolution.
|
|
12
|
+
*
|
|
13
|
+
* Handles seeder registration, retrieval, and ordering based on dependencies
|
|
14
|
+
* using topological sorting.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const registry = new SeederRegistry();
|
|
19
|
+
*
|
|
20
|
+
* registry.register(UserSeeder);
|
|
21
|
+
* registry.register(PostSeeder); // depends on UserSeeder
|
|
22
|
+
*
|
|
23
|
+
* // Get seeders in correct execution order
|
|
24
|
+
* const ordered = registry.getInOrder();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class SeederRegistry {
|
|
28
|
+
seeders = new Map();
|
|
29
|
+
/**
|
|
30
|
+
* Register a seeder in the registry.
|
|
31
|
+
*
|
|
32
|
+
* @param seeder - Seeder to register
|
|
33
|
+
* @throws Error if seeder with same name already exists
|
|
34
|
+
*/
|
|
35
|
+
register(seeder) {
|
|
36
|
+
if (this.seeders.has(seeder.name)) {
|
|
37
|
+
throw new Error(`Seeder '${seeder.name}' is already registered`);
|
|
38
|
+
}
|
|
39
|
+
this.seeders.set(seeder.name, seeder);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register multiple seeders.
|
|
43
|
+
*
|
|
44
|
+
* @param seeders - Seeders to register
|
|
45
|
+
*/
|
|
46
|
+
registerMany(seeders) {
|
|
47
|
+
for (const seeder of seeders) {
|
|
48
|
+
this.register(seeder);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get a seeder by name.
|
|
53
|
+
*
|
|
54
|
+
* @param name - Seeder name
|
|
55
|
+
* @returns Seeder if found, undefined otherwise
|
|
56
|
+
*/
|
|
57
|
+
get(name) {
|
|
58
|
+
return this.seeders.get(name);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get a seeder by name, throwing if not found.
|
|
62
|
+
*
|
|
63
|
+
* @param name - Seeder name
|
|
64
|
+
* @returns Seeder
|
|
65
|
+
* @throws SeederError if not found
|
|
66
|
+
*/
|
|
67
|
+
getOrThrow(name) {
|
|
68
|
+
const seeder = this.seeders.get(name);
|
|
69
|
+
if (!seeder) {
|
|
70
|
+
throw seederNotFound(name);
|
|
71
|
+
}
|
|
72
|
+
return seeder;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if a seeder exists.
|
|
76
|
+
*
|
|
77
|
+
* @param name - Seeder name
|
|
78
|
+
*/
|
|
79
|
+
has(name) {
|
|
80
|
+
return this.seeders.has(name);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get all registered seeder names.
|
|
84
|
+
*/
|
|
85
|
+
getNames() {
|
|
86
|
+
return Array.from(this.seeders.keys());
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get all registered seeders.
|
|
90
|
+
*/
|
|
91
|
+
getAll() {
|
|
92
|
+
return Array.from(this.seeders.values());
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get seeder count.
|
|
96
|
+
*/
|
|
97
|
+
get size() {
|
|
98
|
+
return this.seeders.size;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Clear all registered seeders.
|
|
102
|
+
*/
|
|
103
|
+
clear() {
|
|
104
|
+
this.seeders.clear();
|
|
105
|
+
}
|
|
106
|
+
// ==========================================================================
|
|
107
|
+
// Dependency Resolution
|
|
108
|
+
// ==========================================================================
|
|
109
|
+
/**
|
|
110
|
+
* Validate all seeder dependencies exist and there are no circular dependencies.
|
|
111
|
+
*
|
|
112
|
+
* @throws SeederError if dependencies are invalid
|
|
113
|
+
*/
|
|
114
|
+
validateDependencies() {
|
|
115
|
+
// Check all dependencies exist
|
|
116
|
+
for (const seeder of this.seeders.values()) {
|
|
117
|
+
for (const depName of seeder.dependencies ?? []) {
|
|
118
|
+
if (!this.seeders.has(depName)) {
|
|
119
|
+
throw dependencyNotFound(seeder.name, depName);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Check for circular dependencies
|
|
124
|
+
this.detectCircularDependencies();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get all seeders in dependency order (topological sort).
|
|
128
|
+
*
|
|
129
|
+
* Seeders with no dependencies come first, then seeders that depend on them, etc.
|
|
130
|
+
*
|
|
131
|
+
* @param environment - Optional environment filter
|
|
132
|
+
* @returns Seeders in execution order
|
|
133
|
+
* @throws SeederError if circular dependency detected
|
|
134
|
+
*/
|
|
135
|
+
getInOrder(environment) {
|
|
136
|
+
this.validateDependencies();
|
|
137
|
+
// Filter by environment if specified
|
|
138
|
+
const seeders = environment
|
|
139
|
+
? Array.from(this.seeders.values()).filter((s) => this.shouldRunInEnvironment(s, environment))
|
|
140
|
+
: Array.from(this.seeders.values());
|
|
141
|
+
// Build adjacency list and in-degree count
|
|
142
|
+
const inDegree = new Map();
|
|
143
|
+
const adjacency = new Map();
|
|
144
|
+
for (const seeder of seeders) {
|
|
145
|
+
inDegree.set(seeder.name, 0);
|
|
146
|
+
adjacency.set(seeder.name, []);
|
|
147
|
+
}
|
|
148
|
+
// Count dependencies (in-degree) and build reverse adjacency
|
|
149
|
+
for (const seeder of seeders) {
|
|
150
|
+
for (const depName of seeder.dependencies ?? []) {
|
|
151
|
+
// Only count if dependency is in our filtered set
|
|
152
|
+
if (inDegree.has(depName)) {
|
|
153
|
+
inDegree.set(seeder.name, (inDegree.get(seeder.name) ?? 0) + 1);
|
|
154
|
+
adjacency.get(depName)?.push(seeder.name);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Kahn's algorithm for topological sort
|
|
159
|
+
const queue = [];
|
|
160
|
+
const result = [];
|
|
161
|
+
// Start with seeders that have no dependencies
|
|
162
|
+
for (const [name, degree] of inDegree) {
|
|
163
|
+
if (degree === 0) {
|
|
164
|
+
queue.push(name);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
while (queue.length > 0) {
|
|
168
|
+
const name = queue.shift();
|
|
169
|
+
if (!name)
|
|
170
|
+
continue;
|
|
171
|
+
const seeder = this.seeders.get(name);
|
|
172
|
+
if (!seeder)
|
|
173
|
+
continue;
|
|
174
|
+
result.push(seeder);
|
|
175
|
+
// Reduce in-degree of dependents
|
|
176
|
+
for (const dependent of adjacency.get(name) ?? []) {
|
|
177
|
+
const newDegree = (inDegree.get(dependent) ?? 0) - 1;
|
|
178
|
+
inDegree.set(dependent, newDegree);
|
|
179
|
+
if (newDegree === 0) {
|
|
180
|
+
queue.push(dependent);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// If result doesn't contain all seeders, there's a cycle
|
|
185
|
+
if (result.length !== seeders.length) {
|
|
186
|
+
// Find the cycle for error message
|
|
187
|
+
const remaining = seeders.filter((s) => !result.includes(s));
|
|
188
|
+
const cycle = this.findCycle(remaining[0].name);
|
|
189
|
+
throw circularDependency(cycle);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get seeders filtered by names in dependency order.
|
|
195
|
+
*
|
|
196
|
+
* @param names - Seeder names to include (and their dependencies)
|
|
197
|
+
* @param environment - Optional environment filter
|
|
198
|
+
*/
|
|
199
|
+
getByNames(names, environment) {
|
|
200
|
+
// Collect requested seeders and all their transitive dependencies
|
|
201
|
+
const needed = new Set();
|
|
202
|
+
const stack = [...names];
|
|
203
|
+
while (stack.length > 0) {
|
|
204
|
+
const name = stack.pop();
|
|
205
|
+
if (!name || needed.has(name))
|
|
206
|
+
continue;
|
|
207
|
+
const seeder = this.getOrThrow(name);
|
|
208
|
+
// Skip if not for this environment
|
|
209
|
+
if (environment && !this.shouldRunInEnvironment(seeder, environment)) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
needed.add(name);
|
|
213
|
+
// Add dependencies to stack
|
|
214
|
+
for (const dep of seeder.dependencies ?? []) {
|
|
215
|
+
stack.push(dep);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Get all in order, then filter to only needed
|
|
219
|
+
return this.getInOrder(environment).filter((s) => needed.has(s.name));
|
|
220
|
+
}
|
|
221
|
+
// ==========================================================================
|
|
222
|
+
// Private Helpers
|
|
223
|
+
// ==========================================================================
|
|
224
|
+
/**
|
|
225
|
+
* Check if seeder should run in given environment.
|
|
226
|
+
*/
|
|
227
|
+
shouldRunInEnvironment(seeder, environment) {
|
|
228
|
+
// If no environments specified, run in all
|
|
229
|
+
if (!seeder.environments || seeder.environments.length === 0) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
return seeder.environments.includes(environment);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Detect circular dependencies using DFS.
|
|
236
|
+
*/
|
|
237
|
+
detectCircularDependencies() {
|
|
238
|
+
const visited = new Set();
|
|
239
|
+
const recursionStack = new Set();
|
|
240
|
+
for (const seeder of this.seeders.values()) {
|
|
241
|
+
if (!visited.has(seeder.name)) {
|
|
242
|
+
this.detectCycleDFS(seeder.name, visited, recursionStack);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* DFS helper for cycle detection.
|
|
248
|
+
*/
|
|
249
|
+
detectCycleDFS(name, visited, stack) {
|
|
250
|
+
visited.add(name);
|
|
251
|
+
stack.add(name);
|
|
252
|
+
const seeder = this.seeders.get(name);
|
|
253
|
+
if (!seeder)
|
|
254
|
+
return;
|
|
255
|
+
for (const depName of seeder.dependencies ?? []) {
|
|
256
|
+
if (!visited.has(depName)) {
|
|
257
|
+
this.detectCycleDFS(depName, visited, stack);
|
|
258
|
+
}
|
|
259
|
+
else if (stack.has(depName)) {
|
|
260
|
+
// Found cycle - build the cycle path for error message
|
|
261
|
+
const cycle = this.findCycle(depName);
|
|
262
|
+
throw circularDependency(cycle);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
stack.delete(name);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Find and return a cycle starting from the given node.
|
|
269
|
+
*/
|
|
270
|
+
findCycle(startName) {
|
|
271
|
+
const path = [];
|
|
272
|
+
const visited = new Set();
|
|
273
|
+
const dfs = (name) => {
|
|
274
|
+
if (path.includes(name)) {
|
|
275
|
+
// Found cycle - close it by adding the start again
|
|
276
|
+
path.push(name);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
if (visited.has(name))
|
|
280
|
+
return false;
|
|
281
|
+
visited.add(name);
|
|
282
|
+
path.push(name);
|
|
283
|
+
const seeder = this.seeders.get(name);
|
|
284
|
+
for (const depName of seeder?.dependencies ?? []) {
|
|
285
|
+
if (dfs(depName))
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
path.pop();
|
|
289
|
+
return false;
|
|
290
|
+
};
|
|
291
|
+
dfs(startName);
|
|
292
|
+
// Extract just the cycle portion (from first occurrence of last element)
|
|
293
|
+
const lastElement = path[path.length - 1];
|
|
294
|
+
const firstOccurrence = path.indexOf(lastElement);
|
|
295
|
+
return path.slice(firstOccurrence);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/seeding/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeder Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes seeders with dependency resolution, logging, and error handling.
|
|
5
|
+
*/
|
|
6
|
+
import type { SeederRegistry } from './registry.js';
|
|
7
|
+
import type { BatchSeederResult, PrismaClientLike, SeederRunOptions } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Seeder execution runner.
|
|
10
|
+
*
|
|
11
|
+
* Handles running seeders in correct dependency order with proper
|
|
12
|
+
* context, logging, and error handling.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const runner = new SeederRunner(prisma, registry);
|
|
17
|
+
*
|
|
18
|
+
* // Run all seeders
|
|
19
|
+
* const result = await runner.runAll();
|
|
20
|
+
*
|
|
21
|
+
* // Run specific seeders
|
|
22
|
+
* const result = await runner.run(['UserSeeder', 'PostSeeder']);
|
|
23
|
+
*
|
|
24
|
+
* // Fresh seed (truncate first)
|
|
25
|
+
* const result = await runner.fresh();
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class SeederRunner {
|
|
29
|
+
private readonly prisma;
|
|
30
|
+
private readonly registry;
|
|
31
|
+
private readonly factoryRegistry;
|
|
32
|
+
constructor(prisma: PrismaClientLike, registry: SeederRegistry);
|
|
33
|
+
/**
|
|
34
|
+
* Run all registered seeders in dependency order.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Run options
|
|
37
|
+
* @returns Batch result with individual seeder results
|
|
38
|
+
*/
|
|
39
|
+
runAll(options?: SeederRunOptions): Promise<BatchSeederResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Run specific seeders by name (includes their dependencies).
|
|
42
|
+
*
|
|
43
|
+
* @param names - Seeder names to run
|
|
44
|
+
* @param options - Run options
|
|
45
|
+
* @returns Batch result with individual seeder results
|
|
46
|
+
*/
|
|
47
|
+
run(names: string[], options?: SeederRunOptions): Promise<BatchSeederResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Run seeders with fresh (truncate tables first).
|
|
50
|
+
*
|
|
51
|
+
* Calls truncate() on each seeder in reverse order, then runs them.
|
|
52
|
+
*
|
|
53
|
+
* @param options - Run options
|
|
54
|
+
* @returns Batch result with individual seeder results
|
|
55
|
+
*/
|
|
56
|
+
fresh(options?: SeederRunOptions): Promise<BatchSeederResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Execute a list of seeders in order.
|
|
59
|
+
*/
|
|
60
|
+
private executeSeeders;
|
|
61
|
+
/**
|
|
62
|
+
* Execute a single seeder.
|
|
63
|
+
*/
|
|
64
|
+
private executeSeeder;
|
|
65
|
+
/**
|
|
66
|
+
* Truncate tables for seeders that implement truncate().
|
|
67
|
+
*/
|
|
68
|
+
private truncateSeeders;
|
|
69
|
+
/**
|
|
70
|
+
* Create execution context for a seeder.
|
|
71
|
+
*/
|
|
72
|
+
private createContext;
|
|
73
|
+
/**
|
|
74
|
+
* Create logger for a seeder.
|
|
75
|
+
*/
|
|
76
|
+
private createLogger;
|
|
77
|
+
/**
|
|
78
|
+
* Detect current environment from NODE_ENV.
|
|
79
|
+
*/
|
|
80
|
+
private detectEnvironment;
|
|
81
|
+
/**
|
|
82
|
+
* Test database connection.
|
|
83
|
+
*
|
|
84
|
+
* @throws SeederError if connection fails
|
|
85
|
+
*/
|
|
86
|
+
testConnection(): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/seeding/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EACV,iBAAiB,EAGjB,gBAAgB,EAKhB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAMpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAEtC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc;IAU9D;;;;;OAKG;IACG,MAAM,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOxE;;;;;;OAMG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOtF;;;;;;;OAOG;IACG,KAAK,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgBvE;;OAEG;YACW,cAAc;IAmC5B;;OAEG;YACW,aAAa;IAmC3B;;OAEG;YACW,eAAe;IAmB7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAiCpB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAStC"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seeder Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes seeders with dependency resolution, logging, and error handling.
|
|
5
|
+
*/
|
|
6
|
+
import { executionFailed, seederDatabaseError, truncationFailed } from './errors.js';
|
|
7
|
+
import { createFactoryRegistry } from './factory.js';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Seeder Runner
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Seeder execution runner.
|
|
13
|
+
*
|
|
14
|
+
* Handles running seeders in correct dependency order with proper
|
|
15
|
+
* context, logging, and error handling.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const runner = new SeederRunner(prisma, registry);
|
|
20
|
+
*
|
|
21
|
+
* // Run all seeders
|
|
22
|
+
* const result = await runner.runAll();
|
|
23
|
+
*
|
|
24
|
+
* // Run specific seeders
|
|
25
|
+
* const result = await runner.run(['UserSeeder', 'PostSeeder']);
|
|
26
|
+
*
|
|
27
|
+
* // Fresh seed (truncate first)
|
|
28
|
+
* const result = await runner.fresh();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export class SeederRunner {
|
|
32
|
+
prisma;
|
|
33
|
+
registry;
|
|
34
|
+
factoryRegistry;
|
|
35
|
+
constructor(prisma, registry) {
|
|
36
|
+
this.prisma = prisma;
|
|
37
|
+
this.registry = registry;
|
|
38
|
+
this.factoryRegistry = createFactoryRegistry(prisma);
|
|
39
|
+
}
|
|
40
|
+
// ==========================================================================
|
|
41
|
+
// Public API
|
|
42
|
+
// ==========================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Run all registered seeders in dependency order.
|
|
45
|
+
*
|
|
46
|
+
* @param options - Run options
|
|
47
|
+
* @returns Batch result with individual seeder results
|
|
48
|
+
*/
|
|
49
|
+
async runAll(options = {}) {
|
|
50
|
+
const environment = options.environment ?? this.detectEnvironment();
|
|
51
|
+
const seeders = this.registry.getInOrder(environment);
|
|
52
|
+
return this.executeSeeders(seeders, options);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Run specific seeders by name (includes their dependencies).
|
|
56
|
+
*
|
|
57
|
+
* @param names - Seeder names to run
|
|
58
|
+
* @param options - Run options
|
|
59
|
+
* @returns Batch result with individual seeder results
|
|
60
|
+
*/
|
|
61
|
+
async run(names, options = {}) {
|
|
62
|
+
const environment = options.environment ?? this.detectEnvironment();
|
|
63
|
+
const seeders = this.registry.getByNames(names, environment);
|
|
64
|
+
return this.executeSeeders(seeders, options);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Run seeders with fresh (truncate tables first).
|
|
68
|
+
*
|
|
69
|
+
* Calls truncate() on each seeder in reverse order, then runs them.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Run options
|
|
72
|
+
* @returns Batch result with individual seeder results
|
|
73
|
+
*/
|
|
74
|
+
async fresh(options = {}) {
|
|
75
|
+
const environment = options.environment ?? this.detectEnvironment();
|
|
76
|
+
const seeders = this.registry.getInOrder(environment);
|
|
77
|
+
// Truncate in reverse order (dependents first)
|
|
78
|
+
if (!options.dryRun) {
|
|
79
|
+
await this.truncateSeeders([...seeders].reverse(), options);
|
|
80
|
+
}
|
|
81
|
+
return this.executeSeeders(seeders, options);
|
|
82
|
+
}
|
|
83
|
+
// ==========================================================================
|
|
84
|
+
// Execution
|
|
85
|
+
// ==========================================================================
|
|
86
|
+
/**
|
|
87
|
+
* Execute a list of seeders in order.
|
|
88
|
+
*/
|
|
89
|
+
async executeSeeders(seeders, options) {
|
|
90
|
+
const startTime = Date.now();
|
|
91
|
+
const results = [];
|
|
92
|
+
let successful = 0;
|
|
93
|
+
let failed = 0;
|
|
94
|
+
for (const seeder of seeders) {
|
|
95
|
+
const result = await this.executeSeeder(seeder, options);
|
|
96
|
+
results.push(result);
|
|
97
|
+
if (result.success) {
|
|
98
|
+
successful++;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
failed++;
|
|
102
|
+
// Stop on first failure to prevent cascading errors
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Calculate skipped as seeders that weren't executed due to early failure
|
|
107
|
+
const skipped = seeders.length - results.length;
|
|
108
|
+
return {
|
|
109
|
+
results,
|
|
110
|
+
total: seeders.length,
|
|
111
|
+
successful,
|
|
112
|
+
failed,
|
|
113
|
+
skipped,
|
|
114
|
+
duration: Date.now() - startTime,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Execute a single seeder.
|
|
119
|
+
*/
|
|
120
|
+
async executeSeeder(seeder, options) {
|
|
121
|
+
const startTime = Date.now();
|
|
122
|
+
// Dry run - just report what would run
|
|
123
|
+
if (options.dryRun) {
|
|
124
|
+
return {
|
|
125
|
+
name: seeder.name,
|
|
126
|
+
success: true,
|
|
127
|
+
duration: 0,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Create context for this seeder
|
|
131
|
+
const context = this.createContext(seeder, options);
|
|
132
|
+
try {
|
|
133
|
+
await seeder.run(context);
|
|
134
|
+
return {
|
|
135
|
+
name: seeder.name,
|
|
136
|
+
success: true,
|
|
137
|
+
duration: Date.now() - startTime,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
142
|
+
return {
|
|
143
|
+
name: seeder.name,
|
|
144
|
+
success: false,
|
|
145
|
+
duration: Date.now() - startTime,
|
|
146
|
+
error: err.message,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Truncate tables for seeders that implement truncate().
|
|
152
|
+
*/
|
|
153
|
+
async truncateSeeders(seeders, options) {
|
|
154
|
+
for (const seeder of seeders) {
|
|
155
|
+
if (seeder.truncate) {
|
|
156
|
+
const context = this.createContext(seeder, options);
|
|
157
|
+
try {
|
|
158
|
+
await seeder.truncate(context);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
162
|
+
throw truncationFailed(seeder.name, err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ==========================================================================
|
|
168
|
+
// Context Creation
|
|
169
|
+
// ==========================================================================
|
|
170
|
+
/**
|
|
171
|
+
* Create execution context for a seeder.
|
|
172
|
+
*/
|
|
173
|
+
createContext(seeder, options) {
|
|
174
|
+
const environment = options.environment ?? this.detectEnvironment();
|
|
175
|
+
const log = this.createLogger(seeder.name, options);
|
|
176
|
+
// Capture `this` for runSeeder closure
|
|
177
|
+
const runner = this;
|
|
178
|
+
return {
|
|
179
|
+
db: this.prisma,
|
|
180
|
+
factory: this.factoryRegistry,
|
|
181
|
+
environment,
|
|
182
|
+
log,
|
|
183
|
+
async runSeeder(innerSeeder) {
|
|
184
|
+
const innerContext = runner.createContext(innerSeeder, options);
|
|
185
|
+
try {
|
|
186
|
+
await innerSeeder.run(innerContext);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
190
|
+
throw executionFailed(innerSeeder.name, err);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Create logger for a seeder.
|
|
197
|
+
*/
|
|
198
|
+
createLogger(seederName, options) {
|
|
199
|
+
const prefix = `[${seederName}]`;
|
|
200
|
+
const verbose = options.verbose ?? false;
|
|
201
|
+
return {
|
|
202
|
+
info(message) {
|
|
203
|
+
console.log(`${prefix} ${message}`);
|
|
204
|
+
},
|
|
205
|
+
success(message) {
|
|
206
|
+
console.log(`${prefix} \u2714 ${message}`);
|
|
207
|
+
},
|
|
208
|
+
warning(message) {
|
|
209
|
+
console.log(`${prefix} \u26A0 ${message}`);
|
|
210
|
+
},
|
|
211
|
+
error(message) {
|
|
212
|
+
console.error(`${prefix} \u2718 ${message}`);
|
|
213
|
+
},
|
|
214
|
+
debug(message) {
|
|
215
|
+
if (verbose) {
|
|
216
|
+
console.log(`${prefix} [debug] ${message}`);
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// ==========================================================================
|
|
222
|
+
// Helpers
|
|
223
|
+
// ==========================================================================
|
|
224
|
+
/**
|
|
225
|
+
* Detect current environment from NODE_ENV.
|
|
226
|
+
*/
|
|
227
|
+
detectEnvironment() {
|
|
228
|
+
const env = process.env.NODE_ENV;
|
|
229
|
+
switch (env) {
|
|
230
|
+
case 'production':
|
|
231
|
+
return 'production';
|
|
232
|
+
case 'test':
|
|
233
|
+
return 'test';
|
|
234
|
+
default:
|
|
235
|
+
return 'development';
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Test database connection.
|
|
240
|
+
*
|
|
241
|
+
* @throws SeederError if connection fails
|
|
242
|
+
*/
|
|
243
|
+
async testConnection() {
|
|
244
|
+
try {
|
|
245
|
+
// Execute a simple query to test connection
|
|
246
|
+
await this.prisma.$queryRaw `SELECT 1`;
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
250
|
+
throw seederDatabaseError('connection test', err);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/seeding/runner.ts"],"names":[],"mappings":"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"}
|