okmodel 0.8.0 → 0.9.0
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/README.md +14 -0
- package/dist/dialects/pg/ext/btree-gin.d.ts +26 -0
- package/dist/dialects/pg/ext/btree-gin.js +20 -0
- package/dist/dialects/pg/ext/btree-gist.d.ts +26 -0
- package/dist/dialects/pg/ext/btree-gist.js +20 -0
- package/dist/dialects/pg/ext/call.d.ts +53 -0
- package/dist/dialects/pg/ext/citext.js +1 -1
- package/dist/dialects/pg/ext/feature.d.ts +26 -0
- package/dist/dialects/pg/ext/fuzzystrmatch.d.ts +34 -0
- package/dist/dialects/pg/ext/fuzzystrmatch.js +33 -0
- package/dist/dialects/pg/ext/hstore.d.ts +41 -0
- package/dist/dialects/pg/ext/hstore.js +29 -0
- package/dist/dialects/pg/ext/index.d.ts +56 -0
- package/dist/dialects/pg/ext/index.js +1 -1
- package/dist/dialects/pg/ext/ltree.d.ts +41 -0
- package/dist/dialects/pg/ext/ltree.js +29 -0
- package/dist/dialects/pg/ext/pg-trgm.js +4 -13
- package/dist/dialects/pg/ext/pgcrypto.d.ts +33 -0
- package/dist/dialects/pg/ext/pgcrypto.js +33 -0
- package/dist/dialects/pg/ext/unaccent.d.ts +26 -0
- package/dist/dialects/pg/ext/unaccent.js +21 -0
- package/dist/dialects/pg/ext/using.d.ts +23 -0
- package/dist/dialects/pg/ext/versions.d.ts +36 -0
- package/dist/dialects/pg/external.d.ts +19 -0
- package/dist/dialects/pg/fn/index.js +4 -4
- package/dist/dialects/pg/index.d.ts +1 -0
- package/dist/dialects/pg/index.js +16 -11
- package/dist/dialects/pg/view/index.js +5 -5
- package/dist/dialects/pg/view/scratch.d.ts +4 -1
- package/dist/runtime/artifact-file.d.ts +22 -0
- package/dist/runtime/client.d.ts +10 -0
- package/dist/runtime/drift-detail.d.ts +2 -1
- package/dist/runtime/drift.d.ts +3 -10
- package/dist/runtime/pg/bun.js +4 -4
- package/dist/runtime/pg/neon.js +4 -4
- package/dist/runtime/pg/pg.js +4 -4
- package/dist/runtime/pg/pglite.js +4 -4
- package/dist/runtime/pg/postgresjs.js +4 -4
- package/dist/runtime/server-check.d.ts +36 -6
- package/dist/runtime/traits/index.js +5 -5
- package/dist/runtime/validate/index.js +1 -1
- package/dist/shared/{4m6hskg8.js → 0j6qe91y.js} +4 -4
- package/dist/shared/{14x60fbf.js → 1mxm04fy.js} +5 -5
- package/dist/shared/{b6d6p0zc.js → 2szgv6yj.js} +5 -5
- package/dist/shared/{f4jy1j7x.js → 2zdxkt7b.js} +909 -100
- package/dist/shared/{mnvjvqyp.js → 3456242y.js} +17 -17
- package/dist/shared/3t6kw83m.js +1 -1
- package/dist/shared/{6m78c8ss.js → 5kyb3tqx.js} +1 -1
- package/dist/shared/61bmrmhr.js +35 -0
- package/dist/shared/{zbqbmmrp.js → 62b603gr.js} +8 -8
- package/dist/shared/{jgqj11w4.js → 6f0z3hzh.js} +4 -0
- package/dist/shared/{dpc2r7rb.js → 6nae0spm.js} +150 -89
- package/dist/shared/{0wrea3jq.js → 71n0jmhc.js} +1 -1
- package/dist/shared/7ba5h6pb.js +17 -0
- package/dist/shared/{k86n8vq3.js → 8jesqsrk.js} +1 -1
- package/dist/shared/{qd9hhd8f.js → 8n688yjg.js} +1 -1
- package/dist/shared/{zgex00fd.js → 8qzkd9f3.js} +5 -5
- package/dist/shared/{mkrn359n.js → 90sg0w5a.js} +159 -31
- package/dist/shared/{7ghwamrf.js → 99qp9vtg.js} +1 -1
- package/dist/shared/{bxas03mq.js → 9dtgn1z2.js} +1 -1
- package/dist/shared/{p5nh3r8q.js → aksb89mn.js} +2 -2
- package/dist/shared/{wcrheftc.js → bphrgwz9.js} +2 -2
- package/dist/shared/{wz2a78mp.js → c3mvnq7a.js} +1 -1
- package/dist/shared/{pan0370z.js → ccsmhv9r.js} +24 -6
- package/dist/shared/{n0jmpgj1.js → cexb7z6b.js} +1 -1
- package/dist/shared/{wvdjznah.js → cf8zdz5p.js} +5 -5
- package/dist/shared/{3449rcae.js → ckz05z15.js} +4 -4
- package/dist/shared/{35q0n9tz.js → dd5pmnky.js} +7 -7
- package/dist/shared/{e8zyaqvj.js → ds229x4r.js} +1 -1
- package/dist/{tooling/shared/yw30vnq2.js → shared/e275q7sd.js} +1 -1
- package/dist/shared/{mfedzr74.js → ebhz8vh6.js} +4 -4
- package/dist/shared/{z581d7ny.js → fdsz3w80.js} +2 -2
- package/dist/shared/{sjk86yrx.js → fk9vef30.js} +84 -73
- package/dist/shared/{needfe47.js → g89fmz5s.js} +1 -1
- package/dist/shared/{m4xff2a6.js → ghqzdp94.js} +2 -2
- package/dist/shared/h9811jjm.js +17 -0
- package/dist/shared/{kj9d8maq.js → jpybhf98.js} +1 -1
- package/dist/shared/kzgrnckd.js +29 -0
- package/dist/shared/{agsfb86s.js → mazpbcdj.js} +4 -4
- package/dist/shared/{195pzzzz.js → mgaq2sd3.js} +10 -7
- package/dist/shared/{5mtf6cj3.js → mvmm3xpb.js} +5 -2
- package/dist/shared/{p3xbdcvt.js → myk8fswx.js} +55 -6
- package/dist/shared/{njga14v4.js → n306gqkd.js} +8 -8
- package/dist/shared/n5whk3mt.js +665 -0
- package/dist/shared/{bah9nbg3.js → npdftanb.js} +12 -20
- package/dist/shared/{16kvjebh.js → pg4ezgyf.js} +7 -26
- package/dist/{tooling/shared/08kemxjd.js → shared/pgsak1yw.js} +1 -1
- package/dist/shared/{jp36k7dp.js → qvwwp1mp.js} +61 -40
- package/dist/shared/rbxt795q.js +1766 -0
- package/dist/shared/{g5yc06ka.js → s7he5e5d.js} +1 -1
- package/dist/shared/{hfqmpasr.js → ss2kv2rs.js} +5 -5
- package/dist/shared/stfa9xcw.js +450 -0
- package/dist/{tooling/shared/rs1jb051.js → shared/tr64w5p0.js} +1 -1
- package/dist/shared/{jebgrkeq.js → tw1nvvfj.js} +2 -2
- package/dist/shared/{v1wad97q.js → wvtjg5m3.js} +1 -1
- package/dist/shared/xqacq37x.js +61 -0
- package/dist/shared/{n05z9nwz.js → xtsydxjg.js} +1 -1
- package/dist/shared/{jx2m62cs.js → xv8qj97g.js} +5 -5
- package/dist/shared/{63f4ksbz.js → xwhdcrm4.js} +1 -1
- package/dist/shared/{hm5f8jby.js → yvabyg9k.js} +6 -6
- package/dist/shared/yybhre6n.js +136 -0
- package/dist/shared/zdqf8k5d.js +8 -0
- package/dist/tooling/cli.js +94 -22
- package/dist/tooling/driver-run.js +15 -332
- package/dist/tooling/github/comment.d.ts +50 -0
- package/dist/tooling/github/post-comment.d.ts +17 -0
- package/dist/tooling/migrate/commands.d.ts +2 -1
- package/dist/tooling/migrate/config.d.ts +13 -0
- package/dist/tooling/migrate/export.d.ts +165 -0
- package/dist/tooling/migrate/ext-surface.d.ts +80 -0
- package/dist/tooling/migrate/ext.d.ts +31 -4
- package/dist/tooling/migrate/import-drizzle.d.ts +40 -0
- package/dist/tooling/migrate/index.d.ts +3 -0
- package/dist/tooling/migrate/index.js +55 -10
- package/dist/tooling/migrate/lint-rules.d.ts +18 -1
- package/dist/tooling/migrate/lint.d.ts +14 -1
- package/dist/tooling/migrate/place.d.ts +18 -0
- package/dist/tooling/migrate/plan-json.d.ts +65 -0
- package/dist/tooling/migrate/project.d.ts +10 -1
- package/dist/tooling/migrate/pull-emit.d.ts +98 -0
- package/dist/tooling/migrate/pull-routines.d.ts +126 -0
- package/dist/tooling/migrate/pull-verify.d.ts +26 -0
- package/dist/tooling/migrate/pull.d.ts +62 -0
- package/dist/tooling/migrate/reprint.d.ts +32 -0
- package/dist/tooling/migrate/sandbox.d.ts +8 -2
- package/dist/tooling/migrate/schema-api.d.ts +43 -0
- package/dist/tooling/migrate/sql-lex.d.ts +18 -0
- package/dist/tooling/shared/{3m1hkg7z.js → 04svnxxj.js} +4 -4
- package/dist/tooling/shared/{ppnnnvj8.js → 0j0jtse1.js} +1 -1
- package/dist/tooling/shared/{z8d7ptht.js → 0r05zhyq.js} +5 -5
- package/dist/tooling/shared/{a6pp9d12.js → 1800eymw.js} +3 -3
- package/dist/tooling/shared/{cmptmb4f.js → 35zemrmf.js} +1 -1
- package/dist/tooling/shared/{w7qe8sj1.js → 3rmaz3pq.js} +1 -1
- package/dist/{shared/q0cqt2sp.js → tooling/shared/3yn79q5m.js} +1 -1
- package/dist/tooling/shared/{2revefqt.js → 57btdkgm.js} +2 -2
- package/dist/tooling/shared/{ma2340rx.js → 5bmksndh.js} +2 -2
- package/dist/tooling/shared/{9xzm7hjg.js → 5p8km5jb.js} +3 -3
- package/dist/tooling/shared/{xhrnjch9.js → 5x3pf400.js} +3 -3
- package/dist/tooling/shared/{wwnekq5n.js → 5zrzffnk.js} +1 -1
- package/dist/tooling/shared/{p7f08ktn.js → 62fxpc1p.js} +7 -7
- package/dist/tooling/shared/{7ae7rjmn.js → 68tf18v4.js} +2 -2
- package/dist/tooling/shared/{rf83gr2d.js → 6vk28rjp.js} +7 -3
- package/dist/tooling/shared/76pv6qff.js +9 -0
- package/dist/tooling/shared/{bz2dqhab.js → 7aews1zg.js} +3 -3
- package/dist/tooling/shared/{9kazs5p6.js → 7b3xp9gc.js} +3 -3
- package/dist/tooling/shared/{4d2w25vw.js → 7pxncnzs.js} +2 -2
- package/dist/tooling/shared/{zvnhh1n0.js → 829fjxyw.js} +2 -2
- package/dist/tooling/shared/{dzx85q70.js → 8m5znpdt.js} +1 -1
- package/dist/tooling/shared/{g9ad4n80.js → 8yr7ges1.js} +7 -7
- package/dist/tooling/shared/{tn8gay14.js → 9qr9rkbh.js} +6 -6
- package/dist/tooling/shared/{8sqrsw3s.js → 9sfbtwsk.js} +3 -3
- package/dist/{shared/bnby0esn.js → tooling/shared/9wsnsvbf.js} +1 -1
- package/dist/tooling/shared/{aftb2mwr.js → a2xe04bm.js} +1 -1
- package/dist/tooling/shared/{nf7jmhfa.js → a4pzghha.js} +2 -2
- package/dist/tooling/shared/{y5656f0e.js → am04v8na.js} +5 -5
- package/dist/tooling/shared/{417zdsk7.js → asgr07mp.js} +5 -5
- package/dist/tooling/shared/{pqy21k24.js → c0xevn1h.js} +4 -4
- package/dist/tooling/shared/dhatassp.js +134 -0
- package/dist/tooling/shared/{spk1jg3r.js → ezqn88nj.js} +8 -8
- package/dist/tooling/shared/{6nyfyw70.js → f77nnfqy.js} +2 -2
- package/dist/tooling/shared/{wt7j7nf6.js → fh07z1dt.js} +1 -1
- package/dist/tooling/shared/{3rrw5w8f.js → gqwevek4.js} +1 -1
- package/dist/tooling/shared/{f9mphxej.js → hfq3n3bd.js} +346 -19
- package/dist/tooling/shared/{vs0t6qt8.js → j664qjrt.js} +2 -2
- package/dist/tooling/shared/{733a1tq3.js → jpgmjsx3.js} +3 -3
- package/dist/tooling/shared/{mtrqn2hn.js → jr2nmr81.js} +22 -30
- package/dist/{shared/mtw6jz76.js → tooling/shared/jsjjz875.js} +1 -1
- package/dist/tooling/shared/{2wtvc7rw.js → kbqnrs1x.js} +2 -2
- package/dist/tooling/shared/{gfvtj6d0.js → kz715295.js} +7 -7
- package/dist/tooling/shared/{a7q7t4n3.js → m3xt8b1h.js} +2 -2
- package/dist/tooling/shared/{dw08f3m8.js → m4hhb8aa.js} +2 -2
- package/dist/tooling/shared/{y031jct9.js → mw5npye0.js} +2 -2
- package/dist/tooling/shared/{vraj6d74.js → nxq95eb6.js} +3 -3
- package/dist/tooling/shared/{fb9k2qwd.js → qartgazh.js} +11 -30
- package/dist/tooling/shared/{xjs6zqtc.js → rcywj2w8.js} +9 -9
- package/dist/tooling/shared/{dy672fz6.js → s6qha57m.js} +2 -2
- package/dist/tooling/shared/{vx86qjv8.js → shjs0379.js} +3 -3
- package/dist/tooling/shared/{345tbc2k.js → sjwkt1pg.js} +1 -1
- package/dist/tooling/shared/{rq5kk8j6.js → stebqyyd.js} +3 -3
- package/dist/tooling/shared/{yk9mp7vb.js → t4xveemq.js} +4 -4
- package/dist/tooling/shared/{djydjpqt.js → t6zjeake.js} +5 -5
- package/dist/tooling/shared/{zhwnfyb2.js → tcwpjvxe.js} +1 -1
- package/dist/tooling/shared/{72fyg4zv.js → tpssp7ac.js} +1 -1
- package/dist/tooling/shared/{jne7b93p.js → v6j1ep6w.js} +3 -3
- package/dist/tooling/shared/{ec71zqgt.js → vwr2y833.js} +2 -2
- package/dist/tooling/shared/{j9t5s12a.js → w17sj05d.js} +2 -2
- package/dist/tooling/shared/{3tq8pnb8.js → w5d89rb4.js} +1 -1
- package/dist/tooling/shared/{smn6kz1p.js → wbwq1jsa.js} +2 -2
- package/dist/tooling/shared/{pwsytxm5.js → wezxf3h8.js} +1 -1
- package/dist/tooling/shared/{5bvw2nev.js → yb4kd19s.js} +1 -1
- package/dist/tooling/shared/{gmcf9cxf.js → ybdew6j7.js} +2 -2
- package/dist/tooling/shared/{ep8zh3bk.js → yfedr1zb.js} +1 -1
- package/dist/tooling/shared/{ddjtfgnx.js → yhp829bx.js} +3 -3
- package/dist/tooling/shared/{yfr8hzhm.js → ytk1tjs0.js} +1 -1
- package/dist/tooling/shared/{03k6res6.js → zs9aymcp.js} +1 -1
- package/dist/tooling/shared/zx3v9phv.js +8 -0
- package/dist/tooling/testing/index.js +2 -2
- package/package.json +38 -9
- package/dist/shared/fjpnhqan.js +0 -71
- package/dist/shared/n41w4fbz.js +0 -113
- package/dist/tooling/shared/pw8fgahx.js +0 -69
- /package/dist/shared/{ae4j5f42.js → mfvx6kjx.js} +0 -0
|
@@ -20,12 +20,11 @@ import {
|
|
|
20
20
|
compareText,
|
|
21
21
|
enumType,
|
|
22
22
|
domainType,
|
|
23
|
-
isDomain,
|
|
24
23
|
sameEnumLabels,
|
|
25
24
|
indexObjects,
|
|
26
25
|
orderIndexed,
|
|
27
|
-
creationOrder2,
|
|
28
26
|
quoteLiteral,
|
|
27
|
+
renderCatalog2,
|
|
29
28
|
clientGenerator,
|
|
30
29
|
readClientGenerator,
|
|
31
30
|
definition,
|
|
@@ -46,7 +45,7 @@ import {
|
|
|
46
45
|
jsonb,
|
|
47
46
|
quote,
|
|
48
47
|
primaryUrl
|
|
49
|
-
} from "./shared/
|
|
48
|
+
} from "./shared/hfq3n3bd.js";
|
|
50
49
|
import { createRequire } from "node:module";
|
|
51
50
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
52
51
|
|
|
@@ -693,322 +692,6 @@ function assertForeignKeys(objects, keys) {
|
|
|
693
692
|
}
|
|
694
693
|
}
|
|
695
694
|
|
|
696
|
-
// src/dialects/pg/ddl.ts
|
|
697
|
-
function quoteIdent(name) {
|
|
698
|
-
return `"${name.replaceAll('"', '""')}"`;
|
|
699
|
-
}
|
|
700
|
-
function renderCatalog(source, schema) {
|
|
701
|
-
const folded = foldedKeys(source);
|
|
702
|
-
const statements = [];
|
|
703
|
-
const ordered = creationOrder2(source);
|
|
704
|
-
const created = uniqueBeforeForeignKey(ordered);
|
|
705
|
-
for (const object of ordered) {
|
|
706
|
-
if (object.kind !== "type" || object.owner === "ignored")
|
|
707
|
-
continue;
|
|
708
|
-
const sql = createObjectSql(object, schema);
|
|
709
|
-
if (sql !== undefined)
|
|
710
|
-
statements.push(sql);
|
|
711
|
-
}
|
|
712
|
-
for (const object of created) {
|
|
713
|
-
if (object.kind === "type" || object.kind === "function" || object.kind === "trigger" || object.kind === "view" || object.kind === "materializedView" || object.kind === "policy" || ownedByView(object)) {
|
|
714
|
-
continue;
|
|
715
|
-
}
|
|
716
|
-
if (object.owner === "ignored")
|
|
717
|
-
continue;
|
|
718
|
-
const key = identityKey(object.identity);
|
|
719
|
-
if (object.kind === "table") {
|
|
720
|
-
statements.push(createTableSql(object, source, schema));
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
if (folded.has(key))
|
|
724
|
-
continue;
|
|
725
|
-
const sql = createObjectSql(object, schema);
|
|
726
|
-
if (sql !== undefined)
|
|
727
|
-
statements.push(sql);
|
|
728
|
-
}
|
|
729
|
-
for (const object of created) {
|
|
730
|
-
if (object.kind !== "policy" || object.owner === "ignored")
|
|
731
|
-
continue;
|
|
732
|
-
for (const step of policyCreatePlan(object, schema))
|
|
733
|
-
statements.push(step.sql);
|
|
734
|
-
}
|
|
735
|
-
for (const kind of ["function", "trigger"]) {
|
|
736
|
-
for (const object of ordered) {
|
|
737
|
-
if (object.kind !== kind || object.owner === "ignored")
|
|
738
|
-
continue;
|
|
739
|
-
const sql = createObjectSql(object, schema);
|
|
740
|
-
if (sql !== undefined)
|
|
741
|
-
statements.push(sql);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
for (const kind of ["view", "materializedView"]) {
|
|
745
|
-
for (const object of ordered) {
|
|
746
|
-
if (object.kind !== kind || object.owner === "ignored")
|
|
747
|
-
continue;
|
|
748
|
-
const sql = createObjectSql(object, schema);
|
|
749
|
-
if (sql !== undefined)
|
|
750
|
-
statements.push(sql);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
for (const object of ordered) {
|
|
754
|
-
if (!ownedByView(object) || object.owner === "ignored")
|
|
755
|
-
continue;
|
|
756
|
-
const sql = createObjectSql(object, schema);
|
|
757
|
-
if (sql !== undefined)
|
|
758
|
-
statements.push(sql);
|
|
759
|
-
}
|
|
760
|
-
return statements;
|
|
761
|
-
}
|
|
762
|
-
function uniqueBeforeForeignKey(objects) {
|
|
763
|
-
const uniques = objects.filter((object) => object.kind === "constraint" && object.definition.constraintKind === "unique");
|
|
764
|
-
if (uniques.length === 0)
|
|
765
|
-
return objects;
|
|
766
|
-
const emitted = new Set;
|
|
767
|
-
const result = [];
|
|
768
|
-
for (const object of objects) {
|
|
769
|
-
if (emitted.has(object))
|
|
770
|
-
continue;
|
|
771
|
-
if (object.kind === "constraint" && object.definition.constraintKind === "foreignKey") {
|
|
772
|
-
const target = object.definition.references;
|
|
773
|
-
if (target !== undefined && !coveredByPrimary(objects, target.parent, target.columns)) {
|
|
774
|
-
const columns = target.columns.join("\x00");
|
|
775
|
-
for (const unique of uniques) {
|
|
776
|
-
if (emitted.has(unique))
|
|
777
|
-
continue;
|
|
778
|
-
if (!sameRef(unique.identity.parent, target.parent))
|
|
779
|
-
continue;
|
|
780
|
-
if (unique.definition.columns.join("\x00") !== columns)
|
|
781
|
-
continue;
|
|
782
|
-
result.push(unique);
|
|
783
|
-
emitted.add(unique);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
result.push(object);
|
|
788
|
-
emitted.add(object);
|
|
789
|
-
}
|
|
790
|
-
return result;
|
|
791
|
-
}
|
|
792
|
-
function coveredByPrimary(objects, parent, columns) {
|
|
793
|
-
const key = columns.join("\x00");
|
|
794
|
-
return objects.some((object) => object.kind === "constraint" && object.definition.constraintKind === "primaryKey" && sameRef(object.identity.parent, parent) && object.definition.columns.join("\x00") === key);
|
|
795
|
-
}
|
|
796
|
-
function sameRef(left, right) {
|
|
797
|
-
if (left.name !== right.name || left.namespace.form !== right.namespace.form)
|
|
798
|
-
return false;
|
|
799
|
-
if (left.namespace.form === "static" && right.namespace.form === "static") {
|
|
800
|
-
return left.namespace.name === right.namespace.name;
|
|
801
|
-
}
|
|
802
|
-
return left.namespace.form === "template" && right.namespace.form === "template" ? left.namespace.pattern === right.namespace.pattern : false;
|
|
803
|
-
}
|
|
804
|
-
function ownedByView(object) {
|
|
805
|
-
if (object.kind !== "index")
|
|
806
|
-
return false;
|
|
807
|
-
return object.dependencies.some((edge) => edge.target.kind === "view" || edge.target.kind === "materializedView");
|
|
808
|
-
}
|
|
809
|
-
function createObjectSql(object, schema) {
|
|
810
|
-
switch (object.kind) {
|
|
811
|
-
case "column":
|
|
812
|
-
return `alter table ${qualify(schema, object.identity.parent.name)} add column ${columnSql(object)}`;
|
|
813
|
-
case "index":
|
|
814
|
-
return createIndexSql(object, schema);
|
|
815
|
-
case "constraint":
|
|
816
|
-
return `alter table ${qualify(schema, object.identity.parent.name)} add constraint ${quoteIdent(object.identity.name)} ${constraintBody(object, schema)}`;
|
|
817
|
-
case "sequence":
|
|
818
|
-
return createSequenceSql(object, schema);
|
|
819
|
-
case "type":
|
|
820
|
-
return createTypeSql(object, schema);
|
|
821
|
-
case "extension":
|
|
822
|
-
return createExtensionSql(object);
|
|
823
|
-
case "function":
|
|
824
|
-
return functionSql(object, schema, false);
|
|
825
|
-
case "trigger":
|
|
826
|
-
return triggerSql(object, schema);
|
|
827
|
-
case "view":
|
|
828
|
-
return viewSql(object, schema, false);
|
|
829
|
-
case "materializedView":
|
|
830
|
-
return materializedViewSql(object, schema);
|
|
831
|
-
case "table":
|
|
832
|
-
return;
|
|
833
|
-
default:
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
function functionSql(object, schema, replace) {
|
|
838
|
-
const definition = object.definition;
|
|
839
|
-
const args = definition.arguments.map((argument) => `${quoteIdent(argument.name)} ${argument.type}`).join(", ");
|
|
840
|
-
const head = `${replace ? "create or replace" : "create"} function ${qualify(schema, object.identity.name)}(${args})`;
|
|
841
|
-
const security = ` security ${definition.security}`;
|
|
842
|
-
const path = definition.searchPath === undefined ? "" : ` set search_path to ${definition.searchPath}`;
|
|
843
|
-
const tail = `returns ${definition.returns} language ${definition.language} ${definition.volatility}${security}${path}`;
|
|
844
|
-
if (definition.atomic)
|
|
845
|
-
return `${head} ${tail} ${definition.body}`;
|
|
846
|
-
return `${head} ${tail} as ${dollarQuote(definition.body)}`;
|
|
847
|
-
}
|
|
848
|
-
function viewSql(object, schema, replace) {
|
|
849
|
-
const verb = replace ? "create or replace view" : "create view";
|
|
850
|
-
const invoker = object.definition.securityInvoker === true ? " with (security_invoker = true)" : "";
|
|
851
|
-
return `${verb} ${qualify(schema, object.identity.name)}${invoker} as ${object.definition.query}`;
|
|
852
|
-
}
|
|
853
|
-
function policyCreatePlan(object, schema) {
|
|
854
|
-
const table = qualify(schema, object.identity.parent.name);
|
|
855
|
-
const name = quoteIdent(object.identity.name);
|
|
856
|
-
const command = object.definition.command === "all" ? "all" : "select";
|
|
857
|
-
const check = object.definition.command === "all" ? ` with check ${object.definition.expression}` : "";
|
|
858
|
-
const create = {
|
|
859
|
-
sql: `create policy ${name} on ${table} as permissive for ${command} using ${object.definition.expression}${check}`,
|
|
860
|
-
kind: "create-policy"
|
|
861
|
-
};
|
|
862
|
-
if (object.definition.command !== "all")
|
|
863
|
-
return [create];
|
|
864
|
-
return [
|
|
865
|
-
{ sql: `alter table ${table} enable row level security`, kind: "enable-rls" },
|
|
866
|
-
{ sql: `alter table ${table} force row level security`, kind: "enable-rls" },
|
|
867
|
-
create
|
|
868
|
-
];
|
|
869
|
-
}
|
|
870
|
-
function materializedViewSql(object, schema) {
|
|
871
|
-
return `create materialized view ${qualify(schema, object.identity.name)} as ${object.definition.query} with no data`;
|
|
872
|
-
}
|
|
873
|
-
function triggerSql(object, schema) {
|
|
874
|
-
const definition = object.definition;
|
|
875
|
-
const timing = definition.timing === "instead" ? "instead of" : definition.timing;
|
|
876
|
-
const events = definition.events.map((event) => {
|
|
877
|
-
if (event !== "update" || definition.updateOf === undefined)
|
|
878
|
-
return event;
|
|
879
|
-
return `update of ${definition.updateOf.map((column) => quoteIdent(column)).join(", ")}`;
|
|
880
|
-
}).join(" or ");
|
|
881
|
-
const when = definition.when === undefined ? "" : ` when (${definition.when})`;
|
|
882
|
-
const args = definition.calls.argTypes.join(", ");
|
|
883
|
-
const fn = `${qualify(schema, definition.calls.name)}(${args})`;
|
|
884
|
-
return `create trigger ${quoteIdent(object.identity.name)} ${timing} ${events} on ${qualify(schema, object.identity.parent.name)} for each ${definition.level}${when} execute function ${fn}`;
|
|
885
|
-
}
|
|
886
|
-
function dollarQuote(body) {
|
|
887
|
-
let tag = "okm";
|
|
888
|
-
while (body.includes(`$${tag}$`))
|
|
889
|
-
tag = `${tag}_`;
|
|
890
|
-
return `$${tag}$${body}$${tag}$`;
|
|
891
|
-
}
|
|
892
|
-
function identitySequence(sequence, source) {
|
|
893
|
-
const key = identityKey(sequence.identity);
|
|
894
|
-
return source.objects.some((object) => {
|
|
895
|
-
if (object.kind !== "column" || object.definition.identity === undefined)
|
|
896
|
-
return false;
|
|
897
|
-
return object.dependencies.some((edge) => identityKey(edge.target) === key);
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
function foldedKeys(source) {
|
|
901
|
-
const keys = new Set;
|
|
902
|
-
for (const object of source.objects) {
|
|
903
|
-
if (object.kind === "column")
|
|
904
|
-
keys.add(identityKey(object.identity));
|
|
905
|
-
if (object.kind === "constraint" && object.definition.constraintKind === "primaryKey") {
|
|
906
|
-
keys.add(identityKey(object.identity));
|
|
907
|
-
}
|
|
908
|
-
if (object.kind === "sequence" && identitySequence(object, source)) {
|
|
909
|
-
keys.add(identityKey(object.identity));
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
return keys;
|
|
913
|
-
}
|
|
914
|
-
function createTableSql(tableObject, source, schema) {
|
|
915
|
-
const parent = tableObject.identity.name;
|
|
916
|
-
const columns = source.objects.filter((object) => object.kind === "column" && object.identity.parent.name === parent);
|
|
917
|
-
const primary = source.objects.find((object) => object.kind === "constraint" && object.definition.constraintKind === "primaryKey" && object.identity.parent.name === parent);
|
|
918
|
-
const lines = columns.map((column) => columnSql(column));
|
|
919
|
-
if (primary !== undefined) {
|
|
920
|
-
const cols = primary.definition.columns.map((name) => quoteIdent(name)).join(", ");
|
|
921
|
-
lines.push(`constraint ${quoteIdent(primary.identity.name)} primary key (${cols})`);
|
|
922
|
-
}
|
|
923
|
-
const partition = tableObject.definition.partition;
|
|
924
|
-
const tail = partition === undefined ? "" : ` partition by ${partition.method} (${partition.columns.map((name) => quoteIdent(name)).join(", ")})`;
|
|
925
|
-
return `create table ${qualify(schema, parent)} (
|
|
926
|
-
${lines.join(`,
|
|
927
|
-
`)}
|
|
928
|
-
)${tail}`;
|
|
929
|
-
}
|
|
930
|
-
function collateSql(collation) {
|
|
931
|
-
if (collation === undefined)
|
|
932
|
-
return "";
|
|
933
|
-
return ` collate ${quoteIdent(collation)}`;
|
|
934
|
-
}
|
|
935
|
-
function createTypeSql(object, schema) {
|
|
936
|
-
if (isDomain(object.definition)) {
|
|
937
|
-
const name = object.identity.name;
|
|
938
|
-
const constraint = quoteIdent(fitIdentifier(`${name}_check`));
|
|
939
|
-
return `create domain ${qualify(schema, name)} as ${object.definition.base} constraint ${constraint} check (${object.definition.check})`;
|
|
940
|
-
}
|
|
941
|
-
const labels = object.definition.labels.map((label) => quoteLiteral(label)).join(", ");
|
|
942
|
-
return `create type ${qualify(schema, object.identity.name)} as enum (${labels})`;
|
|
943
|
-
}
|
|
944
|
-
function columnSql(column) {
|
|
945
|
-
const definition = column.definition;
|
|
946
|
-
let sql = `${quoteIdent(column.identity.name)} ${definition.dataType}${collateSql(definition.collation)}`;
|
|
947
|
-
if (definition.identity !== undefined) {
|
|
948
|
-
sql += definition.identity.always ? " generated always as identity" : " generated by default as identity";
|
|
949
|
-
} else if (definition.generated !== undefined) {
|
|
950
|
-
sql += ` generated always as (${definition.generated.expression}) stored`;
|
|
951
|
-
}
|
|
952
|
-
if (!definition.nullable)
|
|
953
|
-
sql += " not null";
|
|
954
|
-
if (definition.defaultExpression !== undefined)
|
|
955
|
-
sql += ` default ${definition.defaultExpression}`;
|
|
956
|
-
return sql;
|
|
957
|
-
}
|
|
958
|
-
function createIndexSql(object, schema) {
|
|
959
|
-
const unique = object.definition.unique ? "unique " : "";
|
|
960
|
-
const where = object.definition.predicate === undefined ? "" : ` where ${object.definition.predicate}`;
|
|
961
|
-
const expression = object.definition.expression;
|
|
962
|
-
const name = quoteIdent(object.identity.name);
|
|
963
|
-
const on = qualify(schema, object.identity.parent.name);
|
|
964
|
-
if (expression !== undefined && expression.startsWith("using ")) {
|
|
965
|
-
return `create ${unique}index ${name} on ${on} ${expression}${where}`;
|
|
966
|
-
}
|
|
967
|
-
const target = expression !== undefined ? `(${expression})` : object.definition.columns.map((column) => quoteIdent(column)).join(", ");
|
|
968
|
-
return `create ${unique}index ${name} on ${on} (${target})${where}`;
|
|
969
|
-
}
|
|
970
|
-
function createExtensionSql(object) {
|
|
971
|
-
const version = object.definition.version;
|
|
972
|
-
const pinned = version !== undefined && /^\d+(?:\.\d+)*$/.test(version) ? ` version ${quoteLiteral(version)}` : "";
|
|
973
|
-
return `create extension ${quoteIdent(object.identity.name)} schema ${quoteIdent(object.definition.schema)}${pinned}`;
|
|
974
|
-
}
|
|
975
|
-
function createSequenceSql(object, schema) {
|
|
976
|
-
const definition = object.definition;
|
|
977
|
-
const cycle = definition.cycle ? " cycle" : "";
|
|
978
|
-
return `create sequence ${qualify(schema, object.identity.name)} as ${definition.dataType} start ${definition.start} increment ${definition.increment}${cycle}`;
|
|
979
|
-
}
|
|
980
|
-
function constraintBody(object, schema) {
|
|
981
|
-
const definition = object.definition;
|
|
982
|
-
const columns = definition.columns.map((name) => quoteIdent(name)).join(", ");
|
|
983
|
-
switch (definition.constraintKind) {
|
|
984
|
-
case "primaryKey":
|
|
985
|
-
return `primary key (${columns})`;
|
|
986
|
-
case "unique": {
|
|
987
|
-
const nulls = definition.nullsNotDistinct ? " nulls not distinct" : "";
|
|
988
|
-
return `unique${nulls} (${columns})${deferClause(definition)}`;
|
|
989
|
-
}
|
|
990
|
-
case "check":
|
|
991
|
-
return `check (${definition.expression ?? "true"})${deferClause(definition)}`;
|
|
992
|
-
case "foreignKey": {
|
|
993
|
-
const references = definition.references;
|
|
994
|
-
const target = references === undefined ? "" : ` references ${qualify(schema, references.parent.name)} (${references.columns.map((name) => quoteIdent(name)).join(", ")})`;
|
|
995
|
-
const onDelete = references?.onDelete === undefined ? "" : ` on delete ${references.onDelete}`;
|
|
996
|
-
const onUpdate = references?.onUpdate === undefined ? "" : ` on update ${references.onUpdate}`;
|
|
997
|
-
return `foreign key (${columns})${target}${onDelete}${onUpdate}${deferClause(definition)}`;
|
|
998
|
-
}
|
|
999
|
-
default:
|
|
1000
|
-
return definition.constraintKind;
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
function deferClause(definition) {
|
|
1004
|
-
if (!definition.deferrable)
|
|
1005
|
-
return "";
|
|
1006
|
-
return ` deferrable initially ${definition.initially}`;
|
|
1007
|
-
}
|
|
1008
|
-
function qualify(schema, name) {
|
|
1009
|
-
return `${quoteIdent(schema)}.${quoteIdent(name)}`;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
695
|
// src/contracts/location.ts
|
|
1013
696
|
function callerLocation(skip) {
|
|
1014
697
|
const lines = new Error().stack?.split(`
|
|
@@ -1221,7 +904,7 @@ function openFilters(table, relations, spec, hiddenFields) {
|
|
|
1221
904
|
}
|
|
1222
905
|
return {
|
|
1223
906
|
parse(query) {
|
|
1224
|
-
return import("./shared/
|
|
907
|
+
return import("./shared/zs9aymcp.js").then((mod) => mod.parseQuery(allow, sort, query, nested));
|
|
1225
908
|
}
|
|
1226
909
|
};
|
|
1227
910
|
}
|
|
@@ -3777,7 +3460,7 @@ function registerTxSuite(suite) {
|
|
|
3777
3460
|
max: options.max ?? 4,
|
|
3778
3461
|
...options.url ? { url: options.url } : {}
|
|
3779
3462
|
});
|
|
3780
|
-
const ddl = [...
|
|
3463
|
+
const ddl = [...renderCatalog2(built.catalog, schemaName), ...options.sql ?? []];
|
|
3781
3464
|
for (const statement of ddl)
|
|
3782
3465
|
await (setup ?? pool).execute(statement);
|
|
3783
3466
|
const db = await suite.connect(pool, {
|
|
@@ -4622,7 +4305,7 @@ function skipped(test, reason) {
|
|
|
4622
4305
|
return skipFor(test, reason, (name) => `${name} (${reason})`);
|
|
4623
4306
|
}
|
|
4624
4307
|
async function openSuiteAdmin(url) {
|
|
4625
|
-
const { openPostgres } = await import("./shared/
|
|
4308
|
+
const { openPostgres } = await import("./shared/wezxf3h8.js");
|
|
4626
4309
|
return openPostgres(url);
|
|
4627
4310
|
}
|
|
4628
4311
|
async function failure2(promise) {
|
|
@@ -4720,8 +4403,8 @@ async function loadTarget(driver, url) {
|
|
|
4720
4403
|
}
|
|
4721
4404
|
async function firstParty(driver, url) {
|
|
4722
4405
|
if (driver === "pglite") {
|
|
4723
|
-
const adapter = await import("./shared/
|
|
4724
|
-
const runtime = await import("./shared/
|
|
4406
|
+
const adapter = await import("./shared/s6qha57m.js");
|
|
4407
|
+
const runtime = await import("./shared/5p8km5jb.js");
|
|
4725
4408
|
return {
|
|
4726
4409
|
name: "pglite",
|
|
4727
4410
|
capabilities: adapter.capabilities,
|
|
@@ -4736,8 +4419,8 @@ async function firstParty(driver, url) {
|
|
|
4736
4419
|
if (url === undefined)
|
|
4737
4420
|
throw new Error(`okm driver test ${driver} needs --url or DATABASE_URL.`);
|
|
4738
4421
|
if (driver === "postgresjs") {
|
|
4739
|
-
const adapter = await import("./shared/
|
|
4740
|
-
const runtime = await import("./shared/
|
|
4422
|
+
const adapter = await import("./shared/mw5npye0.js");
|
|
4423
|
+
const runtime = await import("./shared/nxq95eb6.js");
|
|
4741
4424
|
return networked("postgres.js", adapter.capabilities, true, url, (config) => adapter.open({
|
|
4742
4425
|
url: config.url ?? url,
|
|
4743
4426
|
max: config.max,
|
|
@@ -4746,8 +4429,8 @@ async function firstParty(driver, url) {
|
|
|
4746
4429
|
}), (pool, options) => runtime.connect(pool, options));
|
|
4747
4430
|
}
|
|
4748
4431
|
if (driver === "pg") {
|
|
4749
|
-
const adapter = await import("./shared/
|
|
4750
|
-
const runtime = await import("./shared/
|
|
4432
|
+
const adapter = await import("./shared/a4pzghha.js");
|
|
4433
|
+
const runtime = await import("./shared/v6j1ep6w.js");
|
|
4751
4434
|
return networked("node-postgres", adapter.capabilities, true, url, (config) => adapter.open({
|
|
4752
4435
|
url: config.url ?? url,
|
|
4753
4436
|
max: config.max,
|
|
@@ -4756,8 +4439,8 @@ async function firstParty(driver, url) {
|
|
|
4756
4439
|
}), (pool, options) => runtime.connect(pool, options));
|
|
4757
4440
|
}
|
|
4758
4441
|
if (driver === "neon") {
|
|
4759
|
-
const adapter = await import("./shared/
|
|
4760
|
-
const runtime = await import("./shared/
|
|
4442
|
+
const adapter = await import("./shared/68tf18v4.js");
|
|
4443
|
+
const runtime = await import("./shared/9sfbtwsk.js");
|
|
4761
4444
|
return networked("neon", adapter.capabilities, false, url, (config) => adapter.open({
|
|
4762
4445
|
url: config.url ?? url,
|
|
4763
4446
|
max: config.max,
|
|
@@ -4768,8 +4451,8 @@ async function firstParty(driver, url) {
|
|
|
4768
4451
|
if (typeof Bun === "undefined" || typeof Bun.SQL !== "function") {
|
|
4769
4452
|
throw new Error("bun runs only under Bun.");
|
|
4770
4453
|
}
|
|
4771
|
-
const adapter = await import("./shared/
|
|
4772
|
-
const runtime = await import("./shared/
|
|
4454
|
+
const adapter = await import("./shared/m3xt8b1h.js");
|
|
4455
|
+
const runtime = await import("./shared/1800eymw.js");
|
|
4773
4456
|
return networked("bun.sql", adapter.capabilities, false, url, (config) => adapter.open({
|
|
4774
4457
|
url: config.url ?? url,
|
|
4775
4458
|
max: config.max,
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull-request comment for `okm migrate plan --json` (D279).
|
|
3
|
+
*
|
|
4
|
+
* The text comes from the plan document. It does not read the human plan.
|
|
5
|
+
*/
|
|
6
|
+
import { type PlanDocument } from "../migrate/plan-json.js";
|
|
7
|
+
/**
|
|
8
|
+
* Hidden marker that identifies the sticky comment.
|
|
9
|
+
*
|
|
10
|
+
* A later push updates the comment whose body contains this marker.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PLAN_COMMENT_MARKER = "<!-- okmodel-migrate-plan -->";
|
|
13
|
+
/** A comment the sticky update may replace. */
|
|
14
|
+
export type StickyComment = {
|
|
15
|
+
readonly id: number;
|
|
16
|
+
readonly body: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Renders the plan comment.
|
|
20
|
+
*
|
|
21
|
+
* The first heading is the strictest class. Each step is one table row
|
|
22
|
+
* with its class and lock. The lock is the plan's lock line, including a
|
|
23
|
+
* row estimate when the plan printed one. Lint findings keep their codes.
|
|
24
|
+
*
|
|
25
|
+
* @param plan - Document from `okm migrate plan --json`
|
|
26
|
+
* @returns Markdown, including {@link PLAN_COMMENT_MARKER}
|
|
27
|
+
*/
|
|
28
|
+
export declare function renderPlanComment(plan: PlanDocument): string;
|
|
29
|
+
/**
|
|
30
|
+
* Comment body for a plan file, or a status line when the file is not a document.
|
|
31
|
+
*
|
|
32
|
+
* The status line records exit codes only. It does not include command text.
|
|
33
|
+
*
|
|
34
|
+
* @param text - Stdout of `okm migrate plan --json`, when the file exists
|
|
35
|
+
* @param checkStatus - Exit code of `okm migrate check`
|
|
36
|
+
* @param planStatus - Exit code of `okm migrate plan --json`
|
|
37
|
+
* @returns The comment body
|
|
38
|
+
*/
|
|
39
|
+
export declare function planCommentBody(text: string | undefined, checkStatus: string, planStatus: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* The comment to update, when one already carries the marker.
|
|
42
|
+
*
|
|
43
|
+
* The first match wins. A missing match means the caller creates a comment.
|
|
44
|
+
*
|
|
45
|
+
* @param comments - Comments already on the pull request
|
|
46
|
+
* @returns The id to update, or `undefined` to create one
|
|
47
|
+
*/
|
|
48
|
+
export declare function stickyCommentTarget(comments: readonly StickyComment[]): {
|
|
49
|
+
readonly updateId: number;
|
|
50
|
+
} | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates or updates the sticky plan comment (D279).
|
|
3
|
+
*
|
|
4
|
+
* Uses `GITHUB_TOKEN` only. The workflow needs `pull-requests: write`.
|
|
5
|
+
* The token is not written to stdout or stderr.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Posts the plan comment for one pull request.
|
|
9
|
+
*
|
|
10
|
+
* An existing comment that contains the marker is updated. Otherwise a
|
|
11
|
+
* comment is created. The body comes from {@link planCommentBody}.
|
|
12
|
+
*
|
|
13
|
+
* @param planPath - File written by `okm migrate plan --json`
|
|
14
|
+
* @param checkStatus - Exit code of `okm migrate check`
|
|
15
|
+
* @param planStatus - Exit code of `okm migrate plan --json`
|
|
16
|
+
*/
|
|
17
|
+
export declare function postPlanComment(planPath: string, checkStatus: string, planStatus: string): Promise<void>;
|
|
@@ -22,7 +22,8 @@ export declare function formatFailure(error: unknown, verbose?: boolean): string
|
|
|
22
22
|
* Runs one `okm` invocation.
|
|
23
23
|
*
|
|
24
24
|
* `--version` stays in the bin. This function handles `build`, `check`,
|
|
25
|
-
* `generate`, `dev`, `push`, `seed`, `ext list`, `ext check`, `
|
|
25
|
+
* `generate`, `dev`, `push`, `seed`, `ext list`, `ext check`, `ext scaffold`,
|
|
26
|
+
* `ext test`, `doctor`,
|
|
26
27
|
* `driver test`, and `migrate plan`, `apply`, `status`, and `check`.
|
|
27
28
|
*
|
|
28
29
|
* @param argv - Arguments after the program name
|
|
@@ -45,6 +45,19 @@ export type MigrateConfig = {
|
|
|
45
45
|
* migration.
|
|
46
46
|
*/
|
|
47
47
|
readonly lintFrom?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Postgres schema this catalog owns.
|
|
50
|
+
*
|
|
51
|
+
* Omitted means `public`. `schema()` still compiles `public`. Tooling
|
|
52
|
+
* places the catalog here before it plans, and stores `okm_meta` here.
|
|
53
|
+
*/
|
|
54
|
+
readonly namespace?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Snapshots from `okm catalog export`, one path per owning catalog.
|
|
57
|
+
*
|
|
58
|
+
* `external()` tables are verified against these files.
|
|
59
|
+
*/
|
|
60
|
+
readonly external?: readonly string[];
|
|
48
61
|
/**
|
|
49
62
|
* Batched backfill (D195).
|
|
50
63
|
*
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `okm catalog export` and the check that a dependent catalog runs.
|
|
3
|
+
*
|
|
4
|
+
* The snapshot is derived from the schema source. It stores the catalog
|
|
5
|
+
* hash and, separately, a logical identity. It has no function and no
|
|
6
|
+
* connection URL. Column names and types are what a dependent verifies.
|
|
7
|
+
*/
|
|
8
|
+
import type { Catalog } from "../../contracts/catalog/types.js";
|
|
9
|
+
import type { MigrateConfig } from "./config.js";
|
|
10
|
+
import type { Finding } from "./lint.js";
|
|
11
|
+
/** Snapshot file format. Not the logical schema format. */
|
|
12
|
+
export declare const EXPORT_FORMAT = 1;
|
|
13
|
+
/** Logical schema format. A hash change does not move this. */
|
|
14
|
+
export declare const LOGICAL_FORMAT = 1;
|
|
15
|
+
/** One column a dependent verifies. No default and no expression. */
|
|
16
|
+
export type ExportColumn = {
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly type: string;
|
|
19
|
+
readonly nullable: boolean;
|
|
20
|
+
};
|
|
21
|
+
/** One table in a snapshot. */
|
|
22
|
+
export type ExportTable = {
|
|
23
|
+
readonly namespace: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly columns: readonly ExportColumn[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Logical schema identity.
|
|
29
|
+
*
|
|
30
|
+
* `namespace` and `name` name the schema. `format` is {@link LOGICAL_FORMAT}.
|
|
31
|
+
* None of these is the catalog hash.
|
|
32
|
+
*/
|
|
33
|
+
export type LogicalIdentity = {
|
|
34
|
+
readonly namespace: string;
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly format: typeof LOGICAL_FORMAT;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* A catalog snapshot.
|
|
40
|
+
*
|
|
41
|
+
* `catalogHash` is the physical identity. `logical` is not that hash.
|
|
42
|
+
* `database` is the database name only, never a URL.
|
|
43
|
+
*/
|
|
44
|
+
export type CatalogSnapshot = {
|
|
45
|
+
readonly format: typeof EXPORT_FORMAT;
|
|
46
|
+
readonly logical: LogicalIdentity;
|
|
47
|
+
readonly catalogHash: string;
|
|
48
|
+
readonly database?: string;
|
|
49
|
+
readonly tables: readonly ExportTable[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Builds a snapshot from a placed catalog.
|
|
53
|
+
*
|
|
54
|
+
* @param source - Catalog tooling plans, after namespace placement
|
|
55
|
+
* @param namespace - `defineConfig({ namespace })`, or `public`
|
|
56
|
+
* @param database - Database name, when the config has a target URL
|
|
57
|
+
* @returns A snapshot with no functions and no connection URL
|
|
58
|
+
*/
|
|
59
|
+
export declare function snapshotFromCatalog(source: Catalog, namespace: string, database?: string): CatalogSnapshot;
|
|
60
|
+
/**
|
|
61
|
+
* Serializes a snapshot.
|
|
62
|
+
*
|
|
63
|
+
* The same catalog returns the same bytes, including the trailing newline.
|
|
64
|
+
*
|
|
65
|
+
* @param snapshot - Snapshot to write
|
|
66
|
+
* @returns UTF-8 JSON
|
|
67
|
+
*/
|
|
68
|
+
export declare function serializeSnapshot(snapshot: CatalogSnapshot): string;
|
|
69
|
+
/**
|
|
70
|
+
* Reads a snapshot file.
|
|
71
|
+
*
|
|
72
|
+
* A missing file and a file that is not this format are OKM1841.
|
|
73
|
+
*
|
|
74
|
+
* @param path - Absolute or project-relative path, as the message should name it
|
|
75
|
+
* @param text - File contents
|
|
76
|
+
* @returns The snapshot
|
|
77
|
+
*/
|
|
78
|
+
export declare function parseSnapshot(path: string, text: string): CatalogSnapshot;
|
|
79
|
+
/**
|
|
80
|
+
* Database name from a Postgres URL.
|
|
81
|
+
*
|
|
82
|
+
* The user, password, host, and query are not returned.
|
|
83
|
+
*
|
|
84
|
+
* @param url - Target URL
|
|
85
|
+
* @returns The path segment, or `undefined` when the URL has none
|
|
86
|
+
*/
|
|
87
|
+
export declare function databaseName(url: string): string | undefined;
|
|
88
|
+
/**
|
|
89
|
+
* Namespace `defineConfig` asked for.
|
|
90
|
+
*
|
|
91
|
+
* Omitted means `public`.
|
|
92
|
+
*
|
|
93
|
+
* @param config - Project config
|
|
94
|
+
* @returns The schema name
|
|
95
|
+
*/
|
|
96
|
+
export declare function catalogNamespace(config: MigrateConfig): string;
|
|
97
|
+
/**
|
|
98
|
+
* Loads the snapshots named by `defineConfig({ external })`.
|
|
99
|
+
*
|
|
100
|
+
* A missing path is OKM1841.
|
|
101
|
+
*
|
|
102
|
+
* @param cwd - Project directory
|
|
103
|
+
* @param config - Project config
|
|
104
|
+
* @returns One snapshot per path, in config order
|
|
105
|
+
*/
|
|
106
|
+
export declare function loadSnapshots(cwd: string, config: MigrateConfig): readonly LoadedSnapshot[];
|
|
107
|
+
/** A snapshot and the config path that named it. */
|
|
108
|
+
export type LoadedSnapshot = {
|
|
109
|
+
readonly path: string;
|
|
110
|
+
readonly snapshot: CatalogSnapshot;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* SQL table name to the namespace recorded in a snapshot.
|
|
114
|
+
*
|
|
115
|
+
* @param snapshots - Loaded exports
|
|
116
|
+
* @returns The map `placeCatalog` reads
|
|
117
|
+
*/
|
|
118
|
+
export declare function externalNamespaceMap(snapshots: readonly LoadedSnapshot[]): ReadonlyMap<string, string>;
|
|
119
|
+
/**
|
|
120
|
+
* Cross-catalog foreign keys, as `okm check` warnings.
|
|
121
|
+
*
|
|
122
|
+
* A key inside one namespace is not coupling. The warning does not fail the check.
|
|
123
|
+
*
|
|
124
|
+
* @param source - Placed catalog
|
|
125
|
+
* @returns One warning per foreign key whose namespaces differ
|
|
126
|
+
*/
|
|
127
|
+
export declare function couplingFindings(source: Catalog): readonly Finding[];
|
|
128
|
+
/**
|
|
129
|
+
* Checks external tables against the snapshot files.
|
|
130
|
+
*
|
|
131
|
+
* This does not open a connection. With no `external` paths, a
|
|
132
|
+
* `withOwner(..., "external")` table stays hands-off and is not OKM1841.
|
|
133
|
+
* When paths are set, a missing file, a table the snapshots do not list,
|
|
134
|
+
* or columns that differ is OKM1841.
|
|
135
|
+
*
|
|
136
|
+
* @param cwd - Project directory
|
|
137
|
+
* @param config - Project config
|
|
138
|
+
* @param source - Placed catalog
|
|
139
|
+
*/
|
|
140
|
+
export declare function assertSnapshots(cwd: string, config: MigrateConfig, source: Catalog): void;
|
|
141
|
+
/**
|
|
142
|
+
* Checks external tables against the connected database.
|
|
143
|
+
*
|
|
144
|
+
* A different database name on a cross-catalog foreign key is OKM1842.
|
|
145
|
+
* A hash or column mismatch is a stale snapshot. A missing relation is
|
|
146
|
+
* a missing object. Both are OKM1841.
|
|
147
|
+
*
|
|
148
|
+
* @param url - Target URL
|
|
149
|
+
* @param source - Placed catalog
|
|
150
|
+
* @param snapshots - Files {@link assertSnapshots} already read
|
|
151
|
+
*/
|
|
152
|
+
export declare function assertLiveExternal(url: string, source: Catalog, snapshots: readonly LoadedSnapshot[]): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Writes the snapshot for one project.
|
|
155
|
+
*
|
|
156
|
+
* `--json` prints the bytes. `--out` writes them. With neither, the bytes
|
|
157
|
+
* are printed.
|
|
158
|
+
*
|
|
159
|
+
* @param cwd - Project directory
|
|
160
|
+
* @param config - Project config
|
|
161
|
+
* @param source - Placed catalog
|
|
162
|
+
* @param args - Arguments after `export`
|
|
163
|
+
* @returns Stdout, including a trailing newline
|
|
164
|
+
*/
|
|
165
|
+
export declare function renderExport(cwd: string, config: MigrateConfig, source: Catalog, args: readonly string[]): string;
|