@browserlessapi/inferlo 0.0.0-stage → 0.4.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/LICENSE +21 -0
- package/README.md +130 -2
- package/dist/ai/index.d.ts +138 -0
- package/dist/ai/index.js +450 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/providers.d.ts +150 -0
- package/dist/ai/providers.js +294 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/app.d.ts +109 -0
- package/dist/app.js +419 -0
- package/dist/app.js.map +1 -0
- package/dist/auth.d.ts +29 -0
- package/dist/auth.js +61 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/client-ip.d.ts +7 -0
- package/dist/client-ip.js +27 -0
- package/dist/client-ip.js.map +1 -0
- package/dist/cron.d.ts +17 -0
- package/dist/cron.js +143 -0
- package/dist/cron.js.map +1 -0
- package/dist/db/memory.d.ts +2 -0
- package/dist/db/memory.js +128 -0
- package/dist/db/memory.js.map +1 -0
- package/dist/db/migrate.d.ts +87 -0
- package/dist/db/migrate.js +471 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/postgres.d.ts +37 -0
- package/dist/db/postgres.js +338 -0
- package/dist/db/postgres.js.map +1 -0
- package/dist/db/table.d.ts +117 -0
- package/dist/db/table.js +274 -0
- package/dist/db/table.js.map +1 -0
- package/dist/db/types.d.ts +36 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/describe.d.ts +74 -0
- package/dist/describe.js +69 -0
- package/dist/describe.js.map +1 -0
- package/dist/env.d.ts +19 -0
- package/dist/env.js +72 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +40 -0
- package/dist/errors.js +99 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs.d.ts +177 -0
- package/dist/jobs.js +374 -0
- package/dist/jobs.js.map +1 -0
- package/dist/mcp.d.ts +22 -0
- package/dist/mcp.js +171 -0
- package/dist/mcp.js.map +1 -0
- package/dist/model.d.ts +36 -0
- package/dist/model.js +76 -0
- package/dist/model.js.map +1 -0
- package/dist/openapi.d.ts +6 -0
- package/dist/openapi.js +74 -0
- package/dist/openapi.js.map +1 -0
- package/dist/rate-limit.d.ts +45 -0
- package/dist/rate-limit.js +93 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/route.d.ts +131 -0
- package/dist/route.js +28 -0
- package/dist/route.js.map +1 -0
- package/dist/schema.d.ts +164 -0
- package/dist/schema.js +442 -0
- package/dist/schema.js.map +1 -0
- package/dist/serve.d.ts +11 -0
- package/dist/serve.js +86 -0
- package/dist/serve.js.map +1 -0
- package/dist/testing.d.ts +16 -0
- package/dist/testing.js +30 -0
- package/dist/testing.js.map +1 -0
- package/llms.txt +27 -0
- package/package.json +82 -4
- package/templates/app/AGENTS.md +55 -0
- package/templates/app/CLAUDE.md +1 -0
- package/templates/app/README.md +16 -0
- package/templates/app/_env.example +5 -0
- package/templates/app/_gitignore +3 -0
- package/templates/app/package.json.tpl +32 -0
- package/templates/app/src/app.ts +38 -0
- package/templates/app/src/models.ts +31 -0
- package/templates/app/src/routes/health.ts +3 -0
- package/templates/app/src/routes/notes.ts +56 -0
- package/templates/app/src/server.ts +26 -0
- package/templates/app/test/notes.test.ts +50 -0
- package/templates/app/tsconfig.json +17 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versioned SQL migrations (PostgreSQL).
|
|
3
|
+
*
|
|
4
|
+
* inferlo db migrate add_due_dates # writes migrations/0002_add_due_dates.sql
|
|
5
|
+
* inferlo db migrate --apply # runs pending files, recorded in "inferlo_migrations"
|
|
6
|
+
*
|
|
7
|
+
* planMigration compares your models with migrations/snapshot.json (the models as of the last
|
|
8
|
+
* generated migration) and returns the SQL for the difference. Additive changes are generated
|
|
9
|
+
* directly. Drops of tables, columns and indexes delete data, so they are refused with IL4017
|
|
10
|
+
* unless you pass { allowDrop: true } (inferlo db migrate --allow-drop). Type, default, required and
|
|
11
|
+
* enum value changes are refused with IL4019 unless you pass { allowChange: true } (--allow-change).
|
|
12
|
+
* Renames and reference changes are refused with IL4013, so nothing is lost silently. Snapshots in the
|
|
13
|
+
* 0.2.0 format (inferlo: 1) are read and upgraded; plans always return the current format (inferlo: 2).
|
|
14
|
+
*/
|
|
15
|
+
import { InferloError } from "../errors.js";
|
|
16
|
+
import { columnName } from "../model.js";
|
|
17
|
+
import { columnDefinition, columnType, createTableSql, defaultSql, modelIndexes, sortByReferences, SYSTEM_COLUMNS } from "./postgres.js";
|
|
18
|
+
const q = (identifier) => `"${identifier.replace(/"/g, '""')}"`;
|
|
19
|
+
function columnSnapshot(schema) {
|
|
20
|
+
const d = schema.def;
|
|
21
|
+
const column = { type: columnType(schema), notNull: !d.optional && !d.nullable && d.kind !== "any" };
|
|
22
|
+
const fixedDefault = defaultSql(schema);
|
|
23
|
+
if (fixedDefault !== undefined)
|
|
24
|
+
column.default = fixedDefault;
|
|
25
|
+
if (d.kind === "enum" && d.values)
|
|
26
|
+
column.enum = d.values.map(String);
|
|
27
|
+
if (d.kind === "ref" && d.refTable)
|
|
28
|
+
column.references = { table: d.refTable, onDelete: d.onDelete ?? "restrict" };
|
|
29
|
+
return column;
|
|
30
|
+
}
|
|
31
|
+
function tableSnapshot(model) {
|
|
32
|
+
const columns = Object.fromEntries(SYSTEM_COLUMNS.map(([column, sql]) => [column, parseColumnSql(sql)]));
|
|
33
|
+
for (const [field, schema] of Object.entries(model.fields))
|
|
34
|
+
columns[columnName(field)] = columnSnapshot(schema);
|
|
35
|
+
return { columns, indexes: Object.fromEntries(modelIndexes(model)) };
|
|
36
|
+
}
|
|
37
|
+
const IDENT = `"(?:[^"]|"")*"`;
|
|
38
|
+
const STRING = `'(?:[^']|'')*'`;
|
|
39
|
+
const unquote = (s) => s.slice(1, -1).replace(/''/g, "'");
|
|
40
|
+
/**
|
|
41
|
+
* Parse a column definition as written by Inferlo 0.2.0 (columnDefinition) into its structured form.
|
|
42
|
+
* Returns undefined for anything else.
|
|
43
|
+
*/
|
|
44
|
+
function parseColumnSql(sql) {
|
|
45
|
+
const head = new RegExp(`^${IDENT} (double precision|varchar\\(\\d+\\)|[a-z]+)`).exec(sql);
|
|
46
|
+
if (!head)
|
|
47
|
+
return undefined;
|
|
48
|
+
const column = { type: head[1], notNull: false };
|
|
49
|
+
let rest = sql.slice(head[0].length);
|
|
50
|
+
const clauses = [
|
|
51
|
+
[/^ PRIMARY KEY/, () => ((column.primaryKey = true), (column.notNull = true))],
|
|
52
|
+
[/^ NOT NULL/, () => (column.notNull = true)],
|
|
53
|
+
[new RegExp(`^ DEFAULT (${STRING}(?:::jsonb)?|now\\(\\)|true|false|-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?)`), (m) => (column.default = m[1])],
|
|
54
|
+
[
|
|
55
|
+
new RegExp(`^ CHECK \\(${IDENT} IN \\((${STRING}(?:, ${STRING})*)\\)\\)`),
|
|
56
|
+
(m) => (column.enum = (m[1].match(new RegExp(STRING, "g")) ?? []).map(unquote)),
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
new RegExp(`^ REFERENCES (${IDENT})\\("id"\\) ON DELETE (RESTRICT|CASCADE|SET NULL)`),
|
|
60
|
+
(m) => (column.references = { table: m[1].slice(1, -1).replace(/""/g, '"'), onDelete: m[2].toLowerCase() }),
|
|
61
|
+
],
|
|
62
|
+
];
|
|
63
|
+
while (rest) {
|
|
64
|
+
const clause = clauses.map(([re, apply]) => [re.exec(rest), apply]).find(([m]) => m);
|
|
65
|
+
if (!clause)
|
|
66
|
+
return undefined;
|
|
67
|
+
clause[1](clause[0]);
|
|
68
|
+
rest = rest.slice(clause[0][0].length);
|
|
69
|
+
}
|
|
70
|
+
// Keep the same key order as columnSnapshot, so upgraded snapshots look like fresh ones.
|
|
71
|
+
const { type, notNull, default: fixedDefault, enum: values, references, primaryKey } = column;
|
|
72
|
+
return {
|
|
73
|
+
type,
|
|
74
|
+
notNull,
|
|
75
|
+
...(fixedDefault !== undefined && { default: fixedDefault }),
|
|
76
|
+
...(values && { enum: values }),
|
|
77
|
+
...(references && { references }),
|
|
78
|
+
...(primaryKey && { primaryKey }),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function needsValue(schema) {
|
|
82
|
+
const d = schema.def;
|
|
83
|
+
return !d.optional && !d.nullable && d.kind !== "any" && !(d.hasDefault && typeof d.defaultValue !== "function");
|
|
84
|
+
}
|
|
85
|
+
function invalidSnapshot(fix = "migrations/snapshot.json must be the file written by inferlo db migrate. Restore it from version control; do not edit it by hand.") {
|
|
86
|
+
throw new InferloError("IL4015", "The migration snapshot is not valid.", { fix, expose: true });
|
|
87
|
+
}
|
|
88
|
+
const isRecord = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
89
|
+
function isColumn(c) {
|
|
90
|
+
return (isRecord(c) &&
|
|
91
|
+
typeof c.type === "string" &&
|
|
92
|
+
typeof c.notNull === "boolean" &&
|
|
93
|
+
(c.default === undefined || typeof c.default === "string") &&
|
|
94
|
+
(c.enum === undefined || (Array.isArray(c.enum) && c.enum.every((v) => typeof v === "string"))) &&
|
|
95
|
+
(c.references === undefined || (isRecord(c.references) && typeof c.references.table === "string" && typeof c.references.onDelete === "string")));
|
|
96
|
+
}
|
|
97
|
+
/** Validate a snapshot and return it in the current (inferlo: 2) format. */
|
|
98
|
+
function readSnapshot(input) {
|
|
99
|
+
// Snapshots written before the rename from Kairo use the key "kairo" instead of "inferlo".
|
|
100
|
+
const previous = isRecord(input) && input.inferlo === undefined && "kairo" in input ? { ...input, inferlo: input["kairo"] } : input;
|
|
101
|
+
if (!isRecord(previous) || (previous.inferlo !== 1 && previous.inferlo !== 2) || !isRecord(previous.tables))
|
|
102
|
+
invalidSnapshot();
|
|
103
|
+
const tables = {};
|
|
104
|
+
for (const [name, table] of Object.entries(previous.tables)) {
|
|
105
|
+
if (!isRecord(table) || !isRecord(table.columns) || !isRecord(table.indexes))
|
|
106
|
+
invalidSnapshot();
|
|
107
|
+
const columns = {};
|
|
108
|
+
for (const [column, value] of Object.entries(table.columns)) {
|
|
109
|
+
const parsed = previous.inferlo === 1 ? (typeof value === "string" ? parseColumnSql(value) : undefined) : isColumn(value) ? value : undefined;
|
|
110
|
+
if (!parsed) {
|
|
111
|
+
invalidSnapshot(`Column ${name}.${column} in migrations/snapshot.json is not in the format inferlo db migrate writes. Restore the file from version control; do not edit it by hand.`);
|
|
112
|
+
}
|
|
113
|
+
columns[column] = parsed;
|
|
114
|
+
}
|
|
115
|
+
tables[name] = { columns, indexes: table.indexes };
|
|
116
|
+
}
|
|
117
|
+
return { inferlo: 2, tables };
|
|
118
|
+
}
|
|
119
|
+
/** Plain descriptions of what differs between two versions of a column, e.g. "type text -> varchar(80)". */
|
|
120
|
+
function columnChanges(before, now) {
|
|
121
|
+
const out = [];
|
|
122
|
+
const ref = (r) => (r ? `${r.table} on delete ${r.onDelete}` : "none");
|
|
123
|
+
const values = (v) => (v ? v.map((x) => `'${x.replace(/'/g, "''")}'`).join(", ") : "none");
|
|
124
|
+
if (before.type !== now.type)
|
|
125
|
+
out.push(`type ${before.type} -> ${now.type}`);
|
|
126
|
+
if (before.notNull !== now.notNull)
|
|
127
|
+
out.push(before.notNull ? "required -> optional" : "optional -> required");
|
|
128
|
+
if (before.default !== now.default)
|
|
129
|
+
out.push(`default ${before.default ?? "none"} -> ${now.default ?? "none"}`);
|
|
130
|
+
if (values(before.enum) !== values(now.enum))
|
|
131
|
+
out.push(`enum values ${values(before.enum)} -> ${values(now.enum)}`);
|
|
132
|
+
if (ref(before.references) !== ref(now.references))
|
|
133
|
+
out.push(`reference ${ref(before.references)} -> ${ref(now.references)}`);
|
|
134
|
+
if (Boolean(before.primaryKey) !== Boolean(now.primaryKey))
|
|
135
|
+
out.push(before.primaryKey ? "primary key -> none" : "none -> primary key");
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
/** Changes planMigration can generate with allowChange: only the type, default, required/optional and enum values differ. */
|
|
139
|
+
function isAlterable(before, now) {
|
|
140
|
+
return columnChanges({ ...before, type: now.type, notNull: now.notNull, default: now.default, enum: now.enum }, now).length === 0;
|
|
141
|
+
}
|
|
142
|
+
const isString = (type) => type === "text" || type.startsWith("varchar(");
|
|
143
|
+
/**
|
|
144
|
+
* The USING clause for ALTER COLUMN ... TYPE, or "" when Postgres converts the values itself.
|
|
145
|
+
* Every conversion is strict: a value that does not fit fails the migration (IL4022) instead of
|
|
146
|
+
* being cut, rounded or set to NULL.
|
|
147
|
+
* - to text or varchar(n): no USING (too long values fail, they are not cut);
|
|
148
|
+
* - integer to double precision: no USING;
|
|
149
|
+
* - from jsonb: the JSON value's text ("hello", not "\"hello\""), then converted;
|
|
150
|
+
* - to jsonb: to_jsonb(value), so text becomes a JSON string;
|
|
151
|
+
* - boolean to integer or double precision: true is 1, false is 0;
|
|
152
|
+
* - anything else goes through the value's text, so 2.5 does not become the integer 3.
|
|
153
|
+
*/
|
|
154
|
+
function usingSql(column, from, to) {
|
|
155
|
+
const c = q(column);
|
|
156
|
+
if (to === "jsonb")
|
|
157
|
+
return ` USING to_jsonb(${c})`;
|
|
158
|
+
if (from === "jsonb")
|
|
159
|
+
return isString(to) ? ` USING ${c} #>> '{}'` : ` USING (${c} #>> '{}')::${to}`;
|
|
160
|
+
if (isString(to))
|
|
161
|
+
return "";
|
|
162
|
+
if (from === "integer" && to === "double precision")
|
|
163
|
+
return "";
|
|
164
|
+
if (from === "boolean" && to === "integer")
|
|
165
|
+
return ` USING ${c}::integer`;
|
|
166
|
+
if (from === "boolean" && to === "double precision")
|
|
167
|
+
return ` USING ${c}::integer::double precision`;
|
|
168
|
+
return ` USING ${c}::text::${to}`;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The name Postgres gives the CHECK constraint of an enum column (written inline in the column
|
|
172
|
+
* definition): "<table>_<column>_check", with table and column shortened so it fits in 63 bytes,
|
|
173
|
+
* the same way Postgres shortens it (makeObjectName: trim the longer part one byte at a time).
|
|
174
|
+
*/
|
|
175
|
+
function checkConstraintName(table, column) {
|
|
176
|
+
const encoder = new TextEncoder();
|
|
177
|
+
const a = encoder.encode(table);
|
|
178
|
+
const b = encoder.encode(column);
|
|
179
|
+
let n1 = a.length;
|
|
180
|
+
let n2 = b.length;
|
|
181
|
+
const available = 63 - "_".length - "_check".length;
|
|
182
|
+
while (n1 + n2 > available) {
|
|
183
|
+
if (n1 > n2)
|
|
184
|
+
n1--;
|
|
185
|
+
else
|
|
186
|
+
n2--;
|
|
187
|
+
}
|
|
188
|
+
// Never cut a multi-byte character in half (pg_mbcliplen).
|
|
189
|
+
const clip = (bytes, n) => {
|
|
190
|
+
while (n > 0 && n < bytes.length && (bytes[n] & 0xc0) === 0x80)
|
|
191
|
+
n--;
|
|
192
|
+
return new TextDecoder().decode(bytes.subarray(0, n));
|
|
193
|
+
};
|
|
194
|
+
return `${clip(a, n1)}_${clip(b, n2)}_check`;
|
|
195
|
+
}
|
|
196
|
+
/** ALTER statements for a type, default, required/optional and enum value change (see isAlterable). */
|
|
197
|
+
function alterColumnSql(table, column, before, now) {
|
|
198
|
+
const alter = `ALTER TABLE ${q(table)} ALTER COLUMN ${q(column)}`;
|
|
199
|
+
const out = [];
|
|
200
|
+
const enumChanged = JSON.stringify(before.enum) !== JSON.stringify(now.enum);
|
|
201
|
+
const typeChanged = before.type !== now.type;
|
|
202
|
+
const check = q(checkConstraintName(table, column));
|
|
203
|
+
// The old constraint goes first, so filling NULL rows with a new enum default is allowed.
|
|
204
|
+
// No IF EXISTS: if the constraint has another name, the migration fails instead of keeping it.
|
|
205
|
+
if (enumChanged && before.enum)
|
|
206
|
+
out.push(`ALTER TABLE ${q(table)} DROP CONSTRAINT ${check}`);
|
|
207
|
+
if (before.notNull && !now.notNull)
|
|
208
|
+
out.push(`${alter} DROP NOT NULL`);
|
|
209
|
+
if (typeChanged) {
|
|
210
|
+
// Postgres does not convert a default together with the values, so the old default goes
|
|
211
|
+
// first and the new one is set after the type change.
|
|
212
|
+
if (before.default !== undefined)
|
|
213
|
+
out.push(`${alter} DROP DEFAULT`);
|
|
214
|
+
out.push(`${alter} TYPE ${now.type}${usingSql(column, before.type, now.type)}`);
|
|
215
|
+
if (now.default !== undefined)
|
|
216
|
+
out.push(`${alter} SET DEFAULT ${now.default}`);
|
|
217
|
+
}
|
|
218
|
+
else if (before.default !== now.default)
|
|
219
|
+
out.push(now.default === undefined ? `${alter} DROP DEFAULT` : `${alter} SET DEFAULT ${now.default}`);
|
|
220
|
+
if (!before.notNull && now.notNull) {
|
|
221
|
+
// Same as adding a required column with a default: existing rows get the default.
|
|
222
|
+
if (now.default !== undefined)
|
|
223
|
+
out.push(`UPDATE ${q(table)} SET ${q(column)} = ${now.default} WHERE ${q(column)} IS NULL`);
|
|
224
|
+
out.push(`${alter} SET NOT NULL`);
|
|
225
|
+
}
|
|
226
|
+
if (enumChanged && now.enum) {
|
|
227
|
+
const values = now.enum.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
|
|
228
|
+
out.push(`ALTER TABLE ${q(table)} ADD CONSTRAINT ${check} CHECK (${q(column)} IN (${values}))`);
|
|
229
|
+
}
|
|
230
|
+
return out;
|
|
231
|
+
}
|
|
232
|
+
/** SQL to bring the database from `previous` (or an empty database) to `models`. */
|
|
233
|
+
export function planMigration(models, previous, options = {}) {
|
|
234
|
+
const before = previous === undefined ? {} : readSnapshot(previous).tables;
|
|
235
|
+
const sorted = sortByReferences([...models]);
|
|
236
|
+
const snapshot = { inferlo: 2, tables: {} };
|
|
237
|
+
const statements = [];
|
|
238
|
+
const refused = [];
|
|
239
|
+
const changedColumns = [];
|
|
240
|
+
const drops = [];
|
|
241
|
+
const alterable = [];
|
|
242
|
+
const needDefault = [];
|
|
243
|
+
for (const model of sorted) {
|
|
244
|
+
const now = tableSnapshot(model);
|
|
245
|
+
snapshot.tables[model.name] = now;
|
|
246
|
+
const old = before[model.name];
|
|
247
|
+
if (!old) {
|
|
248
|
+
statements.push(...createTableSql(model));
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const dropIndexes = [];
|
|
252
|
+
const dropColumns = [];
|
|
253
|
+
const alterStatements = [];
|
|
254
|
+
for (const [column, description] of Object.entries(old.columns)) {
|
|
255
|
+
if (!(column in now.columns)) {
|
|
256
|
+
drops.push(`drop column ${model.name}.${column}`);
|
|
257
|
+
dropColumns.push(`ALTER TABLE ${q(model.name)} DROP COLUMN IF EXISTS ${q(column)}`);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const current = now.columns[column];
|
|
261
|
+
const changes = columnChanges(description, current);
|
|
262
|
+
if (!changes.length)
|
|
263
|
+
continue;
|
|
264
|
+
if (isAlterable(description, current)) {
|
|
265
|
+
alterable.push({ table: model.name, column, changes });
|
|
266
|
+
alterStatements.push(...alterColumnSql(model.name, column, description, current));
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
refused.push(`change column ${model.name}.${column}`);
|
|
270
|
+
changedColumns.push({ table: model.name, column, changes });
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
for (const [name, sql] of Object.entries(old.indexes)) {
|
|
274
|
+
if (!(name in now.indexes)) {
|
|
275
|
+
drops.push(`drop index ${name}`);
|
|
276
|
+
dropIndexes.push(`DROP INDEX IF EXISTS ${q(name)}`);
|
|
277
|
+
}
|
|
278
|
+
else if (now.indexes[name] !== sql)
|
|
279
|
+
refused.push(`change index ${name}`);
|
|
280
|
+
}
|
|
281
|
+
statements.push(...dropIndexes, ...dropColumns, ...alterStatements);
|
|
282
|
+
for (const [field, schema] of Object.entries(model.fields)) {
|
|
283
|
+
const column = columnName(field);
|
|
284
|
+
if (column in old.columns)
|
|
285
|
+
continue;
|
|
286
|
+
if (needsValue(schema))
|
|
287
|
+
needDefault.push(`${model.name}.${column}`);
|
|
288
|
+
statements.push(`ALTER TABLE ${q(model.name)} ADD COLUMN IF NOT EXISTS ${columnDefinition(model, field, schema)}`);
|
|
289
|
+
}
|
|
290
|
+
for (const [name, sql] of Object.entries(now.indexes))
|
|
291
|
+
if (!(name in old.indexes))
|
|
292
|
+
statements.push(sql);
|
|
293
|
+
}
|
|
294
|
+
const droppedTables = Object.keys(before).filter((table) => !(table in snapshot.tables));
|
|
295
|
+
if (droppedTables.length) {
|
|
296
|
+
drops.push(...droppedTables.map((table) => `drop table ${table}`));
|
|
297
|
+
// One statement, so foreign keys between the dropped tables do not matter. No CASCADE:
|
|
298
|
+
// if anything else still depends on a table, the migration fails instead of dropping more.
|
|
299
|
+
statements.push(`DROP TABLE IF EXISTS ${droppedTables.map(q).join(", ")}`);
|
|
300
|
+
}
|
|
301
|
+
if (refused.length) {
|
|
302
|
+
const explained = refused.map((change) => {
|
|
303
|
+
const column = changedColumns.find((c) => change === `change column ${c.table}.${c.column}`);
|
|
304
|
+
return column ? `${change} (${column.changes.join(", ")})` : change;
|
|
305
|
+
});
|
|
306
|
+
throw new InferloError("IL4013", `inferlo db migrate cannot generate these changes yet: ${explained.join(", ")}.`, {
|
|
307
|
+
fix: "New tables, columns and indexes, drops with --allow-drop, and type, default, required and enum value changes with --allow-change are generated. Renames, reference and index changes are not yet: undo these model changes, or write the SQL yourself in a new migration file.",
|
|
308
|
+
details: { changes: refused, columns: changedColumns },
|
|
309
|
+
expose: true,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
if (drops.length && !options.allowDrop) {
|
|
313
|
+
throw new InferloError("IL4017", `Your model changes drop data: ${drops.join(", ")}.`, {
|
|
314
|
+
fix: "If you mean to delete this data, run inferlo db migrate --allow-drop (or planMigration(models, snapshot, { allowDrop: true })) and review the file. Otherwise restore the removed models, fields or indexes.",
|
|
315
|
+
details: { drops },
|
|
316
|
+
expose: true,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
const changes = alterable.map((c) => `change column ${c.table}.${c.column} (${c.changes.join(", ")})`);
|
|
320
|
+
if (changes.length && !options.allowChange) {
|
|
321
|
+
throw new InferloError("IL4019", `Your model changes change existing columns: ${changes.join(", ")}.`, {
|
|
322
|
+
fix: "If you mean to change these columns, run inferlo db migrate --allow-change (or planMigration(models, snapshot, { allowChange: true })) and review the file. Changing the type fails if an existing value does not convert. Making a column required fails if rows still have NULL in it, unless the field has a fixed .default(value). Removing an enum value fails if rows still use it. Otherwise undo the model changes.",
|
|
323
|
+
details: { changes, columns: alterable },
|
|
324
|
+
expose: true,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (needDefault.length) {
|
|
328
|
+
throw new InferloError("IL4014", `New required column${needDefault.length > 1 ? "s" : ""} ${needDefault.join(", ")} on an existing table need a value for existing rows.`, {
|
|
329
|
+
fix: 'Add .default(value) (a fixed value, not a function) or .optional() to the field, e.g. status: t.enum(["open", "closed"]).default("open").',
|
|
330
|
+
details: { columns: needDefault },
|
|
331
|
+
expose: true,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
return { statements, snapshot, drops, changes };
|
|
335
|
+
}
|
|
336
|
+
const MIGRATION_NAME = /^[A-Za-z0-9_-]{1,200}$/;
|
|
337
|
+
const LOCK_KEY = 4_812_330_227;
|
|
338
|
+
/** SHA-256 of the SQL as hex, with Windows line endings normalised so a checkout does not count as an edit. */
|
|
339
|
+
async function checksum(sql) {
|
|
340
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(sql.replace(/\r\n/g, "\n")));
|
|
341
|
+
return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, "0")).join("");
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* IL4020 for a Postgres not-null violation (23502), for example SET NOT NULL on a column that still
|
|
345
|
+
* has NULL rows. Undefined for any other error.
|
|
346
|
+
*/
|
|
347
|
+
function nullRowsError(error, migration) {
|
|
348
|
+
const e = error;
|
|
349
|
+
if (!e || e.code !== "23502")
|
|
350
|
+
return undefined;
|
|
351
|
+
const match = /column "((?:[^"]|"")+)" of relation "((?:[^"]|"")+)"/.exec(e.message ?? "");
|
|
352
|
+
const table = e.table ?? match?.[2];
|
|
353
|
+
const column = e.column ?? match?.[1];
|
|
354
|
+
const where = table && column ? `${table}.${column}` : "a required column";
|
|
355
|
+
const update = table && column ? `UPDATE ${q(table)} SET ${q(column)} = <value> WHERE ${q(column)} IS NULL` : "UPDATE <table> SET <column> = <value> WHERE <column> IS NULL";
|
|
356
|
+
return new InferloError("IL4020", `Migration ${migration} failed: ${where} is required (NOT NULL) but rows have NULL in it.`, {
|
|
357
|
+
fix: `Fill the NULL rows first: if ${migration} has not been applied anywhere, add ${update}; before the SET NOT NULL statement, or give the field a fixed .default(value) and regenerate the migration. Or keep the field optional.`,
|
|
358
|
+
details: { migration, table, column },
|
|
359
|
+
cause: error,
|
|
360
|
+
expose: true,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* IL4021 for a Postgres check violation (23514), for example adding an enum's CHECK constraint while
|
|
365
|
+
* rows still use a removed value. Undefined for any other error.
|
|
366
|
+
*/
|
|
367
|
+
function checkViolationError(error, migration) {
|
|
368
|
+
const e = error;
|
|
369
|
+
if (!e || e.code !== "23514")
|
|
370
|
+
return undefined;
|
|
371
|
+
const match = /constraint "((?:[^"]|"")+)" of relation "((?:[^"]|"")+)"/.exec(e.message ?? "");
|
|
372
|
+
const table = e.table ?? match?.[2];
|
|
373
|
+
const constraint = e.constraint ?? match?.[1];
|
|
374
|
+
const where = table ? `rows in ${table}` : "rows";
|
|
375
|
+
return new InferloError("IL4021", `Migration ${migration} failed: ${where} have values that ${constraint ? `the check constraint ${constraint}` : "a check constraint"} does not allow, for example an enum value that was removed.`, {
|
|
376
|
+
fix: `Change those rows to an allowed value first: if ${migration} has not been applied anywhere, add UPDATE ${table ? q(table) : "<table>"} SET <column> = '<new value>' WHERE <column> = '<removed value>'; before the ADD CONSTRAINT statement. Or keep the removed enum value in the model.`,
|
|
377
|
+
details: { migration, table, constraint },
|
|
378
|
+
cause: error,
|
|
379
|
+
expose: true,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
/** SQLSTATEs of a value that does not convert: invalid text, too long, out of range, bad date. */
|
|
383
|
+
const CONVERSION_ERRORS = new Set(["22P02", "22001", "22003", "22007", "22008", "22018"]);
|
|
384
|
+
const TYPE_CHANGE = new RegExp(`ALTER TABLE (${IDENT}) ALTER COLUMN (${IDENT}) TYPE `, "g");
|
|
385
|
+
const unquoteIdent = (s) => s.slice(1, -1).replace(/""/g, '"');
|
|
386
|
+
/**
|
|
387
|
+
* IL4022 for a value that does not convert, in a migration that changes a column type (ALTER COLUMN
|
|
388
|
+
* ... TYPE). Undefined for any other error, or when the migration changes no column type.
|
|
389
|
+
*/
|
|
390
|
+
function conversionError(error, migration, sql) {
|
|
391
|
+
const e = error;
|
|
392
|
+
if (!e || !CONVERSION_ERRORS.has(e.code ?? ""))
|
|
393
|
+
return undefined;
|
|
394
|
+
const columns = [...sql.matchAll(TYPE_CHANGE)].map((m) => `${unquoteIdent(m[1])}.${unquoteIdent(m[2])}`);
|
|
395
|
+
if (!columns.length)
|
|
396
|
+
return undefined;
|
|
397
|
+
const reason = e.message ? ` (${e.message})` : "";
|
|
398
|
+
return new InferloError("IL4022", `Migration ${migration} failed: an existing value does not convert to the new type of ${columns.length > 1 ? `one of ${columns.join(", ")}` : columns[0]}${reason}.`, {
|
|
399
|
+
fix: `Change or clear the values that do not convert first: if ${migration} has not been applied anywhere, add an UPDATE before the ALTER COLUMN ... TYPE statement (for example UPDATE "<table>" SET "<column>" = NULL WHERE ...), or write your own USING expression. Or keep the old field type in the model.`,
|
|
400
|
+
details: { migration, columns, reason: e.message },
|
|
401
|
+
cause: error,
|
|
402
|
+
expose: true,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Run the migrations that are not yet recorded in the "inferlo_migrations" table, in name order,
|
|
407
|
+
* each in its own transaction. Returns the names it applied. Safe to run from several processes
|
|
408
|
+
* at once (a Postgres advisory lock serialises them).
|
|
409
|
+
*
|
|
410
|
+
* Each applied migration is recorded with a checksum of its SQL. Applied migrations whose SQL has
|
|
411
|
+
* changed since are reported to options.onEdited (IL4018) and are not run again.
|
|
412
|
+
*/
|
|
413
|
+
export async function applyMigrations(db, migrations, options = {}) {
|
|
414
|
+
const seen = new Set();
|
|
415
|
+
for (const m of migrations) {
|
|
416
|
+
if (!MIGRATION_NAME.test(m.name) || seen.has(m.name)) {
|
|
417
|
+
throw new InferloError("IL4016", `Invalid or duplicate migration name "${m.name}".`, {
|
|
418
|
+
fix: "Migration names use letters, digits, _ and -, and must be unique, e.g. 0002_add_due_dates.",
|
|
419
|
+
expose: true,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
seen.add(m.name);
|
|
423
|
+
}
|
|
424
|
+
// Databases migrated before the rename from Kairo keep their history: rename the old table once.
|
|
425
|
+
const legacy = await db.$sql(`SELECT (to_regclass('"kairo_migrations"') IS NOT NULL AND to_regclass('"inferlo_migrations"') IS NULL) AS rename`);
|
|
426
|
+
if (legacy[0]?.rename)
|
|
427
|
+
await db.$sql(`ALTER TABLE "kairo_migrations" RENAME TO "inferlo_migrations"`);
|
|
428
|
+
await db.$sql(`CREATE TABLE IF NOT EXISTS "inferlo_migrations" ("name" text PRIMARY KEY, "applied_at" timestamptz NOT NULL DEFAULT now(), "checksum" text)`);
|
|
429
|
+
// Tables created by Inferlo 0.2 have no checksum column. Checked first, because ALTER TABLE locks the table.
|
|
430
|
+
const hasChecksum = await db.$sql(`SELECT 1 FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = 'inferlo_migrations' AND column_name = 'checksum'`);
|
|
431
|
+
if (!hasChecksum.length)
|
|
432
|
+
await db.$sql(`ALTER TABLE "inferlo_migrations" ADD COLUMN IF NOT EXISTS "checksum" text`);
|
|
433
|
+
const done = new Map((await db.$sql(`SELECT "name", "checksum" FROM "inferlo_migrations"`)).map((r) => [String(r.name), r.checksum == null ? null : String(r.checksum)]));
|
|
434
|
+
const sorted = [...migrations].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
435
|
+
const sums = new Map(await Promise.all(sorted.map(async (m) => [m.name, await checksum(m.sql)])));
|
|
436
|
+
const edited = [];
|
|
437
|
+
for (const m of sorted) {
|
|
438
|
+
if (!done.has(m.name))
|
|
439
|
+
continue;
|
|
440
|
+
const recorded = done.get(m.name);
|
|
441
|
+
// Applied before checksums were recorded: record the current file.
|
|
442
|
+
if (recorded === null)
|
|
443
|
+
await db.$sql(`UPDATE "inferlo_migrations" SET "checksum" = $1 WHERE "name" = $2 AND "checksum" IS NULL`, [sums.get(m.name), m.name]);
|
|
444
|
+
else if (recorded !== sums.get(m.name))
|
|
445
|
+
edited.push(m.name);
|
|
446
|
+
}
|
|
447
|
+
if (edited.length)
|
|
448
|
+
options.onEdited?.(edited);
|
|
449
|
+
const applied = [];
|
|
450
|
+
for (const m of sorted) {
|
|
451
|
+
if (done.has(m.name))
|
|
452
|
+
continue;
|
|
453
|
+
const ran = await db.$transaction(async (tx) => {
|
|
454
|
+
await tx.$sql(`SELECT pg_advisory_xact_lock(${LOCK_KEY})`);
|
|
455
|
+
if ((await tx.$sql(`SELECT 1 FROM "inferlo_migrations" WHERE "name" = $1`, [m.name])).length)
|
|
456
|
+
return false;
|
|
457
|
+
try {
|
|
458
|
+
await tx.$sql(m.sql);
|
|
459
|
+
}
|
|
460
|
+
catch (error) {
|
|
461
|
+
throw nullRowsError(error, m.name) ?? checkViolationError(error, m.name) ?? conversionError(error, m.name, m.sql) ?? error;
|
|
462
|
+
}
|
|
463
|
+
await tx.$sql(`INSERT INTO "inferlo_migrations" ("name", "checksum") VALUES ($1, $2)`, [m.name, sums.get(m.name)]);
|
|
464
|
+
return true;
|
|
465
|
+
});
|
|
466
|
+
if (ran)
|
|
467
|
+
applied.push(m.name);
|
|
468
|
+
}
|
|
469
|
+
return applied;
|
|
470
|
+
}
|
|
471
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type AnyModel } from "../model.ts";
|
|
2
|
+
import type { AnySchema } from "../schema.ts";
|
|
3
|
+
import type { Adapter, DbRecord } from "./types.ts";
|
|
4
|
+
interface Queryable {
|
|
5
|
+
query(text: string, params?: unknown[]): Promise<{
|
|
6
|
+
rows: DbRecord[];
|
|
7
|
+
rowCount: number | null;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
interface PoolLike extends Queryable {
|
|
11
|
+
connect(): Promise<Queryable & {
|
|
12
|
+
release(): void;
|
|
13
|
+
}>;
|
|
14
|
+
end(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export interface PostgresOptions {
|
|
17
|
+
/** postgres://user:pass@host:5432/db */
|
|
18
|
+
url?: string;
|
|
19
|
+
/** Bring your own pg.Pool. */
|
|
20
|
+
pool?: PoolLike;
|
|
21
|
+
/** Maximum pool size (default 10). */
|
|
22
|
+
max?: number;
|
|
23
|
+
/** Log every statement with its parameter count. */
|
|
24
|
+
debug?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function columnType(schema: AnySchema): string;
|
|
27
|
+
/** The column's SQL DEFAULT expression, or undefined when it has no fixed default (function defaults run in JavaScript). */
|
|
28
|
+
export declare function defaultSql(schema: AnySchema): string | undefined;
|
|
29
|
+
export declare function columnDefinition(model: AnyModel, field: string, schema: AnySchema, forAlter?: boolean): string;
|
|
30
|
+
export declare const SYSTEM_COLUMNS: [column: string, definition: string][];
|
|
31
|
+
export declare function createTableSql(model: AnyModel): string[];
|
|
32
|
+
/** [index name, CREATE INDEX statement] for every unique, indexed or ref field. */
|
|
33
|
+
export declare function modelIndexes(model: AnyModel): [name: string, sql: string][];
|
|
34
|
+
/** Order models so referenced tables are created first. */
|
|
35
|
+
export declare function sortByReferences(models: AnyModel[]): AnyModel[];
|
|
36
|
+
export declare function postgres(options?: PostgresOptions): Adapter;
|
|
37
|
+
export {};
|