@veloxts/cli 0.4.2 → 0.4.3

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 (67) hide show
  1. package/dist/cli.js +4 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/db.d.ts +12 -0
  4. package/dist/commands/db.d.ts.map +1 -0
  5. package/dist/commands/db.js +18 -0
  6. package/dist/commands/db.js.map +1 -0
  7. package/dist/commands/procedures.d.ts +12 -0
  8. package/dist/commands/procedures.d.ts.map +1 -0
  9. package/dist/commands/procedures.js +153 -0
  10. package/dist/commands/procedures.js.map +1 -0
  11. package/dist/generators/generators/factory.d.ts +36 -0
  12. package/dist/generators/generators/factory.d.ts.map +1 -0
  13. package/dist/generators/generators/factory.js +85 -0
  14. package/dist/generators/generators/factory.js.map +1 -0
  15. package/dist/generators/generators/index.d.ts +2 -0
  16. package/dist/generators/generators/index.d.ts.map +1 -1
  17. package/dist/generators/generators/index.js +8 -0
  18. package/dist/generators/generators/index.js.map +1 -1
  19. package/dist/generators/generators/seeder.d.ts +36 -0
  20. package/dist/generators/generators/seeder.d.ts.map +1 -0
  21. package/dist/generators/generators/seeder.js +99 -0
  22. package/dist/generators/generators/seeder.js.map +1 -0
  23. package/dist/generators/templates/factory.d.ts +26 -0
  24. package/dist/generators/templates/factory.d.ts.map +1 -0
  25. package/dist/generators/templates/factory.js +125 -0
  26. package/dist/generators/templates/factory.js.map +1 -0
  27. package/dist/generators/templates/seeder.d.ts +34 -0
  28. package/dist/generators/templates/seeder.d.ts.map +1 -0
  29. package/dist/generators/templates/seeder.js +129 -0
  30. package/dist/generators/templates/seeder.js.map +1 -0
  31. package/dist/index.d.ts +5 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/seeding/commands/seed.d.ts +11 -0
  36. package/dist/seeding/commands/seed.d.ts.map +1 -0
  37. package/dist/seeding/commands/seed.js +268 -0
  38. package/dist/seeding/commands/seed.js.map +1 -0
  39. package/dist/seeding/errors.d.ts +119 -0
  40. package/dist/seeding/errors.d.ts.map +1 -0
  41. package/dist/seeding/errors.js +191 -0
  42. package/dist/seeding/errors.js.map +1 -0
  43. package/dist/seeding/factory.d.ts +162 -0
  44. package/dist/seeding/factory.d.ts.map +1 -0
  45. package/dist/seeding/factory.js +250 -0
  46. package/dist/seeding/factory.js.map +1 -0
  47. package/dist/seeding/index.d.ts +31 -0
  48. package/dist/seeding/index.d.ts.map +1 -0
  49. package/dist/seeding/index.js +41 -0
  50. package/dist/seeding/index.js.map +1 -0
  51. package/dist/seeding/loader.d.ts +41 -0
  52. package/dist/seeding/loader.d.ts.map +1 -0
  53. package/dist/seeding/loader.js +210 -0
  54. package/dist/seeding/loader.js.map +1 -0
  55. package/dist/seeding/registry.d.ts +116 -0
  56. package/dist/seeding/registry.d.ts.map +1 -0
  57. package/dist/seeding/registry.js +298 -0
  58. package/dist/seeding/registry.js.map +1 -0
  59. package/dist/seeding/runner.d.ts +88 -0
  60. package/dist/seeding/runner.d.ts.map +1 -0
  61. package/dist/seeding/runner.js +254 -0
  62. package/dist/seeding/runner.js.map +1 -0
  63. package/dist/seeding/types.d.ts +247 -0
  64. package/dist/seeding/types.d.ts.map +1 -0
  65. package/dist/seeding/types.js +7 -0
  66. package/dist/seeding/types.js.map +1 -0
  67. package/package.json +6 -6
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Factory System
3
+ *
4
+ * Base factory class and registry for generating fake data.
5
+ */
6
+ import { factoryCreateFailed, stateNotFound } from './errors.js';
7
+ // ============================================================================
8
+ // Base Factory
9
+ // ============================================================================
10
+ /**
11
+ * Abstract base class for model factories.
12
+ *
13
+ * Provides a fluent API for creating model instances with fake data
14
+ * and named state variations.
15
+ *
16
+ * @template TInput - The input type for creating records
17
+ * @template TOutput - The output type returned from database (defaults to TInput)
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { BaseFactory } from '@veloxts/cli';
22
+ * import { faker } from '@faker-js/faker';
23
+ *
24
+ * interface UserInput {
25
+ * email: string;
26
+ * name: string;
27
+ * role: 'admin' | 'user';
28
+ * }
29
+ *
30
+ * export class UserFactory extends BaseFactory<UserInput> {
31
+ * modelName = 'user';
32
+ *
33
+ * definition(): UserInput {
34
+ * return {
35
+ * email: faker.internet.email(),
36
+ * name: faker.person.fullName(),
37
+ * role: 'user',
38
+ * };
39
+ * }
40
+ *
41
+ * admin(): this {
42
+ * return this.state('admin');
43
+ * }
44
+ *
45
+ * constructor(prisma: PrismaClientLike) {
46
+ * super(prisma);
47
+ * this.registerState('admin', (attrs) => ({ ...attrs, role: 'admin' }));
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ export class BaseFactory {
53
+ /** Map of registered state modifiers */
54
+ states = new Map();
55
+ /** Currently active state names */
56
+ activeStates = [];
57
+ /** Prisma client for database operations */
58
+ prisma;
59
+ constructor(prisma) {
60
+ this.prisma = prisma;
61
+ }
62
+ // ==========================================================================
63
+ // State Management
64
+ // ==========================================================================
65
+ /**
66
+ * Register a named state modifier.
67
+ *
68
+ * @param name - State name (e.g., 'admin', 'verified')
69
+ * @param modifier - Function that modifies attributes
70
+ * @returns this for chaining during construction
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * constructor(prisma: PrismaClientLike) {
75
+ * super(prisma);
76
+ * this.registerState('admin', (attrs) => ({ ...attrs, role: 'admin' }));
77
+ * this.registerState('unverified', (attrs) => ({ ...attrs, emailVerified: null }));
78
+ * }
79
+ * ```
80
+ */
81
+ registerState(name, modifier) {
82
+ this.states.set(name, modifier);
83
+ return this;
84
+ }
85
+ /**
86
+ * Apply a named state modifier.
87
+ * Returns a new factory instance with the state applied.
88
+ *
89
+ * @param name - State name to apply
90
+ * @returns New factory instance with state active (preserves subclass type)
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // Create an admin user
95
+ * await factory.get(UserFactory).state('admin').create();
96
+ *
97
+ * // Chain multiple states
98
+ * await factory.get(UserFactory).state('admin').state('verified').create();
99
+ *
100
+ * // Subclass methods preserved after state()
101
+ * const factory = new UserFactory(prisma);
102
+ * await factory.state('verified').admin().create(); // admin() still accessible
103
+ * ```
104
+ */
105
+ state(name) {
106
+ if (!this.states.has(name)) {
107
+ throw stateNotFound(this.constructor.name, name, Array.from(this.states.keys()));
108
+ }
109
+ // Create a shallow clone with the state added
110
+ const clone = Object.create(Object.getPrototypeOf(this));
111
+ Object.assign(clone, this);
112
+ clone.states = new Map(this.states);
113
+ clone.activeStates = [...this.activeStates, name];
114
+ return clone;
115
+ }
116
+ /**
117
+ * Get list of available state names.
118
+ */
119
+ getAvailableStates() {
120
+ return Array.from(this.states.keys());
121
+ }
122
+ // ==========================================================================
123
+ // Make (without persisting)
124
+ // ==========================================================================
125
+ /**
126
+ * Make a single instance without persisting to database.
127
+ *
128
+ * @param overrides - Attributes to override defaults
129
+ * @returns Generated attributes
130
+ */
131
+ make(overrides) {
132
+ return this.buildAttributes(overrides);
133
+ }
134
+ /**
135
+ * Make multiple instances without persisting to database.
136
+ *
137
+ * @param count - Number of instances to make
138
+ * @param overrides - Attributes to override defaults for all instances
139
+ * @returns Array of generated attributes
140
+ */
141
+ makeMany(count, overrides) {
142
+ return Array.from({ length: count }, () => this.buildAttributes(overrides));
143
+ }
144
+ // ==========================================================================
145
+ // Create (persist to database)
146
+ // ==========================================================================
147
+ /**
148
+ * Create a single instance in the database.
149
+ *
150
+ * @param overrides - Attributes to override defaults
151
+ * @returns Created database record
152
+ */
153
+ async create(overrides) {
154
+ const data = this.buildAttributes(overrides);
155
+ try {
156
+ // Access Prisma model dynamically with type-safe casting
157
+ // We use unknown as intermediate to avoid any, then cast to our defined type
158
+ const prismaWithModels = this.prisma;
159
+ const model = prismaWithModels[this.modelName];
160
+ if (!model || typeof model.create !== 'function') {
161
+ throw new Error(`Model '${this.modelName}' not found on Prisma client`);
162
+ }
163
+ return await model.create({ data });
164
+ }
165
+ catch (error) {
166
+ const err = error instanceof Error ? error : new Error(String(error));
167
+ throw factoryCreateFailed(this.modelName, err);
168
+ }
169
+ }
170
+ /**
171
+ * Create multiple instances in the database.
172
+ *
173
+ * @param count - Number of instances to create
174
+ * @param overrides - Attributes to override defaults for all instances
175
+ * @returns Array of created database records
176
+ */
177
+ async createMany(count, overrides) {
178
+ const results = [];
179
+ // Create individually to get all returned records
180
+ // (createMany doesn't return created records in some databases)
181
+ for (let i = 0; i < count; i++) {
182
+ const record = await this.create(overrides);
183
+ results.push(record);
184
+ }
185
+ return results;
186
+ }
187
+ // ==========================================================================
188
+ // Private Helpers
189
+ // ==========================================================================
190
+ /**
191
+ * Build attributes by applying definition, states, and overrides.
192
+ */
193
+ buildAttributes(overrides) {
194
+ // Start with definition
195
+ let attrs = this.definition();
196
+ // Apply active states in order
197
+ for (const stateName of this.activeStates) {
198
+ const modifier = this.states.get(stateName);
199
+ if (modifier) {
200
+ attrs = { ...attrs, ...modifier(attrs) };
201
+ }
202
+ }
203
+ // Apply overrides last
204
+ if (overrides) {
205
+ attrs = { ...attrs, ...overrides };
206
+ }
207
+ return attrs;
208
+ }
209
+ }
210
+ // ============================================================================
211
+ // Factory Registry
212
+ // ============================================================================
213
+ /**
214
+ * Create a factory registry for managing factory instances.
215
+ *
216
+ * The registry caches factory instances and provides type-safe access.
217
+ *
218
+ * @param prisma - Prisma client to inject into factories
219
+ * @returns Factory registry instance
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const registry = createFactoryRegistry(prisma);
224
+ *
225
+ * // Get or create factory instance
226
+ * const userFactory = registry.get(UserFactory);
227
+ * await userFactory.create();
228
+ * ```
229
+ */
230
+ export function createFactoryRegistry(prisma) {
231
+ // Use unknown for type-erased storage, similar to AnyGenerator pattern
232
+ const instances = new Map();
233
+ return {
234
+ get(FactoryClass) {
235
+ // Check cache first
236
+ let instance = instances.get(FactoryClass);
237
+ if (!instance) {
238
+ // Create new instance
239
+ instance = new FactoryClass(prisma);
240
+ instances.set(FactoryClass, instance);
241
+ }
242
+ // Type safety is maintained by the generic constraints on FactoryClass
243
+ return instance;
244
+ },
245
+ clear() {
246
+ instances.clear();
247
+ },
248
+ };
249
+ }
250
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/seeding/factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @veloxts/cli - Database Seeding Module
3
+ *
4
+ * Laravel-inspired database seeding system with factories and seeders.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // In a seeder file (src/database/seeders/UserSeeder.ts)
9
+ * import type { Seeder, SeederContext } from '@veloxts/cli';
10
+ * import { UserFactory } from '../factories/UserFactory.js';
11
+ *
12
+ * export const UserSeeder: Seeder = {
13
+ * name: 'UserSeeder',
14
+ * dependencies: [],
15
+ *
16
+ * async run({ db, factory, log }) {
17
+ * await factory.get(UserFactory).createMany(10);
18
+ * log.success('Created 10 users');
19
+ * },
20
+ * };
21
+ * ```
22
+ *
23
+ * @module @veloxts/cli/seeding
24
+ */
25
+ export type { BatchSeederResult, Environment, Factory, FactoryConstructor, FactoryRegistry, LoadedSeeder, PrismaClientLike, SeedCommandOptions, Seeder, SeederContext, SeederLoadResult, SeederLogger, SeederResult, SeederRunOptions, StateModifier, } from './types.js';
26
+ export { circularDependency, dependencyNotFound, executionFailed, FactoryError, factoryCreateFailed, factoryNotFound, filesystemError, invalidExport, noSeedersFound, SeederError, SeederErrorCode, seederDatabaseError, seederNotFound, stateNotFound, truncationFailed, } from './errors.js';
27
+ export { BaseFactory, createFactoryRegistry } from './factory.js';
28
+ export { loadSeeders, seedersDirectoryExists } from './loader.js';
29
+ export { SeederRegistry } from './registry.js';
30
+ export { SeederRunner } from './runner.js';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seeding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,YAAY,EACV,iBAAiB,EAEjB,WAAW,EAEX,OAAO,EACP,kBAAkB,EAClB,eAAe,EAEf,YAAY,EAEZ,gBAAgB,EAEhB,kBAAkB,EAElB,MAAM,EACN,aAAa,EACb,gBAAgB,EAEhB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,mBAAmB,EAEnB,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAMlE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @veloxts/cli - Database Seeding Module
3
+ *
4
+ * Laravel-inspired database seeding system with factories and seeders.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // In a seeder file (src/database/seeders/UserSeeder.ts)
9
+ * import type { Seeder, SeederContext } from '@veloxts/cli';
10
+ * import { UserFactory } from '../factories/UserFactory.js';
11
+ *
12
+ * export const UserSeeder: Seeder = {
13
+ * name: 'UserSeeder',
14
+ * dependencies: [],
15
+ *
16
+ * async run({ db, factory, log }) {
17
+ * await factory.get(UserFactory).createMany(10);
18
+ * log.success('Created 10 users');
19
+ * },
20
+ * };
21
+ * ```
22
+ *
23
+ * @module @veloxts/cli/seeding
24
+ */
25
+ // ============================================================================
26
+ // Errors
27
+ // ============================================================================
28
+ export { circularDependency, dependencyNotFound, executionFailed, FactoryError, factoryCreateFailed, factoryNotFound, filesystemError, invalidExport, noSeedersFound, SeederError, SeederErrorCode, seederDatabaseError,
29
+ // Error factory functions
30
+ seederNotFound, stateNotFound, truncationFailed, } from './errors.js';
31
+ // ============================================================================
32
+ // Factory System
33
+ // ============================================================================
34
+ export { BaseFactory, createFactoryRegistry } from './factory.js';
35
+ // ============================================================================
36
+ // Seeder Infrastructure
37
+ // ============================================================================
38
+ export { loadSeeders, seedersDirectoryExists } from './loader.js';
39
+ export { SeederRegistry } from './registry.js';
40
+ export { SeederRunner } from './runner.js';
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seeding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA+BH,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,mBAAmB;AACnB,0BAA0B;AAC1B,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAElE,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Seeder Loader
3
+ *
4
+ * Load seeder files from the filesystem.
5
+ */
6
+ import type { Seeder, SeederLoadResult } from './types.js';
7
+ /**
8
+ * Default path for seeders relative to project root
9
+ */
10
+ export declare const DEFAULT_SEEDERS_PATH = "src/database/seeders";
11
+ /**
12
+ * Check if seeders directory exists.
13
+ *
14
+ * @param cwd - Project root directory
15
+ * @param seedersPath - Path to seeders directory (relative to cwd)
16
+ */
17
+ export declare function seedersDirectoryExists(cwd: string, seedersPath?: string): Promise<boolean>;
18
+ /**
19
+ * Load all seeders from the filesystem.
20
+ *
21
+ * @param cwd - Project root directory
22
+ * @param seedersPath - Path to seeders directory (relative to cwd)
23
+ * @returns Load result with seeders and any errors
24
+ */
25
+ export declare function loadSeeders(cwd: string, seedersPath?: string): Promise<SeederLoadResult>;
26
+ /**
27
+ * Load the main DatabaseSeeder entry point.
28
+ *
29
+ * @param cwd - Project root directory
30
+ * @param seedersPath - Path to seeders directory (relative to cwd)
31
+ * @returns DatabaseSeeder if found, null otherwise
32
+ */
33
+ export declare function loadDatabaseSeeder(cwd: string, seedersPath?: string): Promise<Seeder | null>;
34
+ /**
35
+ * Get all seeder file paths from directory.
36
+ *
37
+ * @param cwd - Project root directory
38
+ * @param seedersPath - Path to seeders directory (relative to cwd)
39
+ */
40
+ export declare function getSeederFiles(cwd: string, seedersPath?: string): Promise<string[]>;
41
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/seeding/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAgB,MAAM,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMzE;;GAEG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAgB3D;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,MAA6B,GACzC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,MAA6B,GACzC,OAAO,CAAC,gBAAgB,CAAC,CA0C3B;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,MAA6B,GACzC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBxB;AAiGD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,MAA6B,GACzC,OAAO,CAAC,MAAM,EAAE,CAAC,CAenB"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Seeder Loader
3
+ *
4
+ * Load seeder files from the filesystem.
5
+ */
6
+ import fs from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ import { pathToFileURL } from 'node:url';
9
+ import { filesystemError, invalidExport } from './errors.js';
10
+ // ============================================================================
11
+ // Constants
12
+ // ============================================================================
13
+ /**
14
+ * Default path for seeders relative to project root
15
+ */
16
+ export const DEFAULT_SEEDERS_PATH = 'src/database/seeders';
17
+ /**
18
+ * File patterns that indicate a seeder file
19
+ */
20
+ const SEEDER_FILE_PATTERNS = [/Seeder\.(ts|js)$/, /\.seeder\.(ts|js)$/];
21
+ /**
22
+ * Files to skip
23
+ */
24
+ const SKIP_FILES = ['index.ts', 'index.js', 'DatabaseSeeder.ts', 'DatabaseSeeder.js'];
25
+ // ============================================================================
26
+ // Loader Functions
27
+ // ============================================================================
28
+ /**
29
+ * Check if seeders directory exists.
30
+ *
31
+ * @param cwd - Project root directory
32
+ * @param seedersPath - Path to seeders directory (relative to cwd)
33
+ */
34
+ export async function seedersDirectoryExists(cwd, seedersPath = DEFAULT_SEEDERS_PATH) {
35
+ const fullPath = path.join(cwd, seedersPath);
36
+ try {
37
+ const stat = await fs.stat(fullPath);
38
+ return stat.isDirectory();
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ /**
45
+ * Load all seeders from the filesystem.
46
+ *
47
+ * @param cwd - Project root directory
48
+ * @param seedersPath - Path to seeders directory (relative to cwd)
49
+ * @returns Load result with seeders and any errors
50
+ */
51
+ export async function loadSeeders(cwd, seedersPath = DEFAULT_SEEDERS_PATH) {
52
+ const fullPath = path.join(cwd, seedersPath);
53
+ const seeders = [];
54
+ const errors = [];
55
+ // Check directory exists
56
+ if (!(await seedersDirectoryExists(cwd, seedersPath))) {
57
+ return { seeders: [], errors: [] };
58
+ }
59
+ // List files
60
+ let files;
61
+ try {
62
+ files = await fs.readdir(fullPath);
63
+ }
64
+ catch (error) {
65
+ const err = error instanceof Error ? error : new Error(String(error));
66
+ throw filesystemError('reading seeders directory', fullPath, err);
67
+ }
68
+ // Filter to seeder files
69
+ const seederFiles = files.filter((file) => {
70
+ // Skip non-seeder files
71
+ if (SKIP_FILES.includes(file))
72
+ return false;
73
+ // Check if matches seeder pattern
74
+ return SEEDER_FILE_PATTERNS.some((pattern) => pattern.test(file));
75
+ });
76
+ // Load each seeder
77
+ for (const file of seederFiles) {
78
+ const filePath = path.join(fullPath, file);
79
+ try {
80
+ const seeder = await loadSeederFile(filePath);
81
+ seeders.push({ seeder, filePath });
82
+ }
83
+ catch (error) {
84
+ const err = error instanceof Error ? error : new Error(String(error));
85
+ errors.push({ filePath, error: err.message });
86
+ }
87
+ }
88
+ return { seeders, errors };
89
+ }
90
+ /**
91
+ * Load the main DatabaseSeeder entry point.
92
+ *
93
+ * @param cwd - Project root directory
94
+ * @param seedersPath - Path to seeders directory (relative to cwd)
95
+ * @returns DatabaseSeeder if found, null otherwise
96
+ */
97
+ export async function loadDatabaseSeeder(cwd, seedersPath = DEFAULT_SEEDERS_PATH) {
98
+ const fullPath = path.join(cwd, seedersPath);
99
+ // Try both .ts and .js extensions
100
+ for (const ext of ['ts', 'js']) {
101
+ const filePath = path.join(fullPath, `DatabaseSeeder.${ext}`);
102
+ try {
103
+ const stat = await fs.stat(filePath);
104
+ if (stat.isFile()) {
105
+ return await loadSeederFile(filePath);
106
+ }
107
+ }
108
+ catch {
109
+ // File doesn't exist, try next
110
+ }
111
+ }
112
+ return null;
113
+ }
114
+ /**
115
+ * Load a single seeder file.
116
+ *
117
+ * @param filePath - Absolute path to seeder file
118
+ * @returns Loaded seeder
119
+ */
120
+ async function loadSeederFile(filePath) {
121
+ // Convert to file URL for dynamic import
122
+ const fileUrl = pathToFileURL(filePath).href;
123
+ // Dynamic import
124
+ let module;
125
+ try {
126
+ module = (await import(fileUrl));
127
+ }
128
+ catch (error) {
129
+ const err = error instanceof Error ? error : new Error(String(error));
130
+ throw invalidExport(filePath, `Failed to import: ${err.message}`);
131
+ }
132
+ // Look for seeder export
133
+ const seeder = findSeederExport(module);
134
+ if (!seeder) {
135
+ throw invalidExport(filePath, 'No valid seeder export found. Export a const named *Seeder or use default export.');
136
+ }
137
+ // Validate seeder shape
138
+ validateSeeder(seeder, filePath);
139
+ return seeder;
140
+ }
141
+ /**
142
+ * Find a seeder export in a module.
143
+ */
144
+ function findSeederExport(module) {
145
+ // Check default export first
146
+ if (module.default && isSeederLike(module.default)) {
147
+ return module.default;
148
+ }
149
+ // Look for named export ending in 'Seeder'
150
+ for (const [key, value] of Object.entries(module)) {
151
+ if (key.endsWith('Seeder') && isSeederLike(value)) {
152
+ return value;
153
+ }
154
+ }
155
+ return null;
156
+ }
157
+ /**
158
+ * Check if a value looks like a seeder.
159
+ */
160
+ function isSeederLike(value) {
161
+ if (!value || typeof value !== 'object')
162
+ return false;
163
+ const obj = value;
164
+ return typeof obj.name === 'string' && typeof obj.run === 'function';
165
+ }
166
+ /**
167
+ * Validate a seeder has the required shape.
168
+ */
169
+ function validateSeeder(seeder, filePath) {
170
+ if (!seeder || typeof seeder !== 'object') {
171
+ throw invalidExport(filePath, 'Seeder must be an object');
172
+ }
173
+ const obj = seeder;
174
+ if (typeof obj.name !== 'string' || obj.name.length === 0) {
175
+ throw invalidExport(filePath, "Seeder must have a non-empty 'name' property");
176
+ }
177
+ if (typeof obj.run !== 'function') {
178
+ throw invalidExport(filePath, "Seeder must have a 'run' function");
179
+ }
180
+ if (obj.dependencies !== undefined && !Array.isArray(obj.dependencies)) {
181
+ throw invalidExport(filePath, "'dependencies' must be an array of strings");
182
+ }
183
+ if (obj.environments !== undefined && !Array.isArray(obj.environments)) {
184
+ throw invalidExport(filePath, "'environments' must be an array");
185
+ }
186
+ if (obj.truncate !== undefined && typeof obj.truncate !== 'function') {
187
+ throw invalidExport(filePath, "'truncate' must be a function");
188
+ }
189
+ }
190
+ /**
191
+ * Get all seeder file paths from directory.
192
+ *
193
+ * @param cwd - Project root directory
194
+ * @param seedersPath - Path to seeders directory (relative to cwd)
195
+ */
196
+ export async function getSeederFiles(cwd, seedersPath = DEFAULT_SEEDERS_PATH) {
197
+ const fullPath = path.join(cwd, seedersPath);
198
+ if (!(await seedersDirectoryExists(cwd, seedersPath))) {
199
+ return [];
200
+ }
201
+ const files = await fs.readdir(fullPath);
202
+ return files
203
+ .filter((file) => {
204
+ if (SKIP_FILES.includes(file))
205
+ return false;
206
+ return SEEDER_FILE_PATTERNS.some((pattern) => pattern.test(file));
207
+ })
208
+ .map((file) => path.join(fullPath, file));
209
+ }
210
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/seeding/loader.ts"],"names":[],"mappings":"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"}