@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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -2
  3. package/dist/ai/index.d.ts +138 -0
  4. package/dist/ai/index.js +450 -0
  5. package/dist/ai/index.js.map +1 -0
  6. package/dist/ai/providers.d.ts +150 -0
  7. package/dist/ai/providers.js +294 -0
  8. package/dist/ai/providers.js.map +1 -0
  9. package/dist/app.d.ts +109 -0
  10. package/dist/app.js +419 -0
  11. package/dist/app.js.map +1 -0
  12. package/dist/auth.d.ts +29 -0
  13. package/dist/auth.js +61 -0
  14. package/dist/auth.js.map +1 -0
  15. package/dist/cli/main.d.ts +2 -0
  16. package/dist/cli/main.js +520 -0
  17. package/dist/cli/main.js.map +1 -0
  18. package/dist/client-ip.d.ts +7 -0
  19. package/dist/client-ip.js +27 -0
  20. package/dist/client-ip.js.map +1 -0
  21. package/dist/cron.d.ts +17 -0
  22. package/dist/cron.js +143 -0
  23. package/dist/cron.js.map +1 -0
  24. package/dist/db/memory.d.ts +2 -0
  25. package/dist/db/memory.js +128 -0
  26. package/dist/db/memory.js.map +1 -0
  27. package/dist/db/migrate.d.ts +87 -0
  28. package/dist/db/migrate.js +471 -0
  29. package/dist/db/migrate.js.map +1 -0
  30. package/dist/db/postgres.d.ts +37 -0
  31. package/dist/db/postgres.js +338 -0
  32. package/dist/db/postgres.js.map +1 -0
  33. package/dist/db/table.d.ts +117 -0
  34. package/dist/db/table.js +274 -0
  35. package/dist/db/table.js.map +1 -0
  36. package/dist/db/types.d.ts +36 -0
  37. package/dist/db/types.js +2 -0
  38. package/dist/db/types.js.map +1 -0
  39. package/dist/describe.d.ts +74 -0
  40. package/dist/describe.js +69 -0
  41. package/dist/describe.js.map +1 -0
  42. package/dist/env.d.ts +19 -0
  43. package/dist/env.js +72 -0
  44. package/dist/env.js.map +1 -0
  45. package/dist/errors.d.ts +40 -0
  46. package/dist/errors.js +99 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/index.d.ts +31 -0
  49. package/dist/index.js +20 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/jobs.d.ts +177 -0
  52. package/dist/jobs.js +374 -0
  53. package/dist/jobs.js.map +1 -0
  54. package/dist/mcp.d.ts +22 -0
  55. package/dist/mcp.js +171 -0
  56. package/dist/mcp.js.map +1 -0
  57. package/dist/model.d.ts +36 -0
  58. package/dist/model.js +76 -0
  59. package/dist/model.js.map +1 -0
  60. package/dist/openapi.d.ts +6 -0
  61. package/dist/openapi.js +74 -0
  62. package/dist/openapi.js.map +1 -0
  63. package/dist/rate-limit.d.ts +45 -0
  64. package/dist/rate-limit.js +93 -0
  65. package/dist/rate-limit.js.map +1 -0
  66. package/dist/route.d.ts +131 -0
  67. package/dist/route.js +28 -0
  68. package/dist/route.js.map +1 -0
  69. package/dist/schema.d.ts +164 -0
  70. package/dist/schema.js +442 -0
  71. package/dist/schema.js.map +1 -0
  72. package/dist/serve.d.ts +11 -0
  73. package/dist/serve.js +86 -0
  74. package/dist/serve.js.map +1 -0
  75. package/dist/testing.d.ts +16 -0
  76. package/dist/testing.js +30 -0
  77. package/dist/testing.js.map +1 -0
  78. package/llms.txt +27 -0
  79. package/package.json +82 -4
  80. package/templates/app/AGENTS.md +55 -0
  81. package/templates/app/CLAUDE.md +1 -0
  82. package/templates/app/README.md +16 -0
  83. package/templates/app/_env.example +5 -0
  84. package/templates/app/_gitignore +3 -0
  85. package/templates/app/package.json.tpl +32 -0
  86. package/templates/app/src/app.ts +38 -0
  87. package/templates/app/src/models.ts +31 -0
  88. package/templates/app/src/routes/health.ts +3 -0
  89. package/templates/app/src/routes/notes.ts +56 -0
  90. package/templates/app/src/server.ts +26 -0
  91. package/templates/app/test/notes.test.ts +50 -0
  92. package/templates/app/tsconfig.json +17 -0
package/dist/app.js ADDED
@@ -0,0 +1,419 @@
1
+ /**
2
+ * createApp wires models, routes, database, auth and AI together and gives you a standard
3
+ * fetch(Request) => Response handler that runs on Node, Bun, Deno and edge runtimes.
4
+ */
5
+ import { bindTools, createAI } from "./ai/index.js";
6
+ import { memory } from "./db/memory.js";
7
+ import { createDb } from "./db/table.js";
8
+ import { describeApp } from "./describe.js";
9
+ import { InferloError, didYouMean, suggest } from "./errors.js";
10
+ import { callTool, handleMcp, toolDefinition } from "./mcp.js";
11
+ import { buildOpenAPI } from "./openapi.js";
12
+ import { isRoute } from "./route.js";
13
+ import { checkRateLimit, databaseRateLimitStore, memoryRateLimitStore, rateLimitResult, windowMs } from "./rate-limit.js";
14
+ import { clientIp, clientIps } from "./client-ip.js";
15
+ import { collectCrons, collectJobs, createJobs, jobStoreFor } from "./jobs.js";
16
+ import { ValidationError } from "./schema.js";
17
+ const testUsers = new WeakMap();
18
+ function compile(def) {
19
+ if (!def.path.startsWith("/")) {
20
+ throw new InferloError("IL6003", `Route path "${def.path}" must start with "/".`, { fix: `Use "/${def.path}".` });
21
+ }
22
+ const keys = [];
23
+ let score = 0;
24
+ const parts = def.path.split("/").filter(Boolean);
25
+ const pattern = parts
26
+ .map((part, i) => {
27
+ if (part === "*" && i === parts.length - 1) {
28
+ keys.push("*");
29
+ return "(?:/(.*))?";
30
+ }
31
+ if (part.startsWith(":")) {
32
+ keys.push(part.slice(1));
33
+ score += 1;
34
+ return "/([^/]+)";
35
+ }
36
+ score += 3;
37
+ return "/" + part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38
+ })
39
+ .join("");
40
+ return { def, regex: new RegExp(`^${pattern || ""}/?$`), keys, score: score * 10 + parts.length };
41
+ }
42
+ function collectRoutes(sources) {
43
+ const out = [];
44
+ const seen = new Set();
45
+ const visit = (source, name) => {
46
+ if (!source || typeof source !== "object" || seen.has(source))
47
+ return;
48
+ seen.add(source);
49
+ if (isRoute(source)) {
50
+ out.push(name && !source.name ? { ...source, name } : source);
51
+ return;
52
+ }
53
+ if (Array.isArray(source)) {
54
+ for (const item of source)
55
+ visit(item);
56
+ return;
57
+ }
58
+ for (const [key, value] of Object.entries(source))
59
+ if (isRoute(value) || Array.isArray(value))
60
+ visit(value, key === "default" ? undefined : key);
61
+ };
62
+ visit(sources);
63
+ return out;
64
+ }
65
+ function corsHeaders(config, origin) {
66
+ const allowed = config.origin === "*" ? "*" : origin && (Array.isArray(config.origin) ? config.origin : [config.origin]).includes(origin) ? origin : null;
67
+ if (!allowed)
68
+ return {};
69
+ const h = { "access-control-allow-origin": allowed, vary: "origin" };
70
+ if (config.credentials)
71
+ h["access-control-allow-credentials"] = "true";
72
+ return h;
73
+ }
74
+ async function readBody(req, limit) {
75
+ const length = Number(req.headers.get("content-length") ?? "0");
76
+ if (length > limit)
77
+ throw new InferloError("IL2004", `Request body is larger than ${limit} bytes.`, { status: 413 });
78
+ if (!req.body)
79
+ return "";
80
+ const reader = req.body.getReader();
81
+ const chunks = [];
82
+ let size = 0;
83
+ while (true) {
84
+ const { value, done } = await reader.read();
85
+ if (done)
86
+ break;
87
+ size += value.byteLength;
88
+ if (size > limit) {
89
+ await reader.cancel();
90
+ throw new InferloError("IL2004", `Request body is larger than ${limit} bytes.`, { status: 413 });
91
+ }
92
+ chunks.push(value);
93
+ }
94
+ const all = new Uint8Array(size);
95
+ let offset = 0;
96
+ for (const c of chunks) {
97
+ all.set(c, offset);
98
+ offset += c.byteLength;
99
+ }
100
+ return new TextDecoder().decode(all);
101
+ }
102
+ function queryObject(url) {
103
+ const out = {};
104
+ for (const key of new Set(url.searchParams.keys())) {
105
+ const all = url.searchParams.getAll(key);
106
+ out[key] = all.length > 1 ? all : all[0];
107
+ }
108
+ return out;
109
+ }
110
+ function json(data, status, headers) {
111
+ headers.set("content-type", "application/json; charset=utf-8");
112
+ return new Response(JSON.stringify(data), { status, headers });
113
+ }
114
+ export function createApp(config = {}) {
115
+ const logger = config.logger ?? {
116
+ info: (m, d) => console.log(`[inferlo] ${m}`, d ?? ""),
117
+ error: (m, d) => console.error(`[inferlo] ${m}`, d ?? ""),
118
+ };
119
+ const models = (config.models ?? []);
120
+ const modelNames = new Set();
121
+ for (const m of models) {
122
+ if (modelNames.has(m.name))
123
+ throw new InferloError("IL6004", `Two models are named "${m.name}".`, { fix: "Model names must be unique." });
124
+ modelNames.add(m.name);
125
+ }
126
+ for (const m of models) {
127
+ for (const [field, schema] of Object.entries(m.fields)) {
128
+ const ref = schema.def.refTable;
129
+ if (ref && !modelNames.has(ref)) {
130
+ throw new InferloError("IL6005", `${m.name}.${field} references "${ref}", which is not a registered model.${didYouMean(ref, modelNames)}`, {
131
+ fix: `Add the "${ref}" model to createApp({ models: [...] }) or fix the name in t.ref().`,
132
+ });
133
+ }
134
+ }
135
+ }
136
+ const routes = collectRoutes(config.routes);
137
+ const compiled = routes.map(compile).sort((a, b) => b.score - a.score);
138
+ const signatures = new Map();
139
+ for (const r of routes) {
140
+ const sig = `${r.method} ${r.path.replace(/:[^/]+/g, ":")}`;
141
+ if (signatures.has(sig)) {
142
+ throw new InferloError("IL6001", `Duplicate route ${r.method} ${r.path}.`, { fix: "Each method and path may only be defined once." });
143
+ }
144
+ signatures.set(sig, r);
145
+ }
146
+ const names = new Map();
147
+ for (const r of routes) {
148
+ if (!r.name)
149
+ continue;
150
+ if (names.has(r.name) && names.get(r.name) !== r) {
151
+ throw new InferloError("IL6006", `Two routes are exported as "${r.name}".`, { fix: "Give each route export a unique name; it is used for MCP tools and describe." });
152
+ }
153
+ names.set(r.name, r);
154
+ }
155
+ const needsAuth = routes.filter((r) => (r.options.auth ?? "user") !== "public");
156
+ if (needsAuth.length && !config.auth) {
157
+ throw new InferloError("IL3003", `${needsAuth.length} route(s) require a signed-in user, but createApp has no auth configured: ${needsAuth.map((r) => `${r.method} ${r.path}`).join(", ")}.`, {
158
+ fix: 'Routes are private by default. Add auth: "public" to routes anyone may call, or pass createApp({ auth: { resolve(req) { ... } } }).',
159
+ });
160
+ }
161
+ for (const r of routes)
162
+ if (r.options.rateLimit !== undefined)
163
+ checkRateLimit(r.options.rateLimit, `${r.method} ${r.path}`);
164
+ const storeName = config.rateLimit?.store ?? "memory";
165
+ if (storeName !== "memory" && storeName !== "database") {
166
+ throw new InferloError("IL6007", `Invalid rateLimit store "${String(storeName)}".`, { fix: 'Use createApp({ rateLimit: { store: "memory" } }) or { store: "database" }.' });
167
+ }
168
+ const adapter = config.db ?? memory();
169
+ const db = createDb(models, adapter);
170
+ const rateLimits = storeName === "database" ? databaseRateLimitStore(adapter) : memoryRateLimitStore();
171
+ const ai = createAI(config.ai);
172
+ const jobs = createJobs(collectJobs(config.jobs), { db: db, ai, store: jobStoreFor(config.jobQueue, adapter), queue: config.jobQueue?.store ?? "memory", logger }, collectCrons(config.jobs));
173
+ const maxBody = config.maxBodySize ?? 1024 * 1024;
174
+ const cors = config.cors === true ? { origin: "*" } : config.cors || undefined;
175
+ const openapiPath = config.openapi === undefined ? "/openapi.json" : config.openapi;
176
+ const hasTools = routes.some((r) => r.options.tool);
177
+ const mcpPath = config.mcp === undefined ? (hasTools ? "/mcp" : false) : config.mcp;
178
+ // Routes passed to ai.generate({ tools }) are matched to the registered route by method and path.
179
+ const registeredTool = (route) => {
180
+ const found = routes.find((r) => r.method === route?.method && r.path === route?.path);
181
+ if (!found) {
182
+ throw new InferloError("IL5011", `Tool ${route?.method} ${route?.path} is not a route of this app.`, {
183
+ fix: "Pass routes that are registered in createApp({ routes }) to ai.generate({ tools }).",
184
+ });
185
+ }
186
+ return toolDefinition(found);
187
+ };
188
+ const describeTool = (route) => {
189
+ const { name, description, inputSchema } = registeredTool(route);
190
+ return { name, description, inputSchema };
191
+ };
192
+ const toolsFor = (req) => bindTools(ai, async (route, input) => {
193
+ const tool = registeredTool(route);
194
+ const response = await callTool(app, tool, input, req, testUsers);
195
+ const text = await response.text();
196
+ let output = text;
197
+ try {
198
+ output = text ? JSON.parse(text) : null;
199
+ }
200
+ catch {
201
+ // Not JSON: the model sees the text as it is.
202
+ }
203
+ return { name: tool.name, status: response.status, output, text: text || String(response.status) };
204
+ }, describeTool);
205
+ const roles = (user) => config.auth?.roles?.(user) ?? (user.roles ?? []);
206
+ const errorResponse = (error, headers, req) => {
207
+ if (error instanceof InferloError) {
208
+ if (error.status >= 500)
209
+ logger.error(`${req.method} ${new URL(req.url).pathname} failed: ${error.format()}`, error.cause ?? "");
210
+ const body = error.toJSON();
211
+ if (config.exposeErrors && !error.expose)
212
+ body.error.message = error.message;
213
+ return json(body, error.status, headers);
214
+ }
215
+ logger.error(`${req.method} ${new URL(req.url).pathname} failed`, error);
216
+ const message = config.exposeErrors && error instanceof Error ? error.message : "Internal server error";
217
+ return json({ error: { code: "IL9000", message, docs: new InferloError("IL9000", "").docs } }, 500, headers);
218
+ };
219
+ const dispatch = async (req, url, state, pending, ip) => {
220
+ const headers = new Headers();
221
+ if (cors)
222
+ for (const [k, v] of Object.entries(corsHeaders(cors, req.headers.get("origin"))))
223
+ headers.set(k, v);
224
+ try {
225
+ const method = req.method.toUpperCase();
226
+ if (method === "OPTIONS" && cors) {
227
+ headers.set("access-control-allow-methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
228
+ headers.set("access-control-allow-headers", (cors.headers ?? ["content-type", "authorization"]).join(", "));
229
+ headers.set("access-control-max-age", String(cors.maxAge ?? 600));
230
+ return new Response(null, { status: 204, headers });
231
+ }
232
+ if (openapiPath && url.pathname === openapiPath && method === "GET")
233
+ return json(app.openapi(), 200, headers);
234
+ if (mcpPath && url.pathname === mcpPath)
235
+ return await handleMcp(app, req, headers, testUsers);
236
+ const lookup = method === "HEAD" ? "GET" : method;
237
+ let match;
238
+ const allowed = [];
239
+ for (const c of compiled) {
240
+ const m = c.regex.exec(url.pathname);
241
+ if (!m)
242
+ continue;
243
+ if (c.def.method === lookup) {
244
+ match = { route: c, values: m.slice(1) };
245
+ break;
246
+ }
247
+ allowed.push(c.def.method);
248
+ }
249
+ if (!match) {
250
+ if (allowed.length) {
251
+ headers.set("allow", [...new Set(allowed)].join(", "));
252
+ throw new InferloError("IL2002", `${method} is not allowed on ${url.pathname}. Allowed: ${[...new Set(allowed)].join(", ")}.`, { status: 405 });
253
+ }
254
+ const near = suggest(url.pathname, routes.map((r) => r.path));
255
+ throw new InferloError("IL2001", `No route matches ${method} ${url.pathname}.${near ? ` Closest route: ${near}.` : ""}`, { status: 404 });
256
+ }
257
+ const { def, keys } = match.route;
258
+ const opts = def.options;
259
+ // Auth
260
+ let user = null;
261
+ if (testUsers.has(req))
262
+ user = testUsers.get(req) ?? null;
263
+ else if (config.auth)
264
+ user = (await config.auth.resolve(req, { db: db, url })) ?? null;
265
+ const level = opts.auth ?? "user";
266
+ if (level !== "public") {
267
+ if (!user)
268
+ throw new InferloError("IL3001", "Sign in required.", { status: 401, fix: "Send valid credentials, e.g. an Authorization: Bearer <token> header." });
269
+ if (level !== "user" && !roles(user).includes(level))
270
+ throw new InferloError("IL3002", `This requires the "${level}" role.`, { status: 403 });
271
+ }
272
+ // Rate limit: counted per user (or IP without one), after auth so failed sign-ins on private routes do not use it up.
273
+ if (opts.rateLimit) {
274
+ const who = (opts.rateLimit.by ?? "user") === "user" && user ? `user:${user.id}` : `ip:${ip}`;
275
+ const hit = await rateLimits.hit(`${def.method} ${def.path} ${who}`, windowMs(opts.rateLimit));
276
+ const limited = rateLimitResult(opts.rateLimit, hit);
277
+ for (const [k, v] of Object.entries(limited.headers))
278
+ headers.set(k, v);
279
+ if (limited.error)
280
+ throw limited.error;
281
+ }
282
+ // Input
283
+ const rawParams = {};
284
+ keys.forEach((key, i) => {
285
+ const v = match.values[i];
286
+ if (v !== undefined)
287
+ rawParams[key] = decodeURIComponent(v);
288
+ });
289
+ const params = opts.params ? parseOrThrow(opts.params, rawParams, "path parameters", true) : rawParams;
290
+ const rawQuery = queryObject(url);
291
+ const query = opts.query ? parseOrThrow(opts.query.strip(), rawQuery, "query string", true) : rawQuery;
292
+ let body;
293
+ if (opts.body) {
294
+ const text = method === "GET" || method === "HEAD" ? "" : await readBody(req, maxBody);
295
+ const type = req.headers.get("content-type") ?? "";
296
+ let raw = undefined;
297
+ if (text) {
298
+ if (type.includes("application/x-www-form-urlencoded"))
299
+ raw = Object.fromEntries(new URLSearchParams(text));
300
+ else {
301
+ try {
302
+ raw = JSON.parse(text);
303
+ }
304
+ catch {
305
+ throw new InferloError("IL2003", "Request body is not valid JSON.", { status: 400, fix: "Send JSON with Content-Type: application/json." });
306
+ }
307
+ }
308
+ }
309
+ body = parseOrThrow(opts.body, raw, "request body", type.includes("application/x-www-form-urlencoded"));
310
+ }
311
+ let status = 0;
312
+ const ctx = {
313
+ body,
314
+ query,
315
+ params,
316
+ user,
317
+ db: db,
318
+ ai: toolsFor(req),
319
+ jobs,
320
+ req,
321
+ url,
322
+ headers: req.headers,
323
+ state,
324
+ status: (code) => void (status = code),
325
+ header: (name, value) => headers.set(name, value),
326
+ waitUntil: (p) => void pending.push(p.catch((e) => logger.error("waitUntil task failed", e))),
327
+ };
328
+ const result = await def.handler(ctx);
329
+ if (result instanceof Response) {
330
+ headers.forEach((v, k) => {
331
+ if (!result.headers.has(k))
332
+ result.headers.set(k, v);
333
+ });
334
+ return result;
335
+ }
336
+ if (result === undefined)
337
+ return new Response(null, { status: status || 204, headers });
338
+ const response = json(result, status || 200, headers);
339
+ return method === "HEAD" ? new Response(null, { status: response.status, headers: response.headers }) : response;
340
+ }
341
+ catch (error) {
342
+ return errorResponse(error, headers, req);
343
+ }
344
+ };
345
+ const app = {
346
+ name: config.name ?? "inferlo-app",
347
+ version: config.version ?? "0.0.0",
348
+ routes,
349
+ models,
350
+ db,
351
+ ai,
352
+ jobs,
353
+ async fetch(req, ...rest) {
354
+ const url = new URL(req.url);
355
+ const ip = clientIp(req, Boolean(config.trustProxy), rest[0]);
356
+ if (ip !== "unknown")
357
+ clientIps.set(req, ip);
358
+ const state = {};
359
+ const pending = [];
360
+ const chain = [...(config.middleware ?? [])];
361
+ const run = (i) => {
362
+ const mw = chain[i];
363
+ if (!mw)
364
+ return dispatch(req, url, state, pending, ip);
365
+ return mw({ req, url, state }, () => run(i + 1));
366
+ };
367
+ let response;
368
+ try {
369
+ response = await run(0);
370
+ }
371
+ catch (error) {
372
+ response = errorResponse(error, new Headers(), req);
373
+ }
374
+ if (pending.length) {
375
+ const all = Promise.all(pending);
376
+ const execution = rest[1];
377
+ if (execution?.waitUntil)
378
+ execution.waitUntil(all);
379
+ else
380
+ void all;
381
+ }
382
+ return response;
383
+ },
384
+ async request(path, options = {}) {
385
+ const url = new URL(path, "http://inferlo.test");
386
+ for (const [k, v] of Object.entries(options.query ?? {}))
387
+ if (v !== undefined)
388
+ url.searchParams.set(k, String(v));
389
+ const headers = { ...options.headers };
390
+ let body = options.body;
391
+ if (options.json !== undefined) {
392
+ body = JSON.stringify(options.json);
393
+ headers["content-type"] ??= "application/json";
394
+ }
395
+ const req = new Request(url, { method: (options.method ?? "GET").toUpperCase(), headers, body });
396
+ if ("as" in options)
397
+ testUsers.set(req, options.as ?? null);
398
+ return app.fetch(req);
399
+ },
400
+ async listen(port = 3000, hostname = "0.0.0.0") {
401
+ const { serve } = await import("./serve.js");
402
+ return serve(app, { port, hostname });
403
+ },
404
+ describe() {
405
+ return describeApp(app, { auth: Boolean(config.auth), openapi: openapiPath, mcp: mcpPath, description: config.description });
406
+ },
407
+ openapi() {
408
+ return buildOpenAPI(app, { description: config.description, auth: Boolean(config.auth) });
409
+ },
410
+ };
411
+ return app;
412
+ }
413
+ function parseOrThrow(schema, value, where, coerce) {
414
+ const result = schema.safeParse(value, { coerce });
415
+ if (!result.ok)
416
+ throw new ValidationError(result.issues, where);
417
+ return result.value;
418
+ }
419
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Auth helpers. Inferlo does not force a login system on you: auth.resolve(req) returns the user.
3
+ *
4
+ * auth: bearer(async (token, { db }) => {
5
+ * const key = await db.api_keys.findOne({ hash: await hashToken(token) })
6
+ * return key ? db.users.find(key.userId) : null
7
+ * })
8
+ */
9
+ import type { AuthConfig } from "./app.ts";
10
+ import type { AppDb, AppUser } from "./route.ts";
11
+ type Verify = (token: string, ctx: {
12
+ db: AppDb;
13
+ req: Request;
14
+ }) => AppUser | null | undefined | Promise<AppUser | null | undefined>;
15
+ /** Read "Authorization: Bearer <token>" (or an x-api-key header) and verify it. */
16
+ export declare function bearer(verify: Verify, options?: {
17
+ roles?: (user: AppUser) => string[];
18
+ header?: string;
19
+ }): AuthConfig;
20
+ /** SHA-256 hex digest. Store hashes of API keys, never the keys themselves. */
21
+ export declare function hashToken(token: string): Promise<string>;
22
+ /** A random URL-safe token, e.g. for API keys: createToken("kr_live"). */
23
+ export declare function createToken(prefix?: string, bytes?: number): string;
24
+ /** Constant-time string comparison. */
25
+ export declare function safeEqual(a: string, b: string): boolean;
26
+ /** Password hashing with PBKDF2-SHA256 (Web Crypto, works on every runtime). */
27
+ export declare function hashPassword(password: string, iterations?: number): Promise<string>;
28
+ export declare function verifyPassword(password: string, stored: string): Promise<boolean>;
29
+ export {};
package/dist/auth.js ADDED
@@ -0,0 +1,61 @@
1
+ /** Read "Authorization: Bearer <token>" (or an x-api-key header) and verify it. */
2
+ export function bearer(verify, options = {}) {
3
+ return {
4
+ async resolve(req, { db }) {
5
+ let token;
6
+ const authorization = req.headers.get("authorization");
7
+ if (authorization?.toLowerCase().startsWith("bearer "))
8
+ token = authorization.slice(7).trim();
9
+ token ??= req.headers.get(options.header ?? "x-api-key") ?? undefined;
10
+ if (!token)
11
+ return null;
12
+ return (await verify(token, { db, req })) ?? null;
13
+ },
14
+ roles: options.roles,
15
+ };
16
+ }
17
+ /** SHA-256 hex digest. Store hashes of API keys, never the keys themselves. */
18
+ export async function hashToken(token) {
19
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(token));
20
+ return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
21
+ }
22
+ /** A random URL-safe token, e.g. for API keys: createToken("kr_live"). */
23
+ export function createToken(prefix = "", bytes = 24) {
24
+ const random = crypto.getRandomValues(new Uint8Array(bytes));
25
+ const body = btoa(String.fromCharCode(...random)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
26
+ return prefix ? `${prefix}_${body}` : body;
27
+ }
28
+ /** Constant-time string comparison. */
29
+ export function safeEqual(a, b) {
30
+ if (a.length !== b.length)
31
+ return false;
32
+ let diff = 0;
33
+ for (let i = 0; i < a.length; i++)
34
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
35
+ return diff === 0;
36
+ }
37
+ /** Password hashing with PBKDF2-SHA256 (Web Crypto, works on every runtime). */
38
+ export async function hashPassword(password, iterations = 210_000) {
39
+ const salt = crypto.getRandomValues(new Uint8Array(16));
40
+ const hash = await pbkdf2(password, salt, iterations);
41
+ return `pbkdf2_sha256$${iterations}$${b64(salt)}$${b64(hash)}`;
42
+ }
43
+ export async function verifyPassword(password, stored) {
44
+ const [scheme, iter, salt, hash] = stored.split("$");
45
+ if (scheme !== "pbkdf2_sha256" || !iter || !salt || !hash)
46
+ return false;
47
+ const actual = await pbkdf2(password, unb64(salt), Number(iter));
48
+ return safeEqual(b64(actual), hash);
49
+ }
50
+ async function pbkdf2(password, salt, iterations) {
51
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveBits"]);
52
+ const bits = await crypto.subtle.deriveBits({ name: "PBKDF2", hash: "SHA-256", salt: salt, iterations }, key, 256);
53
+ return new Uint8Array(bits);
54
+ }
55
+ function b64(bytes) {
56
+ return btoa(String.fromCharCode(...bytes));
57
+ }
58
+ function unb64(text) {
59
+ return Uint8Array.from(atob(text), (c) => c.charCodeAt(0));
60
+ }
61
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAaA,mFAAmF;AACnF,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,UAAoE,EAAE;IAC3G,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;YACvB,IAAI,KAAyB,CAAC;YAC9B,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACvD,IAAI,aAAa,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9F,KAAK,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,SAAS,CAAC;YACtE,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,OAAO,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACpD,CAAC;QACD,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa;IAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC7G,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS;IAC5C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7E,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,UAAU,GAAG,OAAO;IACvE,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACtD,OAAO,iBAAiB,UAAU,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAc;IACnE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,eAAe,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,OAAO,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,QAAgB,EAAE,IAAgB,EAAE,UAAkB;IAC1E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IACtH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAoB,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACnI,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,GAAG,CAAC,KAAiB;IAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};