okmodel 0.2.1 → 0.4.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 +882 -48
- package/dist/contracts/catalog/document.d.ts +6 -2
- package/dist/contracts/catalog/enum.d.ts +31 -4
- package/dist/contracts/catalog/extension.d.ts +61 -0
- package/dist/contracts/catalog/privilege.d.ts +64 -0
- package/dist/contracts/catalog/routine.d.ts +56 -0
- package/dist/contracts/catalog/types.d.ts +164 -10
- package/dist/contracts/catalog/view.d.ts +73 -0
- package/dist/dialects/pg/column.d.ts +3 -1
- package/dist/dialects/pg/ddl.d.ts +65 -1
- package/dist/dialects/pg/enum.d.ts +10 -8
- package/dist/dialects/pg/ext/citext.d.ts +14 -0
- package/dist/dialects/pg/ext/citext.js +11 -0
- package/dist/dialects/pg/ext/index.d.ts +52 -0
- package/dist/dialects/pg/ext/index.js +6 -0
- package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
- package/dist/dialects/pg/ext/pg-trgm.js +42 -0
- package/dist/dialects/pg/fn/index.d.ts +107 -0
- package/dist/dialects/pg/fn/index.js +175 -0
- package/dist/dialects/pg/fn/touch.d.ts +14 -0
- package/dist/dialects/pg/index.js +104 -19
- package/dist/dialects/pg/introspect.d.ts +10 -1
- package/dist/dialects/pg/operators.d.ts +8 -1
- package/dist/dialects/pg/role/check.d.ts +45 -0
- package/dist/dialects/pg/role/index.d.ts +50 -0
- package/dist/dialects/pg/role/sql.d.ts +51 -0
- package/dist/dialects/pg/table.d.ts +24 -1
- package/dist/dialects/pg/tenancy.d.ts +9 -0
- package/dist/dialects/pg/view/client.d.ts +30 -0
- package/dist/dialects/pg/view/depend.d.ts +35 -0
- package/dist/dialects/pg/view/index.d.ts +114 -0
- package/dist/dialects/pg/view/index.js +289 -0
- package/dist/dialects/pg/view/scratch.d.ts +22 -0
- package/dist/dialects/pg/where.d.ts +2 -2
- package/dist/runtime/catalog-cache.d.ts +17 -0
- package/dist/runtime/compat-words.d.ts +23 -0
- package/dist/runtime/drift-detail.d.ts +20 -4
- package/dist/runtime/drift.d.ts +4 -2
- package/dist/runtime/pg/bun.js +3 -3
- package/dist/runtime/pg/pg.js +3 -3
- package/dist/runtime/pg/pglite.js +3 -3
- package/dist/runtime/pg/postgresjs.js +3 -3
- package/dist/runtime/tenancy/index.js +6 -3
- package/dist/runtime/traits/index.d.ts +7 -2
- package/dist/runtime/traits/index.js +151 -13
- package/dist/runtime/types.d.ts +2 -0
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{xkz8g6by.js → 1g0drakv.js} +2 -2
- package/dist/shared/2321avmn.js +418 -0
- package/dist/shared/{7mht49yd.js → 3p4b1fg0.js} +57 -18
- package/dist/shared/41kv2xdm.js +318 -0
- package/dist/shared/{97g2jnrw.js → 4ef7mmqf.js} +3 -3
- package/dist/shared/{sacqha1y.js → 4m9fn52z.js} +2 -2
- package/dist/shared/5mtf6cj3.js +94 -0
- package/dist/shared/{1dp5knt7.js → 5vdm4sgp.js} +2 -2
- package/dist/shared/{a1gdp7j9.js → 6693j9rs.js} +1 -1
- package/dist/shared/{38crxbgn.js → 6p5k20sm.js} +3 -3
- package/dist/shared/7nk68fj8.js +751 -0
- package/dist/shared/84ptn35q.js +71 -0
- package/dist/shared/{d2whjz4k.js → 8jb4ymh2.js} +581 -28
- package/dist/shared/8ktwd3rh.js +97 -0
- package/dist/shared/94ez8kzh.js +19 -0
- package/dist/shared/{3a5ne750.js → 9m80mkac.js} +2 -2
- package/dist/shared/9x25fxhc.js +150 -0
- package/dist/shared/9yn6a2vd.js +11 -0
- package/dist/shared/ady1ms74.js +72 -0
- package/dist/shared/{4jzzghr6.js → awrsqrn7.js} +6 -6
- package/dist/shared/{4b9da9d7.js → axhk06q1.js} +19 -1
- package/dist/shared/{d04j53v8.js → c5g81ngb.js} +82 -14
- package/dist/shared/{n47rd821.js → c8aghh05.js} +1 -1
- package/dist/shared/{dd4f8mnx.js → c9z5g0fm.js} +4 -2
- package/dist/shared/{ps43134h.js → dyj86cmj.js} +4 -4
- package/dist/shared/{0qkxbm1f.js → fa9vt245.js} +1 -1
- package/dist/shared/{qa5dsc7z.js → fb00y8fp.js} +3 -3
- package/dist/shared/{qxa0yb9j.js → g7ez901n.js} +30 -1
- package/dist/shared/{py3nh7jy.js → gdh9mrtp.js} +2 -2
- package/dist/shared/{yw5c610b.js → gjthds9j.js} +2 -2
- package/dist/shared/hcmdtwgh.js +102 -0
- package/dist/shared/hqjsxnz7.js +13 -0
- package/dist/shared/htnaj77v.js +17 -0
- package/dist/shared/{v18jva5b.js → jgxzjzcz.js} +1 -1
- package/dist/shared/{x9v1qgeb.js → jsd07prz.js} +3 -3
- package/dist/shared/{g9f0zqce.js → kafaa5zv.js} +1 -1
- package/dist/shared/kj680nxv.js +19 -0
- package/dist/shared/{mxmcdsh5.js → kkzwp3d2.js} +9 -9
- package/dist/shared/{g1b5zzj9.js → n0dgs0pb.js} +1 -1
- package/dist/shared/n5y9zyj1.js +2431 -0
- package/dist/shared/{zt8y0wzb.js → n7mcc1gk.js} +1 -1
- package/dist/shared/{ge03bfca.js → nxb42q7h.js} +2 -2
- package/dist/shared/q6zsyh31.js +2192 -0
- package/dist/shared/{sfh4pk75.js → q795afwa.js} +26 -21
- package/dist/shared/{10tjenmd.js → qn0srwwq.js} +1 -1
- package/dist/shared/s4mb6a4b.js +545 -0
- package/dist/shared/{ytg3xf9p.js → sf8m6tfy.js} +3 -3
- package/dist/shared/{zd93g3rq.js → sr5ms7b3.js} +1 -1
- package/dist/shared/{xatfg0gn.js → tmbdywx0.js} +4 -19
- package/dist/shared/tny2t3sm.js +100 -0
- package/dist/shared/{e7a268fy.js → v7tpnhnz.js} +1 -1
- package/dist/shared/{ecdzej21.js → wqem4jed.js} +7 -7
- package/dist/shared/xghkt7a9.js +1144 -0
- package/dist/shared/y005b761.js +112 -0
- package/dist/shared/ycatkxmq.js +84 -0
- package/dist/shared/ygem90rn.js +900 -0
- package/dist/shared/{eaxwrgby.js → yjw02enp.js} +6 -3
- package/dist/shared/{mrq77sgw.js → zg24x0hm.js} +1 -1
- package/dist/shared/{cstgkzdx.js → zvbjc949.js} +1 -1
- package/dist/tooling/cli.js +66 -13
- package/dist/tooling/migrate/apply.d.ts +75 -5
- package/dist/tooling/migrate/backfill.d.ts +136 -0
- package/dist/tooling/migrate/check.d.ts +65 -0
- package/dist/tooling/migrate/classify.d.ts +108 -0
- package/dist/tooling/migrate/commands.d.ts +2 -1
- package/dist/tooling/migrate/config.d.ts +30 -0
- package/dist/tooling/migrate/doctor.d.ts +28 -0
- package/dist/tooling/migrate/drift.d.ts +35 -0
- package/dist/tooling/migrate/estimate.d.ts +50 -0
- package/dist/tooling/migrate/ext.d.ts +17 -0
- package/dist/tooling/migrate/extensions.d.ts +53 -0
- package/dist/tooling/migrate/files.d.ts +12 -0
- package/dist/tooling/migrate/index.d.ts +3 -2
- package/dist/tooling/migrate/index.js +67 -1
- package/dist/tooling/migrate/lint-rules.d.ts +51 -0
- package/dist/tooling/migrate/lint.d.ts +71 -0
- package/dist/tooling/migrate/managed.d.ts +17 -0
- package/dist/tooling/migrate/plan.d.ts +78 -10
- package/dist/tooling/migrate/project.d.ts +64 -5
- package/dist/tooling/migrate/provision.d.ts +18 -0
- package/dist/tooling/migrate/reference.d.ts +40 -0
- package/dist/tooling/migrate/runner.d.ts +108 -0
- package/dist/tooling/migrate/safe.d.ts +77 -0
- package/dist/tooling/migrate/seed.d.ts +20 -0
- package/dist/tooling/migrate/snapshot.d.ts +78 -0
- package/dist/tooling/migrate/status.d.ts +25 -6
- package/dist/tooling/migrate/type-name.d.ts +19 -0
- package/dist/tooling/testing/factories.d.ts +117 -0
- package/dist/tooling/testing/facts.d.ts +72 -0
- package/dist/tooling/testing/index.d.ts +89 -0
- package/dist/tooling/testing/index.js +8 -0
- package/dist/tooling/testing/isolation.d.ts +30 -0
- package/dist/tooling/testing/random.d.ts +40 -0
- package/dist/tooling/testing/record.d.ts +38 -0
- package/package.json +26 -2
- package/dist/shared/5z4q2zda.js +0 -2073
- package/dist/shared/eqmtn1bj.js +0 -399
- package/dist/shared/rtnaqre0.js +0 -37
- package/dist/shared/zwmqxb0g.js +0 -79
- package/dist/shared/{m9tv7xn7.js → radd3z4g.js} +3 -3
- /package/dist/shared/{9k6vetvf.js → rrstp3kb.js} +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normaliseEdges,
|
|
3
|
+
assertProvenance
|
|
4
|
+
} from "./t4tbsy9h.js";
|
|
5
|
+
import {
|
|
6
|
+
assertIdentifier2
|
|
7
|
+
} from "./nfzc5z0w.js";
|
|
8
|
+
import {
|
|
9
|
+
catalogError2
|
|
10
|
+
} from "./52szzakm.js";
|
|
11
|
+
|
|
12
|
+
// src/contracts/catalog/extension.ts
|
|
13
|
+
function extensionObject(input) {
|
|
14
|
+
assertIdentifier2(input.name, "extension");
|
|
15
|
+
assertIdentifier2(input.schema, "extension schema");
|
|
16
|
+
assertProvenance(input.provenance);
|
|
17
|
+
assertVersion(input.version);
|
|
18
|
+
const definition = {
|
|
19
|
+
schema: input.schema,
|
|
20
|
+
relocatable: input.relocatable ?? true,
|
|
21
|
+
...input.version !== undefined ? { version: input.version } : {}
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
kind: "extension",
|
|
25
|
+
identity: { kind: "extension", name: input.name },
|
|
26
|
+
owner: input.owner ?? "managed",
|
|
27
|
+
definition,
|
|
28
|
+
dependencies: normaliseEdges(input.dependencies ?? []),
|
|
29
|
+
provenance: input.provenance
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function isExactVersion(version) {
|
|
33
|
+
return version !== undefined && /^\d+(?:\.\d+)*$/.test(version);
|
|
34
|
+
}
|
|
35
|
+
function compareExtensionVersions(left, right) {
|
|
36
|
+
const a = parts(left);
|
|
37
|
+
const b = parts(right);
|
|
38
|
+
const length = Math.max(a.length, b.length);
|
|
39
|
+
for (let index = 0;index < length; index += 1) {
|
|
40
|
+
const diff = (a[index] ?? 0) - (b[index] ?? 0);
|
|
41
|
+
if (diff !== 0)
|
|
42
|
+
return diff < 0 ? -1 : 1;
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
function sameExtensionDefinition(before, after) {
|
|
47
|
+
if (before.definition.schema !== after.definition.schema)
|
|
48
|
+
return false;
|
|
49
|
+
if (before.definition.relocatable !== after.definition.relocatable)
|
|
50
|
+
return false;
|
|
51
|
+
return sameVersion(before.definition.version, after.definition.version);
|
|
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
|
+
}
|
|
69
|
+
function sameVersion(before, after) {
|
|
70
|
+
if (!isExactVersion(after) || !isExactVersion(before))
|
|
71
|
+
return true;
|
|
72
|
+
return before === after;
|
|
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
|
+
}
|
|
86
|
+
function assertVersion(version) {
|
|
87
|
+
if (version === undefined)
|
|
88
|
+
return;
|
|
89
|
+
if (isExactVersion(version) || /^>=\d+(?:\.\d+)*$/.test(version))
|
|
90
|
+
return;
|
|
91
|
+
catalogError2("OKM1020", `Extension version ${String(version)} must be a dotted version or a >= floor.`);
|
|
92
|
+
}
|
|
93
|
+
function parts(version) {
|
|
94
|
+
return version.split(".").map((part) => Number(part));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { extensionObject, isExactVersion, compareExtensionVersions, sameExtensionDefinition, alignExtensionVersions };
|
|
@@ -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 };
|
|
@@ -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 };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/runtime/compat-words.ts
|
|
2
|
+
var CURRENT = "current";
|
|
3
|
+
var BEHIND_EXPAND = "behind by expand";
|
|
4
|
+
var BEHIND_CONTRACT = "behind by contract";
|
|
5
|
+
var AHEAD_EXPAND = "ahead by expand";
|
|
6
|
+
var AHEAD_CONTRACT = "ahead by contract";
|
|
7
|
+
function failedAt(step) {
|
|
8
|
+
return `failed at step ${String(step)} (resume with okm migrate apply)`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { CURRENT, BEHIND_EXPAND, BEHIND_CONTRACT, AHEAD_EXPAND, AHEAD_CONTRACT, failedAt };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
open2
|
|
3
|
+
} from "./wqem4jed.js";
|
|
4
|
+
import"./8jb4ymh2.js";
|
|
5
|
+
import {
|
|
6
|
+
createdOf,
|
|
7
|
+
testing2
|
|
8
|
+
} from "./ygem90rn.js";
|
|
9
|
+
import"./n442h54c.js";
|
|
10
|
+
import {
|
|
11
|
+
assertTargetPolicy,
|
|
12
|
+
assertDirectConnection,
|
|
13
|
+
selectTarget,
|
|
14
|
+
loadConfig,
|
|
15
|
+
loadSchema
|
|
16
|
+
} from "./q6zsyh31.js";
|
|
17
|
+
import"./n5y9zyj1.js";
|
|
18
|
+
import"./41kv2xdm.js";
|
|
19
|
+
import {
|
|
20
|
+
OkmError2
|
|
21
|
+
} from "./52szzakm.js";
|
|
22
|
+
|
|
23
|
+
// src/tooling/migrate/seed.ts
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { pathToFileURL } from "node:url";
|
|
27
|
+
async function seedProject(cwd, file, flags) {
|
|
28
|
+
const config = await loadConfig(cwd);
|
|
29
|
+
const target = selectTarget(config, flags.target);
|
|
30
|
+
assertTargetPolicy(target, "seed", flags.allowProtected);
|
|
31
|
+
const path = join(cwd, file);
|
|
32
|
+
if (!existsSync(path)) {
|
|
33
|
+
throw new OkmError2("invalid", `Seed file ${file} was not found.`, {
|
|
34
|
+
fix: { summary: "Pass okm seed <file> a module in this project." }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
assertDirectConnection(target.url, flags.allowPooler || config.allowPooler === true);
|
|
38
|
+
const schema = await loadSchema(cwd, config.schema);
|
|
39
|
+
const pool = open2({ url: target.url, max: 1 });
|
|
40
|
+
const harness = await testing2(schema, { driver: pool, migrate: false });
|
|
41
|
+
try {
|
|
42
|
+
const imported = await import(`${pathToFileURL(path).href}?okm=${Date.now()}`);
|
|
43
|
+
const seed = isRecord(imported) ? imported.default : undefined;
|
|
44
|
+
if (typeof seed !== "function") {
|
|
45
|
+
throw new OkmError2("invalid", `${file} must default-export a function.`, {
|
|
46
|
+
fix: { summary: "export default async function seed(t) { ... }." }
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
await seed(harness);
|
|
50
|
+
return formatCreated(target.name, createdOf(harness));
|
|
51
|
+
} finally {
|
|
52
|
+
await harness.close();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function formatCreated(target, counts) {
|
|
56
|
+
const lines = [`target ${target}`];
|
|
57
|
+
if (counts.length === 0)
|
|
58
|
+
lines.push("created nothing");
|
|
59
|
+
else {
|
|
60
|
+
for (const item of counts)
|
|
61
|
+
lines.push(`${item.table} ${String(item.count)}`);
|
|
62
|
+
}
|
|
63
|
+
return `${lines.join(`
|
|
64
|
+
`)}
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
function isRecord(value) {
|
|
68
|
+
return typeof value === "object" && value !== null;
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
seedProject
|
|
72
|
+
};
|
|
@@ -2,10 +2,7 @@ import {
|
|
|
2
2
|
assertOperatorFits,
|
|
3
3
|
textArray,
|
|
4
4
|
arrayElementType
|
|
5
|
-
} from "./
|
|
6
|
-
import {
|
|
7
|
-
runWrite
|
|
8
|
-
} from "./n4jqhpqz.js";
|
|
5
|
+
} from "./n7mcc1gk.js";
|
|
9
6
|
import {
|
|
10
7
|
stack
|
|
11
8
|
} from "./672t5vym.js";
|
|
@@ -14,12 +11,15 @@ import {
|
|
|
14
11
|
fieldSealed,
|
|
15
12
|
sealingTrait
|
|
16
13
|
} from "./7m88x3e9.js";
|
|
14
|
+
import {
|
|
15
|
+
runWrite
|
|
16
|
+
} from "./n4jqhpqz.js";
|
|
17
17
|
import {
|
|
18
18
|
writeWouldValidate
|
|
19
|
-
} from "./
|
|
19
|
+
} from "./9m80mkac.js";
|
|
20
20
|
import {
|
|
21
21
|
encodeJson
|
|
22
|
-
} from "./
|
|
22
|
+
} from "./gjthds9j.js";
|
|
23
23
|
import {
|
|
24
24
|
withRowFilters,
|
|
25
25
|
archiveRules,
|
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
assertBoundText,
|
|
6
6
|
assertRegconfig,
|
|
7
7
|
textArray
|
|
8
|
-
} from "./
|
|
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);
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./wqem4jed.js";
|
|
4
|
+
import"./8jb4ymh2.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
CURRENT,
|
|
8
|
+
BEHIND_EXPAND,
|
|
9
|
+
BEHIND_CONTRACT,
|
|
10
|
+
AHEAD_EXPAND,
|
|
11
|
+
AHEAD_CONTRACT,
|
|
12
|
+
failedAt
|
|
13
|
+
} from "./9yn6a2vd.js";
|
|
14
|
+
import {
|
|
15
|
+
loadMigrations,
|
|
16
|
+
expandProvisioned,
|
|
17
|
+
provisionHistoryIsKnown
|
|
18
|
+
} from "./7nk68fj8.js";
|
|
9
19
|
import {
|
|
10
20
|
assertTargetPolicy,
|
|
11
21
|
listTargets,
|
|
12
22
|
loadConfig
|
|
13
|
-
} from "./
|
|
23
|
+
} from "./q6zsyh31.js";
|
|
24
|
+
import"./n5y9zyj1.js";
|
|
25
|
+
import"./41kv2xdm.js";
|
|
14
26
|
import {
|
|
15
27
|
OkmError2
|
|
16
28
|
} from "./52szzakm.js";
|
|
@@ -18,8 +30,8 @@ import {
|
|
|
18
30
|
// src/tooling/migrate/status.ts
|
|
19
31
|
import { join } from "node:path";
|
|
20
32
|
function describeStatus(migrations, history, recorded) {
|
|
21
|
-
const done = new Set(history.map((row) => `${row.migrationId}:${String(row.stepIndex)}`));
|
|
22
33
|
const known = new Set(migrations.map((migration) => migration.id));
|
|
34
|
+
const done = expandProvisioned(migrations, new Set(history.map((row) => `${row.migrationId}:${String(row.stepIndex)}`)), history.map((row) => row.migrationId));
|
|
23
35
|
for (const migration of migrations) {
|
|
24
36
|
let have = 0;
|
|
25
37
|
let missing = -1;
|
|
@@ -33,33 +45,33 @@ function describeStatus(migrations, history, recorded) {
|
|
|
33
45
|
return {
|
|
34
46
|
version: migration.id,
|
|
35
47
|
catalogHash: recorded?.hash ?? "-",
|
|
36
|
-
state:
|
|
48
|
+
state: failedAt(missing)
|
|
37
49
|
};
|
|
38
50
|
}
|
|
39
51
|
}
|
|
40
|
-
const extra = history.some((row) => !known.has(row.migrationId));
|
|
41
52
|
const pending = migrations.filter((migration) => migration.steps.some((_, index) => !done.has(`${migration.id}:${String(index)}`)));
|
|
42
53
|
const finished = lastComplete(migrations, done);
|
|
43
54
|
const version = recorded?.version ?? finished ?? "-";
|
|
44
55
|
const catalogHash = recorded?.hash ?? "-";
|
|
56
|
+
const extra = history.some((row) => !provisionHistoryIsKnown(row.migrationId, known));
|
|
45
57
|
if (extra)
|
|
46
|
-
return { version, catalogHash, state:
|
|
58
|
+
return { version, catalogHash, state: aheadState(history, known) };
|
|
47
59
|
if (pending.length > 0) {
|
|
48
60
|
const contract = pending.some((migration) => migration.steps.some((step) => step.class !== "expand"));
|
|
49
61
|
return {
|
|
50
62
|
version,
|
|
51
63
|
catalogHash,
|
|
52
|
-
state: contract ?
|
|
64
|
+
state: contract ? BEHIND_CONTRACT : BEHIND_EXPAND
|
|
53
65
|
};
|
|
54
66
|
}
|
|
55
67
|
const last = migrations.at(-1);
|
|
56
68
|
if (last !== undefined && recorded !== undefined && recorded.hash !== last.catalogHash) {
|
|
57
|
-
return { version, catalogHash, state:
|
|
69
|
+
return { version, catalogHash, state: aheadState(history, known) };
|
|
58
70
|
}
|
|
59
71
|
return {
|
|
60
72
|
version: recorded?.version ?? last?.id ?? "-",
|
|
61
73
|
catalogHash: recorded?.hash ?? last?.catalogHash ?? "-",
|
|
62
|
-
state:
|
|
74
|
+
state: CURRENT
|
|
63
75
|
};
|
|
64
76
|
}
|
|
65
77
|
async function readTargetStatus(input) {
|
|
@@ -81,7 +93,8 @@ async function readTargetStatus(input) {
|
|
|
81
93
|
version: described.version,
|
|
82
94
|
catalogHash: described.catalogHash,
|
|
83
95
|
state: described.state,
|
|
84
|
-
protected: input.protected
|
|
96
|
+
protected: input.protected,
|
|
97
|
+
backfills: await readBackfills(pool)
|
|
85
98
|
};
|
|
86
99
|
} finally {
|
|
87
100
|
await pool.close();
|
|
@@ -104,8 +117,17 @@ async function statusProject(cwd, flags) {
|
|
|
104
117
|
}
|
|
105
118
|
function formatStatus(rows) {
|
|
106
119
|
const lines = ["target\tversion\tcatalog\tstate\tprotected"];
|
|
120
|
+
const backfills = [];
|
|
107
121
|
for (const row of rows) {
|
|
108
122
|
lines.push([row.target, row.version, row.catalogHash, row.state, row.protected ? "true" : "false"].join("\t"));
|
|
123
|
+
backfills.push(...row.backfills);
|
|
124
|
+
}
|
|
125
|
+
if (backfills.length > 0) {
|
|
126
|
+
lines.push("backfill");
|
|
127
|
+
lines.push("migration\tstep\trows\tkey\tstate");
|
|
128
|
+
for (const item of backfills) {
|
|
129
|
+
lines.push([item.migrationId, String(item.stepIndex), item.rows, item.lastKey, item.state].join("\t"));
|
|
130
|
+
}
|
|
109
131
|
}
|
|
110
132
|
return `${lines.join(`
|
|
111
133
|
`)}
|
|
@@ -159,7 +181,33 @@ async function readHistory(pool) {
|
|
|
159
181
|
rows.push({
|
|
160
182
|
migrationId,
|
|
161
183
|
stepIndex: Number(step),
|
|
162
|
-
class: stepClass
|
|
184
|
+
class: storedClass(stepClass)
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return rows;
|
|
188
|
+
}
|
|
189
|
+
async function readBackfills(pool) {
|
|
190
|
+
const present = await pool.execute("select to_regclass('okm_backfill') is not null");
|
|
191
|
+
if (!wireTrue(present.rows[0]?.[0] ?? null))
|
|
192
|
+
return [];
|
|
193
|
+
const result = await pool.execute(`select migration_id, step_index::text, rows_touched::text, last_key, state
|
|
194
|
+
from okm_backfill
|
|
195
|
+
where state <> 'done'
|
|
196
|
+
order by migration_id, step_index`);
|
|
197
|
+
const rows = [];
|
|
198
|
+
for (const row of result.rows) {
|
|
199
|
+
const migrationId = row[0];
|
|
200
|
+
const step = row[1];
|
|
201
|
+
const touched = row[2];
|
|
202
|
+
const state = row[4];
|
|
203
|
+
if (migrationId == null || step == null || touched == null || state == null)
|
|
204
|
+
continue;
|
|
205
|
+
rows.push({
|
|
206
|
+
migrationId,
|
|
207
|
+
stepIndex: Number(step),
|
|
208
|
+
rows: touched,
|
|
209
|
+
lastKey: row[3] ?? "-",
|
|
210
|
+
state
|
|
163
211
|
});
|
|
164
212
|
}
|
|
165
213
|
return rows;
|
|
@@ -167,6 +215,26 @@ async function readHistory(pool) {
|
|
|
167
215
|
function wireTrue(value) {
|
|
168
216
|
return value === "t" || value === "true";
|
|
169
217
|
}
|
|
218
|
+
function aheadState(history, known) {
|
|
219
|
+
let sawExtra = false;
|
|
220
|
+
let expandOnly = true;
|
|
221
|
+
for (const row of history) {
|
|
222
|
+
if (known.has(row.migrationId))
|
|
223
|
+
continue;
|
|
224
|
+
sawExtra = true;
|
|
225
|
+
if (row.class !== "expand")
|
|
226
|
+
expandOnly = false;
|
|
227
|
+
}
|
|
228
|
+
if (!sawExtra) {
|
|
229
|
+
expandOnly = history.length > 0 && history.every((row) => row.class === "expand");
|
|
230
|
+
}
|
|
231
|
+
return expandOnly ? AHEAD_EXPAND : AHEAD_CONTRACT;
|
|
232
|
+
}
|
|
233
|
+
function storedClass(value) {
|
|
234
|
+
if (value === "expand" || value === "contract" || value === "unclassified")
|
|
235
|
+
return value;
|
|
236
|
+
return "unclassified";
|
|
237
|
+
}
|
|
170
238
|
export {
|
|
171
239
|
statusProject
|
|
172
240
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeText,
|
|
3
3
|
decodeText
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./4m9fn52z.js";
|
|
5
5
|
import {
|
|
6
6
|
required,
|
|
7
7
|
openColumn
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./c9z5g0fm.js";
|
|
9
9
|
import {
|
|
10
10
|
definition,
|
|
11
11
|
rejected
|
|
12
|
-
} from "./
|
|
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 };
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
send,
|
|
3
3
|
connectClient
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./6p5k20sm.js";
|
|
5
5
|
import {
|
|
6
6
|
isConnectionLost
|
|
7
7
|
} from "./tbszx8mz.js";
|
|
8
8
|
import {
|
|
9
9
|
WireSession
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./zvbjc949.js";
|
|
11
11
|
import {
|
|
12
12
|
rejectClosed,
|
|
13
13
|
runCall
|
|
14
|
-
} from "./
|
|
14
|
+
} from "./rrstp3kb.js";
|
|
15
15
|
|
|
16
16
|
// src/adapters/pg/nodepostgres-extra.ts
|
|
17
17
|
var RESET_ALL = "RESET ALL";
|