okmodel 0.1.1 → 0.3.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 +727 -37
- package/dist/adapters/capabilities.d.ts +34 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +17 -0
- package/dist/adapters/pg/bunsql.d.ts +60 -0
- package/dist/adapters/pg/call.d.ts +2 -12
- package/dist/adapters/pg/nodepostgres-extra.d.ts +18 -0
- package/dist/adapters/pg/nodepostgres.d.ts +57 -0
- package/dist/adapters/pg/postgres-extra.d.ts +50 -1
- package/dist/adapters/pg/postgresjs.d.ts +0 -4
- package/dist/adapters/pg/session.d.ts +94 -0
- package/dist/adapters/pg/watch.d.ts +18 -0
- package/dist/contracts/catalog/enum.d.ts +31 -4
- package/dist/contracts/catalog/extension.d.ts +61 -0
- package/dist/contracts/catalog/object.d.ts +1 -0
- package/dist/contracts/catalog/privilege.d.ts +64 -0
- package/dist/contracts/catalog/routine.d.ts +56 -0
- package/dist/contracts/catalog/types.d.ts +179 -18
- package/dist/contracts/catalog/view.d.ts +73 -0
- package/dist/contracts/connection.d.ts +13 -0
- package/dist/contracts/driver.d.ts +18 -5
- package/dist/contracts/error.d.ts +17 -1
- package/dist/contracts/generator.d.ts +63 -0
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +1 -1
- package/dist/contracts/internal.js +11 -9
- package/dist/contracts/location.d.ts +24 -0
- package/dist/contracts/rows.d.ts +15 -0
- package/dist/dialects/pg/archive-bind.d.ts +22 -0
- package/dist/dialects/pg/column.d.ts +129 -10
- package/dist/dialects/pg/compile.d.ts +1 -0
- package/dist/dialects/pg/custom.d.ts +6 -0
- package/dist/dialects/pg/ddl.d.ts +65 -1
- package/dist/dialects/pg/enum.d.ts +10 -8
- package/dist/dialects/pg/ext/citext.d.ts +14 -0
- package/dist/dialects/pg/ext/citext.js +11 -0
- package/dist/dialects/pg/ext/index.d.ts +52 -0
- package/dist/dialects/pg/ext/index.js +6 -0
- package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
- package/dist/dialects/pg/ext/pg-trgm.js +42 -0
- package/dist/dialects/pg/filter-parse.d.ts +19 -0
- package/dist/dialects/pg/filters.d.ts +19 -0
- package/dist/dialects/pg/fn/index.d.ts +107 -0
- package/dist/dialects/pg/fn/index.js +175 -0
- package/dist/dialects/pg/fn/touch.d.ts +14 -0
- package/dist/dialects/pg/index.d.ts +11 -2
- package/dist/dialects/pg/index.js +243 -1062
- package/dist/dialects/pg/introspect.d.ts +10 -1
- package/dist/dialects/pg/keys.d.ts +19 -3
- package/dist/dialects/pg/model.d.ts +223 -2
- package/dist/dialects/pg/operator-fit.d.ts +86 -0
- package/dist/dialects/pg/operators.d.ts +46 -1
- package/dist/dialects/pg/ops/arr-append.d.ts +9 -0
- package/dist/dialects/pg/ops/arr-ns.d.ts +7 -0
- package/dist/dialects/pg/ops/arr-remove.d.ts +9 -0
- package/dist/dialects/pg/ops/containedBy.d.ts +9 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -4
- package/dist/dialects/pg/ops/hasAnyKey.d.ts +8 -0
- package/dist/dialects/pg/ops/hasKey.d.ts +8 -0
- package/dist/dialects/pg/ops/json-ns.d.ts +6 -0
- package/dist/dialects/pg/ops/json-set.d.ts +12 -0
- package/dist/dialects/pg/ops/matches.d.ts +16 -0
- package/dist/dialects/pg/ops/overlaps.d.ts +9 -0
- package/dist/dialects/pg/ops/path.d.ts +13 -0
- package/dist/dialects/pg/preset.d.ts +76 -0
- package/dist/dialects/pg/relations.d.ts +59 -2
- package/dist/dialects/pg/role/check.d.ts +45 -0
- package/dist/dialects/pg/role/index.d.ts +50 -0
- package/dist/dialects/pg/role/sql.d.ts +44 -0
- package/dist/dialects/pg/schema.d.ts +109 -5
- package/dist/dialects/pg/table.d.ts +137 -11
- package/dist/dialects/pg/temporal.d.ts +9 -7
- package/dist/dialects/pg/tenancy.d.ts +103 -0
- package/dist/dialects/pg/through.d.ts +21 -0
- package/dist/dialects/pg/trait.d.ts +141 -0
- package/dist/dialects/pg/view/client.d.ts +30 -0
- package/dist/dialects/pg/view/depend.d.ts +35 -0
- package/dist/dialects/pg/view/index.d.ts +114 -0
- package/dist/dialects/pg/view/index.js +289 -0
- package/dist/dialects/pg/view/scratch.d.ts +21 -0
- package/dist/dialects/pg/where.d.ts +37 -0
- package/dist/runtime/aggregate.d.ts +25 -0
- package/dist/runtime/archive-handle.d.ts +18 -0
- package/dist/runtime/archive-rules.d.ts +12 -0
- package/dist/runtime/archive.d.ts +73 -0
- package/dist/runtime/batch.d.ts +20 -0
- package/dist/runtime/client.d.ts +114 -5
- package/dist/runtime/conflict.d.ts +2 -1
- package/dist/runtime/exposure.d.ts +27 -0
- package/dist/runtime/hookm.d.ts +39 -0
- package/dist/runtime/ids/index.d.ts +11 -0
- package/dist/runtime/ids/index.js +193 -0
- package/dist/runtime/ids/okid-extended.d.ts +19 -0
- package/dist/runtime/ids/okid-generator.d.ts +21 -0
- package/dist/runtime/ids/okid-shared.d.ts +89 -0
- package/dist/runtime/ids/okid.d.ts +24 -0
- package/dist/runtime/ids/uuid.d.ts +21 -0
- package/dist/runtime/lock.d.ts +22 -0
- package/dist/runtime/operator-sql.d.ts +8 -0
- package/dist/runtime/page.d.ts +25 -0
- package/dist/runtime/pg/bun.d.ts +30 -0
- package/dist/runtime/pg/bun.js +52 -0
- package/dist/runtime/pg/pg.d.ts +29 -0
- package/dist/runtime/pg/pg.js +52 -0
- package/dist/runtime/pg/pglite.js +16 -17
- package/dist/runtime/pg/postgresjs.js +14 -24
- package/dist/runtime/plan.d.ts +146 -7
- package/dist/runtime/preset-stack.d.ts +17 -0
- package/dist/runtime/presets.d.ts +48 -0
- package/dist/runtime/read-stream.d.ts +26 -0
- package/dist/runtime/safety/index.d.ts +159 -0
- package/dist/runtime/safety/index.js +294 -0
- package/dist/runtime/safety-hook.d.ts +42 -0
- package/dist/runtime/server-check.d.ts +34 -0
- package/dist/runtime/tenancy/index.d.ts +37 -0
- package/dist/runtime/tenancy/index.js +368 -0
- package/dist/runtime/trait-read.d.ts +30 -0
- package/dist/runtime/traits/index.d.ts +133 -0
- package/dist/runtime/traits/index.js +646 -0
- package/dist/runtime/transaction.d.ts +19 -0
- package/dist/runtime/tx.d.ts +22 -7
- package/dist/runtime/types.d.ts +376 -27
- package/dist/runtime/validate/bind.d.ts +11 -0
- package/dist/runtime/validate/closed.d.ts +16 -0
- package/dist/runtime/validate/engine.d.ts +41 -0
- package/dist/runtime/validate/hook.d.ts +17 -0
- package/dist/runtime/validate/index.d.ts +21 -0
- package/dist/runtime/validate/index.js +175 -0
- package/dist/runtime/validate/load.d.ts +13 -0
- package/dist/runtime/validate/places.d.ts +41 -0
- package/dist/runtime/validate/rules.d.ts +108 -0
- package/dist/runtime/validate/surface.d.ts +102 -0
- package/dist/runtime/write.d.ts +30 -5
- package/dist/shared/01yr20s5.js +149 -0
- package/dist/shared/0jc3ffzf.js +154 -0
- package/dist/shared/0v1g424p.js +26 -0
- package/dist/shared/1g0drakv.js +225 -0
- package/dist/shared/{kprcwaha.js → 1tfdfvhh.js} +5 -3
- package/dist/shared/{05w44d8g.js → 2ssqrv66.js} +767 -715
- package/dist/shared/3ekj9x92.js +210 -0
- package/dist/shared/49ypnfwt.js +1122 -0
- package/dist/shared/4e4c6vq2.js +62 -0
- package/dist/shared/4m9fn52z.js +70 -0
- package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
- package/dist/shared/5nmdenb6.js +1229 -0
- package/dist/shared/672t5vym.js +12 -0
- package/dist/shared/6bazvqwm.js +86 -0
- package/dist/shared/6w5j844a.js +201 -0
- package/dist/shared/{fgqgsb5z.js → 75xkjv0t.js} +2 -2
- package/dist/shared/7fvtrkwr.js +84 -0
- package/dist/shared/7m88x3e9.js +45 -0
- package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
- package/dist/shared/83eaefwr.js +10 -0
- package/dist/shared/94ez8kzh.js +19 -0
- package/dist/shared/96ps4g1z.js +32 -0
- package/dist/shared/{xqbhg6cn.js → 999ade2q.js} +95 -10
- package/dist/shared/9m80mkac.js +158 -0
- package/dist/shared/9x25fxhc.js +150 -0
- package/dist/shared/a5sxz52y.js +13 -0
- package/dist/shared/axhk06q1.js +156 -0
- package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
- package/dist/shared/bqha5cg6.js +229 -0
- package/dist/shared/bryqk9k9.js +31 -0
- package/dist/shared/c8aghh05.js +442 -0
- package/dist/shared/c9z5g0fm.js +309 -0
- package/dist/shared/{m3ypagh5.js → dbjej1tw.js} +124 -15
- package/dist/shared/dyj86cmj.js +69 -0
- package/dist/shared/e6wg00wd.js +164 -0
- package/dist/shared/{hadrfb9h.js → edwqqryd.js} +17 -14
- package/dist/shared/{qk3hxfja.js → fptpmvxp.js} +5 -5
- package/dist/shared/fs0ex00p.js +76 -0
- package/dist/shared/{jjb7yht9.js → g4f5kcx9.js} +3 -3
- package/dist/shared/gjthds9j.js +48 -0
- package/dist/shared/hcmdtwgh.js +102 -0
- package/dist/shared/{g5fhqmwe.js → jkc6ws1p.js} +6 -56
- package/dist/shared/{yd1kzwn2.js → jns2wx4t.js} +55 -12
- package/dist/shared/k34e0xf2.js +450 -0
- package/dist/shared/k3ted12y.js +33 -0
- package/dist/shared/k7dwkhvq.js +31 -0
- package/dist/shared/{8b04d28c.js → kgnc8grt.js} +2 -2
- package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
- package/dist/shared/m78s7898.js +376 -0
- package/dist/shared/m9tv7xn7.js +404 -0
- package/dist/shared/meck53jv.js +99 -0
- package/dist/shared/mt5wswjz.js +90 -0
- package/dist/shared/n0dgs0pb.js +75 -0
- package/dist/shared/n442h54c.js +14 -0
- package/dist/shared/n4jqhpqz.js +27 -0
- package/dist/shared/n7mcc1gk.js +132 -0
- package/dist/shared/ne02ng5c.js +68 -0
- package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
- package/dist/shared/nsva2a6b.js +42 -0
- package/dist/shared/p24x2334.js +195 -0
- package/dist/shared/qbxzvwwc.js +88 -0
- package/dist/shared/{w8samvk1.js → qybh48nd.js} +1 -1
- package/dist/shared/r6nwkxnt.js +86 -0
- package/dist/shared/{xy79j5hq.js → rrstp3kb.js} +25 -36
- package/dist/shared/rwmrejjz.js +26 -0
- package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
- package/dist/shared/{523ft3e8.js → scwxrpx2.js} +7 -5
- package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
- package/dist/shared/{y9m15dfv.js → t616ynfn.js} +544 -32
- package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
- package/dist/shared/th14ygv2.js +69 -0
- package/dist/shared/tmbdywx0.js +178 -0
- package/dist/shared/ty3v3hfk.js +64 -0
- package/dist/shared/wekze34d.js +246 -0
- package/dist/shared/x6wysh83.js +1132 -0
- package/dist/shared/{rgs0st28.js → xrfnq5k8.js} +237 -434
- package/dist/shared/{x5x59srr.js → xva8v7qk.js} +416 -83
- package/dist/shared/{dkn3y60a.js → xw1d69vd.js} +76 -112
- package/dist/shared/y005b761.js +112 -0
- package/dist/shared/ydaz1sv3.js +55 -0
- package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
- package/dist/tooling/cli.js +40 -12
- package/dist/tooling/migrate/apply.d.ts +16 -0
- package/dist/tooling/migrate/commands.d.ts +12 -1
- package/dist/tooling/migrate/config.d.ts +8 -0
- package/dist/tooling/migrate/doctor.d.ts +25 -0
- package/dist/tooling/migrate/drift.d.ts +19 -0
- package/dist/tooling/migrate/engine.d.ts +36 -0
- package/dist/tooling/migrate/ext.d.ts +17 -0
- package/dist/tooling/migrate/extensions.d.ts +51 -0
- package/dist/tooling/migrate/managed.d.ts +17 -0
- package/dist/tooling/migrate/plan.d.ts +14 -1
- package/dist/tooling/migrate/project.d.ts +25 -1
- package/dist/tooling/migrate/type-name.d.ts +19 -0
- package/package.json +61 -4
- package/dist/shared/gk7cs7sp.js +0 -566
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safetyInstalled,
|
|
3
|
+
runSafety
|
|
4
|
+
} from "./a5sxz52y.js";
|
|
5
|
+
import {
|
|
6
|
+
isOperator,
|
|
7
|
+
operatorValue
|
|
8
|
+
} from "./cn0n68ft.js";
|
|
9
|
+
import {
|
|
10
|
+
OkmError2
|
|
11
|
+
} from "./52szzakm.js";
|
|
12
|
+
|
|
13
|
+
// src/runtime/exposure.ts
|
|
14
|
+
var REDACTED = "[redacted]";
|
|
15
|
+
var namesOf = new WeakMap;
|
|
16
|
+
function redactView(schema, view, call) {
|
|
17
|
+
const names = concealedNames(schema);
|
|
18
|
+
const secrets = new Set;
|
|
19
|
+
harvest(schema, call.where, names, undefined, secrets);
|
|
20
|
+
harvest(schema, call.include, names, undefined, secrets);
|
|
21
|
+
const model = schema.model[call.table];
|
|
22
|
+
const rules = model === undefined ? view.rules : [...view.rules, ...exposureRules(model, call)];
|
|
23
|
+
if (safetyInstalled())
|
|
24
|
+
runSafety(rules, undefined);
|
|
25
|
+
return {
|
|
26
|
+
...view,
|
|
27
|
+
intent: {
|
|
28
|
+
...view.intent,
|
|
29
|
+
where: walk(view.intent.where, names),
|
|
30
|
+
include: walk(view.intent.include, names)
|
|
31
|
+
},
|
|
32
|
+
rules,
|
|
33
|
+
sql: {
|
|
34
|
+
...view.sql,
|
|
35
|
+
params: view.sql.params.map((value) => value !== null && secrets.has(value) ? REDACTED : value)
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function scrubCall(error, schema, call) {
|
|
40
|
+
const names = concealedNames(schema);
|
|
41
|
+
const secrets = new Set;
|
|
42
|
+
harvest(schema, call.where, names, undefined, secrets);
|
|
43
|
+
harvest(schema, call.include, names, undefined, secrets);
|
|
44
|
+
let message = error.message;
|
|
45
|
+
for (const secret of secrets) {
|
|
46
|
+
if (secret.length < 4 || !message.includes(secret))
|
|
47
|
+
continue;
|
|
48
|
+
message = message.replaceAll(secret, REDACTED);
|
|
49
|
+
}
|
|
50
|
+
if (message === error.message)
|
|
51
|
+
return error;
|
|
52
|
+
return new OkmError2(error.code, message, {
|
|
53
|
+
kind: error.kind,
|
|
54
|
+
...error.table !== undefined ? { table: error.table } : {},
|
|
55
|
+
...error.columns.length > 0 ? { columns: error.columns } : {},
|
|
56
|
+
fix: error.fix
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function concealedNames(schema) {
|
|
60
|
+
const cached = namesOf.get(schema);
|
|
61
|
+
if (cached !== undefined)
|
|
62
|
+
return cached;
|
|
63
|
+
const names = new Set;
|
|
64
|
+
for (const model of Object.values(schema.model)) {
|
|
65
|
+
if (model.conceal !== true)
|
|
66
|
+
continue;
|
|
67
|
+
for (const column of model.columns) {
|
|
68
|
+
if (column.hidden || column.sensitive)
|
|
69
|
+
names.add(column.field);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
namesOf.set(schema, names);
|
|
73
|
+
return names;
|
|
74
|
+
}
|
|
75
|
+
function exposureRules(model, call) {
|
|
76
|
+
const named = namedSelect(call.select);
|
|
77
|
+
const source = model.source;
|
|
78
|
+
const rules = [];
|
|
79
|
+
for (const column of model.columns) {
|
|
80
|
+
if (column.hidden && (named === undefined || !named.has(column.field))) {
|
|
81
|
+
rules.push({
|
|
82
|
+
rule: "hidden",
|
|
83
|
+
contribution: `hidden ${model.name}.${column.field} excluded`,
|
|
84
|
+
provenance: "catalog",
|
|
85
|
+
...source !== undefined ? { source } : {}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (column.sensitive) {
|
|
89
|
+
rules.push({
|
|
90
|
+
rule: "sensitive",
|
|
91
|
+
contribution: `sensitive ${model.name}.${column.field} redacted`,
|
|
92
|
+
provenance: "catalog",
|
|
93
|
+
...source !== undefined ? { source } : {}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return rules;
|
|
98
|
+
}
|
|
99
|
+
function namedSelect(select) {
|
|
100
|
+
if (!Array.isArray(select))
|
|
101
|
+
return;
|
|
102
|
+
const names = new Set;
|
|
103
|
+
for (const name of select) {
|
|
104
|
+
if (typeof name === "string")
|
|
105
|
+
names.add(name);
|
|
106
|
+
}
|
|
107
|
+
return names;
|
|
108
|
+
}
|
|
109
|
+
function harvest(schema, value, names, key, into) {
|
|
110
|
+
if (Array.isArray(value)) {
|
|
111
|
+
for (const item of value)
|
|
112
|
+
harvest(schema, item, names, key, into);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (isOperator(value)) {
|
|
116
|
+
harvest(schema, operatorValue(value), names, key, into);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (typeof value === "object" && value !== null) {
|
|
120
|
+
const record = value;
|
|
121
|
+
for (const child of Object.keys(record))
|
|
122
|
+
harvest(schema, record[child], names, child, into);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (key === undefined || !names.has(key))
|
|
126
|
+
return;
|
|
127
|
+
const encode = encodeOf(schema, key);
|
|
128
|
+
if (encode === undefined)
|
|
129
|
+
return;
|
|
130
|
+
try {
|
|
131
|
+
into.add(encode(value));
|
|
132
|
+
} catch {}
|
|
133
|
+
}
|
|
134
|
+
function encodeOf(schema, field) {
|
|
135
|
+
for (const model of Object.values(schema.model)) {
|
|
136
|
+
for (const column of model.columns) {
|
|
137
|
+
if (column.field === field && (column.hidden || column.sensitive)) {
|
|
138
|
+
return column.encode;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
function walk(value, names, key) {
|
|
145
|
+
if (Array.isArray(value))
|
|
146
|
+
return value.map((item) => walk(item, names, key));
|
|
147
|
+
if (typeof value === "object" && value !== null) {
|
|
148
|
+
const record = value;
|
|
149
|
+
if (typeof record.op === "string" && "value" in record) {
|
|
150
|
+
return { op: record.op, value: walk(record.value, names, key) };
|
|
151
|
+
}
|
|
152
|
+
const out = {};
|
|
153
|
+
for (const child of Object.keys(record))
|
|
154
|
+
out[child] = walk(record[child], names, child);
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
if (key !== undefined && names.has(key))
|
|
158
|
+
return REDACTED;
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
export {
|
|
162
|
+
redactView,
|
|
163
|
+
scrubCall
|
|
164
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
emitRelationFrom,
|
|
2
3
|
decodeResult,
|
|
3
4
|
emitJoin,
|
|
4
5
|
emitWhere,
|
|
@@ -14,13 +15,15 @@ import {
|
|
|
14
15
|
quote,
|
|
15
16
|
list,
|
|
16
17
|
isRecord,
|
|
18
|
+
registerFailFix,
|
|
17
19
|
fail
|
|
18
|
-
} from "./
|
|
20
|
+
} from "./xrfnq5k8.js";
|
|
19
21
|
import {
|
|
20
22
|
throwNamed2
|
|
21
|
-
} from "./
|
|
23
|
+
} from "./52szzakm.js";
|
|
22
24
|
|
|
23
25
|
// src/runtime/include.ts
|
|
26
|
+
registerFailFix("OKM1105", "Pass limit on the include, or call .all(reason).");
|
|
24
27
|
var INCLUDE_OPTIONS = ["all", "include", "limit", "orderBy", "select", "where"];
|
|
25
28
|
function emitIncludeSelect(include, alias, sink, outputs, column) {
|
|
26
29
|
const selected = include.columns;
|
|
@@ -130,11 +133,7 @@ function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
|
130
133
|
emitNestedAggregate(schema, nested, sink, childAlias, depth + 1);
|
|
131
134
|
}
|
|
132
135
|
sink.text(") as item from ");
|
|
133
|
-
|
|
134
|
-
sink.text(" ");
|
|
135
|
-
sink.text(childAlias);
|
|
136
|
-
sink.text(" where ");
|
|
137
|
-
emitJoin(sink, parentAlias, childAlias, include.relation);
|
|
136
|
+
emitRelationFrom(schema, include.relation, child, sink, parentAlias, childAlias, depth + 1);
|
|
138
137
|
emitWhere(schema, child, include.where, sink, childAlias, depth + 1, true);
|
|
139
138
|
emitOrder(child, include.orderBy, sink, childAlias);
|
|
140
139
|
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
@@ -225,11 +224,7 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
|
225
224
|
if (include.columns.length === 0)
|
|
226
225
|
sink.text("1");
|
|
227
226
|
sink.text(") as item from ");
|
|
228
|
-
|
|
229
|
-
sink.text(" ");
|
|
230
|
-
sink.text(childAlias);
|
|
231
|
-
sink.text(" where ");
|
|
232
|
-
emitJoin(sink, alias, childAlias, include.relation);
|
|
227
|
+
emitRelationFrom(schema, include.relation, child, sink, alias, childAlias, depth);
|
|
233
228
|
emitWhere(schema, child, include.where, sink, childAlias, depth, true);
|
|
234
229
|
emitOrder(child, include.orderBy, sink, childAlias);
|
|
235
230
|
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
@@ -242,6 +237,14 @@ function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
|
242
237
|
}
|
|
243
238
|
sink.text(") limited) ordered)");
|
|
244
239
|
}
|
|
240
|
+
function omitHidden(columns) {
|
|
241
|
+
for (const column of columns) {
|
|
242
|
+
if (!column.hidden)
|
|
243
|
+
continue;
|
|
244
|
+
return columns.filter((item) => !item.hidden);
|
|
245
|
+
}
|
|
246
|
+
return columns;
|
|
247
|
+
}
|
|
245
248
|
function readIncludes(schema, table, include, all) {
|
|
246
249
|
if (include === undefined)
|
|
247
250
|
return [];
|
|
@@ -264,7 +267,7 @@ function parseInclude(schema, name, relation, value, all) {
|
|
|
264
267
|
fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
265
268
|
}
|
|
266
269
|
const child = childIndex(schema, relation);
|
|
267
|
-
const columns = selectedColumns(child, undefined);
|
|
270
|
+
const columns = omitHidden(selectedColumns(child, undefined));
|
|
268
271
|
return {
|
|
269
272
|
name,
|
|
270
273
|
relation,
|
|
@@ -288,7 +291,7 @@ function parseInclude(schema, name, relation, value, all) {
|
|
|
288
291
|
fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
289
292
|
}
|
|
290
293
|
const child = childIndex(schema, relation);
|
|
291
|
-
const columns = selectedColumns(child, value.select);
|
|
294
|
+
const columns = omitHidden(selectedColumns(child, value.select));
|
|
292
295
|
const nestedValue = value.include;
|
|
293
296
|
const nested = nestedValue === undefined ? [] : readIncludes(schema, child, nestedValue, reason);
|
|
294
297
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OkmError2
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./52szzakm.js";
|
|
4
4
|
|
|
5
5
|
// src/runtime/drift.ts
|
|
6
6
|
async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
@@ -8,16 +8,16 @@ async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
|
8
8
|
if (code.hash === recordedHash)
|
|
9
9
|
return;
|
|
10
10
|
if (code.artifact !== undefined) {
|
|
11
|
-
const { loadTrustedCatalog } = await import("./
|
|
11
|
+
const { loadTrustedCatalog } = await import("./qybh48nd.js");
|
|
12
12
|
loadTrustedCatalog(code.artifact.text, code.artifact.hash);
|
|
13
13
|
} else {
|
|
14
14
|
const artifact = await readCatalogFile(source.catalogDir);
|
|
15
15
|
if (artifact !== undefined) {
|
|
16
|
-
const { loadTrustedCatalog } = await import("./
|
|
16
|
+
const { loadTrustedCatalog } = await import("./qybh48nd.js");
|
|
17
17
|
loadTrustedCatalog(artifact.text, artifact.hash);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
const { assertDrift } = await import("./
|
|
20
|
+
const { assertDrift } = await import("./zwmqxb0g.js");
|
|
21
21
|
await assertDrift(pool, code.hash, recordedHash, options);
|
|
22
22
|
}
|
|
23
23
|
async function codeHash(schema, source) {
|
|
@@ -26,7 +26,7 @@ async function codeHash(schema, source) {
|
|
|
26
26
|
const listed = await readHashFile(source.catalogDir);
|
|
27
27
|
if (listed !== undefined)
|
|
28
28
|
return { hash: listed };
|
|
29
|
-
const { catalogHash } = await import("./
|
|
29
|
+
const { catalogHash } = await import("./qybh48nd.js");
|
|
30
30
|
return { hash: catalogHash(schemaCatalog(schema)) };
|
|
31
31
|
}
|
|
32
32
|
function schemaCatalog(schema) {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
send2,
|
|
3
|
+
reserve,
|
|
4
|
+
park
|
|
5
|
+
} from "./01yr20s5.js";
|
|
6
|
+
import {
|
|
7
|
+
isConnectionLost
|
|
8
|
+
} from "./tbszx8mz.js";
|
|
9
|
+
import {
|
|
10
|
+
WireSession
|
|
11
|
+
} from "./0jc3ffzf.js";
|
|
12
|
+
import {
|
|
13
|
+
rejectClosed,
|
|
14
|
+
runCall
|
|
15
|
+
} from "./rrstp3kb.js";
|
|
16
|
+
|
|
17
|
+
// src/adapters/pg/bunsql-extra.ts
|
|
18
|
+
async function checkout(held) {
|
|
19
|
+
const { counters, isClosed } = held;
|
|
20
|
+
if (isClosed())
|
|
21
|
+
return rejectClosed();
|
|
22
|
+
const reserved = held.parked.pop() ?? await reserve(held.sql, held.acquireMs, counters);
|
|
23
|
+
counters.reserved += 1;
|
|
24
|
+
const session = new WireSession((text, params) => send2(reserved, text, params), held.notices, isClosed, false, () => {
|
|
25
|
+
counters.reservedBusy += 1;
|
|
26
|
+
}, () => {
|
|
27
|
+
counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
|
|
28
|
+
});
|
|
29
|
+
let lost = false;
|
|
30
|
+
const guard = (run) => lost ? rejectClosed("The connection was lost.") : run().catch((error) => {
|
|
31
|
+
if (isConnectionLost(error))
|
|
32
|
+
lost = true;
|
|
33
|
+
throw error;
|
|
34
|
+
});
|
|
35
|
+
let released = false;
|
|
36
|
+
return {
|
|
37
|
+
execute: (text, params, options) => guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch))),
|
|
38
|
+
batch: (statements, options) => guard(() => runCall(isClosed(), options, async (watch) => {
|
|
39
|
+
const { runAtomicBatch } = await import("./b066g80h.js");
|
|
40
|
+
return runAtomicBatch(session, statements, watch);
|
|
41
|
+
})),
|
|
42
|
+
async release() {
|
|
43
|
+
if (released)
|
|
44
|
+
return;
|
|
45
|
+
released = true;
|
|
46
|
+
try {
|
|
47
|
+
if (!lost)
|
|
48
|
+
await reset(session, reserved);
|
|
49
|
+
} finally {
|
|
50
|
+
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
51
|
+
if (!lost)
|
|
52
|
+
await park(held.parked, reserved);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function reset(session, sql) {
|
|
58
|
+
const run = (text) => sql.unsafe(text);
|
|
59
|
+
if (session.depth() > 0)
|
|
60
|
+
await run("ROLLBACK").catch(() => {
|
|
61
|
+
return;
|
|
62
|
+
});
|
|
63
|
+
try {
|
|
64
|
+
await run("RESET ALL");
|
|
65
|
+
await run("SELECT pg_advisory_unlock_all()");
|
|
66
|
+
} catch {
|
|
67
|
+
await run("ROLLBACK").catch(() => {
|
|
68
|
+
return;
|
|
69
|
+
});
|
|
70
|
+
await run("RESET ALL");
|
|
71
|
+
await run("SELECT pg_advisory_unlock_all()");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
checkout
|
|
76
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
catalogHash2,
|
|
3
3
|
parseCatalog2
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./t616ynfn.js";
|
|
5
5
|
import {
|
|
6
6
|
parsePlan
|
|
7
|
-
} from "./
|
|
7
|
+
} from "./2ssqrv66.js";
|
|
8
8
|
import {
|
|
9
9
|
OkmError2
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./52szzakm.js";
|
|
11
11
|
|
|
12
12
|
// src/tooling/migrate/files.ts
|
|
13
13
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
required
|
|
3
|
+
} from "./c9z5g0fm.js";
|
|
4
|
+
import {
|
|
5
|
+
rejected
|
|
6
|
+
} from "./tmbdywx0.js";
|
|
7
|
+
|
|
8
|
+
// src/dialects/pg/json.ts
|
|
9
|
+
function jsonReplacer2(_key, value) {
|
|
10
|
+
if (typeof value === "bigint") {
|
|
11
|
+
return value.toString();
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function json2() {
|
|
16
|
+
return required({
|
|
17
|
+
baseType: "json",
|
|
18
|
+
encode: encodeJson,
|
|
19
|
+
decode: decodeJson,
|
|
20
|
+
accepts: ["Array", "Object"],
|
|
21
|
+
sqlForm: "json"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function jsonb2() {
|
|
25
|
+
return required({
|
|
26
|
+
baseType: "jsonb",
|
|
27
|
+
encode: encodeJson,
|
|
28
|
+
decode: decodeJson,
|
|
29
|
+
accepts: ["Array", "Object"],
|
|
30
|
+
sqlForm: "jsonb"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function encodeJson(value) {
|
|
34
|
+
const text = JSON.stringify(value, jsonReplacer2);
|
|
35
|
+
if (text === undefined) {
|
|
36
|
+
rejected("json value must be JSON data. undefined and functions are not accepted. bigint is written as a decimal string.");
|
|
37
|
+
}
|
|
38
|
+
return text;
|
|
39
|
+
}
|
|
40
|
+
function decodeJson(wire) {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(wire);
|
|
43
|
+
} catch {
|
|
44
|
+
rejected("json text must be JSON, for example null, a string, a number, true, {}, or [].");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { jsonReplacer2, json2, jsonb2, encodeJson };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError2
|
|
3
|
+
} from "./52szzakm.js";
|
|
4
|
+
|
|
5
|
+
// src/dialects/pg/role/check.ts
|
|
6
|
+
async function assertRoleHealth(runner, roles, objects) {
|
|
7
|
+
const managed = new Set((roles.managed ?? []).map((role) => role.name));
|
|
8
|
+
const named = [roles.migration, roles.app];
|
|
9
|
+
for (const name of named) {
|
|
10
|
+
if (managed.has(name))
|
|
11
|
+
continue;
|
|
12
|
+
if (!await roleExists(runner, name)) {
|
|
13
|
+
throw new OkmError2("not_found", `Role ${name} is named in roles and does not exist.`, {
|
|
14
|
+
kind: "not_found",
|
|
15
|
+
fix: { summary: "Create the role, or list it in roles.managed so the plan creates it." }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (managed.size > 0)
|
|
20
|
+
await assertCreateRole(runner, await currentUser(runner));
|
|
21
|
+
for (const object of objects) {
|
|
22
|
+
if (object.kind !== "grant" || object.identity.role !== roles.app)
|
|
23
|
+
continue;
|
|
24
|
+
await assertGrant(runner, object);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function assertCreateRole(runner, role) {
|
|
28
|
+
const result = await runner.execute("select rolcreaterole from pg_roles where rolname = $1", [
|
|
29
|
+
role
|
|
30
|
+
]);
|
|
31
|
+
if (!truthy(result.rows[0]?.[0])) {
|
|
32
|
+
throw new OkmError2("forbidden", `Role ${role} lacks CREATEROLE. Nothing was changed.`, {
|
|
33
|
+
kind: "forbidden",
|
|
34
|
+
fix: { summary: "Grant CREATEROLE to the role that applies migrations." }
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function currentUser(runner) {
|
|
39
|
+
const result = await runner.execute("select current_user");
|
|
40
|
+
const name = result.rows[0]?.[0];
|
|
41
|
+
return typeof name === "string" ? name : "";
|
|
42
|
+
}
|
|
43
|
+
async function roleExists(runner, name) {
|
|
44
|
+
const result = await runner.execute("select 1 from pg_roles where rolname = $1", [name]);
|
|
45
|
+
return result.rows.length > 0;
|
|
46
|
+
}
|
|
47
|
+
async function assertGrant(runner, object) {
|
|
48
|
+
const target = object.identity.object;
|
|
49
|
+
const schema = target.namespace.form === "static" ? target.namespace.name : "public";
|
|
50
|
+
const privilege = object.identity.privilege;
|
|
51
|
+
if (target.kind === "function") {
|
|
52
|
+
const open = target.name.lastIndexOf("(");
|
|
53
|
+
const fn = open < 0 ? target.name : target.name.slice(0, open);
|
|
54
|
+
const args = open < 0 ? "" : target.name.slice(open + 1, -1);
|
|
55
|
+
if (!await functionExists(runner, schema, fn, args))
|
|
56
|
+
return;
|
|
57
|
+
const allowed = await runner.execute("select has_function_privilege($1, format('%I.%I(%s)', $2::text, $3::text, $4::text), $5)", [object.identity.role, schema, fn, args, privilege]);
|
|
58
|
+
if (!truthy(allowed.rows[0]?.[0]))
|
|
59
|
+
missing(object, `${schema}.${fn}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (target.kind === "namespace")
|
|
63
|
+
return;
|
|
64
|
+
const relkinds = target.kind === "sequence" ? "'S'" : target.kind === "view" ? "'v'" : target.kind === "materializedView" ? "'m'" : "'r', 'p'";
|
|
65
|
+
if (!await relationExists(runner, schema, target.name, relkinds))
|
|
66
|
+
return;
|
|
67
|
+
const probe = target.kind === "sequence" ? "select has_sequence_privilege($1, format('%I.%I', $2::text, $3::text), $4)" : "select has_table_privilege($1, format('%I.%I', $2::text, $3::text), $4)";
|
|
68
|
+
const allowed = await runner.execute(probe, [
|
|
69
|
+
object.identity.role,
|
|
70
|
+
schema,
|
|
71
|
+
target.name,
|
|
72
|
+
privilege
|
|
73
|
+
]);
|
|
74
|
+
if (!truthy(allowed.rows[0]?.[0]))
|
|
75
|
+
missing(object, `${schema}.${target.name}`);
|
|
76
|
+
}
|
|
77
|
+
function missing(object, name) {
|
|
78
|
+
throw new OkmError2("OKM1825", `Role ${object.identity.role} lacks ${object.identity.privilege} on ${name}.`, {
|
|
79
|
+
kind: "forbidden",
|
|
80
|
+
fix: {
|
|
81
|
+
summary: "Grant the privilege, or change the role. okm doctor reports the object and the privilege."
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async function relationExists(runner, schema, name, relkinds) {
|
|
86
|
+
const result = await runner.execute(`select 1 from pg_class c
|
|
87
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
88
|
+
where n.nspname = $1 and c.relname = $2 and c.relkind in (${relkinds})`, [schema, name]);
|
|
89
|
+
return result.rows.length > 0;
|
|
90
|
+
}
|
|
91
|
+
async function functionExists(runner, schema, name, args) {
|
|
92
|
+
const result = await runner.execute(`select 1 from pg_proc p
|
|
93
|
+
join pg_namespace n on n.oid = p.pronamespace
|
|
94
|
+
where n.nspname = $1 and p.proname = $2
|
|
95
|
+
and replace(pg_get_function_identity_arguments(p.oid), ' ', '') = $3`, [schema, name, args]);
|
|
96
|
+
return result.rows.length > 0;
|
|
97
|
+
}
|
|
98
|
+
function truthy(value) {
|
|
99
|
+
return value === true || value === "t" || value === "true";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { assertRoleHealth, assertCreateRole, currentUser, roleExists };
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CATALOG_VERSION2,
|
|
3
|
-
assertNamespace2,
|
|
4
2
|
identityKey2,
|
|
5
3
|
identityLabel2,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
assertProvenance
|
|
9
|
-
} from "./j5cn2963.js";
|
|
4
|
+
compareText
|
|
5
|
+
} from "./t4tbsy9h.js";
|
|
10
6
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./mkjmqjv4.js";
|
|
7
|
+
CATALOG_VERSION2
|
|
8
|
+
} from "./4e4c6vq2.js";
|
|
14
9
|
import {
|
|
15
10
|
catalogError2
|
|
16
|
-
} from "./
|
|
11
|
+
} from "./52szzakm.js";
|
|
17
12
|
|
|
18
13
|
// src/contracts/catalog/order.ts
|
|
19
14
|
function indexObjects(objects) {
|
|
@@ -140,49 +135,4 @@ function assertForeignKeys(objects, keys) {
|
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
137
|
|
|
143
|
-
|
|
144
|
-
function enumType(input) {
|
|
145
|
-
assertNamespace2(input.namespace);
|
|
146
|
-
assertIdentifier2(input.name, "type");
|
|
147
|
-
assertProvenance(input.provenance);
|
|
148
|
-
if (input.labels.length === 0) {
|
|
149
|
-
catalogError2("OKM1020", `Enum ${input.name} must list at least one label.`);
|
|
150
|
-
}
|
|
151
|
-
const labels = [];
|
|
152
|
-
const seen = new Set;
|
|
153
|
-
for (const label of input.labels) {
|
|
154
|
-
assertStoredText(label, "enum label");
|
|
155
|
-
if (label.length === 0) {
|
|
156
|
-
catalogError2("OKM1020", `Enum ${input.name} has an empty label.`);
|
|
157
|
-
}
|
|
158
|
-
if (seen.has(label)) {
|
|
159
|
-
catalogError2("OKM1020", `Enum ${input.name} repeats label ${label}.`);
|
|
160
|
-
}
|
|
161
|
-
seen.add(label);
|
|
162
|
-
labels.push(label);
|
|
163
|
-
}
|
|
164
|
-
const identity = {
|
|
165
|
-
kind: "type",
|
|
166
|
-
namespace: input.namespace,
|
|
167
|
-
name: input.name
|
|
168
|
-
};
|
|
169
|
-
return {
|
|
170
|
-
kind: "type",
|
|
171
|
-
identity,
|
|
172
|
-
owner: input.owner ?? "managed",
|
|
173
|
-
definition: { labels },
|
|
174
|
-
dependencies: normaliseEdges(input.dependencies ?? []),
|
|
175
|
-
provenance: input.provenance
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
function sameEnumLabels(left, right) {
|
|
179
|
-
if (left.length !== right.length)
|
|
180
|
-
return false;
|
|
181
|
-
for (let index = 0;index < left.length; index += 1) {
|
|
182
|
-
if (left[index] !== right[index])
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export { dependencyOrder, catalog, enumType, sameEnumLabels };
|
|
138
|
+
export { dependencyOrder, catalog };
|