okmodel 0.5.1 → 0.7.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 +100 -1116
- package/dist/adapters/capabilities.d.ts +3 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +14 -1
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +20 -0
- package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
- package/dist/adapters/pg/nodepostgres.d.ts +12 -0
- package/dist/adapters/pg/pglite-wire.d.ts +24 -0
- package/dist/adapters/pg/pglite.d.ts +10 -0
- package/dist/adapters/pg/postgres-extra.d.ts +41 -3
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- package/dist/contracts/catalog/document.d.ts +19 -5
- package/dist/contracts/catalog/object.d.ts +2 -1
- package/dist/contracts/catalog/policy.d.ts +48 -0
- package/dist/contracts/catalog/types.d.ts +25 -1
- package/dist/contracts/catalog/view.d.ts +2 -0
- package/dist/contracts/connection.d.ts +7 -6
- package/dist/contracts/internal.js +1 -1
- package/dist/contracts/location.d.ts +10 -0
- package/dist/dialects/pg/column.d.ts +13 -2
- package/dist/dialects/pg/ddl.d.ts +37 -1
- package/dist/dialects/pg/emit.d.ts +19 -1
- package/dist/dialects/pg/errors.d.ts +32 -1
- package/dist/dialects/pg/ext/citext.js +1 -1
- package/dist/dialects/pg/ext/index.js +1 -1
- package/dist/dialects/pg/ext/pg-trgm.js +1 -1
- package/dist/dialects/pg/filter-parse.d.ts +5 -4
- package/dist/dialects/pg/floor.d.ts +68 -0
- package/dist/dialects/pg/fn/index.js +2 -2
- package/dist/dialects/pg/index.d.ts +8 -2
- package/dist/dialects/pg/index.js +67 -171
- package/dist/dialects/pg/introspect.d.ts +7 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +47 -2
- package/dist/dialects/pg/morph.d.ts +43 -0
- package/dist/dialects/pg/operator-fit.d.ts +2 -2
- package/dist/dialects/pg/operators.d.ts +14 -7
- package/dist/dialects/pg/ops/bucket.d.ts +65 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/matches.d.ts +9 -12
- package/dist/dialects/pg/ops/relevance.d.ts +13 -0
- package/dist/dialects/pg/ops/search-query.d.ts +22 -0
- package/dist/dialects/pg/ops/window.d.ts +103 -0
- package/dist/dialects/pg/owner.d.ts +42 -0
- package/dist/dialects/pg/path-endpoint.d.ts +20 -0
- package/dist/dialects/pg/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- package/dist/dialects/pg/role/check.d.ts +3 -0
- package/dist/dialects/pg/role/index.d.ts +71 -6
- package/dist/dialects/pg/role/sql.d.ts +11 -0
- package/dist/dialects/pg/schema.d.ts +33 -3
- package/dist/dialects/pg/table.d.ts +25 -3
- package/dist/dialects/pg/tenancy.d.ts +45 -3
- package/dist/dialects/pg/view/client.d.ts +19 -1
- package/dist/dialects/pg/view/index.d.ts +4 -0
- package/dist/dialects/pg/view/index.js +21 -178
- package/dist/dialects/pg/view/refresh.d.ts +24 -0
- package/dist/runtime/aggregate.d.ts +8 -2
- package/dist/runtime/batch.d.ts +1 -1
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +24 -6
- package/dist/runtime/drift.d.ts +9 -0
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +14 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -5
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -8
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +113 -15
- package/dist/runtime/predicate.d.ts +19 -0
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- package/dist/runtime/safety/index.js +1 -1
- package/dist/runtime/server-check.d.ts +3 -3
- package/dist/runtime/sort-bind.d.ts +21 -0
- package/dist/runtime/sort.d.ts +56 -0
- package/dist/runtime/sync.d.ts +70 -0
- package/dist/runtime/tenancy/composite.d.ts +26 -0
- package/dist/runtime/tenancy/context.d.ts +16 -0
- package/dist/runtime/tenancy/index.d.ts +9 -5
- package/dist/runtime/tenancy/index.js +1511 -38
- package/dist/runtime/tenancy/path.d.ts +87 -0
- package/dist/runtime/tenancy/rls.d.ts +67 -0
- package/dist/runtime/tenancy/via.d.ts +22 -0
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +187 -17
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +231 -23
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/version.d.ts +39 -0
- package/dist/runtime/window.d.ts +21 -0
- package/dist/runtime/write.d.ts +55 -3
- package/dist/shared/{krxx77g0.js → 14vx95q4.js} +12 -18
- package/dist/shared/1est4ezg.js +313 -0
- package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
- package/dist/shared/1w508jbr.js +1611 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/2d3xq4ps.js +9 -0
- package/dist/shared/2shdbn8q.js +23 -0
- package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
- package/dist/shared/3v7t1yrv.js +208 -0
- package/dist/shared/5e3tf63j.js +220 -0
- package/dist/shared/5fe3kbsh.js +10 -0
- package/dist/shared/5v3xf80k.js +37 -0
- package/dist/shared/{51mvgj8w.js → 63qtkrca.js} +130 -3
- package/dist/shared/{gbtcc2d7.js → 67txcrcw.js} +62 -66
- package/dist/shared/79dt02vc.js +12 -0
- package/dist/shared/{v36c5g6p.js → 7k9grvf6.js} +407 -14
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7mnme5tn.js +8 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/{87jvvhnt.js → 81ebdx9p.js} +48 -68
- package/dist/shared/{szm0cksa.js → 8skf0cam.js} +34 -6
- package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
- package/dist/shared/9y3mmmh1.js +436 -0
- package/dist/shared/ab9gmbwy.js +213 -0
- package/dist/shared/{sycnx8gt.js → ax7qv55k.js} +18 -8
- package/dist/shared/{f5cw5q5r.js → aytqh5y2.js} +6 -4
- package/dist/shared/{fancm5pt.js → b5pftnn2.js} +138 -15
- package/dist/shared/{efmy2gcg.js → b76b8d95.js} +2 -2
- package/dist/shared/bdk4sty6.js +58 -0
- package/dist/shared/{32zqc1dw.js → bg3rym3g.js} +63 -32
- package/dist/shared/{0t22wwh1.js → bm22fvzr.js} +16 -14
- package/dist/shared/bz84tkzm.js +342 -0
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/cn957f8d.js +179 -0
- package/dist/shared/{pf0d8f77.js → cnkky55j.js} +25 -14
- package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
- package/dist/shared/{nkaxvt9q.js → dkxgzaqd.js} +224 -19
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
- package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/g6evj1j3.js +66 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{qv2ydck9.js → gs74dbj5.js} +651 -76
- package/dist/shared/gzaveazc.js +285 -0
- package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
- package/dist/shared/{dyj86cmj.js → hyh73qk6.js} +3 -3
- package/dist/shared/je4axnm8.js +22 -0
- package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
- package/dist/shared/{6qd27mx0.js → jvd0mqag.js} +5 -5
- package/dist/shared/jznfax0y.js +155 -0
- package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
- package/dist/shared/{ps7a6h14.js → kr0jzbw2.js} +12 -8
- package/dist/shared/{janx09m5.js → ktz42yez.js} +20 -8
- package/dist/shared/{gde73es6.js → m6p12kbr.js} +56 -55
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{nxdp2ze3.js → mtaszv5a.js} +144 -12
- package/dist/shared/n816peh1.js +45 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/{cctw17hj.js → p6qc5gcp.js} +38 -34
- package/dist/shared/{6rk2gen5.js → pbp1ss85.js} +20 -17
- package/dist/shared/pt94kz7f.js +6 -0
- package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
- package/dist/shared/q5c6ngn3.js +13 -0
- package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
- package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
- package/dist/shared/rhs3xe4k.js +7 -0
- package/dist/shared/{ntneex2a.js → rpycarcr.js} +6 -6
- package/dist/shared/{sdc7r2ww.js → rs73fca9.js} +8 -8
- package/dist/shared/{tm5ab8we.js → sfz1ksn6.js} +7 -4
- package/dist/shared/{6mnp99hx.js → svncdeh5.js} +16 -12
- package/dist/shared/{hf22e0wt.js → tbrvgw6z.js} +62 -42
- package/dist/shared/te5as7z7.js +622 -0
- package/dist/shared/{ga3sfy93.js → tsvww22q.js} +535 -200
- package/dist/shared/{47x8x9ze.js → ttsqgp4p.js} +20 -13
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/vb6qfyve.js +152 -0
- package/dist/shared/{r2sp8hrc.js → vczs8gd4.js} +22 -13
- package/dist/shared/{1g0drakv.js → vqrjpcqn.js} +145 -3
- package/dist/shared/{2pqx26h8.js → w72kgg4q.js} +31 -22
- package/dist/shared/{96qcj21c.js → w79hsckn.js} +16 -51
- package/dist/shared/wa07eas9.js +730 -0
- package/dist/shared/{k8v5v5wj.js → x933k9a3.js} +75 -34
- package/dist/shared/{cr74e96e.js → xhfsfkgk.js} +62 -28
- package/dist/shared/xjk7hnn5.js +272 -0
- package/dist/shared/{5enne4ma.js → xnxsed62.js} +66 -113
- package/dist/shared/xqve9598.js +53 -0
- package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
- package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
- package/dist/shared/y6njgyda.js +249 -0
- package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
- package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
- package/dist/shared/z7s6fpxv.js +62 -0
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
- package/dist/shared/zm0ptry0.js +40 -0
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zp9fmend.js +145 -0
- package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
- package/dist/tooling/cli.js +41 -15
- package/dist/tooling/migrate/apply.d.ts +14 -0
- package/dist/tooling/migrate/check.d.ts +3 -4
- package/dist/tooling/migrate/classify.d.ts +4 -0
- package/dist/tooling/migrate/config.d.ts +3 -2
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/files.d.ts +11 -1
- package/dist/tooling/migrate/index.js +14 -14
- package/dist/tooling/migrate/lint.d.ts +1 -1
- package/dist/tooling/migrate/lost.d.ts +28 -0
- package/dist/tooling/migrate/paths.d.ts +14 -0
- package/dist/tooling/migrate/plan.d.ts +6 -3
- package/dist/tooling/migrate/runner.d.ts +25 -0
- package/dist/tooling/migrate/sandbox.d.ts +57 -0
- package/dist/tooling/migrate/sql-lex.d.ts +20 -3
- package/dist/tooling/migrate/text.d.ts +42 -0
- package/dist/tooling/node-version.d.ts +21 -0
- package/dist/tooling/testing/facts.d.ts +33 -5
- package/dist/tooling/testing/index.d.ts +1 -1
- package/dist/tooling/testing/index.js +3 -3
- package/dist/tooling/testing/isolation.d.ts +11 -5
- package/package.json +8 -3
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/7zwwyh0v.js +0 -448
- package/dist/shared/aj2qxyhj.js +0 -90
- package/dist/shared/caw8b9d8.js +0 -204
- package/dist/shared/jwtxdj06.js +0 -76
- package/dist/shared/kfjp0gck.js +0 -212
- package/dist/shared/q58y17hy.js +0 -21
- package/dist/shared/qm7cdtvr.js +0 -912
- package/dist/shared/r8x5qhd7.js +0 -86
- package/dist/shared/zqrnhwsq.js +0 -31
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
POSTGRES_FLOOR,
|
|
3
|
+
isPostgresMajor,
|
|
4
|
+
parsePostgresFloor,
|
|
5
|
+
serverNeedsPostgres
|
|
6
|
+
} from "./ga9j92qj.js";
|
|
1
7
|
import {
|
|
2
8
|
withHttp,
|
|
3
9
|
attachHttp
|
|
4
|
-
} from "./
|
|
10
|
+
} from "./tbrvgw6z.js";
|
|
5
11
|
import {
|
|
6
12
|
OkmError2
|
|
7
13
|
} from "./52szzakm.js";
|
|
@@ -11,7 +17,7 @@ var versionQuery = "select current_setting('server_version_num'), version(), (se
|
|
|
11
17
|
async function acceptServer(pool, schema, rows, http, requireMeta, options, source) {
|
|
12
18
|
for (const name in schema.model) {
|
|
13
19
|
if (schema.model[name]?.presets !== undefined) {
|
|
14
|
-
(await import("./
|
|
20
|
+
(await import("./m7n9h2a5.js")).checkSchema(schema);
|
|
15
21
|
break;
|
|
16
22
|
}
|
|
17
23
|
}
|
|
@@ -31,7 +37,7 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
|
|
|
31
37
|
}));
|
|
32
38
|
}
|
|
33
39
|
} else {
|
|
34
|
-
const { assertCompatible } = await import("./
|
|
40
|
+
const { assertCompatible } = await import("./ek2wt2dz.js");
|
|
35
41
|
try {
|
|
36
42
|
await assertCompatible(pool, schema, recorded, source, options);
|
|
37
43
|
} catch (error) {
|
|
@@ -41,20 +47,21 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
|
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
const major = Math.floor(Number(rows[0]?.[0] ?? "0") / 1e4);
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
if (major <
|
|
47
|
-
throw new OkmError2("OKM1803",
|
|
48
|
-
fix: {
|
|
50
|
+
const raw = schema.requires?.postgres;
|
|
51
|
+
if (raw === undefined) {
|
|
52
|
+
if (major < POSTGRES_FLOOR) {
|
|
53
|
+
throw new OkmError2("OKM1803", serverNeedsPostgres(major, POSTGRES_FLOOR), withHttp(http, {
|
|
54
|
+
fix: {
|
|
55
|
+
summary: `Upgrade to PostgreSQL ${String(POSTGRES_FLOOR)} or higher.`
|
|
56
|
+
}
|
|
49
57
|
}));
|
|
50
58
|
}
|
|
51
59
|
return;
|
|
52
60
|
}
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
fix: { summary: "Upgrade the server, or lower requires to a version the server meets." }
|
|
61
|
+
const need = parsePostgresFloor(raw);
|
|
62
|
+
if (!isPostgresMajor(need) || major < need) {
|
|
63
|
+
throw new OkmError2("OKM1802", serverNeedsPostgres(major, isPostgresMajor(need) ? need : POSTGRES_FLOOR), withHttp(http, {
|
|
64
|
+
fix: { summary: "Upgrade the server, or lower minPostgres to a major the server meets." }
|
|
58
65
|
}));
|
|
59
66
|
}
|
|
60
67
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runWrite
|
|
3
|
+
} from "./n4jqhpqz.js";
|
|
4
|
+
import {
|
|
5
|
+
refuseUncancellableTimeout
|
|
6
|
+
} from "./2d3xq4ps.js";
|
|
7
|
+
import {
|
|
8
|
+
withHttp,
|
|
9
|
+
settleCall
|
|
10
|
+
} from "./tbrvgw6z.js";
|
|
11
|
+
import {
|
|
12
|
+
rejectKeys,
|
|
13
|
+
isRecord,
|
|
14
|
+
fail2
|
|
15
|
+
} from "./67txcrcw.js";
|
|
16
|
+
import {
|
|
17
|
+
OkmError2
|
|
18
|
+
} from "./52szzakm.js";
|
|
19
|
+
|
|
20
|
+
// src/runtime/batch.ts
|
|
21
|
+
async function batch(session, ops, options, replica) {
|
|
22
|
+
try {
|
|
23
|
+
if (replica !== undefined) {
|
|
24
|
+
throw new OkmError2("OKM1840", "batch() needs the primary. .replica() is not allowed on a batch.", withHttp(session.http, {
|
|
25
|
+
fix: { summary: "Remove .replica(). A batch always runs on the primary." }
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
if (!Array.isArray(ops))
|
|
29
|
+
fail2("OKM1121", "batch expects a list of write operations.");
|
|
30
|
+
const record = options ?? {};
|
|
31
|
+
if (!isRecord(record))
|
|
32
|
+
fail2("OKM1121", "batch options must be an object.");
|
|
33
|
+
rejectKeys(record, ["signal", "timeout"], "batch");
|
|
34
|
+
await refuseUncancellableTimeout(session.pool, typeof record["timeout"] === "number" ? record["timeout"] : undefined);
|
|
35
|
+
for (const op of ops) {
|
|
36
|
+
if (typeof op === "object" && op !== null && op["~refresh"] === true) {
|
|
37
|
+
fail2("OKM1121", "batch does not take refresh(). Await refresh() on its own. It is one statement and cannot share the batch.");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const prepared = [];
|
|
41
|
+
for (const op of ops) {
|
|
42
|
+
const plan = typeof op === "object" && op !== null ? op["~plan"] : undefined;
|
|
43
|
+
if (plan === undefined) {
|
|
44
|
+
fail2("OKM1121", "batch takes write operations: insert, update, delete, and archive. Pass them without awaiting.");
|
|
45
|
+
}
|
|
46
|
+
const item = await plan();
|
|
47
|
+
if (item.checked === "parent") {
|
|
48
|
+
throw new OkmError2("OKM1705", "batch does not take an update that sets a path column. The parent is checked in the statement, and a batch cannot report that after it commits. Use update({ where, set }) inside tx().", { fix: { summary: "Use update({ where, set }) inside tx()." } });
|
|
49
|
+
}
|
|
50
|
+
if (item.checked !== undefined) {
|
|
51
|
+
fail2("OKM1121", item.checked === "restore" ? "batch does not take restore: it is refused while its parent is archived, and a batch cannot report that after it commits. Use tx()." : "batch does not take a write with expect: the count is checked after the statement ran, and a batch cannot report that after it commits. Use tx().");
|
|
52
|
+
}
|
|
53
|
+
prepared.push(item);
|
|
54
|
+
}
|
|
55
|
+
return await run(session, prepared, record);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return settleCall(session, error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function run(session, prepared, options) {
|
|
61
|
+
await session.connected;
|
|
62
|
+
const statements = [];
|
|
63
|
+
const starts = [];
|
|
64
|
+
for (const item of prepared) {
|
|
65
|
+
starts.push(statements.length);
|
|
66
|
+
statements.push(...item.statements);
|
|
67
|
+
}
|
|
68
|
+
if (statements.length === 0)
|
|
69
|
+
return prepared.map((item) => item.finish([]));
|
|
70
|
+
let results;
|
|
71
|
+
try {
|
|
72
|
+
results = await runWrite(session, statements, call(options), true);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw at(error, starts);
|
|
75
|
+
}
|
|
76
|
+
const extra = await recover(session, prepared, results, starts, options);
|
|
77
|
+
return prepared.map((item, index) => {
|
|
78
|
+
const from = starts[index] ?? 0;
|
|
79
|
+
const slice = results.slice(from, from + item.statements.length);
|
|
80
|
+
const more = extra.get(index);
|
|
81
|
+
return item.finish(more === undefined ? slice : slice.concat(more));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function recover(session, prepared, results, starts, options) {
|
|
85
|
+
const pending = [];
|
|
86
|
+
for (let index = 0;index < prepared.length; index += 1) {
|
|
87
|
+
const item = prepared[index];
|
|
88
|
+
if (item?.follow === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const from = starts[index] ?? 0;
|
|
91
|
+
const more = item.follow(results.slice(from, from + item.statements.length));
|
|
92
|
+
if (more.length === 0)
|
|
93
|
+
continue;
|
|
94
|
+
pending.push({ index, statements: more });
|
|
95
|
+
}
|
|
96
|
+
const found = new Map;
|
|
97
|
+
if (pending.length === 0)
|
|
98
|
+
return found;
|
|
99
|
+
const flat = [];
|
|
100
|
+
const extraStarts = [];
|
|
101
|
+
for (const item of pending) {
|
|
102
|
+
extraStarts.push(flat.length);
|
|
103
|
+
flat.push(...item.statements);
|
|
104
|
+
}
|
|
105
|
+
let ran;
|
|
106
|
+
try {
|
|
107
|
+
ran = await runWrite(session, flat, call(options), true);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw mapExtra(error, pending, extraStarts);
|
|
110
|
+
}
|
|
111
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
112
|
+
const item = pending[index];
|
|
113
|
+
if (item === undefined)
|
|
114
|
+
continue;
|
|
115
|
+
const from = extraStarts[index] ?? 0;
|
|
116
|
+
found.set(item.index, ran.slice(from, extraStarts[index + 1] ?? ran.length));
|
|
117
|
+
}
|
|
118
|
+
return found;
|
|
119
|
+
}
|
|
120
|
+
function mapExtra(error, pending, extraStarts) {
|
|
121
|
+
const failed = error?.batchIndex;
|
|
122
|
+
const move = error?.at;
|
|
123
|
+
if (typeof failed !== "number" || typeof move !== "function")
|
|
124
|
+
return error;
|
|
125
|
+
let slot = 0;
|
|
126
|
+
while (slot + 1 < extraStarts.length && (extraStarts[slot + 1] ?? Infinity) <= failed)
|
|
127
|
+
slot += 1;
|
|
128
|
+
const op = pending[slot]?.index ?? slot;
|
|
129
|
+
return op === failed ? error : move.call(error, op);
|
|
130
|
+
}
|
|
131
|
+
function call(options) {
|
|
132
|
+
const { signal, timeout } = options;
|
|
133
|
+
if (signal === undefined && timeout === undefined)
|
|
134
|
+
return;
|
|
135
|
+
return {
|
|
136
|
+
...signal !== undefined ? { signal } : {},
|
|
137
|
+
...typeof timeout === "number" ? { timeout } : {}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function at(error, starts) {
|
|
141
|
+
const failed = error?.batchIndex;
|
|
142
|
+
const move = error?.at;
|
|
143
|
+
if (typeof failed !== "number" || typeof move !== "function")
|
|
144
|
+
return error;
|
|
145
|
+
let index = 0;
|
|
146
|
+
while (index + 1 < starts.length && (starts[index + 1] ?? Infinity) <= failed)
|
|
147
|
+
index += 1;
|
|
148
|
+
return index === failed ? error : move.call(error, index);
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
batch
|
|
152
|
+
};
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
refuseUncancellableTimeout
|
|
3
|
+
} from "./2d3xq4ps.js";
|
|
1
4
|
import {
|
|
2
5
|
isConnectionLost
|
|
3
|
-
} from "./
|
|
6
|
+
} from "./cnkky55j.js";
|
|
4
7
|
import {
|
|
5
8
|
openClient,
|
|
6
9
|
withHttp,
|
|
7
10
|
settleCall
|
|
8
|
-
} from "./
|
|
11
|
+
} from "./tbrvgw6z.js";
|
|
9
12
|
import {
|
|
10
13
|
rejectKeys,
|
|
11
14
|
isRecord,
|
|
12
|
-
|
|
13
|
-
} from "./
|
|
15
|
+
fail2
|
|
16
|
+
} from "./67txcrcw.js";
|
|
14
17
|
import {
|
|
15
18
|
OkmError2
|
|
16
19
|
} from "./52szzakm.js";
|
|
@@ -93,18 +96,19 @@ class Frame {
|
|
|
93
96
|
}
|
|
94
97
|
async function tx(session, args) {
|
|
95
98
|
if (typeof args[0] === "function" && args.length > 1) {
|
|
96
|
-
|
|
99
|
+
fail2("OKM1120", "options go first: tx(options, fn).");
|
|
97
100
|
}
|
|
98
101
|
const fn = typeof args[0] === "function" ? args[0] : args[1];
|
|
99
102
|
const given = typeof args[0] === "function" ? {} : args[0] ?? {};
|
|
100
103
|
try {
|
|
101
104
|
if (typeof fn !== "function")
|
|
102
|
-
|
|
105
|
+
fail2("OKM1121", "tx expects a callback: tx(fn) or tx(options, fn).");
|
|
103
106
|
if (!isRecord(given))
|
|
104
|
-
|
|
107
|
+
fail2("OKM1121", "tx options must be an object.");
|
|
105
108
|
rejectKeys(given, ["isolation", "retry", "signal", "timeout"], "tx");
|
|
106
109
|
const options = given;
|
|
107
110
|
check(options);
|
|
111
|
+
await refuseUncancellableTimeout(session.pool, options.timeout);
|
|
108
112
|
const call = fn;
|
|
109
113
|
return session.tx === undefined ? await outer(session, call, options) : await nested(session, call, options);
|
|
110
114
|
} catch (error) {
|
|
@@ -119,14 +123,14 @@ function failWith(session, error) {
|
|
|
119
123
|
}
|
|
120
124
|
function check(options) {
|
|
121
125
|
if (options.isolation !== undefined && !Object.hasOwn(BEGIN, options.isolation)) {
|
|
122
|
-
|
|
126
|
+
fail2("OKM1120", `isolation must be one of: ${Object.keys(BEGIN).join(", ")}.`);
|
|
123
127
|
}
|
|
124
128
|
const { retry, timeout } = options;
|
|
125
129
|
if (retry !== undefined && (!Number.isInteger(retry) || retry < 0)) {
|
|
126
|
-
|
|
130
|
+
fail2("OKM1121", "retry must be an integer from 0 up.");
|
|
127
131
|
}
|
|
128
132
|
if (timeout !== undefined && (typeof timeout !== "number" || !(timeout > 0))) {
|
|
129
|
-
|
|
133
|
+
fail2("OKM1121", "timeout must be a number of milliseconds above 0.");
|
|
130
134
|
}
|
|
131
135
|
}
|
|
132
136
|
async function outer(session, fn, options) {
|
|
@@ -265,7 +269,7 @@ async function run(session, after, hear) {
|
|
|
265
269
|
}
|
|
266
270
|
async function nested(session, fn, options) {
|
|
267
271
|
if (Object.keys(options).length > 0) {
|
|
268
|
-
|
|
272
|
+
fail2("OKM1121", "isolation, retry, timeout, and signal belong to the outermost tx(). A nested tx() is a savepoint on the same transaction.");
|
|
269
273
|
}
|
|
270
274
|
const { state: frame, depth } = session.tx;
|
|
271
275
|
frame.check();
|
|
@@ -275,6 +279,10 @@ async function nested(session, fn, options) {
|
|
|
275
279
|
const saved = frame.failed;
|
|
276
280
|
const after = [];
|
|
277
281
|
let released = false;
|
|
282
|
+
const hooks = session.pool;
|
|
283
|
+
const pending = hooks.okmScopePending?.();
|
|
284
|
+
if (pending !== undefined)
|
|
285
|
+
await pending;
|
|
278
286
|
try {
|
|
279
287
|
await step(session, frame, `SAVEPOINT ${name}`);
|
|
280
288
|
hear?.phase(session.hookm, "start", depth + 1);
|
|
@@ -293,6 +301,7 @@ async function nested(session, fn, options) {
|
|
|
293
301
|
await frame.conn.execute(`ROLLBACK TO SAVEPOINT ${name}`).catch(() => {
|
|
294
302
|
return;
|
|
295
303
|
});
|
|
304
|
+
hooks.okmForgetScope?.();
|
|
296
305
|
frame.failed = saved;
|
|
297
306
|
hear?.phase(session.hookm, "rollback", depth + 1);
|
|
298
307
|
}
|
|
@@ -338,7 +347,7 @@ function held(session, frame, after, depth) {
|
|
|
338
347
|
extras: {
|
|
339
348
|
afterCommit(callback) {
|
|
340
349
|
if (typeof callback !== "function") {
|
|
341
|
-
|
|
350
|
+
fail2("OKM1121", "afterCommit expects a function.");
|
|
342
351
|
}
|
|
343
352
|
frame.check();
|
|
344
353
|
after.push(callback);
|
|
@@ -371,7 +380,7 @@ function lockKey(key) {
|
|
|
371
380
|
}
|
|
372
381
|
const fits = typeof key === "number" ? Number.isSafeInteger(key) : typeof key === "bigint" && key >= -(2n ** 63n) && key < 2n ** 63n;
|
|
373
382
|
if (!fits)
|
|
374
|
-
|
|
383
|
+
fail2("OKM1121", "advisoryLock takes a string, a safe integer, or a bigint that fits in 64 bits.");
|
|
375
384
|
return ["select pg_advisory_xact_lock($1::bigint)", String(key)];
|
|
376
385
|
}
|
|
377
386
|
function callOf(options) {
|
|
@@ -1,11 +1,153 @@
|
|
|
1
1
|
import {
|
|
2
|
-
required
|
|
3
|
-
|
|
2
|
+
required,
|
|
3
|
+
openColumn
|
|
4
|
+
} from "./ywr8hmey.js";
|
|
4
5
|
import {
|
|
5
6
|
definition,
|
|
6
7
|
rejected
|
|
7
8
|
} from "./tmbdywx0.js";
|
|
8
9
|
|
|
10
|
+
// src/dialects/pg/integer.ts
|
|
11
|
+
function smallint2() {
|
|
12
|
+
return required({
|
|
13
|
+
baseType: "smallint",
|
|
14
|
+
encode: (value) => integerToken(value, -32768, 32767, "smallint"),
|
|
15
|
+
decode: (wire) => decodeBounded(wire, -32768, 32767, "smallint"),
|
|
16
|
+
sqlForm: "raw"
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function integer2() {
|
|
20
|
+
return required({
|
|
21
|
+
baseType: "integer",
|
|
22
|
+
encode: (value) => integerToken(value, -2147483648, 2147483647, "integer"),
|
|
23
|
+
decode: (wire) => decodeBounded(wire, -2147483648, 2147483647, "integer"),
|
|
24
|
+
sqlForm: "raw"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function bigint2(options) {
|
|
28
|
+
const mode = options?.as ?? "string";
|
|
29
|
+
if (mode === "number") {
|
|
30
|
+
return required({
|
|
31
|
+
baseType: "bigint",
|
|
32
|
+
encode: encodeBigintNumber,
|
|
33
|
+
decode: decodeBigintNumber,
|
|
34
|
+
sqlForm: "raw",
|
|
35
|
+
typeLabel: "number"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (mode === "bigint") {
|
|
39
|
+
return required({
|
|
40
|
+
baseType: "bigint",
|
|
41
|
+
encode: encodeBigintValue,
|
|
42
|
+
decode: decodeBigintValue,
|
|
43
|
+
sqlForm: "raw",
|
|
44
|
+
typeLabel: "bigint"
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (mode !== "string") {
|
|
48
|
+
definition(`bigint as ${String(mode)} must be string, number, or bigint.`);
|
|
49
|
+
}
|
|
50
|
+
return required({
|
|
51
|
+
baseType: "bigint",
|
|
52
|
+
encode: encodeBigintString,
|
|
53
|
+
decode: decodeBigintString,
|
|
54
|
+
sqlForm: "raw"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function identity2(options) {
|
|
58
|
+
const mode = options?.as ?? "string";
|
|
59
|
+
if (mode === "number") {
|
|
60
|
+
return openColumn({
|
|
61
|
+
...identityFlags(),
|
|
62
|
+
encode: encodeBigintNumber,
|
|
63
|
+
decode: decodeBigintNumber,
|
|
64
|
+
typeLabel: "number"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (mode === "bigint") {
|
|
68
|
+
return openColumn({
|
|
69
|
+
...identityFlags(),
|
|
70
|
+
encode: encodeBigintValue,
|
|
71
|
+
decode: decodeBigintValue,
|
|
72
|
+
typeLabel: "bigint"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (mode !== "string") {
|
|
76
|
+
definition(`identity as ${String(mode)} must be string, number, or bigint.`);
|
|
77
|
+
}
|
|
78
|
+
return openColumn({
|
|
79
|
+
...identityFlags(),
|
|
80
|
+
encode: encodeBigintString,
|
|
81
|
+
decode: decodeBigintString
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function encodeBigintString(value) {
|
|
85
|
+
parseBigint(value);
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
function decodeBigintString(wire) {
|
|
89
|
+
return encodeBigintString(wire);
|
|
90
|
+
}
|
|
91
|
+
function encodeBigintNumber(value) {
|
|
92
|
+
if (!Number.isSafeInteger(value)) {
|
|
93
|
+
rejected(`bigint number ${String(value)} must be an integer from ${String(Number.MIN_SAFE_INTEGER)} to ${String(Number.MAX_SAFE_INTEGER)}.`);
|
|
94
|
+
}
|
|
95
|
+
return String(value);
|
|
96
|
+
}
|
|
97
|
+
function decodeBigintNumber(wire) {
|
|
98
|
+
const parsed = parseBigint(wire);
|
|
99
|
+
const value = Number(parsed);
|
|
100
|
+
if (!Number.isSafeInteger(value)) {
|
|
101
|
+
rejected(`bigint ${wire} must be an integer from ${String(Number.MIN_SAFE_INTEGER)} to ${String(Number.MAX_SAFE_INTEGER)} when as is number.`);
|
|
102
|
+
}
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
function encodeBigintValue(value) {
|
|
106
|
+
return value.toString();
|
|
107
|
+
}
|
|
108
|
+
function decodeBigintValue(wire) {
|
|
109
|
+
return parseBigint(wire);
|
|
110
|
+
}
|
|
111
|
+
function integerToken(value, min, max, role) {
|
|
112
|
+
if (!Number.isInteger(value) || value < min || value > max) {
|
|
113
|
+
rejected(`${role} ${String(value)} must be an integer from ${String(min)} to ${String(max)}.`);
|
|
114
|
+
}
|
|
115
|
+
return String(value);
|
|
116
|
+
}
|
|
117
|
+
function decodeBounded(wire, min, max, role) {
|
|
118
|
+
if (!integerText().test(wire)) {
|
|
119
|
+
rejected(`${role} ${wire} must be an integer, for example 0 or -12.`);
|
|
120
|
+
}
|
|
121
|
+
const value = Number(wire);
|
|
122
|
+
integerToken(value, min, max, role);
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
function identityFlags() {
|
|
126
|
+
return {
|
|
127
|
+
baseType: "bigint",
|
|
128
|
+
nullable: false,
|
|
129
|
+
hasDefault: true,
|
|
130
|
+
generated: false,
|
|
131
|
+
guarded: false,
|
|
132
|
+
hidden: false,
|
|
133
|
+
omitWrite: true,
|
|
134
|
+
sqlForm: "raw",
|
|
135
|
+
identity: { always: true },
|
|
136
|
+
primaryKey: true
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function parseBigint(wire) {
|
|
140
|
+
if (!integerText().test(wire)) {
|
|
141
|
+
rejected(`bigint ${wire} must be an integer with no leading zeros, for example 0 or -12.`);
|
|
142
|
+
}
|
|
143
|
+
return BigInt(wire);
|
|
144
|
+
}
|
|
145
|
+
function integerText() {
|
|
146
|
+
integerPattern ??= /^-?(?:0|[1-9]\d*)$/;
|
|
147
|
+
return integerPattern;
|
|
148
|
+
}
|
|
149
|
+
var integerPattern;
|
|
150
|
+
|
|
9
151
|
// src/dialects/pg/temporal.ts
|
|
10
152
|
var TEMPORAL_MISSING = "Date and time codecs need the Temporal global. okmodel does not ship a polyfill. Use a runtime that provides Temporal, or assign a polyfill to globalThis.Temporal before using these columns.";
|
|
11
153
|
function requireTemporal() {
|
|
@@ -222,4 +364,4 @@ function timed(name, precision) {
|
|
|
222
364
|
return `${name}(${String(precision)})`;
|
|
223
365
|
}
|
|
224
366
|
|
|
225
|
-
export { encodeInstant, decodeInstant, encodeDate, decodeDate, timestamptz2, timestamp2, date2, time2, timetz2, interval2 };
|
|
367
|
+
export { smallint2, integer2, bigint2, identity2, encodeBigintString, decodeBigintString, integerToken, encodeInstant, decodeInstant, encodeDate, decodeDate, timestamptz2, timestamp2, date2, time2, timetz2, interval2 };
|
|
@@ -1,36 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./14vx95q4.js";
|
|
4
|
+
import"./qq3899ht.js";
|
|
5
5
|
import {
|
|
6
6
|
createdOf,
|
|
7
7
|
testing2
|
|
8
|
-
} from "./
|
|
8
|
+
} from "./7k9grvf6.js";
|
|
9
9
|
import"./n442h54c.js";
|
|
10
10
|
import {
|
|
11
|
+
projectPath,
|
|
11
12
|
loadConfig,
|
|
12
13
|
loadSchema
|
|
13
|
-
} from "./
|
|
14
|
+
} from "./gs74dbj5.js";
|
|
14
15
|
import {
|
|
16
|
+
sessionFailure,
|
|
17
|
+
finishQuiet,
|
|
15
18
|
assertTargetPolicy,
|
|
16
19
|
assertDirectConnection,
|
|
17
20
|
assertStableBackend,
|
|
18
21
|
selectTarget
|
|
19
|
-
} from "./
|
|
20
|
-
import"./
|
|
22
|
+
} from "./tsvww22q.js";
|
|
23
|
+
import"./9s0ypp87.js";
|
|
21
24
|
import {
|
|
22
25
|
OkmError2
|
|
23
26
|
} from "./52szzakm.js";
|
|
24
27
|
|
|
25
28
|
// src/tooling/migrate/seed.ts
|
|
26
29
|
import { existsSync } from "node:fs";
|
|
27
|
-
import { join } from "node:path";
|
|
28
30
|
import { pathToFileURL } from "node:url";
|
|
29
31
|
async function seedProject(cwd, file, flags) {
|
|
30
32
|
const config = await loadConfig(cwd);
|
|
31
33
|
const target = selectTarget(config, flags.target);
|
|
32
34
|
assertTargetPolicy(target, "seed", flags.allowProtected);
|
|
33
|
-
const path =
|
|
35
|
+
const path = projectPath(cwd, file);
|
|
34
36
|
if (!existsSync(path)) {
|
|
35
37
|
throw new OkmError2("invalid", `Seed file ${file} was not found.`, {
|
|
36
38
|
fix: { summary: "Pass okm seed <file> a module in this project." }
|
|
@@ -40,20 +42,21 @@ async function seedProject(cwd, file, flags) {
|
|
|
40
42
|
assertDirectConnection(target.url, allowPooler);
|
|
41
43
|
const schema = await loadSchema(cwd, config.schema);
|
|
42
44
|
const pool = open2({ url: target.url, max: 1 });
|
|
43
|
-
|
|
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
|
-
}
|
|
55
|
-
const harness = await testing2(schema, { driver: pool, migrate: false });
|
|
45
|
+
let harness;
|
|
56
46
|
try {
|
|
47
|
+
const held = await pool.reserve?.();
|
|
48
|
+
if (held !== undefined) {
|
|
49
|
+
try {
|
|
50
|
+
await assertStableBackend(async () => {
|
|
51
|
+
const result = await held.execute("select pg_backend_pid()::text");
|
|
52
|
+
const cell = result.rows[0]?.[0];
|
|
53
|
+
return cell === null || cell === undefined ? "" : String(cell);
|
|
54
|
+
}, allowPooler);
|
|
55
|
+
} finally {
|
|
56
|
+
await finishQuiet(() => held.release());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
harness = await testing2(schema, { driver: pool, migrate: false });
|
|
57
60
|
const imported = await import(`${pathToFileURL(path).href}?okm=${Date.now()}`);
|
|
58
61
|
const seed = isRecord(imported) ? imported.default : undefined;
|
|
59
62
|
if (typeof seed !== "function") {
|
|
@@ -63,8 +66,14 @@ async function seedProject(cwd, file, flags) {
|
|
|
63
66
|
}
|
|
64
67
|
await seed(harness);
|
|
65
68
|
return formatCreated(target.name, createdOf(harness));
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw sessionFailure(error) ?? error;
|
|
66
71
|
} finally {
|
|
67
|
-
|
|
72
|
+
const opened = harness;
|
|
73
|
+
if (opened !== undefined)
|
|
74
|
+
await finishQuiet(() => opened.close());
|
|
75
|
+
else
|
|
76
|
+
await finishQuiet(() => pool.close());
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
function formatCreated(target, counts) {
|