@veloxts/cli 0.4.1 → 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.
- package/README.md +23 -144
- 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/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/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/migrations/rollback-runner.d.ts.map +1 -1
- package/dist/migrations/rollback-runner.js +13 -1
- package/dist/migrations/rollback-runner.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/package.json +6 -6
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory System
|
|
3
|
+
*
|
|
4
|
+
* Base factory class and registry for generating fake data.
|
|
5
|
+
*/
|
|
6
|
+
import type { Factory, FactoryRegistry, PrismaClientLike, StateModifier } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Abstract base class for model factories.
|
|
9
|
+
*
|
|
10
|
+
* Provides a fluent API for creating model instances with fake data
|
|
11
|
+
* and named state variations.
|
|
12
|
+
*
|
|
13
|
+
* @template TInput - The input type for creating records
|
|
14
|
+
* @template TOutput - The output type returned from database (defaults to TInput)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { BaseFactory } from '@veloxts/cli';
|
|
19
|
+
* import { faker } from '@faker-js/faker';
|
|
20
|
+
*
|
|
21
|
+
* interface UserInput {
|
|
22
|
+
* email: string;
|
|
23
|
+
* name: string;
|
|
24
|
+
* role: 'admin' | 'user';
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* export class UserFactory extends BaseFactory<UserInput> {
|
|
28
|
+
* modelName = 'user';
|
|
29
|
+
*
|
|
30
|
+
* definition(): UserInput {
|
|
31
|
+
* return {
|
|
32
|
+
* email: faker.internet.email(),
|
|
33
|
+
* name: faker.person.fullName(),
|
|
34
|
+
* role: 'user',
|
|
35
|
+
* };
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* admin(): this {
|
|
39
|
+
* return this.state('admin');
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* constructor(prisma: PrismaClientLike) {
|
|
43
|
+
* super(prisma);
|
|
44
|
+
* this.registerState('admin', (attrs) => ({ ...attrs, role: 'admin' }));
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare abstract class BaseFactory<TInput extends Record<string, unknown>, TOutput = TInput> implements Factory<TInput, TOutput> {
|
|
50
|
+
/** Map of registered state modifiers */
|
|
51
|
+
protected states: Map<string, StateModifier<TInput>>;
|
|
52
|
+
/** Currently active state names */
|
|
53
|
+
protected activeStates: string[];
|
|
54
|
+
/** Prisma client for database operations */
|
|
55
|
+
protected readonly prisma: PrismaClientLike;
|
|
56
|
+
/**
|
|
57
|
+
* Model name for Prisma operations (e.g., 'user', 'post').
|
|
58
|
+
* Must match the lowercase model name in your Prisma schema.
|
|
59
|
+
*/
|
|
60
|
+
abstract readonly modelName: string;
|
|
61
|
+
/**
|
|
62
|
+
* Define default attributes for new instances.
|
|
63
|
+
* Override this method to provide fake data generation.
|
|
64
|
+
*/
|
|
65
|
+
abstract definition(): TInput;
|
|
66
|
+
constructor(prisma: PrismaClientLike);
|
|
67
|
+
/**
|
|
68
|
+
* Register a named state modifier.
|
|
69
|
+
*
|
|
70
|
+
* @param name - State name (e.g., 'admin', 'verified')
|
|
71
|
+
* @param modifier - Function that modifies attributes
|
|
72
|
+
* @returns this for chaining during construction
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* constructor(prisma: PrismaClientLike) {
|
|
77
|
+
* super(prisma);
|
|
78
|
+
* this.registerState('admin', (attrs) => ({ ...attrs, role: 'admin' }));
|
|
79
|
+
* this.registerState('unverified', (attrs) => ({ ...attrs, emailVerified: null }));
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
protected registerState(name: string, modifier: StateModifier<TInput>): this;
|
|
84
|
+
/**
|
|
85
|
+
* Apply a named state modifier.
|
|
86
|
+
* Returns a new factory instance with the state applied.
|
|
87
|
+
*
|
|
88
|
+
* @param name - State name to apply
|
|
89
|
+
* @returns New factory instance with state active (preserves subclass type)
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // Create an admin user
|
|
94
|
+
* await factory.get(UserFactory).state('admin').create();
|
|
95
|
+
*
|
|
96
|
+
* // Chain multiple states
|
|
97
|
+
* await factory.get(UserFactory).state('admin').state('verified').create();
|
|
98
|
+
*
|
|
99
|
+
* // Subclass methods preserved after state()
|
|
100
|
+
* const factory = new UserFactory(prisma);
|
|
101
|
+
* await factory.state('verified').admin().create(); // admin() still accessible
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
state(name: string): this;
|
|
105
|
+
/**
|
|
106
|
+
* Get list of available state names.
|
|
107
|
+
*/
|
|
108
|
+
getAvailableStates(): ReadonlyArray<string>;
|
|
109
|
+
/**
|
|
110
|
+
* Make a single instance without persisting to database.
|
|
111
|
+
*
|
|
112
|
+
* @param overrides - Attributes to override defaults
|
|
113
|
+
* @returns Generated attributes
|
|
114
|
+
*/
|
|
115
|
+
make(overrides?: Partial<TInput>): TInput;
|
|
116
|
+
/**
|
|
117
|
+
* Make multiple instances without persisting to database.
|
|
118
|
+
*
|
|
119
|
+
* @param count - Number of instances to make
|
|
120
|
+
* @param overrides - Attributes to override defaults for all instances
|
|
121
|
+
* @returns Array of generated attributes
|
|
122
|
+
*/
|
|
123
|
+
makeMany(count: number, overrides?: Partial<TInput>): TInput[];
|
|
124
|
+
/**
|
|
125
|
+
* Create a single instance in the database.
|
|
126
|
+
*
|
|
127
|
+
* @param overrides - Attributes to override defaults
|
|
128
|
+
* @returns Created database record
|
|
129
|
+
*/
|
|
130
|
+
create(overrides?: Partial<TInput>): Promise<TOutput>;
|
|
131
|
+
/**
|
|
132
|
+
* Create multiple instances in the database.
|
|
133
|
+
*
|
|
134
|
+
* @param count - Number of instances to create
|
|
135
|
+
* @param overrides - Attributes to override defaults for all instances
|
|
136
|
+
* @returns Array of created database records
|
|
137
|
+
*/
|
|
138
|
+
createMany(count: number, overrides?: Partial<TInput>): Promise<TOutput[]>;
|
|
139
|
+
/**
|
|
140
|
+
* Build attributes by applying definition, states, and overrides.
|
|
141
|
+
*/
|
|
142
|
+
private buildAttributes;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create a factory registry for managing factory instances.
|
|
146
|
+
*
|
|
147
|
+
* The registry caches factory instances and provides type-safe access.
|
|
148
|
+
*
|
|
149
|
+
* @param prisma - Prisma client to inject into factories
|
|
150
|
+
* @returns Factory registry instance
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const registry = createFactoryRegistry(prisma);
|
|
155
|
+
*
|
|
156
|
+
* // Get or create factory instance
|
|
157
|
+
* const userFactory = registry.get(UserFactory);
|
|
158
|
+
* await userFactory.create();
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
export declare function createFactoryRegistry(prisma: PrismaClientLike): FactoryRegistry;
|
|
162
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/seeding/factory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,OAAO,EAEP,eAAe,EACf,gBAAgB,EAChB,aAAa,EACd,MAAM,YAAY,CAAC;AA2BpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,8BAAsB,WAAW,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CACxF,YAAW,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnC,wCAAwC;IACxC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAa;IAEjE,mCAAmC;IACnC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAM;IAEtC,4CAA4C;IAC5C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAE5C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAEpC;;;OAGG;IACH,QAAQ,CAAC,UAAU,IAAI,MAAM;gBAEjB,MAAM,EAAE,gBAAgB;IAQpC;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI;IAK5E;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAazB;;OAEG;IACH,kBAAkB,IAAI,aAAa,CAAC,MAAM,CAAC;IAQ3C;;;;;OAKG;IACH,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;IAIzC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;IAQ9D;;;;;OAKG;IACG,MAAM,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB3D;;;;;;OAMG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAiBhF;;OAEG;IACH,OAAO,CAAC,eAAe;CAmBxB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAyB/E"}
|
|
@@ -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"}
|