okmodel 0.3.0 → 0.5.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 (123) hide show
  1. package/README.md +263 -23
  2. package/dist/contracts/catalog/document.d.ts +26 -2
  3. package/dist/contracts/driver.d.ts +7 -0
  4. package/dist/dialects/pg/ext/citext.js +1 -1
  5. package/dist/dialects/pg/ext/index.js +1 -1
  6. package/dist/dialects/pg/ext/pg-trgm.js +1 -1
  7. package/dist/dialects/pg/index.js +3 -3
  8. package/dist/dialects/pg/introspect.d.ts +6 -0
  9. package/dist/dialects/pg/role/sql.d.ts +21 -4
  10. package/dist/dialects/pg/schema.d.ts +15 -6
  11. package/dist/dialects/pg/table.d.ts +17 -1
  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 -1
  15. package/dist/runtime/catalog-cache.d.ts +17 -0
  16. package/dist/runtime/compat-words.d.ts +23 -0
  17. package/dist/runtime/drift-detail.d.ts +20 -4
  18. package/dist/runtime/drift.d.ts +4 -2
  19. package/dist/runtime/pg/bun.d.ts +12 -7
  20. package/dist/runtime/pg/bun.js +5 -2
  21. package/dist/runtime/pg/pg.d.ts +12 -6
  22. package/dist/runtime/pg/pg.js +5 -2
  23. package/dist/runtime/pg/pglite.d.ts +11 -3
  24. package/dist/runtime/pg/pglite.js +5 -2
  25. package/dist/runtime/pg/postgresjs.d.ts +12 -6
  26. package/dist/runtime/pg/postgresjs.js +5 -2
  27. package/dist/runtime/plan.d.ts +3 -1
  28. package/dist/runtime/tenancy/index.js +1 -1
  29. package/dist/runtime/topology.d.ts +191 -0
  30. package/dist/runtime/traits/index.js +7 -6
  31. package/dist/runtime/types.d.ts +59 -2
  32. package/dist/runtime/validate/index.js +2 -2
  33. package/dist/shared/{x6wysh83.js → 3p4b1fg0.js} +3 -5
  34. package/dist/shared/{ty3v3hfk.js → 47xzb9fc.js} +2 -2
  35. package/dist/shared/{fs0ex00p.js → 4ef7mmqf.js} +2 -2
  36. package/dist/shared/{qybh48nd.js → 5fqx9yh4.js} +6 -2
  37. package/dist/shared/5mtf6cj3.js +94 -0
  38. package/dist/shared/{999ade2q.js → 5vdm4sgp.js} +1 -1
  39. package/dist/shared/{bqha5cg6.js → 6p5k20sm.js} +2 -2
  40. package/dist/shared/{t616ynfn.js → 8bwbwy8h.js} +71 -13
  41. package/dist/shared/{th14ygv2.js → 8ktwd3rh.js} +29 -1
  42. package/dist/shared/{wekze34d.js → 8xsbagad.js} +74 -2
  43. package/dist/shared/{bryqk9k9.js → 922qbgnw.js} +3 -3
  44. package/dist/shared/{meck53jv.js → 990a291j.js} +6 -5
  45. package/dist/shared/{jns2wx4t.js → 9tgmr1gh.js} +1 -1
  46. package/dist/shared/9yn6a2vd.js +11 -0
  47. package/dist/shared/{2ssqrv66.js → ayz64vzj.js} +1037 -181
  48. package/dist/shared/{k34e0xf2.js → bt9sfq0z.js} +16 -14
  49. package/dist/shared/{scwxrpx2.js → bzsjtd7c.js} +84 -15
  50. package/dist/shared/{m9tv7xn7.js → ckjbyrt9.js} +4 -4
  51. package/dist/shared/{ydaz1sv3.js → dxjp14rk.js} +10 -2
  52. package/dist/shared/{49ypnfwt.js → fancm5pt.js} +24 -229
  53. package/dist/shared/{6bazvqwm.js → fb00y8fp.js} +2 -2
  54. package/dist/shared/{1tfdfvhh.js → fyqkk1m0.js} +6 -4
  55. package/dist/shared/g516zdsb.js +905 -0
  56. package/dist/shared/{jkc6ws1p.js → g7ez901n.js} +83 -2
  57. package/dist/shared/{kgnc8grt.js → gdh9mrtp.js} +1 -1
  58. package/dist/shared/{p24x2334.js → h4nqvjkp.js} +5 -3
  59. package/dist/shared/{edwqqryd.js → h8ne16fq.js} +1 -1
  60. package/dist/shared/htnaj77v.js +17 -0
  61. package/dist/shared/jdgqqx31.js +72 -0
  62. package/dist/shared/{6w5j844a.js → jsd07prz.js} +2 -2
  63. package/dist/shared/{m78s7898.js → k7cc9nzk.js} +24 -7
  64. package/dist/shared/kdkxh3kb.js +758 -0
  65. package/dist/shared/nkc9sfqb.js +1161 -0
  66. package/dist/shared/{xva8v7qk.js → p7pfx624.js} +5 -5
  67. package/dist/shared/{xrfnq5k8.js → qgvt8nx1.js} +11 -2
  68. package/dist/shared/{ne02ng5c.js → qy9rdq0g.js} +9 -5
  69. package/dist/shared/{3ekj9x92.js → r6pj4fq2.js} +5 -3
  70. package/dist/shared/r73pt594.js +426 -0
  71. package/dist/shared/rasvvzgz.js +21 -0
  72. package/dist/shared/{01yr20s5.js → sf8m6tfy.js} +2 -2
  73. package/dist/shared/{hcmdtwgh.js → szm0cksa.js} +4 -1
  74. package/dist/shared/{axhk06q1.js → tq9afp8d.js} +1 -1
  75. package/dist/shared/{xw1d69vd.js → wqem4jed.js} +6 -6
  76. package/dist/shared/wxn4b7pp.js +252 -0
  77. package/dist/shared/xdpj5kkm.js +2203 -0
  78. package/dist/shared/xhh1srw3.js +589 -0
  79. package/dist/shared/{mt5wswjz.js → xsq7v6wp.js} +2 -2
  80. package/dist/shared/{7fvtrkwr.js → ycatkxmq.js} +1 -1
  81. package/dist/shared/ykv7wh5b.js +14 -0
  82. package/dist/shared/{fptpmvxp.js → z2rnngj4.js} +26 -21
  83. package/dist/tooling/cli.js +46 -17
  84. package/dist/tooling/migrate/apply.d.ts +61 -5
  85. package/dist/tooling/migrate/backfill.d.ts +136 -0
  86. package/dist/tooling/migrate/check.d.ts +65 -0
  87. package/dist/tooling/migrate/classify.d.ts +108 -0
  88. package/dist/tooling/migrate/commands.d.ts +2 -2
  89. package/dist/tooling/migrate/config.d.ts +22 -0
  90. package/dist/tooling/migrate/doctor.d.ts +3 -0
  91. package/dist/tooling/migrate/drift.d.ts +18 -2
  92. package/dist/tooling/migrate/estimate.d.ts +50 -0
  93. package/dist/tooling/migrate/extensions.d.ts +2 -0
  94. package/dist/tooling/migrate/files.d.ts +19 -0
  95. package/dist/tooling/migrate/index.d.ts +3 -2
  96. package/dist/tooling/migrate/index.js +69 -1
  97. package/dist/tooling/migrate/lint-rules.d.ts +51 -0
  98. package/dist/tooling/migrate/lint.d.ts +71 -0
  99. package/dist/tooling/migrate/managed.d.ts +1 -1
  100. package/dist/tooling/migrate/plan.d.ts +64 -9
  101. package/dist/tooling/migrate/project.d.ts +42 -7
  102. package/dist/tooling/migrate/provision.d.ts +18 -0
  103. package/dist/tooling/migrate/reference.d.ts +40 -0
  104. package/dist/tooling/migrate/runner.d.ts +108 -0
  105. package/dist/tooling/migrate/safe.d.ts +77 -0
  106. package/dist/tooling/migrate/seed.d.ts +20 -0
  107. package/dist/tooling/migrate/snapshot.d.ts +78 -0
  108. package/dist/tooling/migrate/status.d.ts +25 -6
  109. package/dist/tooling/testing/factories.d.ts +117 -0
  110. package/dist/tooling/testing/facts.d.ts +75 -0
  111. package/dist/tooling/testing/index.d.ts +89 -0
  112. package/dist/tooling/testing/index.js +8 -0
  113. package/dist/tooling/testing/isolation.d.ts +30 -0
  114. package/dist/tooling/testing/random.d.ts +40 -0
  115. package/dist/tooling/testing/record.d.ts +38 -0
  116. package/package.json +6 -2
  117. package/dist/shared/5nmdenb6.js +0 -1229
  118. package/dist/shared/dbjej1tw.js +0 -456
  119. package/dist/shared/g4f5kcx9.js +0 -37
  120. package/dist/shared/qbxzvwwc.js +0 -88
  121. package/dist/shared/zwmqxb0g.js +0 -79
  122. /package/dist/shared/{75xkjv0t.js → fa9vt245.js} +0 -0
  123. /package/dist/shared/{0jc3ffzf.js → zvbjc949.js} +0 -0
@@ -1,3 +1,4 @@
1
+ import"../../shared/8bwbwy8h.js";
1
2
  import {
2
3
  checkPresetNames,
3
4
  duplicatePreset
@@ -7,7 +8,7 @@ import {
7
8
  } from "../../shared/n0dgs0pb.js";
8
9
  import {
9
10
  quoteIdent
10
- } from "../../shared/wekze34d.js";
11
+ } from "../../shared/8xsbagad.js";
11
12
  import {
12
13
  functionObject,
13
14
  triggerObject
@@ -20,7 +21,7 @@ import {
20
21
  } from "../../shared/dyj86cmj.js";
21
22
  import {
22
23
  snakeCase
23
- } from "../../shared/6w5j844a.js";
24
+ } from "../../shared/jsd07prz.js";
24
25
  import {
25
26
  ColumnBuilder2,
26
27
  retarget
@@ -37,10 +38,10 @@ import {
37
38
  queryHandle,
38
39
  attachHttp,
39
40
  settleCall
40
- } from "../../shared/k34e0xf2.js";
41
+ } from "../../shared/bt9sfq0z.js";
41
42
  import {
42
43
  installArchiveInspect
43
- } from "../../shared/xrfnq5k8.js";
44
+ } from "../../shared/qgvt8nx1.js";
44
45
  import {
45
46
  fitIdentifier2
46
47
  } from "../../shared/nfzc5z0w.js";
@@ -57,7 +58,7 @@ function rewriteArchivable(self, tables, casing, schemaTraits, cascade) {
57
58
  const edges = foreignKeys(tables, casing, byName);
58
59
  const archiveSql = casing === "snake" ? "archived_at" : "archivedAt";
59
60
  const idSql = casing === "snake" ? "archive_id" : "archiveId";
60
- const predicate = `"${archiveSql.replaceAll('"', '""')}" is null`;
61
+ const predicate = casing === "snake" ? "(archived_at IS NULL)" : '("archivedAt" IS NULL)';
61
62
  return tables.map((item) => {
62
63
  if (!applies(self, item, schemaTraits))
63
64
  return item;
@@ -458,7 +459,7 @@ function refuse(host, table) {
458
459
  }
459
460
  var archiveMod;
460
461
  function loadArchive() {
461
- archiveMod ??= import("../../shared/m9tv7xn7.js");
462
+ archiveMod ??= import("../../shared/ckjbyrt9.js");
462
463
  return archiveMod;
463
464
  }
464
465
  async function settle(host, table, mods) {
@@ -99,6 +99,12 @@ export type CallOptions = {
99
99
  readonly signal?: AbortSignal;
100
100
  /** Milliseconds. The call fails as `timeout` when it runs longer. */
101
101
  readonly timeout?: number;
102
+ /**
103
+ * Forces this read onto the primary or a replica.
104
+ *
105
+ * Absent, a topology client chooses. A single endpoint serves either value.
106
+ */
107
+ readonly route?: "primary" | "replica";
102
108
  };
103
109
  /** Options shared by reads. */
104
110
  export type ReadOptions<S extends QuerySchema, K extends keyof S["~byName"]> = CallOptions & {
@@ -602,6 +608,55 @@ export type TxClient<S extends QuerySchema, Root extends boolean = false> = {
602
608
  */
603
609
  advisoryLock(key: string | number | bigint, options?: CallOptions): Promise<void>;
604
610
  } & TxApi<S, Root>;
611
+ /** A view field: its column name in camel case, as the client publishes it. */
612
+ type CamelName<N extends string> = N extends `_${infer Rest}` ? CamelName<Rest> : N extends `${infer Head}_${infer Tail}` ? `${Head}${Capitalize<CamelName<Tail>>}` : N;
613
+ /** One view row. Every column is decoded as text, so each field is a string or null. */
614
+ type ViewRow<D> = D extends {
615
+ readonly "~columns"?: infer C extends readonly {
616
+ readonly name: string;
617
+ }[];
618
+ } ? {
619
+ readonly [Col in C[number] as CamelName<Col["name"]>]: string | null;
620
+ } : never;
621
+ /** Options `find` and `one` take on a view. */
622
+ type ViewReadOptions<Row> = CallOptions & {
623
+ readonly where?: FieldWhere<Row>;
624
+ readonly select?: readonly (keyof Row & string)[];
625
+ readonly orderBy?: OrderBy<Row>;
626
+ readonly limit?: number;
627
+ };
628
+ /** The read-only handle `db.views` holds for one view. */
629
+ type ViewApi<Row> = {
630
+ find<const O extends ViewReadOptions<Row> & {
631
+ readonly limit: number;
632
+ }>(options: O): Read<readonly Show<Selected<Row, O extends {
633
+ readonly select: infer Sel;
634
+ } ? Sel : undefined>>[]>;
635
+ find<const O extends ViewReadOptions<Row>>(options: O): {
636
+ all(reason: string): Read<readonly Show<Selected<Row, O extends {
637
+ readonly select: infer Sel;
638
+ } ? Sel : undefined>>[]>;
639
+ };
640
+ one<const O extends ViewReadOptions<Row>>(options?: O): Read<Show<Selected<Row, O extends {
641
+ readonly select: infer Sel;
642
+ } ? Sel : undefined>> | null>;
643
+ count(options?: CallOptions & {
644
+ readonly where?: FieldWhere<Row>;
645
+ }): Read<number>;
646
+ exists(options?: CallOptions & {
647
+ readonly where?: FieldWhere<Row>;
648
+ }): Read<boolean>;
649
+ };
650
+ /** `db.views`, typed from `schema({ views })`. Absent when the schema declares none. */
651
+ type ViewsClient<S> = S extends {
652
+ readonly "~views": infer V extends readonly unknown[];
653
+ } ? {
654
+ readonly views: {
655
+ readonly [D in V[number] as D extends {
656
+ readonly name: infer N extends string;
657
+ } ? CamelName<N> : never]: ViewApi<Show<ViewRow<D>>>;
658
+ };
659
+ } : unknown;
605
660
  /** A client whose tables are already inside one tenant or an unscoped reason. */
606
661
  type ScopedClient<S extends QuerySchema> = {
607
662
  readonly [K in keyof S["~byName"] & string]: TableApi<S, K>;
@@ -612,7 +667,7 @@ type ScopedClient<S extends QuerySchema> = {
612
667
  close(): Promise<void>;
613
668
  /** Resolves when the dialect and `requires` checks have finished. */
614
669
  readonly connected: Promise<void>;
615
- } & TxApi<S, false> & IfAsyncDisposable<typeof Symbol>;
670
+ } & TxApi<S, false> & ViewsClient<S> & IfAsyncDisposable<typeof Symbol>;
616
671
  /** `for` and `unscoped` on a schema that set tenancy. */
617
672
  type ScopeMethods<S extends QuerySchema> = TenantKeyOf<S> extends never ? object : {
618
673
  /**
@@ -650,7 +705,7 @@ export type Connected<S extends QuerySchema> = {
650
705
  close(): Promise<void>;
651
706
  /** Resolves when the dialect and `requires` checks have finished. */
652
707
  readonly connected: Promise<void>;
653
- } & TxApi<S, true> & ScopeMethods<S> & IfAsyncDisposable<typeof Symbol>;
708
+ } & TxApi<S, true> & ScopeMethods<S> & ViewsClient<S> & IfAsyncDisposable<typeof Symbol>;
654
709
  /**
655
710
  * A catalog `okm build` wrote.
656
711
  *
@@ -672,6 +727,8 @@ export type ConnectOptions<S extends QuerySchema> = {
672
727
  * Directory of `catalog.hash` and `catalog.json`.
673
728
  *
674
729
  * When omitted, `connect` reads `.okm` under the process cwd if that hash file exists.
730
+ * The hash file is the fast path. A mismatch then reads `catalog.json` once
731
+ * per process and does not rebuild the catalog from the schema.
675
732
  */
676
733
  readonly catalogDir?: string;
677
734
  readonly logger?: {
@@ -3,10 +3,10 @@ import {
3
3
  } from "../../shared/9m80mkac.js";
4
4
  import {
5
5
  addSchemaHook
6
- } from "../../shared/x6wysh83.js";
6
+ } from "../../shared/3p4b1fg0.js";
7
7
  import {
8
8
  queryHandle
9
- } from "../../shared/k34e0xf2.js";
9
+ } from "../../shared/bt9sfq0z.js";
10
10
  import {
11
11
  OkmError2
12
12
  } from "../../shared/52szzakm.js";
@@ -1,15 +1,13 @@
1
1
  import {
2
- catalog
3
- } from "./jkc6ws1p.js";
4
- import {
2
+ catalog,
5
3
  enumType,
6
4
  sameEnumLabels
7
- } from "./qbxzvwwc.js";
5
+ } from "./g7ez901n.js";
8
6
  import {
9
7
  snakeCase,
10
8
  emittedTypeName,
11
9
  rejectLater
12
- } from "./6w5j844a.js";
10
+ } from "./jsd07prz.js";
13
11
  import {
14
12
  withLocation
15
13
  } from "./k7dwkhvq.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  withHttp,
3
3
  attachHttp
4
- } from "./k34e0xf2.js";
4
+ } from "./bt9sfq0z.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("./fptpmvxp.js");
34
+ const { assertCompatible } = await import("./z2rnngj4.js");
35
35
  try {
36
36
  await assertCompatible(pool, schema, recorded, source, options);
37
37
  } catch (error) {
@@ -2,13 +2,13 @@ import {
2
2
  send2,
3
3
  reserve,
4
4
  park
5
- } from "./01yr20s5.js";
5
+ } from "./sf8m6tfy.js";
6
6
  import {
7
7
  isConnectionLost
8
8
  } from "./tbszx8mz.js";
9
9
  import {
10
10
  WireSession
11
- } from "./0jc3ffzf.js";
11
+ } from "./zvbjc949.js";
12
12
  import {
13
13
  rejectClosed,
14
14
  runCall
@@ -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 "./t616ynfn.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
  };
@@ -0,0 +1,94 @@
1
+ import {
2
+ BEHIND_EXPAND,
3
+ BEHIND_CONTRACT,
4
+ AHEAD_CONTRACT
5
+ } from "./9yn6a2vd.js";
6
+ import {
7
+ OkmError2
8
+ } from "./52szzakm.js";
9
+
10
+ // src/runtime/drift-detail.ts
11
+ function driftVerdict(codeHash, recordedHash, migrations) {
12
+ const codeAt = indexOfHash(migrations, codeHash);
13
+ const recordedAt = indexOfHash(migrations, recordedHash);
14
+ if (codeAt >= 0 && recordedAt >= codeAt) {
15
+ for (let index = codeAt + 1;index <= recordedAt; index += 1) {
16
+ const migration = migrations[index];
17
+ if (migration !== undefined && migration.expand !== true) {
18
+ return { state: "ahead by contract", migrationId: migration.id };
19
+ }
20
+ }
21
+ return { state: "ok" };
22
+ }
23
+ if (codeAt >= 0 && recordedAt >= 0 && recordedAt < codeAt) {
24
+ const next = migrations[recordedAt + 1];
25
+ if (next !== undefined) {
26
+ return {
27
+ state: next.expand ? "behind by expand" : "behind by contract",
28
+ migrationId: next.id
29
+ };
30
+ }
31
+ }
32
+ if (recordedAt >= 0) {
33
+ const at = migrations[recordedAt];
34
+ if (at !== undefined)
35
+ return { state: "behind", migrationId: at.id };
36
+ }
37
+ const last = migrations.at(-1);
38
+ return { state: "behind", migrationId: last?.id ?? "" };
39
+ }
40
+ async function assertDrift(pool, codeHash, recordedHash, options) {
41
+ let rows;
42
+ try {
43
+ const result = await pool.execute("select migration_id, class, catalog_hash from okm_history order by migration_id, step_index", undefined, options);
44
+ rows = result.rows;
45
+ } catch (error) {
46
+ throw gapError({ state: "behind", migrationId: "" }, error);
47
+ }
48
+ const verdict = driftVerdict(codeHash, recordedHash, groupMigrations(rows));
49
+ if (verdict.state === "ok")
50
+ return;
51
+ throw gapError(verdict);
52
+ }
53
+ function indexOfHash(migrations, hash) {
54
+ let found = -1;
55
+ for (let index = 0;index < migrations.length; index += 1) {
56
+ if (migrations[index]?.catalogHash === hash)
57
+ found = index;
58
+ }
59
+ return found;
60
+ }
61
+ function groupMigrations(rows) {
62
+ const grouped = [];
63
+ for (const row of rows) {
64
+ const id = row[0];
65
+ const stepClass = row[1];
66
+ const hash = row[2];
67
+ if (id == null || stepClass == null || hash == null)
68
+ continue;
69
+ const expand = stepClass === "expand";
70
+ const last = grouped.at(-1);
71
+ if (last !== undefined && last.id === id) {
72
+ grouped[grouped.length - 1] = {
73
+ id,
74
+ catalogHash: hash,
75
+ expand: last.expand && expand
76
+ };
77
+ continue;
78
+ }
79
+ grouped.push({ id, catalogHash: hash, expand });
80
+ }
81
+ return grouped;
82
+ }
83
+ function gapError(verdict, cause) {
84
+ const named = verdict.migrationId;
85
+ const phrase = verdict.state === "ahead by contract" ? `${AHEAD_CONTRACT} migration ${named}` : verdict.state === "behind by expand" ? `${BEHIND_EXPAND} migration ${named}` : verdict.state === "behind by contract" ? `${BEHIND_CONTRACT} migration ${named}` : named.length > 0 ? `behind the app at migration ${named}` : "behind the app";
86
+ const fix = named.length > 0 ? `Apply ${named}, or change the deploy order.` : "Apply migrations, or change the deploy order.";
87
+ return new OkmError2("OKM1520", `The database is ${phrase}.`, {
88
+ ...cause === undefined ? {} : { cause },
89
+ fix: { summary: fix }
90
+ });
91
+ }
92
+ export {
93
+ assertDrift
94
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PgSession
3
- } from "./xw1d69vd.js";
3
+ } from "./wqem4jed.js";
4
4
  import {
5
5
  isConnectionLost
6
6
  } from "./tbszx8mz.js";
@@ -3,7 +3,7 @@ import {
3
3
  noticeBuffer,
4
4
  WireSession,
5
5
  cursorStream
6
- } from "./0jc3ffzf.js";
6
+ } from "./zvbjc949.js";
7
7
  import {
8
8
  NODE_POSTGRES_CAPABILITIES,
9
9
  driverErrors,
@@ -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("./6bazvqwm.js").then((mod) => mod.checkout(held));
56
+ const checkout = () => closed ? rejectClosed() : import("./fb00y8fp.js").then((mod) => mod.checkout(held));
57
57
  return {
58
58
  capabilities: NODE_POSTGRES_CAPABILITIES,
59
59
  execute(text, params, options) {
@@ -9,16 +9,14 @@ import {
9
9
  } from "./y005b761.js";
10
10
  import {
11
11
  extensionObject
12
- } from "./th14ygv2.js";
12
+ } from "./8ktwd3rh.js";
13
13
  import {
14
14
  dependencyOrder,
15
- catalog
16
- } from "./jkc6ws1p.js";
17
- import {
15
+ catalog,
18
16
  enumType,
19
17
  domainType,
20
18
  isDomain
21
- } from "./qbxzvwwc.js";
19
+ } from "./g7ez901n.js";
22
20
  import {
23
21
  canonicalJson,
24
22
  staticNamespace2,
@@ -46,7 +44,8 @@ import {
46
44
  } from "./4e4c6vq2.js";
47
45
  import {
48
46
  sha2562,
49
- assertIdentifier2
47
+ assertIdentifier2,
48
+ fitIdentifier2
50
49
  } from "./nfzc5z0w.js";
51
50
  import {
52
51
  catalogError2
@@ -201,7 +200,7 @@ function renameTable2(source, change) {
201
200
  if (!found) {
202
201
  catalogError2("OKM1020", `Table ${change.from} is not in the catalog.`);
203
202
  }
204
- const next = source.objects.map((object) => rewriteTableName(object, change, fromKey, toIdentity));
203
+ const next = source.objects.map((object) => rewriteTableName(object, change, fromKey, toIdentity, source));
205
204
  return catalog(next);
206
205
  }
207
206
  var serializedText = new WeakMap;
@@ -230,6 +229,17 @@ function catalogHash2(source) {
230
229
  serializedHash.set(source, hash);
231
230
  return hash;
232
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
+ }
233
243
  function loadTrustedCatalog2(text, hash) {
234
244
  if (sha2562(text) !== hash) {
235
245
  catalogError2("OKM1027", "Catalog hash does not match the build artifact.");
@@ -473,8 +483,8 @@ function rewriteExpr(text, change, active) {
473
483
  return text;
474
484
  return replaceIdentifier(text, change.from, change.to);
475
485
  }
476
- function rewriteTableName(object, change, fromKey, toIdentity) {
477
- const dependencies = retarget(object.dependencies, fromKey, toIdentity);
486
+ function rewriteTableName(object, change, fromKey, toIdentity, source) {
487
+ const dependencies = retarget(object.dependencies, fromKey, toIdentity, change);
478
488
  const named = object.kind === "table" && object.identity.name === change.from && sameNamespace2(object.identity.namespace, change.namespace);
479
489
  if (object.kind === "table") {
480
490
  return table3({
@@ -579,9 +589,19 @@ function rewriteTableName(object, change, fromKey, toIdentity) {
579
589
  });
580
590
  return rewriteView(object, dependencies, rewriteExpr(object.definition.query, { from: change.from, to: change.to }, local));
581
591
  }
582
- if (object.kind === "role" || object.kind === "grant" || object.kind === "defaultPrivilege") {
592
+ if (object.kind === "role" || object.kind === "defaultPrivilege") {
583
593
  return retargeted(object, dependencies);
584
594
  }
595
+ if (object.kind === "grant") {
596
+ return grantObject({
597
+ role: object.identity.role,
598
+ object: movedGrantRef(object.identity.object, change, source),
599
+ privilege: object.identity.privilege,
600
+ owner: object.owner,
601
+ provenance: object.provenance,
602
+ dependencies
603
+ });
604
+ }
585
605
  if (object.kind === "trigger") {
586
606
  const parent = movedParent(object.identity.parent, change);
587
607
  const local = parent.name !== object.identity.parent.name;
@@ -644,8 +664,46 @@ function rewriteSequence(object, dependencies) {
644
664
  function renameList(names, from, to) {
645
665
  return names.map((name) => name === from ? to : name);
646
666
  }
647
- function retarget(edges, fromKey, to) {
648
- return edges.map((edge) => identityKey2(edge.target) === fromKey ? to : edge.target);
667
+ function retarget(edges, fromKey, to, change) {
668
+ return edges.map((edge) => {
669
+ if (identityKey2(edge.target) === fromKey)
670
+ return to;
671
+ if (change === undefined)
672
+ return edge.target;
673
+ return movedChild(edge.target, change);
674
+ });
675
+ }
676
+ function movedChild(target, change) {
677
+ if (!("parent" in target))
678
+ return target;
679
+ if (target.parent.name !== change.from || !sameNamespace2(target.parent.namespace, change.namespace)) {
680
+ return target;
681
+ }
682
+ return { ...target, parent: { namespace: target.parent.namespace, name: change.to } };
683
+ }
684
+ function movedGrantRef(object, change, source) {
685
+ if (object.kind === "table" && object.name === change.from && sameNamespace2(object.namespace, change.namespace)) {
686
+ return { ...object, name: change.to };
687
+ }
688
+ if (object.kind !== "sequence")
689
+ return object;
690
+ const next = renamedIdentitySequence(source, change, object.name);
691
+ if (next === undefined)
692
+ return object;
693
+ return { ...object, name: next };
694
+ }
695
+ function renamedIdentitySequence(source, change, sequenceName) {
696
+ for (const object of source.objects) {
697
+ if (object.kind !== "column" || object.definition.identity === undefined)
698
+ continue;
699
+ if (object.identity.parent.name !== change.from || !sameNamespace2(object.identity.parent.namespace, change.namespace)) {
700
+ continue;
701
+ }
702
+ if (fitIdentifier2(`${change.from}_${object.identity.name}_seq`) !== sequenceName)
703
+ continue;
704
+ return fitIdentifier2(`${change.to}_${object.identity.name}_seq`);
705
+ }
706
+ return;
649
707
  }
650
708
  function dependencyJson(edges) {
651
709
  const indexed = edges.map((edge) => ({
@@ -1397,4 +1455,4 @@ function assertNeverKind(value) {
1397
1455
  return catalogError2("OKM1020", `Unexpected kind ${JSON.stringify(value)}.`);
1398
1456
  }
1399
1457
 
1400
- 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 };
@@ -50,11 +50,39 @@ function sameExtensionDefinition(before, after) {
50
50
  return false;
51
51
  return sameVersion(before.definition.version, after.definition.version);
52
52
  }
53
+ function alignExtensionVersions(source, other) {
54
+ const loose = looseNames(source, other);
55
+ if (loose.size === 0)
56
+ return source;
57
+ let changed = false;
58
+ const objects = source.objects.map((object) => {
59
+ if (object.kind !== "extension" || object.definition.version === undefined)
60
+ return object;
61
+ if (!loose.has(object.identity.name))
62
+ return object;
63
+ changed = true;
64
+ const { version: _version, ...definition } = object.definition;
65
+ return { ...object, definition };
66
+ });
67
+ return changed ? { version: source.version, objects } : source;
68
+ }
53
69
  function sameVersion(before, after) {
54
70
  if (!isExactVersion(after) || !isExactVersion(before))
55
71
  return true;
56
72
  return before === after;
57
73
  }
74
+ function looseNames(source, other) {
75
+ const names = new Set;
76
+ for (const catalog of [source, other]) {
77
+ for (const object of catalog.objects) {
78
+ if (object.kind !== "extension")
79
+ continue;
80
+ if (!isExactVersion(object.definition.version))
81
+ names.add(object.identity.name);
82
+ }
83
+ }
84
+ return names;
85
+ }
58
86
  function assertVersion(version) {
59
87
  if (version === undefined)
60
88
  return;
@@ -66,4 +94,4 @@ function parts(version) {
66
94
  return version.split(".").map((part) => Number(part));
67
95
  }
68
96
 
69
- export { extensionObject, isExactVersion, compareExtensionVersions, sameExtensionDefinition };
97
+ export { extensionObject, isExactVersion, compareExtensionVersions, sameExtensionDefinition, alignExtensionVersions };
@@ -1,6 +1,9 @@
1
+ import {
2
+ creationOrder2
3
+ } from "./8bwbwy8h.js";
1
4
  import {
2
5
  isDomain
3
- } from "./qbxzvwwc.js";
6
+ } from "./g7ez901n.js";
4
7
  import {
5
8
  quoteLiteral
6
9
  } from "./94ez8kzh.js";
@@ -15,6 +18,61 @@ import {
15
18
  function quoteIdent(name) {
16
19
  return `"${name.replaceAll('"', '""')}"`;
17
20
  }
21
+ function renderCatalog(source, schema) {
22
+ const folded = foldedKeys(source);
23
+ const statements = [];
24
+ const ordered = creationOrder2(source);
25
+ for (const object of ordered) {
26
+ if (object.kind !== "type" || object.owner === "ignored")
27
+ continue;
28
+ const sql = createObjectSql(object, schema);
29
+ if (sql !== undefined)
30
+ statements.push(sql);
31
+ }
32
+ for (const object of ordered) {
33
+ if (object.kind === "type" || object.kind === "function" || object.kind === "trigger" || object.kind === "view" || object.kind === "materializedView" || ownedByView(object)) {
34
+ continue;
35
+ }
36
+ if (object.owner === "ignored")
37
+ continue;
38
+ const key = identityKey2(object.identity);
39
+ if (object.kind === "table") {
40
+ statements.push(createTableSql(object, source, schema));
41
+ continue;
42
+ }
43
+ if (folded.has(key))
44
+ continue;
45
+ const sql = createObjectSql(object, schema);
46
+ if (sql !== undefined)
47
+ statements.push(sql);
48
+ }
49
+ for (const kind of ["function", "trigger"]) {
50
+ for (const object of ordered) {
51
+ if (object.kind !== kind || object.owner === "ignored")
52
+ continue;
53
+ const sql = createObjectSql(object, schema);
54
+ if (sql !== undefined)
55
+ statements.push(sql);
56
+ }
57
+ }
58
+ for (const kind of ["view", "materializedView"]) {
59
+ for (const object of ordered) {
60
+ if (object.kind !== kind || object.owner === "ignored")
61
+ continue;
62
+ const sql = createObjectSql(object, schema);
63
+ if (sql !== undefined)
64
+ statements.push(sql);
65
+ }
66
+ }
67
+ for (const object of ordered) {
68
+ if (!ownedByView(object) || object.owner === "ignored")
69
+ continue;
70
+ const sql = createObjectSql(object, schema);
71
+ if (sql !== undefined)
72
+ statements.push(sql);
73
+ }
74
+ return statements;
75
+ }
18
76
  function ownedByView(object) {
19
77
  if (object.kind !== "index")
20
78
  return false;
@@ -145,6 +203,20 @@ function identitySequence(sequence, source) {
145
203
  return object.dependencies.some((edge) => identityKey2(edge.target) === key);
146
204
  });
147
205
  }
206
+ function foldedKeys(source) {
207
+ const keys = new Set;
208
+ for (const object of source.objects) {
209
+ if (object.kind === "column")
210
+ keys.add(identityKey2(object.identity));
211
+ if (object.kind === "constraint" && object.definition.constraintKind === "primaryKey") {
212
+ keys.add(identityKey2(object.identity));
213
+ }
214
+ if (object.kind === "sequence" && identitySequence(object, source)) {
215
+ keys.add(identityKey2(object.identity));
216
+ }
217
+ }
218
+ return keys;
219
+ }
148
220
  function createTableSql(tableObject, source, schema) {
149
221
  const parent = tableObject.identity.name;
150
222
  const columns = source.objects.filter((object) => object.kind === "column" && object.identity.parent.name === parent);
@@ -243,4 +315,4 @@ function qualify(schema, name) {
243
315
  return `${quoteIdent(schema)}.${quoteIdent(name)}`;
244
316
  }
245
317
 
246
- export { quoteIdent, ownedByView, dropObjectSql, createObjectSql, functionSql, viewSql, refreshMaterializedViewSql, alterColumnSql, identitySequence, createTableSql, qualify };
318
+ export { quoteIdent, renderCatalog, ownedByView, dropObjectSql, createObjectSql, functionSql, viewSql, refreshMaterializedViewSql, alterColumnSql, identitySequence, createTableSql, qualify };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  withHttp
3
- } from "./k34e0xf2.js";
3
+ } from "./bt9sfq0z.js";
4
4
  import {
5
5
  decodeResult
6
- } from "./xrfnq5k8.js";
6
+ } from "./qgvt8nx1.js";
7
7
  import {
8
8
  OkmError2
9
9
  } from "./52szzakm.js";
@@ -17,7 +17,7 @@ async function* streamRows(session, call, prepare, log) {
17
17
  })));
18
18
  }
19
19
  const { plan, params } = await prepare();
20
- const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./edwqqryd.js")).decodeIncluded;
20
+ const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./h8ne16fq.js")).decodeIncluded;
21
21
  for await (const chunk of session.pool.stream(plan.text, params)) {
22
22
  const decoded = decode(plan, chunk, call.table);
23
23
  if (!Array.isArray(decoded))