okmodel 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/README.md +237 -19
  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/object.d.ts +1 -0
  13. package/dist/contracts/catalog/types.d.ts +15 -8
  14. package/dist/contracts/connection.d.ts +13 -0
  15. package/dist/contracts/driver.d.ts +18 -5
  16. package/dist/contracts/error.d.ts +17 -1
  17. package/dist/contracts/generator.d.ts +63 -0
  18. package/dist/contracts/index.d.ts +2 -2
  19. package/dist/contracts/index.js +1 -1
  20. package/dist/contracts/internal.js +11 -9
  21. package/dist/contracts/location.d.ts +24 -0
  22. package/dist/contracts/rows.d.ts +15 -0
  23. package/dist/dialects/pg/archive-bind.d.ts +22 -0
  24. package/dist/dialects/pg/column.d.ts +126 -9
  25. package/dist/dialects/pg/compile.d.ts +1 -0
  26. package/dist/dialects/pg/custom.d.ts +6 -0
  27. package/dist/dialects/pg/filter-parse.d.ts +19 -0
  28. package/dist/dialects/pg/filters.d.ts +19 -0
  29. package/dist/dialects/pg/index.d.ts +11 -2
  30. package/dist/dialects/pg/index.js +159 -1063
  31. package/dist/dialects/pg/keys.d.ts +19 -3
  32. package/dist/dialects/pg/model.d.ts +223 -2
  33. package/dist/dialects/pg/operator-fit.d.ts +86 -0
  34. package/dist/dialects/pg/operators.d.ts +39 -1
  35. package/dist/dialects/pg/ops/arr-append.d.ts +9 -0
  36. package/dist/dialects/pg/ops/arr-ns.d.ts +7 -0
  37. package/dist/dialects/pg/ops/arr-remove.d.ts +9 -0
  38. package/dist/dialects/pg/ops/containedBy.d.ts +9 -0
  39. package/dist/dialects/pg/ops/contains.d.ts +8 -4
  40. package/dist/dialects/pg/ops/hasAnyKey.d.ts +8 -0
  41. package/dist/dialects/pg/ops/hasKey.d.ts +8 -0
  42. package/dist/dialects/pg/ops/json-ns.d.ts +6 -0
  43. package/dist/dialects/pg/ops/json-set.d.ts +12 -0
  44. package/dist/dialects/pg/ops/matches.d.ts +16 -0
  45. package/dist/dialects/pg/ops/overlaps.d.ts +9 -0
  46. package/dist/dialects/pg/ops/path.d.ts +13 -0
  47. package/dist/dialects/pg/preset.d.ts +76 -0
  48. package/dist/dialects/pg/relations.d.ts +59 -2
  49. package/dist/dialects/pg/schema.d.ts +109 -5
  50. package/dist/dialects/pg/table.d.ts +130 -11
  51. package/dist/dialects/pg/temporal.d.ts +9 -7
  52. package/dist/dialects/pg/tenancy.d.ts +94 -0
  53. package/dist/dialects/pg/through.d.ts +21 -0
  54. package/dist/dialects/pg/trait.d.ts +141 -0
  55. package/dist/dialects/pg/where.d.ts +37 -0
  56. package/dist/runtime/aggregate.d.ts +25 -0
  57. package/dist/runtime/archive-handle.d.ts +18 -0
  58. package/dist/runtime/archive-rules.d.ts +12 -0
  59. package/dist/runtime/archive.d.ts +73 -0
  60. package/dist/runtime/batch.d.ts +20 -0
  61. package/dist/runtime/client.d.ts +114 -5
  62. package/dist/runtime/conflict.d.ts +2 -1
  63. package/dist/runtime/exposure.d.ts +27 -0
  64. package/dist/runtime/hookm.d.ts +39 -0
  65. package/dist/runtime/ids/index.d.ts +11 -0
  66. package/dist/runtime/ids/index.js +193 -0
  67. package/dist/runtime/ids/okid-extended.d.ts +19 -0
  68. package/dist/runtime/ids/okid-generator.d.ts +21 -0
  69. package/dist/runtime/ids/okid-shared.d.ts +89 -0
  70. package/dist/runtime/ids/okid.d.ts +24 -0
  71. package/dist/runtime/ids/uuid.d.ts +21 -0
  72. package/dist/runtime/lock.d.ts +22 -0
  73. package/dist/runtime/operator-sql.d.ts +8 -0
  74. package/dist/runtime/page.d.ts +25 -0
  75. package/dist/runtime/pg/bun.d.ts +30 -0
  76. package/dist/runtime/pg/bun.js +52 -0
  77. package/dist/runtime/pg/pg.d.ts +29 -0
  78. package/dist/runtime/pg/pg.js +52 -0
  79. package/dist/runtime/pg/pglite.js +16 -17
  80. package/dist/runtime/pg/postgresjs.js +14 -24
  81. package/dist/runtime/plan.d.ts +146 -7
  82. package/dist/runtime/preset-stack.d.ts +17 -0
  83. package/dist/runtime/presets.d.ts +48 -0
  84. package/dist/runtime/read-stream.d.ts +26 -0
  85. package/dist/runtime/safety/index.d.ts +159 -0
  86. package/dist/runtime/safety/index.js +294 -0
  87. package/dist/runtime/safety-hook.d.ts +42 -0
  88. package/dist/runtime/server-check.d.ts +34 -0
  89. package/dist/runtime/tenancy/index.d.ts +37 -0
  90. package/dist/runtime/tenancy/index.js +365 -0
  91. package/dist/runtime/trait-read.d.ts +30 -0
  92. package/dist/runtime/traits/index.d.ts +128 -0
  93. package/dist/runtime/traits/index.js +509 -0
  94. package/dist/runtime/transaction.d.ts +19 -0
  95. package/dist/runtime/tx.d.ts +22 -7
  96. package/dist/runtime/types.d.ts +390 -25
  97. package/dist/runtime/validate/bind.d.ts +11 -0
  98. package/dist/runtime/validate/closed.d.ts +16 -0
  99. package/dist/runtime/validate/engine.d.ts +41 -0
  100. package/dist/runtime/validate/hook.d.ts +17 -0
  101. package/dist/runtime/validate/index.d.ts +21 -0
  102. package/dist/runtime/validate/index.js +175 -0
  103. package/dist/runtime/validate/load.d.ts +13 -0
  104. package/dist/runtime/validate/places.d.ts +41 -0
  105. package/dist/runtime/validate/rules.d.ts +108 -0
  106. package/dist/runtime/validate/surface.d.ts +102 -0
  107. package/dist/runtime/write.d.ts +30 -5
  108. package/dist/shared/{fgqgsb5z.js → 0qkxbm1f.js} +2 -2
  109. package/dist/shared/0v1g424p.js +26 -0
  110. package/dist/shared/10tjenmd.js +210 -0
  111. package/dist/shared/{tb4ze1tr.js → 1dp5knt7.js} +95 -10
  112. package/dist/shared/38crxbgn.js +229 -0
  113. package/dist/shared/3a5ne750.js +158 -0
  114. package/dist/shared/4b9da9d7.js +138 -0
  115. package/dist/shared/4e4c6vq2.js +62 -0
  116. package/dist/shared/{ckb1p0a4.js → 4jzzghr6.js} +416 -83
  117. package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
  118. package/dist/shared/{kynx7vbm.js → 5z4q2zda.js} +604 -21
  119. package/dist/shared/672t5vym.js +12 -0
  120. package/dist/shared/7m88x3e9.js +45 -0
  121. package/dist/shared/7mht49yd.js +1091 -0
  122. package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
  123. package/dist/shared/83eaefwr.js +10 -0
  124. package/dist/shared/96ps4g1z.js +32 -0
  125. package/dist/shared/97g2jnrw.js +76 -0
  126. package/dist/shared/{xy79j5hq.js → 9k6vetvf.js} +25 -36
  127. package/dist/shared/{w8samvk1.js → a1gdp7j9.js} +1 -1
  128. package/dist/shared/a5sxz52y.js +13 -0
  129. package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
  130. package/dist/shared/cstgkzdx.js +154 -0
  131. package/dist/shared/{ax16zpvm.js → d04j53v8.js} +6 -5
  132. package/dist/shared/{y9m15dfv.js → d2whjz4k.js} +15 -9
  133. package/dist/shared/dd4f8mnx.js +307 -0
  134. package/dist/shared/e6wg00wd.js +164 -0
  135. package/dist/shared/e7a268fy.js +195 -0
  136. package/dist/shared/{vkm3q4x1.js → eaxwrgby.js} +4 -3
  137. package/dist/shared/{7ck0dtry.js → ecdzej21.js} +160 -81
  138. package/dist/shared/{px90pf9p.js → edwqqryd.js} +21 -16
  139. package/dist/shared/{g2v6gnc8.js → eqmtn1bj.js} +57 -5
  140. package/dist/shared/g1b5zzj9.js +75 -0
  141. package/dist/shared/g9f0zqce.js +376 -0
  142. package/dist/shared/ge03bfca.js +64 -0
  143. package/dist/shared/{79ggp945.js → jns2wx4t.js} +55 -12
  144. package/dist/shared/k3ted12y.js +33 -0
  145. package/dist/shared/k7dwkhvq.js +31 -0
  146. package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
  147. package/dist/shared/m9tv7xn7.js +404 -0
  148. package/dist/shared/mrq77sgw.js +55 -0
  149. package/dist/shared/mxmcdsh5.js +450 -0
  150. package/dist/shared/n442h54c.js +14 -0
  151. package/dist/shared/n47rd821.js +442 -0
  152. package/dist/shared/n4jqhpqz.js +27 -0
  153. package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
  154. package/dist/shared/nsva2a6b.js +42 -0
  155. package/dist/shared/ps43134h.js +69 -0
  156. package/dist/shared/{8b04d28c.js → py3nh7jy.js} +2 -2
  157. package/dist/shared/qa5dsc7z.js +86 -0
  158. package/dist/shared/{g5fhqmwe.js → qxa0yb9j.js} +6 -4
  159. package/dist/shared/r6nwkxnt.js +86 -0
  160. package/dist/shared/{4j72449d.js → rtnaqre0.js} +3 -3
  161. package/dist/shared/rwmrejjz.js +26 -0
  162. package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
  163. package/dist/shared/sacqha1y.js +70 -0
  164. package/dist/shared/{qk3hxfja.js → sfh4pk75.js} +5 -5
  165. package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
  166. package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
  167. package/dist/shared/v18jva5b.js +90 -0
  168. package/dist/shared/x9v1qgeb.js +201 -0
  169. package/dist/shared/xatfg0gn.js +193 -0
  170. package/dist/shared/xkz8g6by.js +225 -0
  171. package/dist/shared/{f5thc1s0.js → xrfnq5k8.js} +237 -418
  172. package/dist/shared/ytg3xf9p.js +149 -0
  173. package/dist/shared/yw5c610b.js +48 -0
  174. package/dist/shared/zd93g3rq.js +31 -0
  175. package/dist/shared/zt8y0wzb.js +132 -0
  176. package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
  177. package/dist/tooling/cli.js +14 -10
  178. package/dist/tooling/migrate/commands.d.ts +10 -0
  179. package/dist/tooling/migrate/engine.d.ts +36 -0
  180. package/package.json +56 -4
  181. package/dist/shared/gk7cs7sp.js +0 -566
@@ -1,16 +1,95 @@
1
1
  import {
2
2
  POSTGRESJS_CAPABILITIES,
3
- driverErrors,
4
3
  rejectClosed,
5
4
  mapFailure,
6
5
  nextTransactionDepth,
7
6
  runCall,
8
7
  EMPTY_NOTICES,
9
8
  resultFrom
10
- } from "./xy79j5hq.js";
9
+ } from "./9k6vetvf.js";
11
10
 
12
11
  // src/adapters/pg/postgresjs.ts
12
+ import net from "node:net";
13
13
  import postgres from "postgres";
14
+ class PoolSockets {
15
+ held = [];
16
+ busy = 0;
17
+ listeners = 0;
18
+ hostCursor = 0;
19
+ connect(target) {
20
+ const path = typeof target.path === "string" ? target.path : undefined;
21
+ const hosts = target.host;
22
+ const ports = target.port;
23
+ const index = hosts.length === 0 ? 0 : this.hostCursor % hosts.length;
24
+ this.hostCursor += 1;
25
+ const host = hosts[index] ?? "localhost";
26
+ const port = ports[index] ?? ports[0] ?? 5432;
27
+ const socket = path !== undefined ? net.connect(path) : net.connect(port, host);
28
+ this.held.push(socket);
29
+ return socket;
30
+ }
31
+ occupy(run) {
32
+ this.busy += 1;
33
+ this.wake();
34
+ return run().finally(() => {
35
+ this.busy -= 1;
36
+ this.park();
37
+ });
38
+ }
39
+ busyGate() {
40
+ return {
41
+ enter: () => {
42
+ this.busy += 1;
43
+ this.wake();
44
+ },
45
+ leave: () => {
46
+ this.busy -= 1;
47
+ this.park();
48
+ }
49
+ };
50
+ }
51
+ listenerGate() {
52
+ return {
53
+ enter: () => {
54
+ this.listeners += 1;
55
+ this.wake();
56
+ },
57
+ leave: () => {
58
+ this.listeners -= 1;
59
+ this.park();
60
+ }
61
+ };
62
+ }
63
+ wake() {
64
+ for (const socket of this.held)
65
+ socket.ref();
66
+ }
67
+ park() {
68
+ if (this.busy > 0 || this.listeners > 0)
69
+ return;
70
+ for (const socket of this.held)
71
+ socket.unref();
72
+ }
73
+ }
74
+ function driverOptions(config, state) {
75
+ return {
76
+ max: state.max,
77
+ prepare: state.named,
78
+ idle_timeout: state.plain ? 0 : 30,
79
+ ...state.plain ? { max_lifetime: null } : {},
80
+ connect_timeout: 5,
81
+ types: WIRE_TYPES,
82
+ ...state.plain ? { socket: (options) => state.sockets.connect(options) } : {},
83
+ ...config.ssl !== undefined ? { ssl: config.ssl } : {},
84
+ connection: {
85
+ application_name: "okmodel",
86
+ ...config.searchPath !== undefined ? { search_path: config.searchPath } : {}
87
+ },
88
+ onnotice(notice) {
89
+ state.notices.push(notice);
90
+ }
91
+ };
92
+ }
14
93
  function open2(config) {
15
94
  const max = config.max ?? 10;
16
95
  const acquireMs = config.timeouts?.acquire;
@@ -20,47 +99,65 @@ function open2(config) {
20
99
  let closed = false;
21
100
  const isClosed = () => closed;
22
101
  const named = config.prepared === "named";
23
- const sql = postgres(config.url, {
102
+ const plain = config.ssl === undefined;
103
+ const sockets = new PoolSockets;
104
+ const sql = postgres(config.url, driverOptions(config, {
24
105
  max,
25
- prepare: named,
26
- idle_timeout: 30,
27
- connect_timeout: 5,
28
- types: WIRE_TYPES,
29
- ...config.ssl !== undefined ? { ssl: config.ssl } : {},
30
- connection: {
31
- application_name: "okmodel",
32
- ...config.searchPath !== undefined ? { search_path: config.searchPath } : {}
33
- },
34
- onnotice(notice) {
35
- notices.push(notice);
36
- }
37
- });
106
+ named,
107
+ plain,
108
+ notices,
109
+ sockets
110
+ }));
38
111
  const root = new PgSession(sql, counters, "pool", poolInflight, isClosed, undefined, notices, named);
39
112
  const held = { sql, acquireMs, counters, isClosed, notices, named, poolInflight };
40
113
  return {
41
114
  capabilities: POSTGRESJS_CAPABILITIES,
42
115
  execute(text, params, options) {
43
- return runCall(closed, options, (watch) => root.query(text, params, watch));
116
+ return sockets.occupy(() => runCall(closed, options, (watch) => root.query(text, params, watch)));
44
117
  },
45
118
  async batch(statements, options) {
46
- const { checkout } = await import("./tb4ze1tr.js");
47
- const connection = await checkout(held);
48
- try {
49
- return await connection.batch(statements, options);
50
- } finally {
51
- await connection.release();
52
- }
119
+ return sockets.occupy(async () => {
120
+ const { checkout } = await import("./1dp5knt7.js");
121
+ const connection = await checkout(held);
122
+ try {
123
+ return await connection.batch(statements, options);
124
+ } finally {
125
+ await connection.release();
126
+ }
127
+ });
53
128
  },
54
- reserve: () => import("./tb4ze1tr.js").then((mod) => mod.checkout(held)),
55
- describe: (text, params) => import("./tb4ze1tr.js").then((mod) => mod.describe(sql, text, params)),
129
+ reserve() {
130
+ const gate = sockets.busyGate();
131
+ gate.enter();
132
+ return import("./1dp5knt7.js").then((mod) => mod.holdCheckout(gate, () => mod.checkout(held)), (error) => {
133
+ gate.leave();
134
+ throw error;
135
+ });
136
+ },
137
+ describe: (text, params) => sockets.occupy(() => import("./1dp5knt7.js").then((mod) => mod.describe(sql, text, params))),
56
138
  stream(text, params) {
57
- return loadStream(sql, text, params);
139
+ const gate = sockets.busyGate();
140
+ return async function* () {
141
+ gate.enter();
142
+ try {
143
+ yield* loadStream(sql, text, params);
144
+ } finally {
145
+ gate.leave();
146
+ }
147
+ }();
58
148
  },
59
- async listen(channel, onNotify) {
60
- const listening = await sql.listen(channel, onNotify);
61
- return async () => {
62
- await listening.unlisten();
63
- };
149
+ listen(channel, onNotify) {
150
+ const gate = sockets.listenerGate();
151
+ gate.enter();
152
+ return import("./1dp5knt7.js").then((mod) => mod.holdListener(gate, async () => {
153
+ const listening = await sql.listen(channel, onNotify);
154
+ return async () => {
155
+ await listening.unlisten();
156
+ };
157
+ }), (error) => {
158
+ gate.leave();
159
+ throw error;
160
+ });
64
161
  },
65
162
  cancel() {
66
163
  for (const pending of poolInflight)
@@ -113,7 +210,36 @@ class PgSession {
113
210
  });
114
211
  });
115
212
  }
116
- return this.watched(pending, watch, start, text);
213
+ this.local.add(pending);
214
+ this.shared?.add(pending);
215
+ const onAbort = () => {
216
+ pending.cancel();
217
+ };
218
+ if (watch.signal.aborted)
219
+ onAbort();
220
+ else
221
+ watch.signal.addEventListener("abort", onAbort, { once: true });
222
+ return import("./1dp5knt7.js").then((mod) => mod.watchQuery(pending, watch, onAbort, {
223
+ start,
224
+ text,
225
+ notices: this.notices,
226
+ leave: () => {
227
+ this.leave();
228
+ },
229
+ note: (sqlText) => {
230
+ this.note(sqlText);
231
+ },
232
+ untrack: (item) => {
233
+ this.local.delete(item);
234
+ this.shared?.delete(item);
235
+ }
236
+ }), (error) => {
237
+ this.leave();
238
+ this.local.delete(pending);
239
+ this.shared?.delete(pending);
240
+ watch.signal.removeEventListener("abort", onAbort);
241
+ throw error;
242
+ });
117
243
  }
118
244
  inTransaction() {
119
245
  return this.transactionDepth > 0;
@@ -143,43 +269,9 @@ class PgSession {
143
269
  else
144
270
  this.counters.reservedBusy = Math.max(0, this.counters.reservedBusy - 1);
145
271
  }
146
- track(pending) {
147
- this.local.add(pending);
148
- this.shared?.add(pending);
149
- }
150
- untrack(pending) {
151
- this.local.delete(pending);
152
- this.shared?.delete(pending);
153
- }
154
- watched(pending, watch, start, text) {
155
- this.track(pending);
156
- const onAbort = () => {
157
- pending.cancel();
158
- };
159
- if (watch.signal.aborted)
160
- onAbort();
161
- else
162
- watch.signal.addEventListener("abort", onAbort, { once: true });
163
- return pending.then((result) => {
164
- this.finishWatched(pending, watch, onAbort);
165
- const why = watch.reason();
166
- if (why === "timeout" || why === "cancelled")
167
- return classify(why, watch);
168
- this.note(text);
169
- return resultFrom(result, this.notices.since(start));
170
- }, (error) => {
171
- this.finishWatched(pending, watch, onAbort);
172
- return classify(error, watch);
173
- });
174
- }
175
- finishWatched(pending, watch, onAbort) {
176
- this.leave();
177
- this.untrack(pending);
178
- watch.signal.removeEventListener("abort", onAbort);
179
- }
180
272
  }
181
273
  async function* loadStream(sql, text, params) {
182
- const { stream } = await import("./tb4ze1tr.js");
274
+ const { stream } = await import("./1dp5knt7.js");
183
275
  yield* stream(sql, text, params);
184
276
  }
185
277
  function send(sql, text, params, named) {
@@ -192,19 +284,6 @@ function asParams(params) {
192
284
  return [];
193
285
  return params;
194
286
  }
195
- async function classify(error, watch) {
196
- const errors = await driverErrors();
197
- if (error instanceof errors.DriverError)
198
- return Promise.reject(error);
199
- const why = typeof error === "string" ? error : watch.reason();
200
- if (why === "timeout")
201
- return Promise.reject(errors.timedOut(typeof error === "string" ? undefined : error));
202
- const code = errors.errorField(error, "code");
203
- if (why === "cancelled" || code === "57014") {
204
- return Promise.reject(errors.cancelled(typeof error === "string" ? undefined : error));
205
- }
206
- return Promise.reject(errors.mapDriverError(error));
207
- }
208
287
  function statsOf(counters, size) {
209
288
  return {
210
289
  size,
@@ -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 "./f5thc1s0.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 {
@@ -304,10 +307,12 @@ function parseInclude(schema, name, relation, value, all) {
304
307
  }
305
308
  function anchored(table, columns) {
306
309
  const pk = table.model.primary[0];
307
- const selected = pk === undefined ? -1 : columns.findIndex((column) => column.field === pk);
310
+ if (pk === undefined)
311
+ return { presence: undefined, anchor: 0 };
312
+ const selected = columns.findIndex((column) => column.field === pk);
308
313
  if (selected >= 0)
309
314
  return { presence: undefined, anchor: selected };
310
- return { presence: pk === undefined ? undefined : table.columns.get(pk), anchor: columns.length };
315
+ return { presence: table.columns.get(pk), anchor: columns.length };
311
316
  }
312
317
  function childIndex(schema, relation) {
313
318
  const child = indexes(schema).get(relation.table);
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  open2
3
- } from "./7ck0dtry.js";
3
+ } from "./ecdzej21.js";
4
4
  import {
5
5
  catalogHash2
6
- } from "./y9m15dfv.js";
6
+ } from "./d2whjz4k.js";
7
+ import"./n442h54c.js";
7
8
  import {
8
9
  loadMigrations
9
- } from "./4j72449d.js";
10
+ } from "./rtnaqre0.js";
10
11
  import {
11
12
  quoteIdent,
12
13
  planMigration,
@@ -15,13 +16,63 @@ import {
15
16
  selectTarget,
16
17
  projectHead,
17
18
  loadConfig
18
- } from "./kynx7vbm.js";
19
+ } from "./5z4q2zda.js";
19
20
  import {
20
21
  OkmError2
21
- } from "./ycwz42az.js";
22
+ } from "./52szzakm.js";
22
23
 
23
24
  // src/tooling/migrate/apply.ts
24
25
  import { join } from "node:path";
26
+
27
+ // src/tooling/migrate/engine.ts
28
+ var IDENT = String.raw`"(?:[^"]|"")+"|[A-Za-z_][\w$]*`;
29
+ var DEFAULT_UUIDV7 = /\bdefault\s+uuidv7\s*\(\s*\)/i;
30
+ var TABLE = new RegExp(String.raw`^\s*(?:create\s+table(?:\s+if\s+not\s+exists)?|alter\s+table(?:\s+if\s+exists)?(?:\s+only)?)\s+(?:(?:${IDENT})\.)?(${IDENT})`, "i");
31
+ var COLUMN = new RegExp(String.raw`(${IDENT})\s+(?:uuid\b|set\s+default\b)`, "i");
32
+ function findUuidV7Default(migrations) {
33
+ for (const migration of migrations) {
34
+ for (let stepIndex = 0;stepIndex < migration.steps.length; stepIndex += 1) {
35
+ const sql = migration.steps[stepIndex]?.sql ?? "";
36
+ if (!DEFAULT_UUIDV7.test(sql))
37
+ continue;
38
+ return { migrationId: migration.id, stepIndex, column: columnOf(sql) };
39
+ }
40
+ }
41
+ return;
42
+ }
43
+ async function assertUuidV7Available(connection, migrations) {
44
+ const found = findUuidV7Default(migrations);
45
+ if (found === undefined)
46
+ return;
47
+ const result = await connection.execute("select current_setting('server_version_num'), to_regprocedure('uuidv7()')::text");
48
+ const row = result.rows[0];
49
+ const major = Math.floor(Number(row?.[0] ?? "0") / 1e4);
50
+ const defined = row?.[1] !== null && row?.[1] !== undefined;
51
+ if (major >= 18 || defined)
52
+ return;
53
+ const where = found.column === undefined ? "A column" : `Column ${found.column}`;
54
+ throw new OkmError2("OKM1812", `${where} has a uuidv7() default (migration ${found.migrationId}, step ${String(found.stepIndex)}), and the server is PostgreSQL ${String(major)}. uuidv7() arrives in PostgreSQL 18. Nothing was changed.`, {
55
+ fix: {
56
+ summary: 'Either run PostgreSQL 18 and declare schema({ requires: { postgres: ">=18" } }), or use t.id({ default: "uuidv4" }) (or schema({ defaults: { id: "uuidv4" } })), which uses gen_random_uuid() and works on PostgreSQL 13 and newer. Then delete the migration that was not applied and generate it again.'
57
+ }
58
+ });
59
+ }
60
+ function columnOf(sql) {
61
+ const table = TABLE.exec(sql)?.[1];
62
+ if (table === undefined)
63
+ return;
64
+ const line = sql.split(`
65
+ `).find((text) => DEFAULT_UUIDV7.test(text));
66
+ const column = line === undefined ? undefined : COLUMN.exec(line)?.[1];
67
+ if (column === undefined)
68
+ return;
69
+ return `${unquote(table)}.${unquote(column)}`;
70
+ }
71
+ function unquote(name) {
72
+ return name.startsWith('"') ? name.slice(1, -1).replaceAll('""', '"') : name;
73
+ }
74
+
75
+ // src/tooling/migrate/apply.ts
25
76
  var DEFAULT_LOCK_MS = 5000;
26
77
  var DEFAULT_STATEMENT_MS = 30000;
27
78
  var DEFAULT_RETRIES = 3;
@@ -100,6 +151,7 @@ async function applyTarget(request) {
100
151
  await lockTarget(connection, request.target);
101
152
  locked = true;
102
153
  request.onLocked?.();
154
+ await assertUuidV7Available(connection, request.migrations);
103
155
  await connection.execute(META);
104
156
  await connection.execute(HISTORY);
105
157
  const done = await readDone(connection);
@@ -0,0 +1,75 @@
1
+ import {
2
+ definition,
3
+ unavailable
4
+ } from "./xatfg0gn.js";
5
+
6
+ // src/dialects/pg/trait.ts
7
+ var TRAIT_KEYS = new Set(["fields", "name", "presets", "sealed", "touch"]);
8
+ function checkTrait(value, where) {
9
+ if (!isRecord(value))
10
+ definition(`${where} traits must be a list of traits.`);
11
+ for (const key of Object.keys(value)) {
12
+ if (key === "methods" || key === "requires") {
13
+ unavailable(`Trait option ${key} is not available yet. It arrives in 0.2.`);
14
+ }
15
+ if (!TRAIT_KEYS.has(key)) {
16
+ definition(`${where} trait option ${key} is not supported. Accepted options: fields, name, presets, sealed, touch.`);
17
+ }
18
+ }
19
+ const name = value.name;
20
+ if (typeof name !== "string" || name.length === 0)
21
+ definition(`${where} trait needs a name.`);
22
+ const fields = value.fields;
23
+ if (!isRecord(fields))
24
+ definition(`Trait ${name} needs a fields object.`);
25
+ const known = Object.keys(fields);
26
+ readNames(value.touch, name, "touch", known);
27
+ readNames(value.sealed, name, "sealed", known);
28
+ return value;
29
+ }
30
+ function contributedFields(schemaTraits, options) {
31
+ const chosen = choose(options?.omitDefaults === undefined ? schemaTraits : undefined, options?.traits);
32
+ if (chosen === undefined)
33
+ return [];
34
+ const pairs = [];
35
+ const seen = new Set;
36
+ for (const trait of chosen) {
37
+ for (const field of Object.keys(trait.fields)) {
38
+ if (seen.has(field))
39
+ continue;
40
+ const builder = trait.fields[field];
41
+ if (builder === undefined)
42
+ continue;
43
+ seen.add(field);
44
+ pairs.push([field, builder]);
45
+ }
46
+ }
47
+ return pairs;
48
+ }
49
+ function choose(schemaTraits, local) {
50
+ const shared = schemaTraits ?? [];
51
+ const own = local ?? [];
52
+ if (shared.length === 0 && own.length === 0)
53
+ return;
54
+ if (own.length === 0)
55
+ return shared;
56
+ if (shared.length === 0)
57
+ return own;
58
+ return [...shared, ...own];
59
+ }
60
+ function readNames(value, traitName, label, known) {
61
+ if (value === undefined)
62
+ return;
63
+ if (!Array.isArray(value))
64
+ definition(`Trait ${traitName} ${label} must be a list of field names.`);
65
+ for (const field of value) {
66
+ if (typeof field === "string" && known.includes(field))
67
+ continue;
68
+ definition(`Trait ${traitName} ${label} names ${String(field)}, which is not one of its fields. Accepted fields: ${known.join(", ")}.`);
69
+ }
70
+ }
71
+ function isRecord(value) {
72
+ return typeof value === "object" && value !== null && !Array.isArray(value);
73
+ }
74
+
75
+ export { checkTrait, contributedFields };