@c9up/atlas 0.1.14 → 0.1.16
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/BaseRepository.d.ts +10 -0
- package/dist/BaseRepository.d.ts.map +1 -1
- package/dist/BaseRepository.js +2 -0
- package/dist/BaseRepository.js.map +1 -1
- package/dist/Transaction.d.ts +2 -1
- package/dist/Transaction.d.ts.map +1 -1
- package/dist/Transaction.js +11 -1
- package/dist/Transaction.js.map +1 -1
- package/dist/adapters/NapiDbAdapter.d.ts +23 -0
- package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
- package/dist/adapters/NapiDbAdapter.js +47 -0
- package/dist/adapters/NapiDbAdapter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/schema/Migration.d.ts +3 -3
- package/dist/schema/Migration.d.ts.map +1 -1
- package/dist/schema/Migration.js +3 -3
- package/dist/schema/Migration.js.map +1 -1
- package/dist/schema/TableBuilder.d.ts.map +1 -1
- package/dist/schema/TableBuilder.js +5 -4
- package/dist/schema/TableBuilder.js.map +1 -1
- package/dist/schema/raw.d.ts +13 -18
- package/dist/schema/raw.d.ts.map +1 -1
- package/dist/schema/raw.js +12 -21
- package/dist/schema/raw.js.map +1 -1
- package/dist/services/db.d.ts +12 -1
- package/dist/services/db.d.ts.map +1 -1
- package/dist/services/db.js +5 -0
- package/dist/services/db.js.map +1 -1
- 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
- package/src/BaseRepository.ts +15 -0
- package/src/Transaction.ts +13 -0
- package/src/adapters/NapiDbAdapter.ts +106 -0
- package/src/index.ts +1 -1
- package/src/schema/Migration.ts +5 -5
- package/src/schema/TableBuilder.ts +5 -4
- package/src/schema/raw.ts +14 -21
- package/src/services/db.ts +17 -1
|
@@ -1 +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;
|
|
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;AAE5B,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,UAAU,CAAC;AACjE,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;;;;;OAKG;IACH,UAAU,CAAC,IAAI,SAAO,GAAG,IAAI;IAI7B,sEAAsE;IACtE,aAAa,CAAC,IAAI,SAAO,GAAG,IAAI;IAIhC,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;;;;;;;;OAQG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAG/B,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;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAOpC,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;CAiDjE"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* @implements FR34
|
|
8
8
|
*/
|
|
9
9
|
import { compileStatementNative, getAtlasDialect, } from "../query/native.js";
|
|
10
|
-
import {
|
|
10
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
11
|
+
import { renderDefaultValue } from "./raw.js";
|
|
11
12
|
import { TYPE_KIND_MAP, } from "./types.js";
|
|
12
13
|
/** Table builder — used inside `schema.createTable(name, callback)`. */
|
|
13
14
|
export class TableBuilder {
|
|
@@ -108,7 +109,7 @@ export class TableBuilder {
|
|
|
108
109
|
* the helper dialect-aware.
|
|
109
110
|
*/
|
|
110
111
|
id() {
|
|
111
|
-
return this.uuid("id").primary().defaultTo(
|
|
112
|
+
return this.uuid("id").primary().defaultTo(new RawSql("gen_random_uuid()"));
|
|
112
113
|
}
|
|
113
114
|
/**
|
|
114
115
|
* `created_at` + `updated_at` columns with Postgres-only `DEFAULT NOW()`.
|
|
@@ -134,8 +135,8 @@ export class TableBuilder {
|
|
|
134
135
|
* the helper dialect-aware.
|
|
135
136
|
*/
|
|
136
137
|
timestamps() {
|
|
137
|
-
this.timestamp("created_at").notNullable().defaultTo(
|
|
138
|
-
this.timestamp("updated_at").notNullable().defaultTo(
|
|
138
|
+
this.timestamp("created_at").notNullable().defaultTo(new RawSql("NOW()"));
|
|
139
|
+
this.timestamp("updated_at").notNullable().defaultTo(new RawSql("NOW()"));
|
|
139
140
|
return this;
|
|
140
141
|
}
|
|
141
142
|
// ─── Column modifiers ─────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableBuilder.js","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEN,sBAAsB,EACtB,eAAe,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"TableBuilder.js","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"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"}
|
package/dist/schema/raw.d.ts
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default-value
|
|
2
|
+
* Default-value rendering for the schema builder — Lucid/Knex semantics.
|
|
3
3
|
*
|
|
4
|
-
* `defaultTo` quotes JS literals and emits raw SQL only when
|
|
5
|
-
*
|
|
4
|
+
* `defaultTo` quotes JS literals and emits raw SQL only when given a `RawSql`
|
|
5
|
+
* (the single raw-expression type atlas uses everywhere, incl. queries),
|
|
6
|
+
* produced in a migration by `this.now()` / `this.raw(...)`:
|
|
6
7
|
*
|
|
7
|
-
* t.text('status').defaultTo('new')
|
|
8
|
-
* t.boolean('active').defaultTo(false)
|
|
9
|
-
* t.integer('count').defaultTo(0)
|
|
10
|
-
* t.uuid('id').defaultTo(raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
11
|
-
* t.timestamp('created_at').defaultTo(this.now())
|
|
8
|
+
* t.text('status').defaultTo('new') // → DEFAULT 'new' (quoted literal)
|
|
9
|
+
* t.boolean('active').defaultTo(false) // → DEFAULT false
|
|
10
|
+
* t.integer('count').defaultTo(0) // → DEFAULT 0
|
|
11
|
+
* t.uuid('id').defaultTo(this.raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
12
|
+
* t.timestamp('created_at').defaultTo(this.now()) // → DEFAULT NOW()/CURRENT_TIMESTAMP
|
|
12
13
|
*
|
|
13
14
|
* Before this, `defaultTo` wrote its argument verbatim, so a bare
|
|
14
15
|
* `defaultTo('new')` produced the invalid `DEFAULT new` and string defaults had
|
|
15
16
|
* to be hand-quoted (`defaultTo("'new'")`) — a footgun Lucid/Knex avoid.
|
|
16
17
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
constructor(sql: string);
|
|
21
|
-
}
|
|
22
|
-
/** Wrap a SQL expression so {@link TableBuilder.defaultTo} emits it verbatim. */
|
|
23
|
-
export declare function raw(sql: string): RawValue;
|
|
24
|
-
/** Accepted `defaultTo` argument: a JS literal or a {@link RawValue}. */
|
|
25
|
-
export type DefaultValue = string | number | boolean | RawValue;
|
|
18
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
19
|
+
/** Accepted `defaultTo` argument: a JS literal or a raw SQL expression. */
|
|
20
|
+
export type DefaultValue = string | number | boolean | RawSql;
|
|
26
21
|
/**
|
|
27
22
|
* Render a `defaultTo` argument to the SQL fragment stored as the column
|
|
28
|
-
* default. Literals are quoted/escaped; {@link
|
|
23
|
+
* default. Literals are quoted/escaped; a {@link RawSql} passes through verbatim.
|
|
29
24
|
*/
|
|
30
25
|
export declare function renderDefaultValue(value: DefaultValue): string;
|
|
31
26
|
//# sourceMappingURL=raw.d.ts.map
|
package/dist/schema/raw.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,2EAA2E;AAC3E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAM9D"}
|
package/dist/schema/raw.js
CHANGED
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default-value
|
|
2
|
+
* Default-value rendering for the schema builder — Lucid/Knex semantics.
|
|
3
3
|
*
|
|
4
|
-
* `defaultTo` quotes JS literals and emits raw SQL only when
|
|
5
|
-
*
|
|
4
|
+
* `defaultTo` quotes JS literals and emits raw SQL only when given a `RawSql`
|
|
5
|
+
* (the single raw-expression type atlas uses everywhere, incl. queries),
|
|
6
|
+
* produced in a migration by `this.now()` / `this.raw(...)`:
|
|
6
7
|
*
|
|
7
|
-
* t.text('status').defaultTo('new')
|
|
8
|
-
* t.boolean('active').defaultTo(false)
|
|
9
|
-
* t.integer('count').defaultTo(0)
|
|
10
|
-
* t.uuid('id').defaultTo(raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
11
|
-
* t.timestamp('created_at').defaultTo(this.now())
|
|
8
|
+
* t.text('status').defaultTo('new') // → DEFAULT 'new' (quoted literal)
|
|
9
|
+
* t.boolean('active').defaultTo(false) // → DEFAULT false
|
|
10
|
+
* t.integer('count').defaultTo(0) // → DEFAULT 0
|
|
11
|
+
* t.uuid('id').defaultTo(this.raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
12
|
+
* t.timestamp('created_at').defaultTo(this.now()) // → DEFAULT NOW()/CURRENT_TIMESTAMP
|
|
12
13
|
*
|
|
13
14
|
* Before this, `defaultTo` wrote its argument verbatim, so a bare
|
|
14
15
|
* `defaultTo('new')` produced the invalid `DEFAULT new` and string defaults had
|
|
15
16
|
* to be hand-quoted (`defaultTo("'new'")`) — a footgun Lucid/Knex avoid.
|
|
16
17
|
*/
|
|
17
|
-
|
|
18
|
-
export class RawValue {
|
|
19
|
-
sql;
|
|
20
|
-
constructor(sql) {
|
|
21
|
-
this.sql = sql;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/** Wrap a SQL expression so {@link TableBuilder.defaultTo} emits it verbatim. */
|
|
25
|
-
export function raw(sql) {
|
|
26
|
-
return new RawValue(sql);
|
|
27
|
-
}
|
|
18
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
28
19
|
/**
|
|
29
20
|
* Render a `defaultTo` argument to the SQL fragment stored as the column
|
|
30
|
-
* default. Literals are quoted/escaped; {@link
|
|
21
|
+
* default. Literals are quoted/escaped; a {@link RawSql} passes through verbatim.
|
|
31
22
|
*/
|
|
32
23
|
export function renderDefaultValue(value) {
|
|
33
|
-
if (value instanceof
|
|
24
|
+
if (value instanceof RawSql)
|
|
34
25
|
return value.sql;
|
|
35
26
|
if (typeof value === "number")
|
|
36
27
|
return String(value);
|
package/dist/schema/raw.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw.js","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"raw.js","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAKlD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAmB;IACrD,IAAI,KAAK,YAAY,MAAM;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,2EAA2E;IAC3E,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AACzC,CAAC"}
|
package/dist/services/db.d.ts
CHANGED
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
* container hooks).
|
|
14
14
|
*/
|
|
15
15
|
import type { AsyncDatabaseConnection } from "../adapters/NapiDbAdapter.js";
|
|
16
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
17
|
+
/** The `db` singleton surface: the bound connection plus the AdonisJS-style `db.raw()` builder. */
|
|
18
|
+
export interface DbService extends AsyncDatabaseConnection {
|
|
19
|
+
/**
|
|
20
|
+
* Build a raw SQL expression — AdonisJS `db.raw()` / `Database.raw()`. Use it
|
|
21
|
+
* for query fragments and for column defaults that are SQL expressions:
|
|
22
|
+
*
|
|
23
|
+
* t.uuid('id').defaultTo(db.raw('gen_random_uuid()'))
|
|
24
|
+
*/
|
|
25
|
+
raw(sql: string, params?: unknown[]): RawSql;
|
|
26
|
+
}
|
|
16
27
|
/** @internal Bind the singleton (called by AtlasProvider). */
|
|
17
28
|
export declare function setDb(connection: AsyncDatabaseConnection): void;
|
|
18
29
|
/**
|
|
@@ -24,6 +35,6 @@ export declare function setDb(connection: AsyncDatabaseConnection): void;
|
|
|
24
35
|
export declare function clearDb(connection: AsyncDatabaseConnection): void;
|
|
25
36
|
/** @internal Read the singleton (or `undefined` pre-boot). */
|
|
26
37
|
export declare function getDb(): AsyncDatabaseConnection | undefined;
|
|
27
|
-
declare const db:
|
|
38
|
+
declare const db: DbService;
|
|
28
39
|
export default db;
|
|
29
40
|
//# sourceMappingURL=db.d.ts.map
|
|
@@ -1 +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;
|
|
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;AAC5E,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,mGAAmG;AACnG,MAAM,WAAW,SAAU,SAAQ,uBAAuB;IACzD;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;CAC7C;AAID,8DAA8D;AAC9D,wBAAgB,KAAK,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAEjE;AAED,8DAA8D;AAC9D,wBAAgB,KAAK,IAAI,uBAAuB,GAAG,SAAS,CAE3D;AAED,QAAA,MAAM,EAAE,EAAE,SAiBR,CAAC;AAEH,eAAe,EAAE,CAAC"}
|
package/dist/services/db.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* swap in a custom `AsyncDatabaseConnection` through the provider's
|
|
13
13
|
* container hooks).
|
|
14
14
|
*/
|
|
15
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
15
16
|
let instance;
|
|
16
17
|
/** @internal Bind the singleton (called by AtlasProvider). */
|
|
17
18
|
export function setDb(connection) {
|
|
@@ -33,6 +34,10 @@ export function getDb() {
|
|
|
33
34
|
}
|
|
34
35
|
const db = new Proxy({}, {
|
|
35
36
|
get(_target, prop) {
|
|
37
|
+
// `raw` is a pure builder (no connection needed) — available pre-boot too.
|
|
38
|
+
if (prop === "raw") {
|
|
39
|
+
return (sql, params = []) => new RawSql(sql, params);
|
|
40
|
+
}
|
|
36
41
|
if (!instance) {
|
|
37
42
|
throw new Error("[atlas] db singleton accessed before AtlasProvider.boot() ran. " +
|
|
38
43
|
"Check that `@c9up/atlas/provider` is listed in your reamrc.ts " +
|
package/dist/services/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/services/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/services/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAalD,IAAI,QAA6C,CAAC;AAElD,8DAA8D;AAC9D,MAAM,UAAU,KAAK,CAAC,UAAmC;IACxD,QAAQ,GAAG,UAAU,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,UAAmC;IAC1D,IAAI,QAAQ,KAAK,UAAU;QAAE,QAAQ,GAAG,SAAS,CAAC;AACnD,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,KAAK;IACpB,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,EAAE,GAAc,IAAI,KAAK,CAAC,EAAe,EAAE;IAChD,GAAG,CAAC,OAAO,EAAE,IAAI;QAChB,2EAA2E;QAC3E,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACpB,OAAO,CAAC,GAAW,EAAE,SAAoB,EAAE,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACzE,CAAC;QACD,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"}
|
package/index.darwin-arm64.node
CHANGED
|
Binary file
|
package/index.darwin-x64.node
CHANGED
|
Binary file
|
|
Binary file
|
package/index.linux-x64-gnu.node
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/BaseRepository.ts
CHANGED
|
@@ -27,7 +27,9 @@ import {
|
|
|
27
27
|
type PrimaryKeyGenerator,
|
|
28
28
|
} from "./decorators/entity.js";
|
|
29
29
|
import { fireHooks } from "./decorators/hooks.js";
|
|
30
|
+
import type { TransactionOptions } from "./adapters/NapiDbAdapter.js";
|
|
30
31
|
import { AtlasError, EntityNotFoundError } from "./errors.js";
|
|
32
|
+
import type { TransactionClient } from "./Transaction.js";
|
|
31
33
|
import { ModelQuery, runWithAtlasInternalBypass } from "./ModelQuery.js";
|
|
32
34
|
import {
|
|
33
35
|
type AtlasDialect,
|
|
@@ -118,6 +120,17 @@ export interface DatabaseConnection {
|
|
|
118
120
|
execute(sql: string, params?: unknown[]): Promise<{ rowsAffected: number }>;
|
|
119
121
|
/** Run a SELECT and return all rows. */
|
|
120
122
|
query<T = Row>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
123
|
+
/**
|
|
124
|
+
* Optional — open an interactive transaction pinned to ONE connection
|
|
125
|
+
* (Lucid's `db.transaction`: manual without a callback, managed with one).
|
|
126
|
+
* Present on napi-backed connections (`createNapiConnection`); absent on
|
|
127
|
+
* minimal/test fakes, which are single-connection anyway so the standalone
|
|
128
|
+
* `transaction()` falls back to issuing BEGIN/COMMIT over this same handle.
|
|
129
|
+
*/
|
|
130
|
+
transaction?<T>(
|
|
131
|
+
callback: (trx: TransactionClient) => Promise<T> | T,
|
|
132
|
+
options?: TransactionOptions,
|
|
133
|
+
): Promise<T>;
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
// ─── Repository ─────────────────────────────────────────────
|
|
@@ -132,6 +145,8 @@ const POSTGRES_CAST_TYPES = new Set([
|
|
|
132
145
|
"uuid",
|
|
133
146
|
"json",
|
|
134
147
|
"jsonb",
|
|
148
|
+
"numeric",
|
|
149
|
+
"decimal",
|
|
135
150
|
]);
|
|
136
151
|
|
|
137
152
|
/**
|
package/src/Transaction.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
|
+
import type { TransactionOptions } from "./adapters/NapiDbAdapter.js";
|
|
8
9
|
import type { DatabaseConnection } from "./BaseRepository.js";
|
|
9
10
|
import {
|
|
10
11
|
isTransactionClient,
|
|
@@ -21,6 +22,7 @@ export interface TransactionClient extends DatabaseConnection {
|
|
|
21
22
|
export async function transaction<T>(
|
|
22
23
|
db: DatabaseConnection,
|
|
23
24
|
callback: (trx: TransactionClient) => Promise<T> | T,
|
|
25
|
+
options?: TransactionOptions,
|
|
24
26
|
): Promise<T> {
|
|
25
27
|
if (isTransactionClient(db)) {
|
|
26
28
|
const name = `sp_${randomBytes(6).toString("hex")}`;
|
|
@@ -53,6 +55,17 @@ export async function transaction<T>(
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
// Pinned interactive transaction (napi-backed): db.transaction() acquires ONE
|
|
59
|
+
// connection and issues BEGIN on it; the managed form commits on success /
|
|
60
|
+
// rolls back on throw, every statement on that same connection. This is the
|
|
61
|
+
// CORRECT path. The BEGIN/COMMIT-over-the-pool fallback below is broken on a
|
|
62
|
+
// pool (each db.execute() picks a different connection, so BEGIN/COMMIT and
|
|
63
|
+
// the statements scatter — no atomicity); it's kept only for minimal
|
|
64
|
+
// single-connection connections that lack db.transaction().
|
|
65
|
+
if (typeof db.transaction === "function") {
|
|
66
|
+
return db.transaction(callback, options);
|
|
67
|
+
}
|
|
68
|
+
|
|
56
69
|
await db.execute("BEGIN", []);
|
|
57
70
|
|
|
58
71
|
const trx: TransactionClient = {
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* NapiDbAdapter — bridges the Rust atlas-db NAPI binding to Atlas.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { TransactionClient } from "../Transaction.js";
|
|
5
6
|
import { dialectFromUrl } from "../utils/dialectFromUrl.js";
|
|
7
|
+
import { TRANSACTION_BRAND } from "../utils/transactionBrand.js";
|
|
6
8
|
|
|
7
9
|
/** One `(sql, params)` pair passed to `runInTransaction`. */
|
|
8
10
|
export interface BatchStatement {
|
|
@@ -10,6 +12,22 @@ export interface BatchStatement {
|
|
|
10
12
|
params?: unknown[];
|
|
11
13
|
}
|
|
12
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Transaction isolation level — Lucid-compatible names. Applied via
|
|
17
|
+
* `SET TRANSACTION ISOLATION LEVEL` on Postgres / MySQL; ignored on SQLite
|
|
18
|
+
* (serializable by default, no such statement — same as Lucid).
|
|
19
|
+
*/
|
|
20
|
+
export type IsolationLevel =
|
|
21
|
+
| "read uncommitted"
|
|
22
|
+
| "read committed"
|
|
23
|
+
| "repeatable read"
|
|
24
|
+
| "serializable";
|
|
25
|
+
|
|
26
|
+
/** Options for {@link AsyncDatabaseConnection.transaction}. Mirrors Lucid. */
|
|
27
|
+
export interface TransactionOptions {
|
|
28
|
+
isolationLevel?: IsolationLevel;
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
/** Async database connection backed by Rust (sqlx). */
|
|
14
32
|
export interface AsyncDatabaseConnection {
|
|
15
33
|
/** The dialect this connection targets — derived from the URL scheme at connect time. */
|
|
@@ -25,15 +43,39 @@ export interface AsyncDatabaseConnection {
|
|
|
25
43
|
* wrap `up()` / `down()` SQL together with the `ream_migrations` bookkeeping.
|
|
26
44
|
*/
|
|
27
45
|
runInTransaction(batch: readonly BatchStatement[]): Promise<number>;
|
|
46
|
+
/**
|
|
47
|
+
* Open an INTERACTIVE transaction pinned to one pooled connection — Lucid's
|
|
48
|
+
* `db.transaction`. Manual when called with no callback (you drive
|
|
49
|
+
* `commit()`/`rollback()`), managed when given one (auto commit on success,
|
|
50
|
+
* rollback on throw). Every `execute`/`query` on the trx runs on that same
|
|
51
|
+
* connection, so a read-then-decide-then-write (gap-free numbering,
|
|
52
|
+
* multi-statement create/update/delete) is genuinely atomic — unlike pulling
|
|
53
|
+
* BEGIN/COMMIT through the pool, which scatters statements across connections.
|
|
54
|
+
*/
|
|
55
|
+
transaction(): Promise<TransactionClient>;
|
|
56
|
+
transaction(options: TransactionOptions): Promise<TransactionClient>;
|
|
57
|
+
transaction<T>(
|
|
58
|
+
callback: (trx: TransactionClient) => Promise<T> | T,
|
|
59
|
+
options?: TransactionOptions,
|
|
60
|
+
): Promise<T>;
|
|
28
61
|
close(): Promise<void>;
|
|
29
62
|
ping(): Promise<void>;
|
|
30
63
|
}
|
|
31
64
|
|
|
65
|
+
/** Shape of the NAPI ReamTransaction handle returned by `ReamDatabase.begin()`. */
|
|
66
|
+
interface NapiReamTransaction {
|
|
67
|
+
query(sql: string, paramsJson: string): Promise<string>;
|
|
68
|
+
execute(sql: string, paramsJson: string): Promise<number>;
|
|
69
|
+
commit(): Promise<void>;
|
|
70
|
+
rollback(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
|
|
32
73
|
/** Shape of the NAPI ReamDatabase class. */
|
|
33
74
|
interface NapiReamDatabase {
|
|
34
75
|
query(sql: string, paramsJson: string): Promise<string>;
|
|
35
76
|
execute(sql: string, paramsJson: string): Promise<number>;
|
|
36
77
|
runInTransaction(batchJson: string): Promise<number>;
|
|
78
|
+
begin(isolationLevel?: string): Promise<NapiReamTransaction>;
|
|
37
79
|
close(): Promise<void>;
|
|
38
80
|
ping(): Promise<void>;
|
|
39
81
|
poolSize(): number;
|
|
@@ -128,8 +170,72 @@ export async function createNapiConnection(
|
|
|
128
170
|
retry?.timeoutMs,
|
|
129
171
|
);
|
|
130
172
|
|
|
173
|
+
// Build a TransactionClient bound to a freshly-acquired, pinned connection.
|
|
174
|
+
// `db.begin()` acquires ONE connection and issues BEGIN on it; every call
|
|
175
|
+
// here routes to that same connection until commit/rollback hands it back.
|
|
176
|
+
async function openPinned(
|
|
177
|
+
isolationLevel?: IsolationLevel,
|
|
178
|
+
): Promise<TransactionClient> {
|
|
179
|
+
const native = await db.begin(isolationLevel);
|
|
180
|
+
return {
|
|
181
|
+
async execute(
|
|
182
|
+
sql: string,
|
|
183
|
+
params: unknown[] = [],
|
|
184
|
+
): Promise<{ rowsAffected: number }> {
|
|
185
|
+
const affected = await native.execute(sql, JSON.stringify(params));
|
|
186
|
+
return { rowsAffected: affected };
|
|
187
|
+
},
|
|
188
|
+
async query<T = Record<string, unknown>>(
|
|
189
|
+
sql: string,
|
|
190
|
+
params: unknown[] = [],
|
|
191
|
+
): Promise<T[]> {
|
|
192
|
+
const json = await native.query(sql, JSON.stringify(params));
|
|
193
|
+
return JSON.parse(json) as T[];
|
|
194
|
+
},
|
|
195
|
+
async commit(): Promise<void> {
|
|
196
|
+
await native.commit();
|
|
197
|
+
},
|
|
198
|
+
async rollback(): Promise<void> {
|
|
199
|
+
await native.rollback();
|
|
200
|
+
},
|
|
201
|
+
isNested: false,
|
|
202
|
+
[TRANSACTION_BRAND]: true,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Lucid-compatible `transaction`: managed when given a callback (auto
|
|
207
|
+
// commit / rollback), manual when not (caller drives commit/rollback).
|
|
208
|
+
function transaction(): Promise<TransactionClient>;
|
|
209
|
+
function transaction(options: TransactionOptions): Promise<TransactionClient>;
|
|
210
|
+
function transaction<T>(
|
|
211
|
+
callback: (trx: TransactionClient) => Promise<T> | T,
|
|
212
|
+
options?: TransactionOptions,
|
|
213
|
+
): Promise<T>;
|
|
214
|
+
async function transaction<T>(
|
|
215
|
+
arg1?: TransactionOptions | ((trx: TransactionClient) => Promise<T> | T),
|
|
216
|
+
arg2?: TransactionOptions,
|
|
217
|
+
): Promise<TransactionClient | T> {
|
|
218
|
+
const callback = typeof arg1 === "function" ? arg1 : undefined;
|
|
219
|
+
const options = typeof arg1 === "function" ? arg2 : arg1;
|
|
220
|
+
const trx = await openPinned(options?.isolationLevel);
|
|
221
|
+
if (!callback) return trx;
|
|
222
|
+
try {
|
|
223
|
+
const result = await callback(trx);
|
|
224
|
+
await trx.commit();
|
|
225
|
+
return result;
|
|
226
|
+
} catch (err) {
|
|
227
|
+
try {
|
|
228
|
+
await trx.rollback();
|
|
229
|
+
} catch {
|
|
230
|
+
/* best-effort */
|
|
231
|
+
}
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
131
236
|
return {
|
|
132
237
|
dialect,
|
|
238
|
+
transaction,
|
|
133
239
|
async query<T = Record<string, unknown>>(
|
|
134
240
|
sql: string,
|
|
135
241
|
params: unknown[] = [],
|
package/src/index.ts
CHANGED
|
@@ -111,7 +111,7 @@ export type {
|
|
|
111
111
|
MigrationStatus,
|
|
112
112
|
} from "./schema/MigrationRunner.js";
|
|
113
113
|
export { MigrationRunner } from "./schema/MigrationRunner.js";
|
|
114
|
-
export {
|
|
114
|
+
export type { DefaultValue } from "./schema/raw.js";
|
|
115
115
|
export type { ColumnDefinition, ColumnType } from "./schema/SchemaBuilder.js";
|
|
116
116
|
export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
|
|
117
117
|
export {
|
package/src/schema/Migration.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { AtlasDialect } from "../query/native.js";
|
|
8
|
-
import {
|
|
8
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
9
9
|
import { Schema } from "./SchemaBuilder.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -48,8 +48,8 @@ export abstract class Migration {
|
|
|
48
48
|
abstract down(): Promise<void> | void;
|
|
49
49
|
|
|
50
50
|
/** Helper: raw SQL expression for a column DEFAULT — emitted verbatim, not quoted. */
|
|
51
|
-
raw(expression: string):
|
|
52
|
-
return new
|
|
51
|
+
raw(expression: string): RawSql {
|
|
52
|
+
return new RawSql(expression);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -63,8 +63,8 @@ export abstract class Migration {
|
|
|
63
63
|
* migrations — `NOW()` is not a recognised function there and the column
|
|
64
64
|
* default would blow up at DDL compile time.
|
|
65
65
|
*/
|
|
66
|
-
now():
|
|
67
|
-
return new
|
|
66
|
+
now(): RawSql {
|
|
67
|
+
return new RawSql(
|
|
68
68
|
this.#dialect === "sqlite" ? "CURRENT_TIMESTAMP" : "NOW()",
|
|
69
69
|
);
|
|
70
70
|
}
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
compileStatementNative,
|
|
13
13
|
getAtlasDialect,
|
|
14
14
|
} from "../query/native.js";
|
|
15
|
-
import {
|
|
15
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
16
|
+
import { type DefaultValue, renderDefaultValue } from "./raw.js";
|
|
16
17
|
import {
|
|
17
18
|
type ColumnDefinition,
|
|
18
19
|
type ColumnType,
|
|
@@ -129,7 +130,7 @@ export class TableBuilder {
|
|
|
129
130
|
* the helper dialect-aware.
|
|
130
131
|
*/
|
|
131
132
|
id(): this {
|
|
132
|
-
return this.uuid("id").primary().defaultTo(
|
|
133
|
+
return this.uuid("id").primary().defaultTo(new RawSql("gen_random_uuid()"));
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
/**
|
|
@@ -156,8 +157,8 @@ export class TableBuilder {
|
|
|
156
157
|
* the helper dialect-aware.
|
|
157
158
|
*/
|
|
158
159
|
timestamps(): this {
|
|
159
|
-
this.timestamp("created_at").notNullable().defaultTo(
|
|
160
|
-
this.timestamp("updated_at").notNullable().defaultTo(
|
|
160
|
+
this.timestamp("created_at").notNullable().defaultTo(new RawSql("NOW()"));
|
|
161
|
+
this.timestamp("updated_at").notNullable().defaultTo(new RawSql("NOW()"));
|
|
161
162
|
return this;
|
|
162
163
|
}
|
|
163
164
|
|
package/src/schema/raw.ts
CHANGED
|
@@ -1,39 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default-value
|
|
2
|
+
* Default-value rendering for the schema builder — Lucid/Knex semantics.
|
|
3
3
|
*
|
|
4
|
-
* `defaultTo` quotes JS literals and emits raw SQL only when
|
|
5
|
-
*
|
|
4
|
+
* `defaultTo` quotes JS literals and emits raw SQL only when given a `RawSql`
|
|
5
|
+
* (the single raw-expression type atlas uses everywhere, incl. queries),
|
|
6
|
+
* produced in a migration by `this.now()` / `this.raw(...)`:
|
|
6
7
|
*
|
|
7
|
-
* t.text('status').defaultTo('new')
|
|
8
|
-
* t.boolean('active').defaultTo(false)
|
|
9
|
-
* t.integer('count').defaultTo(0)
|
|
10
|
-
* t.uuid('id').defaultTo(raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
11
|
-
* t.timestamp('created_at').defaultTo(this.now())
|
|
8
|
+
* t.text('status').defaultTo('new') // → DEFAULT 'new' (quoted literal)
|
|
9
|
+
* t.boolean('active').defaultTo(false) // → DEFAULT false
|
|
10
|
+
* t.integer('count').defaultTo(0) // → DEFAULT 0
|
|
11
|
+
* t.uuid('id').defaultTo(this.raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
12
|
+
* t.timestamp('created_at').defaultTo(this.now()) // → DEFAULT NOW()/CURRENT_TIMESTAMP
|
|
12
13
|
*
|
|
13
14
|
* Before this, `defaultTo` wrote its argument verbatim, so a bare
|
|
14
15
|
* `defaultTo('new')` produced the invalid `DEFAULT new` and string defaults had
|
|
15
16
|
* to be hand-quoted (`defaultTo("'new'")`) — a footgun Lucid/Knex avoid.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
export class RawValue {
|
|
20
|
-
constructor(readonly sql: string) {}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Wrap a SQL expression so {@link TableBuilder.defaultTo} emits it verbatim. */
|
|
24
|
-
export function raw(sql: string): RawValue {
|
|
25
|
-
return new RawValue(sql);
|
|
26
|
-
}
|
|
19
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
27
20
|
|
|
28
|
-
/** Accepted `defaultTo` argument: a JS literal or a
|
|
29
|
-
export type DefaultValue = string | number | boolean |
|
|
21
|
+
/** Accepted `defaultTo` argument: a JS literal or a raw SQL expression. */
|
|
22
|
+
export type DefaultValue = string | number | boolean | RawSql;
|
|
30
23
|
|
|
31
24
|
/**
|
|
32
25
|
* Render a `defaultTo` argument to the SQL fragment stored as the column
|
|
33
|
-
* default. Literals are quoted/escaped; {@link
|
|
26
|
+
* default. Literals are quoted/escaped; a {@link RawSql} passes through verbatim.
|
|
34
27
|
*/
|
|
35
28
|
export function renderDefaultValue(value: DefaultValue): string {
|
|
36
|
-
if (value instanceof
|
|
29
|
+
if (value instanceof RawSql) return value.sql;
|
|
37
30
|
if (typeof value === "number") return String(value);
|
|
38
31
|
if (typeof value === "boolean") return value ? "true" : "false";
|
|
39
32
|
// String literal — single-quote and escape embedded quotes (SQL standard).
|
package/src/services/db.ts
CHANGED
|
@@ -14,6 +14,18 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import type { AsyncDatabaseConnection } from "../adapters/NapiDbAdapter.js";
|
|
17
|
+
import { RawSql } from "../query/QueryBuilder.js";
|
|
18
|
+
|
|
19
|
+
/** The `db` singleton surface: the bound connection plus the AdonisJS-style `db.raw()` builder. */
|
|
20
|
+
export interface DbService extends AsyncDatabaseConnection {
|
|
21
|
+
/**
|
|
22
|
+
* Build a raw SQL expression — AdonisJS `db.raw()` / `Database.raw()`. Use it
|
|
23
|
+
* for query fragments and for column defaults that are SQL expressions:
|
|
24
|
+
*
|
|
25
|
+
* t.uuid('id').defaultTo(db.raw('gen_random_uuid()'))
|
|
26
|
+
*/
|
|
27
|
+
raw(sql: string, params?: unknown[]): RawSql;
|
|
28
|
+
}
|
|
17
29
|
|
|
18
30
|
let instance: AsyncDatabaseConnection | undefined;
|
|
19
31
|
|
|
@@ -37,8 +49,12 @@ export function getDb(): AsyncDatabaseConnection | undefined {
|
|
|
37
49
|
return instance;
|
|
38
50
|
}
|
|
39
51
|
|
|
40
|
-
const db:
|
|
52
|
+
const db: DbService = new Proxy({} as DbService, {
|
|
41
53
|
get(_target, prop) {
|
|
54
|
+
// `raw` is a pure builder (no connection needed) — available pre-boot too.
|
|
55
|
+
if (prop === "raw") {
|
|
56
|
+
return (sql: string, params: unknown[] = []) => new RawSql(sql, params);
|
|
57
|
+
}
|
|
42
58
|
if (!instance) {
|
|
43
59
|
throw new Error(
|
|
44
60
|
"[atlas] db singleton accessed before AtlasProvider.boot() ran. " +
|