okmodel 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -12
- package/dist/contracts/catalog/document.d.ts +20 -0
- package/dist/contracts/driver.d.ts +7 -0
- package/dist/dialects/pg/filter-parse.d.ts +8 -2
- package/dist/dialects/pg/fn/index.js +8 -0
- package/dist/dialects/pg/index.js +8 -2
- package/dist/dialects/pg/introspect.d.ts +6 -0
- package/dist/dialects/pg/ops/or.d.ts +1 -1
- package/dist/dialects/pg/role/sql.d.ts +10 -0
- package/dist/dialects/pg/schema.d.ts +15 -6
- package/dist/dialects/pg/temporal.d.ts +5 -76
- package/dist/dialects/pg/view/index.d.ts +20 -6
- package/dist/dialects/pg/view/index.js +1 -1
- package/dist/dialects/pg/view/scratch.d.ts +2 -2
- package/dist/runtime/client.d.ts +6 -1
- package/dist/runtime/conflict.d.ts +2 -1
- package/dist/runtime/pg/bun.d.ts +12 -7
- package/dist/runtime/pg/bun.js +7 -4
- package/dist/runtime/pg/pg.d.ts +12 -6
- package/dist/runtime/pg/pg.js +7 -4
- package/dist/runtime/pg/pglite.d.ts +11 -3
- package/dist/runtime/pg/pglite.js +7 -4
- package/dist/runtime/pg/postgresjs.d.ts +12 -6
- package/dist/runtime/pg/postgresjs.js +7 -4
- package/dist/runtime/plan.d.ts +16 -1
- package/dist/runtime/tenancy/index.js +1 -1
- package/dist/runtime/topology.d.ts +191 -0
- package/dist/runtime/traits/index.js +7 -7
- package/dist/runtime/types.d.ts +57 -2
- package/dist/runtime/validate/index.js +3 -3
- package/dist/shared/{radd3z4g.js → 0t22wwh1.js} +5 -9
- package/dist/shared/{ady1ms74.js → 2pqx26h8.js} +25 -10
- package/dist/shared/{kyxb62mc.js → 31vm914h.js} +9 -1
- package/dist/shared/{jns2wx4t.js → 32zqc1dw.js} +18 -7
- package/dist/shared/{nxb42q7h.js → 47x8x9ze.js} +2 -2
- package/dist/shared/{zvbjc949.js → 4az561fn.js} +1 -1
- package/dist/shared/{s6gqfn5j.js → 51mvgj8w.js} +27 -3
- package/dist/shared/{k3ted12y.js → 54tqkxja.js} +20 -2
- package/dist/shared/{3p4b1fg0.js → 5enne4ma.js} +1 -1
- package/dist/shared/{6693j9rs.js → 5fqx9yh4.js} +6 -2
- package/dist/shared/{c5g81ngb.js → 6mnp99hx.js} +11 -8
- package/dist/shared/{hqjsxnz7.js → 6qd27mx0.js} +5 -4
- package/dist/shared/{v7tpnhnz.js → 6rk2gen5.js} +5 -3
- package/dist/shared/{2321avmn.js → 7zwwyh0v.js} +46 -16
- package/dist/shared/{fa9vt245.js → 87jvvhnt.js} +2 -2
- package/dist/shared/{8jb4ymh2.js → 8bwbwy8h.js} +12 -1
- package/dist/shared/{c8aghh05.js → 8rsy3hxz.js} +7 -1
- package/dist/shared/{41kv2xdm.js → 8xsbagad.js} +1 -1
- package/dist/shared/{6p5k20sm.js → 96qcj21c.js} +3 -3
- package/dist/shared/{jgxzjzcz.js → aj2qxyhj.js} +2 -2
- package/dist/shared/{5vdm4sgp.js → caw8b9d8.js} +4 -4
- package/dist/shared/{s4mb6a4b.js → cctw17hj.js} +74 -15
- package/dist/shared/{rrstp3kb.js → cgbamx3e.js} +2 -2
- package/dist/shared/{axhk06q1.js → cr74e96e.js} +1 -1
- package/dist/shared/{b066g80h.js → efmy2gcg.js} +2 -2
- package/dist/shared/{gdh9mrtp.js → f5cw5q5r.js} +2 -2
- package/dist/shared/{xghkt7a9.js → fancm5pt.js} +6 -233
- package/dist/shared/{n5y9zyj1.js → ga3sfy93.js} +369 -14
- package/dist/shared/{xrfnq5k8.js → gbtcc2d7.js} +55 -5
- package/dist/shared/{7nk68fj8.js → gde73es6.js} +20 -15
- package/dist/shared/{kkzwp3d2.js → hf22e0wt.js} +55 -19
- package/dist/shared/{tny2t3sm.js → janx09m5.js} +8 -7
- package/dist/shared/{4ef7mmqf.js → jwtxdj06.js} +5 -5
- package/dist/shared/{sf8m6tfy.js → k8v5v5wj.js} +3 -3
- package/dist/shared/{qn0srwwq.js → kfjp0gck.js} +5 -3
- package/dist/shared/{wqem4jed.js → krxx77g0.js} +7 -7
- package/dist/shared/{edwqqryd.js → nkaxvt9q.js} +1 -1
- package/dist/shared/{jsd07prz.js → ntneex2a.js} +1 -1
- package/dist/shared/nxdp2ze3.js +1197 -0
- package/dist/shared/{tbszx8mz.js → pf0d8f77.js} +1 -1
- package/dist/shared/{84ptn35q.js → ps7a6h14.js} +10 -9
- package/dist/shared/{kj680nxv.js → q58y17hy.js} +9 -7
- package/dist/shared/{awrsqrn7.js → qm7cdtvr.js} +22 -9
- package/dist/shared/{q6zsyh31.js → qv2ydck9.js} +156 -205
- package/dist/shared/{kafaa5zv.js → r2sp8hrc.js} +28 -8
- package/dist/shared/{fb00y8fp.js → r8x5qhd7.js} +5 -5
- package/dist/shared/{yjw02enp.js → sdc7r2ww.js} +8 -7
- package/dist/shared/sycnx8gt.js +289 -0
- package/dist/shared/{hcmdtwgh.js → szm0cksa.js} +4 -1
- package/dist/shared/{zg24x0hm.js → tm5ab8we.js} +10 -2
- package/dist/shared/{ygem90rn.js → v36c5g6p.js} +85 -21
- package/dist/shared/wq9n6pwr.js +139 -0
- package/dist/shared/{7p2wbz7f.js → x72jb7ad.js} +1 -1
- package/dist/shared/{q795afwa.js → z2rnngj4.js} +3 -3
- package/dist/shared/{sr5ms7b3.js → zqrnhwsq.js} +3 -3
- package/dist/tooling/cli.js +70 -23
- package/dist/tooling/migrate/apply.d.ts +2 -0
- package/dist/tooling/migrate/commands.d.ts +1 -2
- package/dist/tooling/migrate/drift.d.ts +1 -1
- package/dist/tooling/migrate/estimate.d.ts +14 -1
- package/dist/tooling/migrate/files.d.ts +7 -0
- package/dist/tooling/migrate/index.js +12 -9
- package/dist/tooling/migrate/lint.d.ts +3 -3
- package/dist/tooling/migrate/plan.d.ts +7 -3
- package/dist/tooling/migrate/policy.d.ts +11 -0
- package/dist/tooling/migrate/sql-lex.d.ts +22 -0
- package/dist/tooling/testing/factories.d.ts +10 -0
- package/dist/tooling/testing/facts.d.ts +3 -0
- package/dist/tooling/testing/index.js +3 -3
- package/dist/tooling/testing/isolation.d.ts +4 -3
- package/package.json +6 -5
- package/dist/shared/0v1g424p.js +0 -26
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "../../shared/9m80mkac.js";
|
|
4
4
|
import {
|
|
5
5
|
addSchemaHook
|
|
6
|
-
} from "../../shared/
|
|
6
|
+
} from "../../shared/5enne4ma.js";
|
|
7
7
|
import {
|
|
8
8
|
queryHandle
|
|
9
|
-
} from "../../shared/
|
|
9
|
+
} from "../../shared/hf22e0wt.js";
|
|
10
10
|
import {
|
|
11
11
|
OkmError2
|
|
12
12
|
} from "../../shared/52szzakm.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
// src/runtime/validate/load.ts
|
|
15
15
|
var engine;
|
|
16
16
|
function loadEngine() {
|
|
17
|
-
engine ??= import("../../shared/
|
|
17
|
+
engine ??= import("../../shared/8rsy3hxz.js");
|
|
18
18
|
return engine;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -12,16 +12,14 @@ import {
|
|
|
12
12
|
indexes,
|
|
13
13
|
quote,
|
|
14
14
|
isRecord,
|
|
15
|
+
effectivePredicate,
|
|
15
16
|
registerFailFix,
|
|
16
17
|
fail
|
|
17
|
-
} from "./
|
|
18
|
+
} from "./gbtcc2d7.js";
|
|
18
19
|
import {
|
|
19
20
|
safetyInstalled,
|
|
20
21
|
runSafety
|
|
21
22
|
} from "./a5sxz52y.js";
|
|
22
|
-
import {
|
|
23
|
-
isOperator
|
|
24
|
-
} from "./cn0n68ft.js";
|
|
25
23
|
import {
|
|
26
24
|
OkmError2
|
|
27
25
|
} from "./52szzakm.js";
|
|
@@ -362,11 +360,9 @@ function requireFilter(table, where, mods, op) {
|
|
|
362
360
|
}
|
|
363
361
|
return;
|
|
364
362
|
}
|
|
365
|
-
if (
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
return;
|
|
369
|
-
fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
|
|
363
|
+
if (!effectivePredicate(where)) {
|
|
364
|
+
fail("OKM1102", `${op} on ${table.model.name} needs a where. Pass a filter, or .all(reason).`);
|
|
365
|
+
}
|
|
370
366
|
}
|
|
371
367
|
function callOptions(input) {
|
|
372
368
|
const signal = input.signal;
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./krxx77g0.js";
|
|
4
|
+
import"./8bwbwy8h.js";
|
|
5
5
|
import {
|
|
6
6
|
createdOf,
|
|
7
7
|
testing2
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./v36c5g6p.js";
|
|
9
9
|
import"./n442h54c.js";
|
|
10
10
|
import {
|
|
11
|
-
assertTargetPolicy,
|
|
12
|
-
assertDirectConnection,
|
|
13
|
-
selectTarget,
|
|
14
11
|
loadConfig,
|
|
15
12
|
loadSchema
|
|
16
|
-
} from "./
|
|
17
|
-
import
|
|
18
|
-
|
|
13
|
+
} from "./qv2ydck9.js";
|
|
14
|
+
import {
|
|
15
|
+
assertTargetPolicy,
|
|
16
|
+
assertDirectConnection,
|
|
17
|
+
assertStableBackend,
|
|
18
|
+
selectTarget
|
|
19
|
+
} from "./ga3sfy93.js";
|
|
20
|
+
import"./8xsbagad.js";
|
|
19
21
|
import {
|
|
20
22
|
OkmError2
|
|
21
23
|
} from "./52szzakm.js";
|
|
@@ -34,9 +36,22 @@ async function seedProject(cwd, file, flags) {
|
|
|
34
36
|
fix: { summary: "Pass okm seed <file> a module in this project." }
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
|
-
|
|
39
|
+
const allowPooler = flags.allowPooler || config.allowPooler === true;
|
|
40
|
+
assertDirectConnection(target.url, allowPooler);
|
|
38
41
|
const schema = await loadSchema(cwd, config.schema);
|
|
39
42
|
const pool = open2({ url: target.url, max: 1 });
|
|
43
|
+
const held = await pool.reserve?.();
|
|
44
|
+
if (held !== undefined) {
|
|
45
|
+
try {
|
|
46
|
+
await assertStableBackend(async () => {
|
|
47
|
+
const result = await held.execute("select pg_backend_pid()::text");
|
|
48
|
+
const cell = result.rows[0]?.[0];
|
|
49
|
+
return cell === null || cell === undefined ? "" : String(cell);
|
|
50
|
+
}, allowPooler);
|
|
51
|
+
} finally {
|
|
52
|
+
await held.release();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
40
55
|
const harness = await testing2(schema, { driver: pool, migrate: false });
|
|
41
56
|
try {
|
|
42
57
|
const imported = await import(`${pathToFileURL(path).href}?okm=${Date.now()}`);
|
|
@@ -75,7 +75,7 @@ function mapDriverError2(error, batchIndex) {
|
|
|
75
75
|
if (error instanceof DriverError2) {
|
|
76
76
|
return batchIndex === undefined ? error : error.at(batchIndex);
|
|
77
77
|
}
|
|
78
|
-
const message = error
|
|
78
|
+
const message = messageOf(error);
|
|
79
79
|
return new DriverError2(message, driverFields({
|
|
80
80
|
sqlstate: sqlstateOf(error),
|
|
81
81
|
constraint: errorField2(error, "constraint_name") ?? errorField2(error, "constraint"),
|
|
@@ -86,6 +86,14 @@ function mapDriverError2(error, batchIndex) {
|
|
|
86
86
|
batchIndex
|
|
87
87
|
}));
|
|
88
88
|
}
|
|
89
|
+
function messageOf(error) {
|
|
90
|
+
if (!(error instanceof Error))
|
|
91
|
+
return "driver error";
|
|
92
|
+
if (error.message.length > 0)
|
|
93
|
+
return error.message;
|
|
94
|
+
const first = error.errors?.[0];
|
|
95
|
+
return first instanceof Error && first.message.length > 0 ? first.message : "driver error";
|
|
96
|
+
}
|
|
89
97
|
function driverFields(input) {
|
|
90
98
|
const fields = {};
|
|
91
99
|
if (input.sqlstate !== undefined)
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isRecord,
|
|
10
10
|
registerFailFix,
|
|
11
11
|
fail
|
|
12
|
-
} from "./
|
|
12
|
+
} from "./gbtcc2d7.js";
|
|
13
13
|
import {
|
|
14
14
|
throwNamed2
|
|
15
15
|
} from "./52szzakm.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
registerFailFix("OKM1104", "Set on to the columns of a unique constraint or the primary key.");
|
|
19
19
|
registerFailFix("OKM1190", "Remove the guarded field. Input cannot set it.");
|
|
20
20
|
var NO_ALLOW = new Set;
|
|
21
|
-
function readConflict(table, value, allow = NO_ALLOW) {
|
|
21
|
+
function readConflict(table, value, allow = NO_ALLOW, tenantKey) {
|
|
22
22
|
if (value === undefined || value === "error")
|
|
23
23
|
return;
|
|
24
24
|
if (value === "ignore")
|
|
@@ -34,13 +34,13 @@ function readConflict(table, value, allow = NO_ALLOW) {
|
|
|
34
34
|
}
|
|
35
35
|
if (ret === true) {
|
|
36
36
|
rejectConflictKeys(keys, ["on", "return"]);
|
|
37
|
-
return { kind: "return", columns: uniqueColumns(table, value.on), update: [] };
|
|
37
|
+
return { kind: "return", columns: uniqueColumns(table, value.on, tenantKey), update: [] };
|
|
38
38
|
}
|
|
39
39
|
if (update !== undefined) {
|
|
40
40
|
rejectConflictKeys(keys, ["on", "update"]);
|
|
41
41
|
return {
|
|
42
42
|
kind: "update",
|
|
43
|
-
columns: uniqueColumns(table, value.on),
|
|
43
|
+
columns: uniqueColumns(table, value.on, tenantKey),
|
|
44
44
|
update: updateColumns(table, update, allow)
|
|
45
45
|
};
|
|
46
46
|
}
|
|
@@ -110,7 +110,7 @@ function samePrimary(table, columns) {
|
|
|
110
110
|
}
|
|
111
111
|
return true;
|
|
112
112
|
}
|
|
113
|
-
function uniqueColumns(table, on) {
|
|
113
|
+
function uniqueColumns(table, on, tenantKey) {
|
|
114
114
|
const names = conflictNames(on);
|
|
115
115
|
for (const unique of table.model.uniques) {
|
|
116
116
|
if (!same(unique, names))
|
|
@@ -125,8 +125,19 @@ function uniqueColumns(table, on) {
|
|
|
125
125
|
}
|
|
126
126
|
return columns;
|
|
127
127
|
}
|
|
128
|
-
const accepted = table.model
|
|
129
|
-
|
|
128
|
+
const accepted = acceptedConstraints(table.model, tenantKey);
|
|
129
|
+
const implicit = tenantKey === undefined ? "" : ` The tenant key ${tenantKey} is part of each one and is not named here.`;
|
|
130
|
+
throwNamed2("OKM1104", names.join(", "), accepted, `onConflict on ${table.model.name} names ${names.join(", ")}, which is not a unique constraint. Accepted: ${list(accepted)}.${implicit}`);
|
|
131
|
+
}
|
|
132
|
+
function acceptedConstraints(model, key) {
|
|
133
|
+
const shown = new Set;
|
|
134
|
+
for (const fields of model.uniques) {
|
|
135
|
+
const named = key === undefined ? fields : fields.filter((field) => field !== key);
|
|
136
|
+
if (named.length === 0)
|
|
137
|
+
continue;
|
|
138
|
+
shown.add(named.length > 1 ? `(${named.join(", ")})` : named.join(""));
|
|
139
|
+
}
|
|
140
|
+
return [...shown];
|
|
130
141
|
}
|
|
131
142
|
function updateColumns(table, value, allow) {
|
|
132
143
|
if (!Array.isArray(value) || value.length === 0) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withHttp,
|
|
3
3
|
attachHttp
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./hf22e0wt.js";
|
|
5
5
|
import {
|
|
6
6
|
OkmError2
|
|
7
7
|
} from "./52szzakm.js";
|
|
@@ -31,7 +31,7 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
|
|
|
31
31
|
}));
|
|
32
32
|
}
|
|
33
33
|
} else {
|
|
34
|
-
const { assertCompatible } = await import("./
|
|
34
|
+
const { assertCompatible } = await import("./z2rnngj4.js");
|
|
35
35
|
try {
|
|
36
36
|
await assertCompatible(pool, schema, recorded, source, options);
|
|
37
37
|
} catch (error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isConnectionSqlstate,
|
|
3
3
|
isConnectionFailure
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./pf0d8f77.js";
|
|
5
5
|
import {
|
|
6
6
|
OkmError2,
|
|
7
7
|
stripRowValues,
|
|
@@ -16,12 +16,14 @@ function mapPostgresError(error, options) {
|
|
|
16
16
|
return OkmError2.from(error);
|
|
17
17
|
const kind = kindOf(error);
|
|
18
18
|
const columns = columnsOf(error);
|
|
19
|
-
const
|
|
19
|
+
const hint = hintOf(error, kind);
|
|
20
|
+
const fieldReason = hint?.reason ?? (kind === "not_null" ? "not_null" : reasonOf(kind, error.table, error.constraint));
|
|
20
21
|
const values = options?.includeValues === true ? valuesOf(error.detail, columns) : undefined;
|
|
21
22
|
const code = kind === "outcome_unknown" ? "OKM1401" : kind;
|
|
22
23
|
return new OkmError2(code, summaryOf(kind, error, columns, fieldReason), {
|
|
23
24
|
kind,
|
|
24
25
|
fieldReason,
|
|
26
|
+
...hint !== undefined ? { fix: hint.fix } : {},
|
|
25
27
|
...error.table !== undefined ? { table: error.table } : {},
|
|
26
28
|
...columns.length > 0 ? { columns } : {},
|
|
27
29
|
...error.constraint !== undefined ? { constraint: error.constraint } : {},
|
|
@@ -32,6 +34,12 @@ function mapPostgresError(error, options) {
|
|
|
32
34
|
...options?.http !== undefined ? { http: options.http } : {}
|
|
33
35
|
});
|
|
34
36
|
}
|
|
37
|
+
var TLS_CODE = /^(ERR_TLS_|ERR_POSTGRES_TLS_|SELF_SIGNED_CERT_|DEPTH_ZERO_SELF_SIGNED_CERT$|UNABLE_TO_VERIFY_LEAF_SIGNATURE$)/;
|
|
38
|
+
function isTlsFailure(error) {
|
|
39
|
+
const cause = error.cause;
|
|
40
|
+
const code = typeof cause === "object" && cause !== null ? Reflect.get(cause, "code") : undefined;
|
|
41
|
+
return typeof code === "string" && TLS_CODE.test(code);
|
|
42
|
+
}
|
|
35
43
|
function isDriverError(error) {
|
|
36
44
|
if (!(error instanceof Error) || error.name !== "DriverError")
|
|
37
45
|
return false;
|
|
@@ -47,10 +55,26 @@ function kindOf(error) {
|
|
|
47
55
|
if (mapped !== undefined)
|
|
48
56
|
return mapped;
|
|
49
57
|
}
|
|
50
|
-
if (isConnectionFailure(error))
|
|
58
|
+
if (isTlsFailure(error) || isConnectionFailure(error))
|
|
51
59
|
return "unavailable";
|
|
52
60
|
return "driver";
|
|
53
61
|
}
|
|
62
|
+
var MIGRATE_FIX = {
|
|
63
|
+
summary: "Run okm migrate apply so the object exists, then check okm migrate status. The reason names the missing object."
|
|
64
|
+
};
|
|
65
|
+
var TLS_FIX = {
|
|
66
|
+
summary: "Check sslmode in the connection URL against the server certificate: use require, verify-ca, or verify-full with the CA the certificate chains to. For node-postgres, add uselibpqcompat=true so sslmode follows libpq."
|
|
67
|
+
};
|
|
68
|
+
function hintOf(error, kind) {
|
|
69
|
+
if (error.sqlstate === "42P01")
|
|
70
|
+
return { reason: "undefined_table", fix: MIGRATE_FIX };
|
|
71
|
+
if (error.sqlstate === "42703")
|
|
72
|
+
return { reason: "undefined_column", fix: MIGRATE_FIX };
|
|
73
|
+
if (kind === "unavailable" && error.sqlstate === undefined && isTlsFailure(error)) {
|
|
74
|
+
return { reason: "tls", fix: TLS_FIX };
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
54
78
|
function kindFromSqlstate(sqlstate) {
|
|
55
79
|
switch (sqlstate) {
|
|
56
80
|
case "23505":
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
// src/adapters/pg/watch.ts
|
|
2
|
+
var callers = new WeakMap;
|
|
3
|
+
function listenOn(signal, onAbort) {
|
|
4
|
+
let set = callers.get(signal);
|
|
5
|
+
if (set === undefined) {
|
|
6
|
+
const created = new Set;
|
|
7
|
+
callers.set(signal, created);
|
|
8
|
+
signal.addEventListener("abort", () => {
|
|
9
|
+
for (const each of created)
|
|
10
|
+
each();
|
|
11
|
+
}, { once: true });
|
|
12
|
+
set = created;
|
|
13
|
+
}
|
|
14
|
+
const registered = set;
|
|
15
|
+
registered.add(onAbort);
|
|
16
|
+
return () => {
|
|
17
|
+
registered.delete(onAbort);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
2
20
|
function openWatch(options) {
|
|
3
21
|
let kind;
|
|
4
22
|
const controller = new AbortController;
|
|
@@ -7,7 +25,7 @@ function openWatch(options) {
|
|
|
7
25
|
kind = "cancelled";
|
|
8
26
|
controller.abort();
|
|
9
27
|
};
|
|
10
|
-
options.signal
|
|
28
|
+
const release = options.signal === undefined ? undefined : listenOn(options.signal, onAbort);
|
|
11
29
|
let timer;
|
|
12
30
|
if (options.timeout !== undefined) {
|
|
13
31
|
timer = setTimeout(() => {
|
|
@@ -21,7 +39,7 @@ function openWatch(options) {
|
|
|
21
39
|
finish() {
|
|
22
40
|
if (timer !== undefined)
|
|
23
41
|
clearTimeout(timer);
|
|
24
|
-
|
|
42
|
+
release?.();
|
|
25
43
|
},
|
|
26
44
|
reason() {
|
|
27
45
|
return kind;
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
renameTable2,
|
|
5
5
|
serializeCatalog2,
|
|
6
6
|
catalogHash2,
|
|
7
|
+
startupCatalog2,
|
|
8
|
+
startupHash2,
|
|
7
9
|
loadTrustedCatalog2,
|
|
8
10
|
parseCatalog2
|
|
9
|
-
} from "./
|
|
11
|
+
} from "./8bwbwy8h.js";
|
|
10
12
|
export {
|
|
11
13
|
catalogHash2 as catalogHash,
|
|
12
14
|
creationOrder2 as creationOrder,
|
|
@@ -14,5 +16,7 @@ export {
|
|
|
14
16
|
parseCatalog2 as parseCatalog,
|
|
15
17
|
renameColumn2 as renameColumn,
|
|
16
18
|
renameTable2 as renameTable,
|
|
17
|
-
serializeCatalog2 as serializeCatalog
|
|
19
|
+
serializeCatalog2 as serializeCatalog,
|
|
20
|
+
startupCatalog2 as startupCatalog,
|
|
21
|
+
startupHash2 as startupHash
|
|
18
22
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./krxx77g0.js";
|
|
4
|
+
import"./8bwbwy8h.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
7
|
CURRENT,
|
|
@@ -15,14 +15,17 @@ import {
|
|
|
15
15
|
loadMigrations,
|
|
16
16
|
expandProvisioned,
|
|
17
17
|
provisionHistoryIsKnown
|
|
18
|
-
} from "./
|
|
18
|
+
} from "./gde73es6.js";
|
|
19
|
+
import"./szm0cksa.js";
|
|
20
|
+
import"./fancm5pt.js";
|
|
19
21
|
import {
|
|
20
|
-
assertTargetPolicy,
|
|
21
|
-
listTargets,
|
|
22
22
|
loadConfig
|
|
23
|
-
} from "./
|
|
24
|
-
import
|
|
25
|
-
|
|
23
|
+
} from "./qv2ydck9.js";
|
|
24
|
+
import {
|
|
25
|
+
assertTargetPolicy,
|
|
26
|
+
listTargets
|
|
27
|
+
} from "./ga3sfy93.js";
|
|
28
|
+
import"./8xsbagad.js";
|
|
26
29
|
import {
|
|
27
30
|
OkmError2
|
|
28
31
|
} from "./52szzakm.js";
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
assertAuthorDrift2,
|
|
3
3
|
catalogQuery2,
|
|
4
4
|
managedRoleOptions2
|
|
5
|
-
} from "./
|
|
6
|
-
import"./
|
|
7
|
-
import"./
|
|
8
|
-
import"./
|
|
5
|
+
} from "./sycnx8gt.js";
|
|
6
|
+
import"./fancm5pt.js";
|
|
7
|
+
import"./ga3sfy93.js";
|
|
8
|
+
import"./8xsbagad.js";
|
|
9
|
+
import"./8bwbwy8h.js";
|
|
9
10
|
export {
|
|
10
11
|
assertAuthorDrift2 as assertAuthorDrift,
|
|
11
12
|
catalogQuery2 as catalogQuery,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
readHandle,
|
|
4
4
|
readCall,
|
|
5
5
|
attachHttp
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./hf22e0wt.js";
|
|
7
7
|
import {
|
|
8
8
|
selectedColumns,
|
|
9
9
|
parseOrder,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
isRecord,
|
|
16
16
|
registerFailFix,
|
|
17
17
|
fail
|
|
18
|
-
} from "./
|
|
18
|
+
} from "./gbtcc2d7.js";
|
|
19
19
|
import {
|
|
20
20
|
OkmError2,
|
|
21
21
|
throwNamed2
|
|
@@ -30,6 +30,7 @@ var OPTIONS = [
|
|
|
30
30
|
"limit",
|
|
31
31
|
"include",
|
|
32
32
|
"after",
|
|
33
|
+
"route",
|
|
33
34
|
"signal",
|
|
34
35
|
"timeout"
|
|
35
36
|
];
|
|
@@ -69,7 +70,8 @@ function plan(session, table, options, mods, view) {
|
|
|
69
70
|
limit: size + 1,
|
|
70
71
|
include: record.include,
|
|
71
72
|
signal: record.signal,
|
|
72
|
-
timeout: record.timeout
|
|
73
|
+
timeout: record.timeout,
|
|
74
|
+
route: record.route
|
|
73
75
|
}, undefined, session.scope, session.schema.model[table], session.schema, view),
|
|
74
76
|
...after !== undefined ? { after } : {}
|
|
75
77
|
};
|
|
@@ -1,40 +1,45 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseCatalog2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./8bwbwy8h.js";
|
|
4
|
+
import"./krxx77g0.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
7
|
applyTarget2,
|
|
8
8
|
backfillTiming2
|
|
9
|
-
} from "./
|
|
9
|
+
} from "./cctw17hj.js";
|
|
10
10
|
import {
|
|
11
|
-
introspectSchema,
|
|
12
11
|
sealViews,
|
|
13
12
|
catalogQuery2,
|
|
14
13
|
managedRoleOptions2
|
|
15
|
-
} from "./
|
|
14
|
+
} from "./sycnx8gt.js";
|
|
16
15
|
import {
|
|
17
16
|
loadMigrations,
|
|
18
17
|
catalogsEqual,
|
|
19
18
|
snapshotDifference
|
|
20
|
-
} from "./
|
|
19
|
+
} from "./gde73es6.js";
|
|
20
|
+
import"./szm0cksa.js";
|
|
21
|
+
import {
|
|
22
|
+
introspectSchema
|
|
23
|
+
} from "./fancm5pt.js";
|
|
21
24
|
import {
|
|
22
25
|
lintMigrationDirectory,
|
|
23
26
|
hasError,
|
|
24
27
|
lintRefusal,
|
|
25
|
-
selectTarget,
|
|
26
28
|
openProject
|
|
27
|
-
} from "./
|
|
29
|
+
} from "./qv2ydck9.js";
|
|
28
30
|
import {
|
|
29
31
|
canonicalTypeName,
|
|
30
32
|
classOf,
|
|
31
33
|
strictestClass,
|
|
32
34
|
planMigration,
|
|
33
|
-
parsePlan
|
|
34
|
-
|
|
35
|
+
parsePlan,
|
|
36
|
+
assertDirectConnection,
|
|
37
|
+
assertStableBackend,
|
|
38
|
+
selectTarget
|
|
39
|
+
} from "./ga3sfy93.js";
|
|
35
40
|
import {
|
|
36
41
|
quoteIdent
|
|
37
|
-
} from "./
|
|
42
|
+
} from "./8xsbagad.js";
|
|
38
43
|
import {
|
|
39
44
|
catalog,
|
|
40
45
|
isDomain
|
|
@@ -61,6 +66,8 @@ var STALE_FIX = "Run okm generate.";
|
|
|
61
66
|
async function checkMigrations(cwd, flags, options) {
|
|
62
67
|
const opened = await openProject(cwd);
|
|
63
68
|
const target = selectTarget(opened.config, flags.target);
|
|
69
|
+
const allowPooler = flags.allowPooler || opened.config.allowPooler === true;
|
|
70
|
+
assertDirectConnection(target.url, allowPooler);
|
|
64
71
|
if (target.protected) {
|
|
65
72
|
throw new OkmError2("OKM1850", `okm migrate check writes a scratch schema and refuses protected target ${target.name}. Point it at a throwaway Postgres.`, {
|
|
66
73
|
kind: "forbidden",
|
|
@@ -177,6 +184,7 @@ async function proveSnapshot(config, url, target, flags, history) {
|
|
|
177
184
|
idle_timeout: 1,
|
|
178
185
|
onnotice: () => {}
|
|
179
186
|
});
|
|
187
|
+
const allowPooler = flags.allowPooler || config.allowPooler === true;
|
|
180
188
|
const provided = `${CHECK_SCHEMA_PREFIX}p${crypto.randomUUID().replaceAll("-", "")}`;
|
|
181
189
|
const replayed = `${CHECK_SCHEMA_PREFIX}r${crypto.randomUUID().replaceAll("-", "")}`;
|
|
182
190
|
const timing = {
|
|
@@ -185,6 +193,10 @@ async function proveSnapshot(config, url, target, flags, history) {
|
|
|
185
193
|
...backfillTiming2(config.backfill)
|
|
186
194
|
};
|
|
187
195
|
try {
|
|
196
|
+
await assertStableBackend(async () => {
|
|
197
|
+
const rows = await sql`select pg_backend_pid()::text as pid`;
|
|
198
|
+
return rows[0]?.pid ?? "";
|
|
199
|
+
}, allowPooler);
|
|
188
200
|
await sql.unsafe(`create schema ${quoteIdent(provided)}`);
|
|
189
201
|
await sql.unsafe(`create schema ${quoteIdent(replayed)}`);
|
|
190
202
|
const role = config.roles === undefined ? {} : { migrationRole: config.roles.migration, schema: provided };
|
|
@@ -225,9 +237,8 @@ async function proveSnapshot(config, url, target, flags, history) {
|
|
|
225
237
|
})),
|
|
226
238
|
...config.roles !== undefined ? { migrationRole: config.roles.migration, schema: replayed } : {}
|
|
227
239
|
});
|
|
228
|
-
const
|
|
229
|
-
const
|
|
230
|
-
const liveReplayed = await introspectSchema(runner, replayed, "public", managedRoleOptions2(config.roles));
|
|
240
|
+
const liveProvided = await introspectScratch(sql, provided, config);
|
|
241
|
+
const liveReplayed = await introspectScratch(sql, replayed, config);
|
|
231
242
|
const difference = snapshotDifference(liveProvided, liveReplayed);
|
|
232
243
|
if (difference === undefined)
|
|
233
244
|
return;
|
|
@@ -256,9 +267,14 @@ async function replayHistory(config, url, target, flags, history) {
|
|
|
256
267
|
idle_timeout: 1,
|
|
257
268
|
onnotice: () => {}
|
|
258
269
|
});
|
|
270
|
+
const allowPooler = flags.allowPooler || config.allowPooler === true;
|
|
259
271
|
const scratch = `${CHECK_SCHEMA_PREFIX}${crypto.randomUUID().replaceAll("-", "")}`;
|
|
260
272
|
const failures = [];
|
|
261
273
|
try {
|
|
274
|
+
await assertStableBackend(async () => {
|
|
275
|
+
const rows = await sql`select pg_backend_pid()::text as pid`;
|
|
276
|
+
return rows[0]?.pid ?? "";
|
|
277
|
+
}, allowPooler);
|
|
262
278
|
await sql.unsafe(`create schema ${quoteIdent(scratch)}`);
|
|
263
279
|
const runner = catalogQuery2(sql);
|
|
264
280
|
for (let index = 0;index < history.length; index += 1) {
|
|
@@ -284,7 +300,7 @@ async function replayHistory(config, url, target, flags, history) {
|
|
|
284
300
|
],
|
|
285
301
|
...config.roles !== undefined ? { migrationRole: config.roles.migration, schema: scratch } : {}
|
|
286
302
|
});
|
|
287
|
-
const live = await
|
|
303
|
+
const live = await introspectScratch(sql, scratch, config);
|
|
288
304
|
const sealed = await sealViews(runner, migration.catalog);
|
|
289
305
|
const back = planMigration({ before: live, after: sealed, name: migration.id });
|
|
290
306
|
if (back.steps.length === 0)
|
|
@@ -300,6 +316,18 @@ async function replayHistory(config, url, target, flags, history) {
|
|
|
300
316
|
}
|
|
301
317
|
return failures;
|
|
302
318
|
}
|
|
319
|
+
async function introspectScratch(sql, schema, config) {
|
|
320
|
+
const previous = await sql`select current_setting('search_path') as path`;
|
|
321
|
+
const saved = previous[0]?.path ?? "public";
|
|
322
|
+
try {
|
|
323
|
+
await sql.unsafe(`set search_path to ${quoteIdent(schema)}`);
|
|
324
|
+
return await introspectSchema(catalogQuery2(sql), schema, "public", managedRoleOptions2(config.roles));
|
|
325
|
+
} finally {
|
|
326
|
+
await sql`select set_config('search_path', ${saved}, false)`.catch(() => {
|
|
327
|
+
return;
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
303
331
|
function historyFailure(history, index, back) {
|
|
304
332
|
const migration = history[index];
|
|
305
333
|
const id = migration?.id ?? "migration";
|
|
@@ -349,9 +377,11 @@ function sameSql(planned, file) {
|
|
|
349
377
|
function retargetSteps(steps, schema) {
|
|
350
378
|
const from = `${quoteIdent("public")}.`;
|
|
351
379
|
const to = `${quoteIdent(schema)}.`;
|
|
380
|
+
const fromDefaults = `in schema ${quoteIdent("public")} `;
|
|
381
|
+
const toDefaults = `in schema ${quoteIdent(schema)} `;
|
|
352
382
|
return steps.map((step) => ({
|
|
353
383
|
...step,
|
|
354
|
-
sql: step.sql.replaceAll(from, to),
|
|
384
|
+
sql: step.sql.replaceAll(from, to).replaceAll(fromDefaults, toDefaults),
|
|
355
385
|
...step.backfill === undefined ? {} : { backfill: { ...step.backfill, table: step.backfill.table.replaceAll(from, to) } }
|
|
356
386
|
}));
|
|
357
387
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
runCall,
|
|
10
10
|
EMPTY_NOTICES,
|
|
11
11
|
resultFrom
|
|
12
|
-
} from "./
|
|
12
|
+
} from "./cgbamx3e.js";
|
|
13
13
|
|
|
14
14
|
// src/adapters/pg/pglite.ts
|
|
15
15
|
import { PGlite } from "@electric-sql/pglite";
|
|
@@ -48,7 +48,7 @@ async function open3(config = {}) {
|
|
|
48
48
|
return {
|
|
49
49
|
execute: (text, params, options) => runCall(closed, options, (watch) => session.query(text, params, watch)),
|
|
50
50
|
batch: (statements, options) => runCall(closed, options, async (watch) => {
|
|
51
|
-
const { runAtomicBatch } = await import("./
|
|
51
|
+
const { runAtomicBatch } = await import("./efmy2gcg.js");
|
|
52
52
|
return runAtomicBatch(session, statements, watch);
|
|
53
53
|
}),
|
|
54
54
|
async release() {
|
|
@@ -229,6 +229,17 @@ function catalogHash2(source) {
|
|
|
229
229
|
serializedHash.set(source, hash);
|
|
230
230
|
return hash;
|
|
231
231
|
}
|
|
232
|
+
function startupCatalog2(source) {
|
|
233
|
+
if (!source.objects.some(isPrivilege))
|
|
234
|
+
return source;
|
|
235
|
+
return { version: source.version, objects: source.objects.filter((item) => !isPrivilege(item)) };
|
|
236
|
+
}
|
|
237
|
+
function startupHash2(source) {
|
|
238
|
+
return catalogHash2(startupCatalog2(source));
|
|
239
|
+
}
|
|
240
|
+
function isPrivilege(object) {
|
|
241
|
+
return object.kind === "role" || object.kind === "grant" || object.kind === "defaultPrivilege";
|
|
242
|
+
}
|
|
232
243
|
function loadTrustedCatalog2(text, hash) {
|
|
233
244
|
if (sha2562(text) !== hash) {
|
|
234
245
|
catalogError2("OKM1027", "Catalog hash does not match the build artifact.");
|
|
@@ -1444,4 +1455,4 @@ function assertNeverKind(value) {
|
|
|
1444
1455
|
return catalogError2("OKM1020", `Unexpected kind ${JSON.stringify(value)}.`);
|
|
1445
1456
|
}
|
|
1446
1457
|
|
|
1447
|
-
export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, loadTrustedCatalog2, parseCatalog2 };
|
|
1458
|
+
export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, startupCatalog2, startupHash2, loadTrustedCatalog2, parseCatalog2 };
|
|
@@ -422,6 +422,12 @@ function isRecord(value) {
|
|
|
422
422
|
function failShape(message) {
|
|
423
423
|
throw new OkmError2("OKM1121", message, { kind: "invalid" });
|
|
424
424
|
}
|
|
425
|
+
function failedMessage(first) {
|
|
426
|
+
if (first === undefined)
|
|
427
|
+
return "Validation failed.";
|
|
428
|
+
const field = first.path.length === 0 ? "$row" : first.path.join(".");
|
|
429
|
+
return `Validation failed: ${field} ${first.message}`;
|
|
430
|
+
}
|
|
425
431
|
function throwIssues(issues) {
|
|
426
432
|
const columns = [];
|
|
427
433
|
for (const issue of issues) {
|
|
@@ -429,7 +435,7 @@ function throwIssues(issues) {
|
|
|
429
435
|
if (typeof field === "string" && !columns.includes(field))
|
|
430
436
|
columns.push(field);
|
|
431
437
|
}
|
|
432
|
-
throw new OkmError2("OKM1200",
|
|
438
|
+
throw new OkmError2("OKM1200", failedMessage(issues[0]), {
|
|
433
439
|
kind: "invalid",
|
|
434
440
|
...columns.length > 0 ? { columns } : {},
|
|
435
441
|
issues,
|