@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
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* inferlo CLI. Every command supports --json for machine-readable output, so AI coding agents
|
|
12
|
+
* can drive it directly.
|
|
13
|
+
*/
|
|
14
|
+
import { spawn } from "node:child_process";
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
|
+
import { InferloError } from "../errors.js";
|
|
20
|
+
import { INFERLO_VERSION } from "../describe.js";
|
|
21
|
+
import { applyMigrations, planMigration } from "../db/migrate.js";
|
|
22
|
+
const HELP = `inferlo ${INFERLO_VERSION}
|
|
23
|
+
|
|
24
|
+
Usage: inferlo <command> [options]
|
|
25
|
+
|
|
26
|
+
Commands:
|
|
27
|
+
new <dir> Create a new Inferlo project
|
|
28
|
+
dev Run the server and restart on changes (src/server.ts)
|
|
29
|
+
worker Run background jobs from the database queue until SIGTERM or Ctrl+C
|
|
30
|
+
describe Print the app map: routes, models, auth, AI
|
|
31
|
+
check Typecheck, load the app and run tests
|
|
32
|
+
db push [--dry-run] Create missing tables, columns and indexes
|
|
33
|
+
db migrate [name] Write migrations/NNNN_name.sql for model changes (--dry-run to preview,
|
|
34
|
+
--allow-drop to include drops of tables, columns and indexes,
|
|
35
|
+
--allow-change to include type, default, required and enum value changes)
|
|
36
|
+
db migrate --apply Run pending migration files
|
|
37
|
+
openapi [--out file] Print or write the OpenAPI document
|
|
38
|
+
add resource <name> Generate a model plus list/get/create/update/delete routes
|
|
39
|
+
version Print the Inferlo version
|
|
40
|
+
|
|
41
|
+
Options:
|
|
42
|
+
--json Machine-readable output (for AI agents and scripts)
|
|
43
|
+
--entry <file> App module (default: package.json "inferlo.entry" or src/app.ts)
|
|
44
|
+
`;
|
|
45
|
+
function parseArgs(argv) {
|
|
46
|
+
const out = { _: [], flags: {} };
|
|
47
|
+
for (let i = 0; i < argv.length; i++) {
|
|
48
|
+
const a = argv[i];
|
|
49
|
+
if (a.startsWith("--")) {
|
|
50
|
+
const [k, v] = a.slice(2).split("=", 2);
|
|
51
|
+
if (v !== undefined)
|
|
52
|
+
out.flags[k] = v;
|
|
53
|
+
else if (argv[i + 1] && !argv[i + 1].startsWith("--") && ["entry", "out"].includes(k))
|
|
54
|
+
out.flags[k] = argv[++i];
|
|
55
|
+
else
|
|
56
|
+
out.flags[k] = true;
|
|
57
|
+
}
|
|
58
|
+
else
|
|
59
|
+
out._.push(a);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
const cwd = process.cwd();
|
|
64
|
+
async function readPackage(dir = cwd) {
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(await readFile(path.join(dir, "package.json"), "utf8"));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function entryFile(args) {
|
|
73
|
+
const pkg = await readPackage();
|
|
74
|
+
const file = args.flags.entry || pkg?.inferlo?.entry || pkg?.kairo?.entry || "src/app.ts";
|
|
75
|
+
return path.resolve(cwd, file);
|
|
76
|
+
}
|
|
77
|
+
async function loadApp(args) {
|
|
78
|
+
const file = await entryFile(args);
|
|
79
|
+
if (!existsSync(file)) {
|
|
80
|
+
throw new InferloError("IL8001", `App entry ${path.relative(cwd, file)} not found.`, {
|
|
81
|
+
fix: 'Create src/app.ts exporting `app`, pass --entry <file>, or set "inferlo": { "entry": "..." } in package.json.',
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const mod = await import(__rewriteRelativeImportExtension(pathToFileURL(file).href));
|
|
85
|
+
const app = mod.app ?? mod.default;
|
|
86
|
+
if (!app || typeof app.describe !== "function") {
|
|
87
|
+
throw new InferloError("IL8002", `${path.relative(cwd, file)} does not export an Inferlo app.`, { fix: "Add: export const app = createApp({ ... })" });
|
|
88
|
+
}
|
|
89
|
+
return app;
|
|
90
|
+
}
|
|
91
|
+
function print(data, json, text) {
|
|
92
|
+
if (json || !text)
|
|
93
|
+
console.log(JSON.stringify(data, null, 2));
|
|
94
|
+
else
|
|
95
|
+
console.log(text());
|
|
96
|
+
}
|
|
97
|
+
function run(cmd, argv, options = {}) {
|
|
98
|
+
return new Promise((resolve) => {
|
|
99
|
+
const child = spawn(cmd, argv, { cwd, stdio: options.capture ? ["ignore", "pipe", "pipe"] : "inherit", shell: process.platform === "win32" });
|
|
100
|
+
let output = "";
|
|
101
|
+
child.stdout?.on("data", (d) => (output += d));
|
|
102
|
+
child.stderr?.on("data", (d) => (output += d));
|
|
103
|
+
child.on("error", (e) => resolve({ code: 127, output: String(e) }));
|
|
104
|
+
child.on("close", (code) => resolve({ code: code ?? 1, output }));
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------------------------------------
|
|
108
|
+
async function cmdDescribe(args) {
|
|
109
|
+
const app = await loadApp(args);
|
|
110
|
+
const d = app.describe();
|
|
111
|
+
print(d, Boolean(args.flags.json), () => {
|
|
112
|
+
const lines = [`${d.name} ${d.version} (inferlo ${d.inferlo}, db: ${d.database}, auth: ${d.auth ? "on" : "off"})`, "", "Models"];
|
|
113
|
+
for (const m of d.models) {
|
|
114
|
+
lines.push(` ${m.name}`);
|
|
115
|
+
for (const [k, f] of Object.entries(m.fields)) {
|
|
116
|
+
const extra = [f.required ? "required" : "", f.unique ? "unique" : "", f.references ? `-> ${f.references}` : "", f.values ? f.values.join("|") : ""].filter(Boolean).join(", ");
|
|
117
|
+
lines.push(` ${k.padEnd(16)} ${f.type}${extra ? ` (${extra})` : ""}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
lines.push("", "Routes");
|
|
121
|
+
for (const r of d.routes)
|
|
122
|
+
lines.push(` ${r.method.padEnd(6)} ${r.path.padEnd(28)} auth=${r.auth}${r.tool ? ` tool=${r.tool}` : ""}${r.name ? ` (${r.name})` : ""}`);
|
|
123
|
+
if (d.jobs?.length) {
|
|
124
|
+
lines.push("", `Jobs (queue: ${d.jobQueue})`);
|
|
125
|
+
for (const j of d.jobs)
|
|
126
|
+
lines.push(` ${j.name.padEnd(28)} retries=${j.retries}${j.summary ? ` ${j.summary}` : ""}`);
|
|
127
|
+
for (const c of d.crons ?? [])
|
|
128
|
+
lines.push(` cron ${c.schedule.padEnd(23)} ${c.job}`);
|
|
129
|
+
}
|
|
130
|
+
lines.push("", `AI: ${d.ai.configured ? Object.entries(d.ai.aliases).map(([a, ids]) => `${a} = ${ids.join(" > ")}`).join("; ") || "configured" : "not configured"}`);
|
|
131
|
+
if (d.endpoints.openapi)
|
|
132
|
+
lines.push(`OpenAPI: ${d.endpoints.openapi}`);
|
|
133
|
+
if (d.endpoints.mcp)
|
|
134
|
+
lines.push(`MCP: ${d.endpoints.mcp}`);
|
|
135
|
+
return lines.join("\n");
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
async function cmdOpenapi(args) {
|
|
139
|
+
const app = await loadApp(args);
|
|
140
|
+
const doc = JSON.stringify(app.openapi(), null, 2);
|
|
141
|
+
if (typeof args.flags.out === "string") {
|
|
142
|
+
await writeFile(path.resolve(cwd, args.flags.out), doc + "\n");
|
|
143
|
+
print({ ok: true, file: args.flags.out }, Boolean(args.flags.json), () => `Wrote ${args.flags.out}`);
|
|
144
|
+
}
|
|
145
|
+
else
|
|
146
|
+
console.log(doc);
|
|
147
|
+
}
|
|
148
|
+
async function cmdDb(args) {
|
|
149
|
+
if (args._[1] === "migrate")
|
|
150
|
+
return cmdMigrate(args);
|
|
151
|
+
if (args._[1] !== "push")
|
|
152
|
+
throw new InferloError("IL8003", `Unknown db command "${args._[1] ?? ""}".`, { fix: "Use: inferlo db push [--dry-run] or inferlo db migrate [name] [--dry-run | --apply]" });
|
|
153
|
+
const app = await loadApp(args);
|
|
154
|
+
const dryRun = Boolean(args.flags["dry-run"]);
|
|
155
|
+
const statements = await app.db.$sync({ dryRun });
|
|
156
|
+
await app.db.$close();
|
|
157
|
+
print({ ok: true, dryRun, statements }, Boolean(args.flags.json), () => statements.length ? `${dryRun ? "Would run" : "Ran"}:\n\n${statements.join(";\n\n")};` : "Database is up to date.");
|
|
158
|
+
}
|
|
159
|
+
const MIGRATIONS_DIR = "migrations";
|
|
160
|
+
async function migrationFiles(dir) {
|
|
161
|
+
if (!existsSync(dir))
|
|
162
|
+
return [];
|
|
163
|
+
return (await readdir(dir)).filter((f) => /^\d{4}_[A-Za-z0-9_-]+\.sql$/.test(f)).sort();
|
|
164
|
+
}
|
|
165
|
+
async function cmdMigrate(args) {
|
|
166
|
+
const json = Boolean(args.flags.json);
|
|
167
|
+
const dir = path.join(cwd, MIGRATIONS_DIR);
|
|
168
|
+
const app = await loadApp(args);
|
|
169
|
+
try {
|
|
170
|
+
if (args.flags.apply) {
|
|
171
|
+
const files = await migrationFiles(dir);
|
|
172
|
+
const migrations = await Promise.all(files.map(async (f) => ({ name: f.slice(0, -4), sql: await readFile(path.join(dir, f), "utf8") })));
|
|
173
|
+
let edited = [];
|
|
174
|
+
const applied = await applyMigrations(app.db, migrations, { onEdited: (names) => (edited = names) });
|
|
175
|
+
if (edited.length && !json) {
|
|
176
|
+
const files = edited.map((name) => `${MIGRATIONS_DIR}/${name}.sql`).join(", ");
|
|
177
|
+
console.error(`Warning IL4018: ${files} ${edited.length > 1 ? "were" : "was"} edited after being applied, so the change was not run. Restore the applied SQL (git checkout) and put the change in a new migration: inferlo db migrate <name>`);
|
|
178
|
+
}
|
|
179
|
+
print({ ok: true, applied, edited }, json, () => (applied.length ? `Applied:\n${applied.map((a) => ` ${a}`).join("\n")}` : "No pending migrations."));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const snapshotFile = path.join(dir, "snapshot.json");
|
|
183
|
+
let previous;
|
|
184
|
+
if (existsSync(snapshotFile)) {
|
|
185
|
+
try {
|
|
186
|
+
previous = JSON.parse(await readFile(snapshotFile, "utf8"));
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
previous = null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const plan = planMigration(app.models, previous, { allowDrop: Boolean(args.flags["allow-drop"]), allowChange: Boolean(args.flags["allow-change"]) });
|
|
193
|
+
const dryRun = Boolean(args.flags["dry-run"]);
|
|
194
|
+
const dropNote = (plan.drops.length ? `\n\nThis migration deletes data: ${plan.drops.join(", ")}.` : "") +
|
|
195
|
+
(plan.changes.length ? `\n\nThis migration changes columns: ${plan.changes.join(", ")}.` : "");
|
|
196
|
+
if (!plan.statements.length || dryRun) {
|
|
197
|
+
print({ ok: true, dryRun, file: null, statements: plan.statements, drops: plan.drops, changes: plan.changes }, json, () => plan.statements.length ? `Would write:\n\n${plan.statements.join(";\n\n")};${dropNote}` : "No model changes since the last migration.");
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const files = await migrationFiles(dir);
|
|
201
|
+
const last = files.length ? Number(files[files.length - 1].slice(0, 4)) : 0;
|
|
202
|
+
const slug = String(args._[2] ?? "migration").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 60) || "migration";
|
|
203
|
+
const file = `${MIGRATIONS_DIR}/${String(last + 1).padStart(4, "0")}_${slug}.sql`;
|
|
204
|
+
await mkdir(dir, { recursive: true });
|
|
205
|
+
const warning = (plan.drops.length ? `-- WARNING: this migration deletes data (${plan.drops.join(", ")}). Back up first.\n` : "") +
|
|
206
|
+
(plan.changes.length ? `-- This migration changes columns: ${plan.changes.join(", ")}. Changing a type fails (IL4022) if a value does not convert; making a column required fails (IL4020) if rows still have NULL in it; removing an enum value fails (IL4021) if rows still use it.\n` : "");
|
|
207
|
+
await writeFile(path.join(cwd, file), `-- Generated by inferlo db migrate. Review before applying with: inferlo db migrate --apply\n${warning}\n${plan.statements.join(";\n\n")};\n`);
|
|
208
|
+
await writeFile(snapshotFile, JSON.stringify(plan.snapshot, null, 2) + "\n");
|
|
209
|
+
print({ ok: true, dryRun: false, file, statements: plan.statements, drops: plan.drops, changes: plan.changes }, json, () => `Wrote ${file}${dropNote}\nReview it, then run: inferlo db migrate --apply`);
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
await app.db.$close();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async function cmdCheck(args) {
|
|
216
|
+
const json = Boolean(args.flags.json);
|
|
217
|
+
const steps = [];
|
|
218
|
+
const timed = async (name, fn) => {
|
|
219
|
+
const step = { name, ok: true, durationMs: 0, errors: [] };
|
|
220
|
+
const start = Date.now();
|
|
221
|
+
try {
|
|
222
|
+
await fn(step);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
step.ok = false;
|
|
226
|
+
const e = error;
|
|
227
|
+
step.errors.push({ code: e.code, message: e.message ?? String(error), fix: e.fix });
|
|
228
|
+
}
|
|
229
|
+
step.durationMs = Date.now() - start;
|
|
230
|
+
steps.push(step);
|
|
231
|
+
if (!json)
|
|
232
|
+
console.log(`${step.skipped ? "skip" : step.ok ? "ok " : "FAIL"} ${name} (${step.durationMs} ms)`);
|
|
233
|
+
};
|
|
234
|
+
await timed("typecheck", async (step) => {
|
|
235
|
+
const tsc = path.join(cwd, "node_modules", ".bin", "tsc");
|
|
236
|
+
if (!existsSync(path.join(cwd, "tsconfig.json")) || !existsSync(tsc)) {
|
|
237
|
+
step.skipped = true;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const { code, output } = await run(tsc, ["--noEmit", "--pretty", "false"], { capture: true });
|
|
241
|
+
if (code !== 0) {
|
|
242
|
+
step.ok = false;
|
|
243
|
+
for (const line of output.split("\n")) {
|
|
244
|
+
const m = /^(.+?)\((\d+),\d+\): error (TS\d+): (.*)$/.exec(line.trim());
|
|
245
|
+
if (m)
|
|
246
|
+
step.errors.push({ file: m[1], line: Number(m[2]), code: m[3], message: m[4] });
|
|
247
|
+
}
|
|
248
|
+
if (!step.errors.length)
|
|
249
|
+
step.errors.push({ message: output.trim().slice(0, 4000) });
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
await timed("load", async () => {
|
|
253
|
+
await loadApp(args);
|
|
254
|
+
});
|
|
255
|
+
await timed("test", async (step) => {
|
|
256
|
+
const pkg = await readPackage();
|
|
257
|
+
if (!pkg?.scripts?.test) {
|
|
258
|
+
step.skipped = true;
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const { code, output } = await run("npm", ["test", "--silent"], { capture: true });
|
|
262
|
+
if (code !== 0) {
|
|
263
|
+
step.ok = false;
|
|
264
|
+
step.output = output.slice(-6000);
|
|
265
|
+
step.errors.push({ message: "Tests failed. See output." });
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
const ok = steps.every((s) => s.ok);
|
|
269
|
+
if (json)
|
|
270
|
+
console.log(JSON.stringify({ ok, steps }, null, 2));
|
|
271
|
+
else {
|
|
272
|
+
for (const s of steps.filter((s) => !s.ok)) {
|
|
273
|
+
console.log(`\n${s.name}:`);
|
|
274
|
+
for (const e of s.errors)
|
|
275
|
+
console.log(` ${e.file ? `${e.file}:${e.line} ` : ""}${e.code ? e.code + " " : ""}${e.message}${e.fix ? `\n Fix: ${e.fix}` : ""}`);
|
|
276
|
+
if (s.output)
|
|
277
|
+
console.log(s.output);
|
|
278
|
+
}
|
|
279
|
+
console.log(ok ? "\nAll checks passed." : "\nChecks failed.");
|
|
280
|
+
}
|
|
281
|
+
process.exitCode = ok ? 0 : 1;
|
|
282
|
+
}
|
|
283
|
+
async function cmdDev(args) {
|
|
284
|
+
const pkg = await readPackage();
|
|
285
|
+
const server = path.resolve(cwd, args.flags.entry || pkg?.inferlo?.server || pkg?.kairo?.server || "src/server.ts");
|
|
286
|
+
if (!existsSync(server))
|
|
287
|
+
throw new InferloError("IL8001", `Server file ${path.relative(cwd, server)} not found.`, { fix: "Create src/server.ts that calls app.listen()." });
|
|
288
|
+
const isBun = Boolean(globalThis.Bun);
|
|
289
|
+
const cmd = isBun ? "bun" : process.execPath;
|
|
290
|
+
const argv = isBun ? ["--watch", server] : ["--watch", "--env-file-if-exists=.env", server];
|
|
291
|
+
const { code } = await run(cmd, argv);
|
|
292
|
+
process.exitCode = code;
|
|
293
|
+
}
|
|
294
|
+
async function cmdWorker(args) {
|
|
295
|
+
const json = Boolean(args.flags.json);
|
|
296
|
+
// Like inferlo dev: read .env before the app reads its environment. Variables already set win.
|
|
297
|
+
const envFile = path.join(cwd, ".env");
|
|
298
|
+
const loadEnvFile = process.loadEnvFile;
|
|
299
|
+
if (existsSync(envFile) && typeof loadEnvFile === "function")
|
|
300
|
+
loadEnvFile(envFile);
|
|
301
|
+
const app = await loadApp(args);
|
|
302
|
+
const names = app.jobs.list.map((j) => j.name);
|
|
303
|
+
if (!names.length) {
|
|
304
|
+
throw new InferloError("IL8007", "The app has no background jobs, so there is nothing for inferlo worker to run.", {
|
|
305
|
+
fix: 'Define jobs with job("name", { input }).handle(fn) in src/jobs.ts and register them: createApp({ jobs: [jobs] }).',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (app.jobs.queue !== "database") {
|
|
309
|
+
throw new InferloError("IL8008", `inferlo worker needs the database job queue, but the app keeps jobs in ${app.jobs.queue}, where a separate process cannot see them.`, {
|
|
310
|
+
fix: 'Use createApp({ jobQueue: { store: "database" }, db: postgres({ url }) }), or run jobs in the server process with app.jobs.start().',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const say = (event, text) => console.log(json ? JSON.stringify({ ok: true, event, jobs: names, queue: app.jobs.queue }) : text);
|
|
314
|
+
// Listen for signals before announcing the start, so a signal right after "started" is never missed.
|
|
315
|
+
const stopSignal = new Promise((resolve) => {
|
|
316
|
+
let received = false;
|
|
317
|
+
const onSignal = (name) => {
|
|
318
|
+
// A second signal while waiting for the running job stops at once.
|
|
319
|
+
if (received)
|
|
320
|
+
process.exit(1);
|
|
321
|
+
received = true;
|
|
322
|
+
resolve(name);
|
|
323
|
+
};
|
|
324
|
+
process.on("SIGTERM", onSignal);
|
|
325
|
+
process.on("SIGINT", onSignal);
|
|
326
|
+
});
|
|
327
|
+
const worker = app.jobs.start();
|
|
328
|
+
say("started", `inferlo worker: running ${names.length} job(s) (${names.join(", ")}) from the database queue. Stop with Ctrl+C or SIGTERM.`);
|
|
329
|
+
const signal = await stopSignal;
|
|
330
|
+
if (!json)
|
|
331
|
+
console.log(`inferlo worker: ${signal} received, waiting for the running job to finish.`);
|
|
332
|
+
await worker.stop();
|
|
333
|
+
await app.db.$close?.();
|
|
334
|
+
say("stopped", "inferlo worker: stopped.");
|
|
335
|
+
process.exitCode = 0;
|
|
336
|
+
}
|
|
337
|
+
// --- generators --------------------------------------------------------------------------
|
|
338
|
+
const templatesDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "templates");
|
|
339
|
+
async function copyTemplate(from, to, vars, created) {
|
|
340
|
+
await mkdir(to, { recursive: true });
|
|
341
|
+
for (const entry of await readdir(from, { withFileTypes: true })) {
|
|
342
|
+
const src = path.join(from, entry.name);
|
|
343
|
+
const name = entry.name.replace(/^_/, ".").replace(/\.tpl$/, "");
|
|
344
|
+
const dest = path.join(to, name);
|
|
345
|
+
if (entry.isDirectory())
|
|
346
|
+
await copyTemplate(src, dest, vars, created);
|
|
347
|
+
else {
|
|
348
|
+
let text = await readFile(src, "utf8");
|
|
349
|
+
for (const [k, v] of Object.entries(vars))
|
|
350
|
+
text = text.replaceAll(`{{${k}}}`, v);
|
|
351
|
+
await writeFile(dest, text);
|
|
352
|
+
created.push(dest);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
async function cmdNew(args) {
|
|
357
|
+
const dir = args._[1];
|
|
358
|
+
if (!dir)
|
|
359
|
+
throw new InferloError("IL8004", "Missing project directory.", { fix: "Use: inferlo new my-app" });
|
|
360
|
+
const target = path.resolve(cwd, dir);
|
|
361
|
+
if (existsSync(target) && (await readdir(target)).length)
|
|
362
|
+
throw new InferloError("IL8005", `${dir} already exists and is not empty.`);
|
|
363
|
+
const name = path.basename(target).toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
364
|
+
const created = [];
|
|
365
|
+
await copyTemplate(path.join(templatesDir, "app"), target, { name, inferloVersion: INFERLO_VERSION, inferloDependency: `^${INFERLO_VERSION}` }, created);
|
|
366
|
+
print({ ok: true, dir, files: created.map((f) => path.relative(cwd, f)) }, Boolean(args.flags.json), () => [`Created ${dir}`, "", "Next:", ` cd ${dir}`, " npm install", " npm run dev", "", "AGENTS.md explains the conventions to AI coding agents."].join("\n"));
|
|
367
|
+
}
|
|
368
|
+
function pascal(name) {
|
|
369
|
+
return name.replace(/(^|[_-])([a-z])/g, (_, __, c) => c.toUpperCase());
|
|
370
|
+
}
|
|
371
|
+
function singularOf(name) {
|
|
372
|
+
return name.endsWith("ies") ? name.slice(0, -3) + "y" : name.endsWith("s") ? name.slice(0, -1) : name;
|
|
373
|
+
}
|
|
374
|
+
async function cmdAdd(args) {
|
|
375
|
+
const kind = args._[1];
|
|
376
|
+
const raw = args._[2];
|
|
377
|
+
if (kind !== "resource" || !raw)
|
|
378
|
+
throw new InferloError("IL8006", "Use: inferlo add resource <plural_name>, e.g. inferlo add resource invoices");
|
|
379
|
+
const table = raw.toLowerCase().replace(/-/g, "_");
|
|
380
|
+
if (!/^[a-z][a-z0-9_]*$/.test(table))
|
|
381
|
+
throw new InferloError("IL4005", `"${raw}" is not a valid table name.`, { fix: "Use lowercase letters, digits and underscores." });
|
|
382
|
+
const Model = pascal(singularOf(table));
|
|
383
|
+
const routesDir = path.join(cwd, "src", "routes");
|
|
384
|
+
const routeFile = path.join(routesDir, `${table}.ts`);
|
|
385
|
+
if (existsSync(routeFile))
|
|
386
|
+
throw new InferloError("IL8005", `src/routes/${table}.ts already exists.`);
|
|
387
|
+
const changes = [];
|
|
388
|
+
const manual = [];
|
|
389
|
+
const modelsFile = path.join(cwd, "src", "models.ts");
|
|
390
|
+
const modelCode = `export const ${Model} = model("${table}", {\n name: t.string().max(200),\n ownerId: t.ref("users"),\n});\n`;
|
|
391
|
+
if (existsSync(modelsFile)) {
|
|
392
|
+
let text = await readFile(modelsFile, "utf8");
|
|
393
|
+
if (text.includes("// inferlo:models")) {
|
|
394
|
+
text = text.replace("// inferlo:models", `${modelCode}\n// inferlo:models`);
|
|
395
|
+
text = text.replace(/export const models = \[([^\]]*)\]/, (m, list) => `export const models = [${list.trim() ? list.trim().replace(/,\s*$/, "") + ", " : ""}${Model}]`);
|
|
396
|
+
await writeFile(modelsFile, text);
|
|
397
|
+
changes.push("src/models.ts");
|
|
398
|
+
}
|
|
399
|
+
else
|
|
400
|
+
manual.push(`Add to src/models.ts:\n${modelCode}\nand add ${Model} to the models array.`);
|
|
401
|
+
}
|
|
402
|
+
else
|
|
403
|
+
manual.push(`Create the ${Model} model:\n${modelCode}`);
|
|
404
|
+
const routeCode = `import { route, t, notFound } from "@browserlessapi/inferlo";
|
|
405
|
+
import { ${Model} } from "../models.ts";
|
|
406
|
+
|
|
407
|
+
const IdParams = t.object({ id: t.uuid() });
|
|
408
|
+
|
|
409
|
+
export const list${pascal(table)} = route
|
|
410
|
+
.get("/${table}", {
|
|
411
|
+
summary: "List ${table}",
|
|
412
|
+
query: t.object({ limit: t.int().min(1).max(100).default(20), offset: t.int().min(0).default(0) }),
|
|
413
|
+
tool: true,
|
|
414
|
+
})
|
|
415
|
+
.handle(({ query, user, db }) =>
|
|
416
|
+
db.${table}.findMany({ where: { ownerId: user.id }, orderBy: { createdAt: "desc" }, limit: query.limit, offset: query.offset }),
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
export const get${Model} = route
|
|
420
|
+
.get("/${table}/:id", { params: IdParams, summary: "Get one ${singularOf(table)}", tool: true })
|
|
421
|
+
.handle(async ({ params, user, db }) => {
|
|
422
|
+
const row = await db.${table}.get(params.id);
|
|
423
|
+
if (row.ownerId !== user.id) throw notFound();
|
|
424
|
+
return row;
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
export const create${Model} = route
|
|
428
|
+
.post("/${table}", { body: ${Model}.omit("ownerId"), summary: "Create a ${singularOf(table)}", tool: true })
|
|
429
|
+
.handle(({ body, user, db, status }) => {
|
|
430
|
+
status(201);
|
|
431
|
+
return db.${table}.insert({ ...body, ownerId: user.id });
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
export const update${Model} = route
|
|
435
|
+
.patch("/${table}/:id", { params: IdParams, body: ${Model}.omit("ownerId").partial(), summary: "Update a ${singularOf(table)}" })
|
|
436
|
+
.handle(async ({ params, body, user, db }) => {
|
|
437
|
+
const row = await db.${table}.get(params.id);
|
|
438
|
+
if (row.ownerId !== user.id) throw notFound();
|
|
439
|
+
return db.${table}.update(row.id, body);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
export const delete${Model} = route
|
|
443
|
+
.delete("/${table}/:id", { params: IdParams, summary: "Delete a ${singularOf(table)}" })
|
|
444
|
+
.handle(async ({ params, user, db }) => {
|
|
445
|
+
const row = await db.${table}.get(params.id);
|
|
446
|
+
if (row.ownerId !== user.id) throw notFound();
|
|
447
|
+
await db.${table}.delete(row.id);
|
|
448
|
+
});
|
|
449
|
+
`;
|
|
450
|
+
await mkdir(routesDir, { recursive: true });
|
|
451
|
+
await writeFile(routeFile, routeCode);
|
|
452
|
+
changes.push(`src/routes/${table}.ts`);
|
|
453
|
+
const appFile = path.join(cwd, "src", "app.ts");
|
|
454
|
+
if (existsSync(appFile)) {
|
|
455
|
+
let text = await readFile(appFile, "utf8");
|
|
456
|
+
if (text.includes("// inferlo:routes")) {
|
|
457
|
+
text = text.replace(/^(import .*\n)(?![\s\S]*^import )/m, `$1import * as ${table} from "./routes/${table}.ts";\n`);
|
|
458
|
+
text = text.replace(/routes: \[([^\]]*)\]/, (_m, list) => `routes: [${list.trim() ? list.trim().replace(/,\s*$/, "") + ", " : ""}${table}]`);
|
|
459
|
+
await writeFile(appFile, text);
|
|
460
|
+
changes.push("src/app.ts");
|
|
461
|
+
}
|
|
462
|
+
else
|
|
463
|
+
manual.push(`Add to src/app.ts:\nimport * as ${table} from "./routes/${table}.ts";\nand add ${table} to createApp({ routes: [...] }).`);
|
|
464
|
+
}
|
|
465
|
+
print({ ok: true, changed: changes, manual }, Boolean(args.flags.json), () => [`Updated: ${changes.join(", ")}`, ...manual.map((m) => `\nTo do:\n${m}`), "", "Then run: inferlo db push && inferlo check"].join("\n"));
|
|
466
|
+
}
|
|
467
|
+
// ---------------------------------------------------------------------------------------------
|
|
468
|
+
async function main() {
|
|
469
|
+
const args = parseArgs(process.argv.slice(2));
|
|
470
|
+
const command = args._[0];
|
|
471
|
+
try {
|
|
472
|
+
switch (command) {
|
|
473
|
+
case "new":
|
|
474
|
+
return await cmdNew(args);
|
|
475
|
+
case "dev":
|
|
476
|
+
return await cmdDev(args);
|
|
477
|
+
case "worker":
|
|
478
|
+
return await cmdWorker(args);
|
|
479
|
+
case "describe":
|
|
480
|
+
return await cmdDescribe(args);
|
|
481
|
+
case "check":
|
|
482
|
+
return await cmdCheck(args);
|
|
483
|
+
case "db":
|
|
484
|
+
return await cmdDb(args);
|
|
485
|
+
case "openapi":
|
|
486
|
+
return await cmdOpenapi(args);
|
|
487
|
+
case "add":
|
|
488
|
+
return await cmdAdd(args);
|
|
489
|
+
case "version":
|
|
490
|
+
case "--version":
|
|
491
|
+
case "-v":
|
|
492
|
+
return console.log(INFERLO_VERSION);
|
|
493
|
+
case undefined:
|
|
494
|
+
case "help":
|
|
495
|
+
case "--help":
|
|
496
|
+
case "-h":
|
|
497
|
+
return console.log(HELP);
|
|
498
|
+
default:
|
|
499
|
+
throw new InferloError("IL8000", `Unknown command "${command}".`, { fix: "Run inferlo help to see all commands." });
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
const json = Boolean(args.flags.json);
|
|
504
|
+
if (error instanceof InferloError) {
|
|
505
|
+
if (json)
|
|
506
|
+
console.log(JSON.stringify({ ok: false, ...error.toJSON(), message: error.message }, null, 2));
|
|
507
|
+
else
|
|
508
|
+
console.error(error.format());
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
if (json)
|
|
512
|
+
console.log(JSON.stringify({ ok: false, error: { code: "IL9000", message: String(error?.message ?? error) } }, null, 2));
|
|
513
|
+
else
|
|
514
|
+
console.error(error);
|
|
515
|
+
}
|
|
516
|
+
process.exitCode = 1;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
await main();
|
|
520
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Client IP addresses of incoming requests, recorded by serve() (Node) where the Request cannot carry them. */
|
|
2
|
+
export declare const clientIps: WeakMap<Request, string>;
|
|
3
|
+
/**
|
|
4
|
+
* The client IP of a request. With trustProxy, the first X-Forwarded-For address (set by your load balancer).
|
|
5
|
+
* Otherwise the socket address from serve() (Node), Bun's server.requestIP or Deno's remoteAddr, or "unknown".
|
|
6
|
+
*/
|
|
7
|
+
export declare function clientIp(req: Request, trustProxy: boolean, platform: unknown): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Client IP addresses of incoming requests, recorded by serve() (Node) where the Request cannot carry them. */
|
|
2
|
+
export const clientIps = new WeakMap();
|
|
3
|
+
/**
|
|
4
|
+
* The client IP of a request. With trustProxy, the first X-Forwarded-For address (set by your load balancer).
|
|
5
|
+
* Otherwise the socket address from serve() (Node), Bun's server.requestIP or Deno's remoteAddr, or "unknown".
|
|
6
|
+
*/
|
|
7
|
+
export function clientIp(req, trustProxy, platform) {
|
|
8
|
+
if (trustProxy) {
|
|
9
|
+
const forwarded = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
|
|
10
|
+
if (forwarded)
|
|
11
|
+
return forwarded;
|
|
12
|
+
}
|
|
13
|
+
const recorded = clientIps.get(req);
|
|
14
|
+
if (recorded)
|
|
15
|
+
return recorded;
|
|
16
|
+
const p = platform;
|
|
17
|
+
try {
|
|
18
|
+
const address = p?.requestIP?.(req)?.address ?? p?.remoteAddr?.hostname;
|
|
19
|
+
if (address)
|
|
20
|
+
return address;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Not a Bun server or Deno info object.
|
|
24
|
+
}
|
|
25
|
+
return "unknown";
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=client-ip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-ip.js","sourceRoot":"","sources":["../src/client-ip.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,OAAO,EAAmB,CAAC;AAExD;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAY,EAAE,UAAmB,EAAE,QAAiB;IAC3E,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5E,IAAI,SAAS;YAAE,OAAO,SAAS,CAAC;IAClC,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,CAAC,GAAG,QAAmH,CAAC;IAC9H,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC;QACxE,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/cron.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { JobDef } from "./jobs.ts";
|
|
2
|
+
export interface CronDef<J extends JobDef = JobDef> {
|
|
3
|
+
readonly kind: "inferlo.cron";
|
|
4
|
+
/** The five-field schedule: minute hour day-of-month month day-of-week, in UTC. */
|
|
5
|
+
readonly schedule: string;
|
|
6
|
+
/** The job queued at every tick, with input {}. */
|
|
7
|
+
readonly job: J;
|
|
8
|
+
/** The first tick strictly after the given time. */
|
|
9
|
+
next(after: Date): Date;
|
|
10
|
+
}
|
|
11
|
+
/** Parse a schedule into a function giving the first tick strictly after a time. Raises IL6013. */
|
|
12
|
+
export declare function parseCron(schedule: string): (after: Date) => Date;
|
|
13
|
+
/** Run a job on a schedule: export const hourly = cron("0 * * * *", sendReport). Times are UTC. */
|
|
14
|
+
export declare function cron<J extends JobDef>(schedule: string, job: J): CronDef<J>;
|
|
15
|
+
export declare function isCron(value: unknown): value is CronDef;
|
|
16
|
+
/** A fixed UUID for one tick of a cron, so every instance queues the same job id. */
|
|
17
|
+
export declare function cronTickId(def: CronDef, tick: Date): Promise<string>;
|