@c9up/atlas 0.1.3 → 0.1.4

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 (143) hide show
  1. package/db.darwin-arm64.node +0 -0
  2. package/db.darwin-x64.node +0 -0
  3. package/db.linux-arm64-gnu.node +0 -0
  4. package/db.linux-x64-gnu.node +0 -0
  5. package/db.win32-x64-msvc.node +0 -0
  6. package/dist/AtlasProvider.d.ts +106 -0
  7. package/dist/AtlasProvider.d.ts.map +1 -0
  8. package/dist/AtlasProvider.js +190 -0
  9. package/dist/AtlasProvider.js.map +1 -0
  10. package/dist/BaseEntity.d.ts +255 -0
  11. package/dist/BaseEntity.d.ts.map +1 -0
  12. package/dist/BaseEntity.js +420 -0
  13. package/dist/BaseEntity.js.map +1 -0
  14. package/dist/BaseRepository.d.ts +175 -0
  15. package/dist/BaseRepository.d.ts.map +1 -0
  16. package/dist/BaseRepository.js +1394 -0
  17. package/dist/BaseRepository.js.map +1 -0
  18. package/dist/ModelQuery.d.ts +338 -0
  19. package/dist/ModelQuery.d.ts.map +1 -0
  20. package/dist/ModelQuery.js +1598 -0
  21. package/dist/ModelQuery.js.map +1 -0
  22. package/dist/Transaction.d.ts +15 -0
  23. package/dist/Transaction.d.ts.map +1 -0
  24. package/dist/Transaction.js +67 -0
  25. package/dist/Transaction.js.map +1 -0
  26. package/dist/adapters/NapiDbAdapter.d.ts +34 -0
  27. package/dist/adapters/NapiDbAdapter.d.ts.map +1 -0
  28. package/dist/adapters/NapiDbAdapter.js +96 -0
  29. package/dist/adapters/NapiDbAdapter.js.map +1 -0
  30. package/dist/config.d.ts +4 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +4 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/configure.d.ts +10 -0
  35. package/dist/configure.d.ts.map +1 -0
  36. package/dist/configure.js +25 -0
  37. package/dist/configure.js.map +1 -0
  38. package/dist/decorators/entity.d.ts +235 -0
  39. package/dist/decorators/entity.d.ts.map +1 -0
  40. package/dist/decorators/entity.js +264 -0
  41. package/dist/decorators/entity.js.map +1 -0
  42. package/dist/decorators/hooks.d.ts +70 -0
  43. package/dist/decorators/hooks.d.ts.map +1 -0
  44. package/dist/decorators/hooks.js +107 -0
  45. package/dist/decorators/hooks.js.map +1 -0
  46. package/dist/decorators/scope.d.ts +35 -0
  47. package/dist/decorators/scope.d.ts.map +1 -0
  48. package/dist/decorators/scope.js +29 -0
  49. package/dist/decorators/scope.js.map +1 -0
  50. package/dist/errors.d.ts +54 -0
  51. package/dist/errors.d.ts.map +1 -0
  52. package/dist/errors.js +82 -0
  53. package/dist/errors.js.map +1 -0
  54. package/dist/index.d.ts +39 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +28 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/naming/NamingStrategy.d.ts +52 -0
  59. package/dist/naming/NamingStrategy.d.ts.map +1 -0
  60. package/dist/naming/NamingStrategy.js +65 -0
  61. package/dist/naming/NamingStrategy.js.map +1 -0
  62. package/dist/query/QueryBuilder.d.ts +95 -0
  63. package/dist/query/QueryBuilder.d.ts.map +1 -0
  64. package/dist/query/QueryBuilder.js +310 -0
  65. package/dist/query/QueryBuilder.js.map +1 -0
  66. package/dist/query/native.d.ts +18 -0
  67. package/dist/query/native.d.ts.map +1 -0
  68. package/dist/query/native.js +49 -0
  69. package/dist/query/native.js.map +1 -0
  70. package/dist/schema/Migration.d.ts +55 -0
  71. package/dist/schema/Migration.d.ts.map +1 -0
  72. package/dist/schema/Migration.js +68 -0
  73. package/dist/schema/Migration.js.map +1 -0
  74. package/dist/schema/MigrationRunner.d.ts +115 -0
  75. package/dist/schema/MigrationRunner.d.ts.map +1 -0
  76. package/dist/schema/MigrationRunner.js +402 -0
  77. package/dist/schema/MigrationRunner.js.map +1 -0
  78. package/dist/schema/Schema.d.ts +22 -0
  79. package/dist/schema/Schema.d.ts.map +1 -0
  80. package/dist/schema/Schema.js +51 -0
  81. package/dist/schema/Schema.js.map +1 -0
  82. package/dist/schema/SchemaBuilder.d.ts +14 -0
  83. package/dist/schema/SchemaBuilder.d.ts.map +1 -0
  84. package/dist/schema/SchemaBuilder.js +13 -0
  85. package/dist/schema/SchemaBuilder.js.map +1 -0
  86. package/dist/schema/Seeder.d.ts +54 -0
  87. package/dist/schema/Seeder.d.ts.map +1 -0
  88. package/dist/schema/Seeder.js +89 -0
  89. package/dist/schema/Seeder.js.map +1 -0
  90. package/dist/schema/TableBuilder.d.ts +86 -0
  91. package/dist/schema/TableBuilder.d.ts.map +1 -0
  92. package/dist/schema/TableBuilder.js +211 -0
  93. package/dist/schema/TableBuilder.js.map +1 -0
  94. package/dist/schema/types.d.ts +28 -0
  95. package/dist/schema/types.d.ts.map +1 -0
  96. package/dist/schema/types.js +19 -0
  97. package/dist/schema/types.js.map +1 -0
  98. package/dist/services/db.d.ts +22 -0
  99. package/dist/services/db.d.ts.map +1 -0
  100. package/dist/services/db.js +37 -0
  101. package/dist/services/db.js.map +1 -0
  102. package/dist/testing/DatabaseCleanup.d.ts +19 -0
  103. package/dist/testing/DatabaseCleanup.d.ts.map +1 -0
  104. package/dist/testing/DatabaseCleanup.js +40 -0
  105. package/dist/testing/DatabaseCleanup.js.map +1 -0
  106. package/dist/testing/Factory.d.ts +59 -0
  107. package/dist/testing/Factory.d.ts.map +1 -0
  108. package/dist/testing/Factory.js +105 -0
  109. package/dist/testing/Factory.js.map +1 -0
  110. package/dist/testing/TestDatabase.d.ts +25 -0
  111. package/dist/testing/TestDatabase.d.ts.map +1 -0
  112. package/dist/testing/TestDatabase.js +52 -0
  113. package/dist/testing/TestDatabase.js.map +1 -0
  114. package/dist/testing/index.d.ts +4 -0
  115. package/dist/testing/index.d.ts.map +1 -0
  116. package/dist/testing/index.js +4 -0
  117. package/dist/testing/index.js.map +1 -0
  118. package/dist/utils/casing.d.ts +5 -0
  119. package/dist/utils/casing.d.ts.map +1 -0
  120. package/dist/utils/casing.js +9 -0
  121. package/dist/utils/casing.js.map +1 -0
  122. package/dist/utils/dialectFromUrl.d.ts +10 -0
  123. package/dist/utils/dialectFromUrl.d.ts.map +1 -0
  124. package/dist/utils/dialectFromUrl.js +8 -0
  125. package/dist/utils/dialectFromUrl.js.map +1 -0
  126. package/dist/utils/identifier.d.ts +19 -0
  127. package/dist/utils/identifier.d.ts.map +1 -0
  128. package/dist/utils/identifier.js +27 -0
  129. package/dist/utils/identifier.js.map +1 -0
  130. package/dist/utils/safePath.d.ts +22 -0
  131. package/dist/utils/safePath.d.ts.map +1 -0
  132. package/dist/utils/safePath.js +46 -0
  133. package/dist/utils/safePath.js.map +1 -0
  134. package/dist/utils/transactionBrand.d.ts +5 -0
  135. package/dist/utils/transactionBrand.d.ts.map +1 -0
  136. package/dist/utils/transactionBrand.js +5 -0
  137. package/dist/utils/transactionBrand.js.map +1 -0
  138. package/index.darwin-arm64.node +0 -0
  139. package/index.darwin-x64.node +0 -0
  140. package/index.linux-arm64-gnu.node +0 -0
  141. package/index.linux-x64-gnu.node +0 -0
  142. package/index.win32-x64-msvc.node +0 -0
  143. package/package.json +1 -1
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Seeder — populate the database with default / reference / test data.
3
+ *
4
+ * The canonical pattern:
5
+ *
6
+ * export default class CountrySeeder extends BaseSeeder {
7
+ * async run() {
8
+ * // Idempotent via updateOrCreateMany — safe to re-run.
9
+ * await Country.updateOrCreateMany('isoCode', [
10
+ * { isoCode: 'FR', name: 'France' },
11
+ * { isoCode: 'IN', name: 'India' },
12
+ * ])
13
+ * }
14
+ * }
15
+ *
16
+ * @implements MISS-4, Story 32.12
17
+ */
18
+ import * as fsp from "node:fs/promises";
19
+ import { pathToFileURL } from "node:url";
20
+ import { AtlasError } from "../errors.js";
21
+ import { assertPathInsideBase, assertSafeName, pathExists, } from "../utils/safePath.js";
22
+ /**
23
+ * Base class for all seeders.
24
+ *
25
+ * Subclasses receive the database connection via the constructor so they can
26
+ * build repositories inside `run()` without resorting to globals.
27
+ */
28
+ export class BaseSeeder {
29
+ db;
30
+ constructor(db) {
31
+ this.db = db;
32
+ }
33
+ }
34
+ /** Legacy alias kept for code using the previous API. */
35
+ export const Seeder = BaseSeeder;
36
+ /**
37
+ * Run a pre-built list of seeder INSTANCES in order. Each `run()` is awaited
38
+ * sequentially so ordering is deterministic and side effects are visible to
39
+ * subsequent seeders.
40
+ */
41
+ export async function runSeeders(seeders, _db) {
42
+ for (const seeder of seeders) {
43
+ await seeder.run();
44
+ }
45
+ }
46
+ /**
47
+ * Discover seeder files under `dir`, import them in alphabetical order, build
48
+ * instances with the given DB connection, and run them sequentially.
49
+ *
50
+ * Usage: `await runSeederDirectory('./database/seeders', db)`
51
+ *
52
+ * @param dir Directory containing `.ts` / `.js` seeder files
53
+ * @param db Database connection passed to each seeder constructor
54
+ * @param options Optional filter (`files: ['CountrySeeder']`) to run a subset
55
+ *
56
+ * @implements Story 32.12
57
+ */
58
+ export async function runSeederDirectory(dir, db, options) {
59
+ if (!(await pathExists(dir))) {
60
+ throw new AtlasError("E_SEEDER_DIR_NOT_FOUND", `Seeder directory not found: ${dir}`, {
61
+ hint: "Create the directory or adjust the path passed to runSeederDirectory.",
62
+ });
63
+ }
64
+ const allFiles = (await fsp.readdir(dir))
65
+ .filter((f) => (f.endsWith(".ts") || f.endsWith(".js")) && !f.endsWith(".d.ts"))
66
+ .sort();
67
+ const selected = options?.files
68
+ ? allFiles.filter((f) => options.files?.includes(f.replace(/\.(ts|js)$/, "")))
69
+ : allFiles;
70
+ const executed = [];
71
+ for (const file of selected) {
72
+ assertSafeName(file, "E_SEEDER_INVALID", "seeder");
73
+ const resolved = assertPathInsideBase(dir, file, "E_SEEDER_INVALID_PATH", "Seeder");
74
+ // `pathToFileURL` is required on Windows where bare `C:\…` paths
75
+ // trip ESM's ERR_UNSUPPORTED_ESM_URL_SCHEME on dynamic import.
76
+ const mod = await import(pathToFileURL(resolved).href);
77
+ const SeederClass = mod.default;
78
+ if (!SeederClass || typeof SeederClass !== "function") {
79
+ throw new AtlasError("E_SEEDER_INVALID", `Seeder ${file} must export a default class extending BaseSeeder`, {
80
+ hint: "Example: `export default class UserSeeder extends BaseSeeder { async run() { ... } }`",
81
+ });
82
+ }
83
+ const instance = new SeederClass(db);
84
+ await instance.run();
85
+ executed.push(file.replace(/\.(ts|js)$/, ""));
86
+ }
87
+ return executed;
88
+ }
89
+ //# sourceMappingURL=Seeder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Seeder.js","sourceRoot":"","sources":["../../src/schema/Seeder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACN,oBAAoB,EACpB,cAAc,EACd,UAAU,GACV,MAAM,sBAAsB,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,OAAgB,UAAU;IACrB,EAAE,CAAqB;IAEjC,YAAY,EAAsB;QACjC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,CAAC;CAID;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,OAAqB,EACrB,GAAwB;IAExB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACpB,CAAC;AACF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,GAAW,EACX,EAAsB,EACtB,OAAuC;IAEvC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CACnB,wBAAwB,EACxB,+BAA+B,GAAG,EAAE,EACpC;YACC,IAAI,EAAE,uEAAuE;SAC7E,CACD,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;SACvC,MAAM,CACN,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CACvE;SACA,IAAI,EAAE,CAAC;IAET,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAK;QAC9B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CACpD;QACF,CAAC,CAAC,QAAQ,CAAC;IAEZ,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7B,cAAc,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,oBAAoB,CACpC,GAAG,EACH,IAAI,EACJ,uBAAuB,EACvB,QAAQ,CACR,CAAC;QAEF,iEAAiE;QACjE,+DAA+D;QAC/D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;YACvD,MAAM,IAAI,UAAU,CACnB,kBAAkB,EAClB,UAAU,IAAI,mDAAmD,EACjE;gBACC,IAAI,EAAE,uFAAuF;aAC7F,CACD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAe,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * TableBuilder — fluent column/index builder used inside `Schema.createTable()`.
3
+ *
4
+ * Builds an in-memory column/index spec, then delegates SQL generation to the
5
+ * Rust compiler via `compileStatementNative`. No SQL strings are produced in TS.
6
+ *
7
+ * @implements FR34
8
+ */
9
+ import { type AtlasDialect } from "../query/native.js";
10
+ import { type ColumnDefinition, type IndexDefinition } from "./types.js";
11
+ /** Table builder — used inside `schema.createTable(name, callback)`. */
12
+ export declare class TableBuilder {
13
+ #private;
14
+ readonly tableName: string;
15
+ constructor(tableName: string);
16
+ uuid(name: string): this;
17
+ string(name: string, length?: number): this;
18
+ text(name: string): this;
19
+ integer(name: string): this;
20
+ bigInteger(name: string): this;
21
+ decimal(name: string, precision?: number, scale?: number): this;
22
+ boolean(name: string): this;
23
+ date(name: string): this;
24
+ timestamp(name: string): this;
25
+ json(name: string): this;
26
+ binary(name: string): this;
27
+ /**
28
+ * UUID primary key with Postgres-only `gen_random_uuid()` default.
29
+ *
30
+ * **Portability warning — DO NOT use in framework-shipped migration templates.**
31
+ *
32
+ * `gen_random_uuid()` is a Postgres-13+ built-in. SQLite and MySQL do NOT
33
+ * provide a function by that name; calling `id()` in a migration that
34
+ * runs on those dialects fails at `migrations:run` with a "no such
35
+ * function" error. The helper is retained for user-app migrations where
36
+ * the target dialect is known to be Postgres.
37
+ *
38
+ * In framework-shipped templates, write the column explicitly and supply
39
+ * the UUID at INSERT time:
40
+ *
41
+ * t.uuid('id').primary() // no DEFAULT
42
+ * // and at insert: db.insert({ id: crypto.randomUUID(), ... })
43
+ *
44
+ * See `AUDIT-migration-templates.md` (shipped at the package root) for
45
+ * the full audit and the escape-hatch procedure if a future story makes
46
+ * the helper dialect-aware.
47
+ */
48
+ id(): this;
49
+ /**
50
+ * `created_at` + `updated_at` columns with Postgres-only `DEFAULT NOW()`.
51
+ *
52
+ * **Portability warning — DO NOT use in framework-shipped migration templates.**
53
+ *
54
+ * `NOW()` is a Postgres/MySQL function — SQLite does NOT recognise it
55
+ * (SQLite accepts `CURRENT_TIMESTAMP`, not `NOW()`). Calling
56
+ * `timestamps()` in a migration that runs on SQLite fails at
57
+ * `migrations:run` with a "no such function" error. The helper is
58
+ * retained for user-app migrations where the target dialect is known to
59
+ * be Postgres or MySQL.
60
+ *
61
+ * In framework-shipped templates, write the columns explicitly without a
62
+ * DEFAULT and supply the value at INSERT/UPSERT time:
63
+ *
64
+ * t.timestamp('created_at').notNullable() // no DEFAULT
65
+ * t.timestamp('updated_at').notNullable()
66
+ * // and at insert: db.insert({ created_at: new Date().toISOString(), ... })
67
+ *
68
+ * See `AUDIT-migration-templates.md` (shipped at the package root) for
69
+ * the full audit and the escape-hatch procedure if a future story makes
70
+ * the helper dialect-aware.
71
+ */
72
+ timestamps(): this;
73
+ primary(): this;
74
+ notNullable(): this;
75
+ nullable(): this;
76
+ unique(): this;
77
+ defaultTo(value: string): this;
78
+ references(table: string, column?: string): this;
79
+ index(columns: string | string[], name?: string): this;
80
+ uniqueIndex(columns: string | string[], name?: string): this;
81
+ getColumns(): ColumnDefinition[];
82
+ getIndexes(): IndexDefinition[];
83
+ /** Compile to SQL statements via the Rust compiler. */
84
+ toStatements(dialect?: AtlasDialect): string[];
85
+ }
86
+ //# sourceMappingURL=TableBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableBuilder.d.ts","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACN,KAAK,YAAY,EAGjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,eAAe,EAEpB,MAAM,YAAY,CAAC;AAEpB,wEAAwE;AACxE,qBAAa,YAAY;;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAKf,SAAS,EAAE,MAAM;IAM7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,IAAI;IAMxC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAGxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAG3B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAK,EAAE,KAAK,SAAI,GAAG,IAAI;IAStD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAG3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAGxB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAG7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAGxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,EAAE,IAAI,IAAI;IAIV;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,IAAI,IAAI;IAQlB,OAAO,IAAI,IAAI;IAKf,WAAW,IAAI,IAAI;IAKnB,QAAQ,IAAI,IAAI;IAKhB,MAAM,IAAI,IAAI;IAKd,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,IAAI;IAO9C,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAUtD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAY5D,UAAU,IAAI,gBAAgB,EAAE;IAGhC,UAAU,IAAI,eAAe,EAAE;IAI/B,uDAAuD;IACvD,YAAY,CAAC,OAAO,GAAE,YAAgC,GAAG,MAAM,EAAE;CAsCjE"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * TableBuilder — fluent column/index builder used inside `Schema.createTable()`.
3
+ *
4
+ * Builds an in-memory column/index spec, then delegates SQL generation to the
5
+ * Rust compiler via `compileStatementNative`. No SQL strings are produced in TS.
6
+ *
7
+ * @implements FR34
8
+ */
9
+ import { compileStatementNative, getAtlasDialect, } from "../query/native.js";
10
+ import { TYPE_KIND_MAP, } from "./types.js";
11
+ /** Table builder — used inside `schema.createTable(name, callback)`. */
12
+ export class TableBuilder {
13
+ tableName;
14
+ #columns = [];
15
+ #indexes = [];
16
+ #currentColumn;
17
+ constructor(tableName) {
18
+ this.tableName = tableName;
19
+ }
20
+ // ─── Column types ─────────────────────────────────────────
21
+ uuid(name) {
22
+ return this.#addColumn(name, "uuid");
23
+ }
24
+ string(name, length = 255) {
25
+ this.#addColumn(name, "string");
26
+ if (this.#currentColumn)
27
+ this.#currentColumn.length = length;
28
+ return this;
29
+ }
30
+ text(name) {
31
+ return this.#addColumn(name, "text");
32
+ }
33
+ integer(name) {
34
+ return this.#addColumn(name, "integer");
35
+ }
36
+ bigInteger(name) {
37
+ return this.#addColumn(name, "bigInteger");
38
+ }
39
+ decimal(name, precision = 10, scale = 2) {
40
+ this.#addColumn(name, "decimal");
41
+ if (this.#currentColumn) {
42
+ this.#currentColumn.precision = precision;
43
+ this.#currentColumn.scale = scale;
44
+ }
45
+ return this;
46
+ }
47
+ boolean(name) {
48
+ return this.#addColumn(name, "boolean");
49
+ }
50
+ date(name) {
51
+ return this.#addColumn(name, "date");
52
+ }
53
+ timestamp(name) {
54
+ return this.#addColumn(name, "timestamp");
55
+ }
56
+ json(name) {
57
+ return this.#addColumn(name, "json");
58
+ }
59
+ binary(name) {
60
+ return this.#addColumn(name, "binary");
61
+ }
62
+ // ─── Shortcuts ────────────────────────────────────────────
63
+ /**
64
+ * UUID primary key with Postgres-only `gen_random_uuid()` default.
65
+ *
66
+ * **Portability warning — DO NOT use in framework-shipped migration templates.**
67
+ *
68
+ * `gen_random_uuid()` is a Postgres-13+ built-in. SQLite and MySQL do NOT
69
+ * provide a function by that name; calling `id()` in a migration that
70
+ * runs on those dialects fails at `migrations:run` with a "no such
71
+ * function" error. The helper is retained for user-app migrations where
72
+ * the target dialect is known to be Postgres.
73
+ *
74
+ * In framework-shipped templates, write the column explicitly and supply
75
+ * the UUID at INSERT time:
76
+ *
77
+ * t.uuid('id').primary() // no DEFAULT
78
+ * // and at insert: db.insert({ id: crypto.randomUUID(), ... })
79
+ *
80
+ * See `AUDIT-migration-templates.md` (shipped at the package root) for
81
+ * the full audit and the escape-hatch procedure if a future story makes
82
+ * the helper dialect-aware.
83
+ */
84
+ id() {
85
+ return this.uuid("id").primary().defaultTo("gen_random_uuid()");
86
+ }
87
+ /**
88
+ * `created_at` + `updated_at` columns with Postgres-only `DEFAULT NOW()`.
89
+ *
90
+ * **Portability warning — DO NOT use in framework-shipped migration templates.**
91
+ *
92
+ * `NOW()` is a Postgres/MySQL function — SQLite does NOT recognise it
93
+ * (SQLite accepts `CURRENT_TIMESTAMP`, not `NOW()`). Calling
94
+ * `timestamps()` in a migration that runs on SQLite fails at
95
+ * `migrations:run` with a "no such function" error. The helper is
96
+ * retained for user-app migrations where the target dialect is known to
97
+ * be Postgres or MySQL.
98
+ *
99
+ * In framework-shipped templates, write the columns explicitly without a
100
+ * DEFAULT and supply the value at INSERT/UPSERT time:
101
+ *
102
+ * t.timestamp('created_at').notNullable() // no DEFAULT
103
+ * t.timestamp('updated_at').notNullable()
104
+ * // and at insert: db.insert({ created_at: new Date().toISOString(), ... })
105
+ *
106
+ * See `AUDIT-migration-templates.md` (shipped at the package root) for
107
+ * the full audit and the escape-hatch procedure if a future story makes
108
+ * the helper dialect-aware.
109
+ */
110
+ timestamps() {
111
+ this.timestamp("created_at").notNullable().defaultTo("NOW()");
112
+ this.timestamp("updated_at").notNullable().defaultTo("NOW()");
113
+ return this;
114
+ }
115
+ // ─── Column modifiers ─────────────────────────────────────
116
+ primary() {
117
+ if (this.#currentColumn)
118
+ this.#currentColumn.primary = true;
119
+ return this;
120
+ }
121
+ notNullable() {
122
+ if (this.#currentColumn)
123
+ this.#currentColumn.nullable = false;
124
+ return this;
125
+ }
126
+ nullable() {
127
+ if (this.#currentColumn)
128
+ this.#currentColumn.nullable = true;
129
+ return this;
130
+ }
131
+ unique() {
132
+ if (this.#currentColumn)
133
+ this.#currentColumn.unique = true;
134
+ return this;
135
+ }
136
+ defaultTo(value) {
137
+ if (this.#currentColumn)
138
+ this.#currentColumn.defaultValue = value;
139
+ return this;
140
+ }
141
+ references(table, column = "id") {
142
+ if (this.#currentColumn)
143
+ this.#currentColumn.references = { table, column };
144
+ return this;
145
+ }
146
+ // ─── Indexes ──────────────────────────────────────────────
147
+ index(columns, name) {
148
+ const cols = Array.isArray(columns) ? columns : [columns];
149
+ this.#indexes.push({
150
+ name: name ?? `idx_${this.tableName}_${cols.join("_")}`,
151
+ columns: cols,
152
+ unique: false,
153
+ });
154
+ return this;
155
+ }
156
+ uniqueIndex(columns, name) {
157
+ const cols = Array.isArray(columns) ? columns : [columns];
158
+ this.#indexes.push({
159
+ name: name ?? `idx_${this.tableName}_${cols.join("_")}_unique`,
160
+ columns: cols,
161
+ unique: true,
162
+ });
163
+ return this;
164
+ }
165
+ // ─── Accessors ────────────────────────────────────────────
166
+ getColumns() {
167
+ return [...this.#columns];
168
+ }
169
+ getIndexes() {
170
+ return [...this.#indexes];
171
+ }
172
+ /** Compile to SQL statements via the Rust compiler. */
173
+ toStatements(dialect = getAtlasDialect()) {
174
+ const spec = {
175
+ kind: "createTable",
176
+ table: this.tableName,
177
+ columns: this.#columns.map((c) => ({
178
+ name: c.name,
179
+ kind: TYPE_KIND_MAP[c.type],
180
+ length: c.length ?? null,
181
+ precision: c.precision ?? null,
182
+ scale: c.scale ?? null,
183
+ nullable: c.nullable,
184
+ primary: c.primary,
185
+ unique: c.unique,
186
+ default: c.defaultValue ?? null,
187
+ references: c.references ?? null,
188
+ })),
189
+ indexes: this.#indexes.map((i) => ({
190
+ name: i.name,
191
+ columns: i.columns,
192
+ unique: i.unique,
193
+ })),
194
+ ifNotExists: false,
195
+ };
196
+ return compileStatementNative(spec, dialect).statements;
197
+ }
198
+ #addColumn(name, type) {
199
+ const col = {
200
+ name,
201
+ type,
202
+ nullable: true,
203
+ primary: false,
204
+ unique: false,
205
+ };
206
+ this.#columns.push(col);
207
+ this.#currentColumn = col;
208
+ return this;
209
+ }
210
+ }
211
+ //# sourceMappingURL=TableBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableBuilder.js","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared schema types — column type names, definitions, and the
3
+ * mapping from logical TS types to the Rust ColumnTypeKind.
4
+ */
5
+ export type ColumnType = "string" | "text" | "integer" | "bigInteger" | "decimal" | "boolean" | "date" | "timestamp" | "uuid" | "json" | "binary";
6
+ /** Maps our logical type names to the ColumnTypeKind expected by the Rust compiler. */
7
+ export declare const TYPE_KIND_MAP: Record<ColumnType, string>;
8
+ export interface ColumnDefinition {
9
+ name: string;
10
+ type: ColumnType;
11
+ length?: number;
12
+ precision?: number;
13
+ scale?: number;
14
+ nullable: boolean;
15
+ primary: boolean;
16
+ unique: boolean;
17
+ defaultValue?: string;
18
+ references?: {
19
+ table: string;
20
+ column: string;
21
+ };
22
+ }
23
+ export interface IndexDefinition {
24
+ name: string;
25
+ columns: string[];
26
+ unique: boolean;
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,UAAU,GACnB,QAAQ,GACR,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,SAAS,GACT,MAAM,GACN,WAAW,GACX,MAAM,GACN,MAAM,GACN,QAAQ,CAAC;AAEZ,uFAAuF;AACvF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAYpD,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Shared schema types — column type names, definitions, and the
3
+ * mapping from logical TS types to the Rust ColumnTypeKind.
4
+ */
5
+ /** Maps our logical type names to the ColumnTypeKind expected by the Rust compiler. */
6
+ export const TYPE_KIND_MAP = {
7
+ string: "string",
8
+ text: "text",
9
+ integer: "integer",
10
+ bigInteger: "bigInteger",
11
+ decimal: "decimal",
12
+ boolean: "boolean",
13
+ date: "date",
14
+ timestamp: "timestamp",
15
+ uuid: "uuid",
16
+ json: "json",
17
+ binary: "binary",
18
+ };
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,uFAAuF;AACvF,MAAM,CAAC,MAAM,aAAa,GAA+B;IACxD,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;CAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Default `db` singleton — Adonis Lucid–style ergonomic access to the
3
+ * configured database connection.
4
+ *
5
+ * import db from '@c9up/atlas/services/db'
6
+ *
7
+ * const rows = await db.query('SELECT * FROM users WHERE id = ?', [id])
8
+ *
9
+ * Populated by `AtlasProvider.boot()`. The instance is whatever the
10
+ * `database.connections[default]` config block resolves to (typically
11
+ * a `NapiDbAdapter` wrapping the Rust sqlite driver, but apps can
12
+ * swap in a custom `AsyncDatabaseConnection` through the provider's
13
+ * container hooks).
14
+ */
15
+ import type { AsyncDatabaseConnection } from "../adapters/NapiDbAdapter.js";
16
+ /** @internal Bind the singleton (called by AtlasProvider). */
17
+ export declare function setDb(connection: AsyncDatabaseConnection): void;
18
+ /** @internal Read the singleton (or `undefined` pre-boot). */
19
+ export declare function getDb(): AsyncDatabaseConnection | undefined;
20
+ declare const db: AsyncDatabaseConnection;
21
+ export default db;
22
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/services/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAI5E,8DAA8D;AAC9D,wBAAgB,KAAK,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAE/D;AAED,8DAA8D;AAC9D,wBAAgB,KAAK,IAAI,uBAAuB,GAAG,SAAS,CAE3D;AAED,QAAA,MAAM,EAAE,EAAE,uBAaR,CAAC;AAEH,eAAe,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Default `db` singleton — Adonis Lucid–style ergonomic access to the
3
+ * configured database connection.
4
+ *
5
+ * import db from '@c9up/atlas/services/db'
6
+ *
7
+ * const rows = await db.query('SELECT * FROM users WHERE id = ?', [id])
8
+ *
9
+ * Populated by `AtlasProvider.boot()`. The instance is whatever the
10
+ * `database.connections[default]` config block resolves to (typically
11
+ * a `NapiDbAdapter` wrapping the Rust sqlite driver, but apps can
12
+ * swap in a custom `AsyncDatabaseConnection` through the provider's
13
+ * container hooks).
14
+ */
15
+ let instance;
16
+ /** @internal Bind the singleton (called by AtlasProvider). */
17
+ export function setDb(connection) {
18
+ instance = connection;
19
+ }
20
+ /** @internal Read the singleton (or `undefined` pre-boot). */
21
+ export function getDb() {
22
+ return instance;
23
+ }
24
+ const db = new Proxy({}, {
25
+ get(_target, prop) {
26
+ if (!instance) {
27
+ throw new Error("[atlas] db singleton accessed before AtlasProvider.boot() ran. " +
28
+ "Check that `@c9up/atlas/provider` is listed in your reamrc.ts " +
29
+ "providers and that `config/database.ts` defines at least one " +
30
+ "connection.");
31
+ }
32
+ const value = Reflect.get(instance, prop, instance);
33
+ return typeof value === "function" ? value.bind(instance) : value;
34
+ },
35
+ });
36
+ export default db;
37
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/services/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,IAAI,QAA6C,CAAC;AAElD,8DAA8D;AAC9D,MAAM,UAAU,KAAK,CAAC,UAAmC;IACxD,QAAQ,GAAG,UAAU,CAAC;AACvB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,KAAK;IACpB,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,EAAE,GAA4B,IAAI,KAAK,CAAC,EAA6B,EAAE;IAC5E,GAAG,CAAC,OAAO,EAAE,IAAI;QAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACd,iEAAiE;gBAChE,gEAAgE;gBAChE,+DAA+D;gBAC/D,aAAa,CACd,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACnE,CAAC;CACD,CAAC,CAAC;AAEH,eAAe,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Database cleanup utilities for testing.
3
+ *
4
+ * @implements MISS-19
5
+ */
6
+ import type { AsyncDatabaseConnection } from "../adapters/NapiDbAdapter.js";
7
+ /**
8
+ * Wrap a test in a savepoint that is rolled back after.
9
+ */
10
+ export declare function useTransaction(db: AsyncDatabaseConnection): Promise<() => Promise<void>>;
11
+ /**
12
+ * Truncate all user tables (excludes _migrations and internal tables).
13
+ *
14
+ * The SELECT on `sqlite_master` is SQLite-specific introspection and is kept
15
+ * as raw SQL intentionally — it's not a user query. The resulting DELETEs
16
+ * go through the Rust compiler.
17
+ */
18
+ export declare function truncateAll(db: AsyncDatabaseConnection): Promise<void>;
19
+ //# sourceMappingURL=DatabaseCleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseCleanup.d.ts","sourceRoot":"","sources":["../../src/testing/DatabaseCleanup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAG5E;;GAEG;AACH,wBAAsB,cAAc,CACnC,EAAE,EAAE,uBAAuB,GACzB,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAM9B;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,EAAE,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB5E"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Database cleanup utilities for testing.
3
+ *
4
+ * @implements MISS-19
5
+ */
6
+ import { compileStatementNative, getAtlasDialect } from "../query/native.js";
7
+ /**
8
+ * Wrap a test in a savepoint that is rolled back after.
9
+ */
10
+ export async function useTransaction(db) {
11
+ await db.execute("SAVEPOINT test_savepoint");
12
+ return async () => {
13
+ await db.execute("ROLLBACK TO SAVEPOINT test_savepoint");
14
+ await db.execute("RELEASE SAVEPOINT test_savepoint");
15
+ };
16
+ }
17
+ /**
18
+ * Truncate all user tables (excludes _migrations and internal tables).
19
+ *
20
+ * The SELECT on `sqlite_master` is SQLite-specific introspection and is kept
21
+ * as raw SQL intentionally — it's not a user query. The resulting DELETEs
22
+ * go through the Rust compiler.
23
+ */
24
+ export async function truncateAll(db) {
25
+ // SQL LIKE `_` is a single-char wildcard, not a literal underscore.
26
+ // `NOT LIKE '_%'` without `ESCAPE` matches NOTHING (every non-empty name
27
+ // matches `_%`). The `ESCAPE '\'` clause makes `\_` a literal underscore,
28
+ // so the exclusion targets only names starting with `_` (the convention
29
+ // for framework-private tables, including `_migrations`).
30
+ const tables = await db.query("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE '\\_%' ESCAPE '\\' AND name NOT LIKE 'sqlite_%'");
31
+ const dialect = getAtlasDialect();
32
+ for (const row of tables) {
33
+ const name = row.name;
34
+ if (typeof name !== "string")
35
+ continue;
36
+ const compiled = compileStatementNative({ kind: "delete", table: name, wheres: [] }, dialect);
37
+ await db.execute(compiled.statements[0], compiled.params);
38
+ }
39
+ }
40
+ //# sourceMappingURL=DatabaseCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseCleanup.js","sourceRoot":"","sources":["../../src/testing/DatabaseCleanup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE7E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,EAA2B;IAE3B,MAAM,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC7C,OAAO,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAA2B;IAC5D,oEAAoE;IACpE,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,0DAA0D;IAC1D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAC5B,qHAAqH,CACrH,CAAC;IACF,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,SAAS;QACvC,MAAM,QAAQ,GAAG,sBAAsB,CACtC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAC3C,OAAO,CACP,CAAC;QACF,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;AACF,CAAC"}