okmodel 0.5.0 → 0.6.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 +36 -18
- package/dist/adapters/pg/no-inflight-timeout.d.ts +17 -0
- package/dist/adapters/pg/postgres-extra.d.ts +22 -0
- 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/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 +10 -3
- package/dist/dialects/pg/fn/index.js +10 -2
- package/dist/dialects/pg/index.d.ts +2 -1
- package/dist/dialects/pg/index.js +29 -17
- package/dist/dialects/pg/introspect.d.ts +7 -0
- package/dist/dialects/pg/model.d.ts +7 -2
- package/dist/dialects/pg/ops/or.d.ts +1 -1
- package/dist/dialects/pg/owner.d.ts +42 -0
- package/dist/dialects/pg/path-endpoint.d.ts +20 -0
- 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 +2 -0
- package/dist/dialects/pg/table.d.ts +25 -3
- package/dist/dialects/pg/temporal.d.ts +5 -76
- 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/batch.d.ts +1 -1
- package/dist/runtime/client.d.ts +6 -1
- package/dist/runtime/conflict.d.ts +2 -1
- package/dist/runtime/drift.d.ts +9 -0
- package/dist/runtime/inflight.d.ts +14 -0
- package/dist/runtime/pg/bun.js +6 -5
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.js +6 -5
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +22 -1
- package/dist/runtime/predicate.d.ts +19 -0
- package/dist/runtime/safety/index.js +1 -1
- 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 +1508 -37
- 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/traits/index.js +17 -11
- package/dist/runtime/types.d.ts +13 -1
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/write.d.ts +1 -1
- package/dist/shared/09p049xa.js +702 -0
- package/dist/shared/{ykv7wh5b.js → 1f0xa3cb.js} +5 -5
- package/dist/shared/1nw1f3vs.js +23 -0
- package/dist/shared/{6p5k20sm.js → 1z04fa85.js} +21 -11
- package/dist/shared/{p7pfx624.js → 2cg3wnxc.js} +314 -65
- package/dist/shared/{dyj86cmj.js → 2jd1sn0e.js} +2 -2
- package/dist/shared/{qgvt8nx1.js → 2z7wv5tj.js} +21 -5
- package/dist/shared/{kyxb62mc.js → 31vm914h.js} +9 -1
- package/dist/shared/{sf8m6tfy.js → 32cnm7kn.js} +8 -3
- package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
- package/dist/shared/{jdgqqx31.js → 3fqwmr09.js} +38 -14
- package/dist/shared/{922qbgnw.js → 3qnhc7w5.js} +16 -9
- package/dist/shared/{zvbjc949.js → 4az561fn.js} +1 -1
- package/dist/shared/{k3ted12y.js → 54tqkxja.js} +20 -2
- package/dist/shared/{k7cc9nzk.js → 5d8t84hg.js} +15 -3
- package/dist/shared/{fa9vt245.js → 5j36z8dn.js} +17 -6
- package/dist/shared/{1g0drakv.js → 5yv4k6a6.js} +1 -1
- package/dist/shared/8dqhth8c.js +12 -0
- package/dist/shared/8etn7d8w.js +62 -0
- package/dist/shared/{g516zdsb.js → 8x72s86k.js} +476 -30
- package/dist/shared/{nkc9sfqb.js → 929h19xp.js} +145 -7
- package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
- package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
- package/dist/shared/{b066g80h.js → ag4c7516.js} +2 -2
- package/dist/shared/b3awxn7h.js +45 -0
- package/dist/shared/b4v57v3x.js +9 -0
- package/dist/shared/bdk4sty6.js +58 -0
- package/dist/shared/{s6gqfn5j.js → c58secgj.js} +125 -8
- package/dist/shared/{rrstp3kb.js → cgbamx3e.js} +2 -2
- package/dist/shared/d5azex6s.js +6 -0
- package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
- package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
- package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
- package/dist/shared/{wxn4b7pp.js → f0f1n281.js} +59 -12
- package/dist/shared/{gdh9mrtp.js → g90m9b0g.js} +3 -2
- package/dist/shared/{tbszx8mz.js → gwn6v667.js} +2 -2
- package/dist/shared/{c8aghh05.js → h15jx9bc.js} +8 -2
- package/dist/shared/{3p4b1fg0.js → hazqqecq.js} +17 -93
- package/dist/shared/{4ef7mmqf.js → j3rkk835.js} +34 -11
- package/dist/shared/{bt9sfq0z.js → j60w0dvr.js} +56 -21
- package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
- package/dist/shared/k68eedmy.js +85 -0
- package/dist/shared/{szm0cksa.js → knmes2kh.js} +34 -6
- package/dist/shared/{ckjbyrt9.js → mb2ycs1p.js} +7 -9
- package/dist/shared/{tq9afp8d.js → n076ydsc.js} +1 -1
- package/dist/shared/{xhh1srw3.js → nx9hh281.js} +50 -32
- package/dist/shared/{kdkxh3kb.js → p248q79y.js} +58 -59
- package/dist/shared/{990a291j.js → p6bjzq9q.js} +14 -9
- package/dist/shared/{h4nqvjkp.js → pjr6xrm5.js} +2 -2
- package/dist/shared/pz6rj8ay.js +212 -0
- package/dist/shared/{5vdm4sgp.js → q3j1tq7a.js} +36 -23
- package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
- package/dist/shared/{dxjp14rk.js → r11n8grd.js} +2 -2
- package/dist/shared/r1fdd0f6.js +19 -0
- package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
- package/dist/shared/rhs3xe4k.js +7 -0
- package/dist/shared/{jsd07prz.js → rpycarcr.js} +6 -6
- package/dist/shared/{xsq7v6wp.js → sbdme3vy.js} +14 -2
- package/dist/shared/{xdpj5kkm.js → t3g0k88x.js} +775 -264
- package/dist/shared/{ayz64vzj.js → ttmg09vd.js} +708 -19
- package/dist/shared/{r6pj4fq2.js → venqrjna.js} +8 -4
- package/dist/shared/{fancm5pt.js → vjpnzwjz.js} +138 -15
- package/dist/shared/{9tgmr1gh.js → vmfkhszw.js} +44 -9
- package/dist/shared/{wqem4jed.js → wkme6tep.js} +11 -9
- package/dist/shared/{qy9rdq0g.js → wt5rzv1h.js} +15 -11
- package/dist/shared/wxr8cwns.js +6 -0
- package/dist/shared/{bzsjtd7c.js → wynzeggs.js} +19 -14
- package/dist/shared/x3jc53kg.js +220 -0
- package/dist/shared/{7p2wbz7f.js → x72jb7ad.js} +1 -1
- package/dist/shared/{fyqkk1m0.js → xq0mvhts.js} +10 -9
- package/dist/shared/xqve9598.js +53 -0
- package/dist/shared/{47xzb9fc.js → y2t3jktd.js} +2 -2
- package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
- package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
- package/dist/shared/{h8ne16fq.js → ys0xzyaj.js} +1 -1
- package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
- package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
- package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
- package/dist/shared/{fb00y8fp.js → zm0mafk4.js} +12 -6
- package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
- package/dist/tooling/cli.js +97 -24
- 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/commands.d.ts +1 -2
- package/dist/tooling/migrate/config.d.ts +3 -2
- package/dist/tooling/migrate/drift.d.ts +1 -1
- package/dist/tooling/migrate/estimate.d.ts +14 -1
- package/dist/tooling/migrate/files.d.ts +11 -1
- package/dist/tooling/migrate/index.js +17 -16
- package/dist/tooling/migrate/lint.d.ts +4 -4
- 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 +10 -3
- package/dist/tooling/migrate/policy.d.ts +11 -0
- 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 +39 -0
- package/dist/tooling/migrate/text.d.ts +42 -0
- package/dist/tooling/node-version.d.ts +21 -0
- package/dist/tooling/testing/factories.d.ts +10 -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 +15 -8
- package/package.json +10 -6
- package/dist/shared/0v1g424p.js +0 -26
- package/dist/shared/r73pt594.js +0 -426
- package/dist/shared/rasvvzgz.js +0 -21
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodeUuid,
|
|
3
|
+
decodeUuid
|
|
4
|
+
} from "./2jd1sn0e.js";
|
|
5
|
+
import {
|
|
6
|
+
encodeText,
|
|
7
|
+
decodeText
|
|
8
|
+
} from "./ed0b8k4s.js";
|
|
9
|
+
import {
|
|
10
|
+
snakeCase
|
|
11
|
+
} from "./rpycarcr.js";
|
|
12
|
+
import {
|
|
13
|
+
OkmError2
|
|
14
|
+
} from "./52szzakm.js";
|
|
15
|
+
|
|
16
|
+
// src/dialects/pg/view/client.ts
|
|
17
|
+
var globalViews = new WeakMap;
|
|
18
|
+
function viewGlobalReason(model) {
|
|
19
|
+
return globalViews.get(model);
|
|
20
|
+
}
|
|
21
|
+
function viewMentions(query, name) {
|
|
22
|
+
let pattern = '(^|[^A-Za-z0-9_])"?';
|
|
23
|
+
for (const char of name) {
|
|
24
|
+
if ("\\^$[]().*+?|{}".includes(char))
|
|
25
|
+
pattern += "\\";
|
|
26
|
+
pattern += char;
|
|
27
|
+
}
|
|
28
|
+
pattern += '"?(?![A-Za-z0-9_])';
|
|
29
|
+
return new RegExp(pattern).test(query);
|
|
30
|
+
}
|
|
31
|
+
function viewClient(name, columns, query, tenancy, refresh = "plain") {
|
|
32
|
+
const field = camelCase(name);
|
|
33
|
+
const marked = readGlobal(name, tenancy);
|
|
34
|
+
return {
|
|
35
|
+
field,
|
|
36
|
+
install(model, scope, tables, casing, scoped) {
|
|
37
|
+
if (Object.hasOwn(model, field)) {
|
|
38
|
+
throw new OkmError2("OKM1023", `View ${name} uses the client name ${field}.`, {
|
|
39
|
+
fix: { summary: "Give the view a name that no table uses." }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const exposes = exposesKey(columns, scope);
|
|
43
|
+
if (scope !== undefined && readsTenant(query, tables, casing, scoped)) {
|
|
44
|
+
if (!exposes && marked === undefined) {
|
|
45
|
+
throw new OkmError2("OKM1820", `View ${name} reads a tenant table and does not expose ${scope.key}.`, {
|
|
46
|
+
fix: {
|
|
47
|
+
summary: "Expose the tenant key so the predicate can be applied, or declare global(reason)."
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (exposes) {
|
|
52
|
+
scope.scopeView(field);
|
|
53
|
+
scoped.add(name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const built = {
|
|
57
|
+
name: field,
|
|
58
|
+
sql: name,
|
|
59
|
+
primary: [],
|
|
60
|
+
uniques: [],
|
|
61
|
+
columns: columnModels(columns, scope),
|
|
62
|
+
relations: []
|
|
63
|
+
};
|
|
64
|
+
if (marked !== undefined)
|
|
65
|
+
globalViews.set(built, marked);
|
|
66
|
+
model[field] = built;
|
|
67
|
+
},
|
|
68
|
+
hook(target, ctx) {
|
|
69
|
+
if (ctx.table === field && ctx.session !== undefined) {
|
|
70
|
+
if (refresh !== "plain")
|
|
71
|
+
target.refresh = refreshHandle(ctx.session, name, refresh);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
publish(field, target, ctx);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function refreshHandle(session, name, mode) {
|
|
79
|
+
const concurrently = mode === "concurrently";
|
|
80
|
+
return () => lazyRefresh(() => import("./8etn7d8w.js").then((mod) => mod.refreshView(session, name, concurrently)));
|
|
81
|
+
}
|
|
82
|
+
function lazyRefresh(run) {
|
|
83
|
+
let pending;
|
|
84
|
+
const once = () => {
|
|
85
|
+
pending ??= run();
|
|
86
|
+
return pending;
|
|
87
|
+
};
|
|
88
|
+
const self = {
|
|
89
|
+
then(onFulfilled, onRejected) {
|
|
90
|
+
return once().then(onFulfilled, onRejected);
|
|
91
|
+
},
|
|
92
|
+
catch(onRejected) {
|
|
93
|
+
return self.then(undefined, onRejected);
|
|
94
|
+
},
|
|
95
|
+
finally(fn) {
|
|
96
|
+
return self.then((value) => {
|
|
97
|
+
fn();
|
|
98
|
+
return value;
|
|
99
|
+
}, (error) => {
|
|
100
|
+
fn();
|
|
101
|
+
throw error;
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
"~refresh": true
|
|
105
|
+
};
|
|
106
|
+
return self;
|
|
107
|
+
}
|
|
108
|
+
function publish(field, target, ctx) {
|
|
109
|
+
if (ctx.tables === undefined || ctx.table !== undefined)
|
|
110
|
+
return;
|
|
111
|
+
const handle = ctx.tables[field];
|
|
112
|
+
if (typeof handle !== "object" || handle === null)
|
|
113
|
+
return;
|
|
114
|
+
const source = handle;
|
|
115
|
+
const views = target.views;
|
|
116
|
+
const map = typeof views === "object" && views !== null ? views : {};
|
|
117
|
+
map[field] = {
|
|
118
|
+
find: source.find,
|
|
119
|
+
one: source.one,
|
|
120
|
+
count: source.count,
|
|
121
|
+
exists: source.exists,
|
|
122
|
+
...typeof source.refresh === "function" ? { refresh: source.refresh } : {}
|
|
123
|
+
};
|
|
124
|
+
target.views = map;
|
|
125
|
+
delete ctx.tables[field];
|
|
126
|
+
delete target[field];
|
|
127
|
+
}
|
|
128
|
+
function columnModels(columns, tenancy) {
|
|
129
|
+
const seen = new Set;
|
|
130
|
+
const models = [];
|
|
131
|
+
for (const column of columns) {
|
|
132
|
+
const field = fieldName(column.name, tenancy);
|
|
133
|
+
if (seen.has(field)) {
|
|
134
|
+
throw new OkmError2("OKM1020", `View column ${column.name} repeats ${field}.`, {
|
|
135
|
+
fix: { summary: "Declare each output column once." }
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
seen.add(field);
|
|
139
|
+
const uuid = column.type.toLowerCase() === "uuid";
|
|
140
|
+
const key = tenancy !== undefined && field === tenancy.key;
|
|
141
|
+
models.push({
|
|
142
|
+
field,
|
|
143
|
+
sql: column.name,
|
|
144
|
+
dataType: column.type,
|
|
145
|
+
encode: uuid ? (value) => encodeUuid(textValue(value)) : (value) => encodeText(textValue(value)),
|
|
146
|
+
decode: uuid ? decodeUuid : decodeText,
|
|
147
|
+
hidden: false,
|
|
148
|
+
sensitive: false,
|
|
149
|
+
guarded: key,
|
|
150
|
+
writable: false,
|
|
151
|
+
guardUpdate: false
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return models;
|
|
155
|
+
}
|
|
156
|
+
function exposesKey(columns, tenancy) {
|
|
157
|
+
if (tenancy === undefined)
|
|
158
|
+
return false;
|
|
159
|
+
return columns.some((column) => fieldName(column.name, tenancy) === tenancy.key);
|
|
160
|
+
}
|
|
161
|
+
function readsTenant(query, tables, casing, scoped) {
|
|
162
|
+
for (const name of scoped) {
|
|
163
|
+
if (viewMentions(query, name))
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
for (const table of tables) {
|
|
167
|
+
const mark = table.options?.tenancy;
|
|
168
|
+
if (isGlobalMark(mark))
|
|
169
|
+
continue;
|
|
170
|
+
const sql = casing === "snake" ? snakeCase(table.name) : table.name;
|
|
171
|
+
if (viewMentions(query, sql) || viewMentions(query, table.name))
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
function readGlobal(name, tenancy) {
|
|
177
|
+
if (tenancy === undefined)
|
|
178
|
+
return;
|
|
179
|
+
if (!isGlobalMark(tenancy)) {
|
|
180
|
+
throw new OkmError2("OKM1020", `View ${name} tenancy must be global("reason").`, {
|
|
181
|
+
fix: { summary: 'Pass global("reason") from okmodel/tenancy, or omit tenancy.' }
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return tenancy.reason;
|
|
185
|
+
}
|
|
186
|
+
function isGlobalMark(value) {
|
|
187
|
+
if (typeof value !== "object" || value === null)
|
|
188
|
+
return false;
|
|
189
|
+
const record = value;
|
|
190
|
+
return record.kind === "global" && typeof record.reason === "string" && record.reason.trim().length > 0;
|
|
191
|
+
}
|
|
192
|
+
function fieldName(column, tenancy) {
|
|
193
|
+
const field = camelCase(column);
|
|
194
|
+
if (tenancy !== undefined && (column === tenancy.key || field === tenancy.key))
|
|
195
|
+
return tenancy.key;
|
|
196
|
+
return field;
|
|
197
|
+
}
|
|
198
|
+
function camelCase(name) {
|
|
199
|
+
let out = "";
|
|
200
|
+
let upper = false;
|
|
201
|
+
for (const char of name) {
|
|
202
|
+
if (char === "_") {
|
|
203
|
+
upper = out.length > 0;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
out += upper ? char.toUpperCase() : char;
|
|
207
|
+
upper = false;
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
function textValue(value) {
|
|
212
|
+
if (typeof value !== "string") {
|
|
213
|
+
throw new OkmError2("OKM1121", "A view column value must be text.", {
|
|
214
|
+
fix: { summary: "Pass a string." }
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export { viewGlobalReason, viewMentions, viewClient };
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import"./
|
|
1
|
+
import"./qq3899ht.js";
|
|
2
2
|
import"./n442h54c.js";
|
|
3
|
-
import"./
|
|
3
|
+
import"./wkme6tep.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
projectPath,
|
|
6
6
|
loadConfig
|
|
7
|
-
} from "./
|
|
8
|
-
import
|
|
9
|
-
|
|
7
|
+
} from "./t3g0k88x.js";
|
|
8
|
+
import {
|
|
9
|
+
listTargets
|
|
10
|
+
} from "./ttmg09vd.js";
|
|
11
|
+
import"./9s0ypp87.js";
|
|
10
12
|
|
|
11
13
|
// src/tooling/migrate/dev.ts
|
|
12
14
|
import { mkdirSync } from "node:fs";
|
|
13
|
-
import { join } from "node:path";
|
|
14
15
|
async function devProject(cwd) {
|
|
15
16
|
const config = await loadConfig(cwd);
|
|
16
17
|
const named = listTargets(config).find((target) => target.name === "dev");
|
|
17
18
|
if (named !== undefined)
|
|
18
19
|
return `target ${named.name}
|
|
19
20
|
`;
|
|
20
|
-
const directory =
|
|
21
|
+
const directory = projectPath(cwd, config.out ?? ".okm", "dev-db");
|
|
21
22
|
mkdirSync(directory, { recursive: true });
|
|
22
|
-
const { open } = await import("./
|
|
23
|
+
const { open } = await import("./g90m9b0g.js");
|
|
23
24
|
const pool = await open({ dataDir: directory });
|
|
24
25
|
try {
|
|
25
26
|
await pool.execute("select 1");
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError2
|
|
3
|
+
} from "./52szzakm.js";
|
|
4
|
+
|
|
5
|
+
// src/dialects/pg/owner.ts
|
|
6
|
+
var MARKS = new WeakMap;
|
|
7
|
+
function withOwner2(table, owner) {
|
|
8
|
+
if (owner !== "external" && owner !== "ignored") {
|
|
9
|
+
throw new OkmError2("invalid", `Table owner ${String(owner)} is not external or ignored.`, {
|
|
10
|
+
kind: "invalid",
|
|
11
|
+
fix: { summary: "Pass external or ignored. Omit the mark for a managed table." }
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
MARKS.set(table, owner);
|
|
15
|
+
return table;
|
|
16
|
+
}
|
|
17
|
+
function tableOwner(table) {
|
|
18
|
+
return MARKS.get(table);
|
|
19
|
+
}
|
|
20
|
+
function stampOwnership(source, marks) {
|
|
21
|
+
if (marks.size === 0)
|
|
22
|
+
return source;
|
|
23
|
+
let changed = false;
|
|
24
|
+
const objects = source.objects.map((object) => {
|
|
25
|
+
const owner = ownerFor(object, marks);
|
|
26
|
+
if (owner === undefined || object.owner === owner)
|
|
27
|
+
return object;
|
|
28
|
+
changed = true;
|
|
29
|
+
return { ...object, owner };
|
|
30
|
+
});
|
|
31
|
+
if (!changed)
|
|
32
|
+
return source;
|
|
33
|
+
return { version: source.version, objects };
|
|
34
|
+
}
|
|
35
|
+
function ownerFor(object, marks) {
|
|
36
|
+
if (object.kind === "table")
|
|
37
|
+
return marks.get(object.identity.name);
|
|
38
|
+
if (object.kind === "column" || object.kind === "index" || object.kind === "constraint" || object.kind === "trigger" || object.kind === "policy") {
|
|
39
|
+
return marks.get(object.identity.parent.name);
|
|
40
|
+
}
|
|
41
|
+
if (object.kind === "sequence") {
|
|
42
|
+
for (const edge of object.dependencies) {
|
|
43
|
+
if (edge.target.kind !== "table")
|
|
44
|
+
continue;
|
|
45
|
+
const owner = marks.get(edge.target.name);
|
|
46
|
+
if (owner !== undefined)
|
|
47
|
+
return owner;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { withOwner2, tableOwner, stampOwnership };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withHttp,
|
|
3
3
|
attachHttp
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./j60w0dvr.js";
|
|
5
5
|
import {
|
|
6
6
|
OkmError2
|
|
7
7
|
} from "./52szzakm.js";
|
|
@@ -31,7 +31,7 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
|
|
|
31
31
|
}));
|
|
32
32
|
}
|
|
33
33
|
} else {
|
|
34
|
-
const { assertCompatible } = await import("./
|
|
34
|
+
const { assertCompatible } = await import("./ek2wt2dz.js");
|
|
35
35
|
try {
|
|
36
36
|
await assertCompatible(pool, schema, recorded, source, options);
|
|
37
37
|
} catch (error) {
|
|
@@ -4,9 +4,12 @@ function callerLocation(skip) {
|
|
|
4
4
|
`);
|
|
5
5
|
if (lines === undefined)
|
|
6
6
|
return;
|
|
7
|
+
return locationFromLines(lines, skip);
|
|
8
|
+
}
|
|
9
|
+
function locationFromLines(lines, skip) {
|
|
7
10
|
let left = skip;
|
|
8
11
|
for (const line of lines) {
|
|
9
|
-
const slash = line.lastIndexOf("/");
|
|
12
|
+
const slash = Math.max(line.lastIndexOf("/"), line.lastIndexOf("\\"));
|
|
10
13
|
if (slash < 0)
|
|
11
14
|
continue;
|
|
12
15
|
const tail = line.slice(slash + 1);
|
|
@@ -135,8 +135,11 @@ class ColumnBuilder2 {
|
|
|
135
135
|
guarded() {
|
|
136
136
|
return rebuild(this.state, { guarded: true });
|
|
137
137
|
}
|
|
138
|
-
hidden() {
|
|
139
|
-
return rebuild(this.state, {
|
|
138
|
+
hidden(options) {
|
|
139
|
+
return rebuild(this.state, {
|
|
140
|
+
hidden: true,
|
|
141
|
+
...options?.filterable === true ? { filterable: true } : {}
|
|
142
|
+
});
|
|
140
143
|
}
|
|
141
144
|
sensitive() {
|
|
142
145
|
return rebuild(this.state, { sensitive: true });
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DriverError2
|
|
3
|
+
} from "./31vm914h.js";
|
|
1
4
|
import {
|
|
2
5
|
send,
|
|
3
6
|
connectClient
|
|
4
|
-
} from "./
|
|
7
|
+
} from "./1z04fa85.js";
|
|
5
8
|
import {
|
|
6
9
|
isConnectionLost
|
|
7
|
-
} from "./
|
|
10
|
+
} from "./gwn6v667.js";
|
|
8
11
|
import {
|
|
9
12
|
WireSession
|
|
10
|
-
} from "./
|
|
13
|
+
} from "./4az561fn.js";
|
|
11
14
|
import {
|
|
12
15
|
rejectClosed,
|
|
13
16
|
runCall
|
|
14
|
-
} from "./
|
|
17
|
+
} from "./cgbamx3e.js";
|
|
15
18
|
|
|
16
19
|
// src/adapters/pg/nodepostgres-extra.ts
|
|
17
20
|
var RESET_ALL = "RESET ALL";
|
|
@@ -34,16 +37,19 @@ async function checkout(held) {
|
|
|
34
37
|
}, () => {
|
|
35
38
|
counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
|
|
36
39
|
}, local);
|
|
37
|
-
const guard = (run) => lost ? rejectClosed("
|
|
40
|
+
const guard = (run) => lost ? rejectClosed("CONNECTION_CLOSED") : run().catch((error) => {
|
|
38
41
|
if (isConnectionLost(error))
|
|
39
42
|
lost = true;
|
|
43
|
+
if (error instanceof Error && error.message.includes("Connection terminated")) {
|
|
44
|
+
throw new DriverError2("CONNECTION_CLOSED", { cause: error });
|
|
45
|
+
}
|
|
40
46
|
throw error;
|
|
41
47
|
});
|
|
42
48
|
let released = false;
|
|
43
49
|
return {
|
|
44
50
|
execute: (text, params, options) => guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch))),
|
|
45
51
|
batch: (statements, options) => guard(() => runCall(isClosed(), options, async (watch) => {
|
|
46
|
-
const { runAtomicBatch } = await import("./
|
|
52
|
+
const { runAtomicBatch } = await import("./ag4c7516.js");
|
|
47
53
|
return runAtomicBatch(session, statements, watch);
|
|
48
54
|
})),
|
|
49
55
|
cancel() {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
assertNamespace2,
|
|
4
4
|
normaliseEdges,
|
|
5
5
|
assertProvenance
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./358zsv4r.js";
|
|
7
7
|
import {
|
|
8
8
|
assertIdentifier2,
|
|
9
9
|
fitIdentifier2,
|
|
@@ -23,7 +23,11 @@ function viewObject(input) {
|
|
|
23
23
|
const query = readQuery(input.name, input.query);
|
|
24
24
|
assertNamespace2(namespace);
|
|
25
25
|
assertProvenance(input.provenance);
|
|
26
|
-
const definition = {
|
|
26
|
+
const definition = {
|
|
27
|
+
columns,
|
|
28
|
+
query,
|
|
29
|
+
...input.securityInvoker === true ? { securityInvoker: true } : {}
|
|
30
|
+
};
|
|
27
31
|
return {
|
|
28
32
|
kind: "view",
|
|
29
33
|
identity: { kind: "view", namespace, name: input.name },
|
package/dist/tooling/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import"../shared/
|
|
1
|
+
import"../shared/qq3899ht.js";
|
|
2
2
|
import"../shared/n442h54c.js";
|
|
3
|
-
import"../shared/
|
|
3
|
+
import"../shared/wkme6tep.js";
|
|
4
4
|
import {
|
|
5
5
|
formatFindings,
|
|
6
6
|
hasError,
|
|
@@ -9,9 +9,11 @@ import {
|
|
|
9
9
|
generateProject,
|
|
10
10
|
planProject,
|
|
11
11
|
checkProject
|
|
12
|
-
} from "../shared/
|
|
13
|
-
import
|
|
14
|
-
|
|
12
|
+
} from "../shared/t3g0k88x.js";
|
|
13
|
+
import {
|
|
14
|
+
sessionFailure
|
|
15
|
+
} from "../shared/ttmg09vd.js";
|
|
16
|
+
import"../shared/9s0ypp87.js";
|
|
15
17
|
import {
|
|
16
18
|
OkmError2
|
|
17
19
|
} from "../shared/52szzakm.js";
|
|
@@ -22,14 +24,28 @@ import { dirname, join } from "node:path";
|
|
|
22
24
|
import { fileURLToPath } from "node:url";
|
|
23
25
|
|
|
24
26
|
// src/tooling/migrate/commands.ts
|
|
25
|
-
function formatFailure(error) {
|
|
26
|
-
|
|
27
|
-
${
|
|
27
|
+
function formatFailure(error, verbose = false) {
|
|
28
|
+
const mapped = sessionFailure(error) ?? OkmError2.from(error);
|
|
29
|
+
let text = `error ${mapped.code}: ${mapped.message}
|
|
30
|
+
${mapped.fix.summary}
|
|
31
|
+
`;
|
|
32
|
+
if (verbose && error instanceof Error && error.stack !== undefined) {
|
|
33
|
+
text += `${error.stack}
|
|
28
34
|
`;
|
|
35
|
+
}
|
|
36
|
+
return text;
|
|
29
37
|
}
|
|
30
38
|
async function run(argv, io) {
|
|
31
39
|
const cwd = io?.cwd ?? process.cwd();
|
|
32
40
|
const stdout = io?.stdout ?? ((text) => process.stdout.write(text));
|
|
41
|
+
if (argv.length === 0 || argv[0] === "help" || argv[0] === "--help" || argv[0] === "-h") {
|
|
42
|
+
stdout(commandsTable());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
46
|
+
stdout(commandHelp(argv.filter((arg) => arg !== "--help" && arg !== "-h")));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
33
49
|
const [command, ...rest] = argv;
|
|
34
50
|
if (command === "build") {
|
|
35
51
|
const directory = await buildProject(cwd);
|
|
@@ -57,12 +73,12 @@ async function run(argv, io) {
|
|
|
57
73
|
return;
|
|
58
74
|
}
|
|
59
75
|
if (command === "dev") {
|
|
60
|
-
const { devProject } = await import("../shared/
|
|
76
|
+
const { devProject } = await import("../shared/xq0mvhts.js");
|
|
61
77
|
stdout(await devProject(cwd));
|
|
62
78
|
return;
|
|
63
79
|
}
|
|
64
80
|
if (command === "push") {
|
|
65
|
-
const { pushProject } = await import("../shared/
|
|
81
|
+
const { pushProject } = await import("../shared/1nw1f3vs.js");
|
|
66
82
|
stdout(await pushProject(cwd, invoke(splitFlags(rest))));
|
|
67
83
|
return;
|
|
68
84
|
}
|
|
@@ -81,17 +97,17 @@ async function run(argv, io) {
|
|
|
81
97
|
return;
|
|
82
98
|
}
|
|
83
99
|
if (sub === "apply") {
|
|
84
|
-
const { applyProject } = await import("../shared/
|
|
100
|
+
const { applyProject } = await import("../shared/1nw1f3vs.js");
|
|
85
101
|
stdout(await applyProject(cwd, invoke(parsed), stdout));
|
|
86
102
|
return;
|
|
87
103
|
}
|
|
88
104
|
if (sub === "status") {
|
|
89
|
-
const { statusProject } = await import("../shared/
|
|
105
|
+
const { statusProject } = await import("../shared/wynzeggs.js");
|
|
90
106
|
stdout(await statusProject(cwd, invoke(parsed)));
|
|
91
107
|
return;
|
|
92
108
|
}
|
|
93
109
|
if (sub === "check") {
|
|
94
|
-
const { checkMigrations } = await import("../shared/
|
|
110
|
+
const { checkMigrations } = await import("../shared/09p049xa.js");
|
|
95
111
|
const provision = parsed.flags.includes("--provision") || rest.slice(1).includes("--provision");
|
|
96
112
|
stdout(await checkMigrations(cwd, invoke(parsed), { provision }));
|
|
97
113
|
return;
|
|
@@ -104,13 +120,13 @@ async function run(argv, io) {
|
|
|
104
120
|
fix: { summary: "Pass okm seed <file>." }
|
|
105
121
|
});
|
|
106
122
|
}
|
|
107
|
-
const { seedProject } = await import("../shared/
|
|
123
|
+
const { seedProject } = await import("../shared/3fqwmr09.js");
|
|
108
124
|
stdout(await seedProject(cwd, parsed.name, invoke(parsed)));
|
|
109
125
|
return;
|
|
110
126
|
}
|
|
111
127
|
if (command === "doctor") {
|
|
112
128
|
const parsed = splitFlags(rest);
|
|
113
|
-
const { doctorProject } = await import("../shared/
|
|
129
|
+
const { doctorProject } = await import("../shared/wt5rzv1h.js");
|
|
114
130
|
stdout(await doctorProject(cwd, parsed.name, invoke(parsed)));
|
|
115
131
|
return;
|
|
116
132
|
}
|
|
@@ -122,7 +138,7 @@ async function run(argv, io) {
|
|
|
122
138
|
});
|
|
123
139
|
}
|
|
124
140
|
if (sub === "list" || sub === "check") {
|
|
125
|
-
const { extProject } = await import("../shared/
|
|
141
|
+
const { extProject } = await import("../shared/p6bjzq9q.js");
|
|
126
142
|
stdout(await extProject(cwd, sub, invoke(splitFlags(rest.slice(1)))));
|
|
127
143
|
return;
|
|
128
144
|
}
|
|
@@ -210,6 +226,42 @@ function splitFlags(args) {
|
|
|
210
226
|
statementTimeoutMs
|
|
211
227
|
};
|
|
212
228
|
}
|
|
229
|
+
var COMMANDS = [
|
|
230
|
+
["build", "Write the schema build."],
|
|
231
|
+
["check", "Lint the schema and compare it with one target."],
|
|
232
|
+
["dev", "Watch the schema and reload."],
|
|
233
|
+
["doctor [code]", "Print a target report, or one error code."],
|
|
234
|
+
["ext list", "List extensions the server can install."],
|
|
235
|
+
["ext check", "Compare declared extensions with the server."],
|
|
236
|
+
["generate [name]", "Write the next migration."],
|
|
237
|
+
["migrate plan <name>", "Print the plan and its lock estimates."],
|
|
238
|
+
["migrate apply", "Apply pending migrations."],
|
|
239
|
+
["migrate status", "Print whether the target is current."],
|
|
240
|
+
["migrate check", "Replay migration history in a scratch schema."],
|
|
241
|
+
["push", "Apply the schema diff to one target."],
|
|
242
|
+
["seed <file>", "Run a seed file on one target."]
|
|
243
|
+
];
|
|
244
|
+
function commandsTable() {
|
|
245
|
+
const lines = ["okm <command>", ""];
|
|
246
|
+
for (const [name, summary] of COMMANDS)
|
|
247
|
+
lines.push(` ${name.padEnd(24)} ${summary}`);
|
|
248
|
+
lines.push("", "okm <command> --help prints that command.", "");
|
|
249
|
+
return `${lines.join(`
|
|
250
|
+
`)}
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
function commandHelp(argv) {
|
|
254
|
+
const key = argv.join(" ");
|
|
255
|
+
const found = COMMANDS.find(([name]) => name === key || name.startsWith(`${key} `));
|
|
256
|
+
if (found === undefined) {
|
|
257
|
+
return `Unknown command ${key}.
|
|
258
|
+
|
|
259
|
+
${commandsTable()}`;
|
|
260
|
+
}
|
|
261
|
+
return `${found[0]}
|
|
262
|
+
${found[1]}
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
213
265
|
function numberFlag(flag, value) {
|
|
214
266
|
const parsed = value === undefined ? Number.NaN : Number(value);
|
|
215
267
|
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
@@ -220,22 +272,43 @@ function numberFlag(flag, value) {
|
|
|
220
272
|
return parsed;
|
|
221
273
|
}
|
|
222
274
|
|
|
275
|
+
// src/tooling/node-version.ts
|
|
276
|
+
function nodeSupportsConfigTypes(version) {
|
|
277
|
+
const match = /^v(\d+)\.(\d+)/.exec(version);
|
|
278
|
+
if (match === null)
|
|
279
|
+
return false;
|
|
280
|
+
const major = Number(match[1]);
|
|
281
|
+
const minor = Number(match[2]);
|
|
282
|
+
if (major > 22)
|
|
283
|
+
return true;
|
|
284
|
+
if (major < 22)
|
|
285
|
+
return false;
|
|
286
|
+
return minor >= 18;
|
|
287
|
+
}
|
|
288
|
+
function nodeStartupMessage(version, bunRuntime) {
|
|
289
|
+
if (bunRuntime || nodeSupportsConfigTypes(version))
|
|
290
|
+
return;
|
|
291
|
+
return `okm needs Node.js >=22.18 to load a .ts config (type stripping). This process is ${version}. Run bun --bun okm to use the Bun runtime.
|
|
292
|
+
`;
|
|
293
|
+
}
|
|
294
|
+
|
|
223
295
|
// src/tooling/cli.ts
|
|
224
296
|
var here = dirname(fileURLToPath(import.meta.url));
|
|
225
297
|
var packageJsonPath = join(here, "..", "..", "package.json");
|
|
226
|
-
|
|
298
|
+
var nodeProblem = nodeStartupMessage(process.version, process.versions.bun !== undefined);
|
|
299
|
+
if (nodeProblem !== undefined) {
|
|
300
|
+
process.stderr.write(nodeProblem);
|
|
301
|
+
process.exitCode = 1;
|
|
302
|
+
} else if (process.argv.includes("--version")) {
|
|
227
303
|
process.stdout.write(`${readPackageVersion(packageJsonPath)}
|
|
228
304
|
`);
|
|
229
|
-
} else
|
|
305
|
+
} else {
|
|
230
306
|
try {
|
|
231
307
|
await run(process.argv.slice(2));
|
|
232
308
|
} catch (error) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
} else {
|
|
237
|
-
throw error;
|
|
238
|
-
}
|
|
309
|
+
const verbose = process.argv.includes("--verbose") || process.env.OKM_DEBUG === "1";
|
|
310
|
+
process.stderr.write(formatFailure(error, verbose));
|
|
311
|
+
process.exitCode = 1;
|
|
239
312
|
}
|
|
240
313
|
}
|
|
241
314
|
function readPackageVersion(path) {
|