@c9up/atlas 0.2.0 → 0.2.1

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 (234) hide show
  1. package/README.md +8 -0
  2. package/db.darwin-arm64.node +0 -0
  3. package/db.darwin-x64.node +0 -0
  4. package/db.linux-arm64-gnu.node +0 -0
  5. package/db.linux-x64-gnu.node +0 -0
  6. package/db.win32-x64-msvc.node +0 -0
  7. package/dist/AtlasProvider.d.ts +60 -7
  8. package/dist/AtlasProvider.d.ts.map +1 -1
  9. package/dist/AtlasProvider.js +204 -38
  10. package/dist/AtlasProvider.js.map +1 -1
  11. package/dist/BaseEntity.d.ts +17 -0
  12. package/dist/BaseEntity.d.ts.map +1 -1
  13. package/dist/BaseEntity.js.map +1 -1
  14. package/dist/BaseModel.d.ts +63 -27
  15. package/dist/BaseModel.d.ts.map +1 -1
  16. package/dist/BaseModel.js +108 -51
  17. package/dist/BaseModel.js.map +1 -1
  18. package/dist/BaseRepository.d.ts +11 -1
  19. package/dist/BaseRepository.d.ts.map +1 -1
  20. package/dist/BaseRepository.js +95 -20
  21. package/dist/BaseRepository.js.map +1 -1
  22. package/dist/ConnectionManager.d.ts +106 -0
  23. package/dist/ConnectionManager.d.ts.map +1 -0
  24. package/dist/ConnectionManager.js +228 -0
  25. package/dist/ConnectionManager.js.map +1 -0
  26. package/dist/ModelQuery.d.ts +256 -43
  27. package/dist/ModelQuery.d.ts.map +1 -1
  28. package/dist/ModelQuery.js +899 -231
  29. package/dist/ModelQuery.js.map +1 -1
  30. package/dist/Transaction.d.ts +54 -1
  31. package/dist/Transaction.d.ts.map +1 -1
  32. package/dist/Transaction.js +121 -59
  33. package/dist/Transaction.js.map +1 -1
  34. package/dist/adapters/NapiDbAdapter.d.ts +11 -0
  35. package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
  36. package/dist/adapters/NapiDbAdapter.js +35 -7
  37. package/dist/adapters/NapiDbAdapter.js.map +1 -1
  38. package/dist/console/contract.d.ts +62 -0
  39. package/dist/console/contract.d.ts.map +1 -0
  40. package/dist/console/contract.js +38 -0
  41. package/dist/console/contract.js.map +1 -0
  42. package/dist/console/factoryCommands.d.ts +23 -0
  43. package/dist/console/factoryCommands.d.ts.map +1 -0
  44. package/dist/console/factoryCommands.js +62 -0
  45. package/dist/console/factoryCommands.js.map +1 -0
  46. package/dist/console/migrationCommands.d.ts +38 -8
  47. package/dist/console/migrationCommands.d.ts.map +1 -1
  48. package/dist/console/migrationCommands.js +157 -50
  49. package/dist/console/migrationCommands.js.map +1 -1
  50. package/dist/console/schemaCheckCommand.d.ts +11 -17
  51. package/dist/console/schemaCheckCommand.d.ts.map +1 -1
  52. package/dist/console/schemaCheckCommand.js +21 -15
  53. package/dist/console/schemaCheckCommand.js.map +1 -1
  54. package/dist/console/schemaDumpCommand.d.ts +30 -0
  55. package/dist/console/schemaDumpCommand.d.ts.map +1 -0
  56. package/dist/console/schemaDumpCommand.js +69 -0
  57. package/dist/console/schemaDumpCommand.js.map +1 -0
  58. package/dist/console/schemaGenerateCommand.d.ts +100 -0
  59. package/dist/console/schemaGenerateCommand.d.ts.map +1 -0
  60. package/dist/console/schemaGenerateCommand.js +246 -0
  61. package/dist/console/schemaGenerateCommand.js.map +1 -0
  62. package/dist/console/seederCommands.d.ts +46 -0
  63. package/dist/console/seederCommands.d.ts.map +1 -0
  64. package/dist/console/seederCommands.js +136 -0
  65. package/dist/console/seederCommands.js.map +1 -0
  66. package/dist/decorators/entity.d.ts +13 -2
  67. package/dist/decorators/entity.d.ts.map +1 -1
  68. package/dist/decorators/entity.js +10 -0
  69. package/dist/decorators/entity.js.map +1 -1
  70. package/dist/decorators/hooks.d.ts +3 -3
  71. package/dist/decorators/hooks.d.ts.map +1 -1
  72. package/dist/decorators/hooks.js.map +1 -1
  73. package/dist/events.d.ts +5 -0
  74. package/dist/events.d.ts.map +1 -1
  75. package/dist/events.js.map +1 -1
  76. package/dist/factories.d.ts +8 -0
  77. package/dist/factories.d.ts.map +1 -0
  78. package/dist/factories.js +8 -0
  79. package/dist/factories.js.map +1 -0
  80. package/dist/index.d.ts +11 -5
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +12 -4
  83. package/dist/index.js.map +1 -1
  84. package/dist/lucid-schema.d.ts +15 -0
  85. package/dist/lucid-schema.d.ts.map +1 -0
  86. package/dist/lucid-schema.js +16 -0
  87. package/dist/lucid-schema.js.map +1 -0
  88. package/dist/orm.d.ts +14 -0
  89. package/dist/orm.d.ts.map +1 -0
  90. package/dist/orm.js +14 -0
  91. package/dist/orm.js.map +1 -0
  92. package/dist/query/DatabaseQueryBuilder.d.ts +557 -0
  93. package/dist/query/DatabaseQueryBuilder.d.ts.map +1 -0
  94. package/dist/query/DatabaseQueryBuilder.js +1798 -0
  95. package/dist/query/DatabaseQueryBuilder.js.map +1 -0
  96. package/dist/query/DmlBuilder.d.ts +62 -0
  97. package/dist/query/DmlBuilder.d.ts.map +1 -0
  98. package/dist/query/DmlBuilder.js +84 -0
  99. package/dist/query/DmlBuilder.js.map +1 -0
  100. package/dist/query/QueryBuilder.d.ts +5 -0
  101. package/dist/query/QueryBuilder.d.ts.map +1 -1
  102. package/dist/query/QueryBuilder.js +7 -0
  103. package/dist/query/QueryBuilder.js.map +1 -1
  104. package/dist/query/RawQueryBuilder.d.ts +47 -0
  105. package/dist/query/RawQueryBuilder.d.ts.map +1 -0
  106. package/dist/query/RawQueryBuilder.js +138 -0
  107. package/dist/query/RawQueryBuilder.js.map +1 -0
  108. package/dist/query/interpolate.d.ts +45 -0
  109. package/dist/query/interpolate.d.ts.map +1 -0
  110. package/dist/query/interpolate.js +51 -0
  111. package/dist/query/interpolate.js.map +1 -0
  112. package/dist/query/native.d.ts +8 -0
  113. package/dist/query/native.d.ts.map +1 -1
  114. package/dist/query/native.js +14 -0
  115. package/dist/query/native.js.map +1 -1
  116. package/dist/query/operators.d.ts +4 -0
  117. package/dist/query/operators.d.ts.map +1 -0
  118. package/dist/query/operators.js +27 -0
  119. package/dist/query/operators.js.map +1 -0
  120. package/dist/schema/Migration.d.ts +31 -7
  121. package/dist/schema/Migration.d.ts.map +1 -1
  122. package/dist/schema/Migration.js +34 -7
  123. package/dist/schema/Migration.js.map +1 -1
  124. package/dist/schema/MigrationRunner.d.ts +56 -6
  125. package/dist/schema/MigrationRunner.d.ts.map +1 -1
  126. package/dist/schema/MigrationRunner.js +382 -112
  127. package/dist/schema/MigrationRunner.js.map +1 -1
  128. package/dist/schema/Schema.d.ts +59 -2
  129. package/dist/schema/Schema.d.ts.map +1 -1
  130. package/dist/schema/Schema.js +143 -9
  131. package/dist/schema/Schema.js.map +1 -1
  132. package/dist/schema/SchemaDumper.d.ts +121 -0
  133. package/dist/schema/SchemaDumper.d.ts.map +1 -0
  134. package/dist/schema/SchemaDumper.js +365 -0
  135. package/dist/schema/SchemaDumper.js.map +1 -0
  136. package/dist/schema/Seeder.d.ts +13 -0
  137. package/dist/schema/Seeder.d.ts.map +1 -1
  138. package/dist/schema/Seeder.js +28 -5
  139. package/dist/schema/Seeder.js.map +1 -1
  140. package/dist/schema/TableBuilder.d.ts +27 -8
  141. package/dist/schema/TableBuilder.d.ts.map +1 -1
  142. package/dist/schema/TableBuilder.js +50 -12
  143. package/dist/schema/TableBuilder.js.map +1 -1
  144. package/dist/schema/catalog.d.ts +25 -1
  145. package/dist/schema/catalog.d.ts.map +1 -1
  146. package/dist/schema/catalog.js +69 -22
  147. package/dist/schema/catalog.js.map +1 -1
  148. package/dist/schema/introspect.d.ts +1 -1
  149. package/dist/schema/introspect.d.ts.map +1 -1
  150. package/dist/schema/introspect.js +26 -11
  151. package/dist/schema/introspect.js.map +1 -1
  152. package/dist/seeders.d.ts +7 -0
  153. package/dist/seeders.d.ts.map +1 -0
  154. package/dist/seeders.js +7 -0
  155. package/dist/seeders.js.map +1 -0
  156. package/dist/services/db.d.ts +120 -9
  157. package/dist/services/db.d.ts.map +1 -1
  158. package/dist/services/db.js +182 -26
  159. package/dist/services/db.js.map +1 -1
  160. package/dist/testing/DatabaseCleanup.d.ts +29 -6
  161. package/dist/testing/DatabaseCleanup.d.ts.map +1 -1
  162. package/dist/testing/DatabaseCleanup.js +44 -17
  163. package/dist/testing/DatabaseCleanup.js.map +1 -1
  164. package/dist/testing/DbAssertions.d.ts +48 -0
  165. package/dist/testing/DbAssertions.d.ts.map +1 -0
  166. package/dist/testing/DbAssertions.js +80 -0
  167. package/dist/testing/DbAssertions.js.map +1 -0
  168. package/dist/testing/Factory.d.ts +111 -25
  169. package/dist/testing/Factory.d.ts.map +1 -1
  170. package/dist/testing/Factory.js +331 -56
  171. package/dist/testing/Factory.js.map +1 -1
  172. package/dist/testing/TestUtils.d.ts +49 -0
  173. package/dist/testing/TestUtils.d.ts.map +1 -0
  174. package/dist/testing/TestUtils.js +79 -0
  175. package/dist/testing/TestUtils.js.map +1 -0
  176. package/dist/testing/index.d.ts +3 -1
  177. package/dist/testing/index.d.ts.map +1 -1
  178. package/dist/testing/index.js +3 -1
  179. package/dist/testing/index.js.map +1 -1
  180. package/dist/types/relations.d.ts +31 -0
  181. package/dist/types/relations.d.ts.map +1 -0
  182. package/dist/types/relations.js +20 -0
  183. package/dist/types/relations.js.map +1 -0
  184. package/index.darwin-arm64.node +0 -0
  185. package/index.darwin-x64.node +0 -0
  186. package/index.linux-arm64-gnu.node +0 -0
  187. package/index.linux-x64-gnu.node +0 -0
  188. package/index.win32-x64-msvc.node +0 -0
  189. package/package.json +30 -2
  190. package/src/AtlasProvider.ts +297 -51
  191. package/src/BaseEntity.ts +29 -0
  192. package/src/BaseModel.ts +174 -37
  193. package/src/BaseRepository.ts +136 -17
  194. package/src/ConnectionManager.ts +298 -0
  195. package/src/ModelQuery.ts +1309 -260
  196. package/src/Transaction.ts +194 -60
  197. package/src/adapters/NapiDbAdapter.ts +72 -14
  198. package/src/console/contract.ts +96 -0
  199. package/src/console/factoryCommands.ts +73 -0
  200. package/src/console/migrationCommands.ts +253 -63
  201. package/src/console/schemaCheckCommand.ts +26 -22
  202. package/src/console/schemaDumpCommand.ts +96 -0
  203. package/src/console/schemaGenerateCommand.ts +380 -0
  204. package/src/console/seederCommands.ts +174 -0
  205. package/src/decorators/entity.ts +18 -2
  206. package/src/decorators/hooks.ts +5 -3
  207. package/src/events.ts +5 -0
  208. package/src/factories.ts +10 -0
  209. package/src/index.ts +50 -3
  210. package/src/lucid-schema.ts +22 -0
  211. package/src/orm.ts +13 -0
  212. package/src/query/DatabaseQueryBuilder.ts +2724 -0
  213. package/src/query/DmlBuilder.ts +131 -0
  214. package/src/query/QueryBuilder.ts +8 -0
  215. package/src/query/RawQueryBuilder.ts +173 -0
  216. package/src/query/interpolate.ts +73 -0
  217. package/src/query/native.ts +29 -0
  218. package/src/query/operators.ts +27 -0
  219. package/src/schema/Migration.ts +36 -7
  220. package/src/schema/MigrationRunner.ts +483 -119
  221. package/src/schema/Schema.ts +168 -19
  222. package/src/schema/SchemaDumper.ts +518 -0
  223. package/src/schema/Seeder.ts +47 -10
  224. package/src/schema/TableBuilder.ts +48 -11
  225. package/src/schema/catalog.ts +94 -24
  226. package/src/schema/introspect.ts +26 -9
  227. package/src/seeders.ts +16 -0
  228. package/src/services/db.ts +343 -31
  229. package/src/testing/DatabaseCleanup.ts +73 -21
  230. package/src/testing/DbAssertions.ts +127 -0
  231. package/src/testing/Factory.ts +559 -79
  232. package/src/testing/TestUtils.ts +123 -0
  233. package/src/testing/index.ts +12 -1
  234. package/src/types/relations.ts +43 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * `db()` — a helix plugin (AdonisJS Lucid database-assertions parity) that
3
+ * injects database assertions on the test context as `ctx.db`:
4
+ *
5
+ * // tests/bootstrap.ts
6
+ * import { configure } from "@c9up/helix";
7
+ * import { db } from "@c9up/atlas/testing";
8
+ * await configure({ plugins: [db(connection)] });
9
+ *
10
+ * test("registers the user", async ({ db }) => {
11
+ * await db.assertHas("users", { email: "a@b.c" });
12
+ * await db.assertCount("users", 1);
13
+ * });
14
+ *
15
+ * Values are always bound as parameters; table/column identifiers are validated
16
+ * against a strict pattern (letters, digits, `_`, `.`) and quoted, so neither a
17
+ * value nor an identifier can inject SQL.
18
+ *
19
+ * NOTE (namespace): the AdonisJS docs expose these as `db.assert*`; the exact
20
+ * surface is re-verified against the Adonis docs when available. Model-based
21
+ * `assertModelExists`/`assertModelMissing` (entity PK metadata) are pending.
22
+ */
23
+ /** Reject identifiers that could break out of the quoted context. */
24
+ function quoteIdent(name) {
25
+ if (!/^[A-Za-z_][A-Za-z0-9_.]*$/.test(name)) {
26
+ throw new Error(`db assertion: unsafe identifier ${JSON.stringify(name)}`);
27
+ }
28
+ return `"${name.replace(/\./g, '"."')}"`;
29
+ }
30
+ async function countRows(conn, table, payload) {
31
+ let where = "";
32
+ let params = [];
33
+ if (payload) {
34
+ const keys = Object.keys(payload);
35
+ if (keys.length > 0) {
36
+ where = ` WHERE ${keys.map((k) => `${quoteIdent(k)} = ?`).join(" AND ")}`;
37
+ params = keys.map((k) => payload[k]);
38
+ }
39
+ }
40
+ const rows = await conn.query(`SELECT COUNT(*) AS c FROM ${quoteIdent(table)}${where}`, params);
41
+ return Number(rows[0]?.c ?? 0);
42
+ }
43
+ /** Build the assertion surface bound to a connection. */
44
+ export function createDbAssertions(conn) {
45
+ return {
46
+ async assertHas(table, payload) {
47
+ const n = await countRows(conn, table, payload);
48
+ if (n === 0) {
49
+ throw new Error(`Expected "${table}" to have a row matching ${JSON.stringify(payload)}, found none.`);
50
+ }
51
+ },
52
+ async assertMissing(table, payload) {
53
+ const n = await countRows(conn, table, payload);
54
+ if (n > 0) {
55
+ throw new Error(`Expected "${table}" to have NO row matching ${JSON.stringify(payload)}, found ${n}.`);
56
+ }
57
+ },
58
+ async assertCount(table, expected, payload) {
59
+ const n = await countRows(conn, table, payload);
60
+ if (n !== expected) {
61
+ const scope = payload ? ` matching ${JSON.stringify(payload)}` : "";
62
+ throw new Error(`Expected "${table}" to have ${expected} row(s)${scope}, found ${n}.`);
63
+ }
64
+ },
65
+ async assertEmpty(table) {
66
+ const n = await countRows(conn, table);
67
+ if (n > 0) {
68
+ throw new Error(`Expected "${table}" to be empty, found ${n} row(s).`);
69
+ }
70
+ },
71
+ };
72
+ }
73
+ /** The `db()` helix plugin — registers {@link DbAssertions} as `ctx.db`. */
74
+ export function db(conn) {
75
+ const assertions = createDbAssertions(conn);
76
+ return (api) => {
77
+ api.context.macro("db", assertions);
78
+ };
79
+ }
80
+ //# sourceMappingURL=DbAssertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DbAssertions.js","sourceRoot":"","sources":["../../src/testing/DbAssertions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,qEAAqE;AACrE,SAAS,UAAU,CAAC,IAAY;IAC/B,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,SAAS,CACvB,IAAsB,EACtB,KAAa,EACb,OAAiC;IAEjC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,MAAM,GAAc,EAAE,CAAC;IAC3B,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,GAAG,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1E,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAC5B,6BAA6B,UAAU,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,EACxD,MAAM,CACN,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAkBD,yDAAyD;AACzD,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACxD,OAAO;QACN,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO;YAC7B,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACd,aAAa,KAAK,4BAA4B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,CACpF,CAAC;YACH,CAAC;QACF,CAAC;QACD,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO;YACjC,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CACd,aAAa,KAAK,6BAA6B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CACrF,CAAC;YACH,CAAC;QACF,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO;YACzC,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,KAAK,CACd,aAAa,KAAK,aAAa,QAAQ,UAAU,KAAK,WAAW,CAAC,GAAG,CACrE,CAAC;YACH,CAAC;QACF,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,KAAK;YACtB,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,wBAAwB,CAAC,UAAU,CAAC,CAAC;YACxE,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,EAAE,CAAC,IAAsB;IACxC,MAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,EAAE,EAAE;QACd,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrC,CAAC,CAAC;AACH,CAAC"}
@@ -20,28 +20,51 @@ type EntityConstructor<T extends BaseEntity> = new () => T;
20
20
  /** Resolves the factory that builds a related model (Lucid `.relation`). */
21
21
  type RelationResolver = () => FactoryBuilder<BaseEntity>;
22
22
  /**
23
- * Context handed to the `define` callback (Adonis Lucid parity). Currently just
24
- * a Faker instance for generating fake data. A callback that takes no argument
25
- * keeps working it simply ignores the context.
23
+ * Runtime context handed to the factory callbacks (Adonis Lucid parity):
24
+ * `faker` for fake data, `isStubbed` (true during a `makeStubbed*` build), and
25
+ * `$trx`the bound transaction/connection, if any, so a hook's own DB queries
26
+ * commit/roll back alongside the factory. A callback that ignores it keeps
27
+ * working.
26
28
  */
27
29
  export interface FactoryContext {
28
30
  faker: Faker;
31
+ isStubbed: boolean;
32
+ $trx?: DatabaseConnection;
29
33
  }
30
34
  /** Attributes callback — receives {@link FactoryContext}, returns the row shape. */
31
35
  type DefaultsFn = (ctx: FactoryContext) => Record<string, unknown>;
32
- /** A named state — mutates an in-progress data object in place. */
33
- type StateFn<D> = (data: D) => void;
36
+ /**
37
+ * A named state — mutates the built model INSTANCE (Adonis Lucid: states receive
38
+ * the instance + runtime context, not a raw data object).
39
+ */
40
+ type StateFn<T extends BaseEntity> = (model: T, ctx: FactoryContext) => void;
41
+ /**
42
+ * A `merge` callback (Adonis Lucid) — receives the built model INSTANCE, the
43
+ * resolved attributes, and the runtime context, e.g.
44
+ * `.merge((user, attributes) => { user.merge(attributes) })`.
45
+ */
46
+ type MergeFn<T extends BaseEntity> = (model: T, attributes: Record<string, unknown>, ctx: FactoryContext) => void;
34
47
  export interface FactoryBuilder<T extends BaseEntity> {
35
- /** Override specific fields for the next call (reset after consumption). */
36
- merge(overrides: Partial<Record<string, unknown>>): FactoryBuilder<T>;
48
+ /**
49
+ * Override specific fields for the next call (reset after consumption). Pass an
50
+ * object to shallow-merge, a CALLBACK to mutate the resolved attributes
51
+ * imperatively (Adonis Lucid `merge`), or an ARRAY to override per row on
52
+ * `makeMany`/`createMany` — `merge([{a:1},{a:2}]).createMany(2)` applies index
53
+ * `i` to row `i` (rows past the array length keep the plain defaults).
54
+ */
55
+ merge(overrides: Partial<Record<string, unknown>> | MergeFn<T> | Array<Partial<Record<string, unknown>>>): FactoryBuilder<T>;
37
56
  /**
38
57
  * Like {@link merge} but deep — nested plain objects are merged key by key
39
58
  * instead of replaced wholesale (Lucid `mergeRecursive`). Arrays and
40
59
  * non-plain values still replace. Reset after consumption like `merge`.
41
60
  */
42
61
  mergeRecursive(overrides: Partial<Record<string, unknown>>): FactoryBuilder<T>;
43
- /** Declare a named variation of this factory, stored on the factory's state map. */
44
- state(name: string, fn: StateFn<Record<string, unknown>>): FactoryBuilder<T>;
62
+ /**
63
+ * Declare a named variation. The callback receives the built model INSTANCE
64
+ * and the runtime context (Adonis Lucid `state`), e.g.
65
+ * `.state('admin', (user) => { user.role = 'admin' })`.
66
+ */
67
+ state(name: string, fn: StateFn<T>): FactoryBuilder<T>;
45
68
  /**
46
69
  * Activate one or more declared states for the NEXT build. Multiple applies
47
70
  * compose (all fire, in order). NOTE: this mutates the builder's shared
@@ -71,10 +94,16 @@ export interface FactoryBuilder<T extends BaseEntity> {
71
94
  create(db?: DatabaseConnection): Promise<T>;
72
95
  /** Create and persist multiple entities (fires hooks per row). */
73
96
  createMany(count: number, db?: DatabaseConnection): Promise<T[]>;
74
- /** Build the data object without persisting and without instantiating an entity. */
75
- make(): Record<string, unknown>;
76
- /** Build multiple data objects without persisting. */
77
- makeMany(count: number): Record<string, unknown>[];
97
+ /**
98
+ * Build an entity INSTANCE without persisting it (Adonis Lucid `make`). The
99
+ * instance has NO primary key and `$isPersisted === false` — use it to
100
+ * exercise model logic (computed props, validation) with no DB round trip.
101
+ * For an instance that looks persisted (stub id, `$isPersisted === true`),
102
+ * use {@link makeStubbed}.
103
+ */
104
+ make(): T;
105
+ /** Build many un-persisted instances (Adonis Lucid `makeMany`). */
106
+ makeMany(count: number): T[];
78
107
  /**
79
108
  * Build an entity INSTANCE without persisting it (Lucid's `makeStubbed`).
80
109
  * The instance is marked persisted and, unless the build already supplied a
@@ -93,22 +122,58 @@ export interface FactoryBuilder<T extends BaseEntity> {
93
122
  /**
94
123
  * Queue related rows to create together with the next `create`/`createMany`
95
124
  * (Adonis Lucid `.with`). `count` defaults to 1 (ignored past 1 for hasOne).
96
- * The callback receives the related factory to customize it (`merge`/`apply`).
97
- *
98
- * One level deep: the related rows are persisted through the parent's
99
- * relation proxy (which wires the FK / pivot), so a nested `.with()` on the
100
- * callback's factory is not itself applied. `.with()` runs on persistence
101
- * only — `make`/`makeStubbed` ignore it.
125
+ * The callback receives the related factory to customize it `merge`/`apply`,
126
+ * `.pivotAttributes()` for m2m pivot columns, and its own nested `.with()`
127
+ * (arbitrarily deep, Adonis Lucid nested factories). `.with()` runs on
128
+ * persistence only `make`/`makeStubbed` ignore it.
102
129
  */
103
130
  with(name: string, count?: number, callback?: (factory: FactoryBuilder<BaseEntity>) => void): FactoryBuilder<T>;
104
131
  /**
105
- * Register a callback that runs on the built entity INSTANCE before it is
106
- * persisted (Adonis Lucid `.tap`). Multiple taps run in order. Applies to the
107
- * instance-producing paths — `create`/`createMany`/`makeStubbed`/
108
- * `makeStubbedMany` — and is reset after consumption; `make`/`makeMany`
109
- * return plain data, so they ignore it.
132
+ * Register a callback that runs on the built entity INSTANCE (Adonis Lucid
133
+ * `.tap`). Receives the model, the runtime {@link FactoryContext}, and this
134
+ * factory builder. Multiple taps run in order, on every instance-producing
135
+ * path (`make`/`makeMany`/`create`/`createMany`/`makeStubbed*`); reset after
136
+ * consumption.
110
137
  */
111
- tap(fn: (entity: T) => void): FactoryBuilder<T>;
138
+ tap(fn: (model: T, ctx: FactoryContext, builder: FactoryBuilder<T>) => void): FactoryBuilder<T>;
139
+ /**
140
+ * Replace the default `new Model()` instantiation (Adonis Lucid `.newUp`).
141
+ * The callback receives the resolved attributes and the runtime context and
142
+ * returns the model instance to use for every subsequent build.
143
+ */
144
+ newUp(fn: (attributes: Record<string, unknown>, ctx: FactoryContext) => T): FactoryBuilder<T>;
145
+ /**
146
+ * Set pivot columns for the NEXT many-to-many `.with()` link (Adonis Lucid
147
+ * `.pivotAttributes`). Called on the RELATED factory inside a `.with()`
148
+ * callback; the values are written on the pivot row alongside the link. A
149
+ * single object applies to every linked row; pass an ARRAY for different
150
+ * values per row (its length should match the related-row count).
151
+ */
152
+ pivotAttributes(attrs: Record<string, unknown> | Array<Record<string, unknown>>): FactoryBuilder<T>;
153
+ /**
154
+ * Bind the connection/transaction for subsequent `create`/`createMany` via an
155
+ * options object (Adonis Lucid `.query({ client }) / .query({ connection })`).
156
+ * Sugar over {@link client} / {@link connection}; `client` wins over `connection`.
157
+ */
158
+ query(options: {
159
+ client?: DatabaseConnection;
160
+ connection?: string;
161
+ }): FactoryBuilder<T>;
162
+ /**
163
+ * Register a lifecycle hook that runs BEFORE the given event (Adonis Lucid
164
+ * factory `before`). `create` fires before the INSERT; `makeStubbed` fires
165
+ * before the stub is finalised (so it can assign the primary key). The
166
+ * callback receives the factory and the model instance. Persistent (declared
167
+ * once, applies to every build).
168
+ */
169
+ before(event: "create" | "makeStubbed", callback: (factory: FactoryBuilder<T>, model: T, ctx: FactoryContext) => void): FactoryBuilder<T>;
170
+ /**
171
+ * Register a lifecycle hook that runs AFTER the given event (Adonis Lucid
172
+ * factory `after`). `create` fires after the INSERT; `makeStubbed` after the
173
+ * stub is built. `make` fires after an un-persisted `make`/`makeMany` instance
174
+ * is built and tapped (Adonis Lucid `after('make')`). Persistent.
175
+ */
176
+ after(event: "make" | "create" | "makeStubbed", callback: (factory: FactoryBuilder<T>, model: T, ctx: FactoryContext) => void): FactoryBuilder<T>;
112
177
  }
113
178
  /**
114
179
  * Define a model factory.
@@ -118,6 +183,27 @@ export interface FactoryBuilder<T extends BaseEntity> {
118
183
  * name: 'Test User',
119
184
  * }))
120
185
  */
186
+ /**
187
+ * Adonis Lucid `Factory.define(Model, callback).build()` entry point. `define`
188
+ * captures the model and its defaults; `build()` returns the usable factory
189
+ * builder. Equivalent to the one-call {@link factory} shorthand, which stays.
190
+ *
191
+ * const UserFactory = Factory.define(User, ({ faker }) => ({
192
+ * email: faker.internet.email(),
193
+ * })).build()
194
+ */
195
+ export declare const Factory: {
196
+ define<T extends BaseEntity>(entityClass: EntityConstructor<T>, defaults: DefaultsFn): {
197
+ build(): FactoryBuilder<T>;
198
+ };
199
+ /**
200
+ * Override the global stub-id generator (Adonis Lucid `Factory.stubId`). Use
201
+ * when your models have non-integer primary keys — the callback receives the
202
+ * running counter and the instance and returns the id to assign. Pass
203
+ * `null`/nothing to restore the default incrementing integer.
204
+ */
205
+ stubId(generator?: ((counter: number, model: BaseEntity) => unknown) | null): void;
206
+ };
121
207
  export declare function factory<T extends BaseEntity>(entityClass: EntityConstructor<T>, defaults: DefaultsFn): FactoryBuilder<T>;
122
208
  export {};
123
209
  //# sourceMappingURL=Factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Factory.d.ts","sourceRoot":"","sources":["../../src/testing/Factory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Factory.d.ts","sourceRoot":"","sources":["../../src/testing/Factory.ts"],"names":[],"mappings":"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"}