okmodel 0.4.0 → 0.5.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 (102) hide show
  1. package/README.md +95 -12
  2. package/dist/contracts/catalog/document.d.ts +20 -0
  3. package/dist/contracts/driver.d.ts +7 -0
  4. package/dist/dialects/pg/filter-parse.d.ts +8 -2
  5. package/dist/dialects/pg/fn/index.js +8 -0
  6. package/dist/dialects/pg/index.js +8 -2
  7. package/dist/dialects/pg/introspect.d.ts +6 -0
  8. package/dist/dialects/pg/ops/or.d.ts +1 -1
  9. package/dist/dialects/pg/role/sql.d.ts +10 -0
  10. package/dist/dialects/pg/schema.d.ts +15 -6
  11. package/dist/dialects/pg/temporal.d.ts +5 -76
  12. package/dist/dialects/pg/view/index.d.ts +20 -6
  13. package/dist/dialects/pg/view/index.js +1 -1
  14. package/dist/dialects/pg/view/scratch.d.ts +2 -2
  15. package/dist/runtime/client.d.ts +6 -1
  16. package/dist/runtime/conflict.d.ts +2 -1
  17. package/dist/runtime/pg/bun.d.ts +12 -7
  18. package/dist/runtime/pg/bun.js +7 -4
  19. package/dist/runtime/pg/pg.d.ts +12 -6
  20. package/dist/runtime/pg/pg.js +7 -4
  21. package/dist/runtime/pg/pglite.d.ts +11 -3
  22. package/dist/runtime/pg/pglite.js +7 -4
  23. package/dist/runtime/pg/postgresjs.d.ts +12 -6
  24. package/dist/runtime/pg/postgresjs.js +7 -4
  25. package/dist/runtime/plan.d.ts +16 -1
  26. package/dist/runtime/tenancy/index.js +1 -1
  27. package/dist/runtime/topology.d.ts +191 -0
  28. package/dist/runtime/traits/index.js +7 -7
  29. package/dist/runtime/types.d.ts +57 -2
  30. package/dist/runtime/validate/index.js +3 -3
  31. package/dist/shared/{radd3z4g.js → 0t22wwh1.js} +5 -9
  32. package/dist/shared/{ady1ms74.js → 2pqx26h8.js} +25 -10
  33. package/dist/shared/{kyxb62mc.js → 31vm914h.js} +9 -1
  34. package/dist/shared/{jns2wx4t.js → 32zqc1dw.js} +18 -7
  35. package/dist/shared/{nxb42q7h.js → 47x8x9ze.js} +2 -2
  36. package/dist/shared/{zvbjc949.js → 4az561fn.js} +1 -1
  37. package/dist/shared/{s6gqfn5j.js → 51mvgj8w.js} +27 -3
  38. package/dist/shared/{k3ted12y.js → 54tqkxja.js} +20 -2
  39. package/dist/shared/{3p4b1fg0.js → 5enne4ma.js} +1 -1
  40. package/dist/shared/{6693j9rs.js → 5fqx9yh4.js} +6 -2
  41. package/dist/shared/{c5g81ngb.js → 6mnp99hx.js} +11 -8
  42. package/dist/shared/{hqjsxnz7.js → 6qd27mx0.js} +5 -4
  43. package/dist/shared/{v7tpnhnz.js → 6rk2gen5.js} +5 -3
  44. package/dist/shared/{2321avmn.js → 7zwwyh0v.js} +46 -16
  45. package/dist/shared/{fa9vt245.js → 87jvvhnt.js} +2 -2
  46. package/dist/shared/{8jb4ymh2.js → 8bwbwy8h.js} +12 -1
  47. package/dist/shared/{c8aghh05.js → 8rsy3hxz.js} +7 -1
  48. package/dist/shared/{41kv2xdm.js → 8xsbagad.js} +1 -1
  49. package/dist/shared/{6p5k20sm.js → 96qcj21c.js} +3 -3
  50. package/dist/shared/{jgxzjzcz.js → aj2qxyhj.js} +2 -2
  51. package/dist/shared/{5vdm4sgp.js → caw8b9d8.js} +4 -4
  52. package/dist/shared/{s4mb6a4b.js → cctw17hj.js} +74 -15
  53. package/dist/shared/{rrstp3kb.js → cgbamx3e.js} +2 -2
  54. package/dist/shared/{axhk06q1.js → cr74e96e.js} +1 -1
  55. package/dist/shared/{b066g80h.js → efmy2gcg.js} +2 -2
  56. package/dist/shared/{gdh9mrtp.js → f5cw5q5r.js} +2 -2
  57. package/dist/shared/{xghkt7a9.js → fancm5pt.js} +6 -233
  58. package/dist/shared/{n5y9zyj1.js → ga3sfy93.js} +369 -14
  59. package/dist/shared/{xrfnq5k8.js → gbtcc2d7.js} +55 -5
  60. package/dist/shared/{7nk68fj8.js → gde73es6.js} +20 -15
  61. package/dist/shared/{kkzwp3d2.js → hf22e0wt.js} +55 -19
  62. package/dist/shared/{tny2t3sm.js → janx09m5.js} +8 -7
  63. package/dist/shared/{4ef7mmqf.js → jwtxdj06.js} +5 -5
  64. package/dist/shared/{sf8m6tfy.js → k8v5v5wj.js} +3 -3
  65. package/dist/shared/{qn0srwwq.js → kfjp0gck.js} +5 -3
  66. package/dist/shared/{wqem4jed.js → krxx77g0.js} +7 -7
  67. package/dist/shared/{edwqqryd.js → nkaxvt9q.js} +1 -1
  68. package/dist/shared/{jsd07prz.js → ntneex2a.js} +1 -1
  69. package/dist/shared/nxdp2ze3.js +1197 -0
  70. package/dist/shared/{tbszx8mz.js → pf0d8f77.js} +1 -1
  71. package/dist/shared/{84ptn35q.js → ps7a6h14.js} +10 -9
  72. package/dist/shared/{kj680nxv.js → q58y17hy.js} +9 -7
  73. package/dist/shared/{awrsqrn7.js → qm7cdtvr.js} +22 -9
  74. package/dist/shared/{q6zsyh31.js → qv2ydck9.js} +156 -205
  75. package/dist/shared/{kafaa5zv.js → r2sp8hrc.js} +28 -8
  76. package/dist/shared/{fb00y8fp.js → r8x5qhd7.js} +5 -5
  77. package/dist/shared/{yjw02enp.js → sdc7r2ww.js} +8 -7
  78. package/dist/shared/sycnx8gt.js +289 -0
  79. package/dist/shared/{hcmdtwgh.js → szm0cksa.js} +4 -1
  80. package/dist/shared/{zg24x0hm.js → tm5ab8we.js} +10 -2
  81. package/dist/shared/{ygem90rn.js → v36c5g6p.js} +85 -21
  82. package/dist/shared/wq9n6pwr.js +139 -0
  83. package/dist/shared/{7p2wbz7f.js → x72jb7ad.js} +1 -1
  84. package/dist/shared/{q795afwa.js → z2rnngj4.js} +3 -3
  85. package/dist/shared/{sr5ms7b3.js → zqrnhwsq.js} +3 -3
  86. package/dist/tooling/cli.js +70 -23
  87. package/dist/tooling/migrate/apply.d.ts +2 -0
  88. package/dist/tooling/migrate/commands.d.ts +1 -2
  89. package/dist/tooling/migrate/drift.d.ts +1 -1
  90. package/dist/tooling/migrate/estimate.d.ts +14 -1
  91. package/dist/tooling/migrate/files.d.ts +7 -0
  92. package/dist/tooling/migrate/index.js +12 -9
  93. package/dist/tooling/migrate/lint.d.ts +3 -3
  94. package/dist/tooling/migrate/plan.d.ts +7 -3
  95. package/dist/tooling/migrate/policy.d.ts +11 -0
  96. package/dist/tooling/migrate/sql-lex.d.ts +22 -0
  97. package/dist/tooling/testing/factories.d.ts +10 -0
  98. package/dist/tooling/testing/facts.d.ts +3 -0
  99. package/dist/tooling/testing/index.js +3 -3
  100. package/dist/tooling/testing/isolation.d.ts +4 -3
  101. package/package.json +6 -5
  102. package/dist/shared/0v1g424p.js +0 -26
@@ -3,10 +3,10 @@ import {
3
3
  } from "../../shared/9m80mkac.js";
4
4
  import {
5
5
  addSchemaHook
6
- } from "../../shared/3p4b1fg0.js";
6
+ } from "../../shared/5enne4ma.js";
7
7
  import {
8
8
  queryHandle
9
- } from "../../shared/kkzwp3d2.js";
9
+ } from "../../shared/hf22e0wt.js";
10
10
  import {
11
11
  OkmError2
12
12
  } from "../../shared/52szzakm.js";
@@ -14,7 +14,7 @@ import {
14
14
  // src/runtime/validate/load.ts
15
15
  var engine;
16
16
  function loadEngine() {
17
- engine ??= import("../../shared/c8aghh05.js");
17
+ engine ??= import("../../shared/8rsy3hxz.js");
18
18
  return engine;
19
19
  }
20
20
 
@@ -12,16 +12,14 @@ import {
12
12
  indexes,
13
13
  quote,
14
14
  isRecord,
15
+ effectivePredicate,
15
16
  registerFailFix,
16
17
  fail
17
- } from "./xrfnq5k8.js";
18
+ } from "./gbtcc2d7.js";
18
19
  import {
19
20
  safetyInstalled,
20
21
  runSafety
21
22
  } from "./a5sxz52y.js";
22
- import {
23
- isOperator
24
- } from "./cn0n68ft.js";
25
23
  import {
26
24
  OkmError2
27
25
  } from "./52szzakm.js";
@@ -362,11 +360,9 @@ function requireFilter(table, where, mods, op) {
362
360
  }
363
361
  return;
364
362
  }
365
- if (isOperator(where))
366
- return;
367
- if (isRecord(where) && Object.keys(where).length > 0)
368
- return;
369
- fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
363
+ if (!effectivePredicate(where)) {
364
+ fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
365
+ }
370
366
  }
371
367
  function callOptions(input) {
372
368
  const signal = input.signal;
@@ -1,21 +1,23 @@
1
1
  import {
2
2
  open2
3
- } from "./wqem4jed.js";
4
- import"./8jb4ymh2.js";
3
+ } from "./krxx77g0.js";
4
+ import"./8bwbwy8h.js";
5
5
  import {
6
6
  createdOf,
7
7
  testing2
8
- } from "./ygem90rn.js";
8
+ } from "./v36c5g6p.js";
9
9
  import"./n442h54c.js";
10
10
  import {
11
- assertTargetPolicy,
12
- assertDirectConnection,
13
- selectTarget,
14
11
  loadConfig,
15
12
  loadSchema
16
- } from "./q6zsyh31.js";
17
- import"./n5y9zyj1.js";
18
- import"./41kv2xdm.js";
13
+ } from "./qv2ydck9.js";
14
+ import {
15
+ assertTargetPolicy,
16
+ assertDirectConnection,
17
+ assertStableBackend,
18
+ selectTarget
19
+ } from "./ga3sfy93.js";
20
+ import"./8xsbagad.js";
19
21
  import {
20
22
  OkmError2
21
23
  } from "./52szzakm.js";
@@ -34,9 +36,22 @@ async function seedProject(cwd, file, flags) {
34
36
  fix: { summary: "Pass okm seed <file> a module in this project." }
35
37
  });
36
38
  }
37
- assertDirectConnection(target.url, flags.allowPooler || config.allowPooler === true);
39
+ const allowPooler = flags.allowPooler || config.allowPooler === true;
40
+ assertDirectConnection(target.url, allowPooler);
38
41
  const schema = await loadSchema(cwd, config.schema);
39
42
  const pool = open2({ url: target.url, max: 1 });
43
+ const held = await pool.reserve?.();
44
+ if (held !== undefined) {
45
+ try {
46
+ await assertStableBackend(async () => {
47
+ const result = await held.execute("select pg_backend_pid()::text");
48
+ const cell = result.rows[0]?.[0];
49
+ return cell === null || cell === undefined ? "" : String(cell);
50
+ }, allowPooler);
51
+ } finally {
52
+ await held.release();
53
+ }
54
+ }
40
55
  const harness = await testing2(schema, { driver: pool, migrate: false });
41
56
  try {
42
57
  const imported = await import(`${pathToFileURL(path).href}?okm=${Date.now()}`);
@@ -75,7 +75,7 @@ function mapDriverError2(error, batchIndex) {
75
75
  if (error instanceof DriverError2) {
76
76
  return batchIndex === undefined ? error : error.at(batchIndex);
77
77
  }
78
- const message = error instanceof Error ? error.message : "driver error";
78
+ const message = messageOf(error);
79
79
  return new DriverError2(message, driverFields({
80
80
  sqlstate: sqlstateOf(error),
81
81
  constraint: errorField2(error, "constraint_name") ?? errorField2(error, "constraint"),
@@ -86,6 +86,14 @@ function mapDriverError2(error, batchIndex) {
86
86
  batchIndex
87
87
  }));
88
88
  }
89
+ function messageOf(error) {
90
+ if (!(error instanceof Error))
91
+ return "driver error";
92
+ if (error.message.length > 0)
93
+ return error.message;
94
+ const first = error.errors?.[0];
95
+ return first instanceof Error && first.message.length > 0 ? first.message : "driver error";
96
+ }
89
97
  function driverFields(input) {
90
98
  const fields = {};
91
99
  if (input.sqlstate !== undefined)
@@ -9,7 +9,7 @@ import {
9
9
  isRecord,
10
10
  registerFailFix,
11
11
  fail
12
- } from "./xrfnq5k8.js";
12
+ } from "./gbtcc2d7.js";
13
13
  import {
14
14
  throwNamed2
15
15
  } from "./52szzakm.js";
@@ -18,7 +18,7 @@ import {
18
18
  registerFailFix("OKM1104", "Set on to the columns of a unique constraint or the primary key.");
19
19
  registerFailFix("OKM1190", "Remove the guarded field. Input cannot set it.");
20
20
  var NO_ALLOW = new Set;
21
- function readConflict(table, value, allow = NO_ALLOW) {
21
+ function readConflict(table, value, allow = NO_ALLOW, tenantKey) {
22
22
  if (value === undefined || value === "error")
23
23
  return;
24
24
  if (value === "ignore")
@@ -34,13 +34,13 @@ function readConflict(table, value, allow = NO_ALLOW) {
34
34
  }
35
35
  if (ret === true) {
36
36
  rejectConflictKeys(keys, ["on", "return"]);
37
- return { kind: "return", columns: uniqueColumns(table, value.on), update: [] };
37
+ return { kind: "return", columns: uniqueColumns(table, value.on, tenantKey), update: [] };
38
38
  }
39
39
  if (update !== undefined) {
40
40
  rejectConflictKeys(keys, ["on", "update"]);
41
41
  return {
42
42
  kind: "update",
43
- columns: uniqueColumns(table, value.on),
43
+ columns: uniqueColumns(table, value.on, tenantKey),
44
44
  update: updateColumns(table, update, allow)
45
45
  };
46
46
  }
@@ -110,7 +110,7 @@ function samePrimary(table, columns) {
110
110
  }
111
111
  return true;
112
112
  }
113
- function uniqueColumns(table, on) {
113
+ function uniqueColumns(table, on, tenantKey) {
114
114
  const names = conflictNames(on);
115
115
  for (const unique of table.model.uniques) {
116
116
  if (!same(unique, names))
@@ -125,8 +125,19 @@ function uniqueColumns(table, on) {
125
125
  }
126
126
  return columns;
127
127
  }
128
- const accepted = table.model.uniques.map((fields) => fields.join(", "));
129
- throwNamed2("OKM1104", names.join(", "), accepted, `onConflict on ${table.model.name} names ${names.join(", ")}, which is not a unique constraint. Accepted: ${list(accepted)}.`);
128
+ const accepted = acceptedConstraints(table.model, tenantKey);
129
+ const implicit = tenantKey === undefined ? "" : ` The tenant key ${tenantKey} is part of each one and is not named here.`;
130
+ throwNamed2("OKM1104", names.join(", "), accepted, `onConflict on ${table.model.name} names ${names.join(", ")}, which is not a unique constraint. Accepted: ${list(accepted)}.${implicit}`);
131
+ }
132
+ function acceptedConstraints(model, key) {
133
+ const shown = new Set;
134
+ for (const fields of model.uniques) {
135
+ const named = key === undefined ? fields : fields.filter((field) => field !== key);
136
+ if (named.length === 0)
137
+ continue;
138
+ shown.add(named.length > 1 ? `(${named.join(", ")})` : named.join(""));
139
+ }
140
+ return [...shown];
130
141
  }
131
142
  function updateColumns(table, value, allow) {
132
143
  if (!Array.isArray(value) || value.length === 0) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  withHttp,
3
3
  attachHttp
4
- } from "./kkzwp3d2.js";
4
+ } from "./hf22e0wt.js";
5
5
  import {
6
6
  OkmError2
7
7
  } from "./52szzakm.js";
@@ -31,7 +31,7 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
31
31
  }));
32
32
  }
33
33
  } else {
34
- const { assertCompatible } = await import("./q795afwa.js");
34
+ const { assertCompatible } = await import("./z2rnngj4.js");
35
35
  try {
36
36
  await assertCompatible(pool, schema, recorded, source, options);
37
37
  } catch (error) {
@@ -4,7 +4,7 @@ import {
4
4
  nextTransactionDepth,
5
5
  EMPTY_NOTICES,
6
6
  resultFrom
7
- } from "./rrstp3kb.js";
7
+ } from "./cgbamx3e.js";
8
8
 
9
9
  // src/adapters/pg/session.ts
10
10
  function quoteIdent2(name) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isConnectionSqlstate,
3
3
  isConnectionFailure
4
- } from "./tbszx8mz.js";
4
+ } from "./pf0d8f77.js";
5
5
  import {
6
6
  OkmError2,
7
7
  stripRowValues,
@@ -16,12 +16,14 @@ function mapPostgresError(error, options) {
16
16
  return OkmError2.from(error);
17
17
  const kind = kindOf(error);
18
18
  const columns = columnsOf(error);
19
- const fieldReason = kind === "not_null" ? "not_null" : reasonOf(kind, error.table, error.constraint);
19
+ const hint = hintOf(error, kind);
20
+ const fieldReason = hint?.reason ?? (kind === "not_null" ? "not_null" : reasonOf(kind, error.table, error.constraint));
20
21
  const values = options?.includeValues === true ? valuesOf(error.detail, columns) : undefined;
21
22
  const code = kind === "outcome_unknown" ? "OKM1401" : kind;
22
23
  return new OkmError2(code, summaryOf(kind, error, columns, fieldReason), {
23
24
  kind,
24
25
  fieldReason,
26
+ ...hint !== undefined ? { fix: hint.fix } : {},
25
27
  ...error.table !== undefined ? { table: error.table } : {},
26
28
  ...columns.length > 0 ? { columns } : {},
27
29
  ...error.constraint !== undefined ? { constraint: error.constraint } : {},
@@ -32,6 +34,12 @@ function mapPostgresError(error, options) {
32
34
  ...options?.http !== undefined ? { http: options.http } : {}
33
35
  });
34
36
  }
37
+ var TLS_CODE = /^(ERR_TLS_|ERR_POSTGRES_TLS_|SELF_SIGNED_CERT_|DEPTH_ZERO_SELF_SIGNED_CERT$|UNABLE_TO_VERIFY_LEAF_SIGNATURE$)/;
38
+ function isTlsFailure(error) {
39
+ const cause = error.cause;
40
+ const code = typeof cause === "object" && cause !== null ? Reflect.get(cause, "code") : undefined;
41
+ return typeof code === "string" && TLS_CODE.test(code);
42
+ }
35
43
  function isDriverError(error) {
36
44
  if (!(error instanceof Error) || error.name !== "DriverError")
37
45
  return false;
@@ -47,10 +55,26 @@ function kindOf(error) {
47
55
  if (mapped !== undefined)
48
56
  return mapped;
49
57
  }
50
- if (isConnectionFailure(error))
58
+ if (isTlsFailure(error) || isConnectionFailure(error))
51
59
  return "unavailable";
52
60
  return "driver";
53
61
  }
62
+ var MIGRATE_FIX = {
63
+ summary: "Run okm migrate apply so the object exists, then check okm migrate status. The reason names the missing object."
64
+ };
65
+ var TLS_FIX = {
66
+ summary: "Check sslmode in the connection URL against the server certificate: use require, verify-ca, or verify-full with the CA the certificate chains to. For node-postgres, add uselibpqcompat=true so sslmode follows libpq."
67
+ };
68
+ function hintOf(error, kind) {
69
+ if (error.sqlstate === "42P01")
70
+ return { reason: "undefined_table", fix: MIGRATE_FIX };
71
+ if (error.sqlstate === "42703")
72
+ return { reason: "undefined_column", fix: MIGRATE_FIX };
73
+ if (kind === "unavailable" && error.sqlstate === undefined && isTlsFailure(error)) {
74
+ return { reason: "tls", fix: TLS_FIX };
75
+ }
76
+ return;
77
+ }
54
78
  function kindFromSqlstate(sqlstate) {
55
79
  switch (sqlstate) {
56
80
  case "23505":
@@ -1,4 +1,22 @@
1
1
  // src/adapters/pg/watch.ts
2
+ var callers = new WeakMap;
3
+ function listenOn(signal, onAbort) {
4
+ let set = callers.get(signal);
5
+ if (set === undefined) {
6
+ const created = new Set;
7
+ callers.set(signal, created);
8
+ signal.addEventListener("abort", () => {
9
+ for (const each of created)
10
+ each();
11
+ }, { once: true });
12
+ set = created;
13
+ }
14
+ const registered = set;
15
+ registered.add(onAbort);
16
+ return () => {
17
+ registered.delete(onAbort);
18
+ };
19
+ }
2
20
  function openWatch(options) {
3
21
  let kind;
4
22
  const controller = new AbortController;
@@ -7,7 +25,7 @@ function openWatch(options) {
7
25
  kind = "cancelled";
8
26
  controller.abort();
9
27
  };
10
- options.signal?.addEventListener("abort", onAbort, { once: true });
28
+ const release = options.signal === undefined ? undefined : listenOn(options.signal, onAbort);
11
29
  let timer;
12
30
  if (options.timeout !== undefined) {
13
31
  timer = setTimeout(() => {
@@ -21,7 +39,7 @@ function openWatch(options) {
21
39
  finish() {
22
40
  if (timer !== undefined)
23
41
  clearTimeout(timer);
24
- options.signal?.removeEventListener("abort", onAbort);
42
+ release?.();
25
43
  },
26
44
  reason() {
27
45
  return kind;
@@ -7,7 +7,7 @@ import {
7
7
  snakeCase,
8
8
  emittedTypeName,
9
9
  rejectLater
10
- } from "./jsd07prz.js";
10
+ } from "./ntneex2a.js";
11
11
  import {
12
12
  withLocation
13
13
  } from "./k7dwkhvq.js";
@@ -4,9 +4,11 @@ import {
4
4
  renameTable2,
5
5
  serializeCatalog2,
6
6
  catalogHash2,
7
+ startupCatalog2,
8
+ startupHash2,
7
9
  loadTrustedCatalog2,
8
10
  parseCatalog2
9
- } from "./8jb4ymh2.js";
11
+ } from "./8bwbwy8h.js";
10
12
  export {
11
13
  catalogHash2 as catalogHash,
12
14
  creationOrder2 as creationOrder,
@@ -14,5 +16,7 @@ export {
14
16
  parseCatalog2 as parseCatalog,
15
17
  renameColumn2 as renameColumn,
16
18
  renameTable2 as renameTable,
17
- serializeCatalog2 as serializeCatalog
19
+ serializeCatalog2 as serializeCatalog,
20
+ startupCatalog2 as startupCatalog,
21
+ startupHash2 as startupHash
18
22
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  open2
3
- } from "./wqem4jed.js";
4
- import"./8jb4ymh2.js";
3
+ } from "./krxx77g0.js";
4
+ import"./8bwbwy8h.js";
5
5
  import"./n442h54c.js";
6
6
  import {
7
7
  CURRENT,
@@ -15,14 +15,17 @@ import {
15
15
  loadMigrations,
16
16
  expandProvisioned,
17
17
  provisionHistoryIsKnown
18
- } from "./7nk68fj8.js";
18
+ } from "./gde73es6.js";
19
+ import"./szm0cksa.js";
20
+ import"./fancm5pt.js";
19
21
  import {
20
- assertTargetPolicy,
21
- listTargets,
22
22
  loadConfig
23
- } from "./q6zsyh31.js";
24
- import"./n5y9zyj1.js";
25
- import"./41kv2xdm.js";
23
+ } from "./qv2ydck9.js";
24
+ import {
25
+ assertTargetPolicy,
26
+ listTargets
27
+ } from "./ga3sfy93.js";
28
+ import"./8xsbagad.js";
26
29
  import {
27
30
  OkmError2
28
31
  } from "./52szzakm.js";
@@ -2,10 +2,11 @@ import {
2
2
  assertAuthorDrift2,
3
3
  catalogQuery2,
4
4
  managedRoleOptions2
5
- } from "./xghkt7a9.js";
6
- import"./n5y9zyj1.js";
7
- import"./41kv2xdm.js";
8
- import"./8jb4ymh2.js";
5
+ } from "./sycnx8gt.js";
6
+ import"./fancm5pt.js";
7
+ import"./ga3sfy93.js";
8
+ import"./8xsbagad.js";
9
+ import"./8bwbwy8h.js";
9
10
  export {
10
11
  assertAuthorDrift2 as assertAuthorDrift,
11
12
  catalogQuery2 as catalogQuery,
@@ -3,7 +3,7 @@ import {
3
3
  readHandle,
4
4
  readCall,
5
5
  attachHttp
6
- } from "./kkzwp3d2.js";
6
+ } from "./hf22e0wt.js";
7
7
  import {
8
8
  selectedColumns,
9
9
  parseOrder,
@@ -15,7 +15,7 @@ import {
15
15
  isRecord,
16
16
  registerFailFix,
17
17
  fail
18
- } from "./xrfnq5k8.js";
18
+ } from "./gbtcc2d7.js";
19
19
  import {
20
20
  OkmError2,
21
21
  throwNamed2
@@ -30,6 +30,7 @@ var OPTIONS = [
30
30
  "limit",
31
31
  "include",
32
32
  "after",
33
+ "route",
33
34
  "signal",
34
35
  "timeout"
35
36
  ];
@@ -69,7 +70,8 @@ function plan(session, table, options, mods, view) {
69
70
  limit: size + 1,
70
71
  include: record.include,
71
72
  signal: record.signal,
72
- timeout: record.timeout
73
+ timeout: record.timeout,
74
+ route: record.route
73
75
  }, undefined, session.scope, session.schema.model[table], session.schema, view),
74
76
  ...after !== undefined ? { after } : {}
75
77
  };
@@ -1,40 +1,45 @@
1
1
  import {
2
2
  parseCatalog2
3
- } from "./8jb4ymh2.js";
4
- import"./wqem4jed.js";
3
+ } from "./8bwbwy8h.js";
4
+ import"./krxx77g0.js";
5
5
  import"./n442h54c.js";
6
6
  import {
7
7
  applyTarget2,
8
8
  backfillTiming2
9
- } from "./s4mb6a4b.js";
9
+ } from "./cctw17hj.js";
10
10
  import {
11
- introspectSchema,
12
11
  sealViews,
13
12
  catalogQuery2,
14
13
  managedRoleOptions2
15
- } from "./xghkt7a9.js";
14
+ } from "./sycnx8gt.js";
16
15
  import {
17
16
  loadMigrations,
18
17
  catalogsEqual,
19
18
  snapshotDifference
20
- } from "./7nk68fj8.js";
19
+ } from "./gde73es6.js";
20
+ import"./szm0cksa.js";
21
+ import {
22
+ introspectSchema
23
+ } from "./fancm5pt.js";
21
24
  import {
22
25
  lintMigrationDirectory,
23
26
  hasError,
24
27
  lintRefusal,
25
- selectTarget,
26
28
  openProject
27
- } from "./q6zsyh31.js";
29
+ } from "./qv2ydck9.js";
28
30
  import {
29
31
  canonicalTypeName,
30
32
  classOf,
31
33
  strictestClass,
32
34
  planMigration,
33
- parsePlan
34
- } from "./n5y9zyj1.js";
35
+ parsePlan,
36
+ assertDirectConnection,
37
+ assertStableBackend,
38
+ selectTarget
39
+ } from "./ga3sfy93.js";
35
40
  import {
36
41
  quoteIdent
37
- } from "./41kv2xdm.js";
42
+ } from "./8xsbagad.js";
38
43
  import {
39
44
  catalog,
40
45
  isDomain
@@ -61,6 +66,8 @@ var STALE_FIX = "Run okm generate.";
61
66
  async function checkMigrations(cwd, flags, options) {
62
67
  const opened = await openProject(cwd);
63
68
  const target = selectTarget(opened.config, flags.target);
69
+ const allowPooler = flags.allowPooler || opened.config.allowPooler === true;
70
+ assertDirectConnection(target.url, allowPooler);
64
71
  if (target.protected) {
65
72
  throw new OkmError2("OKM1850", `okm migrate check writes a scratch schema and refuses protected target ${target.name}. Point it at a throwaway Postgres.`, {
66
73
  kind: "forbidden",
@@ -177,6 +184,7 @@ async function proveSnapshot(config, url, target, flags, history) {
177
184
  idle_timeout: 1,
178
185
  onnotice: () => {}
179
186
  });
187
+ const allowPooler = flags.allowPooler || config.allowPooler === true;
180
188
  const provided = `${CHECK_SCHEMA_PREFIX}p${crypto.randomUUID().replaceAll("-", "")}`;
181
189
  const replayed = `${CHECK_SCHEMA_PREFIX}r${crypto.randomUUID().replaceAll("-", "")}`;
182
190
  const timing = {
@@ -185,6 +193,10 @@ async function proveSnapshot(config, url, target, flags, history) {
185
193
  ...backfillTiming2(config.backfill)
186
194
  };
187
195
  try {
196
+ await assertStableBackend(async () => {
197
+ const rows = await sql`select pg_backend_pid()::text as pid`;
198
+ return rows[0]?.pid ?? "";
199
+ }, allowPooler);
188
200
  await sql.unsafe(`create schema ${quoteIdent(provided)}`);
189
201
  await sql.unsafe(`create schema ${quoteIdent(replayed)}`);
190
202
  const role = config.roles === undefined ? {} : { migrationRole: config.roles.migration, schema: provided };
@@ -225,9 +237,8 @@ async function proveSnapshot(config, url, target, flags, history) {
225
237
  })),
226
238
  ...config.roles !== undefined ? { migrationRole: config.roles.migration, schema: replayed } : {}
227
239
  });
228
- const runner = catalogQuery2(sql);
229
- const liveProvided = await introspectSchema(runner, provided, "public", managedRoleOptions2(config.roles));
230
- const liveReplayed = await introspectSchema(runner, replayed, "public", managedRoleOptions2(config.roles));
240
+ const liveProvided = await introspectScratch(sql, provided, config);
241
+ const liveReplayed = await introspectScratch(sql, replayed, config);
231
242
  const difference = snapshotDifference(liveProvided, liveReplayed);
232
243
  if (difference === undefined)
233
244
  return;
@@ -256,9 +267,14 @@ async function replayHistory(config, url, target, flags, history) {
256
267
  idle_timeout: 1,
257
268
  onnotice: () => {}
258
269
  });
270
+ const allowPooler = flags.allowPooler || config.allowPooler === true;
259
271
  const scratch = `${CHECK_SCHEMA_PREFIX}${crypto.randomUUID().replaceAll("-", "")}`;
260
272
  const failures = [];
261
273
  try {
274
+ await assertStableBackend(async () => {
275
+ const rows = await sql`select pg_backend_pid()::text as pid`;
276
+ return rows[0]?.pid ?? "";
277
+ }, allowPooler);
262
278
  await sql.unsafe(`create schema ${quoteIdent(scratch)}`);
263
279
  const runner = catalogQuery2(sql);
264
280
  for (let index = 0;index < history.length; index += 1) {
@@ -284,7 +300,7 @@ async function replayHistory(config, url, target, flags, history) {
284
300
  ],
285
301
  ...config.roles !== undefined ? { migrationRole: config.roles.migration, schema: scratch } : {}
286
302
  });
287
- const live = await introspectSchema(runner, scratch, "public", managedRoleOptions2(config.roles));
303
+ const live = await introspectScratch(sql, scratch, config);
288
304
  const sealed = await sealViews(runner, migration.catalog);
289
305
  const back = planMigration({ before: live, after: sealed, name: migration.id });
290
306
  if (back.steps.length === 0)
@@ -300,6 +316,18 @@ async function replayHistory(config, url, target, flags, history) {
300
316
  }
301
317
  return failures;
302
318
  }
319
+ async function introspectScratch(sql, schema, config) {
320
+ const previous = await sql`select current_setting('search_path') as path`;
321
+ const saved = previous[0]?.path ?? "public";
322
+ try {
323
+ await sql.unsafe(`set search_path to ${quoteIdent(schema)}`);
324
+ return await introspectSchema(catalogQuery2(sql), schema, "public", managedRoleOptions2(config.roles));
325
+ } finally {
326
+ await sql`select set_config('search_path', ${saved}, false)`.catch(() => {
327
+ return;
328
+ });
329
+ }
330
+ }
303
331
  function historyFailure(history, index, back) {
304
332
  const migration = history[index];
305
333
  const id = migration?.id ?? "migration";
@@ -349,9 +377,11 @@ function sameSql(planned, file) {
349
377
  function retargetSteps(steps, schema) {
350
378
  const from = `${quoteIdent("public")}.`;
351
379
  const to = `${quoteIdent(schema)}.`;
380
+ const fromDefaults = `in schema ${quoteIdent("public")} `;
381
+ const toDefaults = `in schema ${quoteIdent(schema)} `;
352
382
  return steps.map((step) => ({
353
383
  ...step,
354
- sql: step.sql.replaceAll(from, to),
384
+ sql: step.sql.replaceAll(from, to).replaceAll(fromDefaults, toDefaults),
355
385
  ...step.backfill === undefined ? {} : { backfill: { ...step.backfill, table: step.backfill.table.replaceAll(from, to) } }
356
386
  }));
357
387
  }
@@ -9,7 +9,7 @@ import {
9
9
  runCall,
10
10
  EMPTY_NOTICES,
11
11
  resultFrom
12
- } from "./rrstp3kb.js";
12
+ } from "./cgbamx3e.js";
13
13
 
14
14
  // src/adapters/pg/pglite.ts
15
15
  import { PGlite } from "@electric-sql/pglite";
@@ -48,7 +48,7 @@ async function open3(config = {}) {
48
48
  return {
49
49
  execute: (text, params, options) => runCall(closed, options, (watch) => session.query(text, params, watch)),
50
50
  batch: (statements, options) => runCall(closed, options, async (watch) => {
51
- const { runAtomicBatch } = await import("./b066g80h.js");
51
+ const { runAtomicBatch } = await import("./efmy2gcg.js");
52
52
  return runAtomicBatch(session, statements, watch);
53
53
  }),
54
54
  async release() {
@@ -229,6 +229,17 @@ function catalogHash2(source) {
229
229
  serializedHash.set(source, hash);
230
230
  return hash;
231
231
  }
232
+ function startupCatalog2(source) {
233
+ if (!source.objects.some(isPrivilege))
234
+ return source;
235
+ return { version: source.version, objects: source.objects.filter((item) => !isPrivilege(item)) };
236
+ }
237
+ function startupHash2(source) {
238
+ return catalogHash2(startupCatalog2(source));
239
+ }
240
+ function isPrivilege(object) {
241
+ return object.kind === "role" || object.kind === "grant" || object.kind === "defaultPrivilege";
242
+ }
232
243
  function loadTrustedCatalog2(text, hash) {
233
244
  if (sha2562(text) !== hash) {
234
245
  catalogError2("OKM1027", "Catalog hash does not match the build artifact.");
@@ -1444,4 +1455,4 @@ function assertNeverKind(value) {
1444
1455
  return catalogError2("OKM1020", `Unexpected kind ${JSON.stringify(value)}.`);
1445
1456
  }
1446
1457
 
1447
- export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, loadTrustedCatalog2, parseCatalog2 };
1458
+ export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, startupCatalog2, startupHash2, loadTrustedCatalog2, parseCatalog2 };
@@ -422,6 +422,12 @@ function isRecord(value) {
422
422
  function failShape(message) {
423
423
  throw new OkmError2("OKM1121", message, { kind: "invalid" });
424
424
  }
425
+ function failedMessage(first) {
426
+ if (first === undefined)
427
+ return "Validation failed.";
428
+ const field = first.path.length === 0 ? "$row" : first.path.join(".");
429
+ return `Validation failed: ${field} ${first.message}`;
430
+ }
425
431
  function throwIssues(issues) {
426
432
  const columns = [];
427
433
  for (const issue of issues) {
@@ -429,7 +435,7 @@ function throwIssues(issues) {
429
435
  if (typeof field === "string" && !columns.includes(field))
430
436
  columns.push(field);
431
437
  }
432
- throw new OkmError2("OKM1200", "Validation failed.", {
438
+ throw new OkmError2("OKM1200", failedMessage(issues[0]), {
433
439
  kind: "invalid",
434
440
  ...columns.length > 0 ? { columns } : {},
435
441
  issues,