okmodel 0.5.0 → 0.6.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 (169) hide show
  1. package/README.md +36 -18
  2. package/dist/adapters/pg/no-inflight-timeout.d.ts +17 -0
  3. package/dist/adapters/pg/postgres-extra.d.ts +22 -0
  4. package/dist/contracts/catalog/document.d.ts +19 -5
  5. package/dist/contracts/catalog/object.d.ts +2 -1
  6. package/dist/contracts/catalog/policy.d.ts +48 -0
  7. package/dist/contracts/catalog/types.d.ts +25 -1
  8. package/dist/contracts/catalog/view.d.ts +2 -0
  9. package/dist/contracts/internal.js +1 -1
  10. package/dist/contracts/location.d.ts +10 -0
  11. package/dist/dialects/pg/column.d.ts +13 -2
  12. package/dist/dialects/pg/ddl.d.ts +37 -1
  13. package/dist/dialects/pg/emit.d.ts +19 -1
  14. package/dist/dialects/pg/errors.d.ts +32 -1
  15. package/dist/dialects/pg/ext/citext.js +1 -1
  16. package/dist/dialects/pg/ext/index.js +1 -1
  17. package/dist/dialects/pg/ext/pg-trgm.js +1 -1
  18. package/dist/dialects/pg/filter-parse.d.ts +10 -3
  19. package/dist/dialects/pg/fn/index.js +10 -2
  20. package/dist/dialects/pg/index.d.ts +2 -1
  21. package/dist/dialects/pg/index.js +29 -17
  22. package/dist/dialects/pg/introspect.d.ts +7 -0
  23. package/dist/dialects/pg/model.d.ts +7 -2
  24. package/dist/dialects/pg/ops/or.d.ts +1 -1
  25. package/dist/dialects/pg/owner.d.ts +42 -0
  26. package/dist/dialects/pg/path-endpoint.d.ts +20 -0
  27. package/dist/dialects/pg/role/check.d.ts +3 -0
  28. package/dist/dialects/pg/role/index.d.ts +71 -6
  29. package/dist/dialects/pg/role/sql.d.ts +11 -0
  30. package/dist/dialects/pg/schema.d.ts +2 -0
  31. package/dist/dialects/pg/table.d.ts +25 -3
  32. package/dist/dialects/pg/temporal.d.ts +5 -76
  33. package/dist/dialects/pg/tenancy.d.ts +45 -3
  34. package/dist/dialects/pg/view/client.d.ts +19 -1
  35. package/dist/dialects/pg/view/index.d.ts +4 -0
  36. package/dist/dialects/pg/view/index.js +21 -178
  37. package/dist/dialects/pg/view/refresh.d.ts +24 -0
  38. package/dist/runtime/batch.d.ts +1 -1
  39. package/dist/runtime/client.d.ts +6 -1
  40. package/dist/runtime/conflict.d.ts +2 -1
  41. package/dist/runtime/drift.d.ts +9 -0
  42. package/dist/runtime/inflight.d.ts +14 -0
  43. package/dist/runtime/pg/bun.js +6 -5
  44. package/dist/runtime/pg/pg.js +5 -5
  45. package/dist/runtime/pg/pglite.js +6 -5
  46. package/dist/runtime/pg/postgresjs.js +5 -5
  47. package/dist/runtime/plan.d.ts +22 -1
  48. package/dist/runtime/predicate.d.ts +19 -0
  49. package/dist/runtime/safety/index.js +1 -1
  50. package/dist/runtime/tenancy/composite.d.ts +26 -0
  51. package/dist/runtime/tenancy/context.d.ts +16 -0
  52. package/dist/runtime/tenancy/index.d.ts +9 -5
  53. package/dist/runtime/tenancy/index.js +1508 -37
  54. package/dist/runtime/tenancy/path.d.ts +87 -0
  55. package/dist/runtime/tenancy/rls.d.ts +67 -0
  56. package/dist/runtime/tenancy/via.d.ts +22 -0
  57. package/dist/runtime/traits/index.js +17 -11
  58. package/dist/runtime/types.d.ts +13 -1
  59. package/dist/runtime/validate/index.js +4 -4
  60. package/dist/runtime/write.d.ts +1 -1
  61. package/dist/shared/09p049xa.js +702 -0
  62. package/dist/shared/{ykv7wh5b.js → 1f0xa3cb.js} +5 -5
  63. package/dist/shared/1nw1f3vs.js +23 -0
  64. package/dist/shared/{6p5k20sm.js → 1z04fa85.js} +21 -11
  65. package/dist/shared/{p7pfx624.js → 2cg3wnxc.js} +314 -65
  66. package/dist/shared/{dyj86cmj.js → 2jd1sn0e.js} +2 -2
  67. package/dist/shared/{qgvt8nx1.js → 2z7wv5tj.js} +21 -5
  68. package/dist/shared/{kyxb62mc.js → 31vm914h.js} +9 -1
  69. package/dist/shared/{sf8m6tfy.js → 32cnm7kn.js} +8 -3
  70. package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
  71. package/dist/shared/{jdgqqx31.js → 3fqwmr09.js} +38 -14
  72. package/dist/shared/{922qbgnw.js → 3qnhc7w5.js} +16 -9
  73. package/dist/shared/{zvbjc949.js → 4az561fn.js} +1 -1
  74. package/dist/shared/{k3ted12y.js → 54tqkxja.js} +20 -2
  75. package/dist/shared/{k7cc9nzk.js → 5d8t84hg.js} +15 -3
  76. package/dist/shared/{fa9vt245.js → 5j36z8dn.js} +17 -6
  77. package/dist/shared/{1g0drakv.js → 5yv4k6a6.js} +1 -1
  78. package/dist/shared/8dqhth8c.js +12 -0
  79. package/dist/shared/8etn7d8w.js +62 -0
  80. package/dist/shared/{g516zdsb.js → 8x72s86k.js} +476 -30
  81. package/dist/shared/{nkc9sfqb.js → 929h19xp.js} +145 -7
  82. package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
  83. package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
  84. package/dist/shared/{b066g80h.js → ag4c7516.js} +2 -2
  85. package/dist/shared/b3awxn7h.js +45 -0
  86. package/dist/shared/b4v57v3x.js +9 -0
  87. package/dist/shared/bdk4sty6.js +58 -0
  88. package/dist/shared/{s6gqfn5j.js → c58secgj.js} +125 -8
  89. package/dist/shared/{rrstp3kb.js → cgbamx3e.js} +2 -2
  90. package/dist/shared/d5azex6s.js +6 -0
  91. package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
  92. package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
  93. package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
  94. package/dist/shared/{wxn4b7pp.js → f0f1n281.js} +59 -12
  95. package/dist/shared/{gdh9mrtp.js → g90m9b0g.js} +3 -2
  96. package/dist/shared/{tbszx8mz.js → gwn6v667.js} +2 -2
  97. package/dist/shared/{c8aghh05.js → h15jx9bc.js} +8 -2
  98. package/dist/shared/{3p4b1fg0.js → hazqqecq.js} +17 -93
  99. package/dist/shared/{4ef7mmqf.js → j3rkk835.js} +34 -11
  100. package/dist/shared/{bt9sfq0z.js → j60w0dvr.js} +56 -21
  101. package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
  102. package/dist/shared/k68eedmy.js +85 -0
  103. package/dist/shared/{szm0cksa.js → knmes2kh.js} +34 -6
  104. package/dist/shared/{ckjbyrt9.js → mb2ycs1p.js} +7 -9
  105. package/dist/shared/{tq9afp8d.js → n076ydsc.js} +1 -1
  106. package/dist/shared/{xhh1srw3.js → nx9hh281.js} +50 -32
  107. package/dist/shared/{kdkxh3kb.js → p248q79y.js} +58 -59
  108. package/dist/shared/{990a291j.js → p6bjzq9q.js} +14 -9
  109. package/dist/shared/{h4nqvjkp.js → pjr6xrm5.js} +2 -2
  110. package/dist/shared/pz6rj8ay.js +212 -0
  111. package/dist/shared/{5vdm4sgp.js → q3j1tq7a.js} +36 -23
  112. package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
  113. package/dist/shared/{dxjp14rk.js → r11n8grd.js} +2 -2
  114. package/dist/shared/r1fdd0f6.js +19 -0
  115. package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
  116. package/dist/shared/rhs3xe4k.js +7 -0
  117. package/dist/shared/{jsd07prz.js → rpycarcr.js} +6 -6
  118. package/dist/shared/{xsq7v6wp.js → sbdme3vy.js} +14 -2
  119. package/dist/shared/{xdpj5kkm.js → t3g0k88x.js} +775 -264
  120. package/dist/shared/{ayz64vzj.js → ttmg09vd.js} +708 -19
  121. package/dist/shared/{r6pj4fq2.js → venqrjna.js} +8 -4
  122. package/dist/shared/{fancm5pt.js → vjpnzwjz.js} +138 -15
  123. package/dist/shared/{9tgmr1gh.js → vmfkhszw.js} +44 -9
  124. package/dist/shared/{wqem4jed.js → wkme6tep.js} +11 -9
  125. package/dist/shared/{qy9rdq0g.js → wt5rzv1h.js} +15 -11
  126. package/dist/shared/wxr8cwns.js +6 -0
  127. package/dist/shared/{bzsjtd7c.js → wynzeggs.js} +19 -14
  128. package/dist/shared/x3jc53kg.js +220 -0
  129. package/dist/shared/{7p2wbz7f.js → x72jb7ad.js} +1 -1
  130. package/dist/shared/{fyqkk1m0.js → xq0mvhts.js} +10 -9
  131. package/dist/shared/xqve9598.js +53 -0
  132. package/dist/shared/{47xzb9fc.js → y2t3jktd.js} +2 -2
  133. package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
  134. package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
  135. package/dist/shared/{h8ne16fq.js → ys0xzyaj.js} +1 -1
  136. package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
  137. package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
  138. package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
  139. package/dist/shared/{fb00y8fp.js → zm0mafk4.js} +12 -6
  140. package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
  141. package/dist/tooling/cli.js +97 -24
  142. package/dist/tooling/migrate/apply.d.ts +14 -0
  143. package/dist/tooling/migrate/check.d.ts +3 -4
  144. package/dist/tooling/migrate/classify.d.ts +4 -0
  145. package/dist/tooling/migrate/commands.d.ts +1 -2
  146. package/dist/tooling/migrate/config.d.ts +3 -2
  147. package/dist/tooling/migrate/drift.d.ts +1 -1
  148. package/dist/tooling/migrate/estimate.d.ts +14 -1
  149. package/dist/tooling/migrate/files.d.ts +11 -1
  150. package/dist/tooling/migrate/index.js +17 -16
  151. package/dist/tooling/migrate/lint.d.ts +4 -4
  152. package/dist/tooling/migrate/lost.d.ts +28 -0
  153. package/dist/tooling/migrate/paths.d.ts +14 -0
  154. package/dist/tooling/migrate/plan.d.ts +10 -3
  155. package/dist/tooling/migrate/policy.d.ts +11 -0
  156. package/dist/tooling/migrate/runner.d.ts +25 -0
  157. package/dist/tooling/migrate/sandbox.d.ts +57 -0
  158. package/dist/tooling/migrate/sql-lex.d.ts +39 -0
  159. package/dist/tooling/migrate/text.d.ts +42 -0
  160. package/dist/tooling/node-version.d.ts +21 -0
  161. package/dist/tooling/testing/factories.d.ts +10 -0
  162. package/dist/tooling/testing/facts.d.ts +33 -5
  163. package/dist/tooling/testing/index.d.ts +1 -1
  164. package/dist/tooling/testing/index.js +3 -3
  165. package/dist/tooling/testing/isolation.d.ts +15 -8
  166. package/package.json +10 -6
  167. package/dist/shared/0v1g424p.js +0 -26
  168. package/dist/shared/r73pt594.js +0 -426
  169. package/dist/shared/rasvvzgz.js +0 -21
@@ -1,18 +1,24 @@
1
+ import {
2
+ DriverError2
3
+ } from "./31vm914h.js";
4
+ import {
5
+ noTimeout2
6
+ } from "./8dqhth8c.js";
1
7
  import {
2
8
  send2,
3
9
  reserve,
4
10
  park
5
- } from "./sf8m6tfy.js";
11
+ } from "./32cnm7kn.js";
6
12
  import {
7
13
  isConnectionLost
8
- } from "./tbszx8mz.js";
14
+ } from "./gwn6v667.js";
9
15
  import {
10
16
  WireSession
11
- } from "./zvbjc949.js";
17
+ } from "./4az561fn.js";
12
18
  import {
13
19
  rejectClosed,
14
20
  runCall
15
- } from "./rrstp3kb.js";
21
+ } from "./cgbamx3e.js";
16
22
 
17
23
  // src/adapters/pg/bunsql-extra.ts
18
24
  async function checkout(held) {
@@ -27,18 +33,28 @@ async function checkout(held) {
27
33
  counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
28
34
  });
29
35
  let lost = false;
30
- const guard = (run) => lost ? rejectClosed("The connection was lost.") : run().catch((error) => {
36
+ const guard = (run) => lost ? rejectClosed("CONNECTION_CLOSED") : run().catch((error) => {
31
37
  if (isConnectionLost(error))
32
38
  lost = true;
39
+ if (error instanceof Error && bunClosed(error.message)) {
40
+ lost = true;
41
+ throw new DriverError2("CONNECTION_CLOSED", { cause: error });
42
+ }
33
43
  throw error;
34
44
  });
35
45
  let released = false;
36
46
  return {
37
- execute: (text, params, options) => guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch))),
38
- batch: (statements, options) => guard(() => runCall(isClosed(), options, async (watch) => {
39
- const { runAtomicBatch } = await import("./b066g80h.js");
40
- return runAtomicBatch(session, statements, watch);
41
- })),
47
+ execute: (text, params, options) => {
48
+ noTimeout2(options);
49
+ return guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch)));
50
+ },
51
+ batch: (statements, options) => {
52
+ noTimeout2(options);
53
+ return guard(() => runCall(isClosed(), options, async (watch) => {
54
+ const { runAtomicBatch } = await import("./ag4c7516.js");
55
+ return runAtomicBatch(session, statements, watch);
56
+ }));
57
+ },
42
58
  async release() {
43
59
  if (released)
44
60
  return;
@@ -48,12 +64,19 @@ async function checkout(held) {
48
64
  await reset(session, reserved);
49
65
  } finally {
50
66
  counters.reserved = Math.max(0, counters.reserved - 1);
51
- if (!lost)
67
+ if (lost)
68
+ await held.sql.unsafe("select 1").catch(() => {
69
+ return;
70
+ });
71
+ else
52
72
  await park(held.parked, reserved);
53
73
  }
54
74
  }
55
75
  };
56
76
  }
77
+ function bunClosed(message) {
78
+ return message === "Connection closed" || message === "connection must be a PostgresSQLConnection";
79
+ }
57
80
  async function reset(session, sql) {
58
81
  const run = (text) => sql.unsafe(text);
59
82
  if (session.depth() > 0)
@@ -7,7 +7,7 @@ import {
7
7
  decodeResult,
8
8
  logicalIntent,
9
9
  appliedRules
10
- } from "./qgvt8nx1.js";
10
+ } from "./2z7wv5tj.js";
11
11
  import {
12
12
  OkmError2,
13
13
  safe2,
@@ -22,10 +22,22 @@ var SINGLE_ENDPOINT = {
22
22
  reason: "single-endpoint"
23
23
  };
24
24
  function createClient(schema, pool, options) {
25
- const connected = checkServer(pool, schema, options.http, options.requireMeta === true, callOptions(options), {
25
+ const closing = {
26
+ current: undefined,
27
+ early: false
28
+ };
29
+ const checked = checkServer(pool, schema, options.http, options.requireMeta === true, callOptions(options), {
26
30
  ...options.catalog !== undefined ? { catalog: options.catalog } : {},
27
31
  ...options.catalogDir !== undefined ? { catalogDir: options.catalogDir } : {}
28
32
  });
33
+ const connected = checked.catch((error) => {
34
+ if (!closing.early)
35
+ throw error;
36
+ throw new OkmError2("unavailable", "The client was closed before it connected. Await connected before close(), or do not close it before use.", { kind: "unavailable", fix: { summary: "Await client.connected before calling close()." } });
37
+ });
38
+ connected.catch(() => {
39
+ return;
40
+ });
29
41
  const session = {
30
42
  schema,
31
43
  pool,
@@ -38,7 +50,7 @@ function createClient(schema, pool, options) {
38
50
  generators: options.generators,
39
51
  timeouts: options.timeouts,
40
52
  hookm: options.hookm,
41
- closing: { current: undefined }
53
+ closing
42
54
  };
43
55
  return openClient(session);
44
56
  }
@@ -50,6 +62,7 @@ function openClient(session) {
50
62
  const close = () => {
51
63
  if (!session.ownsPool)
52
64
  return Promise.resolve();
65
+ session.closing.early = true;
53
66
  session.closing.current ??= session.pool.close();
54
67
  return session.closing.current;
55
68
  };
@@ -72,7 +85,7 @@ function openClient(session) {
72
85
  },
73
86
  close,
74
87
  connected: session.connected,
75
- tx: (...args) => import("./k7cc9nzk.js").then((mod) => mod.tx(session, args)),
88
+ tx: (...args) => import("./5d8t84hg.js").then((mod) => mod.tx(session, args)),
76
89
  batch: (ops, options) => batchHandle(session, ops, options),
77
90
  ...session.tx?.extras
78
91
  };
@@ -107,7 +120,7 @@ function tableApi(session, table, view, uses) {
107
120
  const api = {
108
121
  find(options = {}) {
109
122
  if ("lock" in options) {
110
- return lazyRead(session, () => import("./dxjp14rk.js"), table, options, base, view);
123
+ return lazyRead(session, () => import("./r11n8grd.js"), table, options, base, view);
111
124
  }
112
125
  return start(session, "find", table, options, base, view);
113
126
  },
@@ -121,10 +134,10 @@ function tableApi(session, table, view, uses) {
121
134
  return start(session, "exists", table, options, base, view);
122
135
  },
123
136
  page(options) {
124
- return lazyRead(session, () => import("./h4nqvjkp.js"), table, options, base, view);
137
+ return lazyRead(session, () => import("./pjr6xrm5.js"), table, options, base, view);
125
138
  },
126
139
  aggregate(options = {}) {
127
- return lazyRead(session, () => import("./r6pj4fq2.js"), table, options, base, view);
140
+ return lazyRead(session, () => import("./venqrjna.js"), table, options, base, view);
128
141
  },
129
142
  insert(data, options = {}) {
130
143
  return writeHandle(session, "insert", table, data, options, mods);
@@ -154,13 +167,13 @@ function tableApi(session, table, view, uses) {
154
167
  return api;
155
168
  }
156
169
  function batchHandle(session, ops, options, replica) {
157
- return queryHandle(() => import("./xsq7v6wp.js").then((mod) => mod.batch(session, ops, options, replica)), {
170
+ return queryHandle(() => import("./sbdme3vy.js").then((mod) => mod.batch(session, ops, options, replica)), {
158
171
  replica: () => batchHandle(session, ops, options, true)
159
172
  });
160
173
  }
161
174
  var writers;
162
175
  function loadWrite() {
163
- writers ??= import("./p7pfx624.js");
176
+ writers ??= import("./2cg3wnxc.js");
164
177
  return writers;
165
178
  }
166
179
  function queryHandle(run, extra) {
@@ -215,9 +228,30 @@ async function runWrite(session, op, table, input, options, mods, plan) {
215
228
  throw logged(session, await mapError(session, error));
216
229
  }
217
230
  }
231
+ function rejectedRead(error) {
232
+ const fail = () => Promise.reject(error);
233
+ return queryHandle(fail, {
234
+ all: () => rejectedRead(error),
235
+ required: () => rejectedRead(error),
236
+ inspect: fail,
237
+ sql: fail,
238
+ stream() {
239
+ return {
240
+ [Symbol.asyncIterator]() {
241
+ return { next: fail };
242
+ }
243
+ };
244
+ }
245
+ });
246
+ }
218
247
  function start(session, op, table, options, mods, view) {
219
248
  const model = session.schema.model[table];
220
- const call = readCall(op, table, options, mods.all, session.scope, model, session.schema, view);
249
+ let call;
250
+ try {
251
+ call = readCall(op, table, options, mods.all, session.scope, model, session.schema, view);
252
+ } catch (error) {
253
+ return rejectedRead(error instanceof OkmError2 ? attachHttp(session.http, error) : error);
254
+ }
221
255
  return readHandle(session, table, call, mods, async (plan, rows) => {
222
256
  const value = await decodeRows(plan, rows, table);
223
257
  if (mods.required === true && value === null) {
@@ -245,7 +279,7 @@ function lazyRead(session, load, table, options, mods, view) {
245
279
  });
246
280
  }
247
281
  async function decodeRows(plan, rows, table) {
248
- return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./h8ne16fq.js")).decodeIncluded(plan, rows, table);
282
+ return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./ys0xzyaj.js")).decodeIncluded(plan, rows, table);
249
283
  }
250
284
  function readHandle(session, table, call, mods, decode, extra) {
251
285
  let prepared;
@@ -320,7 +354,7 @@ function readHandle(session, table, call, mods, decode, extra) {
320
354
  }
321
355
  function streamLazy(session, call, prepare) {
322
356
  return async function* () {
323
- const { streamRows } = await import("./922qbgnw.js");
357
+ const { streamRows } = await import("./3qnhc7w5.js");
324
358
  yield* streamRows(session, call, prepare, (error) => logged(session, error));
325
359
  }();
326
360
  }
@@ -357,14 +391,14 @@ function readCall(op, table, options, all, scope, model, schema, view) {
357
391
  };
358
392
  }
359
393
  async function checkServer(pool, schema, http, requireMeta, options, source) {
360
- const server = await import("./47xzb9fc.js");
394
+ const server = await import("./y2t3jktd.js");
361
395
  let rows;
362
396
  try {
363
397
  const result = await pool.execute(server.versionQuery, undefined, options);
364
398
  rows = result.rows;
365
399
  } catch (error) {
366
- const { mapPostgresError } = await import("./s6gqfn5j.js");
367
- throw mapPostgresError(error, mapOptions(http, false));
400
+ const { mapPostgresError } = await import("./d5azex6s.js");
401
+ throw mapPostgresError(error, mapOptions(http, false, schema));
368
402
  }
369
403
  await server.acceptServer(pool, schema, rows, http, requireMeta, options, source);
370
404
  }
@@ -372,8 +406,8 @@ async function mapError(session, error) {
372
406
  if (error instanceof OkmError2) {
373
407
  return session.http === undefined ? error : new OkmError2(error.code, error.message, { ...errorFields(error), http: session.http });
374
408
  }
375
- const { mapPostgresError } = await import("./s6gqfn5j.js");
376
- return mapPostgresError(error, mapOptions(session.http, session.includeValues));
409
+ const { mapPostgresError } = await import("./d5azex6s.js");
410
+ return mapPostgresError(error, mapOptions(session.http, session.includeValues, session.schema));
377
411
  }
378
412
  function errorFields(error) {
379
413
  return {
@@ -386,7 +420,7 @@ function errorFields(error) {
386
420
  var includeHooks;
387
421
  var operatorSql;
388
422
  function loadOperatorSql() {
389
- operatorSql ??= import("./tq9afp8d.js").then(() => {
423
+ operatorSql ??= import("./n076ydsc.js").then(() => {
390
424
  return;
391
425
  });
392
426
  return operatorSql;
@@ -394,7 +428,7 @@ function loadOperatorSql() {
394
428
  function hooksFor(call) {
395
429
  if (call.include === undefined)
396
430
  return Promise.resolve(undefined);
397
- includeHooks ??= import("./h8ne16fq.js").then((mod) => mod.includeHooks);
431
+ includeHooks ??= import("./ys0xzyaj.js").then((mod) => mod.includeHooks);
398
432
  return includeHooks;
399
433
  }
400
434
  function bindNow(schema, call) {
@@ -435,10 +469,11 @@ function callOptions(input, statement) {
435
469
  ...route !== undefined ? { route } : {}
436
470
  };
437
471
  }
438
- function mapOptions(http, includeValues) {
472
+ function mapOptions(http, includeValues, schema) {
439
473
  return {
440
474
  ...http !== undefined ? { http } : {},
441
- ...includeValues ? { includeValues: true } : {}
475
+ ...includeValues ? { includeValues: true } : {},
476
+ schema
442
477
  };
443
478
  }
444
479
  async function settleCall(session, error) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  extensionObject
3
- } from "./8ktwd3rh.js";
3
+ } from "./r3j8s5y0.js";
4
4
  import {
5
5
  OkmError2
6
6
  } from "./52szzakm.js";
@@ -0,0 +1,85 @@
1
+ import {
2
+ catalogError2,
3
+ throwNamed2
4
+ } from "./52szzakm.js";
5
+
6
+ // src/dialects/pg/through.ts
7
+ var emit = (planner, schema, relation, child, sink, parent, alias, depth) => {
8
+ const through = relation.through;
9
+ const join = through === undefined ? undefined : planner.indexes(schema).get(through.table);
10
+ if (through === undefined || join === undefined) {
11
+ return catalogError2("OKM1020", `Relation ${relation.name} names a join table that is not in the schema.`);
12
+ }
13
+ const { quote } = planner;
14
+ const joinAlias = `j${alias}`;
15
+ sink.mark(`via:${through.table}`);
16
+ sink.text(`${quote(join.model.sql)} ${joinAlias} join ${quote(child.model.sql)} ${alias} on `);
17
+ for (let index = 0;index < through.local.length; index += 1) {
18
+ const local = through.local[index];
19
+ const remote = through.remote[index];
20
+ if (local === undefined || remote === undefined)
21
+ continue;
22
+ if (index > 0)
23
+ sink.text(" and ");
24
+ sink.text(`${alias}.${quote(remote)} = ${joinAlias}.${quote(local)}`);
25
+ }
26
+ sink.text(" where ");
27
+ planner.join(sink, parent, joinAlias, relation);
28
+ planner.where(schema, join, undefined, sink, joinAlias, depth + 1, true);
29
+ };
30
+ function resolveThrough(scope, table, through, from, to) {
31
+ for (const name of [table, through]) {
32
+ if (!scope.tables.includes(name)) {
33
+ throwNamed2("OKM1020", name, scope.tables, `Relation ${scope.owner}.${scope.name} names ${name}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
34
+ }
35
+ }
36
+ const toOwner = pick(scope, through, scope.owner, from, `${scope.owner}.${scope.name}`, "from");
37
+ const toTable = pick(scope, through, table, to, `${scope.owner}.${scope.name}`, "to");
38
+ if (toOwner === toTable) {
39
+ catalogError2("OKM1021", `Relation ${scope.owner}.${scope.name} uses ${toOwner.fromField} on ${through} for both ends. Pass from and to.`);
40
+ }
41
+ return {
42
+ name: scope.name,
43
+ kind: "many",
44
+ table,
45
+ local: toOwner.remote,
46
+ remote: toOwner.local,
47
+ through: { table: through, local: toTable.local, remote: toTable.remote, emit }
48
+ };
49
+ }
50
+ function pick(scope, through, target, field, label, end) {
51
+ const matches = scope.edges.filter((edge) => edge.fromTable === through && edge.toTable === target && (field === undefined || edge.fromField === field));
52
+ const [only] = matches;
53
+ if (matches.length === 1 && only !== undefined)
54
+ return only;
55
+ const fields = matches.map((edge) => edge.fromField).sort();
56
+ catalogError2("OKM1021", `Relation ${label} through ${through} is ambiguous at ${end}. Accepted columns: ${fields.length === 0 ? "(none)" : fields.join(", ")}.`);
57
+ }
58
+
59
+ // src/dialects/pg/relations.ts
60
+ function one2(table, field) {
61
+ return { kind: "one", table, field };
62
+ }
63
+ function many2(table, field) {
64
+ return { kind: "many", table, field };
65
+ }
66
+ function isRelationCall(value) {
67
+ if (typeof value !== "object" || value === null)
68
+ return false;
69
+ if (!("kind" in value) || !("table" in value))
70
+ return false;
71
+ const kind = value.kind;
72
+ return (kind === "one" || kind === "many") && typeof value.table === "string";
73
+ }
74
+ function manyThrough2(table, options) {
75
+ const { through, from, to } = options;
76
+ return {
77
+ kind: "many",
78
+ table,
79
+ field: undefined,
80
+ through,
81
+ resolve: (scope) => resolveThrough(scope, table, through, from, to)
82
+ };
83
+ }
84
+
85
+ export { one2, many2, isRelationCall, manyThrough2 };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FUNCTION_ARG_TYPES
3
- } from "./fancm5pt.js";
3
+ } from "./vjpnzwjz.js";
4
4
  import {
5
5
  OkmError2
6
6
  } from "./52szzakm.js";
@@ -9,6 +9,8 @@ import {
9
9
  async function assertRoleHealth(runner, roles, objects) {
10
10
  const managed = new Set((roles.managed ?? []).map((role) => role.name));
11
11
  const named = [roles.migration, roles.app];
12
+ if (roles.reporting !== undefined)
13
+ named.push(roles.reporting);
12
14
  for (const name of named) {
13
15
  if (managed.has(name))
14
16
  continue;
@@ -22,15 +24,16 @@ async function assertRoleHealth(runner, roles, objects) {
22
24
  if (managed.size > 0)
23
25
  await assertCreateRole(runner, await currentUser(runner));
24
26
  for (const object of objects) {
25
- if (object.kind !== "grant" || object.identity.role !== roles.app)
27
+ if (object.kind !== "grant")
26
28
  continue;
29
+ if (managed.has(object.identity.role) && !await roleExists(runner, object.identity.role)) {
30
+ continue;
31
+ }
27
32
  await assertGrant(runner, object);
28
33
  }
29
34
  }
30
35
  async function assertCreateRole(runner, role) {
31
- const result = await runner.execute("select rolcreaterole from pg_roles where rolname = $1", [
32
- role
33
- ]);
36
+ const result = await runner.execute("select rolsuper or rolcreaterole from pg_roles where rolname = $1", [role]);
34
37
  if (!truthy(result.rows[0]?.[0])) {
35
38
  throw new OkmError2("forbidden", `Role ${role} lacks CREATEROLE. Nothing was changed.`, {
36
39
  kind: "forbidden",
@@ -62,11 +65,36 @@ async function assertGrant(runner, object) {
62
65
  missing(object, `${schema}.${fn}`);
63
66
  return;
64
67
  }
65
- if (target.kind === "namespace")
68
+ if (target.kind === "namespace") {
69
+ const allowed = await runner.execute(`select exists (
70
+ select 1 from pg_namespace n
71
+ cross join lateral aclexplode(n.nspacl) as a
72
+ where n.nspname = $2
73
+ and a.privilege_type = $3
74
+ and (
75
+ a.grantee = 0
76
+ or a.grantee = (select oid from pg_roles where rolname = $1)
77
+ )
78
+ )`, [object.identity.role, schema, privilege]);
79
+ if (!truthy(allowed.rows[0]?.[0]))
80
+ missing(object, `schema ${schema}`);
66
81
  return;
82
+ }
67
83
  const relkinds = target.kind === "sequence" ? "'S'" : target.kind === "view" ? "'v'" : target.kind === "materializedView" ? "'m'" : "'r', 'p'";
68
84
  if (!await relationExists(runner, schema, target.name, relkinds))
69
85
  return;
86
+ const column = /^(SELECT|UPDATE)\(([^)]*)\)$/.exec(privilege);
87
+ const listed = column?.[2];
88
+ const base = column?.[1];
89
+ if (listed !== undefined && base !== undefined) {
90
+ const names = listed.split(",").filter((name) => name.length > 0);
91
+ for (const name of names) {
92
+ const allowed = await runner.execute("select has_column_privilege($1, format('%I.%I', $2::text, $3::text), $4, $5)", [object.identity.role, schema, target.name, name, base]);
93
+ if (!truthy(allowed.rows[0]?.[0]))
94
+ missing(object, `${schema}.${target.name}.${name}`);
95
+ }
96
+ return;
97
+ }
70
98
  const probe = target.kind === "sequence" ? "select has_sequence_privilege($1, format('%I.%I', $2::text, $3::text), $4)" : "select has_table_privilege($1, format('%I.%I', $2::text, $3::text), $4)";
71
99
  const allowed = await runner.execute(probe, [
72
100
  object.identity.role,
@@ -1,3 +1,6 @@
1
+ import {
2
+ effectivePredicate
3
+ } from "./b3awxn7h.js";
1
4
  import {
2
5
  stack
3
6
  } from "./672t5vym.js";
@@ -14,14 +17,11 @@ import {
14
17
  isRecord,
15
18
  registerFailFix,
16
19
  fail
17
- } from "./qgvt8nx1.js";
20
+ } from "./2z7wv5tj.js";
18
21
  import {
19
22
  safetyInstalled,
20
23
  runSafety
21
24
  } from "./a5sxz52y.js";
22
- import {
23
- isOperator
24
- } from "./cn0n68ft.js";
25
25
  import {
26
26
  OkmError2
27
27
  } from "./52szzakm.js";
@@ -362,11 +362,9 @@ function requireFilter(table, where, mods, op) {
362
362
  }
363
363
  return;
364
364
  }
365
- if (isOperator(where))
366
- return;
367
- if (isRecord(where) && Object.keys(where).length > 0)
368
- return;
369
- fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
365
+ if (!effectivePredicate(where)) {
366
+ fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
367
+ }
370
368
  }
371
369
  function callOptions(input) {
372
370
  const signal = input.signal;
@@ -11,7 +11,7 @@ import {
11
11
  quote,
12
12
  isRecord,
13
13
  fail
14
- } from "./qgvt8nx1.js";
14
+ } from "./2z7wv5tj.js";
15
15
  import {
16
16
  isOperator,
17
17
  operatorName,
@@ -1,50 +1,51 @@
1
1
  import {
2
2
  open2
3
- } from "./wqem4jed.js";
3
+ } from "./wkme6tep.js";
4
4
  import {
5
5
  startupHash2
6
- } from "./8bwbwy8h.js";
6
+ } from "./qq3899ht.js";
7
7
  import {
8
8
  runTarget,
9
9
  assumeRole,
10
+ grantAppMeta,
10
11
  statementOutsideTransaction,
11
- loadMigrations,
12
- loadHeadSnapshot,
13
12
  readReference,
14
13
  referenceInserts,
15
14
  provisionMark,
16
15
  expandProvisioned,
17
16
  installSnapshot
18
- } from "./kdkxh3kb.js";
17
+ } from "./p248q79y.js";
19
18
  import {
20
19
  assertCreateRole,
21
20
  currentUser,
22
21
  roleExists
23
- } from "./szm0cksa.js";
22
+ } from "./knmes2kh.js";
24
23
  import {
24
+ projectPath,
25
+ loadMigrations,
26
+ loadHeadSnapshot,
25
27
  lintMigrationDirectory,
26
28
  hasError,
27
29
  lintRefusal,
28
- assertTargetPolicy,
29
- assertDirectConnection,
30
- selectTarget,
31
30
  projectHead,
32
31
  loadBuiltSchema,
33
32
  loadConfig
34
- } from "./xdpj5kkm.js";
33
+ } from "./t3g0k88x.js";
35
34
  import {
36
35
  changesRole,
37
36
  batchSizeField,
38
37
  assertExtensionsAvailable,
39
- planMigration
40
- } from "./ayz64vzj.js";
38
+ planMigration,
39
+ finishQuiet,
40
+ assertTargetPolicy,
41
+ assertDirectConnection,
42
+ assertStableBackend,
43
+ selectTarget
44
+ } from "./ttmg09vd.js";
41
45
  import {
42
46
  OkmError2
43
47
  } from "./52szzakm.js";
44
48
 
45
- // src/tooling/migrate/apply.ts
46
- import { join } from "node:path";
47
-
48
49
  // src/tooling/migrate/engine.ts
49
50
  var IDENT = String.raw`"(?:[^"]|"")+"|[A-Za-z_][\w$]*`;
50
51
  var DEFAULT_UUIDV7 = /\bdefault\s+uuidv7\s*\(\s*\)/i;
@@ -120,6 +121,11 @@ var BACKFILL = `create table if not exists okm_backfill (
120
121
  updated_at timestamptz not null default now(),
121
122
  primary key (migration_id, step_index)
122
123
  )`;
124
+ async function ensureMigrationTables2(execute) {
125
+ await execute(META);
126
+ await execute(HISTORY);
127
+ await execute(BACKFILL);
128
+ }
123
129
  function applyUnits(migration, done) {
124
130
  const pending = [];
125
131
  for (let index = 0;index < migration.steps.length; index += 1) {
@@ -174,9 +180,12 @@ async function applyTarget2(request) {
174
180
  fix: { summary: "Apply needs a driver with interactive transactions." }
175
181
  });
176
182
  }
177
- const connection = await pool.reserve();
183
+ const reserved = await pool.reserve();
184
+ const connection = reserved;
178
185
  let locked = false;
179
186
  try {
187
+ await assertStableBackend(() => backendPid(connection), request.allowPooler === true);
188
+ await assertStandardStrings(connection);
180
189
  await setTimeouts(connection, request);
181
190
  await lockTarget(connection, request.target);
182
191
  locked = true;
@@ -199,9 +208,7 @@ async function applyTarget2(request) {
199
208
  throw notEmpty(request.target, state.kind === "occupied" ? state.object : "okm_meta");
200
209
  }
201
210
  }
202
- await connection.execute(META);
203
- await connection.execute(HISTORY);
204
- await connection.execute(BACKFILL);
211
+ await ensureMigrationTables2((sql) => connection.execute(sql));
205
212
  const restamped = await restampLegacy(connection, request);
206
213
  const history = await readHistory(connection);
207
214
  const done = expandProvisioned(request.migrations, history.done, history.ids);
@@ -222,14 +229,14 @@ async function applyTarget2(request) {
222
229
  if (request.snapshot !== undefined) {
223
230
  await insertReference(connection, request);
224
231
  }
232
+ await grantAppMeta(connection, request.appRole, session);
225
233
  return restamped.length === 0 ? report : { ...report, restamped };
226
234
  } finally {
227
- if (locked)
228
- await connection.execute("select pg_advisory_unlock(hashtext($1))", [
229
- lockKey(request.target)
230
- ]);
231
- await connection.release();
232
- await pool.close();
235
+ if (locked) {
236
+ await finishQuiet(() => connection.execute("select pg_advisory_unlock(hashtext($1))", [lockKey(request.target)]));
237
+ }
238
+ await finishQuiet(() => connection.release());
239
+ await finishQuiet(() => pool.close());
233
240
  }
234
241
  }
235
242
  async function applyProject2(cwd, flags, write) {
@@ -264,7 +271,7 @@ nothing to apply
264
271
  catalogHash: head.catalogHash,
265
272
  reference: built === undefined ? [] : readReference(built.tables, built.casing, head.catalog)
266
273
  },
267
- ...config.roles !== undefined ? { migrationRole: config.roles.migration } : {},
274
+ ...config.roles !== undefined ? { migrationRole: config.roles.migration, appRole: config.roles.app } : {},
268
275
  lintDirectory: directory,
269
276
  onProgress: (line) => {
270
277
  if (write !== undefined)
@@ -311,7 +318,7 @@ no changes
311
318
  steps: plan.steps
312
319
  }
313
320
  ],
314
- ...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
321
+ ...config.roles !== undefined ? { migrationRole: config.roles.migration, appRole: config.roles.app } : {}
315
322
  });
316
323
  return formatReport(report);
317
324
  }
@@ -377,7 +384,19 @@ var RESTAMP = `with pairs as (
377
384
  )
378
385
  select distinct id from history order by id`;
379
386
  function joinMigrations(cwd, migrations) {
380
- return join(cwd, migrations ?? "migrations");
387
+ return projectPath(cwd, migrations ?? "migrations");
388
+ }
389
+ async function backendPid(connection) {
390
+ const result = await connection.execute("select pg_backend_pid()::text");
391
+ const cell = result.rows[0]?.[0];
392
+ return cell === null || cell === undefined ? "" : String(cell);
393
+ }
394
+ async function assertStandardStrings(connection) {
395
+ const result = await connection.execute("show standard_conforming_strings");
396
+ const value = result.rows[0]?.[0];
397
+ if (value === "on")
398
+ return;
399
+ throw new OkmError2("invalid", `standard_conforming_strings is ${value === null || value === undefined ? "off" : String(value)}. Apply refuses to run.`, { fix: { summary: "Turn standard_conforming_strings on for this database." } });
381
400
  }
382
401
  async function setTimeouts(connection, request) {
383
402
  const lock = request.lockTimeoutMs ?? DEFAULT_LOCK_MS;
@@ -449,10 +468,9 @@ async function provisionEmpty(connection, request, session) {
449
468
  assertTargetPolicy({ name: request.target, protected: request.protected }, "reference", request.allowProtected === true);
450
469
  }
451
470
  const schema = concreteSchema(request);
452
- await connection.execute(META);
453
- await connection.execute(HISTORY);
454
- await connection.execute(BACKFILL);
471
+ await ensureMigrationTables2((sql) => connection.execute(sql));
455
472
  await installSnapshot(connection, snapshot.catalog, schema, snapshot.reference, session, request.migrationRole);
473
+ await grantAppMeta(connection, request.appRole, session);
456
474
  const mark = provisionMark(snapshot.migrationId);
457
475
  await connection.execute("begin");
458
476
  try {
@@ -586,4 +604,4 @@ function wireTrue(value) {
586
604
  return value === "t" || value === "true";
587
605
  }
588
606
 
589
- export { applyTarget2, applyProject2, pushProject2, backfillTiming2 };
607
+ export { ensureMigrationTables2, applyTarget2, applyProject2, pushProject2, backfillTiming2 };