okmodel 0.0.0 → 0.1.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.
- package/README.md +44 -1
- package/dist/adapters/capabilities.d.ts +62 -0
- package/dist/adapters/error.d.ts +91 -0
- package/dist/adapters/failure.d.ts +39 -0
- package/dist/adapters/pg/batch.d.ts +36 -0
- package/dist/adapters/pg/call.d.ts +59 -0
- package/dist/adapters/pg/pglite.d.ts +21 -0
- package/dist/adapters/pg/postgres-extra.d.ts +43 -0
- package/dist/adapters/pg/postgresjs.d.ts +95 -0
- package/dist/adapters/pg/result.d.ts +30 -0
- package/dist/contracts/catalog/build.d.ts +18 -0
- package/dist/contracts/catalog/document.d.ts +79 -0
- package/dist/contracts/catalog/enum.d.ts +35 -0
- package/dist/contracts/catalog/identifier.d.ts +71 -0
- package/dist/contracts/catalog/identity.d.ts +98 -0
- package/dist/contracts/catalog/index.d.ts +11 -0
- package/dist/contracts/catalog/json.d.ts +17 -0
- package/dist/contracts/catalog/object.d.ts +142 -0
- package/dist/contracts/catalog/order.d.ts +43 -0
- package/dist/contracts/catalog/rewrite.d.ts +18 -0
- package/dist/contracts/catalog/types.d.ts +292 -0
- package/dist/contracts/catalog/words.d.ts +13 -0
- package/dist/contracts/connection.d.ts +33 -0
- package/dist/contracts/driver.d.ts +163 -0
- package/dist/contracts/error.d.ts +298 -0
- package/dist/contracts/index.d.ts +11 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/internal.d.ts +15 -0
- package/dist/contracts/internal.js +68 -0
- package/dist/contracts/nearest.d.ts +15 -0
- package/dist/contracts/rows.d.ts +84 -0
- package/dist/contracts/sha256.d.ts +14 -0
- package/dist/contracts/utf8.d.ts +33 -0
- package/dist/dialects/pg/array-literal.d.ts +25 -0
- package/dist/dialects/pg/bool.d.ts +46 -0
- package/dist/dialects/pg/column.d.ts +386 -0
- package/dist/dialects/pg/compile.d.ts +81 -0
- package/dist/dialects/pg/custom.d.ts +21 -0
- package/dist/dialects/pg/ddl.d.ts +70 -0
- package/dist/dialects/pg/decimal.d.ts +62 -0
- package/dist/dialects/pg/declarations.d.ts +34 -0
- package/dist/dialects/pg/emit.d.ts +18 -0
- package/dist/dialects/pg/enum.d.ts +30 -0
- package/dist/dialects/pg/errors.d.ts +30 -0
- package/dist/dialects/pg/finite.d.ts +15 -0
- package/dist/dialects/pg/geometry.d.ts +55 -0
- package/dist/dialects/pg/index.d.ts +45 -0
- package/dist/dialects/pg/index.js +1821 -0
- package/dist/dialects/pg/integer.d.ts +96 -0
- package/dist/dialects/pg/introspect.d.ts +43 -0
- package/dist/dialects/pg/json.d.ts +43 -0
- package/dist/dialects/pg/keys.d.ts +32 -0
- package/dist/dialects/pg/misuse.d.ts +31 -0
- package/dist/dialects/pg/model.d.ts +71 -0
- package/dist/dialects/pg/namespace.d.ts +63 -0
- package/dist/dialects/pg/network.d.ts +28 -0
- package/dist/dialects/pg/operators.d.ts +71 -0
- package/dist/dialects/pg/ops/between.d.ts +10 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -0
- package/dist/dialects/pg/ops/endsWith.d.ts +8 -0
- package/dist/dialects/pg/ops/eq.d.ts +9 -0
- package/dist/dialects/pg/ops/every.d.ts +9 -0
- package/dist/dialects/pg/ops/gt.d.ts +9 -0
- package/dist/dialects/pg/ops/gte.d.ts +9 -0
- package/dist/dialects/pg/ops/has.d.ts +9 -0
- package/dist/dialects/pg/ops/ilike.d.ts +8 -0
- package/dist/dialects/pg/ops/inList.d.ts +9 -0
- package/dist/dialects/pg/ops/inc.d.ts +13 -0
- package/dist/dialects/pg/ops/like.d.ts +8 -0
- package/dist/dialects/pg/ops/lt.d.ts +9 -0
- package/dist/dialects/pg/ops/lte.d.ts +9 -0
- package/dist/dialects/pg/ops/none.d.ts +9 -0
- package/dist/dialects/pg/ops/not.d.ts +9 -0
- package/dist/dialects/pg/ops/notIn.d.ts +9 -0
- package/dist/dialects/pg/ops/or.d.ts +9 -0
- package/dist/dialects/pg/ops/startsWith.d.ts +8 -0
- package/dist/dialects/pg/quote.d.ts +24 -0
- package/dist/dialects/pg/range.d.ts +50 -0
- package/dist/dialects/pg/relations.d.ts +45 -0
- package/dist/dialects/pg/schema.d.ts +77 -0
- package/dist/dialects/pg/search.d.ts +23 -0
- package/dist/dialects/pg/table.d.ts +201 -0
- package/dist/dialects/pg/temporal.d.ts +211 -0
- package/dist/dialects/pg/text.d.ts +44 -0
- package/dist/dialects/pg/time.d.ts +46 -0
- package/dist/okm.js +2 -0
- package/dist/okmodel.js +2 -0
- package/dist/runtime/client.d.ts +47 -0
- package/dist/runtime/conflict.d.ts +38 -0
- package/dist/runtime/drift-detail.d.ts +32 -0
- package/dist/runtime/drift.d.ts +29 -0
- package/dist/runtime/include.d.ts +15 -0
- package/dist/runtime/pg/pglite.d.ts +25 -0
- package/dist/runtime/pg/pglite.js +48 -0
- package/dist/runtime/pg/postgresjs.d.ts +29 -0
- package/dist/runtime/pg/postgresjs.js +62 -0
- package/dist/runtime/plan.d.ts +167 -0
- package/dist/runtime/tx.d.ts +29 -0
- package/dist/runtime/types.d.ts +369 -0
- package/dist/runtime/write.d.ts +48 -0
- package/dist/shared/4j72449d.js +37 -0
- package/dist/shared/79ggp945.js +148 -0
- package/dist/shared/7ck0dtry.js +259 -0
- package/dist/shared/8b04d28c.js +14 -0
- package/dist/shared/ax16zpvm.js +171 -0
- package/dist/shared/ckb1p0a4.js +566 -0
- package/dist/shared/cn0n68ft.js +16 -0
- package/dist/shared/dynq16vb.js +81 -0
- package/dist/shared/f5thc1s0.js +1050 -0
- package/dist/shared/fgqgsb5z.js +281 -0
- package/dist/shared/g2v6gnc8.js +347 -0
- package/dist/shared/g5fhqmwe.js +188 -0
- package/dist/shared/gk7cs7sp.js +566 -0
- package/dist/shared/hd293j9g.js +98 -0
- package/dist/shared/j5cn2963.js +701 -0
- package/dist/shared/kynx7vbm.js +1490 -0
- package/dist/shared/mkjmqjv4.js +456 -0
- package/dist/shared/mtkwv8wx.js +18 -0
- package/dist/shared/ngk8gj61.js +40 -0
- package/dist/shared/p0cbr3g2.js +79 -0
- package/dist/shared/px90pf9p.js +396 -0
- package/dist/shared/qk3hxfja.js +83 -0
- package/dist/shared/tb4ze1tr.js +119 -0
- package/dist/shared/vkm3q4x1.js +30 -0
- package/dist/shared/w8samvk1.js +18 -0
- package/dist/shared/xy79j5hq.js +177 -0
- package/dist/shared/y9m15dfv.js +888 -0
- package/dist/shared/ycwz42az.js +412 -0
- package/dist/shared/zhc5vmgf.js +257 -0
- package/dist/tooling/cli.d.ts +1 -0
- package/dist/tooling/cli.js +193 -0
- package/dist/tooling/errors/registry.d.ts +33 -0
- package/dist/tooling/migrate/apply.d.ts +86 -0
- package/dist/tooling/migrate/commands.d.ts +21 -0
- package/dist/tooling/migrate/config.d.ts +48 -0
- package/dist/tooling/migrate/dev.d.ts +16 -0
- package/dist/tooling/migrate/equal.d.ts +15 -0
- package/dist/tooling/migrate/files.d.ts +19 -0
- package/dist/tooling/migrate/index.d.ts +7 -0
- package/dist/tooling/migrate/index.js +7 -0
- package/dist/tooling/migrate/plan.d.ts +76 -0
- package/dist/tooling/migrate/policy.d.ts +78 -0
- package/dist/tooling/migrate/project.d.ts +69 -0
- package/dist/tooling/migrate/status.d.ts +74 -0
- package/dist/tooling/migrate/values.d.ts +29 -0
- package/package.json +94 -7
- package/dist/index.js +0 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertIdentifier2,
|
|
3
|
+
fitIdentifier2,
|
|
4
|
+
deterministicName2,
|
|
5
|
+
assertStoredText
|
|
6
|
+
} from "./mkjmqjv4.js";
|
|
7
|
+
import {
|
|
8
|
+
catalogError2
|
|
9
|
+
} from "./ycwz42az.js";
|
|
10
|
+
|
|
11
|
+
// src/contracts/catalog/types.ts
|
|
12
|
+
var OWNERS2 = ["managed", "external", "ignored"];
|
|
13
|
+
var OBJECT_KINDS2 = [
|
|
14
|
+
"table",
|
|
15
|
+
"column",
|
|
16
|
+
"index",
|
|
17
|
+
"constraint",
|
|
18
|
+
"sequence",
|
|
19
|
+
"view",
|
|
20
|
+
"materializedView",
|
|
21
|
+
"type",
|
|
22
|
+
"function",
|
|
23
|
+
"trigger",
|
|
24
|
+
"policy",
|
|
25
|
+
"extension",
|
|
26
|
+
"role",
|
|
27
|
+
"grant",
|
|
28
|
+
"defaultPrivilege"
|
|
29
|
+
];
|
|
30
|
+
var BUILT_KINDS2 = ["table", "column", "index", "constraint", "sequence", "type"];
|
|
31
|
+
var OBJECT_OPERATIONS2 = [
|
|
32
|
+
"create",
|
|
33
|
+
"replace",
|
|
34
|
+
"alter",
|
|
35
|
+
"drop",
|
|
36
|
+
"recreateWithDependents"
|
|
37
|
+
];
|
|
38
|
+
var KIND_OPERATIONS2 = {
|
|
39
|
+
table: ["create", "alter", "drop", "recreateWithDependents"],
|
|
40
|
+
column: ["create", "alter", "drop", "recreateWithDependents"],
|
|
41
|
+
index: ["create", "drop", "recreateWithDependents"],
|
|
42
|
+
constraint: ["create", "alter", "drop", "recreateWithDependents"],
|
|
43
|
+
sequence: ["create", "alter", "drop"],
|
|
44
|
+
view: ["create", "replace", "drop", "recreateWithDependents"],
|
|
45
|
+
materializedView: ["create", "drop", "recreateWithDependents"],
|
|
46
|
+
type: ["create", "alter", "drop"],
|
|
47
|
+
function: ["create", "replace", "drop", "recreateWithDependents"],
|
|
48
|
+
trigger: ["create", "drop", "recreateWithDependents"],
|
|
49
|
+
policy: ["create", "alter", "drop"],
|
|
50
|
+
extension: ["create", "alter", "drop"],
|
|
51
|
+
role: ["create", "alter"],
|
|
52
|
+
grant: ["create", "drop"],
|
|
53
|
+
defaultPrivilege: ["create", "alter", "drop"]
|
|
54
|
+
};
|
|
55
|
+
var REFERENTIAL_ACTIONS = [
|
|
56
|
+
"cascade",
|
|
57
|
+
"no action",
|
|
58
|
+
"restrict",
|
|
59
|
+
"set default",
|
|
60
|
+
"set null"
|
|
61
|
+
];
|
|
62
|
+
function referentialAction(value) {
|
|
63
|
+
for (const action of REFERENTIAL_ACTIONS) {
|
|
64
|
+
if (action === value) {
|
|
65
|
+
return action;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
var CATALOG_VERSION2 = 1;
|
|
71
|
+
|
|
72
|
+
// src/contracts/catalog/json.ts
|
|
73
|
+
function canonicalJson(value) {
|
|
74
|
+
return encode(value);
|
|
75
|
+
}
|
|
76
|
+
function encode(value) {
|
|
77
|
+
if (value === null) {
|
|
78
|
+
return "null";
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === "boolean") {
|
|
81
|
+
return value ? "true" : "false";
|
|
82
|
+
}
|
|
83
|
+
if (typeof value === "number") {
|
|
84
|
+
if (!Number.isSafeInteger(value)) {
|
|
85
|
+
catalogError2("OKM1020", "Catalog JSON cannot encode a non-integer number.");
|
|
86
|
+
}
|
|
87
|
+
return String(value);
|
|
88
|
+
}
|
|
89
|
+
if (typeof value === "string") {
|
|
90
|
+
return encodeString(value);
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(value)) {
|
|
93
|
+
return `[${value.map((item) => encode(item)).join(",")}]`;
|
|
94
|
+
}
|
|
95
|
+
if (!isJsonRecord(value)) {
|
|
96
|
+
catalogError2("OKM1020", "Catalog JSON cannot encode this value.");
|
|
97
|
+
}
|
|
98
|
+
const keys = Object.keys(value).sort();
|
|
99
|
+
const parts = [];
|
|
100
|
+
for (const key of keys) {
|
|
101
|
+
const item = value[key];
|
|
102
|
+
if (item === undefined) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
parts.push(`${encodeString(key)}:${encode(item)}`);
|
|
106
|
+
}
|
|
107
|
+
return `{${parts.join(",")}}`;
|
|
108
|
+
}
|
|
109
|
+
function isJsonRecord(value) {
|
|
110
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
111
|
+
}
|
|
112
|
+
function encodeString(value) {
|
|
113
|
+
for (let index = 0;index < value.length; index++) {
|
|
114
|
+
const code = value.charCodeAt(index);
|
|
115
|
+
if (code === 34 || code === 92 || code < 32 || code > 126) {
|
|
116
|
+
return encodeEscaped(value);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return `"${value}"`;
|
|
120
|
+
}
|
|
121
|
+
function encodeEscaped(value) {
|
|
122
|
+
const parts = ['"'];
|
|
123
|
+
let start = 0;
|
|
124
|
+
for (let index = 0;index < value.length; ) {
|
|
125
|
+
const code = value.charCodeAt(index);
|
|
126
|
+
const next = value.charCodeAt(index + 1);
|
|
127
|
+
if (code >= 55296 && code <= 56319 && next >= 56320 && next <= 57343) {
|
|
128
|
+
if (index > start) {
|
|
129
|
+
parts.push(value.slice(start, index));
|
|
130
|
+
}
|
|
131
|
+
parts.push(hexEscape(code), hexEscape(next));
|
|
132
|
+
index += 2;
|
|
133
|
+
start = index;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (needsEscape(code)) {
|
|
137
|
+
if (index > start) {
|
|
138
|
+
parts.push(value.slice(start, index));
|
|
139
|
+
}
|
|
140
|
+
parts.push(escapeUnit(code));
|
|
141
|
+
index += 1;
|
|
142
|
+
start = index;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
index += 1;
|
|
146
|
+
}
|
|
147
|
+
if (start < value.length) {
|
|
148
|
+
parts.push(value.slice(start));
|
|
149
|
+
}
|
|
150
|
+
parts.push('"');
|
|
151
|
+
return parts.join("");
|
|
152
|
+
}
|
|
153
|
+
function needsEscape(code) {
|
|
154
|
+
return code === 34 || code === 92 || code < 32 || code > 126;
|
|
155
|
+
}
|
|
156
|
+
function escapeUnit(code) {
|
|
157
|
+
if (code === 34) {
|
|
158
|
+
return "\\\"";
|
|
159
|
+
}
|
|
160
|
+
if (code === 92) {
|
|
161
|
+
return "\\\\";
|
|
162
|
+
}
|
|
163
|
+
if (code === 8) {
|
|
164
|
+
return "\\b";
|
|
165
|
+
}
|
|
166
|
+
if (code === 12) {
|
|
167
|
+
return "\\f";
|
|
168
|
+
}
|
|
169
|
+
if (code === 10) {
|
|
170
|
+
return "\\n";
|
|
171
|
+
}
|
|
172
|
+
if (code === 13) {
|
|
173
|
+
return "\\r";
|
|
174
|
+
}
|
|
175
|
+
if (code === 9) {
|
|
176
|
+
return "\\t";
|
|
177
|
+
}
|
|
178
|
+
return hexEscape(code);
|
|
179
|
+
}
|
|
180
|
+
function hexEscape(code) {
|
|
181
|
+
return `\\u${code.toString(16).padStart(4, "0")}`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/contracts/catalog/identity.ts
|
|
185
|
+
var UUID_HEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
186
|
+
function staticNamespace2(name) {
|
|
187
|
+
assertIdentifier2(name, "namespace");
|
|
188
|
+
return { form: "static", name };
|
|
189
|
+
}
|
|
190
|
+
function templateNamespace2(pattern) {
|
|
191
|
+
const placeholders = pattern.split("{id}").length - 1;
|
|
192
|
+
if (placeholders < 1) {
|
|
193
|
+
catalogError2("OKM1122", `Namespace template ${pattern} must contain {id}.`);
|
|
194
|
+
}
|
|
195
|
+
const stripped = pattern.replaceAll("{id}", "");
|
|
196
|
+
if (!/^[A-Za-z0-9_]*$/.test(stripped)) {
|
|
197
|
+
catalogError2("OKM1122", `Namespace template ${pattern} may contain only letters, digits, underscores, and {id}.`);
|
|
198
|
+
}
|
|
199
|
+
return { form: "template", pattern };
|
|
200
|
+
}
|
|
201
|
+
function assertNamespace2(namespace) {
|
|
202
|
+
if (namespace.form === "static") {
|
|
203
|
+
assertIdentifier2(namespace.name, "namespace");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
templateNamespace2(namespace.pattern);
|
|
207
|
+
}
|
|
208
|
+
function resolveNamespace2(namespace, tenantId = "") {
|
|
209
|
+
if (namespace.form === "static") {
|
|
210
|
+
assertIdentifier2(namespace.name, "namespace");
|
|
211
|
+
return namespace.name;
|
|
212
|
+
}
|
|
213
|
+
const resolved = namespace.pattern.replaceAll("{id}", canonicalTenantId(tenantId));
|
|
214
|
+
assertIdentifier2(resolved, "namespace");
|
|
215
|
+
return resolved;
|
|
216
|
+
}
|
|
217
|
+
function identityKey2(identity) {
|
|
218
|
+
const plain = plainIdentityKey(identity);
|
|
219
|
+
if (plain !== undefined) {
|
|
220
|
+
return plain;
|
|
221
|
+
}
|
|
222
|
+
return canonicalJson(identityToJson(identity));
|
|
223
|
+
}
|
|
224
|
+
function plainIdentityKey(identity) {
|
|
225
|
+
switch (identity.kind) {
|
|
226
|
+
case "table":
|
|
227
|
+
case "view":
|
|
228
|
+
case "materializedView":
|
|
229
|
+
case "sequence":
|
|
230
|
+
case "type":
|
|
231
|
+
return namespaceIdentityKey(identity.kind, identity.name, identity.namespace);
|
|
232
|
+
case "column":
|
|
233
|
+
case "index":
|
|
234
|
+
case "constraint":
|
|
235
|
+
case "trigger":
|
|
236
|
+
case "policy":
|
|
237
|
+
return anchoredIdentityKey(identity.kind, identity.name, identity.parent);
|
|
238
|
+
case "role":
|
|
239
|
+
case "extension":
|
|
240
|
+
if (!isPlainJsonText(identity.name)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
return `{"kind":"${identity.kind}","name":"${identity.name}"}`;
|
|
244
|
+
default:
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function namespaceIdentityKey(kind, name, namespace) {
|
|
249
|
+
const encoded = staticNamespaceKey(namespace);
|
|
250
|
+
if (encoded === undefined || !isPlainJsonText(name)) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
return `{"kind":"${kind}","name":"${name}","namespace":${encoded}}`;
|
|
254
|
+
}
|
|
255
|
+
function anchoredIdentityKey(kind, name, parent) {
|
|
256
|
+
const encoded = staticNamespaceKey(parent.namespace);
|
|
257
|
+
if (encoded === undefined || !isPlainJsonText(name) || !isPlainJsonText(parent.name)) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
return `{"kind":"${kind}","name":"${name}","parent":{"name":"${parent.name}","namespace":${encoded}}}`;
|
|
261
|
+
}
|
|
262
|
+
function staticNamespaceKey(namespace) {
|
|
263
|
+
if (namespace.form !== "static" || !isPlainJsonText(namespace.name)) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
return `{"form":"static","name":"${namespace.name}"}`;
|
|
267
|
+
}
|
|
268
|
+
function isPlainJsonText(value) {
|
|
269
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
270
|
+
const code = value.charCodeAt(index);
|
|
271
|
+
if (code === 34 || code === 92 || code < 32 || code > 126) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
function identifierLimitApplies2(kind) {
|
|
278
|
+
return kind !== "grant" && kind !== "defaultPrivilege";
|
|
279
|
+
}
|
|
280
|
+
function identityLabel2(identity) {
|
|
281
|
+
if (identity.kind === "grant") {
|
|
282
|
+
return `grant ${identity.role} ${identity.privilege}`;
|
|
283
|
+
}
|
|
284
|
+
if (identity.kind === "defaultPrivilege") {
|
|
285
|
+
return `default privilege ${identity.grantee} ${identity.privilege}`;
|
|
286
|
+
}
|
|
287
|
+
return `${identity.kind} ${identity.name}`;
|
|
288
|
+
}
|
|
289
|
+
function sameRef2(left, right) {
|
|
290
|
+
return left.name === right.name && sameNamespace2(left.namespace, right.namespace);
|
|
291
|
+
}
|
|
292
|
+
function sameNamespace2(left, right) {
|
|
293
|
+
if (left.form !== right.form) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
if (left.form === "static" && right.form === "static") {
|
|
297
|
+
return left.name === right.name;
|
|
298
|
+
}
|
|
299
|
+
if (left.form === "template" && right.form === "template") {
|
|
300
|
+
return left.pattern === right.pattern;
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
function identityToJson(identity) {
|
|
305
|
+
switch (identity.kind) {
|
|
306
|
+
case "table":
|
|
307
|
+
case "view":
|
|
308
|
+
case "materializedView":
|
|
309
|
+
case "sequence":
|
|
310
|
+
case "type":
|
|
311
|
+
return namespaceIdentityJson(identity);
|
|
312
|
+
case "column":
|
|
313
|
+
case "index":
|
|
314
|
+
case "constraint":
|
|
315
|
+
case "trigger":
|
|
316
|
+
case "policy":
|
|
317
|
+
return {
|
|
318
|
+
kind: identity.kind,
|
|
319
|
+
name: identity.name,
|
|
320
|
+
parent: refToJson(identity.parent)
|
|
321
|
+
};
|
|
322
|
+
case "function":
|
|
323
|
+
return functionIdentityJson(identity);
|
|
324
|
+
case "grant":
|
|
325
|
+
return grantIdentityJson(identity);
|
|
326
|
+
case "defaultPrivilege":
|
|
327
|
+
return defaultPrivilegeIdentityJson(identity);
|
|
328
|
+
case "role":
|
|
329
|
+
case "extension":
|
|
330
|
+
return { kind: identity.kind, name: identity.name };
|
|
331
|
+
default:
|
|
332
|
+
return assertNever(identity);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function namespaceToJson(namespace) {
|
|
336
|
+
if (namespace.form === "static") {
|
|
337
|
+
return { form: "static", name: namespace.name };
|
|
338
|
+
}
|
|
339
|
+
return { form: "template", pattern: namespace.pattern };
|
|
340
|
+
}
|
|
341
|
+
function namespaceIdentityJson(identity) {
|
|
342
|
+
return {
|
|
343
|
+
kind: identity.kind,
|
|
344
|
+
name: identity.name,
|
|
345
|
+
namespace: namespaceToJson(identity.namespace)
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function functionIdentityJson(identity) {
|
|
349
|
+
return {
|
|
350
|
+
argTypes: identity.argTypes,
|
|
351
|
+
kind: identity.kind,
|
|
352
|
+
name: identity.name,
|
|
353
|
+
namespace: namespaceToJson(identity.namespace)
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function grantIdentityJson(identity) {
|
|
357
|
+
return {
|
|
358
|
+
kind: identity.kind,
|
|
359
|
+
object: {
|
|
360
|
+
kind: identity.object.kind,
|
|
361
|
+
name: identity.object.name,
|
|
362
|
+
namespace: namespaceToJson(identity.object.namespace)
|
|
363
|
+
},
|
|
364
|
+
privilege: identity.privilege,
|
|
365
|
+
role: identity.role
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function defaultPrivilegeIdentityJson(identity) {
|
|
369
|
+
return {
|
|
370
|
+
forRole: identity.forRole,
|
|
371
|
+
grantee: identity.grantee,
|
|
372
|
+
kind: identity.kind,
|
|
373
|
+
namespace: namespaceToJson(identity.namespace),
|
|
374
|
+
objectKind: identity.objectKind,
|
|
375
|
+
privilege: identity.privilege
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function refToJson(ref) {
|
|
379
|
+
return { name: ref.name, namespace: namespaceToJson(ref.namespace) };
|
|
380
|
+
}
|
|
381
|
+
function canonicalTenantId(tenantId) {
|
|
382
|
+
if (UUID_HEX.test(tenantId)) {
|
|
383
|
+
return tenantId.replaceAll("-", "").toLowerCase();
|
|
384
|
+
}
|
|
385
|
+
if (/^[a-z0-9_]+$/.test(tenantId)) {
|
|
386
|
+
return tenantId;
|
|
387
|
+
}
|
|
388
|
+
catalogError2("OKM1122", `Tenant id ${tenantId} must be a UUID or lowercase [a-z0-9_].`);
|
|
389
|
+
}
|
|
390
|
+
function assertNever(value) {
|
|
391
|
+
return catalogError2("OKM1020", `Unexpected identity ${JSON.stringify(value)}.`);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/contracts/catalog/object.ts
|
|
395
|
+
function table3(input) {
|
|
396
|
+
assertNamespace2(input.namespace);
|
|
397
|
+
assertIdentifier2(input.name, "table");
|
|
398
|
+
assertProvenance(input.provenance);
|
|
399
|
+
const identity = {
|
|
400
|
+
kind: "table",
|
|
401
|
+
namespace: input.namespace,
|
|
402
|
+
name: input.name
|
|
403
|
+
};
|
|
404
|
+
const definition = input.partition === undefined ? {} : { partition: copyPartition(input.partition) };
|
|
405
|
+
return {
|
|
406
|
+
kind: "table",
|
|
407
|
+
identity,
|
|
408
|
+
owner: input.owner ?? "managed",
|
|
409
|
+
definition,
|
|
410
|
+
dependencies: normaliseEdges(input.dependencies ?? []),
|
|
411
|
+
provenance: input.provenance
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function column2(input) {
|
|
415
|
+
assertNamespace2(input.parent.namespace);
|
|
416
|
+
assertIdentifier2(input.name, "column");
|
|
417
|
+
assertIdentifier2(input.parent.name, "column parent");
|
|
418
|
+
assertProvenance(input.provenance);
|
|
419
|
+
assertStoredText(input.dataType, "column type");
|
|
420
|
+
if (input.dataType.length === 0) {
|
|
421
|
+
catalogError2("OKM1020", `Column ${input.name} has no data type.`);
|
|
422
|
+
}
|
|
423
|
+
const modes = [
|
|
424
|
+
input.defaultExpression !== undefined,
|
|
425
|
+
input.identity !== undefined,
|
|
426
|
+
input.generated !== undefined
|
|
427
|
+
].filter(Boolean).length;
|
|
428
|
+
if (modes > 1) {
|
|
429
|
+
catalogError2("OKM1020", `Column ${input.name} sets more than one of default, identity, and generated. Set only one.`);
|
|
430
|
+
}
|
|
431
|
+
if (input.defaultExpression !== undefined) {
|
|
432
|
+
assertStoredText(input.defaultExpression, "column default");
|
|
433
|
+
}
|
|
434
|
+
if (input.generated !== undefined) {
|
|
435
|
+
assertStoredText(input.generated.expression, "column generated expression");
|
|
436
|
+
}
|
|
437
|
+
const identity = {
|
|
438
|
+
kind: "column",
|
|
439
|
+
parent: input.parent,
|
|
440
|
+
name: input.name
|
|
441
|
+
};
|
|
442
|
+
const definition = {
|
|
443
|
+
dataType: input.dataType,
|
|
444
|
+
nullable: input.nullable,
|
|
445
|
+
...input.defaultExpression !== undefined ? { defaultExpression: input.defaultExpression } : {},
|
|
446
|
+
...input.identity !== undefined ? { identity: { always: input.identity.always } } : {},
|
|
447
|
+
...input.generated !== undefined ? {
|
|
448
|
+
generated: {
|
|
449
|
+
stored: input.generated.stored,
|
|
450
|
+
expression: input.generated.expression
|
|
451
|
+
}
|
|
452
|
+
} : {}
|
|
453
|
+
};
|
|
454
|
+
return {
|
|
455
|
+
kind: "column",
|
|
456
|
+
identity,
|
|
457
|
+
owner: input.owner ?? "managed",
|
|
458
|
+
definition,
|
|
459
|
+
dependencies: normaliseEdges([tableIdentity(input.parent), ...input.dependencies ?? []]),
|
|
460
|
+
provenance: input.provenance
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function index3(input) {
|
|
464
|
+
assertNamespace2(input.parent.namespace);
|
|
465
|
+
assertIdentifier2(input.parent.name, "index parent");
|
|
466
|
+
assertProvenance(input.provenance);
|
|
467
|
+
const columns = [...input.columns ?? []];
|
|
468
|
+
for (const name of columns) {
|
|
469
|
+
assertIdentifier2(name, "index column");
|
|
470
|
+
}
|
|
471
|
+
if (columns.length === 0 && input.expression === undefined) {
|
|
472
|
+
catalogError2("OKM1020", `Index on ${input.parent.name} needs a column or an expression.`);
|
|
473
|
+
}
|
|
474
|
+
if (input.predicate !== undefined) {
|
|
475
|
+
assertStoredText(input.predicate, "index predicate");
|
|
476
|
+
}
|
|
477
|
+
if (input.expression !== undefined) {
|
|
478
|
+
assertStoredText(input.expression, "index expression");
|
|
479
|
+
}
|
|
480
|
+
const nameKey = input.nameKey ?? (columns.length > 0 ? columns.join("_") : "expr");
|
|
481
|
+
assertIdentifierTextKey(nameKey);
|
|
482
|
+
const name = input.name === undefined ? deterministicName2({ parent: input.parent.name, purpose: "index", nameKey }) : fitIdentifier2(input.name);
|
|
483
|
+
const identity = {
|
|
484
|
+
kind: "index",
|
|
485
|
+
parent: input.parent,
|
|
486
|
+
name
|
|
487
|
+
};
|
|
488
|
+
const definition = {
|
|
489
|
+
columns,
|
|
490
|
+
unique: input.unique ?? false,
|
|
491
|
+
nameKey,
|
|
492
|
+
...input.predicate !== undefined ? { predicate: input.predicate } : {},
|
|
493
|
+
...input.expression !== undefined ? { expression: input.expression } : {}
|
|
494
|
+
};
|
|
495
|
+
return {
|
|
496
|
+
kind: "index",
|
|
497
|
+
identity,
|
|
498
|
+
owner: input.owner ?? "managed",
|
|
499
|
+
definition,
|
|
500
|
+
dependencies: normaliseEdges([
|
|
501
|
+
tableIdentity(input.parent),
|
|
502
|
+
...columns.map((columnName) => columnIdentity(input.parent, columnName)),
|
|
503
|
+
...input.dependencies ?? []
|
|
504
|
+
]),
|
|
505
|
+
provenance: input.provenance
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function constraint2(input) {
|
|
509
|
+
assertNamespace2(input.parent.namespace);
|
|
510
|
+
assertIdentifier2(input.parent.name, "constraint parent");
|
|
511
|
+
assertProvenance(input.provenance);
|
|
512
|
+
const columns = [...input.columns ?? []];
|
|
513
|
+
for (const name of columns) {
|
|
514
|
+
assertIdentifier2(name, "constraint column");
|
|
515
|
+
}
|
|
516
|
+
const deferrable = input.deferrable ?? false;
|
|
517
|
+
const initially = input.initially ?? "immediate";
|
|
518
|
+
if (initially === "deferred" && !deferrable) {
|
|
519
|
+
catalogError2("OKM1020", `Constraint on ${input.parent.name} is initially deferred but not deferrable.`);
|
|
520
|
+
}
|
|
521
|
+
const nullsNotDistinct = input.nullsNotDistinct ?? false;
|
|
522
|
+
if (nullsNotDistinct && input.constraintKind !== "primaryKey" && input.constraintKind !== "unique") {
|
|
523
|
+
catalogError2("OKM1020", `Constraint on ${input.parent.name} sets nullsNotDistinct on ${input.constraintKind}. nullsNotDistinct applies only to a primary key or a unique constraint.`);
|
|
524
|
+
}
|
|
525
|
+
if (input.constraintKind === "foreignKey") {
|
|
526
|
+
if (input.references === undefined || input.references.columns.length === 0 || columns.length === 0) {
|
|
527
|
+
catalogError2("OKM1021", `Foreign key on ${input.parent.name} is missing its target.`);
|
|
528
|
+
}
|
|
529
|
+
} else if (input.constraintKind === "check") {
|
|
530
|
+
if (input.expression === undefined || input.expression.length === 0) {
|
|
531
|
+
catalogError2("OKM1020", `Check on ${input.parent.name} needs an expression.`);
|
|
532
|
+
}
|
|
533
|
+
} else if (columns.length === 0) {
|
|
534
|
+
catalogError2("OKM1020", `${input.constraintKind} on ${input.parent.name} needs a column.`);
|
|
535
|
+
}
|
|
536
|
+
if (input.expression !== undefined) {
|
|
537
|
+
assertStoredText(input.expression, "constraint expression");
|
|
538
|
+
}
|
|
539
|
+
const references = input.references;
|
|
540
|
+
if (references !== undefined) {
|
|
541
|
+
assertNamespace2(references.parent.namespace);
|
|
542
|
+
assertIdentifier2(references.parent.name, "referenced table");
|
|
543
|
+
for (const name of references.columns) {
|
|
544
|
+
assertIdentifier2(name, "referenced column");
|
|
545
|
+
}
|
|
546
|
+
assertAction(references.onDelete, input.parent.name);
|
|
547
|
+
assertAction(references.onUpdate, input.parent.name);
|
|
548
|
+
}
|
|
549
|
+
if (input.constraintKind === "check" && columns.length === 0 && (input.nameKey === undefined || input.nameKey.length === 0)) {
|
|
550
|
+
catalogError2("OKM1020", `Check on ${input.parent.name} needs a name key.`);
|
|
551
|
+
}
|
|
552
|
+
const nameKey = input.nameKey ?? defaultNameKey(input.constraintKind, columns);
|
|
553
|
+
assertIdentifierTextKey(nameKey);
|
|
554
|
+
const name = input.name === undefined ? deterministicName2({
|
|
555
|
+
parent: input.parent.name,
|
|
556
|
+
purpose: input.constraintKind,
|
|
557
|
+
nameKey
|
|
558
|
+
}) : fitIdentifier2(input.name);
|
|
559
|
+
const identity = {
|
|
560
|
+
kind: "constraint",
|
|
561
|
+
parent: input.parent,
|
|
562
|
+
name
|
|
563
|
+
};
|
|
564
|
+
const definition = {
|
|
565
|
+
constraintKind: input.constraintKind,
|
|
566
|
+
columns,
|
|
567
|
+
nameKey,
|
|
568
|
+
deferrable,
|
|
569
|
+
initially,
|
|
570
|
+
nullsNotDistinct,
|
|
571
|
+
...input.expression !== undefined ? { expression: input.expression } : {},
|
|
572
|
+
...references !== undefined ? {
|
|
573
|
+
references: {
|
|
574
|
+
parent: references.parent,
|
|
575
|
+
columns: [...references.columns],
|
|
576
|
+
...references.onDelete !== undefined ? { onDelete: references.onDelete } : {},
|
|
577
|
+
...references.onUpdate !== undefined ? { onUpdate: references.onUpdate } : {}
|
|
578
|
+
}
|
|
579
|
+
} : {}
|
|
580
|
+
};
|
|
581
|
+
const targets = [
|
|
582
|
+
tableIdentity(input.parent),
|
|
583
|
+
...columns.map((columnName) => columnIdentity(input.parent, columnName))
|
|
584
|
+
];
|
|
585
|
+
if (references !== undefined) {
|
|
586
|
+
targets.push(tableIdentity(references.parent));
|
|
587
|
+
for (const columnName of references.columns) {
|
|
588
|
+
targets.push(columnIdentity(references.parent, columnName));
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
targets.push(...input.dependencies ?? []);
|
|
592
|
+
return {
|
|
593
|
+
kind: "constraint",
|
|
594
|
+
identity,
|
|
595
|
+
owner: input.owner ?? "managed",
|
|
596
|
+
definition,
|
|
597
|
+
dependencies: normaliseEdges(targets),
|
|
598
|
+
provenance: input.provenance
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
function sequence2(input) {
|
|
602
|
+
assertNamespace2(input.namespace);
|
|
603
|
+
assertIdentifier2(input.name, "sequence");
|
|
604
|
+
assertProvenance(input.provenance);
|
|
605
|
+
const start = input.start ?? "1";
|
|
606
|
+
const increment = input.increment ?? "1";
|
|
607
|
+
assertInteger(start, "sequence start");
|
|
608
|
+
assertInteger(increment, "sequence increment");
|
|
609
|
+
if (increment === "0" || increment === "-0") {
|
|
610
|
+
catalogError2("OKM1020", `Sequence ${input.name} has a zero increment.`);
|
|
611
|
+
}
|
|
612
|
+
const identity = {
|
|
613
|
+
kind: "sequence",
|
|
614
|
+
namespace: input.namespace,
|
|
615
|
+
name: input.name
|
|
616
|
+
};
|
|
617
|
+
return {
|
|
618
|
+
kind: "sequence",
|
|
619
|
+
identity,
|
|
620
|
+
owner: input.owner ?? "managed",
|
|
621
|
+
definition: {
|
|
622
|
+
dataType: input.dataType ?? "bigint",
|
|
623
|
+
start,
|
|
624
|
+
increment,
|
|
625
|
+
cycle: input.cycle ?? false
|
|
626
|
+
},
|
|
627
|
+
dependencies: normaliseEdges(input.dependencies ?? []),
|
|
628
|
+
provenance: input.provenance
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
function normaliseEdges(targets) {
|
|
632
|
+
const byKey = new Map;
|
|
633
|
+
for (const target of targets) {
|
|
634
|
+
const key = identityKey2(target);
|
|
635
|
+
if (!byKey.has(key)) {
|
|
636
|
+
byKey.set(key, target);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
return [...byKey.entries()].sort((left, right) => compareText(left[0], right[0])).map(([, target]) => ({ target }));
|
|
640
|
+
}
|
|
641
|
+
function compareText(left, right) {
|
|
642
|
+
if (left < right) {
|
|
643
|
+
return -1;
|
|
644
|
+
}
|
|
645
|
+
if (left > right) {
|
|
646
|
+
return 1;
|
|
647
|
+
}
|
|
648
|
+
return 0;
|
|
649
|
+
}
|
|
650
|
+
function tableIdentity(parent) {
|
|
651
|
+
return { kind: "table", namespace: parent.namespace, name: parent.name };
|
|
652
|
+
}
|
|
653
|
+
function columnIdentity(parent, name) {
|
|
654
|
+
return { kind: "column", parent, name };
|
|
655
|
+
}
|
|
656
|
+
function defaultNameKey(kind, columns) {
|
|
657
|
+
if (kind === "primaryKey") {
|
|
658
|
+
return "pkey";
|
|
659
|
+
}
|
|
660
|
+
return columns.join("_");
|
|
661
|
+
}
|
|
662
|
+
function assertIdentifierTextKey(nameKey) {
|
|
663
|
+
if (nameKey.length === 0) {
|
|
664
|
+
catalogError2("OKM1122", "Name key is empty.");
|
|
665
|
+
}
|
|
666
|
+
if (nameKey.includes("\x00")) {
|
|
667
|
+
catalogError2("OKM1122", "Name key contains NUL.");
|
|
668
|
+
}
|
|
669
|
+
assertStoredText(nameKey, "Name key");
|
|
670
|
+
}
|
|
671
|
+
function assertInteger(value, role) {
|
|
672
|
+
assertStoredText(value, role);
|
|
673
|
+
if (!/^-?\d+$/.test(value)) {
|
|
674
|
+
catalogError2("OKM1020", `${role} ${value} is not an integer.`);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function assertAction(action, parent) {
|
|
678
|
+
if (action === undefined) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (referentialAction(action) === undefined) {
|
|
682
|
+
catalogError2("OKM1020", `Foreign key on ${parent} has referential action ${action}. Accepted actions: cascade, no action, restrict, set default, set null.`);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
function assertProvenance(provenance) {
|
|
686
|
+
assertStoredText(provenance.name, "provenance");
|
|
687
|
+
if (provenance.name.length === 0) {
|
|
688
|
+
catalogError2("OKM1020", "Provenance name is empty.");
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
function copyPartition(partition) {
|
|
692
|
+
if (partition.columns.length === 0) {
|
|
693
|
+
catalogError2("OKM1020", "Partition needs a column.");
|
|
694
|
+
}
|
|
695
|
+
for (const name of partition.columns) {
|
|
696
|
+
assertIdentifier2(name, "partition column");
|
|
697
|
+
}
|
|
698
|
+
return { method: partition.method, columns: [...partition.columns] };
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
export { OWNERS2, OBJECT_KINDS2, BUILT_KINDS2, OBJECT_OPERATIONS2, KIND_OPERATIONS2, REFERENTIAL_ACTIONS, referentialAction, CATALOG_VERSION2, canonicalJson, staticNamespace2, templateNamespace2, assertNamespace2, resolveNamespace2, identityKey2, identifierLimitApplies2, identityLabel2, sameRef2, sameNamespace2, identityToJson, namespaceToJson, table3, column2, index3, constraint2, sequence2, normaliseEdges, compareText, assertProvenance };
|