okmodel 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -16
- 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/object.d.ts +1 -0
- package/dist/contracts/catalog/types.d.ts +15 -8
- 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 +126 -9
- package/dist/dialects/pg/compile.d.ts +1 -0
- package/dist/dialects/pg/custom.d.ts +6 -0
- package/dist/dialects/pg/filter-parse.d.ts +19 -0
- package/dist/dialects/pg/filters.d.ts +19 -0
- package/dist/dialects/pg/index.d.ts +11 -2
- package/dist/dialects/pg/index.js +159 -1063
- 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 +39 -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/schema.d.ts +109 -5
- package/dist/dialects/pg/table.d.ts +130 -11
- package/dist/dialects/pg/temporal.d.ts +9 -7
- package/dist/dialects/pg/tenancy.d.ts +94 -0
- package/dist/dialects/pg/through.d.ts +21 -0
- package/dist/dialects/pg/trait.d.ts +141 -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 +365 -0
- package/dist/runtime/trait-read.d.ts +30 -0
- package/dist/runtime/traits/index.d.ts +128 -0
- package/dist/runtime/traits/index.js +509 -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/{fgqgsb5z.js → 0qkxbm1f.js} +2 -2
- package/dist/shared/0v1g424p.js +26 -0
- package/dist/shared/10tjenmd.js +210 -0
- package/dist/shared/{xqbhg6cn.js → 1dp5knt7.js} +95 -10
- package/dist/shared/38crxbgn.js +229 -0
- package/dist/shared/3a5ne750.js +158 -0
- package/dist/shared/4b9da9d7.js +138 -0
- package/dist/shared/4e4c6vq2.js +62 -0
- package/dist/shared/{x5x59srr.js → 4jzzghr6.js} +416 -83
- package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
- package/dist/shared/{05w44d8g.js → 5z4q2zda.js} +567 -18
- package/dist/shared/672t5vym.js +12 -0
- package/dist/shared/7m88x3e9.js +45 -0
- package/dist/shared/7mht49yd.js +1091 -0
- package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
- package/dist/shared/83eaefwr.js +10 -0
- package/dist/shared/96ps4g1z.js +32 -0
- package/dist/shared/97g2jnrw.js +76 -0
- package/dist/shared/{xy79j5hq.js → 9k6vetvf.js} +25 -36
- package/dist/shared/{w8samvk1.js → a1gdp7j9.js} +1 -1
- package/dist/shared/a5sxz52y.js +13 -0
- package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
- package/dist/shared/cstgkzdx.js +154 -0
- package/dist/shared/{523ft3e8.js → d04j53v8.js} +6 -5
- package/dist/shared/{y9m15dfv.js → d2whjz4k.js} +15 -9
- package/dist/shared/dd4f8mnx.js +307 -0
- package/dist/shared/e6wg00wd.js +164 -0
- package/dist/shared/e7a268fy.js +195 -0
- package/dist/shared/{kprcwaha.js → eaxwrgby.js} +4 -3
- package/dist/shared/{dkn3y60a.js → ecdzej21.js} +76 -112
- package/dist/shared/{hadrfb9h.js → edwqqryd.js} +17 -14
- package/dist/shared/{m3ypagh5.js → eqmtn1bj.js} +57 -5
- package/dist/shared/g1b5zzj9.js +75 -0
- package/dist/shared/g9f0zqce.js +376 -0
- package/dist/shared/ge03bfca.js +64 -0
- package/dist/shared/{yd1kzwn2.js → jns2wx4t.js} +55 -12
- package/dist/shared/k3ted12y.js +33 -0
- package/dist/shared/k7dwkhvq.js +31 -0
- package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
- package/dist/shared/m9tv7xn7.js +404 -0
- package/dist/shared/mrq77sgw.js +55 -0
- package/dist/shared/mxmcdsh5.js +450 -0
- package/dist/shared/n442h54c.js +14 -0
- package/dist/shared/n47rd821.js +442 -0
- package/dist/shared/n4jqhpqz.js +27 -0
- package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
- package/dist/shared/nsva2a6b.js +42 -0
- package/dist/shared/ps43134h.js +69 -0
- package/dist/shared/{8b04d28c.js → py3nh7jy.js} +2 -2
- package/dist/shared/qa5dsc7z.js +86 -0
- package/dist/shared/{g5fhqmwe.js → qxa0yb9j.js} +6 -4
- package/dist/shared/r6nwkxnt.js +86 -0
- package/dist/shared/{jjb7yht9.js → rtnaqre0.js} +3 -3
- package/dist/shared/rwmrejjz.js +26 -0
- package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
- package/dist/shared/sacqha1y.js +70 -0
- package/dist/shared/{qk3hxfja.js → sfh4pk75.js} +5 -5
- package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
- package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
- package/dist/shared/v18jva5b.js +90 -0
- package/dist/shared/x9v1qgeb.js +201 -0
- package/dist/shared/xatfg0gn.js +193 -0
- package/dist/shared/xkz8g6by.js +225 -0
- package/dist/shared/{rgs0st28.js → xrfnq5k8.js} +237 -434
- package/dist/shared/ytg3xf9p.js +149 -0
- package/dist/shared/yw5c610b.js +48 -0
- package/dist/shared/zd93g3rq.js +31 -0
- package/dist/shared/zt8y0wzb.js +132 -0
- package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
- package/dist/tooling/cli.js +14 -10
- package/dist/tooling/migrate/commands.d.ts +10 -0
- package/dist/tooling/migrate/engine.d.ts +36 -0
- package/package.json +41 -4
- package/dist/shared/gk7cs7sp.js +0 -566
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
noticeBuffer,
|
|
3
|
+
WireSession,
|
|
4
|
+
cursorStream
|
|
5
|
+
} from "./cstgkzdx.js";
|
|
6
|
+
import {
|
|
7
|
+
BUNSQL_CAPABILITIES,
|
|
8
|
+
driverErrors,
|
|
9
|
+
rejectClosed,
|
|
10
|
+
mapFailure,
|
|
11
|
+
runCall
|
|
12
|
+
} from "./9k6vetvf.js";
|
|
13
|
+
|
|
14
|
+
// src/adapters/pg/bunsql.ts
|
|
15
|
+
import { SQL } from "bun";
|
|
16
|
+
function open5(config) {
|
|
17
|
+
const max = config.max ?? 10;
|
|
18
|
+
const acquireMs = config.timeouts?.acquire;
|
|
19
|
+
const counters = { reserved: 0, busy: 0, reservedBusy: 0, waiting: 0 };
|
|
20
|
+
const notices = noticeBuffer();
|
|
21
|
+
let closed = false;
|
|
22
|
+
const isClosed = () => closed;
|
|
23
|
+
const named = config.prepared === "named";
|
|
24
|
+
const parked = [];
|
|
25
|
+
const sql = new SQL(config.url, {
|
|
26
|
+
max,
|
|
27
|
+
idleTimeout: 0,
|
|
28
|
+
maxLifetime: 0,
|
|
29
|
+
prepare: named,
|
|
30
|
+
bigint: false,
|
|
31
|
+
connectionTimeout: 5,
|
|
32
|
+
connection: {
|
|
33
|
+
application_name: "okmodel",
|
|
34
|
+
...config.searchPath !== undefined ? { search_path: config.searchPath } : {}
|
|
35
|
+
},
|
|
36
|
+
...config.ssl !== undefined ? { tls: config.ssl } : {}
|
|
37
|
+
});
|
|
38
|
+
const root = new WireSession((text, params) => send2(sql, text, params), notices, isClosed, false, () => {
|
|
39
|
+
counters.busy += 1;
|
|
40
|
+
}, () => {
|
|
41
|
+
counters.busy = Math.max(0, counters.busy - 1);
|
|
42
|
+
});
|
|
43
|
+
const held = { sql, parked, acquireMs, counters, notices, isClosed };
|
|
44
|
+
const checkout = () => closed ? rejectClosed() : import("./97g2jnrw.js").then((mod) => mod.checkout(held));
|
|
45
|
+
return {
|
|
46
|
+
capabilities: BUNSQL_CAPABILITIES,
|
|
47
|
+
execute(text, params, options) {
|
|
48
|
+
return runCall(closed, options, async (watch) => {
|
|
49
|
+
await releaseParked(parked);
|
|
50
|
+
return root.query(text, params, watch);
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
async batch(statements, options) {
|
|
54
|
+
const connection = await checkout();
|
|
55
|
+
try {
|
|
56
|
+
return await connection.batch(statements, options);
|
|
57
|
+
} finally {
|
|
58
|
+
await connection.release();
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
reserve: () => checkout(),
|
|
62
|
+
stream(text, params) {
|
|
63
|
+
return stream(text, params);
|
|
64
|
+
},
|
|
65
|
+
listen(channel, onNotify) {
|
|
66
|
+
return listen(channel, onNotify);
|
|
67
|
+
},
|
|
68
|
+
stats: () => statsOf(counters, max),
|
|
69
|
+
async close() {
|
|
70
|
+
closed = true;
|
|
71
|
+
await releaseParked(parked);
|
|
72
|
+
await sql.close();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function stream(text, params) {
|
|
76
|
+
return async function* () {
|
|
77
|
+
const connection = await checkout();
|
|
78
|
+
try {
|
|
79
|
+
yield* cursorStream((statement, values) => connection.execute(statement, values), text, params);
|
|
80
|
+
} finally {
|
|
81
|
+
await connection.release();
|
|
82
|
+
}
|
|
83
|
+
}();
|
|
84
|
+
}
|
|
85
|
+
async function listen(channel, onNotify) {
|
|
86
|
+
if (closed)
|
|
87
|
+
return rejectClosed();
|
|
88
|
+
await releaseParked(parked);
|
|
89
|
+
const subscription = await sql.listen(channel, onNotify);
|
|
90
|
+
return async () => {
|
|
91
|
+
await subscription.unlisten();
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function send2(sql, text, params) {
|
|
96
|
+
if (params === undefined || params.length === 0)
|
|
97
|
+
return sql.unsafe(text).raw();
|
|
98
|
+
return sql.unsafe(text, [...params]).raw();
|
|
99
|
+
}
|
|
100
|
+
async function reserve(sql, acquireMs, counters) {
|
|
101
|
+
counters.waiting += 1;
|
|
102
|
+
try {
|
|
103
|
+
if (acquireMs === undefined)
|
|
104
|
+
return await sql.reserve();
|
|
105
|
+
return await sql.reserve({ signal: AbortSignal.timeout(acquireMs) });
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (isAbort(error)) {
|
|
108
|
+
const errors = await driverErrors();
|
|
109
|
+
throw errors.acquireTimeout();
|
|
110
|
+
}
|
|
111
|
+
throw await mapFailure(error);
|
|
112
|
+
} finally {
|
|
113
|
+
counters.waiting = Math.max(0, counters.waiting - 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async function park(parked, reserved) {
|
|
117
|
+
parked.push(reserved);
|
|
118
|
+
while (parked.length > 1) {
|
|
119
|
+
const extra = parked.shift();
|
|
120
|
+
if (extra !== undefined)
|
|
121
|
+
await releaseReserved(extra);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function releaseParked(parked) {
|
|
125
|
+
const pending = parked.splice(0);
|
|
126
|
+
for (const reserved of pending)
|
|
127
|
+
await releaseReserved(reserved);
|
|
128
|
+
}
|
|
129
|
+
function releaseReserved(reserved) {
|
|
130
|
+
const done = reserved.release();
|
|
131
|
+
return done instanceof Promise ? done.then(() => {
|
|
132
|
+
return;
|
|
133
|
+
}) : Promise.resolve();
|
|
134
|
+
}
|
|
135
|
+
function isAbort(error) {
|
|
136
|
+
if (!(error instanceof Error))
|
|
137
|
+
return false;
|
|
138
|
+
return error.name === "AbortError" || error.name === "TimeoutError";
|
|
139
|
+
}
|
|
140
|
+
function statsOf(counters, size) {
|
|
141
|
+
return {
|
|
142
|
+
size,
|
|
143
|
+
idle: Math.max(0, size - counters.reserved - counters.busy),
|
|
144
|
+
inflight: counters.busy + counters.reservedBusy,
|
|
145
|
+
waiting: counters.waiting
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { open5, send2, reserve, park };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
required
|
|
3
|
+
} from "./dd4f8mnx.js";
|
|
4
|
+
import {
|
|
5
|
+
rejected
|
|
6
|
+
} from "./xatfg0gn.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,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withHttp
|
|
3
|
+
} from "./mxmcdsh5.js";
|
|
4
|
+
import {
|
|
5
|
+
decodeResult
|
|
6
|
+
} from "./xrfnq5k8.js";
|
|
7
|
+
import {
|
|
8
|
+
OkmError2
|
|
9
|
+
} from "./52szzakm.js";
|
|
10
|
+
|
|
11
|
+
// src/runtime/read-stream.ts
|
|
12
|
+
async function* streamRows(session, call, prepare, log) {
|
|
13
|
+
await session.connected;
|
|
14
|
+
if (session.pool.capabilities.stream !== true || session.pool.stream === undefined) {
|
|
15
|
+
throw log(new OkmError2("OKM1111", "stream needs a driver with stream: true. This driver does not have it.", withHttp(session.http, {
|
|
16
|
+
fix: { summary: "Use a driver that sets stream, or read with find." }
|
|
17
|
+
})));
|
|
18
|
+
}
|
|
19
|
+
const { plan, params } = await prepare();
|
|
20
|
+
const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./edwqqryd.js")).decodeIncluded;
|
|
21
|
+
for await (const chunk of session.pool.stream(plan.text, params)) {
|
|
22
|
+
const decoded = decode(plan, chunk, call.table);
|
|
23
|
+
if (!Array.isArray(decoded))
|
|
24
|
+
continue;
|
|
25
|
+
for (const row of decoded)
|
|
26
|
+
yield row;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
streamRows
|
|
31
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeArray
|
|
3
|
+
} from "./xatfg0gn.js";
|
|
4
|
+
import {
|
|
5
|
+
OkmError2
|
|
6
|
+
} from "./52szzakm.js";
|
|
7
|
+
|
|
8
|
+
// src/dialects/pg/operator-fit.ts
|
|
9
|
+
var FAMILIES = {
|
|
10
|
+
startsWith: ["text"],
|
|
11
|
+
endsWith: ["text"],
|
|
12
|
+
like: ["text"],
|
|
13
|
+
ilike: ["text"],
|
|
14
|
+
contains: ["text", "array", "jsonb", "range"],
|
|
15
|
+
containedBy: ["array", "jsonb", "range"],
|
|
16
|
+
overlaps: ["array", "range"],
|
|
17
|
+
hasKey: ["jsonb"],
|
|
18
|
+
hasAnyKey: ["jsonb"],
|
|
19
|
+
path: ["json", "jsonb"],
|
|
20
|
+
matches: ["tsvector"],
|
|
21
|
+
"json.set": ["json", "jsonb"],
|
|
22
|
+
"arr.append": ["array"],
|
|
23
|
+
"arr.remove": ["array"]
|
|
24
|
+
};
|
|
25
|
+
var ACCEPTED = {
|
|
26
|
+
text: [
|
|
27
|
+
"eq",
|
|
28
|
+
"not",
|
|
29
|
+
"lt",
|
|
30
|
+
"lte",
|
|
31
|
+
"gt",
|
|
32
|
+
"gte",
|
|
33
|
+
"between",
|
|
34
|
+
"startsWith",
|
|
35
|
+
"contains",
|
|
36
|
+
"endsWith",
|
|
37
|
+
"like",
|
|
38
|
+
"ilike",
|
|
39
|
+
"inList",
|
|
40
|
+
"notIn"
|
|
41
|
+
],
|
|
42
|
+
array: [
|
|
43
|
+
"eq",
|
|
44
|
+
"not",
|
|
45
|
+
"contains",
|
|
46
|
+
"containedBy",
|
|
47
|
+
"overlaps",
|
|
48
|
+
"inList",
|
|
49
|
+
"notIn",
|
|
50
|
+
"arr.append",
|
|
51
|
+
"arr.remove"
|
|
52
|
+
],
|
|
53
|
+
jsonb: ["eq", "not", "contains", "containedBy", "hasKey", "hasAnyKey", "path", "json.set"],
|
|
54
|
+
json: ["eq", "not", "path", "json.set"],
|
|
55
|
+
range: ["eq", "not", "lt", "lte", "gt", "gte", "contains", "containedBy", "overlaps"],
|
|
56
|
+
tsvector: ["eq", "not", "matches"],
|
|
57
|
+
scalar: ["eq", "not", "lt", "lte", "gt", "gte", "between", "inList", "notIn", "inc"]
|
|
58
|
+
};
|
|
59
|
+
var SAFE_TYPE = /^[A-Za-z_][A-Za-z0-9_]*(\(\d+\))?(\[\])*$/;
|
|
60
|
+
var REGCONFIG = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$/;
|
|
61
|
+
function columnFamily(dataType) {
|
|
62
|
+
if (dataType.endsWith("[]"))
|
|
63
|
+
return "array";
|
|
64
|
+
if (dataType === "jsonb")
|
|
65
|
+
return "jsonb";
|
|
66
|
+
if (dataType === "json")
|
|
67
|
+
return "json";
|
|
68
|
+
if (dataType === "tsvector")
|
|
69
|
+
return "tsvector";
|
|
70
|
+
if (dataType.endsWith("range"))
|
|
71
|
+
return "range";
|
|
72
|
+
if (dataType === "text" || dataType === "citext" || dataType.startsWith("varchar(") || dataType.startsWith("char(") || dataType.startsWith("character")) {
|
|
73
|
+
return "text";
|
|
74
|
+
}
|
|
75
|
+
return "scalar";
|
|
76
|
+
}
|
|
77
|
+
function assertOperatorFits(column, name) {
|
|
78
|
+
const families = FAMILIES[name];
|
|
79
|
+
if (families === undefined)
|
|
80
|
+
return;
|
|
81
|
+
if (families.includes(columnFamily(column.dataType)))
|
|
82
|
+
return;
|
|
83
|
+
const accepted = ACCEPTED[columnFamily(column.dataType)];
|
|
84
|
+
const search = name === "matches" && columnFamily(column.dataType) === "text" ? " Text search needs a tsvector column." : "";
|
|
85
|
+
throw new OkmError2("OKM1124", `Operator ${name} does not apply to ${column.dataType} column ${column.field}. Accepted operators: ${accepted.join(", ")}.${search}`, { fix: { summary: `Use one of: ${accepted.join(", ")}.` } });
|
|
86
|
+
}
|
|
87
|
+
function sqlType(dataType, column) {
|
|
88
|
+
if (SAFE_TYPE.test(dataType))
|
|
89
|
+
return dataType;
|
|
90
|
+
assertOperatorFits(column, "contains");
|
|
91
|
+
throw new OkmError2("OKM1124", `Operator contains does not apply to ${column.dataType} column ${column.field}. Accepted operators: ${ACCEPTED[columnFamily(column.dataType)].join(", ")}.`, { fix: { summary: "Use a column type this operator accepts." } });
|
|
92
|
+
}
|
|
93
|
+
function assertNoControl(value, role) {
|
|
94
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
95
|
+
const code = value.charCodeAt(index);
|
|
96
|
+
if (code <= 31 || code === 127) {
|
|
97
|
+
throw new OkmError2("OKM1122", `${role} contains a control character.`, {
|
|
98
|
+
fix: { summary: "Remove NUL and other control characters. The value is not sent." }
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function assertBoundText(value, role) {
|
|
104
|
+
if (value.length === 0) {
|
|
105
|
+
throw new OkmError2("OKM1122", `${role} is empty.`, {
|
|
106
|
+
fix: { summary: "Pass a non-empty key or path segment." }
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
assertNoControl(value, role);
|
|
110
|
+
}
|
|
111
|
+
function assertRegconfig(config) {
|
|
112
|
+
if (!REGCONFIG.test(config)) {
|
|
113
|
+
throw new OkmError2("OKM1122", `Text search config ${config} must be a regconfig name such as english or pg_catalog.simple.`, { fix: { summary: "Pass a regconfig name. Quotes and extra clauses are not accepted." } });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function textArray(values, role) {
|
|
117
|
+
for (const value of values)
|
|
118
|
+
assertBoundText(value, role);
|
|
119
|
+
return writeArray(values, 1, (value) => String(value), false);
|
|
120
|
+
}
|
|
121
|
+
function arrayElementType(dataType, column) {
|
|
122
|
+
if (!dataType.endsWith("[]")) {
|
|
123
|
+
assertOperatorFits(column, "arr.append");
|
|
124
|
+
}
|
|
125
|
+
const element = dataType.slice(0, -2);
|
|
126
|
+
if (!SAFE_TYPE.test(element)) {
|
|
127
|
+
throw new OkmError2("OKM1124", `Operator arr.append does not apply to ${column.dataType} column ${column.field}. Accepted operators: ${ACCEPTED.array.join(", ")}.`, { fix: { summary: "Use arr.append on an array column." } });
|
|
128
|
+
}
|
|
129
|
+
return element;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { assertOperatorFits, sqlType, assertNoControl, assertBoundText, assertRegconfig, textArray, arrayElementType };
|
package/dist/tooling/cli.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import"../shared/
|
|
1
|
+
import"../shared/d2whjz4k.js";
|
|
2
|
+
import"../shared/n442h54c.js";
|
|
2
3
|
import {
|
|
3
4
|
formatPlan,
|
|
4
5
|
buildProject,
|
|
5
6
|
generateProject,
|
|
6
7
|
planProject,
|
|
7
8
|
checkProject
|
|
8
|
-
} from "../shared/
|
|
9
|
+
} from "../shared/5z4q2zda.js";
|
|
9
10
|
import {
|
|
10
11
|
OkmError2
|
|
11
|
-
} from "../shared/
|
|
12
|
+
} from "../shared/52szzakm.js";
|
|
12
13
|
|
|
13
14
|
// src/tooling/cli.ts
|
|
14
15
|
import { readFileSync } from "node:fs";
|
|
@@ -16,6 +17,11 @@ import { dirname, join } from "node:path";
|
|
|
16
17
|
import { fileURLToPath } from "node:url";
|
|
17
18
|
|
|
18
19
|
// src/tooling/migrate/commands.ts
|
|
20
|
+
function formatFailure(error) {
|
|
21
|
+
return `${error.code}: ${error.message}
|
|
22
|
+
${error.fix.summary}
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
19
25
|
async function run(argv, io) {
|
|
20
26
|
const cwd = io?.cwd ?? process.cwd();
|
|
21
27
|
const stdout = io?.stdout ?? ((text) => process.stdout.write(text));
|
|
@@ -41,12 +47,12 @@ async function run(argv, io) {
|
|
|
41
47
|
return;
|
|
42
48
|
}
|
|
43
49
|
if (command === "dev") {
|
|
44
|
-
const { devProject } = await import("../shared/
|
|
50
|
+
const { devProject } = await import("../shared/eaxwrgby.js");
|
|
45
51
|
stdout(await devProject(cwd));
|
|
46
52
|
return;
|
|
47
53
|
}
|
|
48
54
|
if (command === "push") {
|
|
49
|
-
const { pushProject } = await import("../shared/
|
|
55
|
+
const { pushProject } = await import("../shared/eqmtn1bj.js");
|
|
50
56
|
stdout(await pushProject(cwd, invoke(splitFlags(rest))));
|
|
51
57
|
return;
|
|
52
58
|
}
|
|
@@ -61,12 +67,12 @@ async function run(argv, io) {
|
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
63
69
|
if (sub === "apply") {
|
|
64
|
-
const { applyProject } = await import("../shared/
|
|
70
|
+
const { applyProject } = await import("../shared/eqmtn1bj.js");
|
|
65
71
|
stdout(await applyProject(cwd, invoke(parsed)));
|
|
66
72
|
return;
|
|
67
73
|
}
|
|
68
74
|
if (sub === "status") {
|
|
69
|
-
const { statusProject } = await import("../shared/
|
|
75
|
+
const { statusProject } = await import("../shared/d04j53v8.js");
|
|
70
76
|
stdout(await statusProject(cwd, invoke(parsed)));
|
|
71
77
|
return;
|
|
72
78
|
}
|
|
@@ -172,9 +178,7 @@ if (process.argv.includes("--version")) {
|
|
|
172
178
|
await run(process.argv.slice(2));
|
|
173
179
|
} catch (error) {
|
|
174
180
|
if (error instanceof OkmError2) {
|
|
175
|
-
process.stderr.write(
|
|
176
|
-
${error.fix.summary}
|
|
177
|
-
`);
|
|
181
|
+
process.stderr.write(formatFailure(error));
|
|
178
182
|
process.exitCode = 1;
|
|
179
183
|
} else {
|
|
180
184
|
throw error;
|
|
@@ -4,11 +4,21 @@
|
|
|
4
4
|
* The bin wrapper imports {@link run}. Importing this module does not parse
|
|
5
5
|
* `process.argv`.
|
|
6
6
|
*/
|
|
7
|
+
import { OkmError } from "../../contracts/error.js";
|
|
7
8
|
/** Where a command reads the project and writes its text. */
|
|
8
9
|
export type CommandIo = {
|
|
9
10
|
readonly cwd?: string;
|
|
10
11
|
readonly stdout?: (text: string) => void;
|
|
11
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Text `okm` writes for a failure.
|
|
15
|
+
*
|
|
16
|
+
* The message includes a source location when the schema recorded one.
|
|
17
|
+
*
|
|
18
|
+
* @param error - Failure from a command
|
|
19
|
+
* @returns The stderr text, including the trailing newline
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatFailure(error: OkmError): string;
|
|
12
22
|
/**
|
|
13
23
|
* Runs one `okm` invocation.
|
|
14
24
|
*
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine-version checks `okm migrate apply` runs before the first statement.
|
|
3
|
+
*
|
|
4
|
+
* The only engine-dependent feature in 0.2 is a `uuidv7()` database default,
|
|
5
|
+
* which Postgres has from 18. Nothing here is reachable from `connect()`.
|
|
6
|
+
*/
|
|
7
|
+
import type { DriverConnection } from "../../contracts/driver.js";
|
|
8
|
+
import type { StoredMigration } from "./files.js";
|
|
9
|
+
/** Where a migration sets a `uuidv7()` default. */
|
|
10
|
+
export type UuidV7Default = {
|
|
11
|
+
readonly migrationId: string;
|
|
12
|
+
readonly stepIndex: number;
|
|
13
|
+
/** `table.column`, or `undefined` when the statement does not name both. */
|
|
14
|
+
readonly column: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Finds the first pending step that sets a `uuidv7()` database default.
|
|
18
|
+
*
|
|
19
|
+
* Only `default uuidv7()` counts, so a string in a data step is not a hit.
|
|
20
|
+
*
|
|
21
|
+
* @param migrations - Migrations in apply order
|
|
22
|
+
* @returns The first hit, or `undefined`
|
|
23
|
+
*/
|
|
24
|
+
export declare function findUuidV7Default(migrations: readonly StoredMigration[]): UuidV7Default | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Refuses a run that would set a `uuidv7()` default on a server that has none.
|
|
27
|
+
*
|
|
28
|
+
* The server is asked only when a step needs it, so a schema without the
|
|
29
|
+
* default costs no round trip. A server below 18 that already has a
|
|
30
|
+
* `uuidv7()` function, such as one the application defined, is accepted.
|
|
31
|
+
*
|
|
32
|
+
* @param connection - The reserved apply connection
|
|
33
|
+
* @param migrations - Migrations in apply order
|
|
34
|
+
* @throws OkmError OKM1812, before any statement of the plan runs
|
|
35
|
+
*/
|
|
36
|
+
export declare function assertUuidV7Available(connection: DriverConnection, migrations: readonly StoredMigration[]): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okmodel",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "okmodel is a catalog-first TypeScript ORM, PostgreSQL first.
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "okmodel is a catalog-first TypeScript ORM, PostgreSQL first.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"migrations",
|
|
7
7
|
"orm",
|
|
@@ -57,10 +57,38 @@
|
|
|
57
57
|
"./pg/pglite": {
|
|
58
58
|
"types": "./dist/runtime/pg/pglite.d.ts",
|
|
59
59
|
"import": "./dist/runtime/pg/pglite.js"
|
|
60
|
+
},
|
|
61
|
+
"./pg/pg": {
|
|
62
|
+
"types": "./dist/runtime/pg/pg.d.ts",
|
|
63
|
+
"import": "./dist/runtime/pg/pg.js"
|
|
64
|
+
},
|
|
65
|
+
"./pg/bun": {
|
|
66
|
+
"types": "./dist/runtime/pg/bun.d.ts",
|
|
67
|
+
"import": "./dist/runtime/pg/bun.js"
|
|
68
|
+
},
|
|
69
|
+
"./ids": {
|
|
70
|
+
"types": "./dist/runtime/ids/index.d.ts",
|
|
71
|
+
"import": "./dist/runtime/ids/index.js"
|
|
72
|
+
},
|
|
73
|
+
"./safety": {
|
|
74
|
+
"types": "./dist/runtime/safety/index.d.ts",
|
|
75
|
+
"import": "./dist/runtime/safety/index.js"
|
|
76
|
+
},
|
|
77
|
+
"./traits": {
|
|
78
|
+
"types": "./dist/runtime/traits/index.d.ts",
|
|
79
|
+
"import": "./dist/runtime/traits/index.js"
|
|
80
|
+
},
|
|
81
|
+
"./tenancy": {
|
|
82
|
+
"types": "./dist/runtime/tenancy/index.d.ts",
|
|
83
|
+
"import": "./dist/runtime/tenancy/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./validate": {
|
|
86
|
+
"types": "./dist/runtime/validate/index.d.ts",
|
|
87
|
+
"import": "./dist/runtime/validate/index.js"
|
|
60
88
|
}
|
|
61
89
|
},
|
|
62
90
|
"scripts": {
|
|
63
|
-
"build": "rm -rf dist && bun build ./src/contracts/index.ts ./src/contracts/internal.ts ./src/dialects/pg/index.ts ./src/runtime/pg/postgresjs.ts ./src/runtime/pg/pglite.ts ./src/tooling/migrate/index.ts ./src/tooling/cli.ts --outdir ./dist --root ./src --format esm --target node --splitting --chunk-naming=shared/[hash].js --external postgres --external @electric-sql/pglite && bunx tsc -p tsconfig.build.json && bun ./scripts/write-bin-wrappers.ts",
|
|
91
|
+
"build": "rm -rf dist && bun build ./src/contracts/index.ts ./src/contracts/internal.ts ./src/dialects/pg/index.ts ./src/runtime/pg/postgresjs.ts ./src/runtime/pg/pglite.ts ./src/runtime/pg/pg.ts ./src/runtime/pg/bun.ts ./src/runtime/ids/index.ts ./src/runtime/safety/index.ts ./src/runtime/traits/index.ts ./src/runtime/tenancy/index.ts ./src/runtime/validate/index.ts ./src/tooling/migrate/index.ts ./src/tooling/cli.ts --outdir ./dist --root ./src --format esm --target node --splitting --chunk-naming=shared/[hash].js --external postgres --external @electric-sql/pglite --external pg --external bun && bunx tsc -p tsconfig.build.json && bun ./scripts/write-bin-wrappers.ts",
|
|
64
92
|
"driver-bench": "bun ./scripts/driver-bench.ts",
|
|
65
93
|
"typecheck": "bunx tsc --noEmit -p tsconfig.json",
|
|
66
94
|
"editor-check": "bun ./scripts/editor-check.ts",
|
|
@@ -70,6 +98,8 @@
|
|
|
70
98
|
"format:check": "oxfmt --check",
|
|
71
99
|
"layers-check": "bun ./scripts/layers-check.ts",
|
|
72
100
|
"core-purity": "bun ./scripts/core-purity.ts",
|
|
101
|
+
"okid-drift": "bun ./scripts/okid-drift.ts",
|
|
102
|
+
"test:runtimes": "bun ./scripts/runtimes.ts",
|
|
73
103
|
"docs:check": "bun ./scripts/docs-check.ts",
|
|
74
104
|
"readme:check": "bun ./scripts/readme-check.ts",
|
|
75
105
|
"compiler-api": "bun ./scripts/compiler-api.ts",
|
|
@@ -81,7 +111,7 @@
|
|
|
81
111
|
"test:postgres": "bun ./scripts/postgres-suite.ts",
|
|
82
112
|
"test:tarball": "bun ./scripts/tarball-smoke.ts",
|
|
83
113
|
"verify": "bun ./scripts/verify.ts",
|
|
84
|
-
"check": "bun run format:check && bun run lint && bun run typecheck && bun run editor-check && bun run type-cost && bun run layers-check && bun run core-purity && bun run docs:check && bun run readme:check && bun run compiler-api && bun run bundle-purity && bun run build && bun test && bun run publint && bun run attw && bun run size",
|
|
114
|
+
"check": "bun run format:check && bun run lint && bun run typecheck && bun run editor-check && bun run type-cost && bun run layers-check && bun run core-purity && bun run okid-drift && bun run docs:check && bun run readme:check && bun run compiler-api && bun run bundle-purity && bun run build && bun test && bun run test:runtimes && bun run publint && bun run attw && bun run size",
|
|
85
115
|
"bump": "bun ./scripts/bump-version.ts",
|
|
86
116
|
"release-check": "bun ./scripts/release-check.ts",
|
|
87
117
|
"db:up": "bun ./packages/harness/src/docker-cli.ts up",
|
|
@@ -108,14 +138,21 @@
|
|
|
108
138
|
},
|
|
109
139
|
"peerDependencies": {
|
|
110
140
|
"@electric-sql/pglite": "^0.5.8",
|
|
141
|
+
"pg": "^8.16.0",
|
|
111
142
|
"postgres": "^3.4.9"
|
|
112
143
|
},
|
|
113
144
|
"peerDependenciesMeta": {
|
|
114
145
|
"@electric-sql/pglite": {
|
|
115
146
|
"optional": true
|
|
116
147
|
},
|
|
148
|
+
"pg": {
|
|
149
|
+
"optional": true
|
|
150
|
+
},
|
|
117
151
|
"postgres": {
|
|
118
152
|
"optional": true
|
|
119
153
|
}
|
|
154
|
+
},
|
|
155
|
+
"engines": {
|
|
156
|
+
"node": ">=22"
|
|
120
157
|
}
|
|
121
158
|
}
|