@geekmidas/testkit 0.0.17 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +302 -199
  2. package/dist/{Factory-CRquB4vz.d.mts → Factory-Cmr3s3-s.d.mts} +2 -2
  3. package/dist/Factory.d.mts +2 -2
  4. package/dist/{KyselyFactory-DRQ83r0o.d.cts → KyselyFactory-BFygzOlO.d.cts} +21 -8
  5. package/dist/{KyselyFactory-BDS_QqRT.d.mts → KyselyFactory-BTdygZ-i.d.mts} +23 -10
  6. package/dist/{KyselyFactory-BcYkC0t2.mjs → KyselyFactory-CXY5gJk2.mjs} +25 -12
  7. package/dist/KyselyFactory-CXY5gJk2.mjs.map +1 -0
  8. package/dist/{KyselyFactory-Cf0o2YxO.cjs → KyselyFactory-DaaCykWP.cjs} +25 -12
  9. package/dist/KyselyFactory-DaaCykWP.cjs.map +1 -0
  10. package/dist/KyselyFactory.cjs +1 -1
  11. package/dist/KyselyFactory.d.cts +1 -1
  12. package/dist/KyselyFactory.d.mts +3 -3
  13. package/dist/KyselyFactory.mjs +1 -1
  14. package/dist/{ObjectionFactory-C3tHvX1d.d.mts → ObjectionFactory-BagGjikT.d.mts} +26 -13
  15. package/dist/{ObjectionFactory-C4X78k0B.d.cts → ObjectionFactory-CeSIN3kZ.d.cts} +24 -11
  16. package/dist/{ObjectionFactory-CDriunkS.cjs → ObjectionFactory-Eb04AOnv.cjs} +28 -15
  17. package/dist/ObjectionFactory-Eb04AOnv.cjs.map +1 -0
  18. package/dist/{ObjectionFactory-8hebmnai.mjs → ObjectionFactory-zf2fLKrL.mjs} +28 -15
  19. package/dist/ObjectionFactory-zf2fLKrL.mjs.map +1 -0
  20. package/dist/ObjectionFactory.cjs +1 -1
  21. package/dist/ObjectionFactory.d.cts +1 -1
  22. package/dist/ObjectionFactory.d.mts +3 -3
  23. package/dist/ObjectionFactory.mjs +1 -1
  24. package/dist/{VitestKyselyTransactionIsolator-COCVfvfr.d.mts → VitestKyselyTransactionIsolator-4HOeLQ0d.d.cts} +2 -2
  25. package/dist/{VitestKyselyTransactionIsolator-Cst3vFjb.cjs → VitestKyselyTransactionIsolator-DX_VPKS-.cjs} +2 -2
  26. package/dist/{VitestKyselyTransactionIsolator-Cst3vFjb.cjs.map → VitestKyselyTransactionIsolator-DX_VPKS-.cjs.map} +1 -1
  27. package/dist/{VitestKyselyTransactionIsolator-DYUYVEh9.d.cts → VitestKyselyTransactionIsolator-DnyZMaA-.d.mts} +2 -2
  28. package/dist/{VitestKyselyTransactionIsolator-BxjlD1YM.mjs → VitestKyselyTransactionIsolator-XDL3ngs_.mjs} +2 -2
  29. package/dist/{VitestKyselyTransactionIsolator-BxjlD1YM.mjs.map → VitestKyselyTransactionIsolator-XDL3ngs_.mjs.map} +1 -1
  30. package/dist/VitestKyselyTransactionIsolator.cjs +2 -2
  31. package/dist/VitestKyselyTransactionIsolator.d.cts +2 -2
  32. package/dist/VitestKyselyTransactionIsolator.d.mts +2 -2
  33. package/dist/VitestKyselyTransactionIsolator.mjs +2 -2
  34. package/dist/{VitestObjectionTransactionIsolator-b973r9O1.d.mts → VitestObjectionTransactionIsolator-COVDlpEo.d.cts} +2 -2
  35. package/dist/{VitestObjectionTransactionIsolator-DzeF4UAq.cjs → VitestObjectionTransactionIsolator-D_tlOtq8.cjs} +2 -2
  36. package/dist/{VitestObjectionTransactionIsolator-DzeF4UAq.cjs.map → VitestObjectionTransactionIsolator-D_tlOtq8.cjs.map} +1 -1
  37. package/dist/{VitestObjectionTransactionIsolator-BU-jXEhz.mjs → VitestObjectionTransactionIsolator-_EhJKu_O.mjs} +2 -2
  38. package/dist/{VitestObjectionTransactionIsolator-BU-jXEhz.mjs.map → VitestObjectionTransactionIsolator-_EhJKu_O.mjs.map} +1 -1
  39. package/dist/{VitestObjectionTransactionIsolator-CJ4ds5Qv.d.cts → VitestObjectionTransactionIsolator-lZUSz1w0.d.mts} +2 -2
  40. package/dist/VitestObjectionTransactionIsolator.cjs +2 -2
  41. package/dist/VitestObjectionTransactionIsolator.d.cts +2 -2
  42. package/dist/VitestObjectionTransactionIsolator.d.mts +2 -2
  43. package/dist/VitestObjectionTransactionIsolator.mjs +2 -2
  44. package/dist/{VitestTransactionIsolator-CskiiJbW.mjs → VitestTransactionIsolator-BIaMs4c2.mjs} +40 -2
  45. package/dist/VitestTransactionIsolator-BIaMs4c2.mjs.map +1 -0
  46. package/dist/{VitestTransactionIsolator-BQ5FpLtC.cjs → VitestTransactionIsolator-BKIrj3Uy.cjs} +45 -1
  47. package/dist/VitestTransactionIsolator-BKIrj3Uy.cjs.map +1 -0
  48. package/dist/{VitestTransactionIsolator-DdLNODZg.d.cts → VitestTransactionIsolator-CyG_i_Nj.d.cts} +61 -3
  49. package/dist/{VitestTransactionIsolator-CsfJBxcb.d.mts → VitestTransactionIsolator-DWDbnITQ.d.mts} +61 -3
  50. package/dist/VitestTransactionIsolator.cjs +3 -2
  51. package/dist/VitestTransactionIsolator.d.cts +2 -2
  52. package/dist/VitestTransactionIsolator.d.mts +2 -2
  53. package/dist/VitestTransactionIsolator.mjs +2 -2
  54. package/dist/better-auth.cjs +8 -11
  55. package/dist/better-auth.cjs.map +1 -1
  56. package/dist/better-auth.d.cts +2 -2
  57. package/dist/better-auth.d.mts +2 -2
  58. package/dist/better-auth.mjs +8 -11
  59. package/dist/better-auth.mjs.map +1 -1
  60. package/dist/{directory-B4oYx02C.d.mts → directory-BXavAeJZ.d.mts} +3 -3
  61. package/dist/{directory-BUcnztHI.d.cts → directory-DlkPEzL4.d.cts} +3 -3
  62. package/dist/{faker-Br8MzXil.d.mts → faker-DHh7xs4u.d.mts} +3 -3
  63. package/dist/faker.d.mts +1 -1
  64. package/dist/kysely.cjs +58 -4
  65. package/dist/kysely.cjs.map +1 -1
  66. package/dist/kysely.d.cts +58 -5
  67. package/dist/kysely.d.mts +59 -6
  68. package/dist/kysely.mjs +57 -5
  69. package/dist/kysely.mjs.map +1 -1
  70. package/dist/objection.cjs +54 -4
  71. package/dist/objection.cjs.map +1 -1
  72. package/dist/objection.d.cts +54 -5
  73. package/dist/objection.d.mts +55 -6
  74. package/dist/objection.mjs +53 -5
  75. package/dist/objection.mjs.map +1 -1
  76. package/dist/os/directory.d.cts +1 -1
  77. package/dist/os/directory.d.mts +1 -1
  78. package/dist/os/index.d.cts +1 -1
  79. package/dist/os/index.d.mts +1 -1
  80. package/package.json +7 -3
  81. package/src/KyselyFactory.ts +29 -16
  82. package/src/ObjectionFactory.ts +34 -19
  83. package/src/VitestTransactionIsolator.ts +110 -2
  84. package/src/__tests__/KyselyFactory.spec.ts +10 -10
  85. package/src/__tests__/ObjectionFactory.spec.ts +9 -12
  86. package/src/__tests__/integration.spec.ts +171 -14
  87. package/src/better-auth.ts +13 -15
  88. package/src/kysely.ts +66 -0
  89. package/src/objection.ts +61 -0
  90. package/dist/KyselyFactory-BcYkC0t2.mjs.map +0 -1
  91. package/dist/KyselyFactory-Cf0o2YxO.cjs.map +0 -1
  92. package/dist/ObjectionFactory-8hebmnai.mjs.map +0 -1
  93. package/dist/ObjectionFactory-CDriunkS.cjs.map +0 -1
  94. package/dist/VitestTransactionIsolator-BQ5FpLtC.cjs.map +0 -1
  95. package/dist/VitestTransactionIsolator-CskiiJbW.mjs.map +0 -1
@@ -22,13 +22,13 @@ import { ControlledTransaction, Insertable, Kysely, Selectable } from "kysely";
22
22
  *
23
23
  * // Create builders
24
24
  * const builders = {
25
- * user: KyselyFactory.createBuilder<Database, 'users'>('users', (attrs, factory, db, faker) => ({
25
+ * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({
26
26
  * id: faker.string.uuid(),
27
27
  * name: faker.person.fullName(),
28
28
  * email: faker.internet.email(),
29
29
  * ...attrs
30
30
  * })),
31
- * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', (attrs) => ({
31
+ * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({
32
32
  * title: 'Test Post',
33
33
  * content: 'Test content',
34
34
  * ...attrs
@@ -74,15 +74,15 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
74
74
  * @template Result - The result type (defaults to Selectable of the table)
75
75
  *
76
76
  * @param table - The name of the database table
77
- * @param item - Optional function to provide default values and transformations
77
+ * @param defaults - Optional function to provide default values (receives destructured context)
78
78
  * @param autoInsert - Whether to automatically insert the record (default: true)
79
79
  * @returns A builder function that creates and optionally inserts records
80
80
  *
81
81
  * @example
82
82
  * ```typescript
83
- * // Create a simple builder with defaults
83
+ * // Create a simple builder with defaults - destructure only what you need
84
84
  * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',
85
- * (attrs, factory, db, faker) => ({
85
+ * ({ attrs, faker }) => ({
86
86
  * id: faker.string.uuid(),
87
87
  * name: faker.person.fullName(),
88
88
  * email: faker.internet.email(),
@@ -91,9 +91,17 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
91
91
  * })
92
92
  * );
93
93
  *
94
+ * // Only need faker? Just destructure that
95
+ * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',
96
+ * ({ faker }) => ({
97
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
98
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
99
+ * })
100
+ * );
101
+ *
94
102
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
95
103
  * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',
96
- * (attrs) => ({
104
+ * ({ attrs }) => ({
97
105
  * street: '123 Main St',
98
106
  * city: 'Anytown',
99
107
  * ...attrs
@@ -102,7 +110,12 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
102
110
  * );
103
111
  * ```
104
112
  */
105
- static createBuilder<DB, TableName extends keyof DB & string, Attrs extends Partial<Insertable<DB[TableName]>> = Partial<Insertable<DB[TableName]>>, Factory = any, Result = Selectable<DB[TableName]>>(table: TableName, item?: (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Partial<Insertable<DB[TableName]>> | Promise<Partial<Insertable<DB[TableName]>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Promise<Result>;
113
+ static createBuilder<DB, TableName extends keyof DB & string, Attrs extends Partial<Insertable<DB[TableName]>> = Partial<Insertable<DB[TableName]>>, Factory = any, Result = Selectable<DB[TableName]>>(table: TableName, defaults?: (context: {
114
+ attrs: Attrs;
115
+ factory: Factory;
116
+ db: Kysely<DB>;
117
+ faker: FakerFactory;
118
+ }) => Partial<Insertable<DB[TableName]>> | Promise<Partial<Insertable<DB[TableName]>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Promise<Result>;
106
119
  /**
107
120
  * Inserts a single record into the database using the specified builder.
108
121
  * The builder function is responsible for generating the record data with defaults
@@ -198,4 +211,4 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
198
211
  }
199
212
  //#endregion
200
213
  export { KyselyFactory };
201
- //# sourceMappingURL=KyselyFactory-DRQ83r0o.d.cts.map
214
+ //# sourceMappingURL=KyselyFactory-BFygzOlO.d.cts.map
@@ -1,5 +1,5 @@
1
- import { FakerFactory } from "./faker-Br8MzXil.mjs";
2
- import { Factory, FactorySeed } from "./Factory-CRquB4vz.mjs";
1
+ import { FakerFactory } from "./faker-DHh7xs4u.mjs";
2
+ import { Factory, FactorySeed } from "./Factory-Cmr3s3-s.mjs";
3
3
  import { ControlledTransaction, Insertable, Kysely, Selectable } from "kysely";
4
4
 
5
5
  //#region src/KyselyFactory.d.ts
@@ -22,13 +22,13 @@ import { ControlledTransaction, Insertable, Kysely, Selectable } from "kysely";
22
22
  *
23
23
  * // Create builders
24
24
  * const builders = {
25
- * user: KyselyFactory.createBuilder<Database, 'users'>('users', (attrs, factory, db, faker) => ({
25
+ * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({
26
26
  * id: faker.string.uuid(),
27
27
  * name: faker.person.fullName(),
28
28
  * email: faker.internet.email(),
29
29
  * ...attrs
30
30
  * })),
31
- * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', (attrs) => ({
31
+ * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({
32
32
  * title: 'Test Post',
33
33
  * content: 'Test content',
34
34
  * ...attrs
@@ -74,15 +74,15 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
74
74
  * @template Result - The result type (defaults to Selectable of the table)
75
75
  *
76
76
  * @param table - The name of the database table
77
- * @param item - Optional function to provide default values and transformations
77
+ * @param defaults - Optional function to provide default values (receives destructured context)
78
78
  * @param autoInsert - Whether to automatically insert the record (default: true)
79
79
  * @returns A builder function that creates and optionally inserts records
80
80
  *
81
81
  * @example
82
82
  * ```typescript
83
- * // Create a simple builder with defaults
83
+ * // Create a simple builder with defaults - destructure only what you need
84
84
  * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',
85
- * (attrs, factory, db, faker) => ({
85
+ * ({ attrs, faker }) => ({
86
86
  * id: faker.string.uuid(),
87
87
  * name: faker.person.fullName(),
88
88
  * email: faker.internet.email(),
@@ -91,9 +91,17 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
91
91
  * })
92
92
  * );
93
93
  *
94
+ * // Only need faker? Just destructure that
95
+ * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',
96
+ * ({ faker }) => ({
97
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
98
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
99
+ * })
100
+ * );
101
+ *
94
102
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
95
103
  * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',
96
- * (attrs) => ({
104
+ * ({ attrs }) => ({
97
105
  * street: '123 Main St',
98
106
  * city: 'Anytown',
99
107
  * ...attrs
@@ -102,7 +110,12 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
102
110
  * );
103
111
  * ```
104
112
  */
105
- static createBuilder<DB, TableName extends keyof DB & string, Attrs extends Partial<Insertable<DB[TableName]>> = Partial<Insertable<DB[TableName]>>, Factory = any, Result = Selectable<DB[TableName]>>(table: TableName, item?: (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Partial<Insertable<DB[TableName]>> | Promise<Partial<Insertable<DB[TableName]>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Promise<Result>;
113
+ static createBuilder<DB, TableName extends keyof DB & string, Attrs extends Partial<Insertable<DB[TableName]>> = Partial<Insertable<DB[TableName]>>, Factory = any, Result = Selectable<DB[TableName]>>(table: TableName, defaults?: (context: {
114
+ attrs: Attrs;
115
+ factory: Factory;
116
+ db: Kysely<DB>;
117
+ faker: FakerFactory;
118
+ }) => Partial<Insertable<DB[TableName]>> | Promise<Partial<Insertable<DB[TableName]>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Kysely<DB>, faker: FakerFactory) => Promise<Result>;
106
119
  /**
107
120
  * Inserts a single record into the database using the specified builder.
108
121
  * The builder function is responsible for generating the record data with defaults
@@ -198,4 +211,4 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
198
211
  }
199
212
  //#endregion
200
213
  export { KyselyFactory };
201
- //# sourceMappingURL=KyselyFactory-BDS_QqRT.d.mts.map
214
+ //# sourceMappingURL=KyselyFactory-BTdygZ-i.d.mts.map
@@ -20,13 +20,13 @@ import { faker } from "./faker-BGKYFoCT.mjs";
20
20
  *
21
21
  * // Create builders
22
22
  * const builders = {
23
- * user: KyselyFactory.createBuilder<Database, 'users'>('users', (attrs, factory, db, faker) => ({
23
+ * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({
24
24
  * id: faker.string.uuid(),
25
25
  * name: faker.person.fullName(),
26
26
  * email: faker.internet.email(),
27
27
  * ...attrs
28
28
  * })),
29
- * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', (attrs) => ({
29
+ * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({
30
30
  * title: 'Test Post',
31
31
  * content: 'Test content',
32
32
  * ...attrs
@@ -76,15 +76,15 @@ var KyselyFactory = class extends Factory {
76
76
  * @template Result - The result type (defaults to Selectable of the table)
77
77
  *
78
78
  * @param table - The name of the database table
79
- * @param item - Optional function to provide default values and transformations
79
+ * @param defaults - Optional function to provide default values (receives destructured context)
80
80
  * @param autoInsert - Whether to automatically insert the record (default: true)
81
81
  * @returns A builder function that creates and optionally inserts records
82
82
  *
83
83
  * @example
84
84
  * ```typescript
85
- * // Create a simple builder with defaults
85
+ * // Create a simple builder with defaults - destructure only what you need
86
86
  * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',
87
- * (attrs, factory, db, faker) => ({
87
+ * ({ attrs, faker }) => ({
88
88
  * id: faker.string.uuid(),
89
89
  * name: faker.person.fullName(),
90
90
  * email: faker.internet.email(),
@@ -93,9 +93,17 @@ var KyselyFactory = class extends Factory {
93
93
  * })
94
94
  * );
95
95
  *
96
+ * // Only need faker? Just destructure that
97
+ * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',
98
+ * ({ faker }) => ({
99
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
100
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
101
+ * })
102
+ * );
103
+ *
96
104
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
97
105
  * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',
98
- * (attrs) => ({
106
+ * ({ attrs }) => ({
99
107
  * street: '123 Main St',
100
108
  * city: 'Anytown',
101
109
  * ...attrs
@@ -104,13 +112,18 @@ var KyselyFactory = class extends Factory {
104
112
  * );
105
113
  * ```
106
114
  */
107
- static createBuilder(table, item, autoInsert) {
108
- return async (attrs, factory, db, faker$1) => {
115
+ static createBuilder(table, defaults, autoInsert) {
116
+ return async (attrs, factory, db, fakerInstance) => {
109
117
  let data = { ...attrs };
110
- if (item) {
111
- const defaults = await item(attrs, factory, db, faker$1);
118
+ if (defaults) {
119
+ const defaultValues = await defaults({
120
+ attrs,
121
+ factory,
122
+ db,
123
+ faker: fakerInstance
124
+ });
112
125
  data = {
113
- ...defaults,
126
+ ...defaultValues,
114
127
  ...data
115
128
  };
116
129
  }
@@ -208,4 +221,4 @@ var KyselyFactory = class extends Factory {
208
221
 
209
222
  //#endregion
210
223
  export { KyselyFactory };
211
- //# sourceMappingURL=KyselyFactory-BcYkC0t2.mjs.map
224
+ //# sourceMappingURL=KyselyFactory-CXY5gJk2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KyselyFactory-CXY5gJk2.mjs","names":["seedFn: Seed","builders: Builders","seeds: Seeds","db: Kysely<DB> | ControlledTransaction<DB, []>","table: TableName","defaults?: (context: {\n attrs: Attrs;\n factory: Factory;\n db: Kysely<DB>;\n faker: FakerFactory;\n }) =>\n | Partial<Insertable<DB[TableName]>>\n | Promise<Partial<Insertable<DB[TableName]>>>","autoInsert?: boolean","attrs: Attrs","factory: Factory","db: Kysely<DB>","fakerInstance: FakerFactory","data: Partial<Insertable<DB[TableName]>>","builderName: K","attrs?: Parameters<Builders[K]>[0]","count: number","attrs?: any","promises: Promise<any>[]","seedName: K","attrs?: Parameters<Seeds[K]>[0]"],"sources":["../src/KyselyFactory.ts"],"sourcesContent":["import type {\n ControlledTransaction,\n Insertable,\n Kysely,\n Selectable,\n} from 'kysely';\nimport { Factory, type FactorySeed } from './Factory.ts';\nimport { type FakerFactory, faker } from './faker.ts';\n\n/**\n * Factory implementation for Kysely ORM, providing test data creation utilities.\n * Extends the base Factory class with Kysely-specific database operations.\n *\n * @template DB - The database schema type\n * @template Builders - Record of builder functions for creating entities\n * @template Seeds - Record of seed functions for complex test scenarios\n *\n * @example\n * ```typescript\n * // Define your database schema\n * interface Database {\n * users: UsersTable;\n * posts: PostsTable;\n * }\n *\n * // Create builders\n * const builders = {\n * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * ...attrs\n * })),\n * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({\n * title: 'Test Post',\n * content: 'Test content',\n * ...attrs\n * }))\n * };\n *\n * // Create factory instance\n * const factory = new KyselyFactory(builders, seeds, db);\n *\n * // Use in tests\n * const user = await factory.insert('user', { name: 'John Doe' });\n * ```\n */\nexport class KyselyFactory<\n DB,\n Builders extends Record<string, any>,\n Seeds extends Record<string, any>,\n> extends Factory<Builders, Seeds> {\n /**\n * Creates a typed seed function with proper type inference.\n * Inherits from the base Factory class implementation.\n *\n * @template Seed - The seed function type\n * @param seedFn - The seed function to wrap\n * @returns The same seed function with proper typing\n */\n static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {\n return Factory.createSeed(seedFn);\n }\n\n /**\n * Creates a new KyselyFactory instance.\n *\n * @param builders - Record of builder functions for creating individual entities\n * @param seeds - Record of seed functions for creating complex test scenarios\n * @param db - Kysely database instance or controlled transaction\n */\n constructor(\n private builders: Builders,\n private seeds: Seeds,\n private db: Kysely<DB> | ControlledTransaction<DB, []>,\n ) {\n super();\n }\n\n /**\n * Creates a typed builder function for a specific database table.\n * This is a utility method that helps create builders with proper type inference for Kysely.\n *\n * @template DB - The database schema type\n * @template TableName - The name of the table (must be a key of DB)\n * @template Attrs - The attributes type for the builder (defaults to Partial<Insertable>)\n * @template Factory - The factory instance type\n * @template Result - The result type (defaults to Selectable of the table)\n *\n * @param table - The name of the database table\n * @param defaults - Optional function to provide default values (receives destructured context)\n * @param autoInsert - Whether to automatically insert the record (default: true)\n * @returns A builder function that creates and optionally inserts records\n *\n * @example\n * ```typescript\n * // Create a simple builder with defaults - destructure only what you need\n * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',\n * ({ attrs, faker }) => ({\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * createdAt: new Date(),\n * ...attrs\n * })\n * );\n *\n * // Only need faker? Just destructure that\n * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',\n * ({ faker }) => ({\n * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),\n * code: faker.string.alpha({ length: 3, casing: 'upper' }),\n * })\n * );\n *\n * // Create a builder that doesn't auto-insert (useful for nested inserts)\n * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',\n * ({ attrs }) => ({\n * street: '123 Main St',\n * city: 'Anytown',\n * ...attrs\n * }),\n * false // Don't auto-insert\n * );\n * ```\n */\n static createBuilder<\n DB,\n TableName extends keyof DB & string,\n Attrs extends Partial<Insertable<DB[TableName]>> = Partial<\n Insertable<DB[TableName]>\n >,\n Factory = any,\n Result = Selectable<DB[TableName]>,\n >(\n table: TableName,\n defaults?: (context: {\n attrs: Attrs;\n factory: Factory;\n db: Kysely<DB>;\n faker: FakerFactory;\n }) =>\n | Partial<Insertable<DB[TableName]>>\n | Promise<Partial<Insertable<DB[TableName]>>>,\n autoInsert?: boolean,\n ): (\n attrs: Attrs,\n factory: Factory,\n db: Kysely<DB>,\n faker: FakerFactory,\n ) => Promise<Result> {\n return async (\n attrs: Attrs,\n factory: Factory,\n db: Kysely<DB>,\n fakerInstance: FakerFactory,\n ) => {\n // Start with attributes\n let data: Partial<Insertable<DB[TableName]>> = { ...attrs };\n\n // Apply defaults\n if (defaults) {\n const defaultValues = await defaults({\n attrs,\n factory,\n db,\n faker: fakerInstance,\n });\n data = { ...defaultValues, ...data };\n }\n\n // Handle insertion based on autoInsert flag\n if (autoInsert !== false) {\n // Auto insert is enabled by default\n const result = await db\n .insertInto(table)\n .values(data as Insertable<DB[TableName]>)\n .returningAll()\n .executeTakeFirst();\n\n if (!result) {\n throw new Error(`Failed to insert into ${table}`);\n }\n\n return result as Result;\n } else {\n // Return object for factory to handle insertion\n return { table, data } as any;\n }\n };\n }\n\n /**\n * Inserts a single record into the database using the specified builder.\n * The builder function is responsible for generating the record data with defaults\n * and the factory handles the actual database insertion.\n *\n * @template K - The builder name (must be a key of Builders)\n * @param builderName - The name of the builder to use\n * @param attrs - Optional attributes to override builder defaults\n * @returns A promise resolving to the inserted record\n * @throws Error if the specified builder doesn't exist\n *\n * @example\n * ```typescript\n * // Insert with defaults\n * const user = await factory.insert('user');\n *\n * // Insert with overrides\n * const adminUser = await factory.insert('user', {\n * email: 'admin@example.com',\n * role: 'admin'\n * });\n *\n * // Use the inserted record\n * const post = await factory.insert('post', {\n * userId: user.id,\n * title: 'My First Post'\n * });\n * ```\n */\n async insert<K extends keyof Builders>(\n builderName: K,\n attrs?: Parameters<Builders[K]>[0],\n ): Promise<Awaited<ReturnType<Builders[K]>>> {\n if (!(builderName in this.builders)) {\n throw new Error(\n `Factory \"${\n builderName as string\n }\" does not exist. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n const result = await this.builders[builderName](\n attrs || {},\n this,\n this.db,\n faker,\n );\n\n // For Kysely, we expect the builder to return an object with table and data properties\n // or to handle the insertion itself and return the inserted record\n if (\n result &&\n typeof result === 'object' &&\n 'table' in result &&\n 'data' in result\n ) {\n // If the builder returns {table: string, data: object}, we insert it\n const inserted = await this.db\n .insertInto(result.table)\n .values(result.data)\n .returningAll()\n .executeTakeFirst();\n\n return inserted as any;\n }\n\n // Otherwise, assume the builder handled the insertion itself\n return result;\n }\n\n /**\n * Inserts multiple records into the database using the specified builder.\n * Supports both static attributes and dynamic attribute generation via a function.\n *\n * @template K - The builder name (must be a key of Builders)\n * @param count - The number of records to insert\n * @param builderName - The name of the builder to use\n * @param attrs - Static attributes or a function that generates attributes for each record\n * @returns A promise resolving to an array of inserted records\n * @throws Error if the specified builder doesn't exist\n *\n * @example\n * ```typescript\n * // Insert multiple with same attributes\n * const users = await factory.insertMany(5, 'user', { role: 'member' });\n *\n * // Insert multiple with dynamic attributes\n * const posts = await factory.insertMany(10, 'post', (idx, faker) => ({\n * title: `Post ${idx + 1}`,\n * content: faker.lorem.paragraph(),\n * publishedAt: faker.date.past()\n * }));\n *\n * // Create users with sequential emails\n * const admins = await factory.insertMany(3, 'user', (idx) => ({\n * email: `admin${idx + 1}@example.com`,\n * role: 'admin'\n * }));\n * ```\n */\n // Method overloads for better type inference\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs?: Parameters<Builders[K]>[0],\n ): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs: (\n idx: number,\n faker: FakerFactory,\n ) => Parameters<Builders[K]>[0] | Promise<Parameters<Builders[K]>[0]>,\n ): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs?: any,\n ): Promise<Awaited<ReturnType<Builders[K]>>[]> {\n if (!(builderName in this.builders)) {\n throw new Error(\n `Builder \"${\n builderName as string\n }\" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n const promises: Promise<any>[] = [];\n\n for (let i = 0; i < count; i++) {\n const newAttrs =\n typeof attrs === 'function' ? await attrs(i, faker) : attrs;\n promises.push(this.insert(builderName, newAttrs));\n }\n\n return Promise.all(promises);\n }\n\n /**\n * Executes a seed function to create complex test scenarios with multiple related records.\n * Seeds are useful for setting up complete test environments with realistic data relationships.\n *\n * @template K - The seed name (must be a key of Seeds)\n * @param seedName - The name of the seed to execute\n * @param attrs - Optional configuration attributes for the seed\n * @returns The result of the seed function (typically the primary record created)\n * @throws Error if the specified seed doesn't exist\n *\n * @example\n * ```typescript\n * // Execute a simple seed\n * const user = await factory.seed('userWithProfile');\n *\n * // Execute a seed with configuration\n * const author = await factory.seed('authorWithBooks', {\n * bookCount: 5,\n * includeReviews: true\n * });\n *\n * // Use seed result in tests\n * const company = await factory.seed('companyWithDepartments', {\n * departmentCount: 3,\n * employeesPerDepartment: 10\n * });\n * expect(company.departments).toHaveLength(3);\n * ```\n */\n seed<K extends keyof Seeds>(\n seedName: K,\n attrs?: Parameters<Seeds[K]>[0],\n ): ReturnType<Seeds[K]> {\n if (!(seedName in this.seeds)) {\n throw new Error(\n `Seed \"${\n seedName as string\n }\" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n return this.seeds[seedName](attrs || {}, this, this.db);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAa,gBAAb,cAIU,QAAyB;;;;;;;;;CASjC,OAAO,WAAqCA,QAAoB;AAC9D,SAAO,QAAQ,WAAW,OAAO;CAClC;;;;;;;;CASD,YACUC,UACAC,OACAC,IACR;AACA,SAAO;EAJC;EACA;EACA;CAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDD,OAAO,cASLC,OACAC,UAQAC,YAMmB;AACnB,SAAO,OACLC,OACAC,SACAC,IACAC,kBACG;GAEH,IAAIC,OAA2C,EAAE,GAAG,MAAO;AAG3D,OAAI,UAAU;IACZ,MAAM,gBAAgB,MAAM,SAAS;KACnC;KACA;KACA;KACA,OAAO;IACR,EAAC;AACF,WAAO;KAAE,GAAG;KAAe,GAAG;IAAM;GACrC;AAGD,OAAI,eAAe,OAAO;IAExB,MAAM,SAAS,MAAM,GAClB,WAAW,MAAM,CACjB,OAAO,KAAkC,CACzC,cAAc,CACd,kBAAkB;AAErB,SAAK,OACH,OAAM,IAAI,OAAO,wBAAwB,MAAM;AAGjD,WAAO;GACR,MAEC,QAAO;IAAE;IAAO;GAAM;EAEzB;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BD,MAAM,OACJC,aACAC,OAC2C;AAC3C,QAAM,eAAe,KAAK,UACxB,OAAM,IAAI,OACP,WACC,YACD;EAIL,MAAM,SAAS,MAAM,KAAK,SAAS,aACjC,SAAS,CAAE,GACX,MACA,KAAK,IACL,MACD;AAID,MACE,iBACO,WAAW,YAClB,WAAW,UACX,UAAU,QACV;GAEA,MAAM,WAAW,MAAM,KAAK,GACzB,WAAW,OAAO,MAAM,CACxB,OAAO,OAAO,KAAK,CACnB,cAAc,CACd,kBAAkB;AAErB,UAAO;EACR;AAGD,SAAO;CACR;CA8CD,MAAM,WACJC,OACAF,aACAG,OAC6C;AAC7C,QAAM,eAAe,KAAK,UACxB,OAAM,IAAI,OACP,WACC,YACD;EAIL,MAAMC,WAA2B,CAAE;AAEnC,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,kBACG,UAAU,aAAa,MAAM,MAAM,GAAG,MAAM,GAAG;AACxD,YAAS,KAAK,KAAK,OAAO,aAAa,SAAS,CAAC;EAClD;AAED,SAAO,QAAQ,IAAI,SAAS;CAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BD,KACEC,UACAC,OACsB;AACtB,QAAM,YAAY,KAAK,OACrB,OAAM,IAAI,OACP,QACC,SACD;AAIL,SAAO,KAAK,MAAM,UAAU,SAAS,CAAE,GAAE,MAAM,KAAK,GAAG;CACxD;AACF"}
@@ -20,13 +20,13 @@ const require_faker = require('./faker-B14IEMIN.cjs');
20
20
  *
21
21
  * // Create builders
22
22
  * const builders = {
23
- * user: KyselyFactory.createBuilder<Database, 'users'>('users', (attrs, factory, db, faker) => ({
23
+ * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({
24
24
  * id: faker.string.uuid(),
25
25
  * name: faker.person.fullName(),
26
26
  * email: faker.internet.email(),
27
27
  * ...attrs
28
28
  * })),
29
- * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', (attrs) => ({
29
+ * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({
30
30
  * title: 'Test Post',
31
31
  * content: 'Test content',
32
32
  * ...attrs
@@ -76,15 +76,15 @@ var KyselyFactory = class extends require_Factory.Factory {
76
76
  * @template Result - The result type (defaults to Selectable of the table)
77
77
  *
78
78
  * @param table - The name of the database table
79
- * @param item - Optional function to provide default values and transformations
79
+ * @param defaults - Optional function to provide default values (receives destructured context)
80
80
  * @param autoInsert - Whether to automatically insert the record (default: true)
81
81
  * @returns A builder function that creates and optionally inserts records
82
82
  *
83
83
  * @example
84
84
  * ```typescript
85
- * // Create a simple builder with defaults
85
+ * // Create a simple builder with defaults - destructure only what you need
86
86
  * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',
87
- * (attrs, factory, db, faker) => ({
87
+ * ({ attrs, faker }) => ({
88
88
  * id: faker.string.uuid(),
89
89
  * name: faker.person.fullName(),
90
90
  * email: faker.internet.email(),
@@ -93,9 +93,17 @@ var KyselyFactory = class extends require_Factory.Factory {
93
93
  * })
94
94
  * );
95
95
  *
96
+ * // Only need faker? Just destructure that
97
+ * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',
98
+ * ({ faker }) => ({
99
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
100
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
101
+ * })
102
+ * );
103
+ *
96
104
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
97
105
  * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',
98
- * (attrs) => ({
106
+ * ({ attrs }) => ({
99
107
  * street: '123 Main St',
100
108
  * city: 'Anytown',
101
109
  * ...attrs
@@ -104,13 +112,18 @@ var KyselyFactory = class extends require_Factory.Factory {
104
112
  * );
105
113
  * ```
106
114
  */
107
- static createBuilder(table, item, autoInsert) {
108
- return async (attrs, factory, db, faker$1) => {
115
+ static createBuilder(table, defaults, autoInsert) {
116
+ return async (attrs, factory, db, fakerInstance) => {
109
117
  let data = { ...attrs };
110
- if (item) {
111
- const defaults = await item(attrs, factory, db, faker$1);
118
+ if (defaults) {
119
+ const defaultValues = await defaults({
120
+ attrs,
121
+ factory,
122
+ db,
123
+ faker: fakerInstance
124
+ });
112
125
  data = {
113
- ...defaults,
126
+ ...defaultValues,
114
127
  ...data
115
128
  };
116
129
  }
@@ -213,4 +226,4 @@ Object.defineProperty(exports, 'KyselyFactory', {
213
226
  return KyselyFactory;
214
227
  }
215
228
  });
216
- //# sourceMappingURL=KyselyFactory-Cf0o2YxO.cjs.map
229
+ //# sourceMappingURL=KyselyFactory-DaaCykWP.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KyselyFactory-DaaCykWP.cjs","names":["Factory","seedFn: Seed","builders: Builders","seeds: Seeds","db: Kysely<DB> | ControlledTransaction<DB, []>","table: TableName","defaults?: (context: {\n attrs: Attrs;\n factory: Factory;\n db: Kysely<DB>;\n faker: FakerFactory;\n }) =>\n | Partial<Insertable<DB[TableName]>>\n | Promise<Partial<Insertable<DB[TableName]>>>","autoInsert?: boolean","attrs: Attrs","factory: Factory","db: Kysely<DB>","fakerInstance: FakerFactory","data: Partial<Insertable<DB[TableName]>>","builderName: K","attrs?: Parameters<Builders[K]>[0]","faker","count: number","attrs?: any","promises: Promise<any>[]","seedName: K","attrs?: Parameters<Seeds[K]>[0]"],"sources":["../src/KyselyFactory.ts"],"sourcesContent":["import type {\n ControlledTransaction,\n Insertable,\n Kysely,\n Selectable,\n} from 'kysely';\nimport { Factory, type FactorySeed } from './Factory.ts';\nimport { type FakerFactory, faker } from './faker.ts';\n\n/**\n * Factory implementation for Kysely ORM, providing test data creation utilities.\n * Extends the base Factory class with Kysely-specific database operations.\n *\n * @template DB - The database schema type\n * @template Builders - Record of builder functions for creating entities\n * @template Seeds - Record of seed functions for complex test scenarios\n *\n * @example\n * ```typescript\n * // Define your database schema\n * interface Database {\n * users: UsersTable;\n * posts: PostsTable;\n * }\n *\n * // Create builders\n * const builders = {\n * user: KyselyFactory.createBuilder<Database, 'users'>('users', ({ attrs, faker }) => ({\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * ...attrs\n * })),\n * post: KyselyFactory.createBuilder<Database, 'posts'>('posts', ({ attrs }) => ({\n * title: 'Test Post',\n * content: 'Test content',\n * ...attrs\n * }))\n * };\n *\n * // Create factory instance\n * const factory = new KyselyFactory(builders, seeds, db);\n *\n * // Use in tests\n * const user = await factory.insert('user', { name: 'John Doe' });\n * ```\n */\nexport class KyselyFactory<\n DB,\n Builders extends Record<string, any>,\n Seeds extends Record<string, any>,\n> extends Factory<Builders, Seeds> {\n /**\n * Creates a typed seed function with proper type inference.\n * Inherits from the base Factory class implementation.\n *\n * @template Seed - The seed function type\n * @param seedFn - The seed function to wrap\n * @returns The same seed function with proper typing\n */\n static createSeed<Seed extends FactorySeed>(seedFn: Seed): Seed {\n return Factory.createSeed(seedFn);\n }\n\n /**\n * Creates a new KyselyFactory instance.\n *\n * @param builders - Record of builder functions for creating individual entities\n * @param seeds - Record of seed functions for creating complex test scenarios\n * @param db - Kysely database instance or controlled transaction\n */\n constructor(\n private builders: Builders,\n private seeds: Seeds,\n private db: Kysely<DB> | ControlledTransaction<DB, []>,\n ) {\n super();\n }\n\n /**\n * Creates a typed builder function for a specific database table.\n * This is a utility method that helps create builders with proper type inference for Kysely.\n *\n * @template DB - The database schema type\n * @template TableName - The name of the table (must be a key of DB)\n * @template Attrs - The attributes type for the builder (defaults to Partial<Insertable>)\n * @template Factory - The factory instance type\n * @template Result - The result type (defaults to Selectable of the table)\n *\n * @param table - The name of the database table\n * @param defaults - Optional function to provide default values (receives destructured context)\n * @param autoInsert - Whether to automatically insert the record (default: true)\n * @returns A builder function that creates and optionally inserts records\n *\n * @example\n * ```typescript\n * // Create a simple builder with defaults - destructure only what you need\n * const userBuilder = KyselyFactory.createBuilder<DB, 'users'>('users',\n * ({ attrs, faker }) => ({\n * id: faker.string.uuid(),\n * name: faker.person.fullName(),\n * email: faker.internet.email(),\n * createdAt: new Date(),\n * ...attrs\n * })\n * );\n *\n * // Only need faker? Just destructure that\n * const leaveTypeBuilder = KyselyFactory.createBuilder<DB, 'leaveTypes'>('leaveTypes',\n * ({ faker }) => ({\n * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),\n * code: faker.string.alpha({ length: 3, casing: 'upper' }),\n * })\n * );\n *\n * // Create a builder that doesn't auto-insert (useful for nested inserts)\n * const addressBuilder = KyselyFactory.createBuilder<DB, 'addresses'>('addresses',\n * ({ attrs }) => ({\n * street: '123 Main St',\n * city: 'Anytown',\n * ...attrs\n * }),\n * false // Don't auto-insert\n * );\n * ```\n */\n static createBuilder<\n DB,\n TableName extends keyof DB & string,\n Attrs extends Partial<Insertable<DB[TableName]>> = Partial<\n Insertable<DB[TableName]>\n >,\n Factory = any,\n Result = Selectable<DB[TableName]>,\n >(\n table: TableName,\n defaults?: (context: {\n attrs: Attrs;\n factory: Factory;\n db: Kysely<DB>;\n faker: FakerFactory;\n }) =>\n | Partial<Insertable<DB[TableName]>>\n | Promise<Partial<Insertable<DB[TableName]>>>,\n autoInsert?: boolean,\n ): (\n attrs: Attrs,\n factory: Factory,\n db: Kysely<DB>,\n faker: FakerFactory,\n ) => Promise<Result> {\n return async (\n attrs: Attrs,\n factory: Factory,\n db: Kysely<DB>,\n fakerInstance: FakerFactory,\n ) => {\n // Start with attributes\n let data: Partial<Insertable<DB[TableName]>> = { ...attrs };\n\n // Apply defaults\n if (defaults) {\n const defaultValues = await defaults({\n attrs,\n factory,\n db,\n faker: fakerInstance,\n });\n data = { ...defaultValues, ...data };\n }\n\n // Handle insertion based on autoInsert flag\n if (autoInsert !== false) {\n // Auto insert is enabled by default\n const result = await db\n .insertInto(table)\n .values(data as Insertable<DB[TableName]>)\n .returningAll()\n .executeTakeFirst();\n\n if (!result) {\n throw new Error(`Failed to insert into ${table}`);\n }\n\n return result as Result;\n } else {\n // Return object for factory to handle insertion\n return { table, data } as any;\n }\n };\n }\n\n /**\n * Inserts a single record into the database using the specified builder.\n * The builder function is responsible for generating the record data with defaults\n * and the factory handles the actual database insertion.\n *\n * @template K - The builder name (must be a key of Builders)\n * @param builderName - The name of the builder to use\n * @param attrs - Optional attributes to override builder defaults\n * @returns A promise resolving to the inserted record\n * @throws Error if the specified builder doesn't exist\n *\n * @example\n * ```typescript\n * // Insert with defaults\n * const user = await factory.insert('user');\n *\n * // Insert with overrides\n * const adminUser = await factory.insert('user', {\n * email: 'admin@example.com',\n * role: 'admin'\n * });\n *\n * // Use the inserted record\n * const post = await factory.insert('post', {\n * userId: user.id,\n * title: 'My First Post'\n * });\n * ```\n */\n async insert<K extends keyof Builders>(\n builderName: K,\n attrs?: Parameters<Builders[K]>[0],\n ): Promise<Awaited<ReturnType<Builders[K]>>> {\n if (!(builderName in this.builders)) {\n throw new Error(\n `Factory \"${\n builderName as string\n }\" does not exist. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n const result = await this.builders[builderName](\n attrs || {},\n this,\n this.db,\n faker,\n );\n\n // For Kysely, we expect the builder to return an object with table and data properties\n // or to handle the insertion itself and return the inserted record\n if (\n result &&\n typeof result === 'object' &&\n 'table' in result &&\n 'data' in result\n ) {\n // If the builder returns {table: string, data: object}, we insert it\n const inserted = await this.db\n .insertInto(result.table)\n .values(result.data)\n .returningAll()\n .executeTakeFirst();\n\n return inserted as any;\n }\n\n // Otherwise, assume the builder handled the insertion itself\n return result;\n }\n\n /**\n * Inserts multiple records into the database using the specified builder.\n * Supports both static attributes and dynamic attribute generation via a function.\n *\n * @template K - The builder name (must be a key of Builders)\n * @param count - The number of records to insert\n * @param builderName - The name of the builder to use\n * @param attrs - Static attributes or a function that generates attributes for each record\n * @returns A promise resolving to an array of inserted records\n * @throws Error if the specified builder doesn't exist\n *\n * @example\n * ```typescript\n * // Insert multiple with same attributes\n * const users = await factory.insertMany(5, 'user', { role: 'member' });\n *\n * // Insert multiple with dynamic attributes\n * const posts = await factory.insertMany(10, 'post', (idx, faker) => ({\n * title: `Post ${idx + 1}`,\n * content: faker.lorem.paragraph(),\n * publishedAt: faker.date.past()\n * }));\n *\n * // Create users with sequential emails\n * const admins = await factory.insertMany(3, 'user', (idx) => ({\n * email: `admin${idx + 1}@example.com`,\n * role: 'admin'\n * }));\n * ```\n */\n // Method overloads for better type inference\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs?: Parameters<Builders[K]>[0],\n ): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs: (\n idx: number,\n faker: FakerFactory,\n ) => Parameters<Builders[K]>[0] | Promise<Parameters<Builders[K]>[0]>,\n ): Promise<Awaited<ReturnType<Builders[K]>>[]>;\n async insertMany<K extends keyof Builders>(\n count: number,\n builderName: K,\n attrs?: any,\n ): Promise<Awaited<ReturnType<Builders[K]>>[]> {\n if (!(builderName in this.builders)) {\n throw new Error(\n `Builder \"${\n builderName as string\n }\" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n const promises: Promise<any>[] = [];\n\n for (let i = 0; i < count; i++) {\n const newAttrs =\n typeof attrs === 'function' ? await attrs(i, faker) : attrs;\n promises.push(this.insert(builderName, newAttrs));\n }\n\n return Promise.all(promises);\n }\n\n /**\n * Executes a seed function to create complex test scenarios with multiple related records.\n * Seeds are useful for setting up complete test environments with realistic data relationships.\n *\n * @template K - The seed name (must be a key of Seeds)\n * @param seedName - The name of the seed to execute\n * @param attrs - Optional configuration attributes for the seed\n * @returns The result of the seed function (typically the primary record created)\n * @throws Error if the specified seed doesn't exist\n *\n * @example\n * ```typescript\n * // Execute a simple seed\n * const user = await factory.seed('userWithProfile');\n *\n * // Execute a seed with configuration\n * const author = await factory.seed('authorWithBooks', {\n * bookCount: 5,\n * includeReviews: true\n * });\n *\n * // Use seed result in tests\n * const company = await factory.seed('companyWithDepartments', {\n * departmentCount: 3,\n * employeesPerDepartment: 10\n * });\n * expect(company.departments).toHaveLength(3);\n * ```\n */\n seed<K extends keyof Seeds>(\n seedName: K,\n attrs?: Parameters<Seeds[K]>[0],\n ): ReturnType<Seeds[K]> {\n if (!(seedName in this.seeds)) {\n throw new Error(\n `Seed \"${\n seedName as string\n }\" is not registered in this factory. Make sure it is correct and registered in src/test/setup.ts`,\n );\n }\n\n return this.seeds[seedName](attrs || {}, this, this.db);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAa,gBAAb,cAIUA,wBAAyB;;;;;;;;;CASjC,OAAO,WAAqCC,QAAoB;AAC9D,SAAO,wBAAQ,WAAW,OAAO;CAClC;;;;;;;;CASD,YACUC,UACAC,OACAC,IACR;AACA,SAAO;EAJC;EACA;EACA;CAGT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDD,OAAO,cASLC,OACAC,UAQAC,YAMmB;AACnB,SAAO,OACLC,OACAC,SACAC,IACAC,kBACG;GAEH,IAAIC,OAA2C,EAAE,GAAG,MAAO;AAG3D,OAAI,UAAU;IACZ,MAAM,gBAAgB,MAAM,SAAS;KACnC;KACA;KACA;KACA,OAAO;IACR,EAAC;AACF,WAAO;KAAE,GAAG;KAAe,GAAG;IAAM;GACrC;AAGD,OAAI,eAAe,OAAO;IAExB,MAAM,SAAS,MAAM,GAClB,WAAW,MAAM,CACjB,OAAO,KAAkC,CACzC,cAAc,CACd,kBAAkB;AAErB,SAAK,OACH,OAAM,IAAI,OAAO,wBAAwB,MAAM;AAGjD,WAAO;GACR,MAEC,QAAO;IAAE;IAAO;GAAM;EAEzB;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BD,MAAM,OACJC,aACAC,OAC2C;AAC3C,QAAM,eAAe,KAAK,UACxB,OAAM,IAAI,OACP,WACC,YACD;EAIL,MAAM,SAAS,MAAM,KAAK,SAAS,aACjC,SAAS,CAAE,GACX,MACA,KAAK,IACLC,oBACD;AAID,MACE,iBACO,WAAW,YAClB,WAAW,UACX,UAAU,QACV;GAEA,MAAM,WAAW,MAAM,KAAK,GACzB,WAAW,OAAO,MAAM,CACxB,OAAO,OAAO,KAAK,CACnB,cAAc,CACd,kBAAkB;AAErB,UAAO;EACR;AAGD,SAAO;CACR;CA8CD,MAAM,WACJC,OACAH,aACAI,OAC6C;AAC7C,QAAM,eAAe,KAAK,UACxB,OAAM,IAAI,OACP,WACC,YACD;EAIL,MAAMC,WAA2B,CAAE;AAEnC,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;GAC9B,MAAM,kBACG,UAAU,aAAa,MAAM,MAAM,GAAGH,oBAAM,GAAG;AACxD,YAAS,KAAK,KAAK,OAAO,aAAa,SAAS,CAAC;EAClD;AAED,SAAO,QAAQ,IAAI,SAAS;CAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BD,KACEI,UACAC,OACsB;AACtB,QAAM,YAAY,KAAK,OACrB,OAAM,IAAI,OACP,QACC,SACD;AAIL,SAAO,KAAK,MAAM,UAAU,SAAS,CAAE,GAAE,MAAM,KAAK,GAAG;CACxD;AACF"}
@@ -1,5 +1,5 @@
1
1
  require('./Factory-WMhTNZ9S.cjs');
2
2
  require('./faker-B14IEMIN.cjs');
3
- const require_KyselyFactory = require('./KyselyFactory-Cf0o2YxO.cjs');
3
+ const require_KyselyFactory = require('./KyselyFactory-DaaCykWP.cjs');
4
4
 
5
5
  exports.KyselyFactory = require_KyselyFactory.KyselyFactory;
@@ -1,4 +1,4 @@
1
1
  import "./faker-Cg76aFNO.cjs";
2
2
  import "./Factory-BZ8uMoXl.cjs";
3
- import { KyselyFactory } from "./KyselyFactory-DRQ83r0o.cjs";
3
+ import { KyselyFactory } from "./KyselyFactory-BFygzOlO.cjs";
4
4
  export { KyselyFactory };
@@ -1,4 +1,4 @@
1
- import "./faker-Br8MzXil.mjs";
2
- import "./Factory-CRquB4vz.mjs";
3
- import { KyselyFactory } from "./KyselyFactory-BDS_QqRT.mjs";
1
+ import "./faker-DHh7xs4u.mjs";
2
+ import "./Factory-Cmr3s3-s.mjs";
3
+ import { KyselyFactory } from "./KyselyFactory-BTdygZ-i.mjs";
4
4
  export { KyselyFactory };
@@ -1,5 +1,5 @@
1
1
  import "./Factory-z2m01hMj.mjs";
2
2
  import "./faker-BGKYFoCT.mjs";
3
- import { KyselyFactory } from "./KyselyFactory-BcYkC0t2.mjs";
3
+ import { KyselyFactory } from "./KyselyFactory-CXY5gJk2.mjs";
4
4
 
5
5
  export { KyselyFactory };
@@ -1,5 +1,5 @@
1
- import { FakerFactory } from "./faker-Br8MzXil.mjs";
2
- import { Factory, FactorySeed } from "./Factory-CRquB4vz.mjs";
1
+ import { FakerFactory } from "./faker-DHh7xs4u.mjs";
2
+ import { Factory, FactorySeed } from "./Factory-Cmr3s3-s.mjs";
3
3
  import { Knex } from "knex";
4
4
  import { Model } from "objection";
5
5
 
@@ -21,17 +21,17 @@ import { Model } from "objection";
21
21
  *
22
22
  * // Create builders
23
23
  * const builders = {
24
- * user: (attrs) => User.fromJson({
24
+ * user: ObjectionFactory.createBuilder(User, ({ attrs, faker }) => ({
25
25
  * id: faker.string.uuid(),
26
26
  * name: faker.person.fullName(),
27
27
  * email: faker.internet.email(),
28
28
  * ...attrs
29
- * }),
30
- * post: (attrs) => Post.fromJson({
29
+ * })),
30
+ * post: ObjectionFactory.createBuilder(Post, ({ attrs }) => ({
31
31
  * title: 'Test Post',
32
32
  * content: 'Test content',
33
33
  * ...attrs
34
- * })
34
+ * })),
35
35
  * };
36
36
  *
37
37
  * // Create factory instance
@@ -64,15 +64,15 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
64
64
  * @template Result - The result type (defaults to the model instance)
65
65
  *
66
66
  * @param ModelClass - The Objection.js Model class
67
- * @param item - Optional function to provide default values and transformations
67
+ * @param defaults - Optional function to provide default values (receives destructured context)
68
68
  * @param autoInsert - Whether to automatically insert the record (default: true)
69
69
  * @returns A builder function that creates and optionally inserts records
70
70
  *
71
71
  * @example
72
72
  * ```typescript
73
- * // Create a simple builder with defaults
73
+ * // Create a simple builder with defaults - destructure only what you need
74
74
  * const userBuilder = ObjectionFactory.createBuilder(User,
75
- * (attrs, factory, db, faker) => ({
75
+ * ({ attrs, faker }) => ({
76
76
  * id: faker.string.uuid(),
77
77
  * name: faker.person.fullName(),
78
78
  * email: faker.internet.email(),
@@ -81,9 +81,17 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
81
81
  * })
82
82
  * );
83
83
  *
84
+ * // Only need faker? Just destructure that
85
+ * const leaveTypeBuilder = ObjectionFactory.createBuilder(LeaveType,
86
+ * ({ faker }) => ({
87
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
88
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
89
+ * })
90
+ * );
91
+ *
84
92
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
85
93
  * const addressBuilder = ObjectionFactory.createBuilder(Address,
86
- * (attrs) => ({
94
+ * ({ attrs }) => ({
87
95
  * street: '123 Main St',
88
96
  * city: 'Anytown',
89
97
  * ...attrs
@@ -93,7 +101,7 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
93
101
  *
94
102
  * // Use with relations
95
103
  * const postBuilder = ObjectionFactory.createBuilder(Post,
96
- * async (attrs, factory) => ({
104
+ * async ({ attrs, factory, faker }) => ({
97
105
  * title: faker.lorem.sentence(),
98
106
  * content: faker.lorem.paragraphs(),
99
107
  * authorId: attrs.authorId || (await factory.insert('user')).id,
@@ -102,7 +110,12 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
102
110
  * );
103
111
  * ```
104
112
  */
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>;
113
+ static createBuilder<TModel extends typeof Model, Attrs extends Partial<InstanceType<TModel>> = Partial<InstanceType<TModel>>, Factory = any, Result = InstanceType<TModel>>(ModelClass: TModel, defaults?: (context: {
114
+ attrs: Attrs;
115
+ factory: Factory;
116
+ db: Knex;
117
+ faker: FakerFactory;
118
+ }) => Partial<InstanceType<TModel>> | Promise<Partial<InstanceType<TModel>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Promise<Result>;
106
119
  /**
107
120
  * Creates a new ObjectionFactory instance.
108
121
  *
@@ -211,4 +224,4 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
211
224
  }
212
225
  //#endregion
213
226
  export { ObjectionFactory };
214
- //# sourceMappingURL=ObjectionFactory-C3tHvX1d.d.mts.map
227
+ //# sourceMappingURL=ObjectionFactory-BagGjikT.d.mts.map
@@ -21,17 +21,17 @@ import { Model } from "objection";
21
21
  *
22
22
  * // Create builders
23
23
  * const builders = {
24
- * user: (attrs) => User.fromJson({
24
+ * user: ObjectionFactory.createBuilder(User, ({ attrs, faker }) => ({
25
25
  * id: faker.string.uuid(),
26
26
  * name: faker.person.fullName(),
27
27
  * email: faker.internet.email(),
28
28
  * ...attrs
29
- * }),
30
- * post: (attrs) => Post.fromJson({
29
+ * })),
30
+ * post: ObjectionFactory.createBuilder(Post, ({ attrs }) => ({
31
31
  * title: 'Test Post',
32
32
  * content: 'Test content',
33
33
  * ...attrs
34
- * })
34
+ * })),
35
35
  * };
36
36
  *
37
37
  * // Create factory instance
@@ -64,15 +64,15 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
64
64
  * @template Result - The result type (defaults to the model instance)
65
65
  *
66
66
  * @param ModelClass - The Objection.js Model class
67
- * @param item - Optional function to provide default values and transformations
67
+ * @param defaults - Optional function to provide default values (receives destructured context)
68
68
  * @param autoInsert - Whether to automatically insert the record (default: true)
69
69
  * @returns A builder function that creates and optionally inserts records
70
70
  *
71
71
  * @example
72
72
  * ```typescript
73
- * // Create a simple builder with defaults
73
+ * // Create a simple builder with defaults - destructure only what you need
74
74
  * const userBuilder = ObjectionFactory.createBuilder(User,
75
- * (attrs, factory, db, faker) => ({
75
+ * ({ attrs, faker }) => ({
76
76
  * id: faker.string.uuid(),
77
77
  * name: faker.person.fullName(),
78
78
  * email: faker.internet.email(),
@@ -81,9 +81,17 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
81
81
  * })
82
82
  * );
83
83
  *
84
+ * // Only need faker? Just destructure that
85
+ * const leaveTypeBuilder = ObjectionFactory.createBuilder(LeaveType,
86
+ * ({ faker }) => ({
87
+ * name: faker.helpers.arrayElement(['Annual', 'Sick', 'Maternity']),
88
+ * code: faker.string.alpha({ length: 3, casing: 'upper' }),
89
+ * })
90
+ * );
91
+ *
84
92
  * // Create a builder that doesn't auto-insert (useful for nested inserts)
85
93
  * const addressBuilder = ObjectionFactory.createBuilder(Address,
86
- * (attrs) => ({
94
+ * ({ attrs }) => ({
87
95
  * street: '123 Main St',
88
96
  * city: 'Anytown',
89
97
  * ...attrs
@@ -93,7 +101,7 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
93
101
  *
94
102
  * // Use with relations
95
103
  * const postBuilder = ObjectionFactory.createBuilder(Post,
96
- * async (attrs, factory) => ({
104
+ * async ({ attrs, factory, faker }) => ({
97
105
  * title: faker.lorem.sentence(),
98
106
  * content: faker.lorem.paragraphs(),
99
107
  * authorId: attrs.authorId || (await factory.insert('user')).id,
@@ -102,7 +110,12 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
102
110
  * );
103
111
  * ```
104
112
  */
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>;
113
+ static createBuilder<TModel extends typeof Model, Attrs extends Partial<InstanceType<TModel>> = Partial<InstanceType<TModel>>, Factory = any, Result = InstanceType<TModel>>(ModelClass: TModel, defaults?: (context: {
114
+ attrs: Attrs;
115
+ factory: Factory;
116
+ db: Knex;
117
+ faker: FakerFactory;
118
+ }) => Partial<InstanceType<TModel>> | Promise<Partial<InstanceType<TModel>>>, autoInsert?: boolean): (attrs: Attrs, factory: Factory, db: Knex, faker: FakerFactory) => Promise<Result>;
106
119
  /**
107
120
  * Creates a new ObjectionFactory instance.
108
121
  *
@@ -211,4 +224,4 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
211
224
  }
212
225
  //#endregion
213
226
  export { ObjectionFactory };
214
- //# sourceMappingURL=ObjectionFactory-C4X78k0B.d.cts.map
227
+ //# sourceMappingURL=ObjectionFactory-CeSIN3kZ.d.cts.map