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,309 @@
|
|
|
1
|
+
import {
|
|
2
|
+
definition,
|
|
3
|
+
rejected,
|
|
4
|
+
writeArray,
|
|
5
|
+
readArray
|
|
6
|
+
} from "./tmbdywx0.js";
|
|
7
|
+
import {
|
|
8
|
+
quoteLiteral
|
|
9
|
+
} from "./94ez8kzh.js";
|
|
10
|
+
import {
|
|
11
|
+
REFERENTIAL_ACTIONS,
|
|
12
|
+
referentialAction
|
|
13
|
+
} from "./4e4c6vq2.js";
|
|
14
|
+
import {
|
|
15
|
+
readClientGenerator
|
|
16
|
+
} from "./rwmrejjz.js";
|
|
17
|
+
|
|
18
|
+
// src/dialects/pg/column.ts
|
|
19
|
+
class ColumnBuilder2 {
|
|
20
|
+
state;
|
|
21
|
+
constructor(state) {
|
|
22
|
+
this.state = state;
|
|
23
|
+
}
|
|
24
|
+
encode(value) {
|
|
25
|
+
return this.state.encode(value);
|
|
26
|
+
}
|
|
27
|
+
decode(wire) {
|
|
28
|
+
return this.state.decode(wire);
|
|
29
|
+
}
|
|
30
|
+
nullable() {
|
|
31
|
+
return rebuild(this.state, { nullable: true });
|
|
32
|
+
}
|
|
33
|
+
default(value) {
|
|
34
|
+
const clientDefault = readClientGenerator(value);
|
|
35
|
+
if (clientDefault !== undefined) {
|
|
36
|
+
return rebuild(this.state, {
|
|
37
|
+
hasDefault: true,
|
|
38
|
+
defaultSql: undefined,
|
|
39
|
+
defaultValue: undefined,
|
|
40
|
+
clientDefault,
|
|
41
|
+
generated: undefined
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (value === null && this.state.nullable === false) {
|
|
45
|
+
definition("A null default is only accepted on a nullable column. Call .nullable() first.");
|
|
46
|
+
}
|
|
47
|
+
if (this.state.picklist !== undefined && value !== null) {
|
|
48
|
+
const text = String(value);
|
|
49
|
+
if (!this.state.picklist.values.includes(text)) {
|
|
50
|
+
definition(`Default ${text} is not in the picklist ${this.state.picklist.values.join(", ")}.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return rebuild(this.state, {
|
|
54
|
+
hasDefault: true,
|
|
55
|
+
defaultSql: value === null ? "NULL" : sqlOf(this.state, value),
|
|
56
|
+
defaultValue: value,
|
|
57
|
+
clientDefault: undefined,
|
|
58
|
+
generated: undefined
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
defaultSql(expression) {
|
|
62
|
+
if (expression.length === 0) {
|
|
63
|
+
definition("defaultSql must be a non-empty SQL expression.");
|
|
64
|
+
}
|
|
65
|
+
return rebuild(this.state, {
|
|
66
|
+
hasDefault: true,
|
|
67
|
+
defaultSql: expression,
|
|
68
|
+
defaultValue: undefined,
|
|
69
|
+
clientDefault: undefined,
|
|
70
|
+
generated: undefined
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
primaryKey() {
|
|
74
|
+
return rebuild(this.state, {
|
|
75
|
+
primaryKey: true,
|
|
76
|
+
omitUpdate: true
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
unique(options) {
|
|
80
|
+
const marker = options?.global;
|
|
81
|
+
if (typeof marker === "string" && marker.trim().length === 0) {
|
|
82
|
+
definition("unique() global needs a reason.");
|
|
83
|
+
}
|
|
84
|
+
const named = typeof marker === "string" ? marker.trim() : undefined;
|
|
85
|
+
const globalFlag = typeof marker === "string" ? true : marker;
|
|
86
|
+
return rebuild(this.state, {
|
|
87
|
+
unique: {
|
|
88
|
+
reason: named ?? options?.reason,
|
|
89
|
+
global: globalFlag
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
picklist(values, options) {
|
|
94
|
+
if (values.length === 0) {
|
|
95
|
+
definition("A picklist must contain at least one value.");
|
|
96
|
+
}
|
|
97
|
+
const allowed = new Set;
|
|
98
|
+
for (const value of values) {
|
|
99
|
+
if (value.length === 0) {
|
|
100
|
+
definition("Picklist values must be non-empty strings.");
|
|
101
|
+
}
|
|
102
|
+
if (allowed.has(value)) {
|
|
103
|
+
definition(`Picklist value ${value} is repeated. Each value is accepted once.`);
|
|
104
|
+
}
|
|
105
|
+
allowed.add(value);
|
|
106
|
+
}
|
|
107
|
+
if (typeof this.state.defaultValue === "string" && !allowed.has(this.state.defaultValue)) {
|
|
108
|
+
definition(`Default ${this.state.defaultValue} is not in the picklist ${values.join(", ")}.`);
|
|
109
|
+
}
|
|
110
|
+
const previous = this.state.elementEncode;
|
|
111
|
+
const elementEncode = (value) => {
|
|
112
|
+
if (typeof value !== "string" || !allowed.has(value)) {
|
|
113
|
+
rejected(`Picklist rejected ${String(value)}. Accepted values: ${[...allowed].join(", ")}.`);
|
|
114
|
+
}
|
|
115
|
+
return previous(value);
|
|
116
|
+
};
|
|
117
|
+
return rebuild(this.state, {
|
|
118
|
+
picklist: { values: values.slice(), check: options?.check !== false },
|
|
119
|
+
elementEncode,
|
|
120
|
+
encode: elementEncode
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
generated(expression, options) {
|
|
124
|
+
if (expression.length === 0) {
|
|
125
|
+
definition("generated() must be a non-empty SQL expression.");
|
|
126
|
+
}
|
|
127
|
+
return rebuild(this.state, {
|
|
128
|
+
generated: { stored: options?.stored !== false, expression },
|
|
129
|
+
hasDefault: true,
|
|
130
|
+
defaultSql: undefined,
|
|
131
|
+
defaultValue: undefined,
|
|
132
|
+
clientDefault: undefined
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
guarded() {
|
|
136
|
+
return rebuild(this.state, { guarded: true });
|
|
137
|
+
}
|
|
138
|
+
hidden() {
|
|
139
|
+
return rebuild(this.state, { hidden: true });
|
|
140
|
+
}
|
|
141
|
+
sensitive() {
|
|
142
|
+
return rebuild(this.state, { sensitive: true });
|
|
143
|
+
}
|
|
144
|
+
validate(rules) {
|
|
145
|
+
const list = Array.isArray(rules) ? rules : [rules];
|
|
146
|
+
return rebuild(this.state, { validate: { rules: list } });
|
|
147
|
+
}
|
|
148
|
+
references(table, options) {
|
|
149
|
+
if (table.length === 0) {
|
|
150
|
+
definition("references() needs a table name.");
|
|
151
|
+
}
|
|
152
|
+
const onDelete = readAction(options?.onDelete, "onDelete");
|
|
153
|
+
const onUpdate = readAction(options?.onUpdate, "onUpdate");
|
|
154
|
+
const columns = readReferenceColumns(options?.columns);
|
|
155
|
+
return rebuild(this.state, {
|
|
156
|
+
references: {
|
|
157
|
+
table,
|
|
158
|
+
...onDelete !== undefined ? { onDelete } : {},
|
|
159
|
+
...onUpdate !== undefined ? { onUpdate } : {},
|
|
160
|
+
...columns !== undefined ? { columns } : {}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
renamedFrom(name) {
|
|
165
|
+
if (name.length === 0) {
|
|
166
|
+
definition("renamedFrom must be a non-empty previous column name.");
|
|
167
|
+
}
|
|
168
|
+
return rebuild(this.state, { renamedFrom: name });
|
|
169
|
+
}
|
|
170
|
+
sqlName(name) {
|
|
171
|
+
if (name.length === 0) {
|
|
172
|
+
definition("sqlName must be a non-empty SQL identifier.");
|
|
173
|
+
}
|
|
174
|
+
return rebuild(this.state, { sqlName: name });
|
|
175
|
+
}
|
|
176
|
+
comment(text) {
|
|
177
|
+
return rebuild(this.state, { comment: text });
|
|
178
|
+
}
|
|
179
|
+
array(options) {
|
|
180
|
+
if (this.state.dims !== 0) {
|
|
181
|
+
definition("array() accepts a scalar column. This column is already an array.");
|
|
182
|
+
}
|
|
183
|
+
const dims = options?.dims ?? 1;
|
|
184
|
+
if (!Number.isInteger(dims) || dims < 1 || dims > 6) {
|
|
185
|
+
definition(`Array dims ${String(dims)} must be an integer from 1 to 6.`);
|
|
186
|
+
}
|
|
187
|
+
const elementEncode = this.state.elementEncode;
|
|
188
|
+
const elementDecode = this.state.elementDecode;
|
|
189
|
+
const raw = this.state.sqlForm === "raw";
|
|
190
|
+
return rebuild(this.state, {
|
|
191
|
+
dims,
|
|
192
|
+
accepts: ["Array"],
|
|
193
|
+
encode: (value) => writeArray(value, dims, elementEncode, raw),
|
|
194
|
+
decode: (wire) => readArray(wire, dims, elementDecode)
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function required(body) {
|
|
199
|
+
return openColumn({
|
|
200
|
+
nullable: false,
|
|
201
|
+
hasDefault: false,
|
|
202
|
+
generated: false,
|
|
203
|
+
guarded: false,
|
|
204
|
+
hidden: false,
|
|
205
|
+
omitWrite: false,
|
|
206
|
+
...body
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function openColumn(input) {
|
|
210
|
+
const elementEncode = input.encode;
|
|
211
|
+
const elementDecode = input.decode;
|
|
212
|
+
return new ColumnBuilder2({
|
|
213
|
+
baseType: input.baseType,
|
|
214
|
+
dims: 0,
|
|
215
|
+
nullable: input.nullable,
|
|
216
|
+
hasDefault: input.hasDefault,
|
|
217
|
+
defaultSql: input.defaultSql,
|
|
218
|
+
defaultValue: undefined,
|
|
219
|
+
clientDefault: input.clientDefault,
|
|
220
|
+
collation: input.collation,
|
|
221
|
+
idSource: input.idSource,
|
|
222
|
+
identity: input.identity,
|
|
223
|
+
generated: undefined,
|
|
224
|
+
unique: undefined,
|
|
225
|
+
picklist: undefined,
|
|
226
|
+
guarded: input.guarded,
|
|
227
|
+
hidden: input.hidden,
|
|
228
|
+
sensitive: false,
|
|
229
|
+
omitWrite: input.omitWrite,
|
|
230
|
+
omitUpdate: input.omitUpdate === true,
|
|
231
|
+
renamedFrom: undefined,
|
|
232
|
+
sqlName: undefined,
|
|
233
|
+
comment: undefined,
|
|
234
|
+
extension: input.extension,
|
|
235
|
+
typeDependency: input.typeDependency,
|
|
236
|
+
enumLabels: input.enumLabels,
|
|
237
|
+
domain: input.domain,
|
|
238
|
+
primaryKey: input.primaryKey === true,
|
|
239
|
+
typeLabel: input.typeLabel,
|
|
240
|
+
references: undefined,
|
|
241
|
+
validate: undefined,
|
|
242
|
+
sqlForm: input.sqlForm,
|
|
243
|
+
encode: input.encode,
|
|
244
|
+
decode: input.decode,
|
|
245
|
+
elementEncode,
|
|
246
|
+
elementDecode,
|
|
247
|
+
accepts: input.accepts
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function formatType(baseType, dims) {
|
|
251
|
+
if (dims === 0) {
|
|
252
|
+
return baseType;
|
|
253
|
+
}
|
|
254
|
+
return baseType + "[]".repeat(dims);
|
|
255
|
+
}
|
|
256
|
+
function sqlOf(state, value) {
|
|
257
|
+
const encoded = state.encode(value);
|
|
258
|
+
const typed = formatType(state.baseType, state.dims);
|
|
259
|
+
if (state.sqlForm === "cast") {
|
|
260
|
+
return `${quoteLiteral(encoded)}::${typed}`;
|
|
261
|
+
}
|
|
262
|
+
if (state.sqlForm === "json") {
|
|
263
|
+
return `${quoteLiteral(encoded)}::json`;
|
|
264
|
+
}
|
|
265
|
+
if (state.sqlForm === "jsonb") {
|
|
266
|
+
return `${quoteLiteral(encoded)}::jsonb`;
|
|
267
|
+
}
|
|
268
|
+
if (state.dims > 0 || state.sqlForm === "quote") {
|
|
269
|
+
return quoteLiteral(encoded);
|
|
270
|
+
}
|
|
271
|
+
return encoded;
|
|
272
|
+
}
|
|
273
|
+
function readAction(action, role) {
|
|
274
|
+
if (action === undefined) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (referentialAction(action) === undefined) {
|
|
278
|
+
definition(`references() ${role} ${action} is not a referential action. Accepted actions: ${REFERENTIAL_ACTIONS.join(", ")}.`);
|
|
279
|
+
}
|
|
280
|
+
return action;
|
|
281
|
+
}
|
|
282
|
+
function readReferenceColumns(columns) {
|
|
283
|
+
if (columns === undefined) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (columns.length === 0) {
|
|
287
|
+
definition("references() columns must name at least one target column.");
|
|
288
|
+
}
|
|
289
|
+
const copy = [];
|
|
290
|
+
for (const name of columns) {
|
|
291
|
+
if (name.length === 0) {
|
|
292
|
+
definition("references() columns must be non-empty names.");
|
|
293
|
+
}
|
|
294
|
+
copy.push(name);
|
|
295
|
+
}
|
|
296
|
+
return copy;
|
|
297
|
+
}
|
|
298
|
+
function retarget(column, patch) {
|
|
299
|
+
return rebuild(column.state, {
|
|
300
|
+
...patch.dropUnique === true ? { unique: undefined } : {},
|
|
301
|
+
...patch.dropPrimary === true ? { primaryKey: false } : {},
|
|
302
|
+
...patch.references !== undefined ? { references: patch.references } : {}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
function rebuild(state, patch) {
|
|
306
|
+
return new ColumnBuilder2({ ...state, ...patch });
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export { ColumnBuilder2, required, openColumn, formatType, retarget };
|
|
@@ -1,27 +1,90 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./xw1d69vd.js";
|
|
4
4
|
import {
|
|
5
5
|
catalogHash2
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./t616ynfn.js";
|
|
7
|
+
import"./n442h54c.js";
|
|
7
8
|
import {
|
|
8
9
|
loadMigrations
|
|
9
|
-
} from "./
|
|
10
|
+
} from "./g4f5kcx9.js";
|
|
11
|
+
import {
|
|
12
|
+
assertCreateRole,
|
|
13
|
+
currentUser,
|
|
14
|
+
roleExists
|
|
15
|
+
} from "./hcmdtwgh.js";
|
|
10
16
|
import {
|
|
11
|
-
quoteIdent,
|
|
12
|
-
planMigration,
|
|
13
17
|
assertTargetPolicy,
|
|
14
18
|
assertDirectConnection,
|
|
15
19
|
selectTarget,
|
|
16
20
|
projectHead,
|
|
17
21
|
loadConfig
|
|
18
|
-
} from "./
|
|
22
|
+
} from "./5nmdenb6.js";
|
|
23
|
+
import {
|
|
24
|
+
createdRoleName,
|
|
25
|
+
changesRole,
|
|
26
|
+
assertExtensionsAvailable,
|
|
27
|
+
planMigration
|
|
28
|
+
} from "./2ssqrv66.js";
|
|
29
|
+
import {
|
|
30
|
+
quoteIdent
|
|
31
|
+
} from "./wekze34d.js";
|
|
19
32
|
import {
|
|
20
33
|
OkmError2
|
|
21
|
-
} from "./
|
|
34
|
+
} from "./52szzakm.js";
|
|
22
35
|
|
|
23
36
|
// src/tooling/migrate/apply.ts
|
|
24
37
|
import { join } from "node:path";
|
|
38
|
+
|
|
39
|
+
// src/tooling/migrate/engine.ts
|
|
40
|
+
var IDENT = String.raw`"(?:[^"]|"")+"|[A-Za-z_][\w$]*`;
|
|
41
|
+
var DEFAULT_UUIDV7 = /\bdefault\s+uuidv7\s*\(\s*\)/i;
|
|
42
|
+
var TABLE = new RegExp(String.raw`^\s*(?:create\s+table(?:\s+if\s+not\s+exists)?|alter\s+table(?:\s+if\s+exists)?(?:\s+only)?)\s+(?:(?:${IDENT})\.)?(${IDENT})`, "i");
|
|
43
|
+
var COLUMN = new RegExp(String.raw`(${IDENT})\s+(?:uuid\b|set\s+default\b)`, "i");
|
|
44
|
+
function findUuidV7Default(migrations) {
|
|
45
|
+
for (const migration of migrations) {
|
|
46
|
+
for (let stepIndex = 0;stepIndex < migration.steps.length; stepIndex += 1) {
|
|
47
|
+
const sql = migration.steps[stepIndex]?.sql ?? "";
|
|
48
|
+
if (!DEFAULT_UUIDV7.test(sql))
|
|
49
|
+
continue;
|
|
50
|
+
return { migrationId: migration.id, stepIndex, column: columnOf(sql) };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
async function assertUuidV7Available(connection, migrations) {
|
|
56
|
+
const found = findUuidV7Default(migrations);
|
|
57
|
+
if (found === undefined)
|
|
58
|
+
return;
|
|
59
|
+
const result = await connection.execute("select current_setting('server_version_num'), to_regprocedure('uuidv7()')::text");
|
|
60
|
+
const row = result.rows[0];
|
|
61
|
+
const major = Math.floor(Number(row?.[0] ?? "0") / 1e4);
|
|
62
|
+
const defined = row?.[1] !== null && row?.[1] !== undefined;
|
|
63
|
+
if (major >= 18 || defined)
|
|
64
|
+
return;
|
|
65
|
+
const where = found.column === undefined ? "A column" : `Column ${found.column}`;
|
|
66
|
+
throw new OkmError2("OKM1812", `${where} has a uuidv7() default (migration ${found.migrationId}, step ${String(found.stepIndex)}), and the server is PostgreSQL ${String(major)}. uuidv7() arrives in PostgreSQL 18. Nothing was changed.`, {
|
|
67
|
+
fix: {
|
|
68
|
+
summary: 'Either run PostgreSQL 18 and declare schema({ requires: { postgres: ">=18" } }), or use t.id({ default: "uuidv4" }) (or schema({ defaults: { id: "uuidv4" } })), which uses gen_random_uuid() and works on PostgreSQL 13 and newer. Then delete the migration that was not applied and generate it again.'
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function columnOf(sql) {
|
|
73
|
+
const table = TABLE.exec(sql)?.[1];
|
|
74
|
+
if (table === undefined)
|
|
75
|
+
return;
|
|
76
|
+
const line = sql.split(`
|
|
77
|
+
`).find((text) => DEFAULT_UUIDV7.test(text));
|
|
78
|
+
const column = line === undefined ? undefined : COLUMN.exec(line)?.[1];
|
|
79
|
+
if (column === undefined)
|
|
80
|
+
return;
|
|
81
|
+
return `${unquote(table)}.${unquote(column)}`;
|
|
82
|
+
}
|
|
83
|
+
function unquote(name) {
|
|
84
|
+
return name.startsWith('"') ? name.slice(1, -1).replaceAll('""', '"') : name;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/tooling/migrate/apply.ts
|
|
25
88
|
var DEFAULT_LOCK_MS = 5000;
|
|
26
89
|
var DEFAULT_STATEMENT_MS = 30000;
|
|
27
90
|
var DEFAULT_RETRIES = 3;
|
|
@@ -100,6 +163,10 @@ async function applyTarget(request) {
|
|
|
100
163
|
await lockTarget(connection, request.target);
|
|
101
164
|
locked = true;
|
|
102
165
|
request.onLocked?.();
|
|
166
|
+
const session = {};
|
|
167
|
+
await prepareMigrationRole(connection, request, session);
|
|
168
|
+
await assertExtensionsAvailable(connection, request.migrations);
|
|
169
|
+
await assertUuidV7Available(connection, request.migrations);
|
|
103
170
|
await connection.execute(META);
|
|
104
171
|
await connection.execute(HISTORY);
|
|
105
172
|
const done = await readDone(connection);
|
|
@@ -110,13 +177,17 @@ async function applyTarget(request) {
|
|
|
110
177
|
continue;
|
|
111
178
|
for (const unit of units) {
|
|
112
179
|
assertUnitPolicy(request, unit);
|
|
113
|
-
await runUnit(connection, unit, request);
|
|
180
|
+
await runUnit(connection, unit, request, session);
|
|
114
181
|
for (const item of unit.steps)
|
|
115
182
|
done.add(`${unit.migrationId}:${String(item.index)}`);
|
|
116
183
|
}
|
|
117
184
|
applied.push(migration.id);
|
|
118
185
|
}
|
|
119
|
-
return {
|
|
186
|
+
return {
|
|
187
|
+
target: request.target,
|
|
188
|
+
applied,
|
|
189
|
+
...session.setRole !== undefined ? { setRole: session.setRole } : {}
|
|
190
|
+
};
|
|
120
191
|
} finally {
|
|
121
192
|
if (locked)
|
|
122
193
|
await connection.execute("select pg_advisory_unlock(hashtext($1))", [
|
|
@@ -142,7 +213,8 @@ nothing to apply
|
|
|
142
213
|
allowPooler: flags.allowPooler || config.allowPooler === true,
|
|
143
214
|
...flags.lockTimeoutMs !== undefined ? { lockTimeoutMs: flags.lockTimeoutMs } : config.timeouts?.lock !== undefined ? { lockTimeoutMs: config.timeouts.lock } : {},
|
|
144
215
|
...flags.statementTimeoutMs !== undefined ? { statementTimeoutMs: flags.statementTimeoutMs } : config.timeouts?.statement !== undefined ? { statementTimeoutMs: config.timeouts.statement } : {},
|
|
145
|
-
migrations
|
|
216
|
+
migrations,
|
|
217
|
+
...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
|
|
146
218
|
});
|
|
147
219
|
return formatReport(report);
|
|
148
220
|
}
|
|
@@ -173,17 +245,20 @@ no changes
|
|
|
173
245
|
catalogHash: catalogHash2(head.catalog),
|
|
174
246
|
steps: plan.steps
|
|
175
247
|
}
|
|
176
|
-
]
|
|
248
|
+
],
|
|
249
|
+
...config.roles !== undefined ? { migrationRole: config.roles.migration } : {}
|
|
177
250
|
});
|
|
178
251
|
return formatReport(report);
|
|
179
252
|
}
|
|
180
253
|
function formatReport(report) {
|
|
254
|
+
const role = report.setRole !== undefined ? `set role ${report.setRole}
|
|
255
|
+
` : "";
|
|
181
256
|
if (report.applied.length === 0)
|
|
182
257
|
return `target ${report.target}
|
|
183
|
-
nothing to apply
|
|
258
|
+
${role}nothing to apply
|
|
184
259
|
`;
|
|
185
260
|
return `target ${report.target}
|
|
186
|
-
${report.applied.map((id) => `applied ${id}`).join(`
|
|
261
|
+
${role}${report.applied.map((id) => `applied ${id}`).join(`
|
|
187
262
|
`)}
|
|
188
263
|
`;
|
|
189
264
|
}
|
|
@@ -237,7 +312,31 @@ async function readDone(connection) {
|
|
|
237
312
|
}
|
|
238
313
|
return done;
|
|
239
314
|
}
|
|
240
|
-
async function
|
|
315
|
+
async function prepareMigrationRole(connection, request, session) {
|
|
316
|
+
const role = request.migrationRole;
|
|
317
|
+
const changes = request.migrations.some((migration) => migration.steps.some((step) => changesRole(step.sql)));
|
|
318
|
+
if (role === undefined) {
|
|
319
|
+
if (changes)
|
|
320
|
+
await assertCreateRole(connection, await currentUser(connection));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const current = await currentUser(connection);
|
|
324
|
+
const exists = await roleExists(connection, role);
|
|
325
|
+
if (changes)
|
|
326
|
+
await assertCreateRole(connection, exists && current !== role ? role : current);
|
|
327
|
+
if (exists && current !== role)
|
|
328
|
+
await assumeRole(connection, role, session);
|
|
329
|
+
}
|
|
330
|
+
async function grantSchema(connection, schema, role) {
|
|
331
|
+
await connection.execute(`grant usage, create on schema ${quoteIdent(schema)} to ${quoteIdent(role)}`);
|
|
332
|
+
}
|
|
333
|
+
async function assumeRole(connection, role, session) {
|
|
334
|
+
if (session.setRole === role)
|
|
335
|
+
return;
|
|
336
|
+
await connection.execute(`set role ${quoteIdent(role)}`);
|
|
337
|
+
session.setRole = role;
|
|
338
|
+
}
|
|
339
|
+
async function runUnit(connection, unit, request, session) {
|
|
241
340
|
const retries = request.retries ?? DEFAULT_RETRIES;
|
|
242
341
|
for (let attempt = 0;attempt <= retries; attempt += 1) {
|
|
243
342
|
let began = false;
|
|
@@ -250,7 +349,17 @@ async function runUnit(connection, unit, request) {
|
|
|
250
349
|
for (const item of unit.steps) {
|
|
251
350
|
current = item.index;
|
|
252
351
|
await rebuildInvalidIndex(connection, item.step.sql);
|
|
253
|
-
|
|
352
|
+
const created = createdRoleName(item.step.sql);
|
|
353
|
+
const existed = created !== undefined && await roleExists(connection, created);
|
|
354
|
+
if (created === undefined || !existed)
|
|
355
|
+
await connection.execute(item.step.sql);
|
|
356
|
+
if (created !== undefined && created === request.migrationRole) {
|
|
357
|
+
if (!existed) {
|
|
358
|
+
await grantSchema(connection, request.schema ?? "public", created);
|
|
359
|
+
await connection.execute(`grant select, insert, update on okm_meta, okm_history to ${quoteIdent(created)}`);
|
|
360
|
+
}
|
|
361
|
+
await assumeRole(connection, created, session);
|
|
362
|
+
}
|
|
254
363
|
if (!unit.transactional) {
|
|
255
364
|
await connection.execute("begin");
|
|
256
365
|
began = true;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodeText,
|
|
3
|
+
decodeText
|
|
4
|
+
} from "./4m9fn52z.js";
|
|
5
|
+
import {
|
|
6
|
+
required,
|
|
7
|
+
openColumn
|
|
8
|
+
} from "./c9z5g0fm.js";
|
|
9
|
+
import {
|
|
10
|
+
definition,
|
|
11
|
+
rejected
|
|
12
|
+
} from "./tmbdywx0.js";
|
|
13
|
+
import {
|
|
14
|
+
readClientGenerator
|
|
15
|
+
} from "./rwmrejjz.js";
|
|
16
|
+
|
|
17
|
+
// src/dialects/pg/keys.ts
|
|
18
|
+
function id2(options) {
|
|
19
|
+
const chosen = options?.default;
|
|
20
|
+
const client = typeof chosen === "function" ? readClientGenerator(chosen) : undefined;
|
|
21
|
+
const okid = client?.name === "okid";
|
|
22
|
+
const supplied = chosen === "none";
|
|
23
|
+
if (client === undefined && chosen !== undefined && chosen !== "uuidv7" && chosen !== "uuidv4" && chosen !== "none") {
|
|
24
|
+
definition(`id() default ${String(chosen)} must be uuidv7, uuidv4, none, or a client generator.`);
|
|
25
|
+
}
|
|
26
|
+
return openColumn({
|
|
27
|
+
baseType: okid ? "text" : "uuid",
|
|
28
|
+
nullable: false,
|
|
29
|
+
hasDefault: client !== undefined || !supplied,
|
|
30
|
+
generated: false,
|
|
31
|
+
guarded: client !== undefined || !supplied,
|
|
32
|
+
hidden: false,
|
|
33
|
+
omitWrite: client !== undefined || !supplied,
|
|
34
|
+
omitUpdate: true,
|
|
35
|
+
...client !== undefined ? { clientDefault: client } : {},
|
|
36
|
+
...okid ? { collation: "C" } : {},
|
|
37
|
+
idSource: chosen === undefined ? "implicit" : "column",
|
|
38
|
+
...client === undefined && !supplied ? { defaultSql: chosen === "uuidv4" ? "gen_random_uuid()" : "uuidv7()" } : {},
|
|
39
|
+
primaryKey: true,
|
|
40
|
+
encode: okid ? encodeText : encodeUuid,
|
|
41
|
+
decode: okid ? decodeText : decodeUuid,
|
|
42
|
+
sqlForm: "quote"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function uuid2() {
|
|
46
|
+
return required({
|
|
47
|
+
baseType: "uuid",
|
|
48
|
+
encode: encodeUuid,
|
|
49
|
+
decode: decodeUuid,
|
|
50
|
+
sqlForm: "quote"
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function encodeUuid(value) {
|
|
54
|
+
const text = value.toLowerCase();
|
|
55
|
+
if (!uuidText().test(text)) {
|
|
56
|
+
rejected(`uuid ${value} must be 8-4-4-4-12 hexadecimal digits, for example 01890c5a-8f0e-7c3a-9b2d-6e4f1a0b9c8d.`);
|
|
57
|
+
}
|
|
58
|
+
return text;
|
|
59
|
+
}
|
|
60
|
+
function decodeUuid(wire) {
|
|
61
|
+
return encodeUuid(wire);
|
|
62
|
+
}
|
|
63
|
+
function uuidText() {
|
|
64
|
+
uuidPattern ??= /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
65
|
+
return uuidPattern;
|
|
66
|
+
}
|
|
67
|
+
var uuidPattern;
|
|
68
|
+
|
|
69
|
+
export { id2, uuid2, encodeUuid, decodeUuid };
|