@geekmidas/testkit 0.4.0 → 0.6.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 (209) hide show
  1. package/dist/Factory-BFVnMMCC.mjs.map +1 -1
  2. package/dist/Factory-BhjUOBWN.cjs.map +1 -1
  3. package/dist/{Factory-c16c27Y6.d.cts → Factory-Bx0AJXZB.d.cts} +3 -2
  4. package/dist/Factory-Bx0AJXZB.d.cts.map +1 -0
  5. package/dist/{Factory-BcGJjLc8.d.mts → Factory-SFupxRC2.d.mts} +2 -1
  6. package/dist/Factory-SFupxRC2.d.mts.map +1 -0
  7. package/dist/Factory.d.cts +2 -2
  8. package/dist/Factory.d.mts +1 -1
  9. package/dist/KyselyFactory-BFqVIn_0.cjs.map +1 -1
  10. package/dist/KyselyFactory-DMswpwji.mjs.map +1 -1
  11. package/dist/{KyselyFactory-uZ45h7YU.d.cts → KyselyFactory-KLeKH43i.d.cts} +4 -3
  12. package/dist/KyselyFactory-KLeKH43i.d.cts.map +1 -0
  13. package/dist/{KyselyFactory-Cj-EultY.d.mts → KyselyFactory-vAxYodck.d.mts} +3 -2
  14. package/dist/KyselyFactory-vAxYodck.d.mts.map +1 -0
  15. package/dist/KyselyFactory.d.cts +3 -3
  16. package/dist/KyselyFactory.d.mts +2 -2
  17. package/dist/{ObjectionFactory-DL4qkuF1.d.mts → ObjectionFactory-BWjB49-i.d.mts} +3 -2
  18. package/dist/ObjectionFactory-BWjB49-i.d.mts.map +1 -0
  19. package/dist/ObjectionFactory-BeFBYcan.cjs.map +1 -1
  20. package/dist/ObjectionFactory-QCJ7u0Ql.mjs.map +1 -1
  21. package/dist/{ObjectionFactory-CdhzKs4f.d.cts → ObjectionFactory-aMGvAKt9.d.cts} +4 -3
  22. package/dist/ObjectionFactory-aMGvAKt9.d.cts.map +1 -0
  23. package/dist/ObjectionFactory.d.cts +3 -3
  24. package/dist/ObjectionFactory.d.mts +2 -2
  25. package/dist/{PostgresKyselyMigrator-upT-hmrz.mjs → PostgresKyselyMigrator-6sE1KOni.mjs} +2 -2
  26. package/dist/PostgresKyselyMigrator-6sE1KOni.mjs.map +1 -0
  27. package/dist/{PostgresKyselyMigrator-CIx3AFSR.d.mts → PostgresKyselyMigrator-CBltSOq5.d.cts} +3 -2
  28. package/dist/PostgresKyselyMigrator-CBltSOq5.d.cts.map +1 -0
  29. package/dist/{PostgresKyselyMigrator-CfytARcA.cjs → PostgresKyselyMigrator-D6IbPq8t.cjs} +2 -2
  30. package/dist/PostgresKyselyMigrator-D6IbPq8t.cjs.map +1 -0
  31. package/dist/{PostgresKyselyMigrator-CQ3aUoy_.d.cts → PostgresKyselyMigrator-DrVWncqd.d.mts} +3 -2
  32. package/dist/PostgresKyselyMigrator-DrVWncqd.d.mts.map +1 -0
  33. package/dist/PostgresKyselyMigrator.cjs +2 -2
  34. package/dist/PostgresKyselyMigrator.d.cts +2 -2
  35. package/dist/PostgresKyselyMigrator.d.mts +2 -2
  36. package/dist/PostgresKyselyMigrator.mjs +2 -2
  37. package/dist/{PostgresMigrator-DbuJGAVy.mjs → PostgresMigrator-BjjenqSd.mjs} +2 -2
  38. package/dist/PostgresMigrator-BjjenqSd.mjs.map +1 -0
  39. package/dist/{PostgresMigrator-D5UkK1_K.d.cts → PostgresMigrator-Bres0U6E.d.cts} +2 -1
  40. package/dist/PostgresMigrator-Bres0U6E.d.cts.map +1 -0
  41. package/dist/{PostgresMigrator-DFcNdCvD.cjs → PostgresMigrator-D6dQn0x2.cjs} +2 -2
  42. package/dist/PostgresMigrator-D6dQn0x2.cjs.map +1 -0
  43. package/dist/{PostgresMigrator-DQaRxoaY.d.mts → PostgresMigrator-S-YYosAC.d.mts} +2 -1
  44. package/dist/PostgresMigrator-S-YYosAC.d.mts.map +1 -0
  45. package/dist/PostgresMigrator.cjs +1 -1
  46. package/dist/PostgresMigrator.d.cts +1 -1
  47. package/dist/PostgresMigrator.d.mts +1 -1
  48. package/dist/PostgresMigrator.mjs +1 -1
  49. package/dist/{PostgresObjectionMigrator-CZHHcCOv.d.cts → PostgresObjectionMigrator-CPfBAP7r.d.cts} +3 -2
  50. package/dist/PostgresObjectionMigrator-CPfBAP7r.d.cts.map +1 -0
  51. package/dist/{PostgresObjectionMigrator-BG6ymgnt.cjs → PostgresObjectionMigrator-DK8ODIHQ.cjs} +2 -2
  52. package/dist/PostgresObjectionMigrator-DK8ODIHQ.cjs.map +1 -0
  53. package/dist/{PostgresObjectionMigrator-D_hCcrQu.d.mts → PostgresObjectionMigrator-DVEqB5tp.d.mts} +3 -2
  54. package/dist/PostgresObjectionMigrator-DVEqB5tp.d.mts.map +1 -0
  55. package/dist/{PostgresObjectionMigrator-DPj2pOpX.mjs → PostgresObjectionMigrator-D_QxXbIN.mjs} +2 -2
  56. package/dist/PostgresObjectionMigrator-D_QxXbIN.mjs.map +1 -0
  57. package/dist/PostgresObjectionMigrator.cjs +2 -2
  58. package/dist/PostgresObjectionMigrator.d.cts +2 -2
  59. package/dist/PostgresObjectionMigrator.d.mts +2 -2
  60. package/dist/PostgresObjectionMigrator.mjs +2 -2
  61. package/dist/{VitestKyselyTransactionIsolator-D3EZZhjZ.d.cts → VitestKyselyTransactionIsolator-CduJlHoT.d.cts} +4 -3
  62. package/dist/VitestKyselyTransactionIsolator-CduJlHoT.d.cts.map +1 -0
  63. package/dist/{VitestKyselyTransactionIsolator-Dxlp1u0f.d.mts → VitestKyselyTransactionIsolator-Cswnnj0k.d.mts} +4 -3
  64. package/dist/VitestKyselyTransactionIsolator-Cswnnj0k.d.mts.map +1 -0
  65. package/dist/{VitestKyselyTransactionIsolator-EvDLk5zg.cjs → VitestKyselyTransactionIsolator-D7RRXOBa.cjs} +2 -2
  66. package/dist/VitestKyselyTransactionIsolator-D7RRXOBa.cjs.map +1 -0
  67. package/dist/{VitestKyselyTransactionIsolator-CNURW8y6.mjs → VitestKyselyTransactionIsolator-DceyIqr4.mjs} +2 -2
  68. package/dist/VitestKyselyTransactionIsolator-DceyIqr4.mjs.map +1 -0
  69. package/dist/VitestKyselyTransactionIsolator.cjs +1 -1
  70. package/dist/VitestKyselyTransactionIsolator.d.cts +2 -2
  71. package/dist/VitestKyselyTransactionIsolator.d.mts +2 -2
  72. package/dist/VitestKyselyTransactionIsolator.mjs +1 -1
  73. package/dist/{VitestObjectionTransactionIsolator-1TpsPqfG.d.cts → VitestObjectionTransactionIsolator-BXoR6xdG.d.cts} +4 -3
  74. package/dist/VitestObjectionTransactionIsolator-BXoR6xdG.d.cts.map +1 -0
  75. package/dist/{VitestObjectionTransactionIsolator-CM5KTAFA.cjs → VitestObjectionTransactionIsolator-CdLRrzNf.cjs} +2 -2
  76. package/dist/VitestObjectionTransactionIsolator-CdLRrzNf.cjs.map +1 -0
  77. package/dist/{VitestObjectionTransactionIsolator-jQFaCz0u.mjs → VitestObjectionTransactionIsolator-OF2osYY5.mjs} +2 -2
  78. package/dist/VitestObjectionTransactionIsolator-OF2osYY5.mjs.map +1 -0
  79. package/dist/{VitestObjectionTransactionIsolator-i9jIgU8Q.d.mts → VitestObjectionTransactionIsolator-x6hY5j4u.d.mts} +4 -3
  80. package/dist/VitestObjectionTransactionIsolator-x6hY5j4u.d.mts.map +1 -0
  81. package/dist/VitestObjectionTransactionIsolator.cjs +1 -1
  82. package/dist/VitestObjectionTransactionIsolator.d.cts +2 -2
  83. package/dist/VitestObjectionTransactionIsolator.d.mts +2 -2
  84. package/dist/VitestObjectionTransactionIsolator.mjs +1 -1
  85. package/dist/{VitestTransactionIsolator-BvR19bYn.d.mts → VitestTransactionIsolator-BNWJqh9f.d.mts} +3 -2
  86. package/dist/VitestTransactionIsolator-BNWJqh9f.d.mts.map +1 -0
  87. package/dist/VitestTransactionIsolator-CMfJXZP8.cjs.map +1 -1
  88. package/dist/{VitestTransactionIsolator-CwQaxZLP.d.cts → VitestTransactionIsolator-CSroc7Df.d.cts} +3 -2
  89. package/dist/VitestTransactionIsolator-CSroc7Df.d.cts.map +1 -0
  90. package/dist/VitestTransactionIsolator-DQ7tLqgV.mjs.map +1 -1
  91. package/dist/VitestTransactionIsolator.d.cts +1 -1
  92. package/dist/VitestTransactionIsolator.d.mts +1 -1
  93. package/dist/aws.cjs.map +1 -1
  94. package/dist/aws.d.cts +2 -0
  95. package/dist/aws.d.cts.map +1 -0
  96. package/dist/aws.d.mts +2 -0
  97. package/dist/aws.d.mts.map +1 -0
  98. package/dist/aws.mjs.map +1 -1
  99. package/dist/benchmark.cjs.map +1 -1
  100. package/dist/benchmark.d.cts +1 -0
  101. package/dist/benchmark.d.cts.map +1 -0
  102. package/dist/benchmark.d.mts +1 -0
  103. package/dist/benchmark.d.mts.map +1 -0
  104. package/dist/benchmark.mjs.map +1 -1
  105. package/dist/better-auth.cjs +29 -30
  106. package/dist/better-auth.cjs.map +1 -1
  107. package/dist/better-auth.d.cts +2 -2
  108. package/dist/better-auth.d.cts.map +1 -0
  109. package/dist/better-auth.d.mts.map +1 -0
  110. package/dist/better-auth.mjs +29 -30
  111. package/dist/better-auth.mjs.map +1 -1
  112. package/dist/directory-B-Ozljzk.mjs.map +1 -1
  113. package/dist/directory-BVC8g7cX.cjs.map +1 -1
  114. package/dist/{directory-BXavAeJZ.d.mts → directory-CVrfTq1I.d.mts} +2 -1
  115. package/dist/directory-CVrfTq1I.d.mts.map +1 -0
  116. package/dist/directory-Cys9g76X.d.cts +13 -0
  117. package/dist/directory-Cys9g76X.d.cts.map +1 -0
  118. package/dist/faker-B14IEMIN.cjs.map +1 -1
  119. package/dist/faker-BGKYFoCT.mjs.map +1 -1
  120. package/dist/{faker-DvxiCtxc.d.cts → faker-BSH1EMtg.d.cts} +3 -3
  121. package/dist/faker-BSH1EMtg.d.cts.map +1 -0
  122. package/dist/faker-DHh7xs4u.d.mts.map +1 -0
  123. package/dist/faker.d.cts +1 -1
  124. package/dist/helpers.cjs.map +1 -1
  125. package/dist/helpers.d.cts +1 -0
  126. package/dist/helpers.d.cts.map +1 -0
  127. package/dist/helpers.d.mts +1 -0
  128. package/dist/helpers.d.mts.map +1 -0
  129. package/dist/helpers.mjs.map +1 -1
  130. package/dist/kysely.cjs +3 -3
  131. package/dist/kysely.cjs.map +1 -1
  132. package/dist/kysely.d.cts +8 -7
  133. package/dist/kysely.d.cts.map +1 -0
  134. package/dist/kysely.d.mts +7 -6
  135. package/dist/kysely.d.mts.map +1 -0
  136. package/dist/kysely.mjs +3 -3
  137. package/dist/kysely.mjs.map +1 -1
  138. package/dist/logger.cjs.map +1 -1
  139. package/dist/logger.d.cts +1 -0
  140. package/dist/logger.d.cts.map +1 -0
  141. package/dist/logger.d.mts +1 -0
  142. package/dist/logger.d.mts.map +1 -0
  143. package/dist/logger.mjs.map +1 -1
  144. package/dist/objection.cjs +3 -3
  145. package/dist/objection.cjs.map +1 -1
  146. package/dist/objection.d.cts +8 -7
  147. package/dist/objection.d.cts.map +1 -0
  148. package/dist/objection.d.mts +7 -6
  149. package/dist/objection.d.mts.map +1 -0
  150. package/dist/objection.mjs +3 -3
  151. package/dist/objection.mjs.map +1 -1
  152. package/dist/os/directory.d.cts +1 -1
  153. package/dist/os/directory.d.mts +1 -1
  154. package/dist/os/index.d.cts +1 -1
  155. package/dist/os/index.d.mts +1 -1
  156. package/dist/timer.cjs.map +1 -1
  157. package/dist/timer.d.cts +2 -0
  158. package/dist/timer.d.cts.map +1 -0
  159. package/dist/timer.d.mts +2 -0
  160. package/dist/timer.d.mts.map +1 -0
  161. package/dist/timer.mjs.map +1 -1
  162. package/package.json +5 -5
  163. package/src/Factory.ts +72 -72
  164. package/src/KyselyFactory.ts +330 -330
  165. package/src/ObjectionFactory.ts +354 -355
  166. package/src/PostgresKyselyMigrator.ts +37 -37
  167. package/src/PostgresMigrator.ts +107 -107
  168. package/src/PostgresObjectionMigrator.ts +91 -91
  169. package/src/VitestKyselyTransactionIsolator.ts +27 -27
  170. package/src/VitestObjectionTransactionIsolator.ts +39 -39
  171. package/src/VitestTransactionIsolator.ts +196 -195
  172. package/src/__tests__/Factory.spec.ts +163 -155
  173. package/src/__tests__/KyselyFactory.spec.ts +443 -439
  174. package/src/__tests__/ObjectionFactory.spec.ts +563 -557
  175. package/src/__tests__/PostgresKyselyMigrator.spec.ts +641 -641
  176. package/src/__tests__/PostgresMigrator.spec.ts +341 -341
  177. package/src/__tests__/PostgresObjectionMigrator.spec.ts +578 -578
  178. package/src/__tests__/VitestObjectionTransactionIsolator.spec.ts +114 -114
  179. package/src/__tests__/benchmark.spec.ts +140 -0
  180. package/src/__tests__/better-auth.spec.ts +15 -15
  181. package/src/__tests__/faker.spec.ts +226 -137
  182. package/src/__tests__/integration.spec.ts +597 -597
  183. package/src/__tests__/utilities.spec.ts +211 -0
  184. package/src/aws.ts +104 -104
  185. package/src/benchmark.ts +12 -12
  186. package/src/better-auth.ts +286 -301
  187. package/src/faker.ts +153 -153
  188. package/src/helpers.ts +6 -6
  189. package/src/kysely.ts +33 -33
  190. package/src/logger.ts +10 -10
  191. package/src/objection.ts +31 -31
  192. package/src/os/directory.ts +11 -10
  193. package/src/timer.ts +1 -1
  194. package/test/globalSetup.ts +45 -45
  195. package/test/helpers.ts +189 -189
  196. package/test/migrations/1749664623372_user.ts +13 -13
  197. package/tsconfig.json +9 -0
  198. package/vitest.config.ts +4 -4
  199. package/dist/PostgresKyselyMigrator-CfytARcA.cjs.map +0 -1
  200. package/dist/PostgresKyselyMigrator-upT-hmrz.mjs.map +0 -1
  201. package/dist/PostgresMigrator-DFcNdCvD.cjs.map +0 -1
  202. package/dist/PostgresMigrator-DbuJGAVy.mjs.map +0 -1
  203. package/dist/PostgresObjectionMigrator-BG6ymgnt.cjs.map +0 -1
  204. package/dist/PostgresObjectionMigrator-DPj2pOpX.mjs.map +0 -1
  205. package/dist/VitestKyselyTransactionIsolator-CNURW8y6.mjs.map +0 -1
  206. package/dist/VitestKyselyTransactionIsolator-EvDLk5zg.cjs.map +0 -1
  207. package/dist/VitestObjectionTransactionIsolator-CM5KTAFA.cjs.map +0 -1
  208. package/dist/VitestObjectionTransactionIsolator-jQFaCz0u.mjs.map +0 -1
  209. package/dist/directory-Mi7tdOuD.d.cts +0 -12
@@ -1,7 +1,7 @@
1
1
  import type { Knex } from 'knex';
2
2
  import {
3
- type IsolationLevel,
4
- VitestPostgresTransactionIsolator,
3
+ type IsolationLevel,
4
+ VitestPostgresTransactionIsolator,
5
5
  } from './VitestTransactionIsolator';
6
6
 
7
7
  /**
@@ -33,43 +33,43 @@ import {
33
33
  * ```
34
34
  */
35
35
  export class VitestObjectionTransactionIsolator extends VitestPostgresTransactionIsolator<
36
- Knex,
37
- Knex.Transaction
36
+ Knex,
37
+ Knex.Transaction
38
38
  > {
39
- async destroy(conn: Knex<any, any[]>): Promise<void> {}
40
- /**
41
- * Creates a Knex transaction with the specified isolation level.
42
- * Implements the abstract transact method from VitestPostgresTransactionIsolator.
43
- * This transaction can be used with Objection.js models via Model.query(trx).
44
- *
45
- * @param conn - The Knex database connection
46
- * @param level - The transaction isolation level
47
- * @param fn - The function to execute within the transaction
48
- * @returns Promise that resolves when the transaction completes
49
- *
50
- * @example
51
- * ```typescript
52
- * await isolator.transact(knex, IsolationLevel.REPEATABLE_READ, async (trx) => {
53
- * // Use transaction with Objection models
54
- * await User.query(trx).insert({ name: 'Test' });
55
- * await Post.query(trx).where('userId', user.id).delete();
56
- * });
57
- * ```
58
- */
59
- async transact(
60
- connection: Knex,
61
- level: IsolationLevel,
62
- fn: (trx: Knex.Transaction) => Promise<void>,
63
- ): Promise<void> {
64
- const isolationLevel = level.toLowerCase() as Lowercase<IsolationLevel>;
39
+ async destroy(_conn: Knex<any, any[]>): Promise<void> {}
40
+ /**
41
+ * Creates a Knex transaction with the specified isolation level.
42
+ * Implements the abstract transact method from VitestPostgresTransactionIsolator.
43
+ * This transaction can be used with Objection.js models via Model.query(trx).
44
+ *
45
+ * @param conn - The Knex database connection
46
+ * @param level - The transaction isolation level
47
+ * @param fn - The function to execute within the transaction
48
+ * @returns Promise that resolves when the transaction completes
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * await isolator.transact(knex, IsolationLevel.REPEATABLE_READ, async (trx) => {
53
+ * // Use transaction with Objection models
54
+ * await User.query(trx).insert({ name: 'Test' });
55
+ * await Post.query(trx).where('userId', user.id).delete();
56
+ * });
57
+ * ```
58
+ */
59
+ async transact(
60
+ connection: Knex,
61
+ level: IsolationLevel,
62
+ fn: (trx: Knex.Transaction) => Promise<void>,
63
+ ): Promise<void> {
64
+ const isolationLevel = level.toLowerCase() as Lowercase<IsolationLevel>;
65
65
 
66
- await connection.transaction(
67
- async (trx) => {
68
- await fn(trx);
69
- },
70
- {
71
- isolationLevel,
72
- },
73
- );
74
- }
66
+ await connection.transaction(
67
+ async (trx) => {
68
+ await fn(trx);
69
+ },
70
+ {
71
+ isolationLevel,
72
+ },
73
+ );
74
+ }
75
75
  }
@@ -7,20 +7,20 @@ import type { TestAPI } from 'vitest';
7
7
  * @template Transaction - The transaction type specific to the database driver
8
8
  * @template Extended - Additional context properties provided by the extend function
9
9
  */
10
- export interface DatabaseFixtures<Transaction, Extended = object> {
11
- /**
12
- * The database transaction available to the test.
13
- * All database operations should use this transaction to ensure proper rollback.
14
- */
15
- trx: Transaction;
10
+ export interface DatabaseFixtures<Transaction, _Extended = object> {
11
+ /**
12
+ * The database transaction available to the test.
13
+ * All database operations should use this transaction to ensure proper rollback.
14
+ */
15
+ trx: Transaction;
16
16
  }
17
17
 
18
18
  /**
19
19
  * Combined fixtures type that merges the base transaction fixture with extended context.
20
20
  */
21
21
  export type ExtendedDatabaseFixtures<
22
- Transaction,
23
- Extended = object,
22
+ Transaction,
23
+ Extended = object,
24
24
  > = DatabaseFixtures<Transaction> & Extended;
25
25
 
26
26
  /**
@@ -37,7 +37,7 @@ export type ExtendedDatabaseFixtures<
37
37
  * ```
38
38
  */
39
39
  export type ExtendContextFn<Transaction, Extended> = (
40
- trx: Transaction,
40
+ trx: Transaction,
41
41
  ) => Extended | Promise<Extended>;
42
42
 
43
43
  /**
@@ -47,26 +47,26 @@ export type ExtendContextFn<Transaction, Extended> = (
47
47
  * @see https://www.postgresql.org/docs/current/transaction-iso.html
48
48
  */
49
49
  export enum IsolationLevel {
50
- /**
51
- * Lowest isolation level. Allows dirty reads.
52
- * Not recommended for testing.
53
- */
54
- READ_UNCOMMITTED = 'READ UNCOMMITTED',
55
- /**
56
- * Default PostgreSQL isolation level.
57
- * Prevents dirty reads but allows non-repeatable reads.
58
- */
59
- READ_COMMITTED = 'READ COMMITTED',
60
- /**
61
- * Prevents dirty reads and non-repeatable reads.
62
- * Recommended for most test scenarios.
63
- */
64
- REPEATABLE_READ = 'REPEATABLE READ',
65
- /**
66
- * Highest isolation level. Prevents all phenomena.
67
- * May cause performance overhead in tests.
68
- */
69
- SERIALIZABLE = 'SERIALIZABLE',
50
+ /**
51
+ * Lowest isolation level. Allows dirty reads.
52
+ * Not recommended for testing.
53
+ */
54
+ READ_UNCOMMITTED = 'READ UNCOMMITTED',
55
+ /**
56
+ * Default PostgreSQL isolation level.
57
+ * Prevents dirty reads but allows non-repeatable reads.
58
+ */
59
+ READ_COMMITTED = 'READ COMMITTED',
60
+ /**
61
+ * Prevents dirty reads and non-repeatable reads.
62
+ * Recommended for most test scenarios.
63
+ */
64
+ REPEATABLE_READ = 'REPEATABLE READ',
65
+ /**
66
+ * Highest isolation level. Prevents all phenomena.
67
+ * May cause performance overhead in tests.
68
+ */
69
+ SERIALIZABLE = 'SERIALIZABLE',
70
70
  }
71
71
 
72
72
  /**
@@ -97,129 +97,130 @@ export enum IsolationLevel {
97
97
  * ```
98
98
  */
99
99
  export abstract class VitestPostgresTransactionIsolator<TConn, Transaction> {
100
- /**
101
- * Abstract method to create a transaction with the specified isolation level.
102
- * Must be implemented by subclasses for specific database drivers.
103
- *
104
- * @param conn - The database connection
105
- * @param isolationLevel - The transaction isolation level
106
- * @param fn - The function to execute within the transaction
107
- * @returns Promise that resolves when the transaction completes
108
- */
109
- abstract transact(
110
- conn: TConn,
111
- isolationLevel: IsolationLevel,
112
- fn: (trx: Transaction) => Promise<void>,
113
- ): Promise<void>;
100
+ /**
101
+ * Abstract method to create a transaction with the specified isolation level.
102
+ * Must be implemented by subclasses for specific database drivers.
103
+ *
104
+ * @param conn - The database connection
105
+ * @param isolationLevel - The transaction isolation level
106
+ * @param fn - The function to execute within the transaction
107
+ * @returns Promise that resolves when the transaction completes
108
+ */
109
+ abstract transact(
110
+ conn: TConn,
111
+ isolationLevel: IsolationLevel,
112
+ fn: (trx: Transaction) => Promise<void>,
113
+ ): Promise<void>;
114
114
 
115
- abstract destroy(conn: TConn): Promise<void>;
116
- /**
117
- * Creates a new VitestPostgresTransactionIsolator instance.
118
- *
119
- * @param api - The Vitest test API (usually the `test` export from vitest)
120
- */
121
- constructor(private readonly api: TestAPI) {}
115
+ abstract destroy(conn: TConn): Promise<void>;
116
+ /**
117
+ * Creates a new VitestPostgresTransactionIsolator instance.
118
+ *
119
+ * @param api - The Vitest test API (usually the `test` export from vitest)
120
+ */
121
+ constructor(private readonly api: TestAPI) {}
122
122
 
123
- /**
124
- * Creates a wrapped version of Vitest's test API that provides transaction isolation.
125
- * Each test will run within a database transaction that is automatically rolled back.
126
- *
127
- * @param options - Configuration options for transaction wrapping
128
- * @returns A wrapped test API with transaction support
129
- *
130
- * @example
131
- * ```typescript
132
- * const isolatedTest = isolator.wrapVitestWithTransaction({
133
- * connection: db,
134
- * setup: async (trx) => {
135
- * await trx.insert('settings', { key: 'test', value: 'true' });
136
- * },
137
- * fixtures: {
138
- * factory: (trx) => new Factory(trx),
139
- * },
140
- * });
141
- *
142
- * isolatedTest('test with transaction', async ({ trx, factory }) => {
143
- * const user = await factory.insert('user', { name: 'Test' });
144
- * expect(user).toBeDefined();
145
- * });
146
- * ```
147
- */
148
- wrapVitestWithTransaction<Extended extends Record<string, unknown> = {}>(
149
- options: TransactionWrapperOptions<TConn, Transaction, Extended>,
150
- ) {
151
- const {
152
- connection,
153
- setup,
154
- isolationLevel = IsolationLevel.REPEATABLE_READ,
155
- fixtures,
156
- } = options;
123
+ /**
124
+ * Creates a wrapped version of Vitest's test API that provides transaction isolation.
125
+ * Each test will run within a database transaction that is automatically rolled back.
126
+ *
127
+ * @param options - Configuration options for transaction wrapping
128
+ * @returns A wrapped test API with transaction support
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const isolatedTest = isolator.wrapVitestWithTransaction({
133
+ * connection: db,
134
+ * setup: async (trx) => {
135
+ * await trx.insert('settings', { key: 'test', value: 'true' });
136
+ * },
137
+ * fixtures: {
138
+ * factory: (trx) => new Factory(trx),
139
+ * },
140
+ * });
141
+ *
142
+ * isolatedTest('test with transaction', async ({ trx, factory }) => {
143
+ * const user = await factory.insert('user', { name: 'Test' });
144
+ * expect(user).toBeDefined();
145
+ * });
146
+ * ```
147
+ */
148
+ wrapVitestWithTransaction<Extended extends Record<string, unknown> = {}>(
149
+ options: TransactionWrapperOptions<TConn, Transaction, Extended>,
150
+ ) {
151
+ const {
152
+ connection,
153
+ setup,
154
+ isolationLevel = IsolationLevel.REPEATABLE_READ,
155
+ fixtures,
156
+ } = options;
157
157
 
158
- // Build fixture definitions for additional fixtures that depend on trx
159
- const additionalFixtures: Record<string, unknown> = {};
160
- if (fixtures) {
161
- for (const [key, creator] of Object.entries(fixtures)) {
162
- additionalFixtures[key] = async (
163
- { trx }: { trx: Transaction },
164
- use: (value: unknown) => Promise<void>,
165
- ) => {
166
- const value = await (creator as (trx: Transaction) => unknown)(trx);
167
- await use(value);
168
- };
169
- }
170
- }
158
+ // Build fixture definitions for additional fixtures that depend on trx
159
+ const additionalFixtures: Record<string, unknown> = {};
160
+ if (fixtures) {
161
+ for (const [key, creator] of Object.entries(fixtures)) {
162
+ additionalFixtures[key] = async (
163
+ { trx }: { trx: Transaction },
164
+ use: (value: unknown) => Promise<void>,
165
+ ) => {
166
+ const value = await (creator as (trx: Transaction) => unknown)(trx);
167
+ await use(value);
168
+ };
169
+ }
170
+ }
171
171
 
172
- type CombinedFixtures = DatabaseFixtures<Transaction> & Extended;
172
+ type CombinedFixtures = DatabaseFixtures<Transaction> & Extended;
173
173
 
174
- // Cast to bypass Vitest's strict fixture typing which can't infer
175
- // dynamically built fixture objects
176
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
- const extendFn = this.api.extend as <T>(fixtures: any) => TestAPI<T>;
174
+ // Cast to bypass Vitest's strict fixture typing which can't infer
175
+ // dynamically built fixture objects
176
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ const extendFn = this.api.extend as <T>(fixtures: any) => TestAPI<T>;
178
178
 
179
- return extendFn<CombinedFixtures>({
180
- // This fixture automatically provides a transaction to each test
181
- trx: async ({}, use: (value: Transaction) => Promise<void>) => {
182
- // Create a custom error class for rollback
183
- class TestRollback extends Error {
184
- constructor() {
185
- super('Test rollback');
186
- this.name = 'TestRollback';
187
- }
188
- }
179
+ return extendFn<CombinedFixtures>({
180
+ // This fixture automatically provides a transaction to each test
181
+ // biome-ignore lint/correctness/noEmptyPattern: this has to be like this to satisfy Biome
182
+ trx: async ({}: {}, use: (value: Transaction) => Promise<void>) => {
183
+ // Create a custom error class for rollback
184
+ class TestRollback extends Error {
185
+ constructor() {
186
+ super('Test rollback');
187
+ this.name = 'TestRollback';
188
+ }
189
+ }
189
190
 
190
- let testError: Error | undefined;
191
- const conn = await connection();
192
- try {
193
- await this.transact(conn, isolationLevel, async (transaction) => {
194
- try {
195
- // Provide the transaction to the test
196
- await setup?.(transaction);
197
- await use(transaction);
198
- } catch (error) {
199
- // Capture any test errors
200
- testError = error as Error;
201
- }
191
+ let testError: Error | undefined;
192
+ const conn = await connection();
193
+ try {
194
+ await this.transact(conn, isolationLevel, async (transaction) => {
195
+ try {
196
+ // Provide the transaction to the test
197
+ await setup?.(transaction);
198
+ await use(transaction);
199
+ } catch (error) {
200
+ // Capture any test errors
201
+ testError = error as Error;
202
+ }
202
203
 
203
- // Always throw to trigger rollback
204
- throw new TestRollback();
205
- });
206
- } catch (error) {
207
- // Only rethrow if it's not our rollback error
208
- if (!(error instanceof TestRollback)) {
209
- throw error;
210
- }
204
+ // Always throw to trigger rollback
205
+ throw new TestRollback();
206
+ });
207
+ } catch (error) {
208
+ // Only rethrow if it's not our rollback error
209
+ if (!(error instanceof TestRollback)) {
210
+ throw error;
211
+ }
211
212
 
212
- // If the test had an error, throw it now
213
- if (testError) {
214
- throw testError;
215
- }
216
- } finally {
217
- await this.destroy(conn);
218
- }
219
- },
220
- ...additionalFixtures,
221
- });
222
- }
213
+ // If the test had an error, throw it now
214
+ if (testError) {
215
+ throw testError;
216
+ }
217
+ } finally {
218
+ await this.destroy(conn);
219
+ }
220
+ },
221
+ ...additionalFixtures,
222
+ });
223
+ }
223
224
  }
224
225
 
225
226
  export type DatabaseConnectionFn<Conn> = () => Conn | Promise<Conn>;
@@ -229,18 +230,18 @@ export type DatabaseConnection<Conn> = DatabaseConnectionFn<Conn>;
229
230
  * Options for wrapping Vitest tests with database transaction isolation.
230
231
  */
231
232
  export interface TransactionWrapperOptions<
232
- TConn,
233
- Transaction,
234
- Extended extends Record<string, unknown> = {},
233
+ TConn,
234
+ Transaction,
235
+ Extended extends Record<string, unknown> = {},
235
236
  > {
236
- /** Function that creates or returns a database connection */
237
- connection: DatabaseConnection<TConn>;
238
- /** Optional setup function to run within the transaction before each test */
239
- setup?: (trx: Transaction) => Promise<void>;
240
- /** Transaction isolation level (defaults to REPEATABLE_READ) */
241
- isolationLevel?: IsolationLevel;
242
- /** Additional fixtures that depend on the transaction */
243
- fixtures?: FixtureCreators<Transaction, Extended>;
237
+ /** Function that creates or returns a database connection */
238
+ connection: DatabaseConnection<TConn>;
239
+ /** Optional setup function to run within the transaction before each test */
240
+ setup?: (trx: Transaction) => Promise<void>;
241
+ /** Transaction isolation level (defaults to REPEATABLE_READ) */
242
+ isolationLevel?: IsolationLevel;
243
+ /** Additional fixtures that depend on the transaction */
244
+ fixtures?: FixtureCreators<Transaction, Extended>;
244
245
  }
245
246
 
246
247
  /**
@@ -248,12 +249,12 @@ export interface TransactionWrapperOptions<
248
249
  * Each function receives the transaction and returns the fixture value.
249
250
  */
250
251
  export type FixtureCreators<
251
- Transaction,
252
- Extended extends Record<string, unknown>,
252
+ Transaction,
253
+ Extended extends Record<string, unknown>,
253
254
  > = {
254
- [K in keyof Extended]: (
255
- trx: Transaction,
256
- ) => Extended[K] | Promise<Extended[K]>;
255
+ [K in keyof Extended]: (
256
+ trx: Transaction,
257
+ ) => Extended[K] | Promise<Extended[K]>;
257
258
  };
258
259
 
259
260
  /**
@@ -265,25 +266,25 @@ export type FixtureCreators<
265
266
  * @template BaseTest - The base wrapped test type
266
267
  */
267
268
  export type TestWithExtendedFixtures<
268
- Transaction,
269
- Extended extends Record<string, unknown>,
270
- BaseTest extends ReturnType<TestAPI['extend']> = ReturnType<
271
- TestAPI['extend']
272
- >,
269
+ Transaction,
270
+ Extended extends Record<string, unknown>,
271
+ BaseTest extends ReturnType<TestAPI['extend']> = ReturnType<
272
+ TestAPI['extend']
273
+ >,
273
274
  > = BaseTest & {
274
- <C extends object>(
275
- name: string,
276
- fn: (
277
- context: DatabaseFixtures<Transaction> & Extended & C,
278
- ) => Promise<void>,
279
- ): void;
280
- <C extends object>(
281
- name: string,
282
- options: object,
283
- fn: (
284
- context: DatabaseFixtures<Transaction> & Extended & C,
285
- ) => Promise<void>,
286
- ): void;
275
+ <C extends object>(
276
+ name: string,
277
+ fn: (
278
+ context: DatabaseFixtures<Transaction> & Extended & C,
279
+ ) => Promise<void>,
280
+ ): void;
281
+ <C extends object>(
282
+ name: string,
283
+ options: object,
284
+ fn: (
285
+ context: DatabaseFixtures<Transaction> & Extended & C,
286
+ ) => Promise<void>,
287
+ ): void;
287
288
  };
288
289
 
289
290
  /**
@@ -320,26 +321,26 @@ export type TestWithExtendedFixtures<
320
321
  * ```
321
322
  */
322
323
  export function extendWithFixtures<
323
- Transaction,
324
- Extended extends Record<string, unknown>,
325
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
326
- T extends ReturnType<TestAPI['extend']> = any,
324
+ Transaction,
325
+ Extended extends Record<string, unknown>,
326
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
327
+ T extends ReturnType<TestAPI['extend']> = any,
327
328
  >(
328
- wrappedTest: T,
329
- fixtures: FixtureCreators<Transaction, Extended>,
329
+ wrappedTest: T,
330
+ fixtures: FixtureCreators<Transaction, Extended>,
330
331
  ): TestWithExtendedFixtures<Transaction, Extended, T> {
331
- // Build fixture definitions for Vitest's extend API
332
- const fixtureDefinitions: Record<string, any> = {};
332
+ // Build fixture definitions for Vitest's extend API
333
+ const fixtureDefinitions: Record<string, any> = {};
333
334
 
334
- for (const [key, creator] of Object.entries(fixtures)) {
335
- fixtureDefinitions[key] = async (
336
- { trx }: { trx: Transaction },
337
- use: (value: unknown) => Promise<void>,
338
- ) => {
339
- const value = await (creator as (trx: Transaction) => unknown)(trx);
340
- await use(value);
341
- };
342
- }
335
+ for (const [key, creator] of Object.entries(fixtures)) {
336
+ fixtureDefinitions[key] = async (
337
+ { trx }: { trx: Transaction },
338
+ use: (value: unknown) => Promise<void>,
339
+ ) => {
340
+ const value = await (creator as (trx: Transaction) => unknown)(trx);
341
+ await use(value);
342
+ };
343
+ }
343
344
 
344
- return (wrappedTest as any).extend(fixtureDefinitions);
345
+ return (wrappedTest as any).extend(fixtureDefinitions);
345
346
  }