@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,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,117 @@
|
|
|
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
|
+
type RefTable<S> = S extends {
|
|
31
|
+
readonly _ref: infer T extends string;
|
|
32
|
+
} ? T : never;
|
|
33
|
+
/** Relations of a model: one per t.ref field named <name>Id, mapped to the referenced table. ownerId: t.ref("users") gives owner -> "users". */
|
|
34
|
+
export type Relations<M extends AnyModel> = {
|
|
35
|
+
[K in keyof M["fields"] & string as K extends `${infer R}Id` ? ([RefTable<M["fields"][K]>] extends [never] ? never : R) : never]: RefTable<M["fields"][K]>;
|
|
36
|
+
};
|
|
37
|
+
type IsUnion<U, A = U> = U extends unknown ? ([A] extends [U] ? false : true) : never;
|
|
38
|
+
/** Relation names R of the fields <R>Id in X that reference table T. */
|
|
39
|
+
type RefFieldsTo<X extends AnyModel, T extends string> = {
|
|
40
|
+
[K in keyof X["fields"] & string]: K extends `${infer R}Id` ? [RefTable<X["fields"][K]>] extends [never] ? never : string extends RefTable<X["fields"][K]> ? never : RefTable<X["fields"][K]> extends T ? R : never : never;
|
|
41
|
+
}[keyof X["fields"] & string];
|
|
42
|
+
type ReverseKey<X extends AnyModel, T extends string, F extends string = RefFieldsTo<X, T>> = [F] extends [never] ? never : true extends IsUnion<F> ? `${X["name"]}By${Capitalize<F>}` : X["name"];
|
|
43
|
+
/**
|
|
44
|
+
* Reverse (has-many) relations of a model: one per model in Models with a t.ref field named <name>Id
|
|
45
|
+
* to this model, named after that model's table (users gets tickets). When a model has several such
|
|
46
|
+
* fields, each is named <table>By<Name> (ticketsByOwner, ticketsByAssignee).
|
|
47
|
+
*/
|
|
48
|
+
export type ReverseRelations<M extends AnyModel, Models extends readonly AnyModel[]> = {
|
|
49
|
+
[X in Models[number] as Exclude<ReverseKey<X, M["name"]>, keyof M["fields"] | keyof Relations<M> | "id" | "createdAt" | "updatedAt">]: X;
|
|
50
|
+
};
|
|
51
|
+
/** Which relations to load: { owner: true } for a t.ref field, { tickets: true } for the rows that reference this one. */
|
|
52
|
+
export type Include<M extends AnyModel, Models extends readonly AnyModel[] = readonly []> = {
|
|
53
|
+
[R in keyof Relations<M> | keyof ReverseRelations<M, Models>]?: boolean;
|
|
54
|
+
};
|
|
55
|
+
type ModelNamed<Models extends readonly AnyModel[], N> = Extract<Models[number], {
|
|
56
|
+
name: N;
|
|
57
|
+
}> extends infer T extends AnyModel ? ([T] extends [never] ? AnyModel : T) : AnyModel;
|
|
58
|
+
type RefValue<M extends AnyModel, R extends string> = `${R}Id` extends keyof Row<M> ? Row<M>[`${R}Id`] : never;
|
|
59
|
+
/** A row with the included relations: Row<typeof Ticket> & { owner: Row<typeof User> }. Optional refs may be null. */
|
|
60
|
+
export type WithInclude<M extends AnyModel, Models extends readonly AnyModel[], I> = Row<M> & {
|
|
61
|
+
[R in keyof I & keyof Relations<M> & string as I[R] extends true ? R : never]: Row<ModelNamed<Models, Relations<M>[R]>> | (null extends RefValue<M, R> ? null : undefined extends RefValue<M, R> ? null : never);
|
|
62
|
+
} & {
|
|
63
|
+
[R in keyof I & keyof ReverseRows<M, Models> & string as I[R] extends true ? R : never]: ReverseRows<M, Models>[R];
|
|
64
|
+
};
|
|
65
|
+
type ReverseRows<M extends AnyModel, Models extends readonly AnyModel[]> = {
|
|
66
|
+
[K in keyof ReverseRelations<M, Models>]: Row<ReverseModel<M, Models, K>>[];
|
|
67
|
+
};
|
|
68
|
+
type ReverseModel<M extends AnyModel, Models extends readonly AnyModel[], K> = Models[number] extends infer X ? X extends AnyModel ? K extends ReverseKey<X, M["name"]> ? X : never : never : never;
|
|
69
|
+
/** Options for reading one row. */
|
|
70
|
+
export interface FindOptions<I> {
|
|
71
|
+
/** Load related rows: { owner: true } adds row.owner for ownerId, { tickets: true } adds row.tickets (rows that reference this one). One extra query per relation. */
|
|
72
|
+
include?: I;
|
|
73
|
+
}
|
|
74
|
+
export declare class Table<M extends AnyModel, Models extends readonly AnyModel[] = readonly AnyModel[]> {
|
|
75
|
+
#private;
|
|
76
|
+
readonly model: M;
|
|
77
|
+
constructor(model: M, adapter: () => Adapter, models?: readonly AnyModel[]);
|
|
78
|
+
/** Validate and insert one row. Returns the stored row. */
|
|
79
|
+
insert(data: CreateInput<M>): Promise<Row<M>>;
|
|
80
|
+
insertMany(items: CreateInput<M>[]): Promise<Row<M>[]>;
|
|
81
|
+
/** Row by id, or null. */
|
|
82
|
+
find<const I extends Include<M, Models> = {}>(id: string, options?: FindOptions<I>): Promise<WithInclude<M, Models, I> | null>;
|
|
83
|
+
/** Row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
84
|
+
get<const I extends Include<M, Models> = {}>(id: string, options?: FindOptions<I>): Promise<WithInclude<M, Models, I>>;
|
|
85
|
+
/** First row matching where, or null. */
|
|
86
|
+
findOne<const I extends Include<M, Models> = {}>(where: Where<Row<M>>, options?: FindOptions<I>): Promise<WithInclude<M, Models, I> | null>;
|
|
87
|
+
/** Rows matching where. include: { owner: true } loads related rows with one extra query per relation. */
|
|
88
|
+
findMany<const I extends Include<M, Models> = {}>(options?: FindManyOptions<Row<M>> & FindOptions<I>): Promise<WithInclude<M, Models, I>[]>;
|
|
89
|
+
count(where?: Where<Row<M>>): Promise<number>;
|
|
90
|
+
/** Validate and update one row by id. Throws IL4001 (HTTP 404) when it does not exist. */
|
|
91
|
+
update(id: string, patch: UpdateInput<M>): Promise<Row<M>>;
|
|
92
|
+
/** Update every row matching where. Returns the updated rows. */
|
|
93
|
+
updateMany(where: Where<Row<M>>, patch: UpdateInput<M>): Promise<Row<M>[]>;
|
|
94
|
+
/** Delete by id. Returns true if a row was deleted. */
|
|
95
|
+
delete(id: string): Promise<boolean>;
|
|
96
|
+
/** Delete every row matching where. Refuses an empty where to prevent accidental wipes. */
|
|
97
|
+
deleteMany(where: Where<Row<M>>): Promise<number>;
|
|
98
|
+
}
|
|
99
|
+
/** db.<table> for every registered model, plus helpers. */
|
|
100
|
+
export type Db<Models extends readonly AnyModel[]> = {
|
|
101
|
+
[M in Models[number] as M["name"]]: Table<M, Models>;
|
|
102
|
+
} & DbHelpers;
|
|
103
|
+
export interface DbHelpers {
|
|
104
|
+
/** The underlying adapter. */
|
|
105
|
+
readonly $adapter: Adapter;
|
|
106
|
+
/** Create missing tables, columns and indexes. */
|
|
107
|
+
$sync(options?: {
|
|
108
|
+
dryRun?: boolean;
|
|
109
|
+
}): Promise<string[]>;
|
|
110
|
+
/** Run fn in a transaction (Postgres). With memory() it simply runs fn. */
|
|
111
|
+
$transaction<T>(fn: (tx: Db<any>) => Promise<T>): Promise<T>;
|
|
112
|
+
/** Raw parameterised SQL (Postgres): $sql("select * from tickets where id = $1", [id]). */
|
|
113
|
+
$sql(text: string, params?: unknown[]): Promise<DbRecord[]>;
|
|
114
|
+
$close(): Promise<void>;
|
|
115
|
+
}
|
|
116
|
+
export declare function createDb<const Models extends readonly AnyModel[]>(models: Models, adapter: Adapter): Db<Models>;
|
|
117
|
+
export {};
|