okmodel 0.1.1 → 0.3.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 (228) hide show
  1. package/README.md +727 -37
  2. package/dist/adapters/capabilities.d.ts +34 -0
  3. package/dist/adapters/pg/bunsql-extra.d.ts +17 -0
  4. package/dist/adapters/pg/bunsql.d.ts +60 -0
  5. package/dist/adapters/pg/call.d.ts +2 -12
  6. package/dist/adapters/pg/nodepostgres-extra.d.ts +18 -0
  7. package/dist/adapters/pg/nodepostgres.d.ts +57 -0
  8. package/dist/adapters/pg/postgres-extra.d.ts +50 -1
  9. package/dist/adapters/pg/postgresjs.d.ts +0 -4
  10. package/dist/adapters/pg/session.d.ts +94 -0
  11. package/dist/adapters/pg/watch.d.ts +18 -0
  12. package/dist/contracts/catalog/enum.d.ts +31 -4
  13. package/dist/contracts/catalog/extension.d.ts +61 -0
  14. package/dist/contracts/catalog/object.d.ts +1 -0
  15. package/dist/contracts/catalog/privilege.d.ts +64 -0
  16. package/dist/contracts/catalog/routine.d.ts +56 -0
  17. package/dist/contracts/catalog/types.d.ts +179 -18
  18. package/dist/contracts/catalog/view.d.ts +73 -0
  19. package/dist/contracts/connection.d.ts +13 -0
  20. package/dist/contracts/driver.d.ts +18 -5
  21. package/dist/contracts/error.d.ts +17 -1
  22. package/dist/contracts/generator.d.ts +63 -0
  23. package/dist/contracts/index.d.ts +2 -2
  24. package/dist/contracts/index.js +1 -1
  25. package/dist/contracts/internal.js +11 -9
  26. package/dist/contracts/location.d.ts +24 -0
  27. package/dist/contracts/rows.d.ts +15 -0
  28. package/dist/dialects/pg/archive-bind.d.ts +22 -0
  29. package/dist/dialects/pg/column.d.ts +129 -10
  30. package/dist/dialects/pg/compile.d.ts +1 -0
  31. package/dist/dialects/pg/custom.d.ts +6 -0
  32. package/dist/dialects/pg/ddl.d.ts +65 -1
  33. package/dist/dialects/pg/enum.d.ts +10 -8
  34. package/dist/dialects/pg/ext/citext.d.ts +14 -0
  35. package/dist/dialects/pg/ext/citext.js +11 -0
  36. package/dist/dialects/pg/ext/index.d.ts +52 -0
  37. package/dist/dialects/pg/ext/index.js +6 -0
  38. package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
  39. package/dist/dialects/pg/ext/pg-trgm.js +42 -0
  40. package/dist/dialects/pg/filter-parse.d.ts +19 -0
  41. package/dist/dialects/pg/filters.d.ts +19 -0
  42. package/dist/dialects/pg/fn/index.d.ts +107 -0
  43. package/dist/dialects/pg/fn/index.js +175 -0
  44. package/dist/dialects/pg/fn/touch.d.ts +14 -0
  45. package/dist/dialects/pg/index.d.ts +11 -2
  46. package/dist/dialects/pg/index.js +243 -1062
  47. package/dist/dialects/pg/introspect.d.ts +10 -1
  48. package/dist/dialects/pg/keys.d.ts +19 -3
  49. package/dist/dialects/pg/model.d.ts +223 -2
  50. package/dist/dialects/pg/operator-fit.d.ts +86 -0
  51. package/dist/dialects/pg/operators.d.ts +46 -1
  52. package/dist/dialects/pg/ops/arr-append.d.ts +9 -0
  53. package/dist/dialects/pg/ops/arr-ns.d.ts +7 -0
  54. package/dist/dialects/pg/ops/arr-remove.d.ts +9 -0
  55. package/dist/dialects/pg/ops/containedBy.d.ts +9 -0
  56. package/dist/dialects/pg/ops/contains.d.ts +8 -4
  57. package/dist/dialects/pg/ops/hasAnyKey.d.ts +8 -0
  58. package/dist/dialects/pg/ops/hasKey.d.ts +8 -0
  59. package/dist/dialects/pg/ops/json-ns.d.ts +6 -0
  60. package/dist/dialects/pg/ops/json-set.d.ts +12 -0
  61. package/dist/dialects/pg/ops/matches.d.ts +16 -0
  62. package/dist/dialects/pg/ops/overlaps.d.ts +9 -0
  63. package/dist/dialects/pg/ops/path.d.ts +13 -0
  64. package/dist/dialects/pg/preset.d.ts +76 -0
  65. package/dist/dialects/pg/relations.d.ts +59 -2
  66. package/dist/dialects/pg/role/check.d.ts +45 -0
  67. package/dist/dialects/pg/role/index.d.ts +50 -0
  68. package/dist/dialects/pg/role/sql.d.ts +44 -0
  69. package/dist/dialects/pg/schema.d.ts +109 -5
  70. package/dist/dialects/pg/table.d.ts +137 -11
  71. package/dist/dialects/pg/temporal.d.ts +9 -7
  72. package/dist/dialects/pg/tenancy.d.ts +103 -0
  73. package/dist/dialects/pg/through.d.ts +21 -0
  74. package/dist/dialects/pg/trait.d.ts +141 -0
  75. package/dist/dialects/pg/view/client.d.ts +30 -0
  76. package/dist/dialects/pg/view/depend.d.ts +35 -0
  77. package/dist/dialects/pg/view/index.d.ts +114 -0
  78. package/dist/dialects/pg/view/index.js +289 -0
  79. package/dist/dialects/pg/view/scratch.d.ts +21 -0
  80. package/dist/dialects/pg/where.d.ts +37 -0
  81. package/dist/runtime/aggregate.d.ts +25 -0
  82. package/dist/runtime/archive-handle.d.ts +18 -0
  83. package/dist/runtime/archive-rules.d.ts +12 -0
  84. package/dist/runtime/archive.d.ts +73 -0
  85. package/dist/runtime/batch.d.ts +20 -0
  86. package/dist/runtime/client.d.ts +114 -5
  87. package/dist/runtime/conflict.d.ts +2 -1
  88. package/dist/runtime/exposure.d.ts +27 -0
  89. package/dist/runtime/hookm.d.ts +39 -0
  90. package/dist/runtime/ids/index.d.ts +11 -0
  91. package/dist/runtime/ids/index.js +193 -0
  92. package/dist/runtime/ids/okid-extended.d.ts +19 -0
  93. package/dist/runtime/ids/okid-generator.d.ts +21 -0
  94. package/dist/runtime/ids/okid-shared.d.ts +89 -0
  95. package/dist/runtime/ids/okid.d.ts +24 -0
  96. package/dist/runtime/ids/uuid.d.ts +21 -0
  97. package/dist/runtime/lock.d.ts +22 -0
  98. package/dist/runtime/operator-sql.d.ts +8 -0
  99. package/dist/runtime/page.d.ts +25 -0
  100. package/dist/runtime/pg/bun.d.ts +30 -0
  101. package/dist/runtime/pg/bun.js +52 -0
  102. package/dist/runtime/pg/pg.d.ts +29 -0
  103. package/dist/runtime/pg/pg.js +52 -0
  104. package/dist/runtime/pg/pglite.js +16 -17
  105. package/dist/runtime/pg/postgresjs.js +14 -24
  106. package/dist/runtime/plan.d.ts +146 -7
  107. package/dist/runtime/preset-stack.d.ts +17 -0
  108. package/dist/runtime/presets.d.ts +48 -0
  109. package/dist/runtime/read-stream.d.ts +26 -0
  110. package/dist/runtime/safety/index.d.ts +159 -0
  111. package/dist/runtime/safety/index.js +294 -0
  112. package/dist/runtime/safety-hook.d.ts +42 -0
  113. package/dist/runtime/server-check.d.ts +34 -0
  114. package/dist/runtime/tenancy/index.d.ts +37 -0
  115. package/dist/runtime/tenancy/index.js +368 -0
  116. package/dist/runtime/trait-read.d.ts +30 -0
  117. package/dist/runtime/traits/index.d.ts +133 -0
  118. package/dist/runtime/traits/index.js +646 -0
  119. package/dist/runtime/transaction.d.ts +19 -0
  120. package/dist/runtime/tx.d.ts +22 -7
  121. package/dist/runtime/types.d.ts +376 -27
  122. package/dist/runtime/validate/bind.d.ts +11 -0
  123. package/dist/runtime/validate/closed.d.ts +16 -0
  124. package/dist/runtime/validate/engine.d.ts +41 -0
  125. package/dist/runtime/validate/hook.d.ts +17 -0
  126. package/dist/runtime/validate/index.d.ts +21 -0
  127. package/dist/runtime/validate/index.js +175 -0
  128. package/dist/runtime/validate/load.d.ts +13 -0
  129. package/dist/runtime/validate/places.d.ts +41 -0
  130. package/dist/runtime/validate/rules.d.ts +108 -0
  131. package/dist/runtime/validate/surface.d.ts +102 -0
  132. package/dist/runtime/write.d.ts +30 -5
  133. package/dist/shared/01yr20s5.js +149 -0
  134. package/dist/shared/0jc3ffzf.js +154 -0
  135. package/dist/shared/0v1g424p.js +26 -0
  136. package/dist/shared/1g0drakv.js +225 -0
  137. package/dist/shared/{kprcwaha.js → 1tfdfvhh.js} +5 -3
  138. package/dist/shared/{05w44d8g.js → 2ssqrv66.js} +767 -715
  139. package/dist/shared/3ekj9x92.js +210 -0
  140. package/dist/shared/49ypnfwt.js +1122 -0
  141. package/dist/shared/4e4c6vq2.js +62 -0
  142. package/dist/shared/4m9fn52z.js +70 -0
  143. package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
  144. package/dist/shared/5nmdenb6.js +1229 -0
  145. package/dist/shared/672t5vym.js +12 -0
  146. package/dist/shared/6bazvqwm.js +86 -0
  147. package/dist/shared/6w5j844a.js +201 -0
  148. package/dist/shared/{fgqgsb5z.js → 75xkjv0t.js} +2 -2
  149. package/dist/shared/7fvtrkwr.js +84 -0
  150. package/dist/shared/7m88x3e9.js +45 -0
  151. package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
  152. package/dist/shared/83eaefwr.js +10 -0
  153. package/dist/shared/94ez8kzh.js +19 -0
  154. package/dist/shared/96ps4g1z.js +32 -0
  155. package/dist/shared/{xqbhg6cn.js → 999ade2q.js} +95 -10
  156. package/dist/shared/9m80mkac.js +158 -0
  157. package/dist/shared/9x25fxhc.js +150 -0
  158. package/dist/shared/a5sxz52y.js +13 -0
  159. package/dist/shared/axhk06q1.js +156 -0
  160. package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
  161. package/dist/shared/bqha5cg6.js +229 -0
  162. package/dist/shared/bryqk9k9.js +31 -0
  163. package/dist/shared/c8aghh05.js +442 -0
  164. package/dist/shared/c9z5g0fm.js +309 -0
  165. package/dist/shared/{m3ypagh5.js → dbjej1tw.js} +124 -15
  166. package/dist/shared/dyj86cmj.js +69 -0
  167. package/dist/shared/e6wg00wd.js +164 -0
  168. package/dist/shared/{hadrfb9h.js → edwqqryd.js} +17 -14
  169. package/dist/shared/{qk3hxfja.js → fptpmvxp.js} +5 -5
  170. package/dist/shared/fs0ex00p.js +76 -0
  171. package/dist/shared/{jjb7yht9.js → g4f5kcx9.js} +3 -3
  172. package/dist/shared/gjthds9j.js +48 -0
  173. package/dist/shared/hcmdtwgh.js +102 -0
  174. package/dist/shared/{g5fhqmwe.js → jkc6ws1p.js} +6 -56
  175. package/dist/shared/{yd1kzwn2.js → jns2wx4t.js} +55 -12
  176. package/dist/shared/k34e0xf2.js +450 -0
  177. package/dist/shared/k3ted12y.js +33 -0
  178. package/dist/shared/k7dwkhvq.js +31 -0
  179. package/dist/shared/{8b04d28c.js → kgnc8grt.js} +2 -2
  180. package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
  181. package/dist/shared/m78s7898.js +376 -0
  182. package/dist/shared/m9tv7xn7.js +404 -0
  183. package/dist/shared/meck53jv.js +99 -0
  184. package/dist/shared/mt5wswjz.js +90 -0
  185. package/dist/shared/n0dgs0pb.js +75 -0
  186. package/dist/shared/n442h54c.js +14 -0
  187. package/dist/shared/n4jqhpqz.js +27 -0
  188. package/dist/shared/n7mcc1gk.js +132 -0
  189. package/dist/shared/ne02ng5c.js +68 -0
  190. package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
  191. package/dist/shared/nsva2a6b.js +42 -0
  192. package/dist/shared/p24x2334.js +195 -0
  193. package/dist/shared/qbxzvwwc.js +88 -0
  194. package/dist/shared/{w8samvk1.js → qybh48nd.js} +1 -1
  195. package/dist/shared/r6nwkxnt.js +86 -0
  196. package/dist/shared/{xy79j5hq.js → rrstp3kb.js} +25 -36
  197. package/dist/shared/rwmrejjz.js +26 -0
  198. package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
  199. package/dist/shared/{523ft3e8.js → scwxrpx2.js} +7 -5
  200. package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
  201. package/dist/shared/{y9m15dfv.js → t616ynfn.js} +544 -32
  202. package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
  203. package/dist/shared/th14ygv2.js +69 -0
  204. package/dist/shared/tmbdywx0.js +178 -0
  205. package/dist/shared/ty3v3hfk.js +64 -0
  206. package/dist/shared/wekze34d.js +246 -0
  207. package/dist/shared/x6wysh83.js +1132 -0
  208. package/dist/shared/{rgs0st28.js → xrfnq5k8.js} +237 -434
  209. package/dist/shared/{x5x59srr.js → xva8v7qk.js} +416 -83
  210. package/dist/shared/{dkn3y60a.js → xw1d69vd.js} +76 -112
  211. package/dist/shared/y005b761.js +112 -0
  212. package/dist/shared/ydaz1sv3.js +55 -0
  213. package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
  214. package/dist/tooling/cli.js +40 -12
  215. package/dist/tooling/migrate/apply.d.ts +16 -0
  216. package/dist/tooling/migrate/commands.d.ts +12 -1
  217. package/dist/tooling/migrate/config.d.ts +8 -0
  218. package/dist/tooling/migrate/doctor.d.ts +25 -0
  219. package/dist/tooling/migrate/drift.d.ts +19 -0
  220. package/dist/tooling/migrate/engine.d.ts +36 -0
  221. package/dist/tooling/migrate/ext.d.ts +17 -0
  222. package/dist/tooling/migrate/extensions.d.ts +51 -0
  223. package/dist/tooling/migrate/managed.d.ts +17 -0
  224. package/dist/tooling/migrate/plan.d.ts +14 -1
  225. package/dist/tooling/migrate/project.d.ts +25 -1
  226. package/dist/tooling/migrate/type-name.d.ts +19 -0
  227. package/package.json +61 -4
  228. package/dist/shared/gk7cs7sp.js +0 -566
@@ -1,13 +1,12 @@
1
1
  import {
2
2
  POSTGRESJS_CAPABILITIES,
3
- driverErrors,
4
3
  rejectClosed,
5
4
  mapFailure,
6
5
  nextTransactionDepth,
7
6
  runCall,
8
7
  EMPTY_NOTICES,
9
8
  resultFrom
10
- } from "./xy79j5hq.js";
9
+ } from "./rrstp3kb.js";
11
10
 
12
11
  // src/adapters/pg/postgresjs.ts
13
12
  import net from "node:net";
@@ -37,61 +36,29 @@ class PoolSockets {
37
36
  this.park();
38
37
  });
39
38
  }
40
- async hold(checkout) {
41
- this.busy += 1;
42
- this.wake();
43
- try {
44
- const connection = await checkout();
45
- let released = false;
46
- const release = connection.release.bind(connection);
47
- connection.release = () => {
48
- if (released)
49
- return Promise.resolve();
50
- released = true;
51
- return release().finally(() => {
52
- this.busy -= 1;
53
- this.park();
54
- });
55
- };
56
- return connection;
57
- } catch (error) {
58
- this.busy -= 1;
59
- this.park();
60
- throw error;
61
- }
62
- }
63
- async* stream(open) {
64
- this.busy += 1;
65
- this.wake();
66
- try {
67
- yield* open();
68
- } finally {
69
- this.busy -= 1;
70
- this.park();
71
- }
39
+ busyGate() {
40
+ return {
41
+ enter: () => {
42
+ this.busy += 1;
43
+ this.wake();
44
+ },
45
+ leave: () => {
46
+ this.busy -= 1;
47
+ this.park();
48
+ }
49
+ };
72
50
  }
73
- async listen(start) {
74
- this.listeners += 1;
75
- this.wake();
76
- try {
77
- const stop = await start();
78
- let stopped = false;
79
- return async () => {
80
- if (stopped)
81
- return;
82
- stopped = true;
83
- try {
84
- await stop();
85
- } finally {
86
- this.listeners -= 1;
87
- this.park();
88
- }
89
- };
90
- } catch (error) {
91
- this.listeners -= 1;
92
- this.park();
93
- throw error;
94
- }
51
+ listenerGate() {
52
+ return {
53
+ enter: () => {
54
+ this.listeners += 1;
55
+ this.wake();
56
+ },
57
+ leave: () => {
58
+ this.listeners -= 1;
59
+ this.park();
60
+ }
61
+ };
95
62
  }
96
63
  wake() {
97
64
  for (const socket of this.held)
@@ -150,7 +117,7 @@ function open2(config) {
150
117
  },
151
118
  async batch(statements, options) {
152
119
  return sockets.occupy(async () => {
153
- const { checkout } = await import("./xqbhg6cn.js");
120
+ const { checkout } = await import("./999ade2q.js");
154
121
  const connection = await checkout(held);
155
122
  try {
156
123
  return await connection.batch(statements, options);
@@ -160,21 +127,36 @@ function open2(config) {
160
127
  });
161
128
  },
162
129
  reserve() {
163
- return sockets.hold(async () => {
164
- const mod = await import("./xqbhg6cn.js");
165
- return mod.checkout(held);
130
+ const gate = sockets.busyGate();
131
+ gate.enter();
132
+ return import("./999ade2q.js").then((mod) => mod.holdCheckout(gate, () => mod.checkout(held)), (error) => {
133
+ gate.leave();
134
+ throw error;
166
135
  });
167
136
  },
168
- describe: (text, params) => sockets.occupy(() => import("./xqbhg6cn.js").then((mod) => mod.describe(sql, text, params))),
137
+ describe: (text, params) => sockets.occupy(() => import("./999ade2q.js").then((mod) => mod.describe(sql, text, params))),
169
138
  stream(text, params) {
170
- return sockets.stream(() => loadStream(sql, text, params));
139
+ const gate = sockets.busyGate();
140
+ return async function* () {
141
+ gate.enter();
142
+ try {
143
+ yield* loadStream(sql, text, params);
144
+ } finally {
145
+ gate.leave();
146
+ }
147
+ }();
171
148
  },
172
149
  listen(channel, onNotify) {
173
- return sockets.listen(async () => {
150
+ const gate = sockets.listenerGate();
151
+ gate.enter();
152
+ return import("./999ade2q.js").then((mod) => mod.holdListener(gate, async () => {
174
153
  const listening = await sql.listen(channel, onNotify);
175
154
  return async () => {
176
155
  await listening.unlisten();
177
156
  };
157
+ }), (error) => {
158
+ gate.leave();
159
+ throw error;
178
160
  });
179
161
  },
180
162
  cancel() {
@@ -228,7 +210,36 @@ class PgSession {
228
210
  });
229
211
  });
230
212
  }
231
- return this.watched(pending, watch, start, text);
213
+ this.local.add(pending);
214
+ this.shared?.add(pending);
215
+ const onAbort = () => {
216
+ pending.cancel();
217
+ };
218
+ if (watch.signal.aborted)
219
+ onAbort();
220
+ else
221
+ watch.signal.addEventListener("abort", onAbort, { once: true });
222
+ return import("./999ade2q.js").then((mod) => mod.watchQuery(pending, watch, onAbort, {
223
+ start,
224
+ text,
225
+ notices: this.notices,
226
+ leave: () => {
227
+ this.leave();
228
+ },
229
+ note: (sqlText) => {
230
+ this.note(sqlText);
231
+ },
232
+ untrack: (item) => {
233
+ this.local.delete(item);
234
+ this.shared?.delete(item);
235
+ }
236
+ }), (error) => {
237
+ this.leave();
238
+ this.local.delete(pending);
239
+ this.shared?.delete(pending);
240
+ watch.signal.removeEventListener("abort", onAbort);
241
+ throw error;
242
+ });
232
243
  }
233
244
  inTransaction() {
234
245
  return this.transactionDepth > 0;
@@ -258,43 +269,9 @@ class PgSession {
258
269
  else
259
270
  this.counters.reservedBusy = Math.max(0, this.counters.reservedBusy - 1);
260
271
  }
261
- track(pending) {
262
- this.local.add(pending);
263
- this.shared?.add(pending);
264
- }
265
- untrack(pending) {
266
- this.local.delete(pending);
267
- this.shared?.delete(pending);
268
- }
269
- watched(pending, watch, start, text) {
270
- this.track(pending);
271
- const onAbort = () => {
272
- pending.cancel();
273
- };
274
- if (watch.signal.aborted)
275
- onAbort();
276
- else
277
- watch.signal.addEventListener("abort", onAbort, { once: true });
278
- return pending.then((result) => {
279
- this.finishWatched(pending, watch, onAbort);
280
- const why = watch.reason();
281
- if (why === "timeout" || why === "cancelled")
282
- return classify(why, watch);
283
- this.note(text);
284
- return resultFrom(result, this.notices.since(start));
285
- }, (error) => {
286
- this.finishWatched(pending, watch, onAbort);
287
- return classify(error, watch);
288
- });
289
- }
290
- finishWatched(pending, watch, onAbort) {
291
- this.leave();
292
- this.untrack(pending);
293
- watch.signal.removeEventListener("abort", onAbort);
294
- }
295
272
  }
296
273
  async function* loadStream(sql, text, params) {
297
- const { stream } = await import("./xqbhg6cn.js");
274
+ const { stream } = await import("./999ade2q.js");
298
275
  yield* stream(sql, text, params);
299
276
  }
300
277
  function send(sql, text, params, named) {
@@ -307,19 +284,6 @@ function asParams(params) {
307
284
  return [];
308
285
  return params;
309
286
  }
310
- async function classify(error, watch) {
311
- const errors = await driverErrors();
312
- if (error instanceof errors.DriverError)
313
- return Promise.reject(error);
314
- const why = typeof error === "string" ? error : watch.reason();
315
- if (why === "timeout")
316
- return Promise.reject(errors.timedOut(typeof error === "string" ? undefined : error));
317
- const code = errors.errorField(error, "code");
318
- if (why === "cancelled" || code === "57014") {
319
- return Promise.reject(errors.cancelled(typeof error === "string" ? undefined : error));
320
- }
321
- return Promise.reject(errors.mapDriverError(error));
322
- }
323
287
  function statsOf(counters, size) {
324
288
  return {
325
289
  size,
@@ -0,0 +1,112 @@
1
+ import {
2
+ staticNamespace2,
3
+ assertNamespace2,
4
+ normaliseEdges,
5
+ assertProvenance
6
+ } from "./t4tbsy9h.js";
7
+ import {
8
+ assertIdentifier2,
9
+ fitIdentifier2,
10
+ deterministicName2
11
+ } from "./nfzc5z0w.js";
12
+ import {
13
+ catalogError2
14
+ } from "./52szzakm.js";
15
+
16
+ // src/contracts/catalog/view.ts
17
+ function normaliseViewQuery(query) {
18
+ return query.trim().replace(/;\s*$/, "");
19
+ }
20
+ function viewObject(input) {
21
+ const namespace = input.namespace ?? staticNamespace2("public");
22
+ const columns = readColumns(input.name, input.columns);
23
+ const query = readQuery(input.name, input.query);
24
+ assertNamespace2(namespace);
25
+ assertProvenance(input.provenance);
26
+ const definition = { columns, query };
27
+ return {
28
+ kind: "view",
29
+ identity: { kind: "view", namespace, name: input.name },
30
+ owner: input.owner ?? "managed",
31
+ definition,
32
+ dependencies: normaliseEdges(input.dependencies ?? []),
33
+ provenance: input.provenance
34
+ };
35
+ }
36
+ function materializedViewObject(input) {
37
+ const namespace = input.namespace ?? staticNamespace2("public");
38
+ const columns = readColumns(input.name, input.columns);
39
+ const query = readQuery(input.name, input.query);
40
+ assertNamespace2(namespace);
41
+ assertProvenance(input.provenance);
42
+ const definition = {
43
+ columns,
44
+ query,
45
+ ...input.refresh === "concurrently" ? { refresh: "concurrently" } : {}
46
+ };
47
+ return {
48
+ kind: "materializedView",
49
+ identity: { kind: "materializedView", namespace, name: input.name },
50
+ owner: input.owner ?? "managed",
51
+ definition,
52
+ dependencies: normaliseEdges(input.dependencies ?? []),
53
+ provenance: input.provenance
54
+ };
55
+ }
56
+ function materializedViewIndex(input) {
57
+ assertNamespace2(input.parent.namespace);
58
+ assertIdentifier2(input.parent.name, "index parent");
59
+ assertProvenance(input.provenance);
60
+ const columns = [...input.columns];
61
+ for (const name of columns)
62
+ assertIdentifier2(name, "index column");
63
+ if (columns.length === 0 && input.expression === undefined) {
64
+ catalogError2("OKM1020", `Index on ${input.parent.name} needs a column or an expression.`);
65
+ }
66
+ const nameKey = input.nameKey ?? (columns.length > 0 ? columns.join("_") : "expr");
67
+ const name = input.name === undefined ? deterministicName2({ parent: input.parent.name, purpose: "index", nameKey }) : fitIdentifier2(input.name);
68
+ const parentView = {
69
+ kind: "materializedView",
70
+ namespace: input.parent.namespace,
71
+ name: input.parent.name
72
+ };
73
+ return {
74
+ kind: "index",
75
+ identity: { kind: "index", parent: input.parent, name },
76
+ owner: input.owner ?? "managed",
77
+ definition: {
78
+ columns,
79
+ unique: input.unique === true,
80
+ nameKey,
81
+ ...input.expression !== undefined ? { expression: input.expression } : {},
82
+ ...input.predicate !== undefined ? { predicate: input.predicate } : {}
83
+ },
84
+ dependencies: normaliseEdges(input.dependencies ?? [parentView]),
85
+ provenance: input.provenance
86
+ };
87
+ }
88
+ function readColumns(view, columns) {
89
+ assertIdentifier2(view, "view");
90
+ if (columns.length === 0)
91
+ catalogError2("OKM1020", `View ${view} needs a column.`);
92
+ const seen = new Set;
93
+ return columns.map((column) => {
94
+ assertIdentifier2(column.name, `view ${view} column`);
95
+ if (seen.has(column.name)) {
96
+ catalogError2("OKM1020", `View ${view} lists column ${column.name} twice.`);
97
+ }
98
+ seen.add(column.name);
99
+ if (column.dataType.length === 0 || /[;'"\\]/.test(column.dataType)) {
100
+ catalogError2("OKM1020", `View ${view} column ${column.name} type is not a type name.`);
101
+ }
102
+ return { name: column.name, dataType: column.dataType };
103
+ });
104
+ }
105
+ function readQuery(view, query) {
106
+ const text = normaliseViewQuery(query);
107
+ if (text.length === 0)
108
+ catalogError2("OKM1020", `View ${view} needs a query.`);
109
+ return text;
110
+ }
111
+
112
+ export { normaliseViewQuery, viewObject, materializedViewObject, materializedViewIndex };
@@ -0,0 +1,55 @@
1
+ import {
2
+ decodeRows,
3
+ readHandle,
4
+ readCall,
5
+ attachHttp
6
+ } from "./k34e0xf2.js";
7
+ import {
8
+ fail
9
+ } from "./xrfnq5k8.js";
10
+ import {
11
+ OkmError2,
12
+ throwNamed2
13
+ } from "./52szzakm.js";
14
+
15
+ // src/runtime/lock.ts
16
+ var LOCKS = ["update", "share"];
17
+ var WAITS = ["nowait", "skip"];
18
+ function shown(value) {
19
+ return typeof value === "string" ? value : JSON.stringify(value) ?? "undefined";
20
+ }
21
+ function build(session, table, options, mods, view) {
22
+ try {
23
+ return plan(session, table, options, mods, view);
24
+ } catch (error) {
25
+ throw error instanceof OkmError2 ? attachHttp(session.http, error) : error;
26
+ }
27
+ }
28
+ function plan(session, table, options, mods, view) {
29
+ const { lock, wait, ...rest } = options;
30
+ if (session.tx === undefined) {
31
+ throw new OkmError2("OKM1830", "A row lock needs a transaction. find was called outside tx().", {
32
+ fix: { summary: "Move the find into tx(): the lock lasts until the transaction ends." }
33
+ });
34
+ }
35
+ if (lock === undefined)
36
+ fail("OKM1121", "wait needs lock: pass lock: update or lock: share.");
37
+ if (typeof lock !== "string" || !LOCKS.includes(lock)) {
38
+ throwNamed2("OKM1120", shown(lock), LOCKS, `lock must be one of: ${LOCKS.join(", ")}.`);
39
+ }
40
+ if (wait !== undefined && (typeof wait !== "string" || !WAITS.includes(wait))) {
41
+ throwNamed2("OKM1120", shown(wait), WAITS, `wait must be one of: ${WAITS.join(", ")}.`);
42
+ }
43
+ const clause = ` for ${lock} of t${wait === undefined ? "" : wait === "skip" ? " skip locked" : " nowait"}`;
44
+ const call = {
45
+ ...readCall("find", table, rest, mods.all, session.scope, session.schema.model[table], session.schema, view),
46
+ tail(sink) {
47
+ sink.text(clause);
48
+ sink.mark(`lock:${clause}`);
49
+ }
50
+ };
51
+ return readHandle(session, table, call, mods, (compiled, rows) => decodeRows(compiled, rows, table));
52
+ }
53
+ export {
54
+ build
55
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OkmError2
3
- } from "./ycwz42az.js";
3
+ } from "./52szzakm.js";
4
4
 
5
5
  // src/runtime/drift-detail.ts
6
6
  function driftVerdict(codeHash, recordedHash, migrations) {
@@ -1,14 +1,17 @@
1
- import"../shared/y9m15dfv.js";
1
+ import"../shared/t616ynfn.js";
2
+ import"../shared/n442h54c.js";
2
3
  import {
3
- formatPlan,
4
4
  buildProject,
5
5
  generateProject,
6
6
  planProject,
7
7
  checkProject
8
- } from "../shared/05w44d8g.js";
8
+ } from "../shared/5nmdenb6.js";
9
+ import {
10
+ formatPlan
11
+ } from "../shared/2ssqrv66.js";
9
12
  import {
10
13
  OkmError2
11
- } from "../shared/ycwz42az.js";
14
+ } from "../shared/52szzakm.js";
12
15
 
13
16
  // src/tooling/cli.ts
14
17
  import { readFileSync } from "node:fs";
@@ -16,6 +19,11 @@ import { dirname, join } from "node:path";
16
19
  import { fileURLToPath } from "node:url";
17
20
 
18
21
  // src/tooling/migrate/commands.ts
22
+ function formatFailure(error) {
23
+ return `${error.code}: ${error.message}
24
+ ${error.fix.summary}
25
+ `;
26
+ }
19
27
  async function run(argv, io) {
20
28
  const cwd = io?.cwd ?? process.cwd();
21
29
  const stdout = io?.stdout ?? ((text) => process.stdout.write(text));
@@ -27,7 +35,7 @@ async function run(argv, io) {
27
35
  return;
28
36
  }
29
37
  if (command === "check") {
30
- await checkProject(cwd);
38
+ await checkProject(cwd, invoke(splitFlags(rest)));
31
39
  stdout(`ok
32
40
  `);
33
41
  return;
@@ -41,12 +49,12 @@ async function run(argv, io) {
41
49
  return;
42
50
  }
43
51
  if (command === "dev") {
44
- const { devProject } = await import("../shared/kprcwaha.js");
52
+ const { devProject } = await import("../shared/1tfdfvhh.js");
45
53
  stdout(await devProject(cwd));
46
54
  return;
47
55
  }
48
56
  if (command === "push") {
49
- const { pushProject } = await import("../shared/m3ypagh5.js");
57
+ const { pushProject } = await import("../shared/dbjej1tw.js");
50
58
  stdout(await pushProject(cwd, invoke(splitFlags(rest))));
51
59
  return;
52
60
  }
@@ -61,16 +69,38 @@ async function run(argv, io) {
61
69
  return;
62
70
  }
63
71
  if (sub === "apply") {
64
- const { applyProject } = await import("../shared/m3ypagh5.js");
72
+ const { applyProject } = await import("../shared/dbjej1tw.js");
65
73
  stdout(await applyProject(cwd, invoke(parsed)));
66
74
  return;
67
75
  }
68
76
  if (sub === "status") {
69
- const { statusProject } = await import("../shared/523ft3e8.js");
77
+ const { statusProject } = await import("../shared/scwxrpx2.js");
70
78
  stdout(await statusProject(cwd, invoke(parsed)));
71
79
  return;
72
80
  }
73
81
  }
82
+ if (command === "doctor") {
83
+ const parsed = splitFlags(rest);
84
+ const { doctorProject } = await import("../shared/ne02ng5c.js");
85
+ stdout(await doctorProject(cwd, parsed.name, invoke(parsed)));
86
+ return;
87
+ }
88
+ if (command === "ext") {
89
+ const sub = rest[0];
90
+ if (sub === "test" || sub === "scaffold") {
91
+ throw new OkmError2("invalid", `okm ext ${sub} is not available yet.`, {
92
+ fix: { summary: "okm ext list and okm ext check are the commands in this version." }
93
+ });
94
+ }
95
+ if (sub === "list" || sub === "check") {
96
+ const { extProject } = await import("../shared/meck53jv.js");
97
+ stdout(await extProject(cwd, sub, invoke(splitFlags(rest.slice(1)))));
98
+ return;
99
+ }
100
+ throw new OkmError2("invalid", `Unknown command ext ${sub ?? ""}.`, {
101
+ fix: { summary: "Use okm ext list or okm ext check." }
102
+ });
103
+ }
74
104
  throw new OkmError2("invalid", `Unknown command ${command ?? ""}.`);
75
105
  }
76
106
  function invoke(parsed) {
@@ -172,9 +202,7 @@ if (process.argv.includes("--version")) {
172
202
  await run(process.argv.slice(2));
173
203
  } catch (error) {
174
204
  if (error instanceof OkmError2) {
175
- process.stderr.write(`${error.code}: ${error.message}
176
- ${error.fix.summary}
177
- `);
205
+ process.stderr.write(formatFailure(error));
178
206
  process.exitCode = 1;
179
207
  } else {
180
208
  throw error;
@@ -37,11 +37,27 @@ export type ApplyRequest = {
37
37
  readonly migrations: readonly StoredMigration[];
38
38
  /** Runs after the advisory lock is held and before the first step. */
39
39
  readonly onLocked?: () => void;
40
+ /**
41
+ * Role that runs the migration.
42
+ *
43
+ * When it already exists and is not `current_user`, the runner issues one
44
+ * `SET ROLE` before any statement. That statement is not a plan step.
45
+ */
46
+ readonly migrationRole?: string;
47
+ /**
48
+ * Schema the migration role may create in.
49
+ *
50
+ * When this run creates that role, the runner grants `USAGE` and `CREATE`
51
+ * on this schema before `SET ROLE`. The default is `public`.
52
+ */
53
+ readonly schema?: string;
40
54
  };
41
55
  /** Migrations that ran at least one step in this invocation. */
42
56
  export type ApplyReport = {
43
57
  readonly target: string;
44
58
  readonly applied: readonly string[];
59
+ /** Set when the runner issued `SET ROLE` at session start. */
60
+ readonly setRole?: string;
45
61
  };
46
62
  /**
47
63
  * Groups pending steps into the transactions apply will run.
@@ -4,16 +4,27 @@
4
4
  * The bin wrapper imports {@link run}. Importing this module does not parse
5
5
  * `process.argv`.
6
6
  */
7
+ import { OkmError } from "../../contracts/error.js";
7
8
  /** Where a command reads the project and writes its text. */
8
9
  export type CommandIo = {
9
10
  readonly cwd?: string;
10
11
  readonly stdout?: (text: string) => void;
11
12
  };
13
+ /**
14
+ * Text `okm` writes for a failure.
15
+ *
16
+ * The message includes a source location when the schema recorded one.
17
+ *
18
+ * @param error - Failure from a command
19
+ * @returns The stderr text, including the trailing newline
20
+ */
21
+ export declare function formatFailure(error: OkmError): string;
12
22
  /**
13
23
  * Runs one `okm` invocation.
14
24
  *
15
25
  * `--version` stays in the bin. This function handles `build`, `check`,
16
- * `generate`, `dev`, `push`, and `migrate plan`, `apply`, and `status`.
26
+ * `generate`, `dev`, `push`, `ext list`, `ext check`, `doctor`, and `migrate plan`,
27
+ * `apply`, and `status`.
17
28
  *
18
29
  * @param argv - Arguments after the program name
19
30
  * @param io - Working directory and stdout. Defaults to the process
@@ -9,6 +9,7 @@ export type TargetInput = string | {
9
9
  /** Refuses contract, push, and other non-expand work unless `--allow-protected`. */
10
10
  readonly protected?: boolean;
11
11
  };
12
+ import type { RolesInput } from "../../dialects/pg/role/index.js";
12
13
  /** Paths and targets `okm` reads. */
13
14
  export type MigrateConfig = {
14
15
  /** Module that exports the built schema. */
@@ -35,6 +36,13 @@ export type MigrateConfig = {
35
36
  readonly lock?: number;
36
37
  readonly statement?: number;
37
38
  };
39
+ /**
40
+ * Migration role and application role.
41
+ *
42
+ * A name is external unless it is also listed in `managed`. The plan creates
43
+ * a managed role and never drops one.
44
+ */
45
+ readonly roles?: RolesInput;
38
46
  };
39
47
  /**
40
48
  * Returns the config unchanged.
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `okm doctor`.
3
+ *
4
+ * A code prints the registry entry. With no code, the project is loaded and
5
+ * each table's triggers are listed. When `roles` is set, the command also
6
+ * connects and checks that those roles exist, that a managed role can be
7
+ * created, and that the application role can reach each managed object.
8
+ */
9
+ import type { CatalogObject } from "../../contracts/catalog/types.js";
10
+ import { type InvokeFlags } from "./policy.js";
11
+ /**
12
+ * Explains one code, or lists the triggers on each table.
13
+ *
14
+ * @param cwd - Project directory
15
+ * @param code - Spec code, when the caller passed one
16
+ * @returns Text for stdout, including the trailing newline
17
+ */
18
+ export declare function doctorProject(cwd: string, code: string | undefined, flags?: InvokeFlags): Promise<string>;
19
+ /**
20
+ * One line per table that has a trigger.
21
+ *
22
+ * @param objects - Catalog objects
23
+ * @returns The listing, or `no triggers` when none are present
24
+ */
25
+ export declare function formatTriggers(objects: readonly CatalogObject[]): string;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Live drift for `okm check`.
3
+ *
4
+ * A database that has never been pushed has no `okm_meta` and is left alone.
5
+ * After push, the introspected catalog is planned back to the schema. Each
6
+ * view is reprinted on this server first, so a `pg_get_viewdef` spelling is
7
+ * not drift. Any remaining statement is OKM1520. `okm_meta` and `okm_history`
8
+ * are omitted by the planner.
9
+ */
10
+ import type { Catalog } from "../../contracts/catalog/types.js";
11
+ import type { RolesInput } from "../../dialects/pg/role/index.js";
12
+ /**
13
+ * Refuses when the connected database differs from the schema.
14
+ *
15
+ * @param url - Target URL
16
+ * @param author - Schema catalog, including roles when the config names them
17
+ * @param roles - `defineConfig({ roles })`, when set
18
+ */
19
+ export declare function assertAuthorDrift(url: string, author: Catalog, roles?: RolesInput): Promise<void>;