@browserlessapi/inferlo 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +127 -2
- package/dist/ai/index.d.ts +96 -0
- package/dist/ai/index.js +327 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/providers.d.ts +97 -0
- package/dist/ai/providers.js +204 -0
- package/dist/ai/providers.js.map +1 -0
- package/dist/app.d.ts +94 -0
- package/dist/app.js +365 -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 +467 -0
- package/dist/cli/main.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 +84 -0
- package/dist/db/migrate.js +355 -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 +72 -0
- package/dist/db/table.js +177 -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 +56 -0
- package/dist/describe.js +64 -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 +26 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +18 -0
- package/dist/mcp.js +166 -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 +71 -0
- package/dist/openapi.js.map +1 -0
- package/dist/route.d.ts +125 -0
- package/dist/route.js +28 -0
- package/dist/route.js.map +1 -0
- package/dist/schema.d.ts +156 -0
- package/dist/schema.js +430 -0
- package/dist/schema.js.map +1 -0
- package/dist/serve.d.ts +11 -0
- package/dist/serve.js +83 -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 +53 -0
- package/templates/app/CLAUDE.md +1 -0
- package/templates/app/README.md +14 -0
- package/templates/app/_env.example +5 -0
- package/templates/app/_gitignore +3 -0
- package/templates/app/package.json.tpl +31 -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 +16 -0
- package/templates/app/test/notes.test.ts +50 -0
- package/templates/app/tsconfig.json +17 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* PostgreSQL adapter (uses the `pg` package: npm install pg).
|
|
11
|
+
*
|
|
12
|
+
* import { postgres } from "@browserlessapi/inferlo/postgres"
|
|
13
|
+
* createApp({ db: postgres({ url: env("DATABASE_URL") }), ... })
|
|
14
|
+
*
|
|
15
|
+
* Every value is sent as a query parameter. Identifiers come only from model definitions,
|
|
16
|
+
* which are validated, and are always quoted.
|
|
17
|
+
*/
|
|
18
|
+
import { InferloError } from "../errors.js";
|
|
19
|
+
import { columnName } from "../model.js";
|
|
20
|
+
const q = (identifier) => `"${identifier.replace(/"/g, '""')}"`;
|
|
21
|
+
export function columnType(schema) {
|
|
22
|
+
const d = schema.def;
|
|
23
|
+
switch (d.kind) {
|
|
24
|
+
case "string":
|
|
25
|
+
return d.max !== undefined && d.max <= 10485760 ? `varchar(${d.max})` : "text";
|
|
26
|
+
case "text":
|
|
27
|
+
case "email":
|
|
28
|
+
case "url":
|
|
29
|
+
case "enum":
|
|
30
|
+
case "literal":
|
|
31
|
+
return "text";
|
|
32
|
+
case "uuid":
|
|
33
|
+
case "ref":
|
|
34
|
+
return "uuid";
|
|
35
|
+
case "number":
|
|
36
|
+
return "double precision";
|
|
37
|
+
case "int":
|
|
38
|
+
return "integer";
|
|
39
|
+
case "boolean":
|
|
40
|
+
return "boolean";
|
|
41
|
+
case "date":
|
|
42
|
+
return "timestamptz";
|
|
43
|
+
case "json":
|
|
44
|
+
case "array":
|
|
45
|
+
case "object":
|
|
46
|
+
case "any":
|
|
47
|
+
return "jsonb";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function isJson(schema) {
|
|
51
|
+
return columnType(schema) === "jsonb";
|
|
52
|
+
}
|
|
53
|
+
function literal(value) {
|
|
54
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
55
|
+
return String(value);
|
|
56
|
+
if (typeof value === "boolean")
|
|
57
|
+
return value ? "true" : "false";
|
|
58
|
+
return `'${String(typeof value === "object" ? JSON.stringify(value) : value).replace(/'/g, "''")}'`;
|
|
59
|
+
}
|
|
60
|
+
/** The column's SQL DEFAULT expression, or undefined when it has no fixed default (function defaults run in JavaScript). */
|
|
61
|
+
export function defaultSql(schema) {
|
|
62
|
+
const d = schema.def;
|
|
63
|
+
if (!d.hasDefault || typeof d.defaultValue === "function")
|
|
64
|
+
return undefined;
|
|
65
|
+
return `${literal(d.defaultValue)}${isJson(schema) ? "::jsonb" : ""}`;
|
|
66
|
+
}
|
|
67
|
+
export function columnDefinition(model, field, schema, forAlter = false) {
|
|
68
|
+
const d = schema.def;
|
|
69
|
+
let sql = `${q(columnName(field))} ${columnType(schema)}`;
|
|
70
|
+
const fixedDefault = defaultSql(schema);
|
|
71
|
+
if (fixedDefault !== undefined)
|
|
72
|
+
sql += ` DEFAULT ${fixedDefault}`;
|
|
73
|
+
const required = !d.optional && !d.nullable && !(d.kind === "any");
|
|
74
|
+
if (required && (!forAlter || (d.hasDefault && typeof d.defaultValue !== "function")))
|
|
75
|
+
sql += " NOT NULL";
|
|
76
|
+
if (d.kind === "enum" && d.values)
|
|
77
|
+
sql += ` CHECK (${q(columnName(field))} IN (${d.values.map(literal).join(", ")}))`;
|
|
78
|
+
if (d.kind === "ref" && d.refTable) {
|
|
79
|
+
sql += ` REFERENCES ${q(d.refTable)}("id") ON DELETE ${(d.onDelete ?? "restrict").toUpperCase()}`;
|
|
80
|
+
}
|
|
81
|
+
void model;
|
|
82
|
+
return sql;
|
|
83
|
+
}
|
|
84
|
+
export const SYSTEM_COLUMNS = [
|
|
85
|
+
["id", `"id" uuid PRIMARY KEY`],
|
|
86
|
+
["created_at", `"created_at" timestamptz NOT NULL DEFAULT now()`],
|
|
87
|
+
["updated_at", `"updated_at" timestamptz NOT NULL DEFAULT now()`],
|
|
88
|
+
];
|
|
89
|
+
export function createTableSql(model) {
|
|
90
|
+
const cols = SYSTEM_COLUMNS.map(([, definition]) => definition);
|
|
91
|
+
for (const [field, schema] of Object.entries(model.fields))
|
|
92
|
+
cols.push(columnDefinition(model, field, schema));
|
|
93
|
+
return [`CREATE TABLE IF NOT EXISTS ${q(model.name)} (\n ${cols.join(",\n ")}\n)`, ...indexSql(model)];
|
|
94
|
+
}
|
|
95
|
+
function indexSql(model) {
|
|
96
|
+
return modelIndexes(model).map(([, sql]) => sql);
|
|
97
|
+
}
|
|
98
|
+
/** [index name, CREATE INDEX statement] for every unique, indexed or ref field. */
|
|
99
|
+
export function modelIndexes(model) {
|
|
100
|
+
const out = [];
|
|
101
|
+
for (const [field, schema] of Object.entries(model.fields)) {
|
|
102
|
+
const col = columnName(field);
|
|
103
|
+
if (schema.def.unique) {
|
|
104
|
+
const name = `${model.name}_${col}_key`;
|
|
105
|
+
out.push([name, `CREATE UNIQUE INDEX IF NOT EXISTS ${q(name)} ON ${q(model.name)} (${q(col)})`]);
|
|
106
|
+
}
|
|
107
|
+
else if (schema.def.index || schema.def.kind === "ref") {
|
|
108
|
+
const name = `${model.name}_${col}_idx`;
|
|
109
|
+
out.push([name, `CREATE INDEX IF NOT EXISTS ${q(name)} ON ${q(model.name)} (${q(col)})`]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
/** Order models so referenced tables are created first. */
|
|
115
|
+
export function sortByReferences(models) {
|
|
116
|
+
const byName = new Map(models.map((m) => [m.name, m]));
|
|
117
|
+
const out = [];
|
|
118
|
+
const seen = new Set();
|
|
119
|
+
const visit = (m, stack) => {
|
|
120
|
+
if (seen.has(m.name) || stack.has(m.name))
|
|
121
|
+
return;
|
|
122
|
+
stack.add(m.name);
|
|
123
|
+
for (const schema of Object.values(m.fields)) {
|
|
124
|
+
const ref = schema.def.refTable;
|
|
125
|
+
if (ref && ref !== m.name && byName.has(ref))
|
|
126
|
+
visit(byName.get(ref), stack);
|
|
127
|
+
}
|
|
128
|
+
seen.add(m.name);
|
|
129
|
+
out.push(m);
|
|
130
|
+
};
|
|
131
|
+
for (const m of models)
|
|
132
|
+
visit(m, new Set());
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
export function postgres(options = {}) {
|
|
136
|
+
let pool = options.pool;
|
|
137
|
+
let models = new Map();
|
|
138
|
+
const getPool = async () => {
|
|
139
|
+
if (pool)
|
|
140
|
+
return pool;
|
|
141
|
+
if (!options.url) {
|
|
142
|
+
throw new InferloError("IL4009", "postgres() needs a connection URL.", {
|
|
143
|
+
fix: 'Pass postgres({ url: env("DATABASE_URL") }) and set DATABASE_URL, e.g. postgres://user:pass@localhost:5432/app',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
let pg;
|
|
147
|
+
try {
|
|
148
|
+
pg = (await import(__rewriteRelativeImportExtension("pg")));
|
|
149
|
+
}
|
|
150
|
+
catch (cause) {
|
|
151
|
+
throw new InferloError("IL4010", "The pg package is not installed.", { fix: "Run: npm install pg", cause });
|
|
152
|
+
}
|
|
153
|
+
const Pool = pg.Pool ?? pg.default.Pool;
|
|
154
|
+
pool = new Pool({ connectionString: options.url, max: options.max ?? 10 });
|
|
155
|
+
return pool;
|
|
156
|
+
};
|
|
157
|
+
return createPgAdapter(async () => getPool(), () => models, (m) => (models = m), options.debug ?? false, async () => {
|
|
158
|
+
if (pool && !options.pool)
|
|
159
|
+
await pool.end();
|
|
160
|
+
pool = undefined;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function createPgAdapter(client, getModels, setModels, debug, close) {
|
|
164
|
+
const run = async (text, params = []) => {
|
|
165
|
+
if (debug)
|
|
166
|
+
console.log(`[inferlo:sql] ${text.replace(/\s+/g, " ")} (${params.length} params)`);
|
|
167
|
+
try {
|
|
168
|
+
return await (await client()).query(text, params);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw translate(error);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const fieldSchema = (model, field) => model.fields[field];
|
|
175
|
+
const toDb = (model, field, value) => {
|
|
176
|
+
const schema = fieldSchema(model, field);
|
|
177
|
+
if (schema && isJson(schema) && value !== null && value !== undefined)
|
|
178
|
+
return JSON.stringify(value);
|
|
179
|
+
return value;
|
|
180
|
+
};
|
|
181
|
+
const fromDb = (model, row) => {
|
|
182
|
+
const out = { id: row.id, createdAt: row.created_at, updatedAt: row.updated_at };
|
|
183
|
+
for (const [field, schema] of Object.entries(model.fields)) {
|
|
184
|
+
let value = row[columnName(field)];
|
|
185
|
+
if (value !== null && value !== undefined && schema.def.kind === "number" && typeof value === "string")
|
|
186
|
+
value = Number(value);
|
|
187
|
+
out[field] = value ?? null;
|
|
188
|
+
}
|
|
189
|
+
return out;
|
|
190
|
+
};
|
|
191
|
+
const whereSql = (model, conditions, params) => {
|
|
192
|
+
if (!conditions.length)
|
|
193
|
+
return "";
|
|
194
|
+
const parts = conditions.map(({ field, op, value }) => {
|
|
195
|
+
const col = q(columnName(field));
|
|
196
|
+
const p = (v) => {
|
|
197
|
+
params.push(toDb(model, field, v));
|
|
198
|
+
return `$${params.length}`;
|
|
199
|
+
};
|
|
200
|
+
switch (op) {
|
|
201
|
+
case "eq":
|
|
202
|
+
return `${col} = ${p(value)}`;
|
|
203
|
+
case "ne":
|
|
204
|
+
return `${col} <> ${p(value)}`;
|
|
205
|
+
case "gt":
|
|
206
|
+
return `${col} > ${p(value)}`;
|
|
207
|
+
case "gte":
|
|
208
|
+
return `${col} >= ${p(value)}`;
|
|
209
|
+
case "lt":
|
|
210
|
+
return `${col} < ${p(value)}`;
|
|
211
|
+
case "lte":
|
|
212
|
+
return `${col} <= ${p(value)}`;
|
|
213
|
+
case "in":
|
|
214
|
+
if (!value.length)
|
|
215
|
+
return "false";
|
|
216
|
+
return `${col} = ANY(${p(value.map((v) => toDb(model, field, v)))})`;
|
|
217
|
+
case "notIn":
|
|
218
|
+
if (!value.length)
|
|
219
|
+
return `${col} IS NOT NULL`;
|
|
220
|
+
return `NOT (${col} = ANY(${p(value.map((v) => toDb(model, field, v)))}))`;
|
|
221
|
+
case "like":
|
|
222
|
+
return `${col} LIKE ${p(value)}`;
|
|
223
|
+
case "ilike":
|
|
224
|
+
return `${col} ILIKE ${p(value)}`;
|
|
225
|
+
case "isNull":
|
|
226
|
+
return value ? `${col} IS NULL` : `${col} IS NOT NULL`;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
return ` WHERE ${parts.join(" AND ")}`;
|
|
230
|
+
};
|
|
231
|
+
const adapter = {
|
|
232
|
+
dialect: "postgres",
|
|
233
|
+
connect(models) {
|
|
234
|
+
setModels(new Map(models.map((m) => [m.name, m])));
|
|
235
|
+
},
|
|
236
|
+
async insert(model, row) {
|
|
237
|
+
const fields = Object.keys(row);
|
|
238
|
+
const params = fields.map((f) => toDb(model, f, row[f]));
|
|
239
|
+
const sql = `INSERT INTO ${q(model.name)} (${fields.map((f) => q(columnName(f))).join(", ")}) VALUES (${fields.map((_, i) => `$${i + 1}`).join(", ")}) RETURNING *`;
|
|
240
|
+
const result = await run(sql, params);
|
|
241
|
+
return fromDb(model, result.rows[0]);
|
|
242
|
+
},
|
|
243
|
+
async select(model, query) {
|
|
244
|
+
const params = [];
|
|
245
|
+
let sql = `SELECT * FROM ${q(model.name)}${whereSql(model, query.where, params)}`;
|
|
246
|
+
if (query.orderBy.length)
|
|
247
|
+
sql += ` ORDER BY ${query.orderBy.map(([f, d]) => `${q(columnName(f))} ${d === "desc" ? "DESC" : "ASC"}`).join(", ")}`;
|
|
248
|
+
if (query.limit !== undefined)
|
|
249
|
+
sql += ` LIMIT ${Number(query.limit)}`;
|
|
250
|
+
if (query.offset)
|
|
251
|
+
sql += ` OFFSET ${Number(query.offset)}`;
|
|
252
|
+
return (await run(sql, params)).rows.map((r) => fromDb(model, r));
|
|
253
|
+
},
|
|
254
|
+
async update(model, where, patch) {
|
|
255
|
+
const params = [];
|
|
256
|
+
const sets = Object.keys(patch).map((f) => {
|
|
257
|
+
params.push(toDb(model, f, patch[f]));
|
|
258
|
+
return `${q(columnName(f))} = $${params.length}`;
|
|
259
|
+
});
|
|
260
|
+
const sql = `UPDATE ${q(model.name)} SET ${sets.join(", ")}${whereSql(model, where, params)} RETURNING *`;
|
|
261
|
+
return (await run(sql, params)).rows.map((r) => fromDb(model, r));
|
|
262
|
+
},
|
|
263
|
+
async delete(model, where) {
|
|
264
|
+
const params = [];
|
|
265
|
+
return (await run(`DELETE FROM ${q(model.name)}${whereSql(model, where, params)}`, params)).rowCount ?? 0;
|
|
266
|
+
},
|
|
267
|
+
async count(model, where) {
|
|
268
|
+
const params = [];
|
|
269
|
+
const result = await run(`SELECT count(*)::int AS n FROM ${q(model.name)}${whereSql(model, where, params)}`, params);
|
|
270
|
+
return Number(result.rows[0]?.n ?? 0);
|
|
271
|
+
},
|
|
272
|
+
async sync(models, options = {}) {
|
|
273
|
+
const statements = [];
|
|
274
|
+
for (const model of sortByReferences(models)) {
|
|
275
|
+
const existing = options.dryRun
|
|
276
|
+
? await run(`SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = $1`, [model.name]).catch(() => ({ rows: [] }))
|
|
277
|
+
: await run(`SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = $1`, [model.name]);
|
|
278
|
+
const columns = new Set(existing.rows.map((r) => String(r.column_name)));
|
|
279
|
+
if (!columns.size) {
|
|
280
|
+
statements.push(...createTableSql(model));
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
for (const [field, schema] of Object.entries(model.fields)) {
|
|
284
|
+
if (!columns.has(columnName(field)))
|
|
285
|
+
statements.push(`ALTER TABLE ${q(model.name)} ADD COLUMN ${columnDefinition(model, field, schema, true)}`);
|
|
286
|
+
}
|
|
287
|
+
statements.push(...indexSql(model));
|
|
288
|
+
}
|
|
289
|
+
if (!options.dryRun)
|
|
290
|
+
for (const s of statements)
|
|
291
|
+
await run(s);
|
|
292
|
+
return statements;
|
|
293
|
+
},
|
|
294
|
+
async sql(text, params = []) {
|
|
295
|
+
return (await run(text, params)).rows;
|
|
296
|
+
},
|
|
297
|
+
async transaction(fn) {
|
|
298
|
+
const pool = (await client());
|
|
299
|
+
if (typeof pool.connect !== "function")
|
|
300
|
+
return fn(adapter);
|
|
301
|
+
const conn = await pool.connect();
|
|
302
|
+
try {
|
|
303
|
+
await conn.query("BEGIN");
|
|
304
|
+
const tx = createPgAdapter(async () => conn, getModels, () => { }, debug, async () => { });
|
|
305
|
+
const result = await fn(tx);
|
|
306
|
+
await conn.query("COMMIT");
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
await conn.query("ROLLBACK").catch(() => { });
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
conn.release();
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
close,
|
|
318
|
+
};
|
|
319
|
+
return adapter;
|
|
320
|
+
}
|
|
321
|
+
function translate(error) {
|
|
322
|
+
const e = error;
|
|
323
|
+
if (e && e.code === "23505") {
|
|
324
|
+
return new InferloError("IL4004", "A row with this value already exists.", { status: 409, details: { table: e.table, constraint: e.constraint }, cause: error });
|
|
325
|
+
}
|
|
326
|
+
if (e && e.code === "23503") {
|
|
327
|
+
return new InferloError("IL4011", "This references a row that does not exist (or is still referenced elsewhere).", {
|
|
328
|
+
status: 409,
|
|
329
|
+
details: { table: e.table, constraint: e.constraint },
|
|
330
|
+
cause: error,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (e && e.code === "42P01") {
|
|
334
|
+
return new InferloError("IL4012", `Table missing: ${e.message}`, { fix: "Run: inferlo db push", cause: error });
|
|
335
|
+
}
|
|
336
|
+
return error;
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/db/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { AnyModel, Row, CreateInput, UpdateInput } from "../model.ts";
|
|
2
|
+
import type { Adapter, DbRecord } from "./types.ts";
|
|
3
|
+
type Comparable<V> = {
|
|
4
|
+
eq?: V;
|
|
5
|
+
ne?: V;
|
|
6
|
+
gt?: V;
|
|
7
|
+
gte?: V;
|
|
8
|
+
lt?: V;
|
|
9
|
+
lte?: V;
|
|
10
|
+
in?: V[];
|
|
11
|
+
notIn?: V[];
|
|
12
|
+
like?: string;
|
|
13
|
+
ilike?: string;
|
|
14
|
+
isNull?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/** Filter rows. A plain value means equals; use an object for other operators. */
|
|
17
|
+
export type Where<R> = {
|
|
18
|
+
[K in keyof R]?: R[K] | Comparable<NonNullable<R[K]>>;
|
|
19
|
+
};
|
|
20
|
+
export type OrderBy<R> = {
|
|
21
|
+
[K in keyof R]?: "asc" | "desc";
|
|
22
|
+
} | [keyof R & string, "asc" | "desc"][];
|
|
23
|
+
export interface FindManyOptions<R> {
|
|
24
|
+
where?: Where<R>;
|
|
25
|
+
orderBy?: OrderBy<R>;
|
|
26
|
+
/** Default 100, maximum 1000. */
|
|
27
|
+
limit?: number;
|
|
28
|
+
offset?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class Table<M extends AnyModel> {
|
|
31
|
+
#private;
|
|
32
|
+
readonly model: M;
|
|
33
|
+
constructor(model: M, adapter: () => Adapter);
|
|
34
|
+
/** Validate and insert one row. Returns the stored row. */
|
|
35
|
+
insert(data: CreateInput<M>): Promise<Row<M>>;
|
|
36
|
+
insertMany(items: CreateInput<M>[]): Promise<Row<M>[]>;
|
|
37
|
+
/** Row by id, or null. */
|
|
38
|
+
find(id: string): Promise<Row<M> | null>;
|
|
39
|
+
/** Row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
40
|
+
get(id: string): Promise<Row<M>>;
|
|
41
|
+
/** First row matching where, or null. */
|
|
42
|
+
findOne(where: Where<Row<M>>): Promise<Row<M> | null>;
|
|
43
|
+
findMany(options?: FindManyOptions<Row<M>>): Promise<Row<M>[]>;
|
|
44
|
+
count(where?: Where<Row<M>>): Promise<number>;
|
|
45
|
+
/** Validate and update one row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
46
|
+
update(id: string, patch: UpdateInput<M>): Promise<Row<M>>;
|
|
47
|
+
/** Update every row matching where. Returns the updated rows. */
|
|
48
|
+
updateMany(where: Where<Row<M>>, patch: UpdateInput<M>): Promise<Row<M>[]>;
|
|
49
|
+
/** Delete by id. Returns true if a row was deleted. */
|
|
50
|
+
delete(id: string): Promise<boolean>;
|
|
51
|
+
/** Delete every row matching where. Refuses an empty where to prevent accidental wipes. */
|
|
52
|
+
deleteMany(where: Where<Row<M>>): Promise<number>;
|
|
53
|
+
}
|
|
54
|
+
/** db.<table> for every registered model, plus helpers. */
|
|
55
|
+
export type Db<Models extends readonly AnyModel[]> = {
|
|
56
|
+
[M in Models[number] as M["name"]]: Table<M>;
|
|
57
|
+
} & DbHelpers;
|
|
58
|
+
export interface DbHelpers {
|
|
59
|
+
/** The underlying adapter. */
|
|
60
|
+
readonly $adapter: Adapter;
|
|
61
|
+
/** Create missing tables, columns and indexes. */
|
|
62
|
+
$sync(options?: {
|
|
63
|
+
dryRun?: boolean;
|
|
64
|
+
}): Promise<string[]>;
|
|
65
|
+
/** Run fn in a transaction (Postgres). With memory() it simply runs fn. */
|
|
66
|
+
$transaction<T>(fn: (tx: Db<any>) => Promise<T>): Promise<T>;
|
|
67
|
+
/** Raw parameterised SQL (Postgres): $sql("select * from tickets where id = $1", [id]). */
|
|
68
|
+
$sql(text: string, params?: unknown[]): Promise<DbRecord[]>;
|
|
69
|
+
$close(): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
export declare function createDb<const Models extends readonly AnyModel[]>(models: Models, adapter: Adapter): Db<Models>;
|
|
72
|
+
export {};
|
package/dist/db/table.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed table clients: db.tickets.insert(...), db.tickets.findMany({ where: { status: "open" } }).
|
|
3
|
+
* Inserts and updates are always validated against the model, and every query is parameterised.
|
|
4
|
+
*/
|
|
5
|
+
import { InferloError, didYouMean, notFound } from "../errors.js";
|
|
6
|
+
import { ValidationError } from "../schema.js";
|
|
7
|
+
const OPS = ["eq", "ne", "gt", "gte", "lt", "lte", "in", "notIn", "like", "ilike", "isNull"];
|
|
8
|
+
const DEFAULT_LIMIT = 100;
|
|
9
|
+
const MAX_LIMIT = 1000;
|
|
10
|
+
export class Table {
|
|
11
|
+
model;
|
|
12
|
+
#adapter;
|
|
13
|
+
constructor(model, adapter) {
|
|
14
|
+
this.model = model;
|
|
15
|
+
this.#adapter = adapter;
|
|
16
|
+
}
|
|
17
|
+
get #fields() {
|
|
18
|
+
return ["id", "createdAt", "updatedAt", ...Object.keys(this.model.fields)];
|
|
19
|
+
}
|
|
20
|
+
/** Validate and insert one row. Returns the stored row. */
|
|
21
|
+
async insert(data) {
|
|
22
|
+
const parsed = this.#validate(this.model.create, data, "insert");
|
|
23
|
+
const now = new Date();
|
|
24
|
+
const row = { id: crypto.randomUUID(), createdAt: now, updatedAt: now, ...parsed };
|
|
25
|
+
return (await this.#adapter().insert(this.model, row));
|
|
26
|
+
}
|
|
27
|
+
async insertMany(items) {
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const item of items)
|
|
30
|
+
out.push(await this.insert(item));
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/** Row by id, or null. */
|
|
34
|
+
async find(id) {
|
|
35
|
+
const rows = await this.#adapter().select(this.model, { where: [{ field: "id", op: "eq", value: id }], orderBy: [], limit: 1 });
|
|
36
|
+
return rows[0] ?? null;
|
|
37
|
+
}
|
|
38
|
+
/** Row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
39
|
+
async get(id) {
|
|
40
|
+
const row = await this.find(id);
|
|
41
|
+
if (!row)
|
|
42
|
+
throw notFound(`${singular(this.model.name)} ${id} was not found.`, { table: this.model.name, id });
|
|
43
|
+
return row;
|
|
44
|
+
}
|
|
45
|
+
/** First row matching where, or null. */
|
|
46
|
+
async findOne(where) {
|
|
47
|
+
const rows = await this.findMany({ where, limit: 1 });
|
|
48
|
+
return rows[0] ?? null;
|
|
49
|
+
}
|
|
50
|
+
async findMany(options = {}) {
|
|
51
|
+
return (await this.#adapter().select(this.model, this.#query(options)));
|
|
52
|
+
}
|
|
53
|
+
async count(where = {}) {
|
|
54
|
+
return this.#adapter().count(this.model, this.#where(where));
|
|
55
|
+
}
|
|
56
|
+
/** Validate and update one row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
57
|
+
async update(id, patch) {
|
|
58
|
+
const parsed = this.#validate(this.model.update, patch, "update");
|
|
59
|
+
const rows = await this.#adapter().update(this.model, [{ field: "id", op: "eq", value: id }], { ...parsed, updatedAt: new Date() });
|
|
60
|
+
if (!rows[0])
|
|
61
|
+
throw notFound(`${singular(this.model.name)} ${id} was not found.`, { table: this.model.name, id });
|
|
62
|
+
return rows[0];
|
|
63
|
+
}
|
|
64
|
+
/** Update every row matching where. Returns the updated rows. */
|
|
65
|
+
async updateMany(where, patch) {
|
|
66
|
+
const conditions = this.#where(where);
|
|
67
|
+
const parsed = this.#validate(this.model.update, patch, "update");
|
|
68
|
+
return (await this.#adapter().update(this.model, conditions, { ...parsed, updatedAt: new Date() }));
|
|
69
|
+
}
|
|
70
|
+
/** Delete by id. Returns true if a row was deleted. */
|
|
71
|
+
async delete(id) {
|
|
72
|
+
return (await this.#adapter().delete(this.model, [{ field: "id", op: "eq", value: id }])) > 0;
|
|
73
|
+
}
|
|
74
|
+
/** Delete every row matching where. Refuses an empty where to prevent accidental wipes. */
|
|
75
|
+
async deleteMany(where) {
|
|
76
|
+
const conditions = this.#where(where);
|
|
77
|
+
if (!conditions.length) {
|
|
78
|
+
throw new InferloError("IL4007", `deleteMany() on "${this.model.name}" needs a where filter.`, {
|
|
79
|
+
fix: "Pass a filter, e.g. deleteMany({ status: \"closed\" }). To delete everything use deleteMany({ id: { isNull: false } }).",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return this.#adapter().delete(this.model, conditions);
|
|
83
|
+
}
|
|
84
|
+
#validate(schema, data, action) {
|
|
85
|
+
const result = schema.safeParse(data);
|
|
86
|
+
if (!result.ok)
|
|
87
|
+
throw new ValidationError(result.issues, `${singular(this.model.name)} ${action}`);
|
|
88
|
+
return result.value;
|
|
89
|
+
}
|
|
90
|
+
#checkField(field, where) {
|
|
91
|
+
if (!this.#fields.includes(field)) {
|
|
92
|
+
throw new InferloError("IL4003", `Unknown field "${field}" in ${where} on "${this.model.name}".${didYouMean(field, this.#fields)}`, {
|
|
93
|
+
fix: `Use one of: ${this.#fields.join(", ")}`,
|
|
94
|
+
status: 500,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
#where(where = {}) {
|
|
99
|
+
const out = [];
|
|
100
|
+
for (const [field, value] of Object.entries(where)) {
|
|
101
|
+
if (value === undefined)
|
|
102
|
+
continue;
|
|
103
|
+
this.#checkField(field, "where");
|
|
104
|
+
if (value !== null && typeof value === "object" && !(value instanceof Date) && !Array.isArray(value)) {
|
|
105
|
+
for (const [op, operand] of Object.entries(value)) {
|
|
106
|
+
if (operand === undefined)
|
|
107
|
+
continue;
|
|
108
|
+
if (!OPS.includes(op)) {
|
|
109
|
+
throw new InferloError("IL4003", `Unknown operator "${op}" for "${field}".${didYouMean(op, OPS)}`, {
|
|
110
|
+
fix: `Operators: ${OPS.join(", ")}`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
out.push({ field, op: op, value: operand });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (value === null) {
|
|
117
|
+
out.push({ field, op: "isNull", value: true });
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
out.push({ field, op: "eq", value });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
#query(options) {
|
|
126
|
+
const orderBy = [];
|
|
127
|
+
const raw = options.orderBy;
|
|
128
|
+
const entries = Array.isArray(raw) ? raw : Object.entries(raw ?? {});
|
|
129
|
+
for (const [field, direction] of entries) {
|
|
130
|
+
this.#checkField(field, "orderBy");
|
|
131
|
+
if (direction !== "asc" && direction !== "desc") {
|
|
132
|
+
throw new InferloError("IL4003", `orderBy direction for "${field}" must be "asc" or "desc".`);
|
|
133
|
+
}
|
|
134
|
+
orderBy.push([field, direction]);
|
|
135
|
+
}
|
|
136
|
+
const limit = Math.min(Math.max(0, Math.floor(options.limit ?? DEFAULT_LIMIT)), MAX_LIMIT);
|
|
137
|
+
const offset = Math.max(0, Math.floor(options.offset ?? 0));
|
|
138
|
+
return { where: this.#where(options.where), orderBy, limit, offset };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function singular(name) {
|
|
142
|
+
const word = name.endsWith("ies") ? name.slice(0, -3) + "y" : name.endsWith("s") ? name.slice(0, -1) : name;
|
|
143
|
+
return word.charAt(0).toUpperCase() + word.slice(1).replace(/_/g, " ");
|
|
144
|
+
}
|
|
145
|
+
export function createDb(models, adapter) {
|
|
146
|
+
const build = (current) => {
|
|
147
|
+
const db = {};
|
|
148
|
+
for (const m of models)
|
|
149
|
+
db[m.name] = new Table(m, () => current);
|
|
150
|
+
const helpers = {
|
|
151
|
+
$adapter: current,
|
|
152
|
+
$sync: (options) => current.sync([...models], options),
|
|
153
|
+
$transaction: async (fn) => (current.transaction ? current.transaction((tx) => fn(build(tx))) : fn(build(current))),
|
|
154
|
+
$sql: async (text, params) => {
|
|
155
|
+
if (!current.sql)
|
|
156
|
+
throw new InferloError("IL4008", `Raw SQL is not supported by the ${current.dialect} adapter.`, { fix: "Use postgres() from @browserlessapi/inferlo/postgres." });
|
|
157
|
+
return current.sql(text, params);
|
|
158
|
+
},
|
|
159
|
+
$close: async () => current.close?.(),
|
|
160
|
+
};
|
|
161
|
+
Object.assign(db, helpers);
|
|
162
|
+
return new Proxy(db, {
|
|
163
|
+
get(target, prop) {
|
|
164
|
+
if (typeof prop === "string" && !(prop in target) && !prop.startsWith("$") && prop !== "then" && prop !== "toJSON") {
|
|
165
|
+
const names = models.map((m) => m.name);
|
|
166
|
+
throw new InferloError("IL4002", `db.${prop} does not exist.${didYouMean(prop, names)}`, {
|
|
167
|
+
fix: `Registered tables: ${names.join(", ") || "(none)"}. Add the model to createApp({ models: [...] }).`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return Reflect.get(target, prop);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
adapter.connect?.([...models]);
|
|
175
|
+
return build(adapter);
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/db/table.ts"],"names":[],"mappings":"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"}
|