@c9up/atlas 0.1.13 → 0.1.14
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.win32-x64-msvc.node +0 -0
- package/dist/AtlasProvider.d.ts +12 -0
- package/dist/AtlasProvider.d.ts.map +1 -1
- package/dist/AtlasProvider.js +19 -1
- package/dist/AtlasProvider.js.map +1 -1
- package/dist/console/schemaCheckCommand.d.ts +37 -0
- package/dist/console/schemaCheckCommand.d.ts.map +1 -0
- package/dist/console/schemaCheckCommand.js +49 -0
- package/dist/console/schemaCheckCommand.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/Migration.d.ts +4 -3
- package/dist/schema/Migration.d.ts.map +1 -1
- package/dist/schema/Migration.js +4 -3
- package/dist/schema/Migration.js.map +1 -1
- package/dist/schema/SchemaCheck.d.ts +61 -0
- package/dist/schema/SchemaCheck.d.ts.map +1 -0
- package/dist/schema/SchemaCheck.js +204 -0
- package/dist/schema/SchemaCheck.js.map +1 -0
- package/dist/schema/TableBuilder.d.ts +7 -1
- package/dist/schema/TableBuilder.d.ts.map +1 -1
- package/dist/schema/TableBuilder.js +12 -5
- package/dist/schema/TableBuilder.js.map +1 -1
- package/dist/schema/introspect.d.ts +34 -0
- package/dist/schema/introspect.d.ts.map +1 -0
- package/dist/schema/introspect.js +83 -0
- package/dist/schema/introspect.js.map +1 -0
- package/dist/schema/raw.d.ts +31 -0
- package/dist/schema/raw.d.ts.map +1 -0
- package/dist/schema/raw.js +42 -0
- package/dist/schema/raw.js.map +1 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
- package/src/AtlasProvider.ts +29 -1
- package/src/console/schemaCheckCommand.ts +62 -0
- package/src/index.ts +19 -0
- package/src/schema/Migration.ts +8 -5
- package/src/schema/SchemaCheck.ts +273 -0
- package/src/schema/TableBuilder.ts +13 -5
- package/src/schema/introspect.ts +133 -0
- package/src/schema/raw.ts +41 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @implements FR34
|
|
8
8
|
*/
|
|
9
9
|
import { type AtlasDialect } from "../query/native.js";
|
|
10
|
+
import { type DefaultValue } from "./raw.js";
|
|
10
11
|
import { type ColumnDefinition, type IndexDefinition } from "./types.js";
|
|
11
12
|
/** Table builder — used inside `schema.createTable(name, callback)`. */
|
|
12
13
|
export declare class TableBuilder {
|
|
@@ -93,7 +94,12 @@ export declare class TableBuilder {
|
|
|
93
94
|
notNullable(): this;
|
|
94
95
|
nullable(): this;
|
|
95
96
|
unique(): this;
|
|
96
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Set a column default. JS literals are quoted/escaped (`'x'`, `123`,
|
|
99
|
+
* `true` — Lucid/Knex semantics); wrap SQL expressions in {@link raw} (or
|
|
100
|
+
* use `Migration.now()`) to emit them verbatim.
|
|
101
|
+
*/
|
|
102
|
+
defaultTo(value: DefaultValue): this;
|
|
97
103
|
references(table: string, column?: string): this;
|
|
98
104
|
index(columns: string | string[], name?: string): this;
|
|
99
105
|
uniqueIndex(columns: string | string[], name?: string): this;
|
|
@@ -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;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;;;;;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,SAAS,CAAC,KAAK,EAAE,
|
|
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,EAAE,KAAK,YAAY,EAA2B,MAAM,UAAU,CAAC;AACtE,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,6 +7,7 @@
|
|
|
7
7
|
* @implements FR34
|
|
8
8
|
*/
|
|
9
9
|
import { compileStatementNative, getAtlasDialect, } from "../query/native.js";
|
|
10
|
+
import { raw, renderDefaultValue } from "./raw.js";
|
|
10
11
|
import { TYPE_KIND_MAP, } from "./types.js";
|
|
11
12
|
/** Table builder — used inside `schema.createTable(name, callback)`. */
|
|
12
13
|
export class TableBuilder {
|
|
@@ -107,7 +108,7 @@ export class TableBuilder {
|
|
|
107
108
|
* the helper dialect-aware.
|
|
108
109
|
*/
|
|
109
110
|
id() {
|
|
110
|
-
return this.uuid("id").primary().defaultTo("gen_random_uuid()");
|
|
111
|
+
return this.uuid("id").primary().defaultTo(raw("gen_random_uuid()"));
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
114
|
* `created_at` + `updated_at` columns with Postgres-only `DEFAULT NOW()`.
|
|
@@ -133,8 +134,8 @@ export class TableBuilder {
|
|
|
133
134
|
* the helper dialect-aware.
|
|
134
135
|
*/
|
|
135
136
|
timestamps() {
|
|
136
|
-
this.timestamp("created_at").notNullable().defaultTo("NOW()");
|
|
137
|
-
this.timestamp("updated_at").notNullable().defaultTo("NOW()");
|
|
137
|
+
this.timestamp("created_at").notNullable().defaultTo(raw("NOW()"));
|
|
138
|
+
this.timestamp("updated_at").notNullable().defaultTo(raw("NOW()"));
|
|
138
139
|
return this;
|
|
139
140
|
}
|
|
140
141
|
// ─── Column modifiers ─────────────────────────────────────
|
|
@@ -158,9 +159,15 @@ export class TableBuilder {
|
|
|
158
159
|
this.#currentColumn.unique = true;
|
|
159
160
|
return this;
|
|
160
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Set a column default. JS literals are quoted/escaped (`'x'`, `123`,
|
|
164
|
+
* `true` — Lucid/Knex semantics); wrap SQL expressions in {@link raw} (or
|
|
165
|
+
* use `Migration.now()`) to emit them verbatim.
|
|
166
|
+
*/
|
|
161
167
|
defaultTo(value) {
|
|
162
|
-
if (this.#currentColumn)
|
|
163
|
-
this.#currentColumn.defaultValue = value;
|
|
168
|
+
if (this.#currentColumn) {
|
|
169
|
+
this.#currentColumn.defaultValue = renderDefaultValue(value);
|
|
170
|
+
}
|
|
164
171
|
return this;
|
|
165
172
|
}
|
|
166
173
|
references(table, column = "id") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableBuilder.js","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TableBuilder.js","sourceRoot":"","sources":["../../src/schema/TableBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live schema introspection — reads the ACTUAL table/column shape from the
|
|
3
|
+
* connected database, per dialect. The reconciler in `SchemaCheck.ts` diffs
|
|
4
|
+
* this against each model's `@Column` metadata.
|
|
5
|
+
*
|
|
6
|
+
* SQLite uses `pragma_table_info`; Postgres and MySQL use `information_schema`.
|
|
7
|
+
* Table names come from `@Entity(...)` (developer-defined, trusted) — they are
|
|
8
|
+
* validated against a strict identifier pattern before interpolation, since
|
|
9
|
+
* `pragma_table_info(...)` cannot bind its argument.
|
|
10
|
+
*/
|
|
11
|
+
import type { AtlasDialect } from "../query/native.js";
|
|
12
|
+
/**
|
|
13
|
+
* Minimal connection surface the check needs: a row-returning `query`. Both the
|
|
14
|
+
* real `AsyncDatabaseConnection` and the test `Database` satisfy it, so the
|
|
15
|
+
* checker doesn't depend on the full driver interface.
|
|
16
|
+
*/
|
|
17
|
+
export interface SchemaIntrospectable {
|
|
18
|
+
query(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
|
|
19
|
+
}
|
|
20
|
+
/** One column as it actually exists in the database. */
|
|
21
|
+
export interface IntrospectedColumn {
|
|
22
|
+
name: string;
|
|
23
|
+
/** Raw dialect type string (e.g. `INTEGER`, `character varying`, `varchar`). */
|
|
24
|
+
type: string;
|
|
25
|
+
nullable: boolean;
|
|
26
|
+
hasDefault: boolean;
|
|
27
|
+
primaryKey: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Introspect one table. Returns its columns, or `null` when the table does not
|
|
31
|
+
* exist in the database (a distinct, reportable drift — not an error).
|
|
32
|
+
*/
|
|
33
|
+
export declare function introspectTable(db: SchemaIntrospectable, dialect: AtlasDialect, table: string): Promise<IntrospectedColumn[] | null>;
|
|
34
|
+
//# sourceMappingURL=introspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../../src/schema/introspect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CAC3E;AAED,wDAAwD;AACxD,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACpB;AAaD;;;GAGG;AACH,wBAAsB,eAAe,CACpC,EAAE,EAAE,oBAAoB,EACxB,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAUtC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live schema introspection — reads the ACTUAL table/column shape from the
|
|
3
|
+
* connected database, per dialect. The reconciler in `SchemaCheck.ts` diffs
|
|
4
|
+
* this against each model's `@Column` metadata.
|
|
5
|
+
*
|
|
6
|
+
* SQLite uses `pragma_table_info`; Postgres and MySQL use `information_schema`.
|
|
7
|
+
* Table names come from `@Entity(...)` (developer-defined, trusted) — they are
|
|
8
|
+
* validated against a strict identifier pattern before interpolation, since
|
|
9
|
+
* `pragma_table_info(...)` cannot bind its argument.
|
|
10
|
+
*/
|
|
11
|
+
/** A safe SQL identifier (table name from `@Entity`). */
|
|
12
|
+
const IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
13
|
+
function assertIdent(name) {
|
|
14
|
+
if (!IDENT.test(name)) {
|
|
15
|
+
throw new Error(`[atlas:check] refusing to introspect unsafe table identifier: ${JSON.stringify(name)}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Introspect one table. Returns its columns, or `null` when the table does not
|
|
20
|
+
* exist in the database (a distinct, reportable drift — not an error).
|
|
21
|
+
*/
|
|
22
|
+
export async function introspectTable(db, dialect, table) {
|
|
23
|
+
assertIdent(table);
|
|
24
|
+
switch (dialect) {
|
|
25
|
+
case "sqlite":
|
|
26
|
+
return introspectSqlite(db, table);
|
|
27
|
+
case "postgres":
|
|
28
|
+
return introspectPostgres(db, table);
|
|
29
|
+
case "mysql":
|
|
30
|
+
return introspectMysql(db, table);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function introspectSqlite(db, table) {
|
|
34
|
+
const rows = await db.query(`SELECT * FROM pragma_table_info('${table}')`);
|
|
35
|
+
if (rows.length === 0)
|
|
36
|
+
return null; // unknown table → no columns
|
|
37
|
+
return rows.map((r) => ({
|
|
38
|
+
name: String(r.name),
|
|
39
|
+
type: String(r.type ?? ""),
|
|
40
|
+
nullable: Number(r.notnull) === 0,
|
|
41
|
+
hasDefault: r.dflt_value !== null && r.dflt_value !== undefined,
|
|
42
|
+
primaryKey: Number(r.pk) > 0,
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
async function introspectPostgres(db, table) {
|
|
46
|
+
const cols = await db.query(`SELECT column_name, data_type, is_nullable, column_default
|
|
47
|
+
FROM information_schema.columns
|
|
48
|
+
WHERE table_schema = current_schema() AND table_name = $1
|
|
49
|
+
ORDER BY ordinal_position`, [table]);
|
|
50
|
+
if (cols.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
const pkRows = await db.query(`SELECT kcu.column_name
|
|
53
|
+
FROM information_schema.table_constraints tc
|
|
54
|
+
JOIN information_schema.key_column_usage kcu
|
|
55
|
+
ON kcu.constraint_name = tc.constraint_name
|
|
56
|
+
AND kcu.table_schema = tc.table_schema
|
|
57
|
+
WHERE tc.table_name = $1 AND tc.constraint_type = 'PRIMARY KEY'`, [table]);
|
|
58
|
+
const pks = new Set(pkRows.map((r) => String(r.column_name)));
|
|
59
|
+
return cols.map((r) => ({
|
|
60
|
+
name: String(r.column_name),
|
|
61
|
+
type: String(r.data_type ?? ""),
|
|
62
|
+
nullable: String(r.is_nullable).toUpperCase() === "YES",
|
|
63
|
+
hasDefault: r.column_default !== null && r.column_default !== undefined,
|
|
64
|
+
primaryKey: pks.has(String(r.column_name)),
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
async function introspectMysql(db, table) {
|
|
68
|
+
const rows = await db.query(`SELECT column_name, data_type, is_nullable, column_default, column_key
|
|
69
|
+
FROM information_schema.columns
|
|
70
|
+
WHERE table_schema = DATABASE() AND table_name = ?
|
|
71
|
+
ORDER BY ordinal_position`, [table]);
|
|
72
|
+
if (rows.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
return rows.map((r) => ({
|
|
75
|
+
name: String(r.column_name ?? r.COLUMN_NAME),
|
|
76
|
+
type: String(r.data_type ?? r.DATA_TYPE ?? ""),
|
|
77
|
+
nullable: String(r.is_nullable ?? r.IS_NULLABLE).toUpperCase() === "YES",
|
|
78
|
+
hasDefault: (r.column_default ?? r.COLUMN_DEFAULT) !== null &&
|
|
79
|
+
(r.column_default ?? r.COLUMN_DEFAULT) !== undefined,
|
|
80
|
+
primaryKey: String(r.column_key ?? r.COLUMN_KEY ?? "").toUpperCase() === "PRI",
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=introspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../src/schema/introspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default-value handling for the schema builder — Lucid/Knex semantics.
|
|
3
|
+
*
|
|
4
|
+
* `defaultTo` quotes JS literals and emits raw SQL only when wrapped in
|
|
5
|
+
* {@link raw} (or produced by `Migration.now()`):
|
|
6
|
+
*
|
|
7
|
+
* t.text('status').defaultTo('new') // → DEFAULT 'new' (quoted literal)
|
|
8
|
+
* t.boolean('active').defaultTo(false) // → DEFAULT false
|
|
9
|
+
* t.integer('count').defaultTo(0) // → DEFAULT 0
|
|
10
|
+
* t.uuid('id').defaultTo(raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
11
|
+
* t.timestamp('created_at').defaultTo(this.now()) // → DEFAULT NOW()/CURRENT_TIMESTAMP
|
|
12
|
+
*
|
|
13
|
+
* Before this, `defaultTo` wrote its argument verbatim, so a bare
|
|
14
|
+
* `defaultTo('new')` produced the invalid `DEFAULT new` and string defaults had
|
|
15
|
+
* to be hand-quoted (`defaultTo("'new'")`) — a footgun Lucid/Knex avoid.
|
|
16
|
+
*/
|
|
17
|
+
/** A raw SQL expression for a column default — emitted verbatim, never quoted. */
|
|
18
|
+
export declare class RawValue {
|
|
19
|
+
readonly sql: string;
|
|
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;
|
|
26
|
+
/**
|
|
27
|
+
* Render a `defaultTo` argument to the SQL fragment stored as the column
|
|
28
|
+
* default. Literals are quoted/escaped; {@link RawValue} passes through.
|
|
29
|
+
*/
|
|
30
|
+
export declare function renderDefaultValue(value: DefaultValue): string;
|
|
31
|
+
//# sourceMappingURL=raw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,kFAAkF;AAClF,qBAAa,QAAQ;IACR,QAAQ,CAAC,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAChC;AAED,iFAAiF;AACjF,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAEzC;AAED,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAM9D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default-value handling for the schema builder — Lucid/Knex semantics.
|
|
3
|
+
*
|
|
4
|
+
* `defaultTo` quotes JS literals and emits raw SQL only when wrapped in
|
|
5
|
+
* {@link raw} (or produced by `Migration.now()`):
|
|
6
|
+
*
|
|
7
|
+
* t.text('status').defaultTo('new') // → DEFAULT 'new' (quoted literal)
|
|
8
|
+
* t.boolean('active').defaultTo(false) // → DEFAULT false
|
|
9
|
+
* t.integer('count').defaultTo(0) // → DEFAULT 0
|
|
10
|
+
* t.uuid('id').defaultTo(raw('gen_random_uuid()')) // → DEFAULT gen_random_uuid()
|
|
11
|
+
* t.timestamp('created_at').defaultTo(this.now()) // → DEFAULT NOW()/CURRENT_TIMESTAMP
|
|
12
|
+
*
|
|
13
|
+
* Before this, `defaultTo` wrote its argument verbatim, so a bare
|
|
14
|
+
* `defaultTo('new')` produced the invalid `DEFAULT new` and string defaults had
|
|
15
|
+
* to be hand-quoted (`defaultTo("'new'")`) — a footgun Lucid/Knex avoid.
|
|
16
|
+
*/
|
|
17
|
+
/** A raw SQL expression for a column default — emitted verbatim, never quoted. */
|
|
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
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Render a `defaultTo` argument to the SQL fragment stored as the column
|
|
30
|
+
* default. Literals are quoted/escaped; {@link RawValue} passes through.
|
|
31
|
+
*/
|
|
32
|
+
export function renderDefaultValue(value) {
|
|
33
|
+
if (value instanceof RawValue)
|
|
34
|
+
return value.sql;
|
|
35
|
+
if (typeof value === "number")
|
|
36
|
+
return String(value);
|
|
37
|
+
if (typeof value === "boolean")
|
|
38
|
+
return value ? "true" : "false";
|
|
39
|
+
// String literal — single-quote and escape embedded quotes (SQL standard).
|
|
40
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=raw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw.js","sourceRoot":"","sources":["../../src/schema/raw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,kFAAkF;AAClF,MAAM,OAAO,QAAQ;IACC;IAArB,YAAqB,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;CACpC;AAED,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAC,GAAW;IAC9B,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAKD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAmB;IACrD,IAAI,KAAK,YAAY,QAAQ;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAChD,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"}
|
|
Binary file
|
package/package.json
CHANGED
package/src/AtlasProvider.ts
CHANGED
|
@@ -122,6 +122,18 @@ export interface AtlasDatabaseConfig extends ConnectionConfig {
|
|
|
122
122
|
*/
|
|
123
123
|
table?: string;
|
|
124
124
|
};
|
|
125
|
+
/**
|
|
126
|
+
* Boot-time schema verification. When set, atlas reconciles each listed
|
|
127
|
+
* model's `@Column` metadata against the LIVE database schema after boot and
|
|
128
|
+
* reports drift (typo'd / missing columns, type mismatches, unmapped NOT NULL
|
|
129
|
+
* columns). `mode: "throw"` (default) fails the boot on drift; `"warn"` logs
|
|
130
|
+
* and continues. Atlas has no global entity registry by design — list your
|
|
131
|
+
* models here (mirrors Lucid, where `ace` is pointed at your models dir).
|
|
132
|
+
*/
|
|
133
|
+
verifySchema?: {
|
|
134
|
+
entities: ReadonlyArray<new (...args: unknown[]) => unknown>;
|
|
135
|
+
mode?: "throw" | "warn";
|
|
136
|
+
};
|
|
125
137
|
}
|
|
126
138
|
|
|
127
139
|
export default class AtlasProvider {
|
|
@@ -269,7 +281,23 @@ export default class AtlasProvider {
|
|
|
269
281
|
}
|
|
270
282
|
}
|
|
271
283
|
|
|
272
|
-
async start() {
|
|
284
|
+
async start() {
|
|
285
|
+
// Boot-time schema verification (opt-in via `database.verifySchema`).
|
|
286
|
+
// Runs AFTER boot so the default connection is open. Reconciles models
|
|
287
|
+
// against the live DB and throws/warns on drift before requests serve.
|
|
288
|
+
const config = this.app.config.get<AtlasDatabaseConfig>("database");
|
|
289
|
+
const verify = config?.verifySchema;
|
|
290
|
+
if (!verify || verify.entities.length === 0) return;
|
|
291
|
+
const db = this.#connections.get(this.#defaultName);
|
|
292
|
+
if (!db) return;
|
|
293
|
+
const [{ verifySchema }, { getAtlasDialect }] = await Promise.all([
|
|
294
|
+
import("./schema/SchemaCheck.js"),
|
|
295
|
+
import("./query/native.js"),
|
|
296
|
+
]);
|
|
297
|
+
await verifySchema(verify.entities, db, getAtlasDialect(), {
|
|
298
|
+
mode: verify.mode,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
273
301
|
async ready() {}
|
|
274
302
|
|
|
275
303
|
/** Normalize the config into a `{ name → ConnectionConfig }` map + default name. */
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `atlas:check` console command — the Ream-idiomatic CLI for schema
|
|
3
|
+
* verification. Ream commands are plain `{ name, description, run }` objects
|
|
4
|
+
* registered in `reamrc.commands` and dispatched by the console kernel
|
|
5
|
+
* (`new Ignitor(...).console().handle(argv)`).
|
|
6
|
+
*
|
|
7
|
+
* Stays framework-agnostic: resolves the live connection + dialect from atlas's
|
|
8
|
+
* OWN service locators (`getDb` / `getAtlasDialect`), never importing
|
|
9
|
+
* `@c9up/ream`. The {@link AtlasCommand} shape structurally matches Ream's
|
|
10
|
+
* `Command` interface, so the console kernel accepts it without a type
|
|
11
|
+
* dependency in either direction.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { getAtlasDialect } from "../query/native.js";
|
|
15
|
+
import { runSchemaCheck } from "../schema/SchemaCheck.js";
|
|
16
|
+
import { getDb } from "../services/db.js";
|
|
17
|
+
|
|
18
|
+
type Constructor = new (...args: unknown[]) => unknown;
|
|
19
|
+
|
|
20
|
+
/** Structural match of Ream's console `Command` (no `@c9up/ream` import). */
|
|
21
|
+
export interface AtlasCommand {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
run(args: string[], flags: Record<string, string | boolean>): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build the `atlas:check` command for the given models. Register it in
|
|
29
|
+
* `reamrc.commands` (atlas has no global entity registry — list your models,
|
|
30
|
+
* as in Lucid). Run it via the console kernel; `--warn` reports drift without a
|
|
31
|
+
* non-zero exit (useful for an advisory CI step).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // commands/atlas-check.ts
|
|
35
|
+
* import { schemaCheckCommand } from '@c9up/atlas'
|
|
36
|
+
* import { User } from '#models/user'
|
|
37
|
+
* export default schemaCheckCommand([User])
|
|
38
|
+
*
|
|
39
|
+
* // reamrc.ts → commands: [() => import('./commands/atlas-check.js')]
|
|
40
|
+
* // run: <console-entry> atlas:check
|
|
41
|
+
*/
|
|
42
|
+
export function schemaCheckCommand(
|
|
43
|
+
entities: readonly Constructor[],
|
|
44
|
+
): AtlasCommand {
|
|
45
|
+
return {
|
|
46
|
+
name: "atlas:check",
|
|
47
|
+
description: "Verify models match the live database schema",
|
|
48
|
+
async run(_args, flags) {
|
|
49
|
+
const db = getDb();
|
|
50
|
+
if (!db) {
|
|
51
|
+
console.error(
|
|
52
|
+
"[atlas:check] no database connection — is AtlasProvider registered?",
|
|
53
|
+
);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const code = await runSchemaCheck(entities, db, getAtlasDialect());
|
|
58
|
+
// `--warn` downgrades drift to advisory (exit 0); default fails CI.
|
|
59
|
+
if (code !== 0 && !flags.warn) process.exitCode = code;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,10 @@ export type { DatabaseConnection } from "./BaseRepository.js";
|
|
|
18
18
|
export { BaseRepository } from "./BaseRepository.js";
|
|
19
19
|
export { defineConfig } from "./config.js";
|
|
20
20
|
export { configure } from "./configure.js";
|
|
21
|
+
export {
|
|
22
|
+
type AtlasCommand,
|
|
23
|
+
schemaCheckCommand,
|
|
24
|
+
} from "./console/schemaCheckCommand.js";
|
|
21
25
|
export type {
|
|
22
26
|
ColumnAdapter,
|
|
23
27
|
ColumnMetadata,
|
|
@@ -95,6 +99,10 @@ export type {
|
|
|
95
99
|
WhereOperator,
|
|
96
100
|
} from "./query/QueryBuilder.js";
|
|
97
101
|
export { QueryBuilder, RawSql } from "./query/QueryBuilder.js";
|
|
102
|
+
export {
|
|
103
|
+
type IntrospectedColumn,
|
|
104
|
+
introspectTable,
|
|
105
|
+
} from "./schema/introspect.js";
|
|
98
106
|
export { Migration } from "./schema/Migration.js";
|
|
99
107
|
export type {
|
|
100
108
|
DatabaseAdapter,
|
|
@@ -103,8 +111,19 @@ export type {
|
|
|
103
111
|
MigrationStatus,
|
|
104
112
|
} from "./schema/MigrationRunner.js";
|
|
105
113
|
export { MigrationRunner } from "./schema/MigrationRunner.js";
|
|
114
|
+
export { type DefaultValue, RawValue, raw } from "./schema/raw.js";
|
|
106
115
|
export type { ColumnDefinition, ColumnType } from "./schema/SchemaBuilder.js";
|
|
107
116
|
export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
|
|
117
|
+
export {
|
|
118
|
+
checkSchema,
|
|
119
|
+
formatSchemaFindings,
|
|
120
|
+
runSchemaCheck,
|
|
121
|
+
type SchemaFinding,
|
|
122
|
+
type SchemaFindingKind,
|
|
123
|
+
suggestColumn,
|
|
124
|
+
typesCompatible,
|
|
125
|
+
verifySchema,
|
|
126
|
+
} from "./schema/SchemaCheck.js";
|
|
108
127
|
export {
|
|
109
128
|
BaseSeeder,
|
|
110
129
|
runSeederDirectory,
|
package/src/schema/Migration.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { AtlasDialect } from "../query/native.js";
|
|
8
|
+
import { RawValue } from "./raw.js";
|
|
8
9
|
import { Schema } from "./SchemaBuilder.js";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -46,9 +47,9 @@ export abstract class Migration {
|
|
|
46
47
|
/** Rollback the migration. */
|
|
47
48
|
abstract down(): Promise<void> | void;
|
|
48
49
|
|
|
49
|
-
/** Helper: raw SQL expression
|
|
50
|
-
raw(expression: string):
|
|
51
|
-
return expression;
|
|
50
|
+
/** Helper: raw SQL expression for a column DEFAULT — emitted verbatim, not quoted. */
|
|
51
|
+
raw(expression: string): RawValue {
|
|
52
|
+
return new RawValue(expression);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
/**
|
|
@@ -62,8 +63,10 @@ export abstract class Migration {
|
|
|
62
63
|
* migrations — `NOW()` is not a recognised function there and the column
|
|
63
64
|
* default would blow up at DDL compile time.
|
|
64
65
|
*/
|
|
65
|
-
now():
|
|
66
|
-
return
|
|
66
|
+
now(): RawValue {
|
|
67
|
+
return new RawValue(
|
|
68
|
+
this.#dialect === "sqlite" ? "CURRENT_TIMESTAMP" : "NOW()",
|
|
69
|
+
);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
/** Get the SQL statements generated by this migration. */
|