@intentius/chant-lexicon-sql 0.118.0 → 0.118.1
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.
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* git-ignored paths, child projects and the project's `exclude` globs are
|
|
9
9
|
* left out. A file whose first lines carry `-- chant-discovery-skip` (or the
|
|
10
10
|
* `/* chant-discovery-skip *\/` form) is not read, for SQL that is not schema:
|
|
11
|
-
* seed data, a migration, a query.
|
|
11
|
+
* seed data, a migration, a query. Nor is a file under a `migrations`
|
|
12
|
+
* directory (#3713): versioned migrations and an ORM's generated migrations
|
|
13
|
+
* are `ALTER`s and repeated `CREATE`s of objects declared elsewhere, and a
|
|
14
|
+
* build of the project root, as `chant lifecycle diff` and an ApplyOp's plan
|
|
15
|
+
* run with no `sourceDir`, walks into them.
|
|
12
16
|
*
|
|
13
17
|
* The dialect is the declarations': a project whose templates are Postgres
|
|
14
18
|
* reads its files as Postgres. With no templates it is `sql.dialect`, and
|
|
@@ -19,6 +23,10 @@ import type { BuildRootContext, BuildRootContribution } from "@intentius/chant/l
|
|
|
19
23
|
import { type SqlDialect } from "../dialects.js";
|
|
20
24
|
/** Whether a file is a `.sql` file to read: the name, and no skip or generated marker. */
|
|
21
25
|
export declare function isSqlSourceFile(name: string, full: string): boolean;
|
|
26
|
+
/** A directory whose `.sql` files are migrations, never declarations. */
|
|
27
|
+
export declare const MIGRATIONS_DIR = "migrations";
|
|
28
|
+
/** Whether `file` sits under a {@link MIGRATIONS_DIR} directory below `sourceDir`. */
|
|
29
|
+
export declare function inMigrationsDir(sourceDir: string, file: string): boolean;
|
|
22
30
|
/** The dialect the project's `.sql` files are read as. */
|
|
23
31
|
export declare function filesDialect(entities: ReadonlyMap<string, Declarable> | undefined, config: Record<string, unknown>): SqlDialect;
|
|
24
32
|
/** The `buildRoots` contribution: every `.sql` file's declarations, or nothing when the source directory holds none. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-root.d.ts","sourceRoot":"","sources":["../../src/files/build-root.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"build-root.d.ts","sourceRoot":"","sources":["../../src/files/build-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAGxF,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ5D,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAInE;AAED,yEAAyE;AACzE,eAAO,MAAM,cAAc,eAAe,CAAC;AAE3C,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAExE;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAY/H;AAED,wHAAwH;AACxH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAO7F"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "dee03b1b2c3883aa14ff3fb1868f4d6f28e6771cd19654ab48cc4b2e92530520",
|
|
5
5
|
"meta.json": "44b1dcfa5b5e5be2239fdc9614ab6c11d3f1461d64e61d572e3658af6c96aa68",
|
|
6
6
|
"types/index.d.ts": "0286ebb367773e84c76818b0f69cb14cff8328fd2f8c65ed87563c8d5815458c",
|
|
7
7
|
"rules/postgres-templates.ts": "da6e305bc2ff3d0d64a20925fe588e051c2a4b556b37f2581c61c314ef7c580d",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"rules/sqlpg117.ts": "3d5c2d57ccdee3cf91c3ba3cb6363750787a850df8ebd75e9cc3f33113303827",
|
|
58
58
|
"rules/sqlpg118.ts": "e2a40a88a9374c4d99d02118ca4c60877ba0c6eb1ce603a93b24f5fd23d81dde"
|
|
59
59
|
},
|
|
60
|
-
"composite": "
|
|
60
|
+
"composite": "870e87be62c02d9d259b98eb5c9f9928db21950ffd6a569e0f1df10268cea4e3"
|
|
61
61
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-sql",
|
|
3
|
-
"version": "0.118.
|
|
3
|
+
"version": "0.118.1",
|
|
4
4
|
"description": "SQL lexicon for chant — database schema as typed declarations, one dialect at a time; ClickHouse first, with types read from a pinned server's catalog",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"typescript": "^5.9.3"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"@intentius/chant": "^0.118.
|
|
73
|
+
"@intentius/chant": "^0.118.1",
|
|
74
74
|
"typescript": "^5.9.3"
|
|
75
75
|
}
|
|
76
76
|
}
|
package/src/files/build-root.ts
CHANGED
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* git-ignored paths, child projects and the project's `exclude` globs are
|
|
9
9
|
* left out. A file whose first lines carry `-- chant-discovery-skip` (or the
|
|
10
10
|
* `/* chant-discovery-skip *\/` form) is not read, for SQL that is not schema:
|
|
11
|
-
* seed data, a migration, a query.
|
|
11
|
+
* seed data, a migration, a query. Nor is a file under a `migrations`
|
|
12
|
+
* directory (#3713): versioned migrations and an ORM's generated migrations
|
|
13
|
+
* are `ALTER`s and repeated `CREATE`s of objects declared elsewhere, and a
|
|
14
|
+
* build of the project root, as `chant lifecycle diff` and an ApplyOp's plan
|
|
15
|
+
* run with no `sourceDir`, walks into them.
|
|
12
16
|
*
|
|
13
17
|
* The dialect is the declarations': a project whose templates are Postgres
|
|
14
18
|
* reads its files as Postgres. With no templates it is `sql.dialect`, and
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
*/
|
|
17
21
|
|
|
18
22
|
import { readFileSync } from "node:fs";
|
|
19
|
-
import { relative, resolve } from "node:path";
|
|
23
|
+
import { relative, resolve, sep } from "node:path";
|
|
20
24
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
21
25
|
import type { BuildRootContext, BuildRootContribution } from "@intentius/chant/lexicon";
|
|
22
26
|
import { findSourceFiles, hasDiscoveryMarkerSync } from "@intentius/chant/discovery/files";
|
|
@@ -36,6 +40,14 @@ export function isSqlSourceFile(name: string, full: string): boolean {
|
|
|
36
40
|
return !SQL_SKIP_MARKER.test(readHead(full, 1024));
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
/** A directory whose `.sql` files are migrations, never declarations. */
|
|
44
|
+
export const MIGRATIONS_DIR = "migrations";
|
|
45
|
+
|
|
46
|
+
/** Whether `file` sits under a {@link MIGRATIONS_DIR} directory below `sourceDir`. */
|
|
47
|
+
export function inMigrationsDir(sourceDir: string, file: string): boolean {
|
|
48
|
+
return relative(sourceDir, file).split(sep).slice(0, -1).includes(MIGRATIONS_DIR);
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
/** The dialect the project's `.sql` files are read as. */
|
|
40
52
|
export function filesDialect(entities: ReadonlyMap<string, Declarable> | undefined, config: Record<string, unknown>): SqlDialect {
|
|
41
53
|
for (const e of entities?.values() ?? []) {
|
|
@@ -54,7 +66,7 @@ export function filesDialect(entities: ReadonlyMap<string, Declarable> | undefin
|
|
|
54
66
|
/** The `buildRoots` contribution: every `.sql` file's declarations, or nothing when the source directory holds none. */
|
|
55
67
|
export async function sqlFilesBuildRoot(ctx: BuildRootContext): Promise<BuildRootContribution> {
|
|
56
68
|
const sourceDir = ctx.sourceDir ?? resolve(ctx.projectRoot, typeof ctx.config.sourceDir === "string" ? ctx.config.sourceDir : ".");
|
|
57
|
-
const files = (await findSourceFiles(sourceDir, isSqlSourceFile)).sort();
|
|
69
|
+
const files = (await findSourceFiles(sourceDir, isSqlSourceFile)).filter((f) => !inMigrationsDir(sourceDir, f)).sort();
|
|
58
70
|
if (files.length === 0) return { entities: new Map() };
|
|
59
71
|
const dialect = filesDialect(ctx.entities, ctx.config);
|
|
60
72
|
const sources = files.map((f) => ({ origin: relative(ctx.projectRoot, f) || f, ddl: readFileSync(f, "utf8") }));
|
package/src/sql-files.test.ts
CHANGED
|
@@ -174,6 +174,38 @@ export const activeUsers = view\`CREATE VIEW app.active_users AS SELECT id FROM
|
|
|
174
174
|
});
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
+
describe("SQL that is not schema, in a build of the project root (#3713)", () => {
|
|
178
|
+
const dirs: string[] = [];
|
|
179
|
+
afterAll(async () => {
|
|
180
|
+
for (const d of dirs) await rm(d, { recursive: true, force: true });
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("a .sql file under a migrations directory, at any depth, is not read", async () => {
|
|
184
|
+
const dir = await project("migrations", {
|
|
185
|
+
"app.ts": `import { schema, table } from "@intentius/chant-lexicon-sql/postgres";\nexport const app = schema\`CREATE SCHEMA app\`;\nexport const users = table\`CREATE TABLE app.users (id bigint)\`;\n`,
|
|
186
|
+
});
|
|
187
|
+
dirs.push(dir);
|
|
188
|
+
await mkdir(join(dir, "src", "migrations", "20261010T0000-add-email"), { recursive: true });
|
|
189
|
+
await writeFile(join(dir, "src", "migrations", "20261010T0000-add-email", "migration.sql"), "ALTER TABLE app.users ADD COLUMN email text;\n");
|
|
190
|
+
await mkdir(join(dir, "src", "prisma", "migrations", "0001_init"), { recursive: true });
|
|
191
|
+
await writeFile(join(dir, "src", "prisma", "migrations", "0001_init", "migration.sql"), "CREATE TABLE app.users (id bigint);\n");
|
|
192
|
+
const { errors, doc } = await buildProject(dir);
|
|
193
|
+
expect(errors).toEqual([]);
|
|
194
|
+
expect(doc!.applyOrder).toEqual(["app", "users"]);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("a file named migrations.sql, or in a directory that only starts with the word, is still read", async () => {
|
|
198
|
+
const dir = await project("not-migrations", { "app.ts": `import { schema } from "@intentius/chant-lexicon-sql/postgres";\nexport const app = schema\`CREATE SCHEMA app\`;\n` });
|
|
199
|
+
dirs.push(dir);
|
|
200
|
+
await writeFile(join(dir, "src", "migrations.sql"), "CREATE TABLE app.a (id bigint);\n");
|
|
201
|
+
await mkdir(join(dir, "src", "migrations-old"), { recursive: true });
|
|
202
|
+
await writeFile(join(dir, "src", "migrations-old", "b.sql"), "CREATE TABLE app.b (id bigint);\n");
|
|
203
|
+
const { errors, doc } = await buildProject(dir);
|
|
204
|
+
expect(errors).toEqual([]);
|
|
205
|
+
expect([...doc!.applyOrder].sort()).toEqual(["a", "app", "b"]);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
177
209
|
describe("references between a file's objects", () => {
|
|
178
210
|
test("a bare name where SQL names an object is a reference, and a cycle is an error", async () => {
|
|
179
211
|
const { sqlFileEntities } = await import("./sql-files");
|