okmodel 0.5.1 → 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 (155) hide show
  1. package/README.md +29 -14
  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 +5 -4
  19. package/dist/dialects/pg/fn/index.js +2 -2
  20. package/dist/dialects/pg/index.d.ts +2 -1
  21. package/dist/dialects/pg/index.js +23 -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/owner.d.ts +42 -0
  25. package/dist/dialects/pg/path-endpoint.d.ts +20 -0
  26. package/dist/dialects/pg/role/check.d.ts +3 -0
  27. package/dist/dialects/pg/role/index.d.ts +71 -6
  28. package/dist/dialects/pg/role/sql.d.ts +11 -0
  29. package/dist/dialects/pg/schema.d.ts +2 -0
  30. package/dist/dialects/pg/table.d.ts +25 -3
  31. package/dist/dialects/pg/tenancy.d.ts +45 -3
  32. package/dist/dialects/pg/view/client.d.ts +19 -1
  33. package/dist/dialects/pg/view/index.d.ts +4 -0
  34. package/dist/dialects/pg/view/index.js +21 -178
  35. package/dist/dialects/pg/view/refresh.d.ts +24 -0
  36. package/dist/runtime/batch.d.ts +1 -1
  37. package/dist/runtime/conflict.d.ts +2 -2
  38. package/dist/runtime/drift.d.ts +9 -0
  39. package/dist/runtime/inflight.d.ts +14 -0
  40. package/dist/runtime/pg/bun.js +4 -3
  41. package/dist/runtime/pg/pg.js +3 -3
  42. package/dist/runtime/pg/pglite.js +4 -3
  43. package/dist/runtime/pg/postgresjs.js +3 -3
  44. package/dist/runtime/plan.d.ts +18 -10
  45. package/dist/runtime/predicate.d.ts +19 -0
  46. package/dist/runtime/safety/index.js +1 -1
  47. package/dist/runtime/tenancy/composite.d.ts +26 -0
  48. package/dist/runtime/tenancy/context.d.ts +16 -0
  49. package/dist/runtime/tenancy/index.d.ts +9 -5
  50. package/dist/runtime/tenancy/index.js +1508 -37
  51. package/dist/runtime/tenancy/path.d.ts +87 -0
  52. package/dist/runtime/tenancy/rls.d.ts +67 -0
  53. package/dist/runtime/tenancy/via.d.ts +22 -0
  54. package/dist/runtime/traits/index.js +17 -11
  55. package/dist/runtime/types.d.ts +13 -1
  56. package/dist/runtime/validate/index.js +4 -4
  57. package/dist/runtime/write.d.ts +1 -1
  58. package/dist/shared/09p049xa.js +702 -0
  59. package/dist/shared/{6qd27mx0.js → 1f0xa3cb.js} +5 -5
  60. package/dist/shared/1nw1f3vs.js +23 -0
  61. package/dist/shared/{96qcj21c.js → 1z04fa85.js} +19 -9
  62. package/dist/shared/{qm7cdtvr.js → 2cg3wnxc.js} +296 -60
  63. package/dist/shared/{dyj86cmj.js → 2jd1sn0e.js} +2 -2
  64. package/dist/shared/{gbtcc2d7.js → 2z7wv5tj.js} +10 -35
  65. package/dist/shared/{k8v5v5wj.js → 32cnm7kn.js} +6 -1
  66. package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
  67. package/dist/shared/{2pqx26h8.js → 3fqwmr09.js} +31 -22
  68. package/dist/shared/{zqrnhwsq.js → 3qnhc7w5.js} +16 -9
  69. package/dist/shared/{r2sp8hrc.js → 5d8t84hg.js} +12 -3
  70. package/dist/shared/{87jvvhnt.js → 5j36z8dn.js} +16 -5
  71. package/dist/shared/{1g0drakv.js → 5yv4k6a6.js} +1 -1
  72. package/dist/shared/8dqhth8c.js +12 -0
  73. package/dist/shared/8etn7d8w.js +62 -0
  74. package/dist/shared/{v36c5g6p.js → 8x72s86k.js} +400 -13
  75. package/dist/shared/{nxdp2ze3.js → 929h19xp.js} +107 -5
  76. package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
  77. package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
  78. package/dist/shared/{efmy2gcg.js → ag4c7516.js} +1 -1
  79. package/dist/shared/b3awxn7h.js +45 -0
  80. package/dist/shared/b4v57v3x.js +9 -0
  81. package/dist/shared/bdk4sty6.js +58 -0
  82. package/dist/shared/{51mvgj8w.js → c58secgj.js} +100 -7
  83. package/dist/shared/d5azex6s.js +6 -0
  84. package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
  85. package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
  86. package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
  87. package/dist/shared/{sycnx8gt.js → f0f1n281.js} +18 -8
  88. package/dist/shared/{f5cw5q5r.js → g90m9b0g.js} +2 -1
  89. package/dist/shared/{pf0d8f77.js → gwn6v667.js} +1 -1
  90. package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
  91. package/dist/shared/{5enne4ma.js → hazqqecq.js} +17 -93
  92. package/dist/shared/{jwtxdj06.js → j3rkk835.js} +32 -9
  93. package/dist/shared/{hf22e0wt.js → j60w0dvr.js} +19 -18
  94. package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
  95. package/dist/shared/k68eedmy.js +85 -0
  96. package/dist/shared/{szm0cksa.js → knmes2kh.js} +34 -6
  97. package/dist/shared/{0t22wwh1.js → mb2ycs1p.js} +4 -2
  98. package/dist/shared/{cr74e96e.js → n076ydsc.js} +1 -1
  99. package/dist/shared/{cctw17hj.js → nx9hh281.js} +31 -28
  100. package/dist/shared/{gde73es6.js → p248q79y.js} +56 -55
  101. package/dist/shared/{janx09m5.js → p6bjzq9q.js} +11 -7
  102. package/dist/shared/{6rk2gen5.js → pjr6xrm5.js} +2 -2
  103. package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
  104. package/dist/shared/{caw8b9d8.js → q3j1tq7a.js} +35 -22
  105. package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
  106. package/dist/shared/{tm5ab8we.js → r11n8grd.js} +2 -2
  107. package/dist/shared/r1fdd0f6.js +19 -0
  108. package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
  109. package/dist/shared/rhs3xe4k.js +7 -0
  110. package/dist/shared/{ntneex2a.js → rpycarcr.js} +6 -6
  111. package/dist/shared/{aj2qxyhj.js → sbdme3vy.js} +14 -2
  112. package/dist/shared/{qv2ydck9.js → t3g0k88x.js} +638 -67
  113. package/dist/shared/{ga3sfy93.js → ttmg09vd.js} +535 -200
  114. package/dist/shared/{kfjp0gck.js → venqrjna.js} +8 -4
  115. package/dist/shared/{fancm5pt.js → vjpnzwjz.js} +138 -15
  116. package/dist/shared/{32zqc1dw.js → vmfkhszw.js} +31 -7
  117. package/dist/shared/{krxx77g0.js → wkme6tep.js} +10 -8
  118. package/dist/shared/{ps7a6h14.js → wt5rzv1h.js} +12 -8
  119. package/dist/shared/wxr8cwns.js +6 -0
  120. package/dist/shared/{6mnp99hx.js → wynzeggs.js} +16 -12
  121. package/dist/shared/x3jc53kg.js +220 -0
  122. package/dist/shared/{sdc7r2ww.js → xq0mvhts.js} +8 -8
  123. package/dist/shared/xqve9598.js +53 -0
  124. package/dist/shared/{47x8x9ze.js → y2t3jktd.js} +2 -2
  125. package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
  126. package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
  127. package/dist/shared/{nkaxvt9q.js → ys0xzyaj.js} +1 -1
  128. package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
  129. package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
  130. package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
  131. package/dist/shared/{r8x5qhd7.js → zm0mafk4.js} +10 -4
  132. package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
  133. package/dist/tooling/cli.js +41 -15
  134. package/dist/tooling/migrate/apply.d.ts +14 -0
  135. package/dist/tooling/migrate/check.d.ts +3 -4
  136. package/dist/tooling/migrate/classify.d.ts +4 -0
  137. package/dist/tooling/migrate/config.d.ts +3 -2
  138. package/dist/tooling/migrate/files.d.ts +11 -1
  139. package/dist/tooling/migrate/index.js +14 -14
  140. package/dist/tooling/migrate/lint.d.ts +1 -1
  141. package/dist/tooling/migrate/lost.d.ts +28 -0
  142. package/dist/tooling/migrate/paths.d.ts +14 -0
  143. package/dist/tooling/migrate/plan.d.ts +6 -3
  144. package/dist/tooling/migrate/runner.d.ts +25 -0
  145. package/dist/tooling/migrate/sandbox.d.ts +57 -0
  146. package/dist/tooling/migrate/sql-lex.d.ts +20 -3
  147. package/dist/tooling/migrate/text.d.ts +42 -0
  148. package/dist/tooling/node-version.d.ts +21 -0
  149. package/dist/tooling/testing/facts.d.ts +33 -5
  150. package/dist/tooling/testing/index.d.ts +1 -1
  151. package/dist/tooling/testing/index.js +3 -3
  152. package/dist/tooling/testing/isolation.d.ts +11 -5
  153. package/package.json +5 -2
  154. package/dist/shared/7zwwyh0v.js +0 -448
  155. package/dist/shared/q58y17hy.js +0 -21
@@ -2,23 +2,23 @@ import {
2
2
  catalog,
3
3
  enumType,
4
4
  sameEnumLabels
5
- } from "./g7ez901n.js";
5
+ } from "./ywspezzx.js";
6
6
  import {
7
- snakeCase,
8
- emittedTypeName,
9
- rejectLater
10
- } from "./ntneex2a.js";
11
- import {
12
- withLocation
13
- } from "./k7dwkhvq.js";
7
+ isRelationCall
8
+ } from "./k68eedmy.js";
14
9
  import {
15
10
  encodeText,
16
11
  decodeText
17
- } from "./4m9fn52z.js";
12
+ } from "./ed0b8k4s.js";
13
+ import {
14
+ snakeCase,
15
+ emittedTypeName,
16
+ rejectLater
17
+ } from "./rpycarcr.js";
18
18
  import {
19
19
  ColumnBuilder2,
20
20
  formatType
21
- } from "./c9z5g0fm.js";
21
+ } from "./ywr8hmey.js";
22
22
  import {
23
23
  definition,
24
24
  unavailable
@@ -26,6 +26,9 @@ import {
26
26
  import {
27
27
  quoteLiteral
28
28
  } from "./94ez8kzh.js";
29
+ import {
30
+ withLocation
31
+ } from "./y6jdds7g.js";
29
32
  import {
30
33
  staticNamespace2,
31
34
  table3,
@@ -34,7 +37,7 @@ import {
34
37
  constraint2,
35
38
  sequence2,
36
39
  compareText
37
- } from "./t4tbsy9h.js";
40
+ } from "./358zsv4r.js";
38
41
  import {
39
42
  assertIdentifier2,
40
43
  fitIdentifier2,
@@ -49,85 +52,6 @@ import {
49
52
  readClientGenerator
50
53
  } from "./rwmrejjz.js";
51
54
 
52
- // src/dialects/pg/through.ts
53
- var emit = (planner, schema, relation, child, sink, parent, alias, depth) => {
54
- const through = relation.through;
55
- const join = through === undefined ? undefined : planner.indexes(schema).get(through.table);
56
- if (through === undefined || join === undefined) {
57
- return catalogError2("OKM1020", `Relation ${relation.name} names a join table that is not in the schema.`);
58
- }
59
- const { quote } = planner;
60
- const joinAlias = `j${alias}`;
61
- sink.mark(`via:${through.table}`);
62
- sink.text(`${quote(join.model.sql)} ${joinAlias} join ${quote(child.model.sql)} ${alias} on `);
63
- for (let index = 0;index < through.local.length; index += 1) {
64
- const local = through.local[index];
65
- const remote = through.remote[index];
66
- if (local === undefined || remote === undefined)
67
- continue;
68
- if (index > 0)
69
- sink.text(" and ");
70
- sink.text(`${alias}.${quote(remote)} = ${joinAlias}.${quote(local)}`);
71
- }
72
- sink.text(" where ");
73
- planner.join(sink, parent, joinAlias, relation);
74
- planner.where(schema, join, undefined, sink, joinAlias, depth + 1, true);
75
- };
76
- function resolveThrough(scope, table, through, from, to) {
77
- for (const name of [table, through]) {
78
- if (!scope.tables.includes(name)) {
79
- throwNamed2("OKM1020", name, scope.tables, `Relation ${scope.owner}.${scope.name} names ${name}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
80
- }
81
- }
82
- const toOwner = pick(scope, through, scope.owner, from, `${scope.owner}.${scope.name}`, "from");
83
- const toTable = pick(scope, through, table, to, `${scope.owner}.${scope.name}`, "to");
84
- if (toOwner === toTable) {
85
- catalogError2("OKM1021", `Relation ${scope.owner}.${scope.name} uses ${toOwner.fromField} on ${through} for both ends. Pass from and to.`);
86
- }
87
- return {
88
- name: scope.name,
89
- kind: "many",
90
- table,
91
- local: toOwner.remote,
92
- remote: toOwner.local,
93
- through: { table: through, local: toTable.local, remote: toTable.remote, emit }
94
- };
95
- }
96
- function pick(scope, through, target, field, label, end) {
97
- const matches = scope.edges.filter((edge) => edge.fromTable === through && edge.toTable === target && (field === undefined || edge.fromField === field));
98
- const [only] = matches;
99
- if (matches.length === 1 && only !== undefined)
100
- return only;
101
- const fields = matches.map((edge) => edge.fromField).sort();
102
- catalogError2("OKM1021", `Relation ${label} through ${through} is ambiguous at ${end}. Accepted columns: ${fields.length === 0 ? "(none)" : fields.join(", ")}.`);
103
- }
104
-
105
- // src/dialects/pg/relations.ts
106
- function one2(table, field) {
107
- return { kind: "one", table, field };
108
- }
109
- function many2(table, field) {
110
- return { kind: "many", table, field };
111
- }
112
- function isRelationCall(value) {
113
- if (typeof value !== "object" || value === null)
114
- return false;
115
- if (!("kind" in value) || !("table" in value))
116
- return false;
117
- const kind = value.kind;
118
- return (kind === "one" || kind === "many") && typeof value.table === "string";
119
- }
120
- function manyThrough2(table, options) {
121
- const { through, from, to } = options;
122
- return {
123
- kind: "many",
124
- table,
125
- field: undefined,
126
- through,
127
- resolve: (scope) => resolveThrough(scope, table, through, from, to)
128
- };
129
- }
130
-
131
55
  // src/dialects/pg/compile.ts
132
56
  function compileColumn(builder, input) {
133
57
  const state = builder.state;
@@ -212,7 +136,7 @@ function readTenancy(value) {
212
136
  definition("schema() tenancy must be columnTenancy() from okmodel/tenancy.");
213
137
  }
214
138
  const record = value;
215
- if (record.strategy !== "column" || typeof record.rewrite !== "function") {
139
+ if (typeof record.rewrite !== "function") {
216
140
  definition("schema() tenancy must be columnTenancy() from okmodel/tenancy.");
217
141
  }
218
142
  return value;
@@ -557,7 +481,7 @@ function compileTable(item, namespace, casing, codecs, requires, idDefault, jobs
557
481
  references: column.state.references,
558
482
  encode: column.state.encode,
559
483
  decode: decode === decodeText ? undefined : decode,
560
- hidden: column.state.hidden,
484
+ hidden: column.state.filterable === true ? "filter" : column.state.hidden,
561
485
  sensitive: column.state.sensitive,
562
486
  guarded: column.state.guarded,
563
487
  writable: column.state.guarded !== true && column.state.omitWrite !== true && column.state.generated === undefined,
@@ -1127,4 +1051,4 @@ function list(names) {
1127
1051
  return names.length === 0 ? "(none)" : names.join(", ");
1128
1052
  }
1129
1053
 
1130
- export { one2, many2, manyThrough2, schema2, addSchemaHook };
1054
+ export { schema2, addSchemaHook };
@@ -1,11 +1,17 @@
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 "./k8v5v5wj.js";
11
+ } from "./32cnm7kn.js";
6
12
  import {
7
13
  isConnectionLost
8
- } from "./pf0d8f77.js";
14
+ } from "./gwn6v667.js";
9
15
  import {
10
16
  WireSession
11
17
  } from "./4az561fn.js";
@@ -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("./efmy2gcg.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 "./gbtcc2d7.js";
10
+ } from "./2z7wv5tj.js";
11
11
  import {
12
12
  OkmError2,
13
13
  safe2,
@@ -85,7 +85,7 @@ function openClient(session) {
85
85
  },
86
86
  close,
87
87
  connected: session.connected,
88
- tx: (...args) => import("./r2sp8hrc.js").then((mod) => mod.tx(session, args)),
88
+ tx: (...args) => import("./5d8t84hg.js").then((mod) => mod.tx(session, args)),
89
89
  batch: (ops, options) => batchHandle(session, ops, options),
90
90
  ...session.tx?.extras
91
91
  };
@@ -120,7 +120,7 @@ function tableApi(session, table, view, uses) {
120
120
  const api = {
121
121
  find(options = {}) {
122
122
  if ("lock" in options) {
123
- return lazyRead(session, () => import("./tm5ab8we.js"), table, options, base, view);
123
+ return lazyRead(session, () => import("./r11n8grd.js"), table, options, base, view);
124
124
  }
125
125
  return start(session, "find", table, options, base, view);
126
126
  },
@@ -134,10 +134,10 @@ function tableApi(session, table, view, uses) {
134
134
  return start(session, "exists", table, options, base, view);
135
135
  },
136
136
  page(options) {
137
- return lazyRead(session, () => import("./6rk2gen5.js"), table, options, base, view);
137
+ return lazyRead(session, () => import("./pjr6xrm5.js"), table, options, base, view);
138
138
  },
139
139
  aggregate(options = {}) {
140
- return lazyRead(session, () => import("./kfjp0gck.js"), table, options, base, view);
140
+ return lazyRead(session, () => import("./venqrjna.js"), table, options, base, view);
141
141
  },
142
142
  insert(data, options = {}) {
143
143
  return writeHandle(session, "insert", table, data, options, mods);
@@ -167,13 +167,13 @@ function tableApi(session, table, view, uses) {
167
167
  return api;
168
168
  }
169
169
  function batchHandle(session, ops, options, replica) {
170
- return queryHandle(() => import("./aj2qxyhj.js").then((mod) => mod.batch(session, ops, options, replica)), {
170
+ return queryHandle(() => import("./sbdme3vy.js").then((mod) => mod.batch(session, ops, options, replica)), {
171
171
  replica: () => batchHandle(session, ops, options, true)
172
172
  });
173
173
  }
174
174
  var writers;
175
175
  function loadWrite() {
176
- writers ??= import("./qm7cdtvr.js");
176
+ writers ??= import("./2cg3wnxc.js");
177
177
  return writers;
178
178
  }
179
179
  function queryHandle(run, extra) {
@@ -279,7 +279,7 @@ function lazyRead(session, load, table, options, mods, view) {
279
279
  });
280
280
  }
281
281
  async function decodeRows(plan, rows, table) {
282
- return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./nkaxvt9q.js")).decodeIncluded(plan, rows, table);
282
+ return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./ys0xzyaj.js")).decodeIncluded(plan, rows, table);
283
283
  }
284
284
  function readHandle(session, table, call, mods, decode, extra) {
285
285
  let prepared;
@@ -354,7 +354,7 @@ function readHandle(session, table, call, mods, decode, extra) {
354
354
  }
355
355
  function streamLazy(session, call, prepare) {
356
356
  return async function* () {
357
- const { streamRows } = await import("./zqrnhwsq.js");
357
+ const { streamRows } = await import("./3qnhc7w5.js");
358
358
  yield* streamRows(session, call, prepare, (error) => logged(session, error));
359
359
  }();
360
360
  }
@@ -391,14 +391,14 @@ function readCall(op, table, options, all, scope, model, schema, view) {
391
391
  };
392
392
  }
393
393
  async function checkServer(pool, schema, http, requireMeta, options, source) {
394
- const server = await import("./47x8x9ze.js");
394
+ const server = await import("./y2t3jktd.js");
395
395
  let rows;
396
396
  try {
397
397
  const result = await pool.execute(server.versionQuery, undefined, options);
398
398
  rows = result.rows;
399
399
  } catch (error) {
400
- const { mapPostgresError } = await import("./51mvgj8w.js");
401
- throw mapPostgresError(error, mapOptions(http, false));
400
+ const { mapPostgresError } = await import("./d5azex6s.js");
401
+ throw mapPostgresError(error, mapOptions(http, false, schema));
402
402
  }
403
403
  await server.acceptServer(pool, schema, rows, http, requireMeta, options, source);
404
404
  }
@@ -406,8 +406,8 @@ async function mapError(session, error) {
406
406
  if (error instanceof OkmError2) {
407
407
  return session.http === undefined ? error : new OkmError2(error.code, error.message, { ...errorFields(error), http: session.http });
408
408
  }
409
- const { mapPostgresError } = await import("./51mvgj8w.js");
410
- 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));
411
411
  }
412
412
  function errorFields(error) {
413
413
  return {
@@ -420,7 +420,7 @@ function errorFields(error) {
420
420
  var includeHooks;
421
421
  var operatorSql;
422
422
  function loadOperatorSql() {
423
- operatorSql ??= import("./cr74e96e.js").then(() => {
423
+ operatorSql ??= import("./n076ydsc.js").then(() => {
424
424
  return;
425
425
  });
426
426
  return operatorSql;
@@ -428,7 +428,7 @@ function loadOperatorSql() {
428
428
  function hooksFor(call) {
429
429
  if (call.include === undefined)
430
430
  return Promise.resolve(undefined);
431
- includeHooks ??= import("./nkaxvt9q.js").then((mod) => mod.includeHooks);
431
+ includeHooks ??= import("./ys0xzyaj.js").then((mod) => mod.includeHooks);
432
432
  return includeHooks;
433
433
  }
434
434
  function bindNow(schema, call) {
@@ -469,10 +469,11 @@ function callOptions(input, statement) {
469
469
  ...route !== undefined ? { route } : {}
470
470
  };
471
471
  }
472
- function mapOptions(http, includeValues) {
472
+ function mapOptions(http, includeValues, schema) {
473
473
  return {
474
474
  ...http !== undefined ? { http } : {},
475
- ...includeValues ? { includeValues: true } : {}
475
+ ...includeValues ? { includeValues: true } : {},
476
+ schema
476
477
  };
477
478
  }
478
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";
@@ -12,10 +15,9 @@ import {
12
15
  indexes,
13
16
  quote,
14
17
  isRecord,
15
- effectivePredicate,
16
18
  registerFailFix,
17
19
  fail
18
- } from "./gbtcc2d7.js";
20
+ } from "./2z7wv5tj.js";
19
21
  import {
20
22
  safetyInstalled,
21
23
  runSafety
@@ -11,7 +11,7 @@ import {
11
11
  quote,
12
12
  isRecord,
13
13
  fail
14
- } from "./gbtcc2d7.js";
14
+ } from "./2z7wv5tj.js";
15
15
  import {
16
16
  isOperator,
17
17
  operatorName,