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
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError2,
|
|
3
|
+
catalogError2,
|
|
4
|
+
throwNamed2
|
|
5
|
+
} from "./52szzakm.js";
|
|
6
|
+
|
|
7
|
+
// src/dialects/pg/morph.ts
|
|
8
|
+
var refuseTo = (planner, schema, relation, child, sink, parent, alias, depth) => {
|
|
9
|
+
const morph = relation.morph;
|
|
10
|
+
const typeField = morph?.typeField ?? "type";
|
|
11
|
+
const idField = morph?.idField ?? "id";
|
|
12
|
+
throw new OkmError2("OKM1120", `Relation ${relation.name} is a morph. Filter ${typeField} and ${idField}, or include it. has, none, and every are not available on it.`);
|
|
13
|
+
};
|
|
14
|
+
function resolveMorph(scope, name, targets) {
|
|
15
|
+
const label = `${scope.owner}.${scope.name}`;
|
|
16
|
+
const owner = described(scope, scope.owner, label);
|
|
17
|
+
const typeField = `${name}Type`;
|
|
18
|
+
const idField = `${name}Id`;
|
|
19
|
+
const typeColumn = requireColumn(owner, typeField, label);
|
|
20
|
+
const idColumn = requireColumn(owner, idField, label);
|
|
21
|
+
if (typeColumn.nullable !== idColumn.nullable) {
|
|
22
|
+
catalogError2("OKM1021", `Relation ${label} columns ${owner.tsName}.${typeColumn.field} and ${owner.tsName}.${idColumn.field} must both be nullable, or neither.`);
|
|
23
|
+
}
|
|
24
|
+
if (!isTextType(typeColumn.dataType)) {
|
|
25
|
+
catalogError2("OKM1022", `Relation ${label} type column ${owner.tsName}.${typeColumn.field} is ${typeColumn.dataType}. Accepted type: text.`);
|
|
26
|
+
}
|
|
27
|
+
const seen = new Set;
|
|
28
|
+
const resolved = [];
|
|
29
|
+
for (const targetName of targets) {
|
|
30
|
+
if (seen.has(targetName)) {
|
|
31
|
+
catalogError2("OKM1023", `Relation ${label} lists ${targetName} twice.`);
|
|
32
|
+
}
|
|
33
|
+
seen.add(targetName);
|
|
34
|
+
if (!scope.tables.includes(targetName)) {
|
|
35
|
+
throwNamed2("OKM1020", targetName, scope.tables, `Relation ${label} names ${targetName}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
36
|
+
}
|
|
37
|
+
const target = described(scope, targetName, label);
|
|
38
|
+
const key = requireKey(target, label, scope.scopeFields);
|
|
39
|
+
if (idColumn.dataType !== key.dataType) {
|
|
40
|
+
catalogError2("OKM1022", `Relation ${label} id column ${owner.tsName}.${idColumn.field} is ${idColumn.dataType} and ${target.tsName}.${key.field} is ${key.dataType}. Accepted type: ${key.dataType}.`);
|
|
41
|
+
}
|
|
42
|
+
const limit = textLimit(typeColumn.dataType);
|
|
43
|
+
if (limit !== undefined && targetName.length > limit) {
|
|
44
|
+
catalogError2("OKM1022", `Relation ${label} type column ${owner.tsName}.${typeColumn.field} is ${typeColumn.dataType} and ${target.tsName} does not fit. Accepted type: text.`);
|
|
45
|
+
}
|
|
46
|
+
resolved.push({
|
|
47
|
+
type: target.tsName,
|
|
48
|
+
table: target.tsName,
|
|
49
|
+
sql: target.sqlName,
|
|
50
|
+
keySql: key.sql
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const first = resolved[0];
|
|
54
|
+
if (first === undefined) {
|
|
55
|
+
catalogError2("OKM1020", `Relation ${label} needs a target table.`);
|
|
56
|
+
}
|
|
57
|
+
const morph = {
|
|
58
|
+
direction: "to",
|
|
59
|
+
name,
|
|
60
|
+
typeField,
|
|
61
|
+
idField,
|
|
62
|
+
typeSql: typeColumn.sqlName,
|
|
63
|
+
idSql: idColumn.sqlName,
|
|
64
|
+
targets: resolved
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
name: scope.name,
|
|
68
|
+
kind: "one",
|
|
69
|
+
table: first.table,
|
|
70
|
+
local: [idColumn.sqlName],
|
|
71
|
+
remote: [first.keySql],
|
|
72
|
+
morph,
|
|
73
|
+
through: {
|
|
74
|
+
table: first.table,
|
|
75
|
+
local: [idColumn.sqlName],
|
|
76
|
+
remote: [first.keySql],
|
|
77
|
+
emit: refuseTo
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function resolveMorphMany(scope, table, name) {
|
|
82
|
+
const label = `${scope.owner}.${scope.name}`;
|
|
83
|
+
if (!scope.tables.includes(table)) {
|
|
84
|
+
throwNamed2("OKM1020", table, scope.tables, `Relation ${label} names ${table}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
85
|
+
}
|
|
86
|
+
const owner = described(scope, table, label);
|
|
87
|
+
const here = described(scope, scope.owner, label);
|
|
88
|
+
const targets = declaredTargets(owner.relationOptions, name);
|
|
89
|
+
if (targets === undefined) {
|
|
90
|
+
catalogError2("OKM1021", `Relation ${label} needs morph("${name}", [...]) on ${owner.tsName}. ${owner.tsName} has no morph named ${name}.`);
|
|
91
|
+
}
|
|
92
|
+
if (!targets.includes(scope.owner)) {
|
|
93
|
+
catalogError2("OKM1020", `Relation ${label} is not a target of ${owner.tsName}.${name}. Accepted tables: ${targets.join(", ")}.`);
|
|
94
|
+
}
|
|
95
|
+
const typeField = `${name}Type`;
|
|
96
|
+
const idField = `${name}Id`;
|
|
97
|
+
const typeColumn = requireColumn(owner, typeField, label);
|
|
98
|
+
const idColumn = requireColumn(owner, idField, label);
|
|
99
|
+
const key = requireKey(here, label, scope.scopeFields);
|
|
100
|
+
if (idColumn.dataType !== key.dataType) {
|
|
101
|
+
catalogError2("OKM1022", `Relation ${label} id column ${owner.tsName}.${idColumn.field} is ${idColumn.dataType} and ${here.tsName}.${key.field} is ${key.dataType}. Accepted type: ${key.dataType}.`);
|
|
102
|
+
}
|
|
103
|
+
const morph = {
|
|
104
|
+
direction: "many",
|
|
105
|
+
name,
|
|
106
|
+
typeField,
|
|
107
|
+
idField,
|
|
108
|
+
typeSql: typeColumn.sqlName,
|
|
109
|
+
idSql: idColumn.sqlName,
|
|
110
|
+
typeValue: here.tsName,
|
|
111
|
+
targets: [
|
|
112
|
+
{
|
|
113
|
+
type: here.tsName,
|
|
114
|
+
table: here.tsName,
|
|
115
|
+
sql: here.sqlName,
|
|
116
|
+
keySql: key.sql
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
name: scope.name,
|
|
122
|
+
kind: "many",
|
|
123
|
+
table: owner.tsName,
|
|
124
|
+
local: [key.sql],
|
|
125
|
+
remote: [idColumn.sqlName],
|
|
126
|
+
morph,
|
|
127
|
+
through: {
|
|
128
|
+
table: owner.tsName,
|
|
129
|
+
local: [idColumn.sqlName],
|
|
130
|
+
remote: [key.sql],
|
|
131
|
+
emit: morphManyEmit(here.tsName)
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function morphManyEmit(typeValue) {
|
|
136
|
+
return (planner, schema, relation, child, sink, parent, alias) => {
|
|
137
|
+
const pair = relation.morph;
|
|
138
|
+
const local = relation.local[0];
|
|
139
|
+
if (pair === undefined || local === undefined) {
|
|
140
|
+
throw new OkmError2("OKM1120", `Relation ${relation.name} is not a morph many.`);
|
|
141
|
+
}
|
|
142
|
+
const { quote } = planner;
|
|
143
|
+
sink.text(quote(child.model.sql));
|
|
144
|
+
sink.text(" ");
|
|
145
|
+
sink.text(alias);
|
|
146
|
+
sink.text(" where ");
|
|
147
|
+
sink.text(alias);
|
|
148
|
+
sink.text(".");
|
|
149
|
+
sink.text(quote(pair.typeSql));
|
|
150
|
+
sink.text(" = ");
|
|
151
|
+
sink.param(typeValue);
|
|
152
|
+
sink.text("::text");
|
|
153
|
+
sink.text(" and ");
|
|
154
|
+
sink.text(alias);
|
|
155
|
+
sink.text(".");
|
|
156
|
+
sink.text(quote(pair.idSql));
|
|
157
|
+
sink.text(" = ");
|
|
158
|
+
sink.text(parent);
|
|
159
|
+
sink.text(".");
|
|
160
|
+
sink.text(quote(local));
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function described(scope, table, label) {
|
|
164
|
+
const found = scope.describe?.(table);
|
|
165
|
+
if (!isDescribed(found)) {
|
|
166
|
+
catalogError2("OKM1020", `Relation ${label} names ${table}, which is not in the schema.`);
|
|
167
|
+
}
|
|
168
|
+
return found;
|
|
169
|
+
}
|
|
170
|
+
function isDescribed(value) {
|
|
171
|
+
if (typeof value !== "object" || value === null)
|
|
172
|
+
return false;
|
|
173
|
+
if (!("tsName" in value) || typeof value.tsName !== "string")
|
|
174
|
+
return false;
|
|
175
|
+
if (!("sqlName" in value) || typeof value.sqlName !== "string")
|
|
176
|
+
return false;
|
|
177
|
+
if (!("primary" in value) || !Array.isArray(value.primary))
|
|
178
|
+
return false;
|
|
179
|
+
if (!("byField" in value) || !(value.byField instanceof Map))
|
|
180
|
+
return false;
|
|
181
|
+
if (!("bySql" in value) || !(value.bySql instanceof Map))
|
|
182
|
+
return false;
|
|
183
|
+
return "relationOptions" in value;
|
|
184
|
+
}
|
|
185
|
+
function requireColumn(table, field, label) {
|
|
186
|
+
const column = table.byField.get(field);
|
|
187
|
+
if (column === undefined) {
|
|
188
|
+
catalogError2("OKM1021", `Relation ${label} needs column ${field} on ${table.tsName}.`);
|
|
189
|
+
}
|
|
190
|
+
return column;
|
|
191
|
+
}
|
|
192
|
+
function requireKey(table, label, scopeFields) {
|
|
193
|
+
const skip = scopeFields ?? [];
|
|
194
|
+
const keys = [];
|
|
195
|
+
for (const sql of table.primary) {
|
|
196
|
+
const column = table.bySql.get(sql);
|
|
197
|
+
if (column === undefined || skip.includes(column.field))
|
|
198
|
+
continue;
|
|
199
|
+
keys.push({ field: column.field, sql, dataType: column.dataType });
|
|
200
|
+
}
|
|
201
|
+
const only = keys.length === 1 ? keys[0] : undefined;
|
|
202
|
+
if (only !== undefined)
|
|
203
|
+
return only;
|
|
204
|
+
const names = keys.map((key) => key.field);
|
|
205
|
+
catalogError2("OKM1021", `Relation ${label} cannot use ${table.tsName} as a target. Its primary key is ${names.length === 0 ? "(none)" : names.join(", ")}. A morph id matches one column.`);
|
|
206
|
+
}
|
|
207
|
+
function declaredTargets(options, name) {
|
|
208
|
+
if (typeof options !== "object" || options === null)
|
|
209
|
+
return;
|
|
210
|
+
for (const value of Object.values(options)) {
|
|
211
|
+
if (typeof value !== "object" || value === null || !("morph" in value))
|
|
212
|
+
continue;
|
|
213
|
+
const morph = value.morph;
|
|
214
|
+
if (morph === undefined || morph.name !== name || !Array.isArray(morph.targets))
|
|
215
|
+
continue;
|
|
216
|
+
const names = [];
|
|
217
|
+
for (const target of morph.targets) {
|
|
218
|
+
if (typeof target === "string")
|
|
219
|
+
names.push(target);
|
|
220
|
+
}
|
|
221
|
+
return names;
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
function assertMorphTo(name, type, id) {
|
|
226
|
+
if (name === null || type === null || typeof id !== "string" || id.length === 0) {
|
|
227
|
+
throw new OkmError2("OKM1120", "morphTo() needs a morph name, a target table, and that table's id.");
|
|
228
|
+
}
|
|
229
|
+
if (typeof name !== "string" || name.length === 0 || typeof type !== "string" || type.length === 0) {
|
|
230
|
+
throw new OkmError2("OKM1020", "morphTo() needs a morph name and a target table.");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function isTextType(dataType) {
|
|
234
|
+
return dataType === "text" || dataType === "citext" || dataType.startsWith("varchar(") || dataType.startsWith("character varying(") || dataType.startsWith("char(") || dataType.startsWith("character(");
|
|
235
|
+
}
|
|
236
|
+
function textLimit(dataType) {
|
|
237
|
+
const match = /^(?:varchar|character varying|char|character)\((\d+)\)$/.exec(dataType);
|
|
238
|
+
if (match?.[1] === undefined)
|
|
239
|
+
return;
|
|
240
|
+
return Number(match[1]);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/dialects/pg/through.ts
|
|
244
|
+
var emit = (planner, schema, relation, child, sink, parent, alias, depth) => {
|
|
245
|
+
const through = relation.through;
|
|
246
|
+
const join = through === undefined ? undefined : planner.indexes(schema).get(through.table);
|
|
247
|
+
if (through === undefined || join === undefined) {
|
|
248
|
+
return catalogError2("OKM1020", `Relation ${relation.name} names a join table that is not in the schema.`);
|
|
249
|
+
}
|
|
250
|
+
const { quote } = planner;
|
|
251
|
+
const joinAlias = `j${alias}`;
|
|
252
|
+
sink.mark(`via:${through.table}`);
|
|
253
|
+
sink.text(`${quote(join.model.sql)} ${joinAlias} join ${quote(child.model.sql)} ${alias} on `);
|
|
254
|
+
for (let index = 0;index < through.local.length; index += 1) {
|
|
255
|
+
const local = through.local[index];
|
|
256
|
+
const remote = through.remote[index];
|
|
257
|
+
if (local === undefined || remote === undefined)
|
|
258
|
+
continue;
|
|
259
|
+
if (index > 0)
|
|
260
|
+
sink.text(" and ");
|
|
261
|
+
sink.text(`${alias}.${quote(remote)} = ${joinAlias}.${quote(local)}`);
|
|
262
|
+
}
|
|
263
|
+
sink.text(" where ");
|
|
264
|
+
planner.join(sink, parent, joinAlias, relation);
|
|
265
|
+
planner.where(schema, join, undefined, sink, joinAlias, depth + 1, true);
|
|
266
|
+
};
|
|
267
|
+
function resolveThrough(scope, table, through, from, to) {
|
|
268
|
+
for (const name of [table, through]) {
|
|
269
|
+
if (!scope.tables.includes(name)) {
|
|
270
|
+
throwNamed2("OKM1020", name, scope.tables, `Relation ${scope.owner}.${scope.name} names ${name}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const toOwner = pick(scope, through, scope.owner, from, `${scope.owner}.${scope.name}`, "from");
|
|
274
|
+
const toTable = pick(scope, through, table, to, `${scope.owner}.${scope.name}`, "to");
|
|
275
|
+
if (toOwner === toTable) {
|
|
276
|
+
catalogError2("OKM1021", `Relation ${scope.owner}.${scope.name} uses ${toOwner.fromField} on ${through} for both ends. Pass from and to.`);
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
name: scope.name,
|
|
280
|
+
kind: "many",
|
|
281
|
+
table,
|
|
282
|
+
local: toOwner.remote,
|
|
283
|
+
remote: toOwner.local,
|
|
284
|
+
through: { table: through, local: toTable.local, remote: toTable.remote, emit }
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function pick(scope, through, target, field, label, end) {
|
|
288
|
+
const matches = scope.edges.filter((edge) => edge.fromTable === through && edge.toTable === target && (field === undefined || edge.fromField === field));
|
|
289
|
+
const [only] = matches;
|
|
290
|
+
if (matches.length === 1 && only !== undefined)
|
|
291
|
+
return only;
|
|
292
|
+
const fields = matches.map((edge) => edge.fromField).sort();
|
|
293
|
+
catalogError2("OKM1021", `Relation ${label} through ${through} is ambiguous at ${end}. Accepted columns: ${fields.length === 0 ? "(none)" : fields.join(", ")}.`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/dialects/pg/relations.ts
|
|
297
|
+
function one2(table, field) {
|
|
298
|
+
return { kind: "one", table, field };
|
|
299
|
+
}
|
|
300
|
+
function many2(table, field) {
|
|
301
|
+
return { kind: "many", table, field };
|
|
302
|
+
}
|
|
303
|
+
function isRelationCall(value) {
|
|
304
|
+
if (typeof value !== "object" || value === null)
|
|
305
|
+
return false;
|
|
306
|
+
if (!("kind" in value) || !("table" in value))
|
|
307
|
+
return false;
|
|
308
|
+
const kind = value.kind;
|
|
309
|
+
return (kind === "one" || kind === "many") && typeof value.table === "string";
|
|
310
|
+
}
|
|
311
|
+
function manyThrough2(table, options) {
|
|
312
|
+
const { through, from, to } = options;
|
|
313
|
+
return {
|
|
314
|
+
kind: "many",
|
|
315
|
+
table,
|
|
316
|
+
field: undefined,
|
|
317
|
+
through,
|
|
318
|
+
resolve: (scope) => resolveThrough(scope, table, through, from, to)
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function morph2(name, targets) {
|
|
322
|
+
if (name.length === 0)
|
|
323
|
+
throw new OkmError2("OKM1020", "morph() needs a name.");
|
|
324
|
+
if (targets.length === 0)
|
|
325
|
+
throw new OkmError2("OKM1020", "morph() needs a target table.");
|
|
326
|
+
for (const target of targets) {
|
|
327
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
328
|
+
throw new OkmError2("OKM1020", "morph() targets must be table names.");
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const list = targets;
|
|
332
|
+
return {
|
|
333
|
+
kind: "one",
|
|
334
|
+
table: targets[0],
|
|
335
|
+
field: undefined,
|
|
336
|
+
morph: { name, targets, typeField: `${name}Type` },
|
|
337
|
+
resolve: (scope) => resolveMorph(scope, name, list)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function morphMany2(table, name) {
|
|
341
|
+
if (table.length === 0 || name.length === 0) {
|
|
342
|
+
throw new OkmError2("OKM1020", "morphMany() needs a table and a morph name.");
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
kind: "many",
|
|
346
|
+
table,
|
|
347
|
+
field: undefined,
|
|
348
|
+
resolve: (scope) => resolveMorphMany(scope, table, name)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function morphTo2(name, type, id) {
|
|
352
|
+
assertMorphTo(name, type, id);
|
|
353
|
+
const row = {};
|
|
354
|
+
row[`${name}Type`] = type;
|
|
355
|
+
row[`${name}Id`] = id;
|
|
356
|
+
return row;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export { one2, many2, isRelationCall, manyThrough2, morph2, morphMany2, morphTo2 };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mapFailure
|
|
3
|
+
} from "./kb2sdhfb.js";
|
|
4
|
+
|
|
5
|
+
// src/adapters/pg/pglite-wire.ts
|
|
6
|
+
var OIDS = [
|
|
7
|
+
16,
|
|
8
|
+
17,
|
|
9
|
+
20,
|
|
10
|
+
21,
|
|
11
|
+
23,
|
|
12
|
+
25,
|
|
13
|
+
114,
|
|
14
|
+
700,
|
|
15
|
+
701,
|
|
16
|
+
1043,
|
|
17
|
+
1082,
|
|
18
|
+
1114,
|
|
19
|
+
1184,
|
|
20
|
+
1700,
|
|
21
|
+
2950,
|
|
22
|
+
3802,
|
|
23
|
+
1000,
|
|
24
|
+
1005,
|
|
25
|
+
1007,
|
|
26
|
+
1009,
|
|
27
|
+
1016,
|
|
28
|
+
1115,
|
|
29
|
+
1182,
|
|
30
|
+
1185,
|
|
31
|
+
1231,
|
|
32
|
+
199,
|
|
33
|
+
3807
|
|
34
|
+
];
|
|
35
|
+
function identity(value) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function serialize(value) {
|
|
39
|
+
if (typeof value === "number" || typeof value === "bigint")
|
|
40
|
+
return String(value);
|
|
41
|
+
if (typeof value === "boolean")
|
|
42
|
+
return value ? "t" : "f";
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
var parsers = {};
|
|
46
|
+
var serializers = {};
|
|
47
|
+
for (const oid of OIDS) {
|
|
48
|
+
parsers[oid] = identity;
|
|
49
|
+
serializers[oid] = serialize;
|
|
50
|
+
}
|
|
51
|
+
function fail(error) {
|
|
52
|
+
return mapFailure(protocol(error));
|
|
53
|
+
}
|
|
54
|
+
function protocol(error) {
|
|
55
|
+
if (typeof error !== "object" || error === null || !("code" in error))
|
|
56
|
+
return error;
|
|
57
|
+
if (error.code !== "08P01")
|
|
58
|
+
return error;
|
|
59
|
+
const message = error instanceof Error ? error.message : "";
|
|
60
|
+
return new Error(message.length > 0 ? message : "protocol error");
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
fail,
|
|
64
|
+
parsers,
|
|
65
|
+
serializers
|
|
66
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/dialects/pg/floor.ts
|
|
2
|
+
var POSTGRES_FLOOR = 15;
|
|
3
|
+
var UUIDV7_POSTGRES = 18;
|
|
4
|
+
function isPostgresMajor(value) {
|
|
5
|
+
return typeof value === "number" && (value | 0) === value && value >= 15 && value <= 18;
|
|
6
|
+
}
|
|
7
|
+
var FLOOR_TEXT = /^>=(\d+)$/;
|
|
8
|
+
function parsePostgresFloor(postgres) {
|
|
9
|
+
return Number(FLOOR_TEXT.exec(postgres ?? "")?.[1]);
|
|
10
|
+
}
|
|
11
|
+
function formatPostgresFloor(major) {
|
|
12
|
+
return `>=${major}`;
|
|
13
|
+
}
|
|
14
|
+
function minPostgresDefinition() {
|
|
15
|
+
return "minPostgres: 15-18.";
|
|
16
|
+
}
|
|
17
|
+
function uuidv7NeedsPostgres() {
|
|
18
|
+
const need = UUIDV7_POSTGRES;
|
|
19
|
+
return `uuidv7() needs PostgreSQL ${need} or higher. minPostgres: ${need}.`;
|
|
20
|
+
}
|
|
21
|
+
function serverNeedsPostgres(server, need) {
|
|
22
|
+
return `The server is PostgreSQL ${server}. This schema needs PostgreSQL ${need} or higher (minPostgres: ${need}).`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { POSTGRES_FLOOR, UUIDV7_POSTGRES, isPostgresMajor, parsePostgresFloor, formatPostgresFloor, minPostgresDefinition, uuidv7NeedsPostgres, serverNeedsPostgres };
|