okmodel 0.5.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 (80) hide show
  1. package/README.md +9 -6
  2. package/dist/dialects/pg/filter-parse.d.ts +8 -2
  3. package/dist/dialects/pg/fn/index.js +8 -0
  4. package/dist/dialects/pg/index.js +8 -2
  5. package/dist/dialects/pg/ops/or.d.ts +1 -1
  6. package/dist/dialects/pg/temporal.d.ts +5 -76
  7. package/dist/dialects/pg/view/index.js +1 -1
  8. package/dist/runtime/client.d.ts +6 -1
  9. package/dist/runtime/conflict.d.ts +2 -1
  10. package/dist/runtime/pg/bun.js +5 -5
  11. package/dist/runtime/pg/pg.js +5 -5
  12. package/dist/runtime/pg/pglite.js +5 -5
  13. package/dist/runtime/pg/postgresjs.js +5 -5
  14. package/dist/runtime/plan.d.ts +13 -0
  15. package/dist/runtime/tenancy/index.js +1 -1
  16. package/dist/runtime/traits/index.js +4 -4
  17. package/dist/runtime/validate/index.js +3 -3
  18. package/dist/shared/{ckjbyrt9.js → 0t22wwh1.js} +5 -9
  19. package/dist/shared/{jdgqqx31.js → 2pqx26h8.js} +23 -8
  20. package/dist/shared/{kyxb62mc.js → 31vm914h.js} +9 -1
  21. package/dist/shared/{9tgmr1gh.js → 32zqc1dw.js} +18 -7
  22. package/dist/shared/{47xzb9fc.js → 47x8x9ze.js} +1 -1
  23. package/dist/shared/{zvbjc949.js → 4az561fn.js} +1 -1
  24. package/dist/shared/{s6gqfn5j.js → 51mvgj8w.js} +27 -3
  25. package/dist/shared/{k3ted12y.js → 54tqkxja.js} +20 -2
  26. package/dist/shared/{3p4b1fg0.js → 5enne4ma.js} +1 -1
  27. package/dist/shared/{bzsjtd7c.js → 6mnp99hx.js} +7 -6
  28. package/dist/shared/{ykv7wh5b.js → 6qd27mx0.js} +2 -2
  29. package/dist/shared/{h4nqvjkp.js → 6rk2gen5.js} +2 -2
  30. package/dist/shared/{r73pt594.js → 7zwwyh0v.js} +32 -10
  31. package/dist/shared/{fa9vt245.js → 87jvvhnt.js} +2 -2
  32. package/dist/shared/{c8aghh05.js → 8rsy3hxz.js} +7 -1
  33. package/dist/shared/{6p5k20sm.js → 96qcj21c.js} +3 -3
  34. package/dist/shared/{xsq7v6wp.js → aj2qxyhj.js} +2 -2
  35. package/dist/shared/{5vdm4sgp.js → caw8b9d8.js} +4 -4
  36. package/dist/shared/{xhh1srw3.js → cctw17hj.js} +23 -8
  37. package/dist/shared/{rrstp3kb.js → cgbamx3e.js} +2 -2
  38. package/dist/shared/{tq9afp8d.js → cr74e96e.js} +1 -1
  39. package/dist/shared/{b066g80h.js → efmy2gcg.js} +2 -2
  40. package/dist/shared/{gdh9mrtp.js → f5cw5q5r.js} +2 -2
  41. package/dist/shared/{ayz64vzj.js → ga3sfy93.js} +357 -3
  42. package/dist/shared/{qgvt8nx1.js → gbtcc2d7.js} +44 -3
  43. package/dist/shared/{kdkxh3kb.js → gde73es6.js} +5 -7
  44. package/dist/shared/{bt9sfq0z.js → hf22e0wt.js} +51 -17
  45. package/dist/shared/{990a291j.js → janx09m5.js} +6 -5
  46. package/dist/shared/{4ef7mmqf.js → jwtxdj06.js} +5 -5
  47. package/dist/shared/{sf8m6tfy.js → k8v5v5wj.js} +3 -3
  48. package/dist/shared/{r6pj4fq2.js → kfjp0gck.js} +2 -2
  49. package/dist/shared/{wqem4jed.js → krxx77g0.js} +7 -7
  50. package/dist/shared/{h8ne16fq.js → nkaxvt9q.js} +1 -1
  51. package/dist/shared/{jsd07prz.js → ntneex2a.js} +1 -1
  52. package/dist/shared/{nkc9sfqb.js → nxdp2ze3.js} +40 -4
  53. package/dist/shared/{tbszx8mz.js → pf0d8f77.js} +1 -1
  54. package/dist/shared/{qy9rdq0g.js → ps7a6h14.js} +6 -6
  55. package/dist/shared/{rasvvzgz.js → q58y17hy.js} +5 -5
  56. package/dist/shared/{p7pfx624.js → qm7cdtvr.js} +22 -9
  57. package/dist/shared/{xdpj5kkm.js → qv2ydck9.js} +149 -209
  58. package/dist/shared/{k7cc9nzk.js → r2sp8hrc.js} +6 -3
  59. package/dist/shared/{fb00y8fp.js → r8x5qhd7.js} +5 -5
  60. package/dist/shared/{fyqkk1m0.js → sdc7r2ww.js} +6 -5
  61. package/dist/shared/{wxn4b7pp.js → sycnx8gt.js} +42 -5
  62. package/dist/shared/{dxjp14rk.js → tm5ab8we.js} +2 -2
  63. package/dist/shared/{g516zdsb.js → v36c5g6p.js} +78 -19
  64. package/dist/shared/wq9n6pwr.js +139 -0
  65. package/dist/shared/{7p2wbz7f.js → x72jb7ad.js} +1 -1
  66. package/dist/shared/{922qbgnw.js → zqrnhwsq.js} +3 -3
  67. package/dist/tooling/cli.js +68 -21
  68. package/dist/tooling/migrate/commands.d.ts +1 -2
  69. package/dist/tooling/migrate/drift.d.ts +1 -1
  70. package/dist/tooling/migrate/estimate.d.ts +14 -1
  71. package/dist/tooling/migrate/index.js +8 -7
  72. package/dist/tooling/migrate/lint.d.ts +3 -3
  73. package/dist/tooling/migrate/plan.d.ts +7 -3
  74. package/dist/tooling/migrate/policy.d.ts +11 -0
  75. package/dist/tooling/migrate/sql-lex.d.ts +22 -0
  76. package/dist/tooling/testing/factories.d.ts +10 -0
  77. package/dist/tooling/testing/index.js +1 -1
  78. package/dist/tooling/testing/isolation.d.ts +4 -3
  79. package/package.json +6 -5
  80. package/dist/shared/0v1g424p.js +0 -26
@@ -9,7 +9,7 @@ import {
9
9
  isRecord,
10
10
  registerFailFix,
11
11
  fail
12
- } from "./qgvt8nx1.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 "./bt9sfq0z.js";
4
+ } from "./hf22e0wt.js";
5
5
  import {
6
6
  OkmError2
7
7
  } from "./52szzakm.js";
@@ -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";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  open2
3
- } from "./wqem4jed.js";
3
+ } from "./krxx77g0.js";
4
4
  import"./8bwbwy8h.js";
5
5
  import"./n442h54c.js";
6
6
  import {
@@ -15,15 +15,16 @@ import {
15
15
  loadMigrations,
16
16
  expandProvisioned,
17
17
  provisionHistoryIsKnown
18
- } from "./kdkxh3kb.js";
18
+ } from "./gde73es6.js";
19
19
  import"./szm0cksa.js";
20
20
  import"./fancm5pt.js";
21
21
  import {
22
- assertTargetPolicy,
23
- listTargets,
24
22
  loadConfig
25
- } from "./xdpj5kkm.js";
26
- import"./ayz64vzj.js";
23
+ } from "./qv2ydck9.js";
24
+ import {
25
+ assertTargetPolicy,
26
+ listTargets
27
+ } from "./ga3sfy93.js";
27
28
  import"./8xsbagad.js";
28
29
  import {
29
30
  OkmError2
@@ -2,9 +2,9 @@ import {
2
2
  assertAuthorDrift2,
3
3
  catalogQuery2,
4
4
  managedRoleOptions2
5
- } from "./wxn4b7pp.js";
5
+ } from "./sycnx8gt.js";
6
6
  import"./fancm5pt.js";
7
- import"./ayz64vzj.js";
7
+ import"./ga3sfy93.js";
8
8
  import"./8xsbagad.js";
9
9
  import"./8bwbwy8h.js";
10
10
  export {
@@ -3,7 +3,7 @@ import {
3
3
  readHandle,
4
4
  readCall,
5
5
  attachHttp
6
- } from "./bt9sfq0z.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 "./qgvt8nx1.js";
18
+ } from "./gbtcc2d7.js";
19
19
  import {
20
20
  OkmError2,
21
21
  throwNamed2
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  parseCatalog2
3
3
  } from "./8bwbwy8h.js";
4
- import"./wqem4jed.js";
4
+ import"./krxx77g0.js";
5
5
  import"./n442h54c.js";
6
6
  import {
7
7
  applyTarget2,
8
8
  backfillTiming2
9
- } from "./xhh1srw3.js";
9
+ } from "./cctw17hj.js";
10
10
  import {
11
11
  sealViews,
12
12
  catalogQuery2,
13
13
  managedRoleOptions2
14
- } from "./wxn4b7pp.js";
14
+ } from "./sycnx8gt.js";
15
15
  import {
16
16
  loadMigrations,
17
17
  catalogsEqual,
18
18
  snapshotDifference
19
- } from "./kdkxh3kb.js";
19
+ } from "./gde73es6.js";
20
20
  import"./szm0cksa.js";
21
21
  import {
22
22
  introspectSchema
@@ -25,16 +25,18 @@ import {
25
25
  lintMigrationDirectory,
26
26
  hasError,
27
27
  lintRefusal,
28
- selectTarget,
29
28
  openProject
30
- } from "./xdpj5kkm.js";
29
+ } from "./qv2ydck9.js";
31
30
  import {
32
31
  canonicalTypeName,
33
32
  classOf,
34
33
  strictestClass,
35
34
  planMigration,
36
- parsePlan
37
- } from "./ayz64vzj.js";
35
+ parsePlan,
36
+ assertDirectConnection,
37
+ assertStableBackend,
38
+ selectTarget
39
+ } from "./ga3sfy93.js";
38
40
  import {
39
41
  quoteIdent
40
42
  } from "./8xsbagad.js";
@@ -64,6 +66,8 @@ var STALE_FIX = "Run okm generate.";
64
66
  async function checkMigrations(cwd, flags, options) {
65
67
  const opened = await openProject(cwd);
66
68
  const target = selectTarget(opened.config, flags.target);
69
+ const allowPooler = flags.allowPooler || opened.config.allowPooler === true;
70
+ assertDirectConnection(target.url, allowPooler);
67
71
  if (target.protected) {
68
72
  throw new OkmError2("OKM1850", `okm migrate check writes a scratch schema and refuses protected target ${target.name}. Point it at a throwaway Postgres.`, {
69
73
  kind: "forbidden",
@@ -180,6 +184,7 @@ async function proveSnapshot(config, url, target, flags, history) {
180
184
  idle_timeout: 1,
181
185
  onnotice: () => {}
182
186
  });
187
+ const allowPooler = flags.allowPooler || config.allowPooler === true;
183
188
  const provided = `${CHECK_SCHEMA_PREFIX}p${crypto.randomUUID().replaceAll("-", "")}`;
184
189
  const replayed = `${CHECK_SCHEMA_PREFIX}r${crypto.randomUUID().replaceAll("-", "")}`;
185
190
  const timing = {
@@ -188,6 +193,10 @@ async function proveSnapshot(config, url, target, flags, history) {
188
193
  ...backfillTiming2(config.backfill)
189
194
  };
190
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);
191
200
  await sql.unsafe(`create schema ${quoteIdent(provided)}`);
192
201
  await sql.unsafe(`create schema ${quoteIdent(replayed)}`);
193
202
  const role = config.roles === undefined ? {} : { migrationRole: config.roles.migration, schema: provided };
@@ -258,9 +267,14 @@ async function replayHistory(config, url, target, flags, history) {
258
267
  idle_timeout: 1,
259
268
  onnotice: () => {}
260
269
  });
270
+ const allowPooler = flags.allowPooler || config.allowPooler === true;
261
271
  const scratch = `${CHECK_SCHEMA_PREFIX}${crypto.randomUUID().replaceAll("-", "")}`;
262
272
  const failures = [];
263
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);
264
278
  await sql.unsafe(`create schema ${quoteIdent(scratch)}`);
265
279
  const runner = catalogQuery2(sql);
266
280
  for (let index = 0;index < history.length; index += 1) {
@@ -303,8 +317,16 @@ async function replayHistory(config, url, target, flags, history) {
303
317
  return failures;
304
318
  }
305
319
  async function introspectScratch(sql, schema, config) {
306
- await sql.unsafe(`set search_path to ${quoteIdent(schema)}`);
307
- return introspectSchema(catalogQuery2(sql), schema, "public", managedRoleOptions2(config.roles));
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
+ }
308
330
  }
309
331
  function historyFailure(history, index, back) {
310
332
  const migration = history[index];
@@ -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() {
@@ -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,
@@ -3,14 +3,14 @@ import {
3
3
  noticeBuffer,
4
4
  WireSession,
5
5
  cursorStream
6
- } from "./zvbjc949.js";
6
+ } from "./4az561fn.js";
7
7
  import {
8
8
  NODE_POSTGRES_CAPABILITIES,
9
9
  driverErrors,
10
10
  rejectClosed,
11
11
  mapFailure,
12
12
  runCall
13
- } from "./rrstp3kb.js";
13
+ } from "./cgbamx3e.js";
14
14
 
15
15
  // src/adapters/pg/nodepostgres.ts
16
16
  import net from "node:net";
@@ -53,7 +53,7 @@ function open4(config) {
53
53
  counters.busy = Math.max(0, counters.busy - 1);
54
54
  }, inflight);
55
55
  const held = { pool, acquireMs, counters, notices, named, isClosed };
56
- const checkout = () => closed ? rejectClosed() : import("./fb00y8fp.js").then((mod) => mod.checkout(held));
56
+ const checkout = () => closed ? rejectClosed() : import("./r8x5qhd7.js").then((mod) => mod.checkout(held));
57
57
  return {
58
58
  capabilities: NODE_POSTGRES_CAPABILITIES,
59
59
  execute(text, params, options) {
@@ -4,12 +4,12 @@ import {
4
4
  import {
5
5
  withHttp,
6
6
  settleCall
7
- } from "./bt9sfq0z.js";
7
+ } from "./hf22e0wt.js";
8
8
  import {
9
9
  rejectKeys,
10
10
  isRecord,
11
11
  fail
12
- } from "./qgvt8nx1.js";
12
+ } from "./gbtcc2d7.js";
13
13
  import {
14
14
  OkmError2
15
15
  } from "./52szzakm.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  PgSession
3
- } from "./wqem4jed.js";
3
+ } from "./krxx77g0.js";
4
4
  import {
5
5
  isConnectionLost
6
- } from "./tbszx8mz.js";
6
+ } from "./pf0d8f77.js";
7
7
  import {
8
8
  driverErrors,
9
9
  rejectClosed,
@@ -11,7 +11,7 @@ import {
11
11
  runCall,
12
12
  rowsFrom,
13
13
  resultFrom
14
- } from "./rrstp3kb.js";
14
+ } from "./cgbamx3e.js";
15
15
 
16
16
  // src/adapters/pg/postgres-extra.ts
17
17
  var RESET_ALL = "RESET ALL";
@@ -33,7 +33,7 @@ async function checkout(pool) {
33
33
  return {
34
34
  execute: (text, params, options) => guard(() => runCall(pool.isClosed(), options, (watch) => session.query(text, params, watch))),
35
35
  batch: (statements, options) => guard(() => runCall(pool.isClosed(), options, async (watch) => {
36
- const { runAtomicBatch } = await import("./b066g80h.js");
36
+ const { runAtomicBatch } = await import("./efmy2gcg.js");
37
37
  return runAtomicBatch(session, statements, watch);
38
38
  })),
39
39
  cancel() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  open2
3
- } from "./wqem4jed.js";
3
+ } from "./krxx77g0.js";
4
4
  import {
5
5
  startupHash2
6
6
  } from "./8bwbwy8h.js";
@@ -15,7 +15,7 @@ import {
15
15
  provisionMark,
16
16
  expandProvisioned,
17
17
  installSnapshot
18
- } from "./kdkxh3kb.js";
18
+ } from "./gde73es6.js";
19
19
  import {
20
20
  assertCreateRole,
21
21
  currentUser,
@@ -25,19 +25,20 @@ import {
25
25
  lintMigrationDirectory,
26
26
  hasError,
27
27
  lintRefusal,
28
- assertTargetPolicy,
29
- assertDirectConnection,
30
- selectTarget,
31
28
  projectHead,
32
29
  loadBuiltSchema,
33
30
  loadConfig
34
- } from "./xdpj5kkm.js";
31
+ } from "./qv2ydck9.js";
35
32
  import {
36
33
  changesRole,
37
34
  batchSizeField,
38
35
  assertExtensionsAvailable,
39
- planMigration
40
- } from "./ayz64vzj.js";
36
+ planMigration,
37
+ assertTargetPolicy,
38
+ assertDirectConnection,
39
+ assertStableBackend,
40
+ selectTarget
41
+ } from "./ga3sfy93.js";
41
42
  import {
42
43
  OkmError2
43
44
  } from "./52szzakm.js";
@@ -177,6 +178,8 @@ async function applyTarget2(request) {
177
178
  const connection = await pool.reserve();
178
179
  let locked = false;
179
180
  try {
181
+ await assertStableBackend(() => backendPid(connection), request.allowPooler === true);
182
+ await assertStandardStrings(connection);
180
183
  await setTimeouts(connection, request);
181
184
  await lockTarget(connection, request.target);
182
185
  locked = true;
@@ -379,6 +382,18 @@ select distinct id from history order by id`;
379
382
  function joinMigrations(cwd, migrations) {
380
383
  return join(cwd, migrations ?? "migrations");
381
384
  }
385
+ async function backendPid(connection) {
386
+ const result = await connection.execute("select pg_backend_pid()::text");
387
+ const cell = result.rows[0]?.[0];
388
+ return cell === null || cell === undefined ? "" : String(cell);
389
+ }
390
+ async function assertStandardStrings(connection) {
391
+ const result = await connection.execute("show standard_conforming_strings");
392
+ const value = result.rows[0]?.[0];
393
+ if (value === "on")
394
+ return;
395
+ throw new OkmError2("invalid", `standard_conforming_strings is ${value === null || value === undefined ? "off" : String(value)}. Apply refuses to run.`, { fix: { summary: "Turn standard_conforming_strings on for this database." } });
396
+ }
382
397
  async function setTimeouts(connection, request) {
383
398
  const lock = request.lockTimeoutMs ?? DEFAULT_LOCK_MS;
384
399
  const statement = request.statementTimeoutMs ?? DEFAULT_STATEMENT_MS;
@@ -41,7 +41,7 @@ function hasCapability2(flags, name) {
41
41
  // src/adapters/failure.ts
42
42
  var loading;
43
43
  function driverErrors() {
44
- loading ??= import("./7p2wbz7f.js");
44
+ loading ??= import("./x72jb7ad.js");
45
45
  return loading;
46
46
  }
47
47
  function rejectClosed(message = "The pool is closed.") {
@@ -83,7 +83,7 @@ function runCall(closed, options, fn) {
83
83
  if (options === undefined || !needsWatch(options))
84
84
  return fn(undefined);
85
85
  const watched = options;
86
- return import("./k3ted12y.js").then(({ openWatch }) => {
86
+ return import("./54tqkxja.js").then(({ openWatch }) => {
87
87
  const watch = openWatch(watched);
88
88
  return fn(watch).finally(() => {
89
89
  watch.finish();
@@ -11,7 +11,7 @@ import {
11
11
  quote,
12
12
  isRecord,
13
13
  fail
14
- } from "./qgvt8nx1.js";
14
+ } from "./gbtcc2d7.js";
15
15
  import {
16
16
  isOperator,
17
17
  operatorName,
@@ -2,10 +2,10 @@ import {
2
2
  DriverError2,
3
3
  outcomeUnknown2,
4
4
  mapDriverError2
5
- } from "./kyxb62mc.js";
5
+ } from "./31vm914h.js";
6
6
  import {
7
7
  isConnectionLost
8
- } from "./tbszx8mz.js";
8
+ } from "./pf0d8f77.js";
9
9
 
10
10
  // src/adapters/pg/batch.ts
11
11
  var savepointIds = 0;
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  open3
3
- } from "./fa9vt245.js";
3
+ } from "./87jvvhnt.js";
4
4
  import {
5
5
  PGLITE_CAPABILITIES,
6
6
  readCapability2,
7
7
  hasCapability2
8
- } from "./rrstp3kb.js";
8
+ } from "./cgbamx3e.js";
9
9
  export {
10
10
  PGLITE_CAPABILITIES as capabilities,
11
11
  hasCapability2 as hasCapability,