@geekmidas/testkit 0.0.10 → 0.0.12
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/Factory-Bm44VKa-.d.cts +131 -0
- package/dist/Factory-tjCDNgUK.d.mts +131 -0
- package/dist/Factory.d.cts +3 -0
- package/dist/Factory.d.mts +3 -0
- package/dist/KyselyFactory-BoPDDitt.d.cts +200 -0
- package/dist/{KyselyFactory-ELiHgHVv.mjs → KyselyFactory-C3Bc3p4L.mjs} +1 -1
- package/dist/{KyselyFactory-Bdq1s1Go.cjs → KyselyFactory-CXtfmMfK.cjs} +1 -1
- package/dist/KyselyFactory-D82j74t9.d.mts +200 -0
- package/dist/KyselyFactory.cjs +2 -2
- package/dist/KyselyFactory.d.cts +4 -0
- package/dist/KyselyFactory.d.mts +4 -0
- package/dist/KyselyFactory.mjs +2 -2
- package/dist/ObjectionFactory-BWMTXsxH.d.cts +213 -0
- package/dist/ObjectionFactory-CEG5qUrm.d.mts +213 -0
- package/dist/{ObjectionFactory-C47B03Ot.cjs → ObjectionFactory-DxIxJagq.cjs} +82 -40
- package/dist/{ObjectionFactory-89p-FFEw.mjs → ObjectionFactory-qIICOph3.mjs} +82 -40
- package/dist/ObjectionFactory.cjs +2 -1
- package/dist/ObjectionFactory.d.cts +4 -0
- package/dist/ObjectionFactory.d.mts +4 -0
- package/dist/ObjectionFactory.mjs +2 -1
- package/dist/PostgresKyselyMigrator-CQ3aUoy_.d.cts +67 -0
- package/dist/PostgresKyselyMigrator-_6yHZigp.d.mts +67 -0
- package/dist/PostgresKyselyMigrator.d.cts +3 -0
- package/dist/PostgresKyselyMigrator.d.mts +3 -0
- package/dist/PostgresMigrator-BlvuQl7d.d.mts +84 -0
- package/dist/PostgresMigrator-D5UkK1_K.d.cts +84 -0
- package/dist/PostgresMigrator.d.cts +2 -0
- package/dist/PostgresMigrator.d.mts +2 -0
- package/dist/PostgresObjectionMigrator-C69n7vzr.d.mts +77 -0
- package/dist/PostgresObjectionMigrator-CZHHcCOv.d.cts +77 -0
- package/dist/PostgresObjectionMigrator.d.cts +3 -0
- package/dist/PostgresObjectionMigrator.d.mts +3 -0
- package/dist/VitestKyselyTransactionIsolator-ClCazkBO.d.mts +56 -0
- package/dist/VitestKyselyTransactionIsolator-UE1J-UoP.d.cts +56 -0
- package/dist/VitestKyselyTransactionIsolator.d.cts +3 -0
- package/dist/VitestKyselyTransactionIsolator.d.mts +3 -0
- package/dist/VitestObjectionTransactionIsolator-CO2nTi9r.d.cts +57 -0
- package/dist/VitestObjectionTransactionIsolator-D264iuPy.d.mts +57 -0
- package/dist/VitestObjectionTransactionIsolator.d.cts +3 -0
- package/dist/VitestObjectionTransactionIsolator.d.mts +3 -0
- package/dist/VitestTransactionIsolator-DHf2MxmC.d.cts +118 -0
- package/dist/VitestTransactionIsolator-Xqyjlmw6.d.mts +118 -0
- package/dist/VitestTransactionIsolator.d.cts +2 -0
- package/dist/VitestTransactionIsolator.d.mts +2 -0
- package/dist/__tests__/Factory.spec.d.cts +1 -0
- package/dist/__tests__/Factory.spec.d.mts +1 -0
- package/dist/__tests__/KyselyFactory.spec.cjs +2 -2
- package/dist/__tests__/KyselyFactory.spec.d.cts +1 -0
- package/dist/__tests__/KyselyFactory.spec.d.mts +1 -0
- package/dist/__tests__/KyselyFactory.spec.mjs +2 -2
- package/dist/__tests__/ObjectionFactory.spec.cjs +117 -1
- package/dist/__tests__/ObjectionFactory.spec.d.cts +1 -0
- package/dist/__tests__/ObjectionFactory.spec.d.mts +1 -0
- package/dist/__tests__/ObjectionFactory.spec.mjs +117 -1
- package/dist/__tests__/PostgresMigrator.spec.d.cts +1 -0
- package/dist/__tests__/PostgresMigrator.spec.d.mts +1 -0
- package/dist/__tests__/PostgresObjectionMigrator.spec.d.cts +1 -0
- package/dist/__tests__/PostgresObjectionMigrator.spec.d.mts +1 -0
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.cjs +2 -1
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.d.cts +1 -0
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.d.mts +1 -0
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.mjs +2 -1
- package/dist/__tests__/faker.spec.cjs +1 -1
- package/dist/__tests__/faker.spec.d.cts +1 -0
- package/dist/__tests__/faker.spec.d.mts +1 -0
- package/dist/__tests__/faker.spec.mjs +1 -1
- package/dist/__tests__/integration.spec.cjs +2 -2
- package/dist/__tests__/integration.spec.d.cts +1 -0
- package/dist/__tests__/integration.spec.d.mts +1 -0
- package/dist/__tests__/integration.spec.mjs +2 -2
- package/dist/example.cjs +2 -2
- package/dist/example.d.cts +26 -0
- package/dist/example.d.mts +26 -0
- package/dist/example.mjs +2 -2
- package/dist/{faker-SMN4ira4.cjs → faker-B14IEMIN.cjs} +41 -1
- package/dist/{faker-CxKkEeYi.mjs → faker-BGKYFoCT.mjs} +36 -2
- package/dist/faker-ChuHaYMR.d.mts +165 -0
- package/dist/faker-km9UhOS6.d.cts +165 -0
- package/dist/faker.cjs +2 -1
- package/dist/faker.d.cts +2 -0
- package/dist/faker.d.mts +2 -0
- package/dist/faker.mjs +2 -2
- package/dist/helpers.d.cts +41 -0
- package/dist/helpers.d.mts +41 -0
- package/dist/kysely.cjs +2 -2
- package/dist/kysely.d.cts +73 -0
- package/dist/kysely.d.mts +73 -0
- package/dist/kysely.mjs +2 -2
- package/dist/objection.cjs +2 -1
- package/dist/objection.d.cts +88 -0
- package/dist/objection.d.mts +88 -0
- package/dist/objection.mjs +2 -1
- package/package.json +5 -5
- package/src/ObjectionFactory.ts +156 -13
- package/src/__tests__/ObjectionFactory.spec.ts +162 -0
- package/src/faker.ts +86 -0
- package/PostgresKyselyMigrator.spec +0 -471
package/dist/KyselyFactory.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require('./Factory-WMhTNZ9S.cjs');
|
|
2
|
-
require('./faker-
|
|
3
|
-
const require_KyselyFactory = require('./KyselyFactory-
|
|
2
|
+
require('./faker-B14IEMIN.cjs');
|
|
3
|
+
const require_KyselyFactory = require('./KyselyFactory-CXtfmMfK.cjs');
|
|
4
4
|
|
|
5
5
|
exports.KyselyFactory = require_KyselyFactory.KyselyFactory;
|
package/dist/KyselyFactory.mjs
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { FakerFactory } from "./faker-km9UhOS6.cjs";
|
|
2
|
+
import { Factory, FactorySeed } from "./Factory-Bm44VKa-.cjs";
|
|
3
|
+
import { Knex } from "knex";
|
|
4
|
+
import { Model } from "objection";
|
|
5
|
+
|
|
6
|
+
//#region src/ObjectionFactory.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Factory implementation for Objection.js ORM, providing test data creation utilities.
|
|
10
|
+
* Extends the base Factory class with Objection.js-specific database operations.
|
|
11
|
+
*
|
|
12
|
+
* @template Builders - Record of builder functions for creating entities
|
|
13
|
+
* @template Seeds - Record of seed functions for complex test scenarios
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Define your models with Objection.js
|
|
18
|
+
* class User extends Model {
|
|
19
|
+
* static tableName = 'users';
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* // Create builders
|
|
23
|
+
* const builders = {
|
|
24
|
+
* user: (attrs) => User.fromJson({
|
|
25
|
+
* id: faker.string.uuid(),
|
|
26
|
+
* name: faker.person.fullName(),
|
|
27
|
+
* email: faker.internet.email(),
|
|
28
|
+
* ...attrs
|
|
29
|
+
* }),
|
|
30
|
+
* post: (attrs) => Post.fromJson({
|
|
31
|
+
* title: 'Test Post',
|
|
32
|
+
* content: 'Test content',
|
|
33
|
+
* ...attrs
|
|
34
|
+
* })
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* // Create factory instance
|
|
38
|
+
* const factory = new ObjectionFactory(builders, seeds, knex);
|
|
39
|
+
*
|
|
40
|
+
* // Use in tests
|
|
41
|
+
* const user = await factory.insert('user', { name: 'John Doe' });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare class ObjectionFactory<Builders extends Record<string, any>, Seeds extends Record<string, any>> extends Factory<Builders, Seeds> {
|
|
45
|
+
private builders;
|
|
46
|
+
private seeds;
|
|
47
|
+
private db;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a typed seed function with proper type inference.
|
|
50
|
+
* Inherits from the base Factory class implementation.
|
|
51
|
+
*
|
|
52
|
+
* @template Seed - The seed function type
|
|
53
|
+
* @param seedFn - The seed function to wrap
|
|
54
|
+
* @returns The same seed function with proper typing
|
|
55
|
+
*/
|
|
56
|
+
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a typed builder function for Objection.js models.
|
|
59
|
+
* This is a utility method that helps create builders with proper type inference.
|
|
60
|
+
*
|
|
61
|
+
* @template TModel - The Objection.js Model class type
|
|
62
|
+
* @template Attrs - The attributes type for the builder (defaults to Partial of model)
|
|
63
|
+
* @template Factory - The factory instance type
|
|
64
|
+
* @template Result - The result type (defaults to the model instance)
|
|
65
|
+
*
|
|
66
|
+
* @param ModelClass - The Objection.js Model class
|
|
67
|
+
* @param item - Optional function to provide default values and transformations
|
|
68
|
+
* @param autoInsert - Whether to automatically insert the record (default: true)
|
|
69
|
+
* @returns A builder function that creates and optionally inserts records
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // Create a simple builder with defaults
|
|
74
|
+
* const userBuilder = ObjectionFactory.createBuilder(User,
|
|
75
|
+
* (attrs, factory, db, faker) => ({
|
|
76
|
+
* id: faker.string.uuid(),
|
|
77
|
+
* name: faker.person.fullName(),
|
|
78
|
+
* email: faker.internet.email(),
|
|
79
|
+
* createdAt: new Date(),
|
|
80
|
+
* ...attrs
|
|
81
|
+
* })
|
|
82
|
+
* );
|
|
83
|
+
*
|
|
84
|
+
* // Create a builder that doesn't auto-insert (useful for nested inserts)
|
|
85
|
+
* const addressBuilder = ObjectionFactory.createBuilder(Address,
|
|
86
|
+
* (attrs) => ({
|
|
87
|
+
* street: '123 Main St',
|
|
88
|
+
* city: 'Anytown',
|
|
89
|
+
* ...attrs
|
|
90
|
+
* }),
|
|
91
|
+
* false // Don't auto-insert
|
|
92
|
+
* );
|
|
93
|
+
*
|
|
94
|
+
* // Use with relations
|
|
95
|
+
* const postBuilder = ObjectionFactory.createBuilder(Post,
|
|
96
|
+
* async (attrs, factory) => ({
|
|
97
|
+
* title: faker.lorem.sentence(),
|
|
98
|
+
* content: faker.lorem.paragraphs(),
|
|
99
|
+
* authorId: attrs.authorId || (await factory.insert('user')).id,
|
|
100
|
+
* ...attrs
|
|
101
|
+
* })
|
|
102
|
+
* );
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
static createBuilder<TModel extends typeof Model, Attrs extends Partial<InstanceType<TModel>> = Partial<InstanceType<TModel>>, Factory = any, Result = InstanceType<TModel>>(ModelClass: TModel, item?: (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Partial<InstanceType<TModel>> | Promise<Partial<InstanceType<TModel>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Promise<Result>;
|
|
106
|
+
/**
|
|
107
|
+
* Creates a new ObjectionFactory instance.
|
|
108
|
+
*
|
|
109
|
+
* @param builders - Record of builder functions for creating individual entities
|
|
110
|
+
* @param seeds - Record of seed functions for creating complex test scenarios
|
|
111
|
+
* @param db - Knex database connection instance
|
|
112
|
+
*/
|
|
113
|
+
constructor(builders: Builders, seeds: Seeds, db: Knex);
|
|
114
|
+
/**
|
|
115
|
+
* Inserts a single record into the database using the specified builder.
|
|
116
|
+
* Uses Objection.js's insertGraph method to handle nested relations.
|
|
117
|
+
*
|
|
118
|
+
* @template K - The builder name (must be a key of Builders)
|
|
119
|
+
* @param builderName - The name of the builder to use
|
|
120
|
+
* @param attrs - Optional attributes to override builder defaults
|
|
121
|
+
* @returns A promise resolving to the inserted record with all relations
|
|
122
|
+
* @throws Error if the specified builder doesn't exist
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* // Insert with defaults
|
|
127
|
+
* const user = await factory.insert('user');
|
|
128
|
+
*
|
|
129
|
+
* // Insert with overrides
|
|
130
|
+
* const adminUser = await factory.insert('user', {
|
|
131
|
+
* email: 'admin@example.com',
|
|
132
|
+
* role: 'admin'
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* // Insert with nested relations
|
|
136
|
+
* const userWithProfile = await factory.insert('user', {
|
|
137
|
+
* name: 'John Doe',
|
|
138
|
+
* profile: {
|
|
139
|
+
* bio: 'Software Developer',
|
|
140
|
+
* avatar: 'avatar.jpg'
|
|
141
|
+
* }
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
146
|
+
/**
|
|
147
|
+
* Inserts multiple records into the database using the specified builder.
|
|
148
|
+
* Supports both static attributes and dynamic attribute generation via a function.
|
|
149
|
+
*
|
|
150
|
+
* @param count - The number of records to insert
|
|
151
|
+
* @param builderName - The name of the builder to use
|
|
152
|
+
* @param attrs - Static attributes or a function that generates attributes for each record
|
|
153
|
+
* @returns A promise resolving to an array of inserted records
|
|
154
|
+
* @throws Error if the specified builder doesn't exist
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // Insert multiple with same attributes
|
|
159
|
+
* const users = await factory.insertMany(5, 'user', { role: 'member' });
|
|
160
|
+
*
|
|
161
|
+
* // Insert multiple with dynamic attributes
|
|
162
|
+
* const posts = await factory.insertMany(10, 'post', (idx) => ({
|
|
163
|
+
* title: `Post ${idx + 1}`,
|
|
164
|
+
* content: `Content for post ${idx + 1}`,
|
|
165
|
+
* publishedAt: new Date()
|
|
166
|
+
* }));
|
|
167
|
+
*
|
|
168
|
+
* // Create users with sequential emails
|
|
169
|
+
* const admins = await factory.insertMany(3, 'user', (idx) => ({
|
|
170
|
+
* email: `admin${idx + 1}@example.com`,
|
|
171
|
+
* role: 'admin'
|
|
172
|
+
* }));
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
insertMany<K extends keyof Builders>(count: number, builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
176
|
+
insertMany<K extends keyof Builders>(count: number, builderName: K, attrs: (idx: number, faker: FakerFactory) => Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
177
|
+
/**
|
|
178
|
+
* Executes a seed function to create complex test scenarios with multiple related records.
|
|
179
|
+
* Seeds are useful for setting up complete test environments with realistic data relationships.
|
|
180
|
+
*
|
|
181
|
+
* @template K - The seed name (must be a key of Seeds)
|
|
182
|
+
* @param seedName - The name of the seed to execute
|
|
183
|
+
* @param attrs - Optional configuration attributes for the seed
|
|
184
|
+
* @returns The result of the seed function (typically the primary record created)
|
|
185
|
+
* @throws Error if the specified seed doesn't exist
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* // Execute a simple seed
|
|
190
|
+
* const user = await factory.seed('userWithProfile');
|
|
191
|
+
*
|
|
192
|
+
* // Execute a seed with configuration
|
|
193
|
+
* const author = await factory.seed('authorWithBooks', {
|
|
194
|
+
* bookCount: 5,
|
|
195
|
+
* includeReviews: true
|
|
196
|
+
* });
|
|
197
|
+
*
|
|
198
|
+
* // Use seed result in tests with Objection.js relations
|
|
199
|
+
* const company = await factory.seed('companyWithDepartments', {
|
|
200
|
+
* departmentCount: 3,
|
|
201
|
+
* employeesPerDepartment: 10
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* // Access eager loaded relations
|
|
205
|
+
* const companyWithRelations = await Company.query()
|
|
206
|
+
* .findById(company.id)
|
|
207
|
+
* .withGraphFetched('[departments.employees]');
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
seed<K extends keyof Seeds>(seedName: K, attrs?: Parameters<Seeds[K]>[0]): ReturnType<Seeds[K]>;
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { ObjectionFactory };
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { FakerFactory } from "./faker-ChuHaYMR.mjs";
|
|
2
|
+
import { Factory, FactorySeed } from "./Factory-tjCDNgUK.mjs";
|
|
3
|
+
import { Knex } from "knex";
|
|
4
|
+
import { Model } from "objection";
|
|
5
|
+
|
|
6
|
+
//#region src/ObjectionFactory.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Factory implementation for Objection.js ORM, providing test data creation utilities.
|
|
10
|
+
* Extends the base Factory class with Objection.js-specific database operations.
|
|
11
|
+
*
|
|
12
|
+
* @template Builders - Record of builder functions for creating entities
|
|
13
|
+
* @template Seeds - Record of seed functions for complex test scenarios
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Define your models with Objection.js
|
|
18
|
+
* class User extends Model {
|
|
19
|
+
* static tableName = 'users';
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* // Create builders
|
|
23
|
+
* const builders = {
|
|
24
|
+
* user: (attrs) => User.fromJson({
|
|
25
|
+
* id: faker.string.uuid(),
|
|
26
|
+
* name: faker.person.fullName(),
|
|
27
|
+
* email: faker.internet.email(),
|
|
28
|
+
* ...attrs
|
|
29
|
+
* }),
|
|
30
|
+
* post: (attrs) => Post.fromJson({
|
|
31
|
+
* title: 'Test Post',
|
|
32
|
+
* content: 'Test content',
|
|
33
|
+
* ...attrs
|
|
34
|
+
* })
|
|
35
|
+
* };
|
|
36
|
+
*
|
|
37
|
+
* // Create factory instance
|
|
38
|
+
* const factory = new ObjectionFactory(builders, seeds, knex);
|
|
39
|
+
*
|
|
40
|
+
* // Use in tests
|
|
41
|
+
* const user = await factory.insert('user', { name: 'John Doe' });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare class ObjectionFactory<Builders extends Record<string, any>, Seeds extends Record<string, any>> extends Factory<Builders, Seeds> {
|
|
45
|
+
private builders;
|
|
46
|
+
private seeds;
|
|
47
|
+
private db;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a typed seed function with proper type inference.
|
|
50
|
+
* Inherits from the base Factory class implementation.
|
|
51
|
+
*
|
|
52
|
+
* @template Seed - The seed function type
|
|
53
|
+
* @param seedFn - The seed function to wrap
|
|
54
|
+
* @returns The same seed function with proper typing
|
|
55
|
+
*/
|
|
56
|
+
static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a typed builder function for Objection.js models.
|
|
59
|
+
* This is a utility method that helps create builders with proper type inference.
|
|
60
|
+
*
|
|
61
|
+
* @template TModel - The Objection.js Model class type
|
|
62
|
+
* @template Attrs - The attributes type for the builder (defaults to Partial of model)
|
|
63
|
+
* @template Factory - The factory instance type
|
|
64
|
+
* @template Result - The result type (defaults to the model instance)
|
|
65
|
+
*
|
|
66
|
+
* @param ModelClass - The Objection.js Model class
|
|
67
|
+
* @param item - Optional function to provide default values and transformations
|
|
68
|
+
* @param autoInsert - Whether to automatically insert the record (default: true)
|
|
69
|
+
* @returns A builder function that creates and optionally inserts records
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // Create a simple builder with defaults
|
|
74
|
+
* const userBuilder = ObjectionFactory.createBuilder(User,
|
|
75
|
+
* (attrs, factory, db, faker) => ({
|
|
76
|
+
* id: faker.string.uuid(),
|
|
77
|
+
* name: faker.person.fullName(),
|
|
78
|
+
* email: faker.internet.email(),
|
|
79
|
+
* createdAt: new Date(),
|
|
80
|
+
* ...attrs
|
|
81
|
+
* })
|
|
82
|
+
* );
|
|
83
|
+
*
|
|
84
|
+
* // Create a builder that doesn't auto-insert (useful for nested inserts)
|
|
85
|
+
* const addressBuilder = ObjectionFactory.createBuilder(Address,
|
|
86
|
+
* (attrs) => ({
|
|
87
|
+
* street: '123 Main St',
|
|
88
|
+
* city: 'Anytown',
|
|
89
|
+
* ...attrs
|
|
90
|
+
* }),
|
|
91
|
+
* false // Don't auto-insert
|
|
92
|
+
* );
|
|
93
|
+
*
|
|
94
|
+
* // Use with relations
|
|
95
|
+
* const postBuilder = ObjectionFactory.createBuilder(Post,
|
|
96
|
+
* async (attrs, factory) => ({
|
|
97
|
+
* title: faker.lorem.sentence(),
|
|
98
|
+
* content: faker.lorem.paragraphs(),
|
|
99
|
+
* authorId: attrs.authorId || (await factory.insert('user')).id,
|
|
100
|
+
* ...attrs
|
|
101
|
+
* })
|
|
102
|
+
* );
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
static createBuilder<TModel extends typeof Model, Attrs extends Partial<InstanceType<TModel>> = Partial<InstanceType<TModel>>, Factory = any, Result = InstanceType<TModel>>(ModelClass: TModel, item?: (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Partial<InstanceType<TModel>> | Promise<Partial<InstanceType<TModel>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Promise<Result>;
|
|
106
|
+
/**
|
|
107
|
+
* Creates a new ObjectionFactory instance.
|
|
108
|
+
*
|
|
109
|
+
* @param builders - Record of builder functions for creating individual entities
|
|
110
|
+
* @param seeds - Record of seed functions for creating complex test scenarios
|
|
111
|
+
* @param db - Knex database connection instance
|
|
112
|
+
*/
|
|
113
|
+
constructor(builders: Builders, seeds: Seeds, db: Knex);
|
|
114
|
+
/**
|
|
115
|
+
* Inserts a single record into the database using the specified builder.
|
|
116
|
+
* Uses Objection.js's insertGraph method to handle nested relations.
|
|
117
|
+
*
|
|
118
|
+
* @template K - The builder name (must be a key of Builders)
|
|
119
|
+
* @param builderName - The name of the builder to use
|
|
120
|
+
* @param attrs - Optional attributes to override builder defaults
|
|
121
|
+
* @returns A promise resolving to the inserted record with all relations
|
|
122
|
+
* @throws Error if the specified builder doesn't exist
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* // Insert with defaults
|
|
127
|
+
* const user = await factory.insert('user');
|
|
128
|
+
*
|
|
129
|
+
* // Insert with overrides
|
|
130
|
+
* const adminUser = await factory.insert('user', {
|
|
131
|
+
* email: 'admin@example.com',
|
|
132
|
+
* role: 'admin'
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* // Insert with nested relations
|
|
136
|
+
* const userWithProfile = await factory.insert('user', {
|
|
137
|
+
* name: 'John Doe',
|
|
138
|
+
* profile: {
|
|
139
|
+
* bio: 'Software Developer',
|
|
140
|
+
* avatar: 'avatar.jpg'
|
|
141
|
+
* }
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
insert<K extends keyof Builders>(builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>>;
|
|
146
|
+
/**
|
|
147
|
+
* Inserts multiple records into the database using the specified builder.
|
|
148
|
+
* Supports both static attributes and dynamic attribute generation via a function.
|
|
149
|
+
*
|
|
150
|
+
* @param count - The number of records to insert
|
|
151
|
+
* @param builderName - The name of the builder to use
|
|
152
|
+
* @param attrs - Static attributes or a function that generates attributes for each record
|
|
153
|
+
* @returns A promise resolving to an array of inserted records
|
|
154
|
+
* @throws Error if the specified builder doesn't exist
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // Insert multiple with same attributes
|
|
159
|
+
* const users = await factory.insertMany(5, 'user', { role: 'member' });
|
|
160
|
+
*
|
|
161
|
+
* // Insert multiple with dynamic attributes
|
|
162
|
+
* const posts = await factory.insertMany(10, 'post', (idx) => ({
|
|
163
|
+
* title: `Post ${idx + 1}`,
|
|
164
|
+
* content: `Content for post ${idx + 1}`,
|
|
165
|
+
* publishedAt: new Date()
|
|
166
|
+
* }));
|
|
167
|
+
*
|
|
168
|
+
* // Create users with sequential emails
|
|
169
|
+
* const admins = await factory.insertMany(3, 'user', (idx) => ({
|
|
170
|
+
* email: `admin${idx + 1}@example.com`,
|
|
171
|
+
* role: 'admin'
|
|
172
|
+
* }));
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
insertMany<K extends keyof Builders>(count: number, builderName: K, attrs?: Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
176
|
+
insertMany<K extends keyof Builders>(count: number, builderName: K, attrs: (idx: number, faker: FakerFactory) => Parameters<Builders[K]>[0]): Promise<Awaited<ReturnType<Builders[K]>>[]>;
|
|
177
|
+
/**
|
|
178
|
+
* Executes a seed function to create complex test scenarios with multiple related records.
|
|
179
|
+
* Seeds are useful for setting up complete test environments with realistic data relationships.
|
|
180
|
+
*
|
|
181
|
+
* @template K - The seed name (must be a key of Seeds)
|
|
182
|
+
* @param seedName - The name of the seed to execute
|
|
183
|
+
* @param attrs - Optional configuration attributes for the seed
|
|
184
|
+
* @returns The result of the seed function (typically the primary record created)
|
|
185
|
+
* @throws Error if the specified seed doesn't exist
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* // Execute a simple seed
|
|
190
|
+
* const user = await factory.seed('userWithProfile');
|
|
191
|
+
*
|
|
192
|
+
* // Execute a seed with configuration
|
|
193
|
+
* const author = await factory.seed('authorWithBooks', {
|
|
194
|
+
* bookCount: 5,
|
|
195
|
+
* includeReviews: true
|
|
196
|
+
* });
|
|
197
|
+
*
|
|
198
|
+
* // Use seed result in tests with Objection.js relations
|
|
199
|
+
* const company = await factory.seed('companyWithDepartments', {
|
|
200
|
+
* departmentCount: 3,
|
|
201
|
+
* employeesPerDepartment: 10
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* // Access eager loaded relations
|
|
205
|
+
* const companyWithRelations = await Company.query()
|
|
206
|
+
* .findById(company.id)
|
|
207
|
+
* .withGraphFetched('[departments.employees]');
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
seed<K extends keyof Seeds>(seedName: K, attrs?: Parameters<Seeds[K]>[0]): ReturnType<Seeds[K]>;
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { ObjectionFactory };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_Factory = require('./Factory-WMhTNZ9S.cjs');
|
|
2
|
+
const require_faker = require('./faker-B14IEMIN.cjs');
|
|
2
3
|
|
|
3
4
|
//#region src/ObjectionFactory.ts
|
|
4
5
|
/**
|
|
@@ -50,6 +51,71 @@ var ObjectionFactory = class extends require_Factory.Factory {
|
|
|
50
51
|
return require_Factory.Factory.createSeed(seedFn);
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
54
|
+
* Creates a typed builder function for Objection.js models.
|
|
55
|
+
* This is a utility method that helps create builders with proper type inference.
|
|
56
|
+
*
|
|
57
|
+
* @template TModel - The Objection.js Model class type
|
|
58
|
+
* @template Attrs - The attributes type for the builder (defaults to Partial of model)
|
|
59
|
+
* @template Factory - The factory instance type
|
|
60
|
+
* @template Result - The result type (defaults to the model instance)
|
|
61
|
+
*
|
|
62
|
+
* @param ModelClass - The Objection.js Model class
|
|
63
|
+
* @param item - Optional function to provide default values and transformations
|
|
64
|
+
* @param autoInsert - Whether to automatically insert the record (default: true)
|
|
65
|
+
* @returns A builder function that creates and optionally inserts records
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Create a simple builder with defaults
|
|
70
|
+
* const userBuilder = ObjectionFactory.createBuilder(User,
|
|
71
|
+
* (attrs, factory, db, faker) => ({
|
|
72
|
+
* id: faker.string.uuid(),
|
|
73
|
+
* name: faker.person.fullName(),
|
|
74
|
+
* email: faker.internet.email(),
|
|
75
|
+
* createdAt: new Date(),
|
|
76
|
+
* ...attrs
|
|
77
|
+
* })
|
|
78
|
+
* );
|
|
79
|
+
*
|
|
80
|
+
* // Create a builder that doesn't auto-insert (useful for nested inserts)
|
|
81
|
+
* const addressBuilder = ObjectionFactory.createBuilder(Address,
|
|
82
|
+
* (attrs) => ({
|
|
83
|
+
* street: '123 Main St',
|
|
84
|
+
* city: 'Anytown',
|
|
85
|
+
* ...attrs
|
|
86
|
+
* }),
|
|
87
|
+
* false // Don't auto-insert
|
|
88
|
+
* );
|
|
89
|
+
*
|
|
90
|
+
* // Use with relations
|
|
91
|
+
* const postBuilder = ObjectionFactory.createBuilder(Post,
|
|
92
|
+
* async (attrs, factory) => ({
|
|
93
|
+
* title: faker.lorem.sentence(),
|
|
94
|
+
* content: faker.lorem.paragraphs(),
|
|
95
|
+
* authorId: attrs.authorId || (await factory.insert('user')).id,
|
|
96
|
+
* ...attrs
|
|
97
|
+
* })
|
|
98
|
+
* );
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
static createBuilder(ModelClass, item, autoInsert) {
|
|
102
|
+
return async (attrs, factory, db, faker$1) => {
|
|
103
|
+
let data = { ...attrs };
|
|
104
|
+
if (item) {
|
|
105
|
+
const defaults = await item(attrs, factory, db, faker$1);
|
|
106
|
+
data = {
|
|
107
|
+
...defaults,
|
|
108
|
+
...data
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const model = ModelClass.fromJson(data);
|
|
112
|
+
if (autoInsert !== false) {
|
|
113
|
+
const result = await model.$query(db).insertGraph(model).execute();
|
|
114
|
+
return result;
|
|
115
|
+
} else return model;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
53
119
|
* Creates a new ObjectionFactory instance.
|
|
54
120
|
*
|
|
55
121
|
* @param builders - Record of builder functions for creating individual entities
|
|
@@ -66,7 +132,8 @@ var ObjectionFactory = class extends require_Factory.Factory {
|
|
|
66
132
|
* Inserts a single record into the database using the specified builder.
|
|
67
133
|
* Uses Objection.js's insertGraph method to handle nested relations.
|
|
68
134
|
*
|
|
69
|
-
* @
|
|
135
|
+
* @template K - The builder name (must be a key of Builders)
|
|
136
|
+
* @param builderName - The name of the builder to use
|
|
70
137
|
* @param attrs - Optional attributes to override builder defaults
|
|
71
138
|
* @returns A promise resolving to the inserted record with all relations
|
|
72
139
|
* @throws Error if the specified builder doesn't exist
|
|
@@ -92,47 +159,21 @@ var ObjectionFactory = class extends require_Factory.Factory {
|
|
|
92
159
|
* });
|
|
93
160
|
* ```
|
|
94
161
|
*/
|
|
95
|
-
insert(
|
|
96
|
-
if (!(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
162
|
+
async insert(builderName, attrs) {
|
|
163
|
+
if (!(builderName in this.builders)) throw new Error(`Factory "${builderName}" does not exist. Make sure it is correct and registered in src/test/setup.ts`);
|
|
164
|
+
const result = await this.builders[builderName](attrs || {}, this, this.db, require_faker.faker);
|
|
165
|
+
if (result && typeof result.$query === "function") return await result.$query(this.db).insertGraph(result).execute();
|
|
166
|
+
return result;
|
|
100
167
|
}
|
|
101
|
-
|
|
102
|
-
* Inserts multiple records into the database using the specified builder.
|
|
103
|
-
* Supports both static attributes and dynamic attribute generation via a function.
|
|
104
|
-
*
|
|
105
|
-
* @param count - The number of records to insert
|
|
106
|
-
* @param builderName - The name of the builder to use
|
|
107
|
-
* @param attrs - Static attributes or a function that generates attributes for each record
|
|
108
|
-
* @returns A promise resolving to an array of inserted records
|
|
109
|
-
* @throws Error if the specified builder doesn't exist
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```typescript
|
|
113
|
-
* // Insert multiple with same attributes
|
|
114
|
-
* const users = await factory.insertMany(5, 'user', { role: 'member' });
|
|
115
|
-
*
|
|
116
|
-
* // Insert multiple with dynamic attributes
|
|
117
|
-
* const posts = await factory.insertMany(10, 'post', (idx) => ({
|
|
118
|
-
* title: `Post ${idx + 1}`,
|
|
119
|
-
* content: `Content for post ${idx + 1}`,
|
|
120
|
-
* publishedAt: new Date()
|
|
121
|
-
* }));
|
|
122
|
-
*
|
|
123
|
-
* // Create users with sequential emails
|
|
124
|
-
* const admins = await factory.insertMany(3, 'user', (idx) => ({
|
|
125
|
-
* email: `admin${idx + 1}@example.com`,
|
|
126
|
-
* role: 'admin'
|
|
127
|
-
* }));
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
insertMany(count, builderName, attrs = {}) {
|
|
168
|
+
async insertMany(count, builderName, attrs) {
|
|
131
169
|
if (!(builderName in this.builders)) throw new Error(`Builder "${builderName}" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`);
|
|
132
170
|
const records = [];
|
|
133
171
|
for (let i = 0; i < count; i++) {
|
|
134
|
-
const newAttrs = typeof attrs === "function" ? attrs(i) : attrs;
|
|
135
|
-
records.push(this.builders[builderName](newAttrs,
|
|
172
|
+
const newAttrs = typeof attrs === "function" ? attrs(i, require_faker.faker) : attrs;
|
|
173
|
+
records.push(this.builders[builderName](newAttrs, this, this.db, require_faker.faker).then((record) => {
|
|
174
|
+
if (record && typeof record.$query === "function") return record.$query(this.db).insertGraph(record).execute();
|
|
175
|
+
return record;
|
|
176
|
+
}));
|
|
136
177
|
}
|
|
137
178
|
return Promise.all(records);
|
|
138
179
|
}
|
|
@@ -140,6 +181,7 @@ var ObjectionFactory = class extends require_Factory.Factory {
|
|
|
140
181
|
* Executes a seed function to create complex test scenarios with multiple related records.
|
|
141
182
|
* Seeds are useful for setting up complete test environments with realistic data relationships.
|
|
142
183
|
*
|
|
184
|
+
* @template K - The seed name (must be a key of Seeds)
|
|
143
185
|
* @param seedName - The name of the seed to execute
|
|
144
186
|
* @param attrs - Optional configuration attributes for the seed
|
|
145
187
|
* @returns The result of the seed function (typically the primary record created)
|
|
@@ -168,9 +210,9 @@ var ObjectionFactory = class extends require_Factory.Factory {
|
|
|
168
210
|
* .withGraphFetched('[departments.employees]');
|
|
169
211
|
* ```
|
|
170
212
|
*/
|
|
171
|
-
seed(seedName, attrs
|
|
213
|
+
seed(seedName, attrs) {
|
|
172
214
|
if (!(seedName in this.seeds)) throw new Error(`Seed "${seedName}" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`);
|
|
173
|
-
return this.seeds[seedName](attrs, this, this.db);
|
|
215
|
+
return this.seeds[seedName](attrs || {}, this, this.db);
|
|
174
216
|
}
|
|
175
217
|
};
|
|
176
218
|
|