@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
package/db.win32-x64-msvc.node
CHANGED
|
Binary file
|
package/dist/AtlasProvider.d.ts
CHANGED
|
@@ -106,6 +106,18 @@ export interface AtlasDatabaseConfig extends ConnectionConfig {
|
|
|
106
106
|
*/
|
|
107
107
|
table?: string;
|
|
108
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* Boot-time schema verification. When set, atlas reconciles each listed
|
|
111
|
+
* model's `@Column` metadata against the LIVE database schema after boot and
|
|
112
|
+
* reports drift (typo'd / missing columns, type mismatches, unmapped NOT NULL
|
|
113
|
+
* columns). `mode: "throw"` (default) fails the boot on drift; `"warn"` logs
|
|
114
|
+
* and continues. Atlas has no global entity registry by design — list your
|
|
115
|
+
* models here (mirrors Lucid, where `ace` is pointed at your models dir).
|
|
116
|
+
*/
|
|
117
|
+
verifySchema?: {
|
|
118
|
+
entities: ReadonlyArray<new (...args: unknown[]) => unknown>;
|
|
119
|
+
mode?: "throw" | "warn";
|
|
120
|
+
};
|
|
109
121
|
}
|
|
110
122
|
export default class AtlasProvider {
|
|
111
123
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AtlasProvider.d.ts","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAaH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;KACR,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;CACzD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB;;;EAGrB,CAAC;AAEZ,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAChC,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC1C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC5D,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAKrB,SAAS,CAAC,GAAG,EAAE,eAAe;gBAApB,GAAG,EAAE,eAAe;IAE1C,QAAQ;IAEF,IAAI;IAmGJ,QAAQ;IAqCR,KAAK;
|
|
1
|
+
{"version":3,"file":"AtlasProvider.d.ts","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAaH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;KACR,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;CACzD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB;;;EAGrB,CAAC;AAEZ,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAChC,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC1C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC5D,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE;QACd,QAAQ,EAAE,aAAa,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KACxB,CAAC;CACF;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAKrB,SAAS,CAAC,GAAG,EAAE,eAAe;gBAApB,GAAG,EAAE,eAAe;IAE1C,QAAQ;IAEF,IAAI;IAmGJ,QAAQ;IAqCR,KAAK;IAiBL,KAAK;CAwDX"}
|
package/dist/AtlasProvider.js
CHANGED
|
@@ -157,7 +157,25 @@ export default class AtlasProvider {
|
|
|
157
157
|
throw new AggregateError(errors.map((e) => e.error), `AtlasProvider: ${errors.length} connection(s) failed to close — ${summary}`);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
async start() {
|
|
160
|
+
async start() {
|
|
161
|
+
// Boot-time schema verification (opt-in via `database.verifySchema`).
|
|
162
|
+
// Runs AFTER boot so the default connection is open. Reconciles models
|
|
163
|
+
// against the live DB and throws/warns on drift before requests serve.
|
|
164
|
+
const config = this.app.config.get("database");
|
|
165
|
+
const verify = config?.verifySchema;
|
|
166
|
+
if (!verify || verify.entities.length === 0)
|
|
167
|
+
return;
|
|
168
|
+
const db = this.#connections.get(this.#defaultName);
|
|
169
|
+
if (!db)
|
|
170
|
+
return;
|
|
171
|
+
const [{ verifySchema }, { getAtlasDialect }] = await Promise.all([
|
|
172
|
+
import("./schema/SchemaCheck.js"),
|
|
173
|
+
import("./query/native.js"),
|
|
174
|
+
]);
|
|
175
|
+
await verifySchema(verify.entities, db, getAtlasDialect(), {
|
|
176
|
+
mode: verify.mode,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
161
179
|
async ready() { }
|
|
162
180
|
/** Normalize the config into a `{ name → ConnectionConfig }` map + default name. */
|
|
163
181
|
#resolveConnections(config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AtlasProvider.js","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAEN,oBAAoB,GACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAEN,eAAe,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAwB3D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,KAAK;IACnB,WAAW,EAAE,QAAQ;CACZ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"AtlasProvider.js","sourceRoot":"","sources":["../src/AtlasProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
type Constructor = new (...args: unknown[]) => unknown;
|
|
14
|
+
/** Structural match of Ream's console `Command` (no `@c9up/ream` import). */
|
|
15
|
+
export interface AtlasCommand {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
run(args: string[], flags: Record<string, string | boolean>): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the `atlas:check` command for the given models. Register it in
|
|
22
|
+
* `reamrc.commands` (atlas has no global entity registry — list your models,
|
|
23
|
+
* as in Lucid). Run it via the console kernel; `--warn` reports drift without a
|
|
24
|
+
* non-zero exit (useful for an advisory CI step).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // commands/atlas-check.ts
|
|
28
|
+
* import { schemaCheckCommand } from '@c9up/atlas'
|
|
29
|
+
* import { User } from '#models/user'
|
|
30
|
+
* export default schemaCheckCommand([User])
|
|
31
|
+
*
|
|
32
|
+
* // reamrc.ts → commands: [() => import('./commands/atlas-check.js')]
|
|
33
|
+
* // run: <console-entry> atlas:check
|
|
34
|
+
*/
|
|
35
|
+
export declare function schemaCheckCommand(entities: readonly Constructor[]): AtlasCommand;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=schemaCheckCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaCheckCommand.d.ts","sourceRoot":"","sources":["../../src/console/schemaCheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,KAAK,WAAW,GAAG,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAEvD,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,YAAY,CAkBd"}
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
import { getAtlasDialect } from "../query/native.js";
|
|
14
|
+
import { runSchemaCheck } from "../schema/SchemaCheck.js";
|
|
15
|
+
import { getDb } from "../services/db.js";
|
|
16
|
+
/**
|
|
17
|
+
* Build the `atlas:check` command for the given models. Register it in
|
|
18
|
+
* `reamrc.commands` (atlas has no global entity registry — list your models,
|
|
19
|
+
* as in Lucid). Run it via the console kernel; `--warn` reports drift without a
|
|
20
|
+
* non-zero exit (useful for an advisory CI step).
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // commands/atlas-check.ts
|
|
24
|
+
* import { schemaCheckCommand } from '@c9up/atlas'
|
|
25
|
+
* import { User } from '#models/user'
|
|
26
|
+
* export default schemaCheckCommand([User])
|
|
27
|
+
*
|
|
28
|
+
* // reamrc.ts → commands: [() => import('./commands/atlas-check.js')]
|
|
29
|
+
* // run: <console-entry> atlas:check
|
|
30
|
+
*/
|
|
31
|
+
export function schemaCheckCommand(entities) {
|
|
32
|
+
return {
|
|
33
|
+
name: "atlas:check",
|
|
34
|
+
description: "Verify models match the live database schema",
|
|
35
|
+
async run(_args, flags) {
|
|
36
|
+
const db = getDb();
|
|
37
|
+
if (!db) {
|
|
38
|
+
console.error("[atlas:check] no database connection — is AtlasProvider registered?");
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const code = await runSchemaCheck(entities, db, getAtlasDialect());
|
|
43
|
+
// `--warn` downgrades drift to advisory (exit 0); default fails CI.
|
|
44
|
+
if (code !== 0 && !flags.warn)
|
|
45
|
+
process.exitCode = code;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=schemaCheckCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaCheckCommand.js","sourceRoot":"","sources":["../../src/console/schemaCheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAW1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CACjC,QAAgC;IAEhC,OAAO;QACN,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,8CAA8C;QAC3D,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK;YACrB,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,EAAE,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CACZ,qEAAqE,CACrE,CAAC;gBACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACR,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;YACnE,oEAAoE;YACpE,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;gBAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxD,CAAC;KACD,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type { DatabaseConnection } from "./BaseRepository.js";
|
|
|
13
13
|
export { BaseRepository } from "./BaseRepository.js";
|
|
14
14
|
export { defineConfig } from "./config.js";
|
|
15
15
|
export { configure } from "./configure.js";
|
|
16
|
+
export { type AtlasCommand, schemaCheckCommand, } from "./console/schemaCheckCommand.js";
|
|
16
17
|
export type { ColumnAdapter, ColumnMetadata, ColumnOptions, DateColumnConfig, DateTimeColumnOptions, EntityMetadata, ManyToManyOptions, RelationMetadata, } from "./decorators/entity.js";
|
|
17
18
|
export { BelongsTo, Column, column, computed, Entity, getColumnMetadata, getDateColumnConfig, getEntityMetadata, getPrimaryKey, getRelationMetadata, HasMany, HasManyThrough, HasOne, HasOneThrough, hasSoftDeletes, ManyToMany, PrimaryKey, SoftDeletes, } from "./decorators/entity.js";
|
|
18
19
|
export { afterCreate, afterDelete, afterFetch, afterFind, afterPaginate, afterSave, afterUpdate, beforeCreate, beforeDelete, beforeFetch, beforeFind, beforePaginate, beforeSave, beforeUpdate, } from "./decorators/hooks.js";
|
|
@@ -26,11 +27,14 @@ export type { AtlasDialect } from "./query/native.js";
|
|
|
26
27
|
export { getAtlasDialect, setAtlasDialect } from "./query/native.js";
|
|
27
28
|
export type { CteDefinition, ExistsClause, OrderByClause, QueryResult, WhereClause, WhereOperator, } from "./query/QueryBuilder.js";
|
|
28
29
|
export { QueryBuilder, RawSql } from "./query/QueryBuilder.js";
|
|
30
|
+
export { type IntrospectedColumn, introspectTable, } from "./schema/introspect.js";
|
|
29
31
|
export { Migration } from "./schema/Migration.js";
|
|
30
32
|
export type { DatabaseAdapter, MigrationRecord, MigrationState, MigrationStatus, } from "./schema/MigrationRunner.js";
|
|
31
33
|
export { MigrationRunner } from "./schema/MigrationRunner.js";
|
|
34
|
+
export { type DefaultValue, RawValue, raw } from "./schema/raw.js";
|
|
32
35
|
export type { ColumnDefinition, ColumnType } from "./schema/SchemaBuilder.js";
|
|
33
36
|
export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
|
|
37
|
+
export { checkSchema, formatSchemaFindings, runSchemaCheck, type SchemaFinding, type SchemaFindingKind, suggestColumn, typesCompatible, verifySchema, } from "./schema/SchemaCheck.js";
|
|
34
38
|
export { BaseSeeder, runSeederDirectory, runSeeders, Seeder, } from "./schema/Seeder.js";
|
|
35
39
|
export type { TransactionClient } from "./Transaction.js";
|
|
36
40
|
export { transaction } from "./Transaction.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { BaseEntity } from "./BaseEntity.js";
|
|
|
10
10
|
export { BaseRepository } from "./BaseRepository.js";
|
|
11
11
|
export { defineConfig } from "./config.js";
|
|
12
12
|
export { configure } from "./configure.js";
|
|
13
|
+
export { schemaCheckCommand, } from "./console/schemaCheckCommand.js";
|
|
13
14
|
export { BelongsTo, Column, column, computed, Entity, getColumnMetadata, getDateColumnConfig, getEntityMetadata, getPrimaryKey, getRelationMetadata, HasMany, HasManyThrough, HasOne, HasOneThrough, hasSoftDeletes, ManyToMany, PrimaryKey, SoftDeletes, } from "./decorators/entity.js";
|
|
14
15
|
export { afterCreate, afterDelete, afterFetch, afterFind, afterPaginate, afterSave, afterUpdate, beforeCreate, beforeDelete, beforeFetch, beforeFind, beforePaginate, beforeSave, beforeUpdate, } from "./decorators/hooks.js";
|
|
15
16
|
export { scope } from "./decorators/scope.js";
|
|
@@ -18,9 +19,12 @@ export { isAtlasStrictMode, ModelQuery, setAtlasStrictMode, } from "./ModelQuery
|
|
|
18
19
|
export { CamelCaseNamingStrategy, defaultNamingStrategy, getNamingStrategy, } from "./naming/NamingStrategy.js";
|
|
19
20
|
export { getAtlasDialect, setAtlasDialect } from "./query/native.js";
|
|
20
21
|
export { QueryBuilder, RawSql } from "./query/QueryBuilder.js";
|
|
22
|
+
export { introspectTable, } from "./schema/introspect.js";
|
|
21
23
|
export { Migration } from "./schema/Migration.js";
|
|
22
24
|
export { MigrationRunner } from "./schema/MigrationRunner.js";
|
|
25
|
+
export { RawValue, raw } from "./schema/raw.js";
|
|
23
26
|
export { Schema, TableBuilder } from "./schema/SchemaBuilder.js";
|
|
27
|
+
export { checkSchema, formatSchemaFindings, runSchemaCheck, suggestColumn, typesCompatible, verifySchema, } from "./schema/SchemaCheck.js";
|
|
24
28
|
export { BaseSeeder, runSeederDirectory, runSeeders, Seeder, } from "./schema/Seeder.js";
|
|
25
29
|
export { transaction } from "./Transaction.js";
|
|
26
30
|
export { truncateAll, useTransaction } from "./testing/DatabaseCleanup.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAEN,kBAAkB,GAClB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,EACN,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,EACR,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,OAAO,EACP,cAAc,EACd,MAAM,EACN,aAAa,EACb,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,GACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,GACZ,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EACN,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASrE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAEN,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOlD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAqB,QAAQ,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACN,WAAW,EACX,oBAAoB,EACpB,cAAc,EAGd,aAAa,EACb,eAAe,EACf,YAAY,GACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,MAAM,GACN,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @implements FR34
|
|
5
5
|
*/
|
|
6
6
|
import type { AtlasDialect } from "../query/native.js";
|
|
7
|
+
import { RawValue } from "./raw.js";
|
|
7
8
|
import { Schema } from "./SchemaBuilder.js";
|
|
8
9
|
/**
|
|
9
10
|
* Base class for all migrations.
|
|
@@ -34,8 +35,8 @@ export declare abstract class Migration {
|
|
|
34
35
|
abstract up(): Promise<void> | void;
|
|
35
36
|
/** Rollback the migration. */
|
|
36
37
|
abstract down(): Promise<void> | void;
|
|
37
|
-
/** Helper: raw SQL expression
|
|
38
|
-
raw(expression: string):
|
|
38
|
+
/** Helper: raw SQL expression for a column DEFAULT — emitted verbatim, not quoted. */
|
|
39
|
+
raw(expression: string): RawValue;
|
|
39
40
|
/**
|
|
40
41
|
* Dialect-aware "current timestamp" helper for column defaults.
|
|
41
42
|
*
|
|
@@ -47,7 +48,7 @@ export declare abstract class Migration {
|
|
|
47
48
|
* migrations — `NOW()` is not a recognised function there and the column
|
|
48
49
|
* default would blow up at DDL compile time.
|
|
49
50
|
*/
|
|
50
|
-
now():
|
|
51
|
+
now(): RawValue;
|
|
51
52
|
/** Get the SQL statements generated by this migration. */
|
|
52
53
|
getUpSQL(): Promise<string[]>;
|
|
53
54
|
getDownSQL(): Promise<string[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Migration.d.ts","sourceRoot":"","sources":["../../src/schema/Migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,SAAS;;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGZ,OAAO,CAAC,EAAE,YAAY;IAQlC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAEnC,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAErC,
|
|
1
|
+
{"version":3,"file":"Migration.d.ts","sourceRoot":"","sources":["../../src/schema/Migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,SAAS;;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGZ,OAAO,CAAC,EAAE,YAAY;IAQlC,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAEnC,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAErC,sFAAsF;IACtF,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ;IAIjC;;;;;;;;;;OAUG;IACH,GAAG,IAAI,QAAQ;IAMf,0DAA0D;IACpD,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM7B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAKrC"}
|
package/dist/schema/Migration.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @implements FR34
|
|
5
5
|
*/
|
|
6
|
+
import { RawValue } from "./raw.js";
|
|
6
7
|
import { Schema } from "./SchemaBuilder.js";
|
|
7
8
|
/**
|
|
8
9
|
* Base class for all migrations.
|
|
@@ -35,9 +36,9 @@ export class Migration {
|
|
|
35
36
|
// on postgres/mysql too, so this is the safest conservative default.
|
|
36
37
|
this.#dialect = dialect ?? "sqlite";
|
|
37
38
|
}
|
|
38
|
-
/** Helper: raw SQL expression
|
|
39
|
+
/** Helper: raw SQL expression for a column DEFAULT — emitted verbatim, not quoted. */
|
|
39
40
|
raw(expression) {
|
|
40
|
-
return expression;
|
|
41
|
+
return new RawValue(expression);
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
44
|
* Dialect-aware "current timestamp" helper for column defaults.
|
|
@@ -51,7 +52,7 @@ export class Migration {
|
|
|
51
52
|
* default would blow up at DDL compile time.
|
|
52
53
|
*/
|
|
53
54
|
now() {
|
|
54
|
-
return this.#dialect === "sqlite" ? "CURRENT_TIMESTAMP" : "NOW()";
|
|
55
|
+
return new RawValue(this.#dialect === "sqlite" ? "CURRENT_TIMESTAMP" : "NOW()");
|
|
55
56
|
}
|
|
56
57
|
/** Get the SQL statements generated by this migration. */
|
|
57
58
|
async getUpSQL() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Migration.js","sourceRoot":"","sources":["../../src/schema/Migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAgB,SAAS;IACrB,MAAM,CAAS;IACf,QAAQ,CAAe;IAEhC,YAAY,OAAsB;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,oEAAoE;QACpE,uEAAuE;QACvE,qEAAqE;QACrE,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,QAAQ,CAAC;IACrC,CAAC;IAQD,
|
|
1
|
+
{"version":3,"file":"Migration.js","sourceRoot":"","sources":["../../src/schema/Migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAgB,SAAS;IACrB,MAAM,CAAS;IACf,QAAQ,CAAe;IAEhC,YAAY,OAAsB;QACjC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,oEAAoE;QACpE,uEAAuE;QACvE,qEAAqE;QACrE,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,QAAQ,CAAC;IACrC,CAAC;IAQD,sFAAsF;IACtF,GAAG,CAAC,UAAkB;QACrB,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;;OAUG;IACH,GAAG;QACF,OAAO,IAAI,QAAQ,CAClB,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAC1D,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,QAAQ;QACb,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,UAAU;QACf,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema verification — reconciles each model's `@Column` metadata against the
|
|
3
|
+
* LIVE database schema (via {@link introspectTable}) and reports drift BEFORE
|
|
4
|
+
* it bites at runtime. This is what pure-JS ORMs (Lucid) structurally cannot
|
|
5
|
+
* do; atlas can because its driver introspects the real database.
|
|
6
|
+
*
|
|
7
|
+
* Four drift categories:
|
|
8
|
+
* - `missing-table` — the model's table does not exist.
|
|
9
|
+
* - `missing-in-db` — a model column maps to a non-existent DB column
|
|
10
|
+
* (typo → `did you mean`).
|
|
11
|
+
* - `type-mismatch` — a declared `@Column({ type })` clashes with the DB
|
|
12
|
+
* column's type (conservative: only clear num↔text).
|
|
13
|
+
* - `missing-in-model` — a NOT NULL DB column with no default that no model
|
|
14
|
+
* property maps to → inserts will fail.
|
|
15
|
+
*
|
|
16
|
+
* The check is dialect-agnostic; only {@link introspectTable} is dialect-aware.
|
|
17
|
+
* Kept free of any `@c9up/ream` import — atlas stays framework-agnostic.
|
|
18
|
+
*/
|
|
19
|
+
import type { AtlasDialect } from "../query/native.js";
|
|
20
|
+
import { type SchemaIntrospectable } from "./introspect.js";
|
|
21
|
+
type Constructor = new (...args: unknown[]) => unknown;
|
|
22
|
+
export type SchemaFindingKind = "missing-table" | "missing-in-db" | "type-mismatch" | "missing-in-model";
|
|
23
|
+
export interface SchemaFinding {
|
|
24
|
+
entity: string;
|
|
25
|
+
table: string;
|
|
26
|
+
kind: SchemaFindingKind;
|
|
27
|
+
column: string;
|
|
28
|
+
detail: string;
|
|
29
|
+
/** A close DB column name, for typo diagnostics (`did you mean`). */
|
|
30
|
+
suggestion?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Compatible unless the model and DB types are in clearly-different groups. */
|
|
33
|
+
export declare function typesCompatible(modelType: string, dbType: string): boolean;
|
|
34
|
+
/** Closest candidate within edit distance 2 (typo suggestion), else undefined. */
|
|
35
|
+
export declare function suggestColumn(name: string, candidates: string[]): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Reconcile every given entity against the live database. Pass the app's model
|
|
38
|
+
* classes (atlas has no global entity registry by design — mirror Lucid, where
|
|
39
|
+
* `ace` is pointed at your models). Returns a flat list of findings (empty when
|
|
40
|
+
* the schema and models agree).
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkSchema(entities: readonly Constructor[], db: SchemaIntrospectable, dialect: AtlasDialect): Promise<SchemaFinding[]>;
|
|
43
|
+
/** Render findings as a didactic, Adonis-style diff (grouped per table). */
|
|
44
|
+
export declare function formatSchemaFindings(findings: SchemaFinding[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* Boot-time guard: run {@link checkSchema} and either throw (fail-fast, for CI /
|
|
47
|
+
* dev startup) or warn (non-blocking). Returns the findings. `mode` defaults to
|
|
48
|
+
* `"throw"` — a schema mismatch is a misconfiguration that should stop the boot
|
|
49
|
+
* before requests serve stale assumptions.
|
|
50
|
+
*/
|
|
51
|
+
export declare function verifySchema(entities: readonly Constructor[], db: SchemaIntrospectable, dialect: AtlasDialect, opts?: {
|
|
52
|
+
mode?: "throw" | "warn";
|
|
53
|
+
}): Promise<SchemaFinding[]>;
|
|
54
|
+
/**
|
|
55
|
+
* CLI body: run the check, print the report (diff or the OK line), and return
|
|
56
|
+
* the process exit code (`0` = schema matches, `1` = drift). Used by the
|
|
57
|
+
* `atlas:check` console command; safe to call from any script.
|
|
58
|
+
*/
|
|
59
|
+
export declare function runSchemaCheck(entities: readonly Constructor[], db: SchemaIntrospectable, dialect: AtlasDialect): Promise<number>;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=SchemaCheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaCheck.d.ts","sourceRoot":"","sources":["../../src/schema/SchemaCheck.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,iBAAiB,CAAC;AAEzB,KAAK,WAAW,GAAG,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAC1B,eAAe,GACf,eAAe,GACf,eAAe,GACf,kBAAkB,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAmBD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK1E;AAsBD,kFAAkF;AAClF,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,GAClB,MAAM,GAAG,SAAS,CAWpB;AA+DD;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,EAAE,EAAE,oBAAoB,EACxB,OAAO,EAAE,YAAY,GACnB,OAAO,CAAC,aAAa,EAAE,CAAC,CAgC1B;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAoBtE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,EAAE,EAAE,oBAAoB,EACxB,OAAO,EAAE,YAAY,EACrB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GACpC,OAAO,CAAC,aAAa,EAAE,CAAC,CAU1B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,EAAE,EAAE,oBAAoB,EACxB,OAAO,EAAE,YAAY,GACnB,OAAO,CAAC,MAAM,CAAC,CAIjB"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema verification — reconciles each model's `@Column` metadata against the
|
|
3
|
+
* LIVE database schema (via {@link introspectTable}) and reports drift BEFORE
|
|
4
|
+
* it bites at runtime. This is what pure-JS ORMs (Lucid) structurally cannot
|
|
5
|
+
* do; atlas can because its driver introspects the real database.
|
|
6
|
+
*
|
|
7
|
+
* Four drift categories:
|
|
8
|
+
* - `missing-table` — the model's table does not exist.
|
|
9
|
+
* - `missing-in-db` — a model column maps to a non-existent DB column
|
|
10
|
+
* (typo → `did you mean`).
|
|
11
|
+
* - `type-mismatch` — a declared `@Column({ type })` clashes with the DB
|
|
12
|
+
* column's type (conservative: only clear num↔text).
|
|
13
|
+
* - `missing-in-model` — a NOT NULL DB column with no default that no model
|
|
14
|
+
* property maps to → inserts will fail.
|
|
15
|
+
*
|
|
16
|
+
* The check is dialect-agnostic; only {@link introspectTable} is dialect-aware.
|
|
17
|
+
* Kept free of any `@c9up/ream` import — atlas stays framework-agnostic.
|
|
18
|
+
*/
|
|
19
|
+
import { getColumnMetadata, getEntityMetadata } from "../decorators/entity.js";
|
|
20
|
+
import { getNamingStrategy } from "../naming/NamingStrategy.js";
|
|
21
|
+
import { introspectTable, } from "./introspect.js";
|
|
22
|
+
// ─── Type compatibility (conservative) ───────────────────────────────
|
|
23
|
+
/**
|
|
24
|
+
* Coarse group of a type string. We only ever flag a mismatch between the two
|
|
25
|
+
* UNAMBIGUOUS groups (`num` vs `text`); everything storage-dependent
|
|
26
|
+
* (date/time, binary, blob — SQLite stores these as TEXT/NUMERIC) is `other`
|
|
27
|
+
* and never flagged, so the check has NO false positives.
|
|
28
|
+
*/
|
|
29
|
+
function typeGroup(raw) {
|
|
30
|
+
const t = raw.toLowerCase();
|
|
31
|
+
if (/(^|[^a-z])(int|serial|decimal|numeric|real|float|double|bool)/.test(t)) {
|
|
32
|
+
return "num";
|
|
33
|
+
}
|
|
34
|
+
if (/char|text|clob|string|uuid|json/.test(t))
|
|
35
|
+
return "text";
|
|
36
|
+
return "other";
|
|
37
|
+
}
|
|
38
|
+
/** Compatible unless the model and DB types are in clearly-different groups. */
|
|
39
|
+
export function typesCompatible(modelType, dbType) {
|
|
40
|
+
const m = typeGroup(modelType);
|
|
41
|
+
const d = typeGroup(dbType);
|
|
42
|
+
if (m === "other" || d === "other")
|
|
43
|
+
return true;
|
|
44
|
+
return m === d;
|
|
45
|
+
}
|
|
46
|
+
// ─── `did you mean` (atlas-local; no @c9up/ream import) ───────────────
|
|
47
|
+
function levenshtein(a, b) {
|
|
48
|
+
const dp = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
49
|
+
for (let i = 1; i <= a.length; i++) {
|
|
50
|
+
let prev = dp[0];
|
|
51
|
+
dp[0] = i;
|
|
52
|
+
for (let j = 1; j <= b.length; j++) {
|
|
53
|
+
const tmp = dp[j];
|
|
54
|
+
dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
55
|
+
prev = tmp;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return dp[b.length];
|
|
59
|
+
}
|
|
60
|
+
/** Closest candidate within edit distance 2 (typo suggestion), else undefined. */
|
|
61
|
+
export function suggestColumn(name, candidates) {
|
|
62
|
+
let best;
|
|
63
|
+
let bestD = Number.POSITIVE_INFINITY;
|
|
64
|
+
for (const c of candidates) {
|
|
65
|
+
const d = levenshtein(name, c);
|
|
66
|
+
if (d < bestD) {
|
|
67
|
+
bestD = d;
|
|
68
|
+
best = c;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return bestD <= 2 ? best : undefined;
|
|
72
|
+
}
|
|
73
|
+
// ─── Reconciler ──────────────────────────────────────────────────────
|
|
74
|
+
function reconcile(entityName, table, cols, columnNameOf, dbCols) {
|
|
75
|
+
const findings = [];
|
|
76
|
+
const dbByName = new Map(dbCols.map((c) => [c.name, c]));
|
|
77
|
+
const dbNames = dbCols.map((c) => c.name);
|
|
78
|
+
const mappedDbColumns = new Set();
|
|
79
|
+
for (const col of cols) {
|
|
80
|
+
const dbName = columnNameOf(col.propertyKey);
|
|
81
|
+
mappedDbColumns.add(dbName);
|
|
82
|
+
const dbCol = dbByName.get(dbName);
|
|
83
|
+
if (!dbCol) {
|
|
84
|
+
findings.push({
|
|
85
|
+
entity: entityName,
|
|
86
|
+
table,
|
|
87
|
+
kind: "missing-in-db",
|
|
88
|
+
column: dbName,
|
|
89
|
+
detail: `model property \`${col.propertyKey}\` maps to column \`${dbName}\`, which does not exist`,
|
|
90
|
+
suggestion: suggestColumn(dbName, dbNames),
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (col.type && !typesCompatible(col.type, dbCol.type)) {
|
|
95
|
+
findings.push({
|
|
96
|
+
entity: entityName,
|
|
97
|
+
table,
|
|
98
|
+
kind: "type-mismatch",
|
|
99
|
+
column: dbName,
|
|
100
|
+
detail: `declared \`${col.type}\` but column is \`${dbCol.type}\``,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Reverse drift — a NOT NULL column with no default that no model property
|
|
105
|
+
// writes: every insert omitting it fails. The dangerous, easy-to-miss case
|
|
106
|
+
// (e.g. a migration added a column the model never caught up to). PKs are
|
|
107
|
+
// excluded (DB-generated).
|
|
108
|
+
for (const dbCol of dbCols) {
|
|
109
|
+
if (dbCol.primaryKey)
|
|
110
|
+
continue;
|
|
111
|
+
if (!dbCol.nullable && !dbCol.hasDefault && !mappedDbColumns.has(dbCol.name)) {
|
|
112
|
+
findings.push({
|
|
113
|
+
entity: entityName,
|
|
114
|
+
table,
|
|
115
|
+
kind: "missing-in-model",
|
|
116
|
+
column: dbCol.name,
|
|
117
|
+
detail: `column \`${dbCol.name}\` is NOT NULL with no default but no model property maps to it — inserts will fail`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return findings;
|
|
122
|
+
}
|
|
123
|
+
// ─── Public API ──────────────────────────────────────────────────────
|
|
124
|
+
/**
|
|
125
|
+
* Reconcile every given entity against the live database. Pass the app's model
|
|
126
|
+
* classes (atlas has no global entity registry by design — mirror Lucid, where
|
|
127
|
+
* `ace` is pointed at your models). Returns a flat list of findings (empty when
|
|
128
|
+
* the schema and models agree).
|
|
129
|
+
*/
|
|
130
|
+
export async function checkSchema(entities, db, dialect) {
|
|
131
|
+
const findings = [];
|
|
132
|
+
for (const entity of entities) {
|
|
133
|
+
const meta = getEntityMetadata(entity);
|
|
134
|
+
if (!meta?.tableName)
|
|
135
|
+
continue; // not an @Entity — skip silently
|
|
136
|
+
const table = meta.tableName;
|
|
137
|
+
const entityName = entity.name;
|
|
138
|
+
const dbCols = await introspectTable(db, dialect, table);
|
|
139
|
+
if (dbCols === null) {
|
|
140
|
+
findings.push({
|
|
141
|
+
entity: entityName,
|
|
142
|
+
table,
|
|
143
|
+
kind: "missing-table",
|
|
144
|
+
column: table,
|
|
145
|
+
detail: `table \`${table}\` does not exist in the database — run your migrations`,
|
|
146
|
+
});
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const strategy = getNamingStrategy(entity);
|
|
150
|
+
findings.push(...reconcile(entityName, table, getColumnMetadata(entity), (p) => strategy.columnName(p), dbCols));
|
|
151
|
+
}
|
|
152
|
+
return findings;
|
|
153
|
+
}
|
|
154
|
+
/** Render findings as a didactic, Adonis-style diff (grouped per table). */
|
|
155
|
+
export function formatSchemaFindings(findings) {
|
|
156
|
+
if (findings.length === 0)
|
|
157
|
+
return "[atlas:check] schema OK — models match the database.";
|
|
158
|
+
const byTable = new Map();
|
|
159
|
+
for (const f of findings) {
|
|
160
|
+
const key = `${f.table} (${f.entity})`;
|
|
161
|
+
const list = byTable.get(key) ?? [];
|
|
162
|
+
list.push(f);
|
|
163
|
+
byTable.set(key, list);
|
|
164
|
+
}
|
|
165
|
+
const lines = [
|
|
166
|
+
`[atlas:check] ${findings.length} schema issue(s) found:`,
|
|
167
|
+
];
|
|
168
|
+
for (const [key, list] of byTable) {
|
|
169
|
+
lines.push(`\n ${key}`);
|
|
170
|
+
for (const f of list) {
|
|
171
|
+
const hint = f.suggestion ? ` — did you mean \`${f.suggestion}\`?` : "";
|
|
172
|
+
lines.push(` ✗ ${f.column}: ${f.detail}${hint}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return lines.join("\n");
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Boot-time guard: run {@link checkSchema} and either throw (fail-fast, for CI /
|
|
179
|
+
* dev startup) or warn (non-blocking). Returns the findings. `mode` defaults to
|
|
180
|
+
* `"throw"` — a schema mismatch is a misconfiguration that should stop the boot
|
|
181
|
+
* before requests serve stale assumptions.
|
|
182
|
+
*/
|
|
183
|
+
export async function verifySchema(entities, db, dialect, opts = {}) {
|
|
184
|
+
const findings = await checkSchema(entities, db, dialect);
|
|
185
|
+
if (findings.length > 0) {
|
|
186
|
+
const report = formatSchemaFindings(findings);
|
|
187
|
+
if ((opts.mode ?? "throw") === "throw") {
|
|
188
|
+
throw new Error(report);
|
|
189
|
+
}
|
|
190
|
+
console.warn(report);
|
|
191
|
+
}
|
|
192
|
+
return findings;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* CLI body: run the check, print the report (diff or the OK line), and return
|
|
196
|
+
* the process exit code (`0` = schema matches, `1` = drift). Used by the
|
|
197
|
+
* `atlas:check` console command; safe to call from any script.
|
|
198
|
+
*/
|
|
199
|
+
export async function runSchemaCheck(entities, db, dialect) {
|
|
200
|
+
const findings = await checkSchema(entities, db, dialect);
|
|
201
|
+
console.log(formatSchemaFindings(findings));
|
|
202
|
+
return findings.length > 0 ? 1 : 0;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=SchemaCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaCheck.js","sourceRoot":"","sources":["../../src/schema/SchemaCheck.ts"],"names":[],"mappings":"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"}
|