@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.
- package/db.darwin-arm64.node +0 -0
- package/db.darwin-x64.node +0 -0
- package/db.linux-arm64-gnu.node +0 -0
- package/db.linux-x64-gnu.node +0 -0
- package/db.win32-x64-msvc.node +0 -0
- package/dist/AtlasProvider.d.ts +106 -0
- package/dist/AtlasProvider.d.ts.map +1 -0
- package/dist/AtlasProvider.js +190 -0
- package/dist/AtlasProvider.js.map +1 -0
- package/dist/BaseEntity.d.ts +255 -0
- package/dist/BaseEntity.d.ts.map +1 -0
- package/dist/BaseEntity.js +420 -0
- package/dist/BaseEntity.js.map +1 -0
- package/dist/BaseRepository.d.ts +175 -0
- package/dist/BaseRepository.d.ts.map +1 -0
- package/dist/BaseRepository.js +1394 -0
- package/dist/BaseRepository.js.map +1 -0
- package/dist/ModelQuery.d.ts +338 -0
- package/dist/ModelQuery.d.ts.map +1 -0
- package/dist/ModelQuery.js +1598 -0
- package/dist/ModelQuery.js.map +1 -0
- package/dist/Transaction.d.ts +15 -0
- package/dist/Transaction.d.ts.map +1 -0
- package/dist/Transaction.js +67 -0
- package/dist/Transaction.js.map +1 -0
- package/dist/adapters/NapiDbAdapter.d.ts +34 -0
- package/dist/adapters/NapiDbAdapter.d.ts.map +1 -0
- package/dist/adapters/NapiDbAdapter.js +96 -0
- package/dist/adapters/NapiDbAdapter.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -0
- package/dist/configure.d.ts +10 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +25 -0
- package/dist/configure.js.map +1 -0
- package/dist/decorators/entity.d.ts +235 -0
- package/dist/decorators/entity.d.ts.map +1 -0
- package/dist/decorators/entity.js +264 -0
- package/dist/decorators/entity.js.map +1 -0
- package/dist/decorators/hooks.d.ts +70 -0
- package/dist/decorators/hooks.d.ts.map +1 -0
- package/dist/decorators/hooks.js +107 -0
- package/dist/decorators/hooks.js.map +1 -0
- package/dist/decorators/scope.d.ts +35 -0
- package/dist/decorators/scope.d.ts.map +1 -0
- package/dist/decorators/scope.js +29 -0
- package/dist/decorators/scope.js.map +1 -0
- package/dist/errors.d.ts +54 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +82 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/naming/NamingStrategy.d.ts +52 -0
- package/dist/naming/NamingStrategy.d.ts.map +1 -0
- package/dist/naming/NamingStrategy.js +65 -0
- package/dist/naming/NamingStrategy.js.map +1 -0
- package/dist/query/QueryBuilder.d.ts +95 -0
- package/dist/query/QueryBuilder.d.ts.map +1 -0
- package/dist/query/QueryBuilder.js +310 -0
- package/dist/query/QueryBuilder.js.map +1 -0
- package/dist/query/native.d.ts +18 -0
- package/dist/query/native.d.ts.map +1 -0
- package/dist/query/native.js +49 -0
- package/dist/query/native.js.map +1 -0
- package/dist/schema/Migration.d.ts +55 -0
- package/dist/schema/Migration.d.ts.map +1 -0
- package/dist/schema/Migration.js +68 -0
- package/dist/schema/Migration.js.map +1 -0
- package/dist/schema/MigrationRunner.d.ts +115 -0
- package/dist/schema/MigrationRunner.d.ts.map +1 -0
- package/dist/schema/MigrationRunner.js +402 -0
- package/dist/schema/MigrationRunner.js.map +1 -0
- package/dist/schema/Schema.d.ts +22 -0
- package/dist/schema/Schema.d.ts.map +1 -0
- package/dist/schema/Schema.js +51 -0
- package/dist/schema/Schema.js.map +1 -0
- package/dist/schema/SchemaBuilder.d.ts +14 -0
- package/dist/schema/SchemaBuilder.d.ts.map +1 -0
- package/dist/schema/SchemaBuilder.js +13 -0
- package/dist/schema/SchemaBuilder.js.map +1 -0
- package/dist/schema/Seeder.d.ts +54 -0
- package/dist/schema/Seeder.d.ts.map +1 -0
- package/dist/schema/Seeder.js +89 -0
- package/dist/schema/Seeder.js.map +1 -0
- package/dist/schema/TableBuilder.d.ts +86 -0
- package/dist/schema/TableBuilder.d.ts.map +1 -0
- package/dist/schema/TableBuilder.js +211 -0
- package/dist/schema/TableBuilder.js.map +1 -0
- package/dist/schema/types.d.ts +28 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +19 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/services/db.d.ts +22 -0
- package/dist/services/db.d.ts.map +1 -0
- package/dist/services/db.js +37 -0
- package/dist/services/db.js.map +1 -0
- package/dist/testing/DatabaseCleanup.d.ts +19 -0
- package/dist/testing/DatabaseCleanup.d.ts.map +1 -0
- package/dist/testing/DatabaseCleanup.js +40 -0
- package/dist/testing/DatabaseCleanup.js.map +1 -0
- package/dist/testing/Factory.d.ts +59 -0
- package/dist/testing/Factory.d.ts.map +1 -0
- package/dist/testing/Factory.js +105 -0
- package/dist/testing/Factory.js.map +1 -0
- package/dist/testing/TestDatabase.d.ts +25 -0
- package/dist/testing/TestDatabase.d.ts.map +1 -0
- package/dist/testing/TestDatabase.js +52 -0
- package/dist/testing/TestDatabase.js.map +1 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/utils/casing.d.ts +5 -0
- package/dist/utils/casing.d.ts.map +1 -0
- package/dist/utils/casing.js +9 -0
- package/dist/utils/casing.js.map +1 -0
- package/dist/utils/dialectFromUrl.d.ts +10 -0
- package/dist/utils/dialectFromUrl.d.ts.map +1 -0
- package/dist/utils/dialectFromUrl.js +8 -0
- package/dist/utils/dialectFromUrl.js.map +1 -0
- package/dist/utils/identifier.d.ts +19 -0
- package/dist/utils/identifier.d.ts.map +1 -0
- package/dist/utils/identifier.js +27 -0
- package/dist/utils/identifier.js.map +1 -0
- package/dist/utils/safePath.d.ts +22 -0
- package/dist/utils/safePath.d.ts.map +1 -0
- package/dist/utils/safePath.js +46 -0
- package/dist/utils/safePath.js.map +1 -0
- package/dist/utils/transactionBrand.d.ts +5 -0
- package/dist/utils/transactionBrand.d.ts.map +1 -0
- package/dist/utils/transactionBrand.js +5 -0
- package/dist/utils/transactionBrand.js.map +1 -0
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- 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"}
|