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
@@ -0,0 +1,164 @@
1
+ import {
2
+ safetyInstalled,
3
+ runSafety
4
+ } from "./a5sxz52y.js";
5
+ import {
6
+ isOperator,
7
+ operatorValue
8
+ } from "./cn0n68ft.js";
9
+ import {
10
+ OkmError2
11
+ } from "./52szzakm.js";
12
+
13
+ // src/runtime/exposure.ts
14
+ var REDACTED = "[redacted]";
15
+ var namesOf = new WeakMap;
16
+ function redactView(schema, view, call) {
17
+ const names = concealedNames(schema);
18
+ const secrets = new Set;
19
+ harvest(schema, call.where, names, undefined, secrets);
20
+ harvest(schema, call.include, names, undefined, secrets);
21
+ const model = schema.model[call.table];
22
+ const rules = model === undefined ? view.rules : [...view.rules, ...exposureRules(model, call)];
23
+ if (safetyInstalled())
24
+ runSafety(rules, undefined);
25
+ return {
26
+ ...view,
27
+ intent: {
28
+ ...view.intent,
29
+ where: walk(view.intent.where, names),
30
+ include: walk(view.intent.include, names)
31
+ },
32
+ rules,
33
+ sql: {
34
+ ...view.sql,
35
+ params: view.sql.params.map((value) => value !== null && secrets.has(value) ? REDACTED : value)
36
+ }
37
+ };
38
+ }
39
+ function scrubCall(error, schema, call) {
40
+ const names = concealedNames(schema);
41
+ const secrets = new Set;
42
+ harvest(schema, call.where, names, undefined, secrets);
43
+ harvest(schema, call.include, names, undefined, secrets);
44
+ let message = error.message;
45
+ for (const secret of secrets) {
46
+ if (secret.length < 4 || !message.includes(secret))
47
+ continue;
48
+ message = message.replaceAll(secret, REDACTED);
49
+ }
50
+ if (message === error.message)
51
+ return error;
52
+ return new OkmError2(error.code, message, {
53
+ kind: error.kind,
54
+ ...error.table !== undefined ? { table: error.table } : {},
55
+ ...error.columns.length > 0 ? { columns: error.columns } : {},
56
+ fix: error.fix
57
+ });
58
+ }
59
+ function concealedNames(schema) {
60
+ const cached = namesOf.get(schema);
61
+ if (cached !== undefined)
62
+ return cached;
63
+ const names = new Set;
64
+ for (const model of Object.values(schema.model)) {
65
+ if (model.conceal !== true)
66
+ continue;
67
+ for (const column of model.columns) {
68
+ if (column.hidden || column.sensitive)
69
+ names.add(column.field);
70
+ }
71
+ }
72
+ namesOf.set(schema, names);
73
+ return names;
74
+ }
75
+ function exposureRules(model, call) {
76
+ const named = namedSelect(call.select);
77
+ const source = model.source;
78
+ const rules = [];
79
+ for (const column of model.columns) {
80
+ if (column.hidden && (named === undefined || !named.has(column.field))) {
81
+ rules.push({
82
+ rule: "hidden",
83
+ contribution: `hidden ${model.name}.${column.field} excluded`,
84
+ provenance: "catalog",
85
+ ...source !== undefined ? { source } : {}
86
+ });
87
+ }
88
+ if (column.sensitive) {
89
+ rules.push({
90
+ rule: "sensitive",
91
+ contribution: `sensitive ${model.name}.${column.field} redacted`,
92
+ provenance: "catalog",
93
+ ...source !== undefined ? { source } : {}
94
+ });
95
+ }
96
+ }
97
+ return rules;
98
+ }
99
+ function namedSelect(select) {
100
+ if (!Array.isArray(select))
101
+ return;
102
+ const names = new Set;
103
+ for (const name of select) {
104
+ if (typeof name === "string")
105
+ names.add(name);
106
+ }
107
+ return names;
108
+ }
109
+ function harvest(schema, value, names, key, into) {
110
+ if (Array.isArray(value)) {
111
+ for (const item of value)
112
+ harvest(schema, item, names, key, into);
113
+ return;
114
+ }
115
+ if (isOperator(value)) {
116
+ harvest(schema, operatorValue(value), names, key, into);
117
+ return;
118
+ }
119
+ if (typeof value === "object" && value !== null) {
120
+ const record = value;
121
+ for (const child of Object.keys(record))
122
+ harvest(schema, record[child], names, child, into);
123
+ return;
124
+ }
125
+ if (key === undefined || !names.has(key))
126
+ return;
127
+ const encode = encodeOf(schema, key);
128
+ if (encode === undefined)
129
+ return;
130
+ try {
131
+ into.add(encode(value));
132
+ } catch {}
133
+ }
134
+ function encodeOf(schema, field) {
135
+ for (const model of Object.values(schema.model)) {
136
+ for (const column of model.columns) {
137
+ if (column.field === field && (column.hidden || column.sensitive)) {
138
+ return column.encode;
139
+ }
140
+ }
141
+ }
142
+ return;
143
+ }
144
+ function walk(value, names, key) {
145
+ if (Array.isArray(value))
146
+ return value.map((item) => walk(item, names, key));
147
+ if (typeof value === "object" && value !== null) {
148
+ const record = value;
149
+ if (typeof record.op === "string" && "value" in record) {
150
+ return { op: record.op, value: walk(record.value, names, key) };
151
+ }
152
+ const out = {};
153
+ for (const child of Object.keys(record))
154
+ out[child] = walk(record[child], names, child);
155
+ return out;
156
+ }
157
+ if (key !== undefined && names.has(key))
158
+ return REDACTED;
159
+ return value;
160
+ }
161
+ export {
162
+ redactView,
163
+ scrubCall
164
+ };
@@ -1,4 +1,5 @@
1
1
  import {
2
+ emitRelationFrom,
2
3
  decodeResult,
3
4
  emitJoin,
4
5
  emitWhere,
@@ -14,13 +15,15 @@ import {
14
15
  quote,
15
16
  list,
16
17
  isRecord,
18
+ registerFailFix,
17
19
  fail
18
- } from "./rgs0st28.js";
20
+ } from "./xrfnq5k8.js";
19
21
  import {
20
22
  throwNamed2
21
- } from "./ycwz42az.js";
23
+ } from "./52szzakm.js";
22
24
 
23
25
  // src/runtime/include.ts
26
+ registerFailFix("OKM1105", "Pass limit on the include, or call .all(reason).");
24
27
  var INCLUDE_OPTIONS = ["all", "include", "limit", "orderBy", "select", "where"];
25
28
  function emitIncludeSelect(include, alias, sink, outputs, column) {
26
29
  const selected = include.columns;
@@ -130,11 +133,7 @@ function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
130
133
  emitNestedAggregate(schema, nested, sink, childAlias, depth + 1);
131
134
  }
132
135
  sink.text(") as item from ");
133
- sink.text(quote(child.model.sql));
134
- sink.text(" ");
135
- sink.text(childAlias);
136
- sink.text(" where ");
137
- emitJoin(sink, parentAlias, childAlias, include.relation);
136
+ emitRelationFrom(schema, include.relation, child, sink, parentAlias, childAlias, depth + 1);
138
137
  emitWhere(schema, child, include.where, sink, childAlias, depth + 1, true);
139
138
  emitOrder(child, include.orderBy, sink, childAlias);
140
139
  if (include.orderBy === undefined && child.model.primary.length > 0) {
@@ -225,11 +224,7 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
225
224
  if (include.columns.length === 0)
226
225
  sink.text("1");
227
226
  sink.text(") as item from ");
228
- sink.text(quote(child.model.sql));
229
- sink.text(" ");
230
- sink.text(childAlias);
231
- sink.text(" where ");
232
- emitJoin(sink, alias, childAlias, include.relation);
227
+ emitRelationFrom(schema, include.relation, child, sink, alias, childAlias, depth);
233
228
  emitWhere(schema, child, include.where, sink, childAlias, depth, true);
234
229
  emitOrder(child, include.orderBy, sink, childAlias);
235
230
  if (include.orderBy === undefined && child.model.primary.length > 0) {
@@ -242,6 +237,14 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
242
237
  }
243
238
  sink.text(") limited) ordered)");
244
239
  }
240
+ function omitHidden(columns) {
241
+ for (const column of columns) {
242
+ if (!column.hidden)
243
+ continue;
244
+ return columns.filter((item) => !item.hidden);
245
+ }
246
+ return columns;
247
+ }
245
248
  function readIncludes(schema, table, include, all) {
246
249
  if (include === undefined)
247
250
  return [];
@@ -264,7 +267,7 @@ function parseInclude(schema, name, relation, value, all) {
264
267
  fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
265
268
  }
266
269
  const child = childIndex(schema, relation);
267
- const columns = selectedColumns(child, undefined);
270
+ const columns = omitHidden(selectedColumns(child, undefined));
268
271
  return {
269
272
  name,
270
273
  relation,
@@ -288,7 +291,7 @@ function parseInclude(schema, name, relation, value, all) {
288
291
  fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
289
292
  }
290
293
  const child = childIndex(schema, relation);
291
- const columns = selectedColumns(child, value.select);
294
+ const columns = omitHidden(selectedColumns(child, value.select));
292
295
  const nestedValue = value.include;
293
296
  const nested = nestedValue === undefined ? [] : readIncludes(schema, child, nestedValue, reason);
294
297
  return {
@@ -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.ts
6
6
  async function assertCompatible(pool, schema, recordedHash, source, options) {
@@ -8,16 +8,16 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
8
8
  if (code.hash === recordedHash)
9
9
  return;
10
10
  if (code.artifact !== undefined) {
11
- const { loadTrustedCatalog } = await import("./w8samvk1.js");
11
+ const { loadTrustedCatalog } = await import("./qybh48nd.js");
12
12
  loadTrustedCatalog(code.artifact.text, code.artifact.hash);
13
13
  } else {
14
14
  const artifact = await readCatalogFile(source.catalogDir);
15
15
  if (artifact !== undefined) {
16
- const { loadTrustedCatalog } = await import("./w8samvk1.js");
16
+ const { loadTrustedCatalog } = await import("./qybh48nd.js");
17
17
  loadTrustedCatalog(artifact.text, artifact.hash);
18
18
  }
19
19
  }
20
- const { assertDrift } = await import("./p0cbr3g2.js");
20
+ const { assertDrift } = await import("./zwmqxb0g.js");
21
21
  await assertDrift(pool, code.hash, recordedHash, options);
22
22
  }
23
23
  async function codeHash(schema, source) {
@@ -26,7 +26,7 @@ async function codeHash(schema, source) {
26
26
  const listed = await readHashFile(source.catalogDir);
27
27
  if (listed !== undefined)
28
28
  return { hash: listed };
29
- const { catalogHash } = await import("./w8samvk1.js");
29
+ const { catalogHash } = await import("./qybh48nd.js");
30
30
  return { hash: catalogHash(schemaCatalog(schema)) };
31
31
  }
32
32
  function schemaCatalog(schema) {
@@ -0,0 +1,76 @@
1
+ import {
2
+ send2,
3
+ reserve,
4
+ park
5
+ } from "./01yr20s5.js";
6
+ import {
7
+ isConnectionLost
8
+ } from "./tbszx8mz.js";
9
+ import {
10
+ WireSession
11
+ } from "./0jc3ffzf.js";
12
+ import {
13
+ rejectClosed,
14
+ runCall
15
+ } from "./rrstp3kb.js";
16
+
17
+ // src/adapters/pg/bunsql-extra.ts
18
+ async function checkout(held) {
19
+ const { counters, isClosed } = held;
20
+ if (isClosed())
21
+ return rejectClosed();
22
+ const reserved = held.parked.pop() ?? await reserve(held.sql, held.acquireMs, counters);
23
+ counters.reserved += 1;
24
+ const session = new WireSession((text, params) => send2(reserved, text, params), held.notices, isClosed, false, () => {
25
+ counters.reservedBusy += 1;
26
+ }, () => {
27
+ counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
28
+ });
29
+ let lost = false;
30
+ const guard = (run) => lost ? rejectClosed("The connection was lost.") : run().catch((error) => {
31
+ if (isConnectionLost(error))
32
+ lost = true;
33
+ throw error;
34
+ });
35
+ let released = false;
36
+ 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
+ })),
42
+ async release() {
43
+ if (released)
44
+ return;
45
+ released = true;
46
+ try {
47
+ if (!lost)
48
+ await reset(session, reserved);
49
+ } finally {
50
+ counters.reserved = Math.max(0, counters.reserved - 1);
51
+ if (!lost)
52
+ await park(held.parked, reserved);
53
+ }
54
+ }
55
+ };
56
+ }
57
+ async function reset(session, sql) {
58
+ const run = (text) => sql.unsafe(text);
59
+ if (session.depth() > 0)
60
+ await run("ROLLBACK").catch(() => {
61
+ return;
62
+ });
63
+ try {
64
+ await run("RESET ALL");
65
+ await run("SELECT pg_advisory_unlock_all()");
66
+ } catch {
67
+ await run("ROLLBACK").catch(() => {
68
+ return;
69
+ });
70
+ await run("RESET ALL");
71
+ await run("SELECT pg_advisory_unlock_all()");
72
+ }
73
+ }
74
+ export {
75
+ checkout
76
+ };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  catalogHash2,
3
3
  parseCatalog2
4
- } from "./y9m15dfv.js";
4
+ } from "./t616ynfn.js";
5
5
  import {
6
6
  parsePlan
7
- } from "./05w44d8g.js";
7
+ } from "./2ssqrv66.js";
8
8
  import {
9
9
  OkmError2
10
- } from "./ycwz42az.js";
10
+ } from "./52szzakm.js";
11
11
 
12
12
  // src/tooling/migrate/files.ts
13
13
  import { existsSync, readdirSync, readFileSync } from "node:fs";
@@ -0,0 +1,48 @@
1
+ import {
2
+ required
3
+ } from "./c9z5g0fm.js";
4
+ import {
5
+ rejected
6
+ } from "./tmbdywx0.js";
7
+
8
+ // src/dialects/pg/json.ts
9
+ function jsonReplacer2(_key, value) {
10
+ if (typeof value === "bigint") {
11
+ return value.toString();
12
+ }
13
+ return value;
14
+ }
15
+ function json2() {
16
+ return required({
17
+ baseType: "json",
18
+ encode: encodeJson,
19
+ decode: decodeJson,
20
+ accepts: ["Array", "Object"],
21
+ sqlForm: "json"
22
+ });
23
+ }
24
+ function jsonb2() {
25
+ return required({
26
+ baseType: "jsonb",
27
+ encode: encodeJson,
28
+ decode: decodeJson,
29
+ accepts: ["Array", "Object"],
30
+ sqlForm: "jsonb"
31
+ });
32
+ }
33
+ function encodeJson(value) {
34
+ const text = JSON.stringify(value, jsonReplacer2);
35
+ if (text === undefined) {
36
+ rejected("json value must be JSON data. undefined and functions are not accepted. bigint is written as a decimal string.");
37
+ }
38
+ return text;
39
+ }
40
+ function decodeJson(wire) {
41
+ try {
42
+ return JSON.parse(wire);
43
+ } catch {
44
+ rejected("json text must be JSON, for example null, a string, a number, true, {}, or [].");
45
+ }
46
+ }
47
+
48
+ export { jsonReplacer2, json2, jsonb2, encodeJson };
@@ -0,0 +1,102 @@
1
+ import {
2
+ OkmError2
3
+ } from "./52szzakm.js";
4
+
5
+ // src/dialects/pg/role/check.ts
6
+ async function assertRoleHealth(runner, roles, objects) {
7
+ const managed = new Set((roles.managed ?? []).map((role) => role.name));
8
+ const named = [roles.migration, roles.app];
9
+ for (const name of named) {
10
+ if (managed.has(name))
11
+ continue;
12
+ if (!await roleExists(runner, name)) {
13
+ throw new OkmError2("not_found", `Role ${name} is named in roles and does not exist.`, {
14
+ kind: "not_found",
15
+ fix: { summary: "Create the role, or list it in roles.managed so the plan creates it." }
16
+ });
17
+ }
18
+ }
19
+ if (managed.size > 0)
20
+ await assertCreateRole(runner, await currentUser(runner));
21
+ for (const object of objects) {
22
+ if (object.kind !== "grant" || object.identity.role !== roles.app)
23
+ continue;
24
+ await assertGrant(runner, object);
25
+ }
26
+ }
27
+ async function assertCreateRole(runner, role) {
28
+ const result = await runner.execute("select rolcreaterole from pg_roles where rolname = $1", [
29
+ role
30
+ ]);
31
+ if (!truthy(result.rows[0]?.[0])) {
32
+ throw new OkmError2("forbidden", `Role ${role} lacks CREATEROLE. Nothing was changed.`, {
33
+ kind: "forbidden",
34
+ fix: { summary: "Grant CREATEROLE to the role that applies migrations." }
35
+ });
36
+ }
37
+ }
38
+ async function currentUser(runner) {
39
+ const result = await runner.execute("select current_user");
40
+ const name = result.rows[0]?.[0];
41
+ return typeof name === "string" ? name : "";
42
+ }
43
+ async function roleExists(runner, name) {
44
+ const result = await runner.execute("select 1 from pg_roles where rolname = $1", [name]);
45
+ return result.rows.length > 0;
46
+ }
47
+ async function assertGrant(runner, object) {
48
+ const target = object.identity.object;
49
+ const schema = target.namespace.form === "static" ? target.namespace.name : "public";
50
+ const privilege = object.identity.privilege;
51
+ if (target.kind === "function") {
52
+ const open = target.name.lastIndexOf("(");
53
+ const fn = open < 0 ? target.name : target.name.slice(0, open);
54
+ const args = open < 0 ? "" : target.name.slice(open + 1, -1);
55
+ if (!await functionExists(runner, schema, fn, args))
56
+ return;
57
+ const allowed = await runner.execute("select has_function_privilege($1, format('%I.%I(%s)', $2::text, $3::text, $4::text), $5)", [object.identity.role, schema, fn, args, privilege]);
58
+ if (!truthy(allowed.rows[0]?.[0]))
59
+ missing(object, `${schema}.${fn}`);
60
+ return;
61
+ }
62
+ if (target.kind === "namespace")
63
+ return;
64
+ const relkinds = target.kind === "sequence" ? "'S'" : target.kind === "view" ? "'v'" : target.kind === "materializedView" ? "'m'" : "'r', 'p'";
65
+ if (!await relationExists(runner, schema, target.name, relkinds))
66
+ return;
67
+ 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)";
68
+ const allowed = await runner.execute(probe, [
69
+ object.identity.role,
70
+ schema,
71
+ target.name,
72
+ privilege
73
+ ]);
74
+ if (!truthy(allowed.rows[0]?.[0]))
75
+ missing(object, `${schema}.${target.name}`);
76
+ }
77
+ function missing(object, name) {
78
+ throw new OkmError2("OKM1825", `Role ${object.identity.role} lacks ${object.identity.privilege} on ${name}.`, {
79
+ kind: "forbidden",
80
+ fix: {
81
+ summary: "Grant the privilege, or change the role. okm doctor reports the object and the privilege."
82
+ }
83
+ });
84
+ }
85
+ async function relationExists(runner, schema, name, relkinds) {
86
+ const result = await runner.execute(`select 1 from pg_class c
87
+ join pg_namespace n on n.oid = c.relnamespace
88
+ where n.nspname = $1 and c.relname = $2 and c.relkind in (${relkinds})`, [schema, name]);
89
+ return result.rows.length > 0;
90
+ }
91
+ async function functionExists(runner, schema, name, args) {
92
+ const result = await runner.execute(`select 1 from pg_proc p
93
+ join pg_namespace n on n.oid = p.pronamespace
94
+ where n.nspname = $1 and p.proname = $2
95
+ and replace(pg_get_function_identity_arguments(p.oid), ' ', '') = $3`, [schema, name, args]);
96
+ return result.rows.length > 0;
97
+ }
98
+ function truthy(value) {
99
+ return value === true || value === "t" || value === "true";
100
+ }
101
+
102
+ export { assertRoleHealth, assertCreateRole, currentUser, roleExists };
@@ -1,19 +1,14 @@
1
1
  import {
2
- CATALOG_VERSION2,
3
- assertNamespace2,
4
2
  identityKey2,
5
3
  identityLabel2,
6
- normaliseEdges,
7
- compareText,
8
- assertProvenance
9
- } from "./j5cn2963.js";
4
+ compareText
5
+ } from "./t4tbsy9h.js";
10
6
  import {
11
- assertIdentifier2,
12
- assertStoredText
13
- } from "./mkjmqjv4.js";
7
+ CATALOG_VERSION2
8
+ } from "./4e4c6vq2.js";
14
9
  import {
15
10
  catalogError2
16
- } from "./ycwz42az.js";
11
+ } from "./52szzakm.js";
17
12
 
18
13
  // src/contracts/catalog/order.ts
19
14
  function indexObjects(objects) {
@@ -140,49 +135,4 @@ function assertForeignKeys(objects, keys) {
140
135
  }
141
136
  }
142
137
 
143
- // src/contracts/catalog/enum.ts
144
- function enumType(input) {
145
- assertNamespace2(input.namespace);
146
- assertIdentifier2(input.name, "type");
147
- assertProvenance(input.provenance);
148
- if (input.labels.length === 0) {
149
- catalogError2("OKM1020", `Enum ${input.name} must list at least one label.`);
150
- }
151
- const labels = [];
152
- const seen = new Set;
153
- for (const label of input.labels) {
154
- assertStoredText(label, "enum label");
155
- if (label.length === 0) {
156
- catalogError2("OKM1020", `Enum ${input.name} has an empty label.`);
157
- }
158
- if (seen.has(label)) {
159
- catalogError2("OKM1020", `Enum ${input.name} repeats label ${label}.`);
160
- }
161
- seen.add(label);
162
- labels.push(label);
163
- }
164
- const identity = {
165
- kind: "type",
166
- namespace: input.namespace,
167
- name: input.name
168
- };
169
- return {
170
- kind: "type",
171
- identity,
172
- owner: input.owner ?? "managed",
173
- definition: { labels },
174
- dependencies: normaliseEdges(input.dependencies ?? []),
175
- provenance: input.provenance
176
- };
177
- }
178
- function sameEnumLabels(left, right) {
179
- if (left.length !== right.length)
180
- return false;
181
- for (let index = 0;index < left.length; index += 1) {
182
- if (left[index] !== right[index])
183
- return false;
184
- }
185
- return true;
186
- }
187
-
188
- export { dependencyOrder, catalog, enumType, sameEnumLabels };
138
+ export { dependencyOrder, catalog };