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
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Machine-readable `okm migrate plan --json` (D279).
3
+ *
4
+ * The document is the plan the comment renderer reads. It is not parsed
5
+ * back out of the human SQL text.
6
+ */
7
+ import type { MigrationClass } from "./classify.js";
8
+ import type { Finding } from "./lint.js";
9
+ import type { MigrationPlan, PlanStep } from "./plan.js";
10
+ /** One step in a plan document. `lock` matches the human `-- lock:` line. */
11
+ export type PlanStepJson = {
12
+ readonly class: MigrationClass;
13
+ readonly lock: string;
14
+ readonly sql: string;
15
+ };
16
+ /** One lint finding in a plan document. */
17
+ export type PlanFindingJson = {
18
+ readonly severity: "error" | "warning";
19
+ readonly code: string;
20
+ readonly place: string;
21
+ readonly reason: string;
22
+ readonly fix: string;
23
+ };
24
+ /**
25
+ * What `okm migrate plan --json` prints.
26
+ *
27
+ * `class` is the strictest class, the same value as the human header.
28
+ */
29
+ export type PlanDocument = {
30
+ readonly name: string;
31
+ readonly class: MigrationClass;
32
+ readonly steps: readonly PlanStepJson[];
33
+ readonly findings: readonly PlanFindingJson[];
34
+ };
35
+ /**
36
+ * Builds the document `okm migrate plan --json` prints.
37
+ *
38
+ * `lockText` is the same callback {@link formatPlan} uses, so a lock line
39
+ * that includes a row estimate is the same string in both outputs.
40
+ *
41
+ * @param plan - Plan the command already computed
42
+ * @param findings - Lint findings for that plan
43
+ * @param lockText - Annotated lock, when a target answered
44
+ * @returns The document
45
+ */
46
+ export declare function planDocument(plan: MigrationPlan, findings: readonly Finding[], lockText?: (step: PlanStep) => string): PlanDocument;
47
+ /**
48
+ * Serialises a plan document.
49
+ *
50
+ * @param plan - Plan the command already computed
51
+ * @param findings - Lint findings for that plan
52
+ * @param lockText - Annotated lock, when a target answered
53
+ * @returns JSON text ending in a newline
54
+ */
55
+ export declare function formatPlanJson(plan: MigrationPlan, findings: readonly Finding[], lockText?: (step: PlanStep) => string): string;
56
+ /**
57
+ * Reads a plan document.
58
+ *
59
+ * Extra fields are ignored. A missing field, or a class that is not
60
+ * `expand`, `contract`, or `unclassified`, is refused.
61
+ *
62
+ * @param text - JSON from `okm migrate plan --json`
63
+ * @returns The document
64
+ */
65
+ export declare function parsePlanJson(text: string): PlanDocument;
@@ -56,17 +56,29 @@ export declare function assertTargetAlias(targets: readonly TargetRecord[]): voi
56
56
  * @param allowPooler - The invocation opted in
57
57
  */
58
58
  export declare function assertDirectConnection(url: string, allowPooler: boolean): void;
59
+ /** Options for {@link assertStableBackend}. */
60
+ export type StableBackendOptions = {
61
+ /**
62
+ * Holds another backend between pid reads so a LIFO transaction-mode
63
+ * pooler cannot hand the next read the same server. Resolves to a release
64
+ * function that ends the hold.
65
+ */
66
+ readonly holdBackend?: () => Promise<() => Promise<void>>;
67
+ };
59
68
  /**
60
- * Refuses a session whose backend pid changes between two statements.
69
+ * Refuses a session whose backend pid changes across eight statements.
61
70
  *
62
- * The two reads are separate round trips and are not wrapped in a
63
- * transaction. A transaction-mode pooler can hand back a different backend
64
- * for the second one. `--allow-pooler` skips the probe.
71
+ * The reads are separate round trips and are not wrapped in a transaction.
72
+ * A transaction-mode pooler can hand back a different backend. Two reads
73
+ * miss a default PgBouncer with `server_round_robin=0` (LIFO); eight reads
74
+ * plus an optional hold between them catch that case. A direct session
75
+ * keeps one pid. `--allow-pooler` skips the probe.
65
76
  *
66
77
  * @param readPid - Reads `pg_backend_pid()` on the session under test
67
78
  * @param allowPooler - The invocation opted in
79
+ * @param options - Optional hold used by the migrate warm-and-hold probe
68
80
  */
69
- export declare function assertStableBackend(readPid: () => Promise<string>, allowPooler: boolean): Promise<void>;
81
+ export declare function assertStableBackend(readPid: () => Promise<string>, allowPooler: boolean, options?: StableBackendOptions): Promise<void>;
70
82
  /**
71
83
  * Lists configured targets.
72
84
  *
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Pid probe for transaction-mode poolers (B-41).
3
+ *
4
+ * Eight separate `pg_backend_pid()` reads on the caller's session. Two or
5
+ * more distinct pids mean a pooler handed out a new backend. A direct
6
+ * session keeps one pid.
7
+ *
8
+ * Warm-and-hold for LIFO PgBouncer (`server_round_robin=0`) needs extra
9
+ * connections and deadlocks a single-connection target (PGlite wire) when
10
+ * apply/seed already hold `max: 1`. That path stays in the PgBouncer test
11
+ * via {@link holdBackendBetweenReads}; production keeps URL heuristics plus
12
+ * these eight reads.
13
+ */
14
+ import { type StableBackendOptions } from "./policy.js";
15
+ /**
16
+ * Refuses a session whose backend pid changes across eight reads.
17
+ *
18
+ * @param _url - Target URL (unused; kept for call-site stability)
19
+ * @param readPid - Reads `pg_backend_pid()` on the session under test
20
+ * @param allowPooler - The invocation opted in
21
+ * @param options - Optional hold between reads (PgBouncer tests)
22
+ */
23
+ export declare function probeStableBackend(_url: string, readPid: () => Promise<string>, allowPooler: boolean, options?: StableBackendOptions): Promise<void>;
@@ -46,12 +46,13 @@ export declare function generateProject(cwd: string, name: string, flags: readon
46
46
  * @param name - Plan name
47
47
  * @param flags - `--replace` values
48
48
  * @param invoke - Target and protection flags, when the command passed them
49
- * @returns The plan, its lint findings, and the text to print
49
+ * @returns The plan, its lint findings, the human text, and the `--json` document. Both forms use the same lock lines
50
50
  */
51
51
  export declare function planProject(cwd: string, name: string, flags: readonly string[], invoke?: InvokeFlags): Promise<{
52
52
  readonly plan: MigrationPlan;
53
53
  readonly findings: readonly Finding[];
54
54
  readonly text: string;
55
+ readonly json: string;
55
56
  }>;
56
57
  /**
57
58
  * Validates the schema, then reports stale renames and unlisted table files.
@@ -113,6 +114,14 @@ export declare function openProject(cwd: string): Promise<{
113
114
  * @returns The built schema, with roles attached when the config declares them
114
115
  */
115
116
  export declare function loadBuiltSchema(cwd: string, config: MigrateConfig): Promise<Built>;
117
+ /**
118
+ * Prints or writes the catalog snapshot.
119
+ *
120
+ * @param cwd - Project directory
121
+ * @param args - Arguments after `export`
122
+ * @returns Stdout
123
+ */
124
+ export declare function exportProject(cwd: string, args: readonly string[]): Promise<string>;
116
125
  /**
117
126
  * Loads `okmodel.config.ts`.
118
127
  *
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Turns an introspected catalog into table files and a schema file.
3
+ *
4
+ * `schema()` is the only writer. Functions, triggers, and views are written
5
+ * beside the tables. A kind it cannot store is returned, with the SQL the
6
+ * catalog already holds, and is not guessed.
7
+ */
8
+ import type { Catalog } from "../../contracts/catalog/types.js";
9
+ import { type RoutinePlan, type RoutineVerdict } from "./pull-routines.js";
10
+ /** One file `okm pull` writes. */
11
+ export type PullFile = {
12
+ /** Absolute path. */
13
+ readonly path: string;
14
+ /** Source text, before the project formatter runs. */
15
+ readonly text: string;
16
+ };
17
+ /** One object the schema file does not declare. */
18
+ export type PullSkip = {
19
+ /** {@link identityKey} of the catalog object. */
20
+ readonly key: string;
21
+ /** Catalog kind, or `column` for a type `table()` cannot build. */
22
+ readonly kind: string;
23
+ /** `table.column`, or the object name. */
24
+ readonly label: string;
25
+ /** Why this step left it out. */
26
+ readonly reason: string;
27
+ /** SQL from the catalog. Empty when the kind has no statement of its own. */
28
+ readonly sql: string;
29
+ };
30
+ /** Where the schema file and the table files go. */
31
+ export type PullLayout = {
32
+ /** Absolute path of the schema module. */
33
+ readonly schemaFile: string;
34
+ /** Absolute directory of one file per table. */
35
+ readonly tablesDir: string;
36
+ };
37
+ /** Files to write, and the objects those files leave out. */
38
+ export type PullEmission = {
39
+ readonly files: readonly PullFile[];
40
+ readonly skipped: readonly PullSkip[];
41
+ /** Scratch results for the routines the files declare. */
42
+ readonly verdicts: readonly RoutineVerdict[];
43
+ readonly counts: {
44
+ readonly tables: number;
45
+ readonly functions: number;
46
+ readonly triggers: number;
47
+ readonly views: number;
48
+ readonly materializedViews: number;
49
+ };
50
+ };
51
+ /** A kind the catalog cannot store, counted for the report. */
52
+ export type PullCount = {
53
+ readonly kind: string;
54
+ readonly count: number;
55
+ readonly reason: string;
56
+ };
57
+ /** Scratch verdicts and the kinds the catalog has no object for. */
58
+ export type PullReview = {
59
+ readonly plan: RoutinePlan;
60
+ readonly verdicts: readonly RoutineVerdict[];
61
+ readonly unexpressed: readonly PullCount[];
62
+ };
63
+ /**
64
+ * Writes one table module per table and the schema module that imports them.
65
+ *
66
+ * Column order, import order, and option keys are sorted, so the same catalog
67
+ * produces the same text.
68
+ *
69
+ * @param source - Catalog from introspection, logical namespace `public`
70
+ * @param layout - Schema file and tables directory
71
+ * @param review - Scratch verdicts. Omitted marks every function candidate-only
72
+ * @returns The files and the objects they do not declare
73
+ */
74
+ export declare function emitPull(source: Catalog, layout: PullLayout, review?: PullReview): PullEmission;
75
+ /**
76
+ * Text `okm pull` prints.
77
+ *
78
+ * Deferred kinds and kinds the catalog cannot store are always listed,
79
+ * including a count of zero, so a kind is not dropped without a line.
80
+ * Each pulled function is `verified`, `candidate-only`, or `unverified`.
81
+ *
82
+ * @param counts - Objects the files declare
83
+ * @param skipped - Objects the files leave out
84
+ * @param verdicts - Scratch results. Empty when no routine was pulled
85
+ * @param unexpressed - Aggregates, procedures, event triggers, and rules
86
+ * @param verb - `imported` for `okm import drizzle`. `pulled` is `okm pull`
87
+ * @returns The report, with a trailing newline
88
+ */
89
+ export declare function formatPullReport(counts: PullEmission["counts"], skipped: readonly PullSkip[], verdicts?: readonly RoutineVerdict[], unexpressed?: readonly PullCount[], verb?: "pulled" | "imported"): string;
90
+ /**
91
+ * SQL table name to the binding `table()` writes.
92
+ *
93
+ * A partitioned table is omitted. The binding matches the table file.
94
+ *
95
+ * @param source - Introspected catalog
96
+ * @returns Bindings for tables this step writes
97
+ */
98
+ export declare function tableExportNames(source: Catalog): ReadonlyMap<string, string>;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Plans `fn()`, `trigger()`, `view()`, and `materializedView()` for `okm pull`.
3
+ *
4
+ * Views and `BEGIN ATOMIC` bodies take edges the catalog already read from
5
+ * `pg_depend`. A plpgsql or SQL-string body gets table candidates from
6
+ * {@link sqlIdentifiers}. A view or a function named in that body is an
7
+ * ordering edge only: `dependsOn` accepts tables and columns. A view query
8
+ * is matched the same way, so a view over a view waits for the view it names
9
+ * when `pg_depend` recorded no column edge.
10
+ */
11
+ import type { Catalog, FunctionObject, IndexObject, MaterializedViewObject, ObjectIdentity, TriggerObject, ViewObject } from "../../contracts/catalog/types.js";
12
+ /** Why a pulled routine is marked the way it is. */
13
+ export type RoutineStatus = "verified" | "candidate-only" | "unverified";
14
+ /** One function, trigger, or view after the scratch replay. */
15
+ export type RoutineVerdict = {
16
+ /** {@link identityKey} of the catalog object. */
17
+ readonly key: string;
18
+ /** Catalog kind. */
19
+ readonly kind: "function" | "trigger" | "view" | "materializedView";
20
+ /** Report label. */
21
+ readonly label: string;
22
+ /** What the scratch run proved. */
23
+ readonly status: RoutineStatus;
24
+ /** Postgres error, or why the scratch schema did not run. Empty when proved or candidate-only. */
25
+ readonly detail: string;
26
+ };
27
+ /** One object the schema file does not declare. Shape matches the pull skip. */
28
+ export type RoutineSkip = {
29
+ readonly key: string;
30
+ readonly kind: string;
31
+ readonly label: string;
32
+ readonly reason: string;
33
+ readonly sql: string;
34
+ };
35
+ /** A function the schema file will declare. */
36
+ export type PlannedFunction = {
37
+ readonly object: FunctionObject;
38
+ /** Binding in the schema file. */
39
+ readonly binding: string;
40
+ /** Source fragments inside `dependsOn: [...]`. */
41
+ readonly dependsOn: readonly string[];
42
+ };
43
+ /** A trigger the schema file will declare. */
44
+ export type PlannedTrigger = {
45
+ readonly object: TriggerObject;
46
+ readonly binding: string;
47
+ /** Table binding passed to `on`. */
48
+ readonly on: string;
49
+ /** Function binding passed to `calls`. */
50
+ readonly calls: string;
51
+ };
52
+ /** A view or materialized view the schema file will declare. */
53
+ export type PlannedView = {
54
+ readonly object: ViewObject | MaterializedViewObject;
55
+ readonly binding: string;
56
+ /** Indexes `materializedView()` can store. Expression indexes are skipped. */
57
+ readonly indexes: readonly IndexObject[];
58
+ };
59
+ /**
60
+ * Routines to write, and the extra edges the scratch replay orders by.
61
+ *
62
+ * `orderEdges` are not written. `dependsOn` cannot name a view or a function.
63
+ */
64
+ export type RoutinePlan = {
65
+ readonly functions: readonly PlannedFunction[];
66
+ readonly triggers: readonly PlannedTrigger[];
67
+ readonly views: readonly PlannedView[];
68
+ readonly skipped: readonly RoutineSkip[];
69
+ /** Identity key to edges added for the scratch order only. */
70
+ readonly orderEdges: ReadonlyMap<string, readonly ObjectIdentity[]>;
71
+ };
72
+ /** Bindings and declarations inserted into the schema file. */
73
+ export type RenderedRoutines = {
74
+ readonly imports: readonly string[];
75
+ readonly body: string;
76
+ readonly functions: readonly string[];
77
+ readonly triggers: readonly string[];
78
+ readonly views: readonly string[];
79
+ };
80
+ /**
81
+ * Chooses which routines to write and which names `dependsOn` can cite.
82
+ *
83
+ * @param source - Introspected catalog
84
+ * @param tableExports - SQL table name to the binding `table()` writes
85
+ * @returns The plan. Comments are applied later, from the scratch verdicts
86
+ */
87
+ export declare function planRoutines(source: Catalog, tableExports: ReadonlyMap<string, string>): RoutinePlan;
88
+ /**
89
+ * Renders the schema-file text for a plan.
90
+ *
91
+ * A missing verdict is candidate-only for a function and unverified for a
92
+ * view or a trigger. That is what a scratch run that did not happen can say.
93
+ *
94
+ * @param plan - Routines to write
95
+ * @param verdicts - Scratch results, keyed by {@link identityKey}
96
+ * @returns Imports, bindings, and the `schema()` lists
97
+ */
98
+ export declare function renderRoutines(plan: RoutinePlan, verdicts: ReadonlyMap<string, RoutineVerdict>): RenderedRoutines;
99
+ /**
100
+ * Verdicts for a plan when the scratch schema was not created.
101
+ *
102
+ * Nothing is verified. A plpgsql function stays candidate-only. A SQL
103
+ * function, a view, and a trigger are unverified.
104
+ *
105
+ * @param plan - Routines that would have been replayed
106
+ * @param detail - Why the scratch schema was not created
107
+ * @returns One verdict per planned routine
108
+ */
109
+ export declare function verdictsWithoutScratch(plan: RoutinePlan, detail: string): readonly RoutineVerdict[];
110
+ /**
111
+ * Tables, views, and functions named in `body`.
112
+ *
113
+ * Unquoted names fold to lower case. A quoted name matches the stored spelling.
114
+ * The function's own name is included; the caller drops a self-edge.
115
+ *
116
+ * @param body - Function body or view query
117
+ * @param tables - Pulled tables
118
+ * @param views - Pulled views and materialized views
119
+ * @param functions - Functions grouped by name
120
+ * @returns Matches, tables by SQL name and the other two as identities
121
+ */
122
+ export declare function matchNames(body: string, tables: ReadonlyMap<string, ObjectIdentity>, views: ReadonlyMap<string, ViewObject | MaterializedViewObject>, functions: ReadonlyMap<string, readonly FunctionObject[]>): {
123
+ readonly tables: readonly string[];
124
+ readonly views: readonly ObjectIdentity[];
125
+ readonly functions: readonly ObjectIdentity[];
126
+ };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Replays pulled routines on a scratch schema.
3
+ *
4
+ * Create order is the catalog's dependency order, plus lexical edges for a
5
+ * plpgsql or SQL-string body. `check_function_bodies` is on. A SQL function
6
+ * or a view whose dependency is missing fails creation. A plpgsql body is
7
+ * not proved by creation, so a function that is created is still
8
+ * candidate-only. The scratch schema is dropped before this returns.
9
+ */
10
+ import type { Catalog } from "../../contracts/catalog/types.js";
11
+ import type { CatalogQuery } from "../../dialects/pg/introspect.js";
12
+ import { type RoutinePlan, type RoutineVerdict } from "./pull-routines.js";
13
+ /**
14
+ * Creates the planned routines from empty and records what that proved.
15
+ *
16
+ * Types are created first. Everything else follows the catalog dependency
17
+ * order, so a function with no edge is created before its tables. Routine
18
+ * bodies see only the scratch schema. A role that cannot create a schema
19
+ * leaves every function unproved.
20
+ *
21
+ * @param runner - Database connection. Statements share its session
22
+ * @param source - Introspected catalog
23
+ * @param plan - Routines `okm pull` will write
24
+ * @returns One verdict per planned function, trigger, and view
25
+ */
26
+ export declare function verifyPulled(runner: CatalogQuery, source: Catalog, plan: RoutinePlan): Promise<readonly RoutineVerdict[]>;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `okm pull` reads a database and writes table files plus a schema file.
3
+ *
4
+ * The selected namespaces are only read. A scratch schema is created and
5
+ * dropped to verify functions and views, then dropped before this returns.
6
+ * A protected target is allowed. An existing file is refused before anything
7
+ * is written.
8
+ */
9
+ import { type PullFile, type PullLayout, type PullSkip } from "./pull-emit.js";
10
+ /** What `okm pull` prints, and the objects the files leave out. */
11
+ export type PullResult = {
12
+ /** Report text, including the trailing newline. */
13
+ readonly text: string;
14
+ /** Objects that were not written. */
15
+ readonly skipped: readonly PullSkip[];
16
+ };
17
+ /**
18
+ * Introspects the selected namespaces and writes the schema source.
19
+ *
20
+ * The default namespace is `current_schema()`. `--schema` selects others and
21
+ * may be repeated. `--out` is the directory that receives `schema.ts` and
22
+ * `tables/`. Without it, the project's schema path and tables directory are
23
+ * used. A tables directory that the config omits is `tables` beside the
24
+ * schema file.
25
+ *
26
+ * @param cwd - Project directory
27
+ * @param argv - Arguments after `pull`
28
+ * @returns The report
29
+ */
30
+ export declare function pullProject(cwd: string, argv: readonly string[]): Promise<PullResult>;
31
+ /**
32
+ * Reads `--out`, `--schema`, and `--target` from a pull invocation.
33
+ *
34
+ * @param argv - Arguments after `pull`
35
+ * @returns The flags this command reads
36
+ */
37
+ export declare function parsePullArgs(argv: readonly string[]): {
38
+ readonly target: string | undefined;
39
+ readonly allowProtected: boolean;
40
+ readonly out: string | undefined;
41
+ readonly schemas: readonly string[];
42
+ };
43
+ /**
44
+ * Resolves the schema file and the tables directory for a pull or an import.
45
+ *
46
+ * `--out` writes `schema.ts` and `tables/` under that directory. Without it,
47
+ * the project's schema path and tables directory are used.
48
+ *
49
+ * @param cwd - Project directory
50
+ * @param schema - Config schema path
51
+ * @param tables - Config tables directory, when set
52
+ * @param out - `--out` directory, when set
53
+ * @returns Absolute paths
54
+ */
55
+ export declare function pullLayout(cwd: string, schema: string, tables: string | undefined, out: string | undefined): PullLayout;
56
+ /**
57
+ * Refuses an existing file, writes the rest, and formats them.
58
+ *
59
+ * When `oxfmt` is missing or fails, the files stay as written and a notice is
60
+ * printed on stderr. The pull or import report still returns.
61
+ *
62
+ * @param files - Files from {@link emitPull}
63
+ * @param verb - `Pull` or `Import`, named in OKM1855
64
+ */
65
+ export declare function commitPullFiles(files: readonly PullFile[], verb?: "Pull" | "Import"): void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Warns when a domain check or a `LANGUAGE sql` body reprints (D276).
3
+ *
4
+ * The comparison runs after `okm migrate check` has created the objects.
5
+ * The linter itself does not connect. A matching stored text is silent.
6
+ */
7
+ import type { Catalog } from "../../contracts/catalog/types.js";
8
+ import type { LintSeverity } from "./lint-rules.js";
9
+ import type { PlanStep } from "./plan.js";
10
+ /** Check-stage warning for a reprinted domain check or SQL function body. */
11
+ export declare const REPRINT_CODE = "OKM1552";
12
+ /** One reprint comparison, before the registry sentence is attached. */
13
+ export type ReprintHit = {
14
+ readonly severity: LintSeverity;
15
+ readonly code: string;
16
+ readonly place: string;
17
+ readonly reason: string;
18
+ };
19
+ /**
20
+ * Compares declared text with the text Postgres stored.
21
+ *
22
+ * A step that does not create or replace the object is skipped, so a later
23
+ * migration does not repeat the warning. `-- okm-allow OKM1552: reason` on
24
+ * that step silences it. An empty reason, or an allow on a statement whose
25
+ * text matches, is OKM1510.
26
+ *
27
+ * @param declared - Catalog stored with the migration
28
+ * @param stored - Catalog introspection read back after the replay
29
+ * @param steps - Statements of that migration, including allows
30
+ * @returns Findings in catalog order
31
+ */
32
+ export declare function reprintHits(declared: Catalog, stored: Catalog, steps: readonly PlanStep[]): readonly ReprintHit[];
@@ -7,6 +7,7 @@
7
7
  * `okm_backfill` after each commit.
8
8
  */
9
9
  import type { DriverConnection } from "../../contracts/driver.js";
10
+ import { OkmError } from "../../contracts/error.js";
10
11
  import type { PlanStep } from "./plan.js";
11
12
  /** One step with its index in the migration file. */
12
13
  export type RunnableStep = {
@@ -79,7 +80,9 @@ export declare function runTarget(connection: DriverConnection, run: TargetRun,
79
80
  /**
80
81
  * Assumes `role` for the rest of this connection.
81
82
  *
82
- * A second call with the same role does nothing.
83
+ * A second call with the same role does nothing. A non-superuser that created
84
+ * the role with `CREATEROLE` is granted membership first: Postgres 15 creates
85
+ * no membership row, and Postgres 16+ grants `ADMIN` without `SET`.
83
86
  *
84
87
  * @param connection - Reserved connection
85
88
  * @param role - Migration role
@@ -88,6 +91,15 @@ export declare function runTarget(connection: DriverConnection, run: TargetRun,
88
91
  export declare function assumeRole(connection: DriverConnection, role: string, session: {
89
92
  setRole?: string;
90
93
  }): Promise<void>;
94
+ /**
95
+ * Maps a Postgres role-privilege refusal to a clear `OkmError`.
96
+ *
97
+ * @param error - Driver failure
98
+ * @param role - Role named in the step, when known
99
+ * @returns A forbidden error that names CREATEROLE or the SET option, or
100
+ * `undefined` when the failure is something else
101
+ */
102
+ export declare function rolePrivilegeError(error: unknown, role?: string): OkmError | undefined;
91
103
  /**
92
104
  * Lets a new migration role create objects in `schema`.
93
105
  *
@@ -110,6 +122,17 @@ export declare function grantAppMeta(connection: DriverConnection, role: string
110
122
  setRole?: string;
111
123
  }): Promise<void>;
112
124
  export declare function grantSchema(connection: DriverConnection, schema: string, role: string): Promise<void>;
125
+ /**
126
+ * Makes `role` the owner of `schema` when the connecting role can.
127
+ *
128
+ * Grants on the schema to reporting and other roles need the migration role
129
+ * to own it. A connecting role that is not the owner leaves the schema as is.
130
+ *
131
+ * @param connection - Reserved connection, before `SET ROLE`
132
+ * @param schema - Schema the migration writes
133
+ * @param role - Migration role that was just created
134
+ */
135
+ export declare function ownSchema(connection: DriverConnection, schema: string, role: string): Promise<void>;
113
136
  /**
114
137
  * Fails when `GRANT USAGE ON SCHEMA` did not add the role.
115
138
  *
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { Catalog } from "../../contracts/catalog/types.js";
9
9
  import type { MigrateConfig } from "./config.js";
10
+ import { type Finding } from "./lint.js";
10
11
  import { type MigrationPlan, type PlanStep } from "./plan.js";
11
12
  /** One migration the check replays. */
12
13
  export type CheckMigration = {
@@ -22,6 +23,7 @@ export type ReplayStop = {
22
23
  /** Replay result. `skips` are statements check did not execute. */
23
24
  export type ReplayOutcome = {
24
25
  readonly skips: readonly string[];
26
+ readonly reprints: readonly Finding[];
25
27
  readonly stop?: ReplayStop;
26
28
  };
27
29
  /**
@@ -48,10 +50,14 @@ export declare function replayCheckHistory(url: string, scratch: string, config:
48
50
  */
49
51
  export declare function proveCheckSnapshot(url: string, provided: string, replayed: string, config: MigrateConfig, allowPooler: boolean, history: readonly CheckMigration[]): Promise<string | undefined>;
50
52
  /**
51
- * Rewrites `"public".` to the scratch schema.
53
+ * Rewrites the catalog schema to the scratch schema.
54
+ *
55
+ * `source` defaults to `public`. A foreign key aimed at another schema is
56
+ * left in place.
52
57
  *
53
58
  * @param steps - Plan steps
54
59
  * @param schema - Scratch schema
60
+ * @param source - Schema the statements currently name
55
61
  * @returns The same steps, aimed at `schema`
56
62
  */
57
- export declare function retargetSteps(steps: readonly PlanStep[], schema: string): readonly PlanStep[];
63
+ export declare function retargetSteps(steps: readonly PlanStep[], schema: string, source?: string): readonly PlanStep[];
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Programmatic schema API (D26, D284).
3
+ *
4
+ * `describe` turns a `schema()` result into JSON. `buildCatalog` reads that
5
+ * JSON back into the catalog tooling already plans. Codecs and client
6
+ * generators stay on the schema. They are functions, and the catalog hash
7
+ * does not include them.
8
+ */
9
+ import type { Catalog } from "../../contracts/catalog/types.js";
10
+ import { type LogicalIdentity } from "./export.js";
11
+ /**
12
+ * JSON description of one schema.
13
+ *
14
+ * `logical` names the schema. It is not the catalog hash. `catalog` is the
15
+ * catalog document: no functions, and object keys in sorted order.
16
+ */
17
+ export type SchemaDescription = {
18
+ readonly logical: LogicalIdentity;
19
+ readonly catalog: Catalog;
20
+ };
21
+ /**
22
+ * Describes a schema as JSON.
23
+ *
24
+ * The logical identity is `public`. Placing the same catalog into another
25
+ * namespace does not change it. The catalog document keeps the namespaces
26
+ * the catalog already has, so the catalog hash still changes with placement.
27
+ *
28
+ * @param schema - A `schema()` result, or any value that carries its catalog
29
+ * @returns A description `JSON.stringify` can store
30
+ */
31
+ export declare function describe(schema: {
32
+ readonly catalog: Catalog;
33
+ }): SchemaDescription;
34
+ /**
35
+ * Builds the catalog from a description.
36
+ *
37
+ * `JSON.parse(JSON.stringify(describe(schema)))` is a valid argument. The
38
+ * result has the same catalog hash as `schema.catalog`.
39
+ *
40
+ * @param description - Description from {@link describe}, including one read back from JSON
41
+ * @returns The catalog `okm` plans
42
+ */
43
+ export declare function buildCatalog(description: SchemaDescription): Catalog;
@@ -37,3 +37,21 @@ export declare function sqlQuoteOpen(sql: string): boolean;
37
37
  * @returns The command, or `undefined` when the step stays in one transaction
38
38
  */
39
39
  export declare function transactionControl(sql: string): string | undefined;
40
+ /** One identifier {@link sqlIdentifiers} found outside a string or a comment. */
41
+ export type SqlName = {
42
+ /** Spelling as written. A quoted name is unescaped. An unquoted name is not folded. */
43
+ readonly text: string;
44
+ /** True when the name was a double-quoted identifier. */
45
+ readonly quoted: boolean;
46
+ };
47
+ /**
48
+ * Identifiers outside comments, strings, and dollar quotes.
49
+ *
50
+ * The quote rules are the same ones {@link sqlStatements} uses. A name inside
51
+ * a string or a dollar quote is not a match: Postgres still resolves
52
+ * `'notes'::regclass`, and this scan does not.
53
+ *
54
+ * @param sql - Function body or view query
55
+ * @returns Identifiers in source order
56
+ */
57
+ export declare function sqlIdentifiers(sql: string): readonly SqlName[];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  fail2
3
- } from "./f9mphxej.js";
3
+ } from "./2jdn09e2.js";
4
4
 
5
5
  // src/runtime/result-name.ts
6
6
  var PROTOTYPE_KEYS = ",__proto__,constructor,toString,hasOwnProperty,valueOf,isPrototypeOf,propertyIsEnumerable,toLocaleString,__defineGetter__,__defineSetter__,__lookupGetter__,__lookupSetter__,then,";