okmodel 0.8.0 → 0.9.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.
Files changed (237) hide show
  1. package/README.md +23 -1
  2. package/dist/adapters/pg/bunsql-extra.d.ts +5 -5
  3. package/dist/adapters/pg/bunsql.d.ts +6 -2
  4. package/dist/adapters/pg/nodepostgres.d.ts +16 -1
  5. package/dist/adapters/pg/postgres-extra.d.ts +3 -17
  6. package/dist/adapters/pg/postgresjs.d.ts +2 -1
  7. package/dist/contracts/driver.d.ts +3 -2
  8. package/dist/contracts/error.d.ts +1 -1
  9. package/dist/dialects/pg/errors.d.ts +2 -0
  10. package/dist/dialects/pg/ext/btree-gin.d.ts +26 -0
  11. package/dist/dialects/pg/ext/btree-gin.js +20 -0
  12. package/dist/dialects/pg/ext/btree-gist.d.ts +26 -0
  13. package/dist/dialects/pg/ext/btree-gist.js +20 -0
  14. package/dist/dialects/pg/ext/call.d.ts +53 -0
  15. package/dist/dialects/pg/ext/citext.js +1 -1
  16. package/dist/dialects/pg/ext/feature.d.ts +26 -0
  17. package/dist/dialects/pg/ext/fuzzystrmatch.d.ts +34 -0
  18. package/dist/dialects/pg/ext/fuzzystrmatch.js +33 -0
  19. package/dist/dialects/pg/ext/hstore.d.ts +41 -0
  20. package/dist/dialects/pg/ext/hstore.js +29 -0
  21. package/dist/dialects/pg/ext/index.d.ts +56 -0
  22. package/dist/dialects/pg/ext/index.js +1 -1
  23. package/dist/dialects/pg/ext/ltree.d.ts +41 -0
  24. package/dist/dialects/pg/ext/ltree.js +29 -0
  25. package/dist/dialects/pg/ext/pg-trgm.js +4 -13
  26. package/dist/dialects/pg/ext/pgcrypto.d.ts +33 -0
  27. package/dist/dialects/pg/ext/pgcrypto.js +33 -0
  28. package/dist/dialects/pg/ext/unaccent.d.ts +26 -0
  29. package/dist/dialects/pg/ext/unaccent.js +21 -0
  30. package/dist/dialects/pg/ext/using.d.ts +23 -0
  31. package/dist/dialects/pg/ext/versions.d.ts +36 -0
  32. package/dist/dialects/pg/external.d.ts +19 -0
  33. package/dist/dialects/pg/filters.d.ts +2 -2
  34. package/dist/dialects/pg/fn/index.js +5 -5
  35. package/dist/dialects/pg/index.d.ts +1 -0
  36. package/dist/dialects/pg/index.js +19 -14
  37. package/dist/dialects/pg/introspect.d.ts +12 -0
  38. package/dist/dialects/pg/view/index.js +7 -7
  39. package/dist/dialects/pg/view/scratch.d.ts +4 -1
  40. package/dist/runtime/artifact-file.d.ts +22 -0
  41. package/dist/runtime/client.d.ts +10 -0
  42. package/dist/runtime/drift-detail.d.ts +2 -1
  43. package/dist/runtime/drift.d.ts +3 -10
  44. package/dist/runtime/param-limit.d.ts +20 -0
  45. package/dist/runtime/pg/bun.js +4 -4
  46. package/dist/runtime/pg/neon.js +4 -4
  47. package/dist/runtime/pg/pg.js +4 -4
  48. package/dist/runtime/pg/pglite.js +4 -4
  49. package/dist/runtime/pg/postgresjs.js +11 -11
  50. package/dist/runtime/server-check.d.ts +36 -6
  51. package/dist/runtime/tenancy/index.js +1 -1
  52. package/dist/runtime/traits/index.js +6 -6
  53. package/dist/runtime/validate/index.js +2 -2
  54. package/dist/runtime/write.d.ts +1 -1
  55. package/dist/shared/{4m6hskg8.js → 0j6qe91y.js} +4 -4
  56. package/dist/shared/{6m78c8ss.js → 1h5h1rf5.js} +1 -1
  57. package/dist/shared/{4vbf83xx.js → 2vcnpf0n.js} +1 -1
  58. package/dist/shared/{qd9hhd8f.js → 3ap5hxvj.js} +2 -1
  59. package/dist/shared/{v1wad97q.js → 3d7a80fq.js} +1 -1
  60. package/dist/shared/{wcrheftc.js → 3dr444ny.js} +58 -79
  61. package/dist/shared/{hm5f8jby.js → 3vvpcphd.js} +8 -7
  62. package/dist/shared/{760ppr76.js → 4a3mmhhe.js} +2 -2
  63. package/dist/shared/{mkrn359n.js → 4pkz5nvw.js} +222 -39
  64. package/dist/shared/{agsfb86s.js → 4te76xc5.js} +4 -4
  65. package/dist/shared/{63f4ksbz.js → 60y4ahmw.js} +1 -1
  66. package/dist/shared/61bmrmhr.js +35 -0
  67. package/dist/shared/{bxas03mq.js → 63qjmhnp.js} +100 -17
  68. package/dist/shared/{g5yc06ka.js → 67w3kn71.js} +1 -1
  69. package/dist/shared/{jgqj11w4.js → 6f0z3hzh.js} +4 -0
  70. package/dist/shared/{njga14v4.js → 6vfvsdkt.js} +10 -8
  71. package/dist/shared/{kj9d8maq.js → 6xqvesa5.js} +1 -1
  72. package/dist/shared/8gdbty5v.js +665 -0
  73. package/dist/shared/{pan0370z.js → 8ma6drzr.js} +211 -30
  74. package/dist/shared/{mnvjvqyp.js → 8p2bgye0.js} +124 -32
  75. package/dist/shared/{mfedzr74.js → 8qwqrxed.js} +14 -6
  76. package/dist/shared/{hfqmpasr.js → 8v7vzpgt.js} +11 -8
  77. package/dist/shared/{7ghwamrf.js → 99qp9vtg.js} +1 -1
  78. package/dist/shared/{zgex00fd.js → ak61ye1f.js} +5 -5
  79. package/dist/shared/{dpc2r7rb.js → bdekbvmt.js} +218 -95
  80. package/dist/shared/{jebgrkeq.js → bxjq6xqv.js} +2 -2
  81. package/dist/shared/c7dqd3gk.js +1806 -0
  82. package/dist/shared/ddh72ym5.js +20 -0
  83. package/dist/shared/e1c55v04.js +10 -0
  84. package/dist/shared/{mtw6jz76.js → e275q7sd.js} +1 -1
  85. package/dist/shared/{k86n8vq3.js → ekhq3ytz.js} +1 -1
  86. package/dist/shared/esy4dyxe.js +17 -0
  87. package/dist/shared/{gcefca6p.js → f9t9g54z.js} +22 -9
  88. package/dist/shared/{sjk86yrx.js → fk9vef30.js} +84 -73
  89. package/dist/shared/fkjne6gx.js +8 -0
  90. package/dist/shared/{e8zyaqvj.js → fne90dvz.js} +4 -1
  91. package/dist/shared/{needfe47.js → g89fmz5s.js} +1 -1
  92. package/dist/shared/{m4xff2a6.js → ghqzdp94.js} +2 -2
  93. package/dist/shared/{n0jmpgj1.js → gr9sn4za.js} +1 -1
  94. package/dist/shared/{5mtf6cj3.js → gzgfsspx.js} +5 -2
  95. package/dist/shared/h9811jjm.js +17 -0
  96. package/dist/shared/{z581d7ny.js → hgt69zjf.js} +2 -2
  97. package/dist/shared/{35q0n9tz.js → jvxcp1qk.js} +71 -87
  98. package/dist/shared/k73e8n9d.js +136 -0
  99. package/dist/shared/{195pzzzz.js → kzgrcy8s.js} +12 -8
  100. package/dist/shared/kzgrnckd.js +29 -0
  101. package/dist/shared/{p3xbdcvt.js → mz48rs74.js} +68 -8
  102. package/dist/shared/{zbqbmmrp.js → n6je5b28.js} +13 -26
  103. package/dist/shared/{b6d6p0zc.js → ns35jqz0.js} +75 -49
  104. package/dist/shared/{n05z9nwz.js → nstwgzn8.js} +1 -1
  105. package/dist/{tooling/shared/08kemxjd.js → shared/pgsak1yw.js} +1 -1
  106. package/dist/shared/py2zrrm6.js +451 -0
  107. package/dist/shared/{9dr2qnx7.js → qqm3ze6q.js} +1 -1
  108. package/dist/shared/{wvdjznah.js → rcjm0yn7.js} +31 -38
  109. package/dist/shared/rged92v6.js +17 -0
  110. package/dist/shared/{jp36k7dp.js → rw4tpcd0.js} +81 -51
  111. package/dist/shared/{bsek72fg.js → s5qe47a6.js} +3 -0
  112. package/dist/shared/{1d9q9cv2.js → smxzjz60.js} +2 -2
  113. package/dist/shared/{wz2a78mp.js → th5rnaxw.js} +1 -1
  114. package/dist/{tooling/shared/rs1jb051.js → shared/tr64w5p0.js} +1 -1
  115. package/dist/shared/{14x60fbf.js → tyqapcgk.js} +73 -10
  116. package/dist/shared/vsna85qf.js +8 -0
  117. package/dist/shared/{63qtkrca.js → vy47ryqa.js} +55 -5
  118. package/dist/shared/{jx2m62cs.js → wbdh9qbg.js} +7 -5
  119. package/dist/shared/{f4jy1j7x.js → wp7y8q3y.js} +946 -105
  120. package/dist/shared/{16kvjebh.js → xbd9xs6p.js} +7 -26
  121. package/dist/shared/{bah9nbg3.js → xbvz446k.js} +18 -23
  122. package/dist/shared/{p5nh3r8q.js → y6tfjk9q.js} +2 -2
  123. package/dist/shared/{3bb7wsqt.js → ycnft340.js} +1 -1
  124. package/dist/shared/{z7s6fpxv.js → ymenf259.js} +1 -1
  125. package/dist/shared/{0wrea3jq.js → ysdw2fg3.js} +10 -2
  126. package/dist/shared/zecrwdk9.js +61 -0
  127. package/dist/shared/{3t6kw83m.js → zm2rzqba.js} +2 -1
  128. package/dist/tooling/cli.js +200 -50
  129. package/dist/tooling/driver-run.js +109 -343
  130. package/dist/tooling/github/comment.d.ts +56 -0
  131. package/dist/tooling/github/post-comment.d.ts +17 -0
  132. package/dist/tooling/migrate/apply.d.ts +17 -2
  133. package/dist/tooling/migrate/commands.d.ts +2 -1
  134. package/dist/tooling/migrate/config.d.ts +13 -0
  135. package/dist/tooling/migrate/drift.d.ts +12 -0
  136. package/dist/tooling/migrate/driver-url.d.ts +17 -0
  137. package/dist/tooling/migrate/export.d.ts +165 -0
  138. package/dist/tooling/migrate/ext-surface.d.ts +80 -0
  139. package/dist/tooling/migrate/ext.d.ts +31 -4
  140. package/dist/tooling/migrate/import-drizzle.d.ts +40 -0
  141. package/dist/tooling/migrate/index.d.ts +3 -0
  142. package/dist/tooling/migrate/index.js +57 -10
  143. package/dist/tooling/migrate/lint-rules.d.ts +18 -1
  144. package/dist/tooling/migrate/lint.d.ts +14 -1
  145. package/dist/tooling/migrate/place.d.ts +18 -0
  146. package/dist/tooling/migrate/plan-json.d.ts +65 -0
  147. package/dist/tooling/migrate/policy.d.ts +17 -5
  148. package/dist/tooling/migrate/pooler-probe.d.ts +23 -0
  149. package/dist/tooling/migrate/project.d.ts +10 -1
  150. package/dist/tooling/migrate/pull-emit.d.ts +98 -0
  151. package/dist/tooling/migrate/pull-routines.d.ts +126 -0
  152. package/dist/tooling/migrate/pull-verify.d.ts +26 -0
  153. package/dist/tooling/migrate/pull.d.ts +65 -0
  154. package/dist/tooling/migrate/reprint.d.ts +32 -0
  155. package/dist/tooling/migrate/runner.d.ts +24 -1
  156. package/dist/tooling/migrate/sandbox.d.ts +8 -2
  157. package/dist/tooling/migrate/schema-api.d.ts +43 -0
  158. package/dist/tooling/migrate/sql-lex.d.ts +18 -0
  159. package/dist/tooling/shared/{ppnnnvj8.js → 09a6vsys.js} +1 -1
  160. package/dist/tooling/shared/{7ae7rjmn.js → 0v9ptnxp.js} +8 -8
  161. package/dist/tooling/shared/{fb9k2qwd.js → 0wtzps9p.js} +11 -30
  162. package/dist/tooling/shared/{a6pp9d12.js → 0yhf1db4.js} +6 -6
  163. package/dist/tooling/shared/{dy672fz6.js → 19msgrsc.js} +2 -2
  164. package/dist/{shared/q0cqt2sp.js → tooling/shared/1fwfm5m3.js} +1 -1
  165. package/dist/tooling/shared/{f9mphxej.js → 2jdn09e2.js} +401 -24
  166. package/dist/tooling/shared/{jne7b93p.js → 2qrte2ct.js} +5 -5
  167. package/dist/tooling/shared/{5bvw2nev.js → 2v4nwnkb.js} +1 -1
  168. package/dist/tooling/shared/{spk1jg3r.js → 33z39trp.js} +106 -23
  169. package/dist/tooling/shared/{z8d7ptht.js → 353vnw9z.js} +5 -5
  170. package/dist/tooling/shared/{dw08f3m8.js → 390kry9g.js} +2 -2
  171. package/dist/tooling/shared/{xjs6zqtc.js → 3f6etb9z.js} +18 -31
  172. package/dist/{shared/bnby0esn.js → tooling/shared/3t2cqmsx.js} +1 -1
  173. package/dist/tooling/shared/{wwnekq5n.js → 4dzvjtpy.js} +1 -1
  174. package/dist/tooling/shared/{y5656f0e.js → 4ec0nxvw.js} +10 -10
  175. package/dist/tooling/shared/{3m1hkg7z.js → 4tg2bn41.js} +59 -78
  176. package/dist/tooling/shared/{zvnhh1n0.js → 5rah55z0.js} +2 -2
  177. package/dist/tooling/shared/{pqy21k24.js → 804w1t69.js} +4 -4
  178. package/dist/tooling/shared/8g0m0rvd.js +134 -0
  179. package/dist/tooling/shared/8msbtw5s.js +8 -0
  180. package/dist/tooling/shared/{4d2w25vw.js → 8t22h3h7.js} +2 -2
  181. package/dist/tooling/shared/{smn6kz1p.js → 91c59b7b.js} +2 -2
  182. package/dist/tooling/shared/{aftb2mwr.js → adk9k6va.js} +1 -1
  183. package/dist/tooling/shared/{j9t5s12a.js → ajjd5cwz.js} +2 -2
  184. package/dist/tooling/shared/{cmptmb4f.js → angjck01.js} +1 -1
  185. package/dist/tooling/shared/{yw30vnq2.js → asnnc3v5.js} +1 -1
  186. package/dist/tooling/shared/{ma2340rx.js → bj1kyqc8.js} +2 -2
  187. package/dist/tooling/shared/{2wtvc7rw.js → bt3tjemb.js} +11 -3
  188. package/dist/tooling/shared/{ec71zqgt.js → chk2bh4f.js} +2 -2
  189. package/dist/tooling/shared/{gmcf9cxf.js → ckq4z5ax.js} +5 -2
  190. package/dist/tooling/shared/{w7qe8sj1.js → d3rhb24q.js} +1 -1
  191. package/dist/tooling/shared/{y031jct9.js → d8q00vxg.js} +4 -4
  192. package/dist/tooling/shared/{vs0t6qt8.js → dx188rxs.js} +2 -2
  193. package/dist/tooling/shared/{g9ad4n80.js → efq6p9df.js} +35 -42
  194. package/dist/tooling/shared/{ddjtfgnx.js → en6rwzq0.js} +3 -3
  195. package/dist/tooling/shared/{6nyfyw70.js → f2r5g0fs.js} +2 -2
  196. package/dist/tooling/shared/{03k6res6.js → f4gep0nk.js} +1 -1
  197. package/dist/tooling/shared/{gfvtj6d0.js → f8a010fm.js} +13 -11
  198. package/dist/tooling/shared/{3tq8pnb8.js → fdsek6pa.js} +1 -1
  199. package/dist/tooling/shared/fvmrxsd1.js +8 -0
  200. package/dist/tooling/shared/{733a1tq3.js → g3xybeqf.js} +4 -3
  201. package/dist/tooling/shared/{pwsytxm5.js → gefmpwsa.js} +1 -1
  202. package/dist/tooling/shared/{mtrqn2hn.js → gjj71hfh.js} +25 -30
  203. package/dist/tooling/shared/{8sqrsw3s.js → jgzt69pa.js} +5 -5
  204. package/dist/tooling/shared/{nf7jmhfa.js → jm30k2ca.js} +10 -8
  205. package/dist/tooling/shared/{vx86qjv8.js → kayqzpbk.js} +6 -3
  206. package/dist/tooling/shared/{zhwnfyb2.js → kvw1672d.js} +1 -1
  207. package/dist/tooling/shared/{rq5kk8j6.js → mr1kcgpw.js} +3 -3
  208. package/dist/tooling/shared/{72fyg4zv.js → mwbdf409.js} +1 -1
  209. package/dist/tooling/shared/{wt7j7nf6.js → ns9207v3.js} +1 -1
  210. package/dist/tooling/shared/{9xzm7hjg.js → p6tjv97k.js} +3 -3
  211. package/dist/tooling/shared/{yfr8hzhm.js → p73evwf0.js} +1 -1
  212. package/dist/tooling/shared/{dzx85q70.js → phc1nc4g.js} +1 -1
  213. package/dist/tooling/shared/{417zdsk7.js → ppybjw50.js} +79 -16
  214. package/dist/tooling/shared/{yk9mp7vb.js → qdrn8ghn.js} +5 -4
  215. package/dist/tooling/shared/rd8h01ta.js +20 -0
  216. package/dist/tooling/shared/{bz2dqhab.js → rwg8y90m.js} +3 -3
  217. package/dist/tooling/shared/{xhrnjch9.js → ry2f3w8p.js} +3 -3
  218. package/dist/tooling/shared/{a7q7t4n3.js → ryc5sa58.js} +8 -8
  219. package/dist/tooling/shared/{2revefqt.js → ss87qxwv.js} +2 -2
  220. package/dist/tooling/shared/{rf83gr2d.js → vg68k11z.js} +7 -3
  221. package/dist/tooling/shared/{p7f08ktn.js → vms9dta5.js} +73 -89
  222. package/dist/tooling/shared/{3rrw5w8f.js → xchpnbdv.js} +1 -1
  223. package/dist/tooling/shared/{djydjpqt.js → xn6p01fh.js} +5 -5
  224. package/dist/tooling/shared/{9kazs5p6.js → xwr6q618.js} +3 -3
  225. package/dist/tooling/shared/{ep8zh3bk.js → xx3gmq94.js} +1 -1
  226. package/dist/tooling/shared/{tn8gay14.js → y2bd7yfx.js} +21 -13
  227. package/dist/tooling/shared/{vraj6d74.js → y4gq9rbe.js} +11 -11
  228. package/dist/tooling/shared/y4vwft92.js +9 -0
  229. package/dist/tooling/shared/{345tbc2k.js → yz68xcmc.js} +1 -1
  230. package/dist/tooling/testing/factories.d.ts +1 -3
  231. package/dist/tooling/testing/index.js +2 -2
  232. package/package.json +39 -9
  233. package/dist/shared/3449rcae.js +0 -14
  234. package/dist/shared/fjpnhqan.js +0 -71
  235. package/dist/shared/n41w4fbz.js +0 -113
  236. package/dist/tooling/shared/pw8fgahx.js +0 -69
  237. /package/dist/shared/{ae4j5f42.js → mfvx6kjx.js} +0 -0
@@ -93,6 +93,20 @@ export type ApplyRequest = {
93
93
  readonly reference: readonly ReferenceTable[];
94
94
  readonly only?: boolean;
95
95
  };
96
+ /**
97
+ * Catalog hash `okm_meta` must record when this run finishes.
98
+ *
99
+ * When the plan (or pending units) leave the database matching the schema
100
+ * but `okm_meta` still holds an older hash — for example an external table
101
+ * gained a column and the dependent exported a new snapshot — the runner
102
+ * re-stamps `okm_meta` and `okm_history` under a fresh id. File apply only
103
+ * enables that path when `defineConfig({ external })` is set; a foreign or
104
+ * legacy hash without external snapshots is left for connect or the pre-D208
105
+ * restamp.
106
+ */
107
+ readonly headHash?: string;
108
+ /** When true, an empty apply may re-stamp `okm_meta` to {@link headHash}. */
109
+ readonly restampHead?: boolean;
96
110
  };
97
111
  /** Migrations that ran at least one step in this invocation. */
98
112
  export type ApplyReport = {
@@ -147,8 +161,9 @@ export declare function applyProject(cwd: string, flags: InvokeFlags, write?: (t
147
161
  /**
148
162
  * Prototype sync. Blocked on a protected target.
149
163
  *
150
- * A target named production is not special. Protection is the `protected`
151
- * flag (spec §19.8). The plan's statements run as one migration.
164
+ * Plans from the live catalog on the target (not the last migration file),
165
+ * applies under a fresh `push-<n>` id from `okm_history`, and re-stamps
166
+ * `okm_meta` when the schema hash moved with no DDL (B-29, B-21).
152
167
  *
153
168
  * @param cwd - Project directory
154
169
  * @param flags - Target and protection flags
@@ -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
  *
@@ -19,6 +19,18 @@ import type { RolesInput } from "../../dialects/pg/role/index.js";
19
19
  * @param roles - `defineConfig({ roles })`, when set
20
20
  */
21
21
  export declare function assertAuthorDrift(url: string, author: Catalog, roles?: RolesInput, allowPooler?: boolean): Promise<void>;
22
+ /**
23
+ * Reprints each domain check the way this server stores it.
24
+ *
25
+ * Author spellings such as `VALUE > 0` become `((VALUE > 0))`, so a plan
26
+ * against a live catalog does not treat the reprint as a permanent change.
27
+ * The catalog hash still uses the author text (B-37).
28
+ *
29
+ * @param runner - Database connection
30
+ * @param source - Catalog whose domain checks may still be author SQL
31
+ * @returns A catalog whose domain checks carry the server reprint
32
+ */
33
+ export declare function sealDomainChecks(runner: CatalogQuery, source: Catalog): Promise<Catalog>;
22
34
  /**
23
35
  * Turns a postgres.js handle into the query shape introspection uses.
24
36
  *
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Connection URL helpers for migrate commands.
3
+ *
4
+ * Pooler client hints in the query string are not Postgres startup parameters.
5
+ * Every migrate path that opens a driver must strip those hints first. The
6
+ * URL guard still reads `pgbouncer=true` on the original URL before this runs.
7
+ */
8
+ /**
9
+ * Removes the `pgbouncer` query parameter before a driver opens a connection.
10
+ *
11
+ * Other pooler hints in the URL are left alone: this version does not
12
+ * interpret them.
13
+ *
14
+ * @param url - A `postgres://` or `postgresql://` URL
15
+ * @returns The same URL without `pgbouncer` in the query string
16
+ */
17
+ export declare function driverUrl(url: string): string;
@@ -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;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Catalog reads shared by `okm ext scaffold` and `okm ext test`.
3
+ *
4
+ * Both are read-only. The queries are `pg_depend`, `pg_type`, `pg_proc`,
5
+ * `pg_operator`, and `pg_settings`. Nothing is created.
6
+ */
7
+ import type { DriverPool } from "../../contracts/driver.js";
8
+ import type { Extension, ExtensionFunction, ExtensionIndexMethod, ExtensionOperator, ExtensionProvides, ExtensionType } from "../../dialects/pg/ext/index.js";
9
+ /** One extension as the connected server describes it. */
10
+ export type ServerSurface = {
11
+ readonly name: string;
12
+ readonly version: string;
13
+ readonly schema: string;
14
+ readonly relocatable: boolean;
15
+ readonly serverMajor: number;
16
+ readonly types: readonly ExtensionType[];
17
+ readonly operators: readonly ExtensionOperator[];
18
+ readonly functions: readonly ExtensionFunction[];
19
+ readonly indexMethods: readonly ExtensionIndexMethod[];
20
+ readonly settings: readonly string[];
21
+ };
22
+ /**
23
+ * Reads one installed extension.
24
+ *
25
+ * A name that is not installed is OKM1811. The connection is not asked to
26
+ * create it.
27
+ *
28
+ * @param pool - Connected server
29
+ * @param name - Extension name
30
+ * @returns The catalog surface
31
+ */
32
+ export declare function readSurface(pool: DriverPool, name: string): Promise<ServerSurface>;
33
+ /**
34
+ * Prints a starting `extension()` definition.
35
+ *
36
+ * The developer owns the file. `requires` and `provides` are the fields
37
+ * `okm ext test` reads. Settings are a comment, because they are not part
38
+ * of the definition.
39
+ *
40
+ * @param surface - Catalog read
41
+ * @returns TypeScript source, including the trailing newline
42
+ */
43
+ export declare function renderScaffold(surface: ServerSurface): string;
44
+ /**
45
+ * Lists mismatches between a definition and the server.
46
+ *
47
+ * An empty list means the definition matches. Version failures and signature
48
+ * failures are both lines in that list.
49
+ *
50
+ * @param declared - The loaded `extension()` value
51
+ * @param server - The catalog read for `declared.name`
52
+ * @returns Mismatch lines, stable order
53
+ */
54
+ export declare function surfaceMismatches(declared: Extension, server: ServerSurface): readonly string[];
55
+ /**
56
+ * Throws when {@link surfaceMismatches} found any line.
57
+ *
58
+ * Version lines are OKM1812. A signature line is `invalid`. Both are listed
59
+ * in the message.
60
+ *
61
+ * @param name - Extension name
62
+ * @param mismatches - Lines from {@link surfaceMismatches}
63
+ */
64
+ export declare function refuseMismatches(name: string, mismatches: readonly string[]): void;
65
+ /**
66
+ * Reports whether a value is an `extension()` result.
67
+ *
68
+ * @param value - A module export
69
+ * @returns `true` when it has a name and `contribute`
70
+ */
71
+ export declare function isExtension(value: unknown): value is Extension;
72
+ /**
73
+ * Reads `extension()` values exported by a loaded module.
74
+ *
75
+ * @param imported - Module namespace
76
+ * @returns The definitions, in export order
77
+ */
78
+ export declare function extensionsFromModule(imported: unknown): readonly Extension[];
79
+ /** Provides kept on the type so a scaffold round-trip can name them. */
80
+ export type { ExtensionProvides };
@@ -1,9 +1,10 @@
1
1
  /**
2
- * `okm ext list` and `okm ext check`.
2
+ * `okm ext list`, `check`, `scaffold`, and `test`.
3
3
  *
4
- * Both talk to the selected target. List prints every extension the server
5
- * can install, and the installed version when one is present. Check compares
6
- * the schema's declarations with what is installed.
4
+ * All four talk to the selected target and are read-only, including on a
5
+ * protected target. List prints every extension the server can install.
6
+ * Check compares the schema's declarations with what is installed. Scaffold
7
+ * prints a starting definition. Test checks that definition against the server.
7
8
  */
8
9
  import { type InvokeFlags } from "./policy.js";
9
10
  /**
@@ -15,3 +16,29 @@ import { type InvokeFlags } from "./policy.js";
15
16
  * @returns Text for stdout, including the trailing newline
16
17
  */
17
18
  export declare function extProject(cwd: string, command: "list" | "check", flags: InvokeFlags): Promise<string>;
19
+ /**
20
+ * Prints a starting definition for one installed extension.
21
+ *
22
+ * `--out` writes the file when that path does not exist. An existing file
23
+ * is refused and nothing is written. Without `--out`, the text is returned
24
+ * for stdout.
25
+ *
26
+ * @param cwd - Project directory
27
+ * @param name - Extension name
28
+ * @param flags - Target and protection flags
29
+ * @param out - File to write, when the caller passed `--out`
30
+ * @returns The definition, or a one-line wrote message
31
+ */
32
+ export declare function extScaffold(cwd: string, name: string, flags: InvokeFlags, out?: string): Promise<string>;
33
+ /**
34
+ * Checks one definition file against the connected server.
35
+ *
36
+ * Every declared type, operator, function, and index method must exist with
37
+ * the declared signature. `requires` must be met (OKM1812).
38
+ *
39
+ * @param cwd - Project directory
40
+ * @param file - Definition file, relative to `cwd` or absolute
41
+ * @param flags - Target and protection flags
42
+ * @returns `ok <name>` for each definition
43
+ */
44
+ export declare function extTest(cwd: string, file: string, flags: InvokeFlags): Promise<string>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `okm import drizzle` reads a Drizzle schema and writes table files.
3
+ *
4
+ * The schema is imported with the project's own `drizzle-orm`. That import
5
+ * runs the file. okmodel does not depend on drizzle-orm. The catalog is
6
+ * written by the same emitter as `okm pull`.
7
+ */
8
+ import { type PullSkip } from "./pull-emit.js";
9
+ /** What `okm import drizzle` prints, and the objects the files leave out. */
10
+ export type ImportDrizzleResult = {
11
+ /** Report text, including the trailing newline. */
12
+ readonly text: string;
13
+ /** Objects that were not written. */
14
+ readonly skipped: readonly PullSkip[];
15
+ /** Postgres schema the tables share. `schema()` still compiles `public`. */
16
+ readonly namespace: string;
17
+ };
18
+ /**
19
+ * Imports a Drizzle schema and writes one table file per table, plus the schema file.
20
+ *
21
+ * The path is a module in the project. `--out` is the directory that receives
22
+ * `schema.ts` and `tables/`. Without it, an `okmodel.config.ts` in `cwd`
23
+ * supplies the layout. A project that has no config yet writes `schema.ts`
24
+ * and `tables/` in `cwd`.
25
+ *
26
+ * @param cwd - Project directory the files are written into
27
+ * @param argv - Arguments after `import drizzle`
28
+ * @returns The report and the Postgres schema name
29
+ */
30
+ export declare function importDrizzle(cwd: string, argv: readonly string[]): Promise<ImportDrizzleResult>;
31
+ /**
32
+ * Reads the schema path and `--out`.
33
+ *
34
+ * @param argv - Arguments after `import drizzle`
35
+ * @returns The path and the optional output directory
36
+ */
37
+ export declare function parseImportArgs(argv: readonly string[]): {
38
+ readonly path: string;
39
+ readonly out: string | undefined;
40
+ };
@@ -2,7 +2,10 @@
2
2
  * Public entry for `okmodel/migrate`.
3
3
  *
4
4
  * `defineConfig`, its types, and `provision` for one configured target.
5
+ * `describe` and `buildCatalog` are the programmatic schema API.
5
6
  * The CLI imports planning and apply helpers from their modules.
6
7
  */
7
8
  export { defineConfig, type MigrateConfig, type TargetInput } from "./config.js";
9
+ export { type LogicalIdentity } from "./export.js";
10
+ export { buildCatalog, describe, type SchemaDescription } from "./schema-api.js";
8
11
  export { provision } from "./provision.js";
@@ -1,35 +1,80 @@
1
- import"../../shared/35q0n9tz.js";
2
- import"../../shared/12z7aznj.js";
1
+ import {
2
+ serializeCatalog2,
3
+ parseCatalog2
4
+ } from "../../shared/12z7aznj.js";
5
+ import"../../shared/fk9vef30.js";
6
+ import"../../shared/jvxcp1qk.js";
3
7
  import"../../shared/n442h54c.js";
8
+ import"../../shared/4pkz5nvw.js";
4
9
  import {
5
10
  applyTarget2,
6
11
  backfillTiming2
7
- } from "../../shared/pan0370z.js";
12
+ } from "../../shared/8ma6drzr.js";
8
13
  import {
9
14
  readReference
10
- } from "../../shared/mnvjvqyp.js";
11
- import"../../shared/kj9d8maq.js";
12
- import"../../shared/p3xbdcvt.js";
15
+ } from "../../shared/8p2bgye0.js";
16
+ import"../../shared/6xqvesa5.js";
17
+ import"../../shared/e1c55v04.js";
18
+ import"../../shared/mz48rs74.js";
13
19
  import {
14
20
  projectPath,
21
+ LOGICAL_FORMAT,
15
22
  loadMigrations,
16
23
  loadHeadSnapshot,
17
24
  loadBuiltSchema,
18
25
  loadConfig
19
- } from "../../shared/f4jy1j7x.js";
26
+ } from "../../shared/wp7y8q3y.js";
20
27
  import {
21
28
  assertTargetPolicy,
22
29
  selectTarget
23
- } from "../../shared/dpc2r7rb.js";
24
- import"../../shared/sjk86yrx.js";
30
+ } from "../../shared/bdekbvmt.js";
31
+ import {
32
+ canonicalJson
33
+ } from "../../shared/358zsv4r.js";
25
34
  import {
26
- OkmError2
35
+ OkmError2,
36
+ catalogError2
27
37
  } from "../../shared/52szzakm.js";
28
38
 
29
39
  // src/tooling/migrate/config.ts
30
40
  function defineConfig(config) {
31
41
  return config;
32
42
  }
43
+ // src/tooling/migrate/schema-api.ts
44
+ var LOGICAL_NAMESPACE = "public";
45
+ function describe(schema) {
46
+ const source = schemaCatalog(schema);
47
+ const document = JSON.parse(serializeCatalog2(source));
48
+ const text = canonicalJson({
49
+ catalog: document,
50
+ logical: {
51
+ format: LOGICAL_FORMAT,
52
+ name: LOGICAL_NAMESPACE,
53
+ namespace: LOGICAL_NAMESPACE
54
+ }
55
+ });
56
+ return JSON.parse(text);
57
+ }
58
+ function buildCatalog(description) {
59
+ if (description === null || typeof description !== "object" || !("catalog" in description)) {
60
+ catalogError2("OKM1027", "Catalog document is not an object.");
61
+ }
62
+ const body = description.catalog;
63
+ if (body === null || typeof body !== "object") {
64
+ catalogError2("OKM1027", "Catalog document is not an object.");
65
+ }
66
+ return parseCatalog2(JSON.stringify(body));
67
+ }
68
+ function schemaCatalog(schema) {
69
+ if (schema === null || typeof schema !== "object") {
70
+ catalogError2("OKM1020", "describe() needs the schema() result.");
71
+ }
72
+ const catalog = schema.catalog;
73
+ if (typeof catalog !== "object" || catalog === null || !("objects" in catalog)) {
74
+ catalogError2("OKM1020", "describe() needs the schema() result.");
75
+ }
76
+ return catalog;
77
+ }
33
78
  // src/tooling/migrate/provision.ts
34
79
  async function provision(target, cwd = process.cwd()) {
35
80
  const config = await loadConfig(cwd);
@@ -71,6 +116,8 @@ ${report.applied.map((id) => `applied ${id}`).join(`
71
116
  `;
72
117
  }
73
118
  export {
119
+ buildCatalog,
74
120
  defineConfig,
121
+ describe,
75
122
  provision
76
123
  };
@@ -42,10 +42,27 @@ export type ColumnRule = {
42
42
  * Step rules, lowest free code in each category.
43
43
  *
44
44
  * OKM1534 to OKM1537 are errors when the statement is not the safe form.
45
- * OKM1538 stays a warning: a rewriting type change has no safe form here.
45
+ * OKM1538 stays a warning, and only when the type change rewrites the table.
46
46
  */
47
47
  export declare const STEP_RULES: readonly StepRule[];
48
48
  /**
49
49
  * Type preferences. Warnings, read from the schema catalog by `okm check`.
50
50
  */
51
51
  export declare const COLUMN_RULES: readonly ColumnRule[];
52
+ /**
53
+ * Collapses whitespace and lowercases SQL outside quoted identifiers.
54
+ *
55
+ * @param sql - One statement
56
+ * @returns The comparison form
57
+ */
58
+ export declare function normalizedSql(sql: string): string;
59
+ /**
60
+ * A create or alter of a domain, or a `LANGUAGE sql` function.
61
+ *
62
+ * Offline lint cannot see the reprint. The allow is still for that statement.
63
+ * `okm migrate check` decides whether the text actually differs.
64
+ *
65
+ * @param sql - One statement
66
+ * @returns `true` when OKM1552 can fire for this statement
67
+ */
68
+ export declare function statementMayReprint(sql: string): boolean;
@@ -8,7 +8,7 @@
8
8
  import type { Catalog } from "../../contracts/catalog/types.js";
9
9
  import { OkmError } from "../../contracts/error.js";
10
10
  import { type LintSeverity } from "./lint-rules.js";
11
- import type { MigrationPlan } from "./plan.js";
11
+ import type { MigrationPlan, PlanStep } from "./plan.js";
12
12
  /** One finding. `place` is `step N`, `step N statement M`, or `table.column`. */
13
13
  export type Finding = {
14
14
  readonly severity: LintSeverity;
@@ -26,6 +26,19 @@ export type Finding = {
26
26
  * @returns Findings in step order, then code order
27
27
  */
28
28
  export declare function lintPlan(plan: MigrationPlan, before: Catalog, after: Catalog): readonly Finding[];
29
+ /**
30
+ * Warns when a replayed domain check or `LANGUAGE sql` body reprints.
31
+ *
32
+ * Called from `okm migrate check` after introspection. A warning does not
33
+ * fail the command. An allow with an empty reason, or a code the replay did
34
+ * not trigger, is OKM1510.
35
+ *
36
+ * @param declared - Catalog stored with the migration
37
+ * @param stored - Catalog read back from the scratch schema
38
+ * @param steps - Statements of that migration, including `-- okm-allow`
39
+ * @returns Findings in catalog order
40
+ */
41
+ export declare function lintReprints(declared: Catalog, stored: Catalog, steps: readonly PlanStep[]): readonly Finding[];
29
42
  /**
30
43
  * Lints type preferences on the author catalog.
31
44
  *
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Places a `schema()` catalog into the namespace from `defineConfig`.
3
+ *
4
+ * `schema()` compiles `public`. Planning reads this copy, so two catalogs
5
+ * on one database do not share table identities. An `external` table keeps
6
+ * the namespace from its snapshot. A catalog that is already `public` and
7
+ * has no external namespace is returned as itself, so its hash does not change.
8
+ */
9
+ import type { Catalog } from "../../contracts/catalog/types.js";
10
+ /**
11
+ * Rewrites managed objects into `namespace` and external tables into `externalNamespaces`.
12
+ *
13
+ * @param source - Catalog from `schema()`, after ownership is stamped
14
+ * @param namespace - Postgres schema this catalog owns. `public` is the default
15
+ * @param externalNamespaces - SQL table name to the owning catalog's namespace
16
+ * @returns `source` when nothing moves, otherwise a new catalog
17
+ */
18
+ export declare function placeCatalog(source: Catalog, namespace: string, externalNamespaces: ReadonlyMap<string, string>): Catalog;