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.
Files changed (202) hide show
  1. package/README.md +14 -0
  2. package/dist/dialects/pg/ext/btree-gin.d.ts +26 -0
  3. package/dist/dialects/pg/ext/btree-gin.js +20 -0
  4. package/dist/dialects/pg/ext/btree-gist.d.ts +26 -0
  5. package/dist/dialects/pg/ext/btree-gist.js +20 -0
  6. package/dist/dialects/pg/ext/call.d.ts +53 -0
  7. package/dist/dialects/pg/ext/citext.js +1 -1
  8. package/dist/dialects/pg/ext/feature.d.ts +26 -0
  9. package/dist/dialects/pg/ext/fuzzystrmatch.d.ts +34 -0
  10. package/dist/dialects/pg/ext/fuzzystrmatch.js +33 -0
  11. package/dist/dialects/pg/ext/hstore.d.ts +41 -0
  12. package/dist/dialects/pg/ext/hstore.js +29 -0
  13. package/dist/dialects/pg/ext/index.d.ts +56 -0
  14. package/dist/dialects/pg/ext/index.js +1 -1
  15. package/dist/dialects/pg/ext/ltree.d.ts +41 -0
  16. package/dist/dialects/pg/ext/ltree.js +29 -0
  17. package/dist/dialects/pg/ext/pg-trgm.js +4 -13
  18. package/dist/dialects/pg/ext/pgcrypto.d.ts +33 -0
  19. package/dist/dialects/pg/ext/pgcrypto.js +33 -0
  20. package/dist/dialects/pg/ext/unaccent.d.ts +26 -0
  21. package/dist/dialects/pg/ext/unaccent.js +21 -0
  22. package/dist/dialects/pg/ext/using.d.ts +23 -0
  23. package/dist/dialects/pg/ext/versions.d.ts +36 -0
  24. package/dist/dialects/pg/external.d.ts +19 -0
  25. package/dist/dialects/pg/fn/index.js +4 -4
  26. package/dist/dialects/pg/index.d.ts +1 -0
  27. package/dist/dialects/pg/index.js +16 -11
  28. package/dist/dialects/pg/view/index.js +5 -5
  29. package/dist/dialects/pg/view/scratch.d.ts +4 -1
  30. package/dist/runtime/artifact-file.d.ts +22 -0
  31. package/dist/runtime/client.d.ts +10 -0
  32. package/dist/runtime/drift-detail.d.ts +2 -1
  33. package/dist/runtime/drift.d.ts +3 -10
  34. package/dist/runtime/pg/bun.js +4 -4
  35. package/dist/runtime/pg/neon.js +4 -4
  36. package/dist/runtime/pg/pg.js +4 -4
  37. package/dist/runtime/pg/pglite.js +4 -4
  38. package/dist/runtime/pg/postgresjs.js +4 -4
  39. package/dist/runtime/server-check.d.ts +36 -6
  40. package/dist/runtime/traits/index.js +5 -5
  41. package/dist/runtime/validate/index.js +1 -1
  42. package/dist/shared/{4m6hskg8.js → 0j6qe91y.js} +4 -4
  43. package/dist/shared/{14x60fbf.js → 1mxm04fy.js} +5 -5
  44. package/dist/shared/{b6d6p0zc.js → 2szgv6yj.js} +5 -5
  45. package/dist/shared/{f4jy1j7x.js → 2zdxkt7b.js} +909 -100
  46. package/dist/shared/{mnvjvqyp.js → 3456242y.js} +17 -17
  47. package/dist/shared/3t6kw83m.js +1 -1
  48. package/dist/shared/{6m78c8ss.js → 5kyb3tqx.js} +1 -1
  49. package/dist/shared/61bmrmhr.js +35 -0
  50. package/dist/shared/{zbqbmmrp.js → 62b603gr.js} +8 -8
  51. package/dist/shared/{jgqj11w4.js → 6f0z3hzh.js} +4 -0
  52. package/dist/shared/{dpc2r7rb.js → 6nae0spm.js} +150 -89
  53. package/dist/shared/{0wrea3jq.js → 71n0jmhc.js} +1 -1
  54. package/dist/shared/7ba5h6pb.js +17 -0
  55. package/dist/shared/{k86n8vq3.js → 8jesqsrk.js} +1 -1
  56. package/dist/shared/{qd9hhd8f.js → 8n688yjg.js} +1 -1
  57. package/dist/shared/{zgex00fd.js → 8qzkd9f3.js} +5 -5
  58. package/dist/shared/{mkrn359n.js → 90sg0w5a.js} +159 -31
  59. package/dist/shared/{7ghwamrf.js → 99qp9vtg.js} +1 -1
  60. package/dist/shared/{bxas03mq.js → 9dtgn1z2.js} +1 -1
  61. package/dist/shared/{p5nh3r8q.js → aksb89mn.js} +2 -2
  62. package/dist/shared/{wcrheftc.js → bphrgwz9.js} +2 -2
  63. package/dist/shared/{wz2a78mp.js → c3mvnq7a.js} +1 -1
  64. package/dist/shared/{pan0370z.js → ccsmhv9r.js} +24 -6
  65. package/dist/shared/{n0jmpgj1.js → cexb7z6b.js} +1 -1
  66. package/dist/shared/{wvdjznah.js → cf8zdz5p.js} +5 -5
  67. package/dist/shared/{3449rcae.js → ckz05z15.js} +4 -4
  68. package/dist/shared/{35q0n9tz.js → dd5pmnky.js} +7 -7
  69. package/dist/shared/{e8zyaqvj.js → ds229x4r.js} +1 -1
  70. package/dist/{tooling/shared/yw30vnq2.js → shared/e275q7sd.js} +1 -1
  71. package/dist/shared/{mfedzr74.js → ebhz8vh6.js} +4 -4
  72. package/dist/shared/{z581d7ny.js → fdsz3w80.js} +2 -2
  73. package/dist/shared/{sjk86yrx.js → fk9vef30.js} +84 -73
  74. package/dist/shared/{needfe47.js → g89fmz5s.js} +1 -1
  75. package/dist/shared/{m4xff2a6.js → ghqzdp94.js} +2 -2
  76. package/dist/shared/h9811jjm.js +17 -0
  77. package/dist/shared/{kj9d8maq.js → jpybhf98.js} +1 -1
  78. package/dist/shared/kzgrnckd.js +29 -0
  79. package/dist/shared/{agsfb86s.js → mazpbcdj.js} +4 -4
  80. package/dist/shared/{195pzzzz.js → mgaq2sd3.js} +10 -7
  81. package/dist/shared/{5mtf6cj3.js → mvmm3xpb.js} +5 -2
  82. package/dist/shared/{p3xbdcvt.js → myk8fswx.js} +55 -6
  83. package/dist/shared/{njga14v4.js → n306gqkd.js} +8 -8
  84. package/dist/shared/n5whk3mt.js +665 -0
  85. package/dist/shared/{bah9nbg3.js → npdftanb.js} +12 -20
  86. package/dist/shared/{16kvjebh.js → pg4ezgyf.js} +7 -26
  87. package/dist/{tooling/shared/08kemxjd.js → shared/pgsak1yw.js} +1 -1
  88. package/dist/shared/{jp36k7dp.js → qvwwp1mp.js} +61 -40
  89. package/dist/shared/rbxt795q.js +1766 -0
  90. package/dist/shared/{g5yc06ka.js → s7he5e5d.js} +1 -1
  91. package/dist/shared/{hfqmpasr.js → ss2kv2rs.js} +5 -5
  92. package/dist/shared/stfa9xcw.js +450 -0
  93. package/dist/{tooling/shared/rs1jb051.js → shared/tr64w5p0.js} +1 -1
  94. package/dist/shared/{jebgrkeq.js → tw1nvvfj.js} +2 -2
  95. package/dist/shared/{v1wad97q.js → wvtjg5m3.js} +1 -1
  96. package/dist/shared/xqacq37x.js +61 -0
  97. package/dist/shared/{n05z9nwz.js → xtsydxjg.js} +1 -1
  98. package/dist/shared/{jx2m62cs.js → xv8qj97g.js} +5 -5
  99. package/dist/shared/{63f4ksbz.js → xwhdcrm4.js} +1 -1
  100. package/dist/shared/{hm5f8jby.js → yvabyg9k.js} +6 -6
  101. package/dist/shared/yybhre6n.js +136 -0
  102. package/dist/shared/zdqf8k5d.js +8 -0
  103. package/dist/tooling/cli.js +94 -22
  104. package/dist/tooling/driver-run.js +15 -332
  105. package/dist/tooling/github/comment.d.ts +50 -0
  106. package/dist/tooling/github/post-comment.d.ts +17 -0
  107. package/dist/tooling/migrate/commands.d.ts +2 -1
  108. package/dist/tooling/migrate/config.d.ts +13 -0
  109. package/dist/tooling/migrate/export.d.ts +165 -0
  110. package/dist/tooling/migrate/ext-surface.d.ts +80 -0
  111. package/dist/tooling/migrate/ext.d.ts +31 -4
  112. package/dist/tooling/migrate/import-drizzle.d.ts +40 -0
  113. package/dist/tooling/migrate/index.d.ts +3 -0
  114. package/dist/tooling/migrate/index.js +55 -10
  115. package/dist/tooling/migrate/lint-rules.d.ts +18 -1
  116. package/dist/tooling/migrate/lint.d.ts +14 -1
  117. package/dist/tooling/migrate/place.d.ts +18 -0
  118. package/dist/tooling/migrate/plan-json.d.ts +65 -0
  119. package/dist/tooling/migrate/project.d.ts +10 -1
  120. package/dist/tooling/migrate/pull-emit.d.ts +98 -0
  121. package/dist/tooling/migrate/pull-routines.d.ts +126 -0
  122. package/dist/tooling/migrate/pull-verify.d.ts +26 -0
  123. package/dist/tooling/migrate/pull.d.ts +62 -0
  124. package/dist/tooling/migrate/reprint.d.ts +32 -0
  125. package/dist/tooling/migrate/sandbox.d.ts +8 -2
  126. package/dist/tooling/migrate/schema-api.d.ts +43 -0
  127. package/dist/tooling/migrate/sql-lex.d.ts +18 -0
  128. package/dist/tooling/shared/{3m1hkg7z.js → 04svnxxj.js} +4 -4
  129. package/dist/tooling/shared/{ppnnnvj8.js → 0j0jtse1.js} +1 -1
  130. package/dist/tooling/shared/{z8d7ptht.js → 0r05zhyq.js} +5 -5
  131. package/dist/tooling/shared/{a6pp9d12.js → 1800eymw.js} +3 -3
  132. package/dist/tooling/shared/{cmptmb4f.js → 35zemrmf.js} +1 -1
  133. package/dist/tooling/shared/{w7qe8sj1.js → 3rmaz3pq.js} +1 -1
  134. package/dist/{shared/q0cqt2sp.js → tooling/shared/3yn79q5m.js} +1 -1
  135. package/dist/tooling/shared/{2revefqt.js → 57btdkgm.js} +2 -2
  136. package/dist/tooling/shared/{ma2340rx.js → 5bmksndh.js} +2 -2
  137. package/dist/tooling/shared/{9xzm7hjg.js → 5p8km5jb.js} +3 -3
  138. package/dist/tooling/shared/{xhrnjch9.js → 5x3pf400.js} +3 -3
  139. package/dist/tooling/shared/{wwnekq5n.js → 5zrzffnk.js} +1 -1
  140. package/dist/tooling/shared/{p7f08ktn.js → 62fxpc1p.js} +7 -7
  141. package/dist/tooling/shared/{7ae7rjmn.js → 68tf18v4.js} +2 -2
  142. package/dist/tooling/shared/{rf83gr2d.js → 6vk28rjp.js} +7 -3
  143. package/dist/tooling/shared/76pv6qff.js +9 -0
  144. package/dist/tooling/shared/{bz2dqhab.js → 7aews1zg.js} +3 -3
  145. package/dist/tooling/shared/{9kazs5p6.js → 7b3xp9gc.js} +3 -3
  146. package/dist/tooling/shared/{4d2w25vw.js → 7pxncnzs.js} +2 -2
  147. package/dist/tooling/shared/{zvnhh1n0.js → 829fjxyw.js} +2 -2
  148. package/dist/tooling/shared/{dzx85q70.js → 8m5znpdt.js} +1 -1
  149. package/dist/tooling/shared/{g9ad4n80.js → 8yr7ges1.js} +7 -7
  150. package/dist/tooling/shared/{tn8gay14.js → 9qr9rkbh.js} +6 -6
  151. package/dist/tooling/shared/{8sqrsw3s.js → 9sfbtwsk.js} +3 -3
  152. package/dist/{shared/bnby0esn.js → tooling/shared/9wsnsvbf.js} +1 -1
  153. package/dist/tooling/shared/{aftb2mwr.js → a2xe04bm.js} +1 -1
  154. package/dist/tooling/shared/{nf7jmhfa.js → a4pzghha.js} +2 -2
  155. package/dist/tooling/shared/{y5656f0e.js → am04v8na.js} +5 -5
  156. package/dist/tooling/shared/{417zdsk7.js → asgr07mp.js} +5 -5
  157. package/dist/tooling/shared/{pqy21k24.js → c0xevn1h.js} +4 -4
  158. package/dist/tooling/shared/dhatassp.js +134 -0
  159. package/dist/tooling/shared/{spk1jg3r.js → ezqn88nj.js} +8 -8
  160. package/dist/tooling/shared/{6nyfyw70.js → f77nnfqy.js} +2 -2
  161. package/dist/tooling/shared/{wt7j7nf6.js → fh07z1dt.js} +1 -1
  162. package/dist/tooling/shared/{3rrw5w8f.js → gqwevek4.js} +1 -1
  163. package/dist/tooling/shared/{f9mphxej.js → hfq3n3bd.js} +346 -19
  164. package/dist/tooling/shared/{vs0t6qt8.js → j664qjrt.js} +2 -2
  165. package/dist/tooling/shared/{733a1tq3.js → jpgmjsx3.js} +3 -3
  166. package/dist/tooling/shared/{mtrqn2hn.js → jr2nmr81.js} +22 -30
  167. package/dist/{shared/mtw6jz76.js → tooling/shared/jsjjz875.js} +1 -1
  168. package/dist/tooling/shared/{2wtvc7rw.js → kbqnrs1x.js} +2 -2
  169. package/dist/tooling/shared/{gfvtj6d0.js → kz715295.js} +7 -7
  170. package/dist/tooling/shared/{a7q7t4n3.js → m3xt8b1h.js} +2 -2
  171. package/dist/tooling/shared/{dw08f3m8.js → m4hhb8aa.js} +2 -2
  172. package/dist/tooling/shared/{y031jct9.js → mw5npye0.js} +2 -2
  173. package/dist/tooling/shared/{vraj6d74.js → nxq95eb6.js} +3 -3
  174. package/dist/tooling/shared/{fb9k2qwd.js → qartgazh.js} +11 -30
  175. package/dist/tooling/shared/{xjs6zqtc.js → rcywj2w8.js} +9 -9
  176. package/dist/tooling/shared/{dy672fz6.js → s6qha57m.js} +2 -2
  177. package/dist/tooling/shared/{vx86qjv8.js → shjs0379.js} +3 -3
  178. package/dist/tooling/shared/{345tbc2k.js → sjwkt1pg.js} +1 -1
  179. package/dist/tooling/shared/{rq5kk8j6.js → stebqyyd.js} +3 -3
  180. package/dist/tooling/shared/{yk9mp7vb.js → t4xveemq.js} +4 -4
  181. package/dist/tooling/shared/{djydjpqt.js → t6zjeake.js} +5 -5
  182. package/dist/tooling/shared/{zhwnfyb2.js → tcwpjvxe.js} +1 -1
  183. package/dist/tooling/shared/{72fyg4zv.js → tpssp7ac.js} +1 -1
  184. package/dist/tooling/shared/{jne7b93p.js → v6j1ep6w.js} +3 -3
  185. package/dist/tooling/shared/{ec71zqgt.js → vwr2y833.js} +2 -2
  186. package/dist/tooling/shared/{j9t5s12a.js → w17sj05d.js} +2 -2
  187. package/dist/tooling/shared/{3tq8pnb8.js → w5d89rb4.js} +1 -1
  188. package/dist/tooling/shared/{smn6kz1p.js → wbwq1jsa.js} +2 -2
  189. package/dist/tooling/shared/{pwsytxm5.js → wezxf3h8.js} +1 -1
  190. package/dist/tooling/shared/{5bvw2nev.js → yb4kd19s.js} +1 -1
  191. package/dist/tooling/shared/{gmcf9cxf.js → ybdew6j7.js} +2 -2
  192. package/dist/tooling/shared/{ep8zh3bk.js → yfedr1zb.js} +1 -1
  193. package/dist/tooling/shared/{ddjtfgnx.js → yhp829bx.js} +3 -3
  194. package/dist/tooling/shared/{yfr8hzhm.js → ytk1tjs0.js} +1 -1
  195. package/dist/tooling/shared/{03k6res6.js → zs9aymcp.js} +1 -1
  196. package/dist/tooling/shared/zx3v9phv.js +8 -0
  197. package/dist/tooling/testing/index.js +2 -2
  198. package/package.json +38 -9
  199. package/dist/shared/fjpnhqan.js +0 -71
  200. package/dist/shared/n41w4fbz.js +0 -113
  201. package/dist/tooling/shared/pw8fgahx.js +0 -69
  202. /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/f9mphxej.js";
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/03k6res6.js").then((mod) => mod.parseQuery(allow, sort, query, nested));
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 = [...renderCatalog(built.catalog, schemaName), ...options.sql ?? []];
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/pwsytxm5.js");
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/dy672fz6.js");
4724
- const runtime = await import("./shared/9xzm7hjg.js");
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/y031jct9.js");
4740
- const runtime = await import("./shared/vraj6d74.js");
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/nf7jmhfa.js");
4750
- const runtime = await import("./shared/jne7b93p.js");
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/7ae7rjmn.js");
4760
- const runtime = await import("./shared/8sqrsw3s.js");
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/a7q7t4n3.js");
4772
- const runtime = await import("./shared/a6pp9d12.js");
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`, `doctor`,
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;