okmodel 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +710 -36
  2. package/dist/contracts/catalog/enum.d.ts +31 -4
  3. package/dist/contracts/catalog/extension.d.ts +61 -0
  4. package/dist/contracts/catalog/privilege.d.ts +64 -0
  5. package/dist/contracts/catalog/routine.d.ts +56 -0
  6. package/dist/contracts/catalog/types.d.ts +164 -10
  7. package/dist/contracts/catalog/view.d.ts +73 -0
  8. package/dist/dialects/pg/column.d.ts +3 -1
  9. package/dist/dialects/pg/ddl.d.ts +65 -1
  10. package/dist/dialects/pg/enum.d.ts +10 -8
  11. package/dist/dialects/pg/ext/citext.d.ts +14 -0
  12. package/dist/dialects/pg/ext/citext.js +11 -0
  13. package/dist/dialects/pg/ext/index.d.ts +52 -0
  14. package/dist/dialects/pg/ext/index.js +6 -0
  15. package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
  16. package/dist/dialects/pg/ext/pg-trgm.js +42 -0
  17. package/dist/dialects/pg/fn/index.d.ts +107 -0
  18. package/dist/dialects/pg/fn/index.js +175 -0
  19. package/dist/dialects/pg/fn/touch.d.ts +14 -0
  20. package/dist/dialects/pg/index.js +104 -19
  21. package/dist/dialects/pg/introspect.d.ts +10 -1
  22. package/dist/dialects/pg/operators.d.ts +8 -1
  23. package/dist/dialects/pg/role/check.d.ts +45 -0
  24. package/dist/dialects/pg/role/index.d.ts +50 -0
  25. package/dist/dialects/pg/role/sql.d.ts +44 -0
  26. package/dist/dialects/pg/table.d.ts +7 -0
  27. package/dist/dialects/pg/tenancy.d.ts +9 -0
  28. package/dist/dialects/pg/view/client.d.ts +30 -0
  29. package/dist/dialects/pg/view/depend.d.ts +35 -0
  30. package/dist/dialects/pg/view/index.d.ts +114 -0
  31. package/dist/dialects/pg/view/index.js +289 -0
  32. package/dist/dialects/pg/view/scratch.d.ts +21 -0
  33. package/dist/dialects/pg/where.d.ts +2 -2
  34. package/dist/runtime/pg/bun.js +3 -3
  35. package/dist/runtime/pg/pg.js +3 -3
  36. package/dist/runtime/pg/pglite.js +3 -3
  37. package/dist/runtime/pg/postgresjs.js +3 -3
  38. package/dist/runtime/tenancy/index.js +6 -3
  39. package/dist/runtime/traits/index.d.ts +7 -2
  40. package/dist/runtime/traits/index.js +149 -12
  41. package/dist/runtime/validate/index.js +4 -4
  42. package/dist/shared/{ytg3xf9p.js → 01yr20s5.js} +3 -3
  43. package/dist/shared/{cstgkzdx.js → 0jc3ffzf.js} +1 -1
  44. package/dist/shared/{xkz8g6by.js → 1g0drakv.js} +2 -2
  45. package/dist/shared/{eaxwrgby.js → 1tfdfvhh.js} +4 -3
  46. package/dist/shared/2ssqrv66.js +1576 -0
  47. package/dist/shared/{10tjenmd.js → 3ekj9x92.js} +1 -1
  48. package/dist/shared/49ypnfwt.js +1122 -0
  49. package/dist/shared/{sacqha1y.js → 4m9fn52z.js} +2 -2
  50. package/dist/shared/5nmdenb6.js +1229 -0
  51. package/dist/shared/{qa5dsc7z.js → 6bazvqwm.js} +3 -3
  52. package/dist/shared/{x9v1qgeb.js → 6w5j844a.js} +1 -1
  53. package/dist/shared/{0qkxbm1f.js → 75xkjv0t.js} +1 -1
  54. package/dist/shared/7fvtrkwr.js +84 -0
  55. package/dist/shared/94ez8kzh.js +19 -0
  56. package/dist/shared/{1dp5knt7.js → 999ade2q.js} +2 -2
  57. package/dist/shared/{3a5ne750.js → 9m80mkac.js} +2 -2
  58. package/dist/shared/9x25fxhc.js +150 -0
  59. package/dist/shared/{4b9da9d7.js → axhk06q1.js} +19 -1
  60. package/dist/shared/{38crxbgn.js → bqha5cg6.js} +3 -3
  61. package/dist/shared/{zd93g3rq.js → bryqk9k9.js} +1 -1
  62. package/dist/shared/{n47rd821.js → c8aghh05.js} +1 -1
  63. package/dist/shared/{dd4f8mnx.js → c9z5g0fm.js} +4 -2
  64. package/dist/shared/{eqmtn1bj.js → dbjej1tw.js} +71 -14
  65. package/dist/shared/{ps43134h.js → dyj86cmj.js} +4 -4
  66. package/dist/shared/{sfh4pk75.js → fptpmvxp.js} +3 -3
  67. package/dist/shared/{97g2jnrw.js → fs0ex00p.js} +3 -3
  68. package/dist/shared/{rtnaqre0.js → g4f5kcx9.js} +2 -2
  69. package/dist/shared/{yw5c610b.js → gjthds9j.js} +2 -2
  70. package/dist/shared/hcmdtwgh.js +102 -0
  71. package/dist/shared/{qxa0yb9j.js → jkc6ws1p.js} +2 -54
  72. package/dist/shared/{mxmcdsh5.js → k34e0xf2.js} +9 -9
  73. package/dist/shared/{py3nh7jy.js → kgnc8grt.js} +2 -2
  74. package/dist/shared/{g9f0zqce.js → m78s7898.js} +1 -1
  75. package/dist/shared/meck53jv.js +99 -0
  76. package/dist/shared/{v18jva5b.js → mt5wswjz.js} +1 -1
  77. package/dist/shared/{g1b5zzj9.js → n0dgs0pb.js} +1 -1
  78. package/dist/shared/{zt8y0wzb.js → n7mcc1gk.js} +1 -1
  79. package/dist/shared/ne02ng5c.js +68 -0
  80. package/dist/shared/{e7a268fy.js → p24x2334.js} +1 -1
  81. package/dist/shared/qbxzvwwc.js +88 -0
  82. package/dist/shared/{a1gdp7j9.js → qybh48nd.js} +1 -1
  83. package/dist/shared/{d04j53v8.js → scwxrpx2.js} +5 -4
  84. package/dist/shared/{d2whjz4k.js → t616ynfn.js} +530 -24
  85. package/dist/shared/th14ygv2.js +69 -0
  86. package/dist/shared/{xatfg0gn.js → tmbdywx0.js} +4 -19
  87. package/dist/shared/{ge03bfca.js → ty3v3hfk.js} +2 -2
  88. package/dist/shared/wekze34d.js +246 -0
  89. package/dist/shared/{7mht49yd.js → x6wysh83.js} +59 -18
  90. package/dist/shared/{4jzzghr6.js → xva8v7qk.js} +8 -8
  91. package/dist/shared/{ecdzej21.js → xw1d69vd.js} +7 -7
  92. package/dist/shared/y005b761.js +112 -0
  93. package/dist/shared/{mrq77sgw.js → ydaz1sv3.js} +1 -1
  94. package/dist/tooling/cli.js +32 -8
  95. package/dist/tooling/migrate/apply.d.ts +16 -0
  96. package/dist/tooling/migrate/commands.d.ts +2 -1
  97. package/dist/tooling/migrate/config.d.ts +8 -0
  98. package/dist/tooling/migrate/doctor.d.ts +25 -0
  99. package/dist/tooling/migrate/drift.d.ts +19 -0
  100. package/dist/tooling/migrate/ext.d.ts +17 -0
  101. package/dist/tooling/migrate/extensions.d.ts +51 -0
  102. package/dist/tooling/migrate/managed.d.ts +17 -0
  103. package/dist/tooling/migrate/plan.d.ts +14 -1
  104. package/dist/tooling/migrate/project.d.ts +25 -1
  105. package/dist/tooling/migrate/type-name.d.ts +19 -0
  106. package/package.json +22 -2
  107. package/dist/shared/5z4q2zda.js +0 -2073
  108. /package/dist/shared/{9k6vetvf.js → rrstp3kb.js} +0 -0
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  send,
3
3
  connectClient
4
- } from "./38crxbgn.js";
4
+ } from "./bqha5cg6.js";
5
5
  import {
6
6
  isConnectionLost
7
7
  } from "./tbszx8mz.js";
8
8
  import {
9
9
  WireSession
10
- } from "./cstgkzdx.js";
10
+ } from "./0jc3ffzf.js";
11
11
  import {
12
12
  rejectClosed,
13
13
  runCall
14
- } from "./9k6vetvf.js";
14
+ } from "./rrstp3kb.js";
15
15
 
16
16
  // src/adapters/pg/nodepostgres-extra.ts
17
17
  var RESET_ALL = "RESET ALL";
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  definition,
7
7
  unavailable
8
- } from "./xatfg0gn.js";
8
+ } from "./tmbdywx0.js";
9
9
  import {
10
10
  OkmError2,
11
11
  throwNamed2
@@ -9,7 +9,7 @@ import {
9
9
  runCall,
10
10
  EMPTY_NOTICES,
11
11
  resultFrom
12
- } from "./9k6vetvf.js";
12
+ } from "./rrstp3kb.js";
13
13
 
14
14
  // src/adapters/pg/pglite.ts
15
15
  import { PGlite } from "@electric-sql/pglite";
@@ -0,0 +1,84 @@
1
+ import {
2
+ extensionObject
3
+ } from "./th14ygv2.js";
4
+ import {
5
+ OkmError2
6
+ } from "./52szzakm.js";
7
+
8
+ // src/dialects/pg/ext/index.ts
9
+ function extension2(name, options = {}) {
10
+ const schema = options.schema ?? "public";
11
+ const relocatable = options.relocatable ?? true;
12
+ const version = options.version;
13
+ const record = extensionObject({
14
+ name,
15
+ schema,
16
+ relocatable,
17
+ ...version !== undefined ? { version } : {},
18
+ provenance: { origin: "extension", name }
19
+ });
20
+ return {
21
+ name,
22
+ schema,
23
+ relocatable,
24
+ ...version !== undefined ? { version } : {},
25
+ contribute(peers, built) {
26
+ const names = peerNames(peers);
27
+ assertDeclared(names, built);
28
+ return [record];
29
+ }
30
+ };
31
+ }
32
+ function peerNames(peers) {
33
+ if (!Array.isArray(peers)) {
34
+ extensionError("OKM1810", "schema({ extensions }) must be a list of extensions.");
35
+ }
36
+ const counts = new Map;
37
+ for (const peer of peers) {
38
+ if (!isPeer(peer)) {
39
+ extensionError("OKM1810", "schema({ extensions }) must be a list of extensions.");
40
+ }
41
+ counts.set(peer.name, (counts.get(peer.name) ?? 0) + 1);
42
+ }
43
+ for (const [name, count] of counts) {
44
+ if (count > 1)
45
+ extensionError("OKM1813", `Extension ${name} is defined twice.`);
46
+ }
47
+ return counts;
48
+ }
49
+ function assertDeclared(names, built) {
50
+ if (!Array.isArray(built))
51
+ return;
52
+ for (const object of built) {
53
+ if (typeof object !== "object" || object === null || !("dependencies" in object))
54
+ continue;
55
+ const dependencies = object.dependencies;
56
+ if (!Array.isArray(dependencies))
57
+ continue;
58
+ for (const edge of dependencies) {
59
+ if (typeof edge !== "object" || edge === null || !("target" in edge))
60
+ continue;
61
+ const target = edge.target;
62
+ if (typeof target !== "object" || target === null)
63
+ continue;
64
+ if (!("kind" in target) || !("name" in target))
65
+ continue;
66
+ if (target.kind === "extension" && typeof target.name === "string" && !names.has(target.name)) {
67
+ extensionError("OKM1810", `Extension ${target.name} is used but not declared.`);
68
+ }
69
+ }
70
+ }
71
+ }
72
+ function isPeer(value) {
73
+ if (typeof value !== "object" || value === null)
74
+ return false;
75
+ if (!("name" in value) || !("contribute" in value))
76
+ return false;
77
+ return typeof value.name === "string" && value.name.length > 0 && typeof value.contribute === "function";
78
+ }
79
+ function extensionError(code, message) {
80
+ const summary = code === "OKM1813" ? "Keep one definition. A second copy fails at build." : "Declare the extension next to the schema that uses it.";
81
+ throw new OkmError2(code, message, { fix: { summary } });
82
+ }
83
+
84
+ export { extension2 };
@@ -0,0 +1,19 @@
1
+ // src/dialects/pg/quote.ts
2
+ function quoteLiteral(value) {
3
+ return `'${value.replaceAll("'", "''")}'`;
4
+ }
5
+ function arrayElement(encoded, raw) {
6
+ if (raw && (encoded === "true" || encoded === "false" || isBareNumber(encoded))) {
7
+ return encoded;
8
+ }
9
+ return `"${encoded.replaceAll("\\", "\\\\").replaceAll('"', "\\\"")}"`;
10
+ }
11
+ function isBareNumber(encoded) {
12
+ let pattern = bareNumber;
13
+ pattern ??= /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
14
+ bareNumber = pattern;
15
+ return pattern.test(encoded);
16
+ }
17
+ var bareNumber;
18
+
19
+ export { quoteLiteral, arrayElement };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  PgSession
3
- } from "./ecdzej21.js";
3
+ } from "./xw1d69vd.js";
4
4
  import {
5
5
  isConnectionLost
6
6
  } from "./tbszx8mz.js";
@@ -11,7 +11,7 @@ import {
11
11
  runCall,
12
12
  rowsFrom,
13
13
  resultFrom
14
- } from "./9k6vetvf.js";
14
+ } from "./rrstp3kb.js";
15
15
 
16
16
  // src/adapters/pg/postgres-extra.ts
17
17
  var RESET_ALL = "RESET ALL";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ColumnBuilder2
3
- } from "./dd4f8mnx.js";
3
+ } from "./c9z5g0fm.js";
4
4
  import {
5
5
  definition
6
- } from "./xatfg0gn.js";
6
+ } from "./tmbdywx0.js";
7
7
  import {
8
8
  OkmError2
9
9
  } from "./52szzakm.js";
@@ -0,0 +1,150 @@
1
+ import {
2
+ staticNamespace2,
3
+ assertNamespace2,
4
+ normaliseEdges,
5
+ assertProvenance
6
+ } from "./t4tbsy9h.js";
7
+ import {
8
+ assertIdentifier2
9
+ } from "./nfzc5z0w.js";
10
+ import {
11
+ catalogError2
12
+ } from "./52szzakm.js";
13
+
14
+ // src/contracts/catalog/routine.ts
15
+ var VOLATILITY = new Set(["volatile", "stable", "immutable"]);
16
+ var SECURITY = new Set(["invoker", "definer"]);
17
+ var TIMING = new Set(["before", "after", "instead"]);
18
+ var LEVEL = new Set(["row", "statement"]);
19
+ var EVENT_ORDER = ["insert", "update", "delete", "truncate"];
20
+ var TYPE_TEXT = /^[A-Za-z][A-Za-z0-9_ ]*(\(\d+(,\s*\d+)?\))?(\[\])*$/;
21
+ function functionObject(input) {
22
+ assertIdentifier2(input.name, "function");
23
+ const namespace = input.namespace ?? staticNamespace2("public");
24
+ assertNamespace2(namespace);
25
+ assertProvenance(input.provenance);
26
+ if (input.language !== "sql" && input.language !== "plpgsql") {
27
+ catalogError2("OKM1020", `Function ${input.name} language must be sql or plpgsql.`);
28
+ }
29
+ const volatility = input.volatility ?? "volatile";
30
+ if (!VOLATILITY.has(volatility)) {
31
+ catalogError2("OKM1020", `Function ${input.name} volatility ${volatility} is not supported.`);
32
+ }
33
+ const security = input.security ?? "invoker";
34
+ if (!SECURITY.has(security)) {
35
+ catalogError2("OKM1020", `Function ${input.name} security ${security} is not supported.`);
36
+ }
37
+ assertTypeName(input.returns, `function ${input.name} return type`);
38
+ const args = (input.arguments ?? []).map((argument) => readArgument(input.name, argument));
39
+ if (input.body.length === 0) {
40
+ catalogError2("OKM1020", `Function ${input.name} needs a body.`);
41
+ }
42
+ const atomic = input.atomic === true;
43
+ if (atomic && input.language !== "sql") {
44
+ catalogError2("OKM1020", `Function ${input.name} BEGIN ATOMIC needs language sql.`);
45
+ }
46
+ if (input.searchPath !== undefined && input.searchPath.trim().length === 0) {
47
+ catalogError2("OKM1020", `Function ${input.name} search_path is empty.`);
48
+ }
49
+ const definition = {
50
+ arguments: args,
51
+ returns: input.returns,
52
+ language: input.language,
53
+ volatility,
54
+ security,
55
+ body: input.body,
56
+ ...input.searchPath !== undefined ? { searchPath: input.searchPath } : {},
57
+ ...atomic ? { atomic: true } : {}
58
+ };
59
+ return {
60
+ kind: "function",
61
+ identity: {
62
+ kind: "function",
63
+ namespace,
64
+ name: input.name,
65
+ argTypes: args.map((arg) => arg.type)
66
+ },
67
+ owner: input.owner ?? "managed",
68
+ definition,
69
+ dependencies: normaliseEdges(input.dependencies ?? []),
70
+ provenance: input.provenance
71
+ };
72
+ }
73
+ function triggerObject(input) {
74
+ assertIdentifier2(input.name, "trigger");
75
+ assertNamespace2(input.parent.namespace);
76
+ assertIdentifier2(input.parent.name, "trigger table");
77
+ assertProvenance(input.provenance);
78
+ if (!TIMING.has(input.timing)) {
79
+ catalogError2("OKM1020", `Trigger ${input.name} timing ${input.timing} is not supported.`);
80
+ }
81
+ if (!LEVEL.has(input.level)) {
82
+ catalogError2("OKM1020", `Trigger ${input.name} level ${input.level} is not supported.`);
83
+ }
84
+ const events = EVENT_ORDER.filter((event) => input.events.includes(event));
85
+ if (events.length === 0) {
86
+ catalogError2("OKM1020", `Trigger ${input.name} needs an event.`);
87
+ }
88
+ const updateOf = input.updateOf === undefined ? undefined : [...input.updateOf];
89
+ if (updateOf !== undefined) {
90
+ if (!events.includes("update")) {
91
+ catalogError2("OKM1020", `Trigger ${input.name} lists UPDATE OF columns without an update event.`);
92
+ }
93
+ if (input.level !== "row") {
94
+ catalogError2("OKM1020", `Trigger ${input.name} UPDATE OF columns need level row.`);
95
+ }
96
+ for (const column of updateOf)
97
+ assertIdentifier2(column, "trigger column");
98
+ }
99
+ assertIdentifier2(input.calls.name, "trigger function");
100
+ assertNamespace2(input.calls.namespace);
101
+ for (const typeName of input.calls.argTypes)
102
+ assertTypeName(typeName, `trigger ${input.name}`);
103
+ const edges = [
104
+ { kind: "table", namespace: input.parent.namespace, name: input.parent.name },
105
+ {
106
+ kind: "function",
107
+ namespace: input.calls.namespace,
108
+ name: input.calls.name,
109
+ argTypes: input.calls.argTypes
110
+ },
111
+ ...(updateOf ?? []).map((column) => ({
112
+ kind: "column",
113
+ parent: input.parent,
114
+ name: column
115
+ })),
116
+ ...input.dependencies ?? []
117
+ ];
118
+ const definition = {
119
+ timing: input.timing,
120
+ events,
121
+ level: input.level,
122
+ calls: {
123
+ namespace: input.calls.namespace,
124
+ name: input.calls.name,
125
+ argTypes: [...input.calls.argTypes]
126
+ },
127
+ ...updateOf !== undefined && updateOf.length > 0 ? { updateOf } : {},
128
+ ...input.when !== undefined && input.when.length > 0 ? { when: input.when } : {}
129
+ };
130
+ return {
131
+ kind: "trigger",
132
+ identity: { kind: "trigger", parent: input.parent, name: input.name },
133
+ owner: input.owner ?? "managed",
134
+ definition,
135
+ dependencies: normaliseEdges(edges),
136
+ provenance: input.provenance
137
+ };
138
+ }
139
+ function readArgument(fn, argument) {
140
+ assertIdentifier2(argument.name, `function ${fn} argument`);
141
+ assertTypeName(argument.type, `function ${fn} argument ${argument.name}`);
142
+ return { name: argument.name, type: argument.type };
143
+ }
144
+ function assertTypeName(typeName, role) {
145
+ if (!TYPE_TEXT.test(typeName)) {
146
+ catalogError2("OKM1020", `${role} ${typeName} is not a type name.`);
147
+ }
148
+ }
149
+
150
+ export { functionObject, triggerObject };
@@ -5,9 +5,10 @@ import {
5
5
  assertBoundText,
6
6
  assertRegconfig,
7
7
  textArray
8
- } from "./zt8y0wzb.js";
8
+ } from "./n7mcc1gk.js";
9
9
  import {
10
10
  installOperatorSql,
11
+ quote,
11
12
  isRecord,
12
13
  fail
13
14
  } from "./xrfnq5k8.js";
@@ -35,6 +36,10 @@ function emitStructured(column, ref, name, value, sink) {
35
36
  emitMatches(column, ref, value, sink);
36
37
  return;
37
38
  }
39
+ if (name === "similar" || name === "wordSimilar") {
40
+ emitTrigram(column, ref, name, value, sink);
41
+ return;
42
+ }
38
43
  assertOperatorFits(column, name);
39
44
  fail("OKM1121", `${name} is not a value operator on ${column.field}. Use has, none, or every on a relation.`);
40
45
  }
@@ -135,4 +140,17 @@ function emitMatches(column, ref, value, sink) {
135
140
  sink.param(value.query);
136
141
  sink.text(")");
137
142
  }
143
+ function emitTrigram(column, ref, name, value, sink) {
144
+ if (!isRecord(value) || typeof value.query !== "string" || typeof value.schema !== "string") {
145
+ fail("OKM1121", `${name} on ${column.field} needs query text.`);
146
+ }
147
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.schema)) {
148
+ fail("OKM1121", `${name} on ${column.field} needs an extension schema name.`);
149
+ }
150
+ sink.text(ref);
151
+ sink.text(" operator(");
152
+ sink.text(quote(value.schema));
153
+ sink.text(name === "similar" ? ".%) " : ".<%) ");
154
+ sink.param(value.query);
155
+ }
138
156
  installOperatorSql(emitStructured);
@@ -3,14 +3,14 @@ import {
3
3
  noticeBuffer,
4
4
  WireSession,
5
5
  cursorStream
6
- } from "./cstgkzdx.js";
6
+ } from "./0jc3ffzf.js";
7
7
  import {
8
8
  NODE_POSTGRES_CAPABILITIES,
9
9
  driverErrors,
10
10
  rejectClosed,
11
11
  mapFailure,
12
12
  runCall
13
- } from "./9k6vetvf.js";
13
+ } from "./rrstp3kb.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("./qa5dsc7z.js").then((mod) => mod.checkout(held));
56
+ const checkout = () => closed ? rejectClosed() : import("./6bazvqwm.js").then((mod) => mod.checkout(held));
57
57
  return {
58
58
  capabilities: NODE_POSTGRES_CAPABILITIES,
59
59
  execute(text, params, options) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  withHttp
3
- } from "./mxmcdsh5.js";
3
+ } from "./k34e0xf2.js";
4
4
  import {
5
5
  decodeResult
6
6
  } from "./xrfnq5k8.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  validationGate
3
- } from "./3a5ne750.js";
3
+ } from "./9m80mkac.js";
4
4
  import {
5
5
  isOperator
6
6
  } from "./cn0n68ft.js";
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  definition,
3
3
  rejected,
4
- quoteLiteral,
5
4
  writeArray,
6
5
  readArray
7
- } from "./xatfg0gn.js";
6
+ } from "./tmbdywx0.js";
7
+ import {
8
+ quoteLiteral
9
+ } from "./94ez8kzh.js";
8
10
  import {
9
11
  REFERENTIAL_ACTIONS,
10
12
  referentialAction
@@ -1,22 +1,34 @@
1
1
  import {
2
2
  open2
3
- } from "./ecdzej21.js";
3
+ } from "./xw1d69vd.js";
4
4
  import {
5
5
  catalogHash2
6
- } from "./d2whjz4k.js";
6
+ } from "./t616ynfn.js";
7
7
  import"./n442h54c.js";
8
8
  import {
9
9
  loadMigrations
10
- } from "./rtnaqre0.js";
10
+ } from "./g4f5kcx9.js";
11
+ import {
12
+ assertCreateRole,
13
+ currentUser,
14
+ roleExists
15
+ } from "./hcmdtwgh.js";
11
16
  import {
12
- quoteIdent,
13
- planMigration,
14
17
  assertTargetPolicy,
15
18
  assertDirectConnection,
16
19
  selectTarget,
17
20
  projectHead,
18
21
  loadConfig
19
- } from "./5z4q2zda.js";
22
+ } from "./5nmdenb6.js";
23
+ import {
24
+ createdRoleName,
25
+ changesRole,
26
+ assertExtensionsAvailable,
27
+ planMigration
28
+ } from "./2ssqrv66.js";
29
+ import {
30
+ quoteIdent
31
+ } from "./wekze34d.js";
20
32
  import {
21
33
  OkmError2
22
34
  } from "./52szzakm.js";
@@ -151,6 +163,9 @@ async function applyTarget(request) {
151
163
  await lockTarget(connection, request.target);
152
164
  locked = true;
153
165
  request.onLocked?.();
166
+ const session = {};
167
+ await prepareMigrationRole(connection, request, session);
168
+ await assertExtensionsAvailable(connection, request.migrations);
154
169
  await assertUuidV7Available(connection, request.migrations);
155
170
  await connection.execute(META);
156
171
  await connection.execute(HISTORY);
@@ -162,13 +177,17 @@ async function applyTarget(request) {
162
177
  continue;
163
178
  for (const unit of units) {
164
179
  assertUnitPolicy(request, unit);
165
- await runUnit(connection, unit, request);
180
+ await runUnit(connection, unit, request, session);
166
181
  for (const item of unit.steps)
167
182
  done.add(`${unit.migrationId}:${String(item.index)}`);
168
183
  }
169
184
  applied.push(migration.id);
170
185
  }
171
- return { target: request.target, applied };
186
+ return {
187
+ target: request.target,
188
+ applied,
189
+ ...session.setRole !== undefined ? { setRole: session.setRole } : {}
190
+ };
172
191
  } finally {
173
192
  if (locked)
174
193
  await connection.execute("select pg_advisory_unlock(hashtext($1))", [
@@ -194,7 +213,8 @@ nothing to apply
194
213
  allowPooler: flags.allowPooler || config.allowPooler === true,
195
214
  ...flags.lockTimeoutMs !== undefined ? { lockTimeoutMs: flags.lockTimeoutMs } : config.timeouts?.lock !== undefined ? { lockTimeoutMs: config.timeouts.lock } : {},
196
215
  ...flags.statementTimeoutMs !== undefined ? { statementTimeoutMs: flags.statementTimeoutMs } : config.timeouts?.statement !== undefined ? { statementTimeoutMs: config.timeouts.statement } : {},
197
- migrations
216
+ migrations,
217
+ ...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
198
218
  });
199
219
  return formatReport(report);
200
220
  }
@@ -225,17 +245,20 @@ no changes
225
245
  catalogHash: catalogHash2(head.catalog),
226
246
  steps: plan.steps
227
247
  }
228
- ]
248
+ ],
249
+ ...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
229
250
  });
230
251
  return formatReport(report);
231
252
  }
232
253
  function formatReport(report) {
254
+ const role = report.setRole !== undefined ? `set role ${report.setRole}
255
+ ` : "";
233
256
  if (report.applied.length === 0)
234
257
  return `target ${report.target}
235
- nothing to apply
258
+ ${role}nothing to apply
236
259
  `;
237
260
  return `target ${report.target}
238
- ${report.applied.map((id) => `applied ${id}`).join(`
261
+ ${role}${report.applied.map((id) => `applied ${id}`).join(`
239
262
  `)}
240
263
  `;
241
264
  }
@@ -289,7 +312,31 @@ async function readDone(connection) {
289
312
  }
290
313
  return done;
291
314
  }
292
- async function runUnit(connection, unit, request) {
315
+ async function prepareMigrationRole(connection, request, session) {
316
+ const role = request.migrationRole;
317
+ const changes = request.migrations.some((migration) => migration.steps.some((step) => changesRole(step.sql)));
318
+ if (role === undefined) {
319
+ if (changes)
320
+ await assertCreateRole(connection, await currentUser(connection));
321
+ return;
322
+ }
323
+ const current = await currentUser(connection);
324
+ const exists = await roleExists(connection, role);
325
+ if (changes)
326
+ await assertCreateRole(connection, exists && current !== role ? role : current);
327
+ if (exists && current !== role)
328
+ await assumeRole(connection, role, session);
329
+ }
330
+ async function grantSchema(connection, schema, role) {
331
+ await connection.execute(`grant usage, create on schema ${quoteIdent(schema)} to ${quoteIdent(role)}`);
332
+ }
333
+ async function assumeRole(connection, role, session) {
334
+ if (session.setRole === role)
335
+ return;
336
+ await connection.execute(`set role ${quoteIdent(role)}`);
337
+ session.setRole = role;
338
+ }
339
+ async function runUnit(connection, unit, request, session) {
293
340
  const retries = request.retries ?? DEFAULT_RETRIES;
294
341
  for (let attempt = 0;attempt <= retries; attempt += 1) {
295
342
  let began = false;
@@ -302,7 +349,17 @@ async function runUnit(connection, unit, request) {
302
349
  for (const item of unit.steps) {
303
350
  current = item.index;
304
351
  await rebuildInvalidIndex(connection, item.step.sql);
305
- await connection.execute(item.step.sql);
352
+ const created = createdRoleName(item.step.sql);
353
+ const existed = created !== undefined && await roleExists(connection, created);
354
+ if (created === undefined || !existed)
355
+ await connection.execute(item.step.sql);
356
+ if (created !== undefined && created === request.migrationRole) {
357
+ if (!existed) {
358
+ await grantSchema(connection, request.schema ?? "public", created);
359
+ await connection.execute(`grant select, insert, update on okm_meta, okm_history to ${quoteIdent(created)}`);
360
+ }
361
+ await assumeRole(connection, created, session);
362
+ }
306
363
  if (!unit.transactional) {
307
364
  await connection.execute("begin");
308
365
  began = true;
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  encodeText,
3
3
  decodeText
4
- } from "./sacqha1y.js";
4
+ } from "./4m9fn52z.js";
5
5
  import {
6
6
  required,
7
7
  openColumn
8
- } from "./dd4f8mnx.js";
8
+ } from "./c9z5g0fm.js";
9
9
  import {
10
10
  definition,
11
11
  rejected
12
- } from "./xatfg0gn.js";
12
+ } from "./tmbdywx0.js";
13
13
  import {
14
14
  readClientGenerator
15
15
  } from "./rwmrejjz.js";
@@ -66,4 +66,4 @@ function uuidText() {
66
66
  }
67
67
  var uuidPattern;
68
68
 
69
- export { id2, uuid2 };
69
+ export { id2, uuid2, encodeUuid, decodeUuid };
@@ -8,12 +8,12 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
8
8
  if (code.hash === recordedHash)
9
9
  return;
10
10
  if (code.artifact !== undefined) {
11
- const { loadTrustedCatalog } = await import("./a1gdp7j9.js");
11
+ const { loadTrustedCatalog } = await import("./qybh48nd.js");
12
12
  loadTrustedCatalog(code.artifact.text, code.artifact.hash);
13
13
  } else {
14
14
  const artifact = await readCatalogFile(source.catalogDir);
15
15
  if (artifact !== undefined) {
16
- const { loadTrustedCatalog } = await import("./a1gdp7j9.js");
16
+ const { loadTrustedCatalog } = await import("./qybh48nd.js");
17
17
  loadTrustedCatalog(artifact.text, artifact.hash);
18
18
  }
19
19
  }
@@ -26,7 +26,7 @@ async function codeHash(schema, source) {
26
26
  const listed = await readHashFile(source.catalogDir);
27
27
  if (listed !== undefined)
28
28
  return { hash: listed };
29
- const { catalogHash } = await import("./a1gdp7j9.js");
29
+ const { catalogHash } = await import("./qybh48nd.js");
30
30
  return { hash: catalogHash(schemaCatalog(schema)) };
31
31
  }
32
32
  function schemaCatalog(schema) {
@@ -2,17 +2,17 @@ import {
2
2
  send2,
3
3
  reserve,
4
4
  park
5
- } from "./ytg3xf9p.js";
5
+ } from "./01yr20s5.js";
6
6
  import {
7
7
  isConnectionLost
8
8
  } from "./tbszx8mz.js";
9
9
  import {
10
10
  WireSession
11
- } from "./cstgkzdx.js";
11
+ } from "./0jc3ffzf.js";
12
12
  import {
13
13
  rejectClosed,
14
14
  runCall
15
- } from "./9k6vetvf.js";
15
+ } from "./rrstp3kb.js";
16
16
 
17
17
  // src/adapters/pg/bunsql-extra.ts
18
18
  async function checkout(held) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  catalogHash2,
3
3
  parseCatalog2
4
- } from "./d2whjz4k.js";
4
+ } from "./t616ynfn.js";
5
5
  import {
6
6
  parsePlan
7
- } from "./5z4q2zda.js";
7
+ } from "./2ssqrv66.js";
8
8
  import {
9
9
  OkmError2
10
10
  } from "./52szzakm.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  required
3
- } from "./dd4f8mnx.js";
3
+ } from "./c9z5g0fm.js";
4
4
  import {
5
5
  rejected
6
- } from "./xatfg0gn.js";
6
+ } from "./tmbdywx0.js";
7
7
 
8
8
  // src/dialects/pg/json.ts
9
9
  function jsonReplacer2(_key, value) {