@browserlessapi/inferlo 0.6.0 → 0.8.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/README.md +9 -5
- package/dist/ai/ai-sdk.d.ts +48 -0
- package/dist/ai/ai-sdk.js +235 -0
- package/dist/ai/ai-sdk.js.map +1 -0
- package/dist/ai/index.d.ts +37 -3
- package/dist/ai/index.js +96 -7
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/public.d.ts +5 -1
- package/dist/ai/public.js +2 -0
- package/dist/ai/public.js.map +1 -1
- package/dist/ai/ui.d.ts +47 -0
- package/dist/ai/ui.js +33 -0
- package/dist/ai/ui.js.map +1 -0
- package/dist/app.d.ts +55 -4
- package/dist/app.js +439 -39
- package/dist/app.js.map +1 -1
- package/dist/astro.d.ts +60 -0
- package/dist/astro.js +68 -0
- package/dist/astro.js.map +1 -0
- package/dist/audit.d.ts +8 -1
- package/dist/audit.js +9 -2
- package/dist/audit.js.map +1 -1
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +1 -0
- package/dist/auth.js.map +1 -1
- package/dist/authjs.d.ts +70 -0
- package/dist/authjs.js +94 -0
- package/dist/authjs.js.map +1 -0
- package/dist/azure.d.ts +66 -0
- package/dist/azure.js +119 -0
- package/dist/azure.js.map +1 -0
- package/dist/better-auth.d.ts +89 -0
- package/dist/better-auth.js +75 -0
- package/dist/better-auth.js.map +1 -0
- package/dist/cache.d.ts +13 -9
- package/dist/cache.js +11 -9
- package/dist/cache.js.map +1 -1
- package/dist/cli/main.js +5 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/client-ip.d.ts +41 -1
- package/dist/client-ip.js +85 -1
- package/dist/client-ip.js.map +1 -1
- package/dist/cross-site.d.ts +14 -0
- package/dist/cross-site.js +56 -0
- package/dist/cross-site.js.map +1 -0
- package/dist/db/memory.js +2 -1
- package/dist/db/memory.js.map +1 -1
- package/dist/db/postgres.js +23 -6
- package/dist/db/postgres.js.map +1 -1
- package/dist/db/table.d.ts +37 -5
- package/dist/db/table.js +96 -15
- package/dist/db/table.js.map +1 -1
- package/dist/db/types.d.ts +2 -0
- package/dist/describe.d.ts +23 -5
- package/dist/describe.js +20 -2
- package/dist/describe.js.map +1 -1
- package/dist/disk-storage.d.ts +6 -0
- package/dist/disk-storage.js +96 -0
- package/dist/disk-storage.js.map +1 -0
- package/dist/events.d.ts +134 -0
- package/dist/events.js +196 -0
- package/dist/events.js.map +1 -0
- package/dist/files.d.ts +23 -0
- package/dist/files.js +168 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +26 -8
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +56 -10
- package/dist/jobs.js +71 -13
- package/dist/jobs.js.map +1 -1
- package/dist/jwt.d.ts +83 -0
- package/dist/jwt.js +312 -0
- package/dist/jwt.js.map +1 -0
- package/dist/langchain.d.ts +58 -0
- package/dist/langchain.js +220 -0
- package/dist/langchain.js.map +1 -0
- package/dist/model.d.ts +23 -6
- package/dist/model.js +41 -7
- package/dist/model.js.map +1 -1
- package/dist/oidc.d.ts +70 -0
- package/dist/oidc.js +379 -0
- package/dist/oidc.js.map +1 -0
- package/dist/openapi.js +17 -2
- package/dist/openapi.js.map +1 -1
- package/dist/passport.d.ts +54 -0
- package/dist/passport.js +68 -0
- package/dist/passport.js.map +1 -0
- package/dist/postgres-js.d.ts +39 -0
- package/dist/postgres-js.js +71 -0
- package/dist/postgres-js.js.map +1 -0
- package/dist/rate-limit.d.ts +5 -3
- package/dist/rate-limit.js +3 -3
- package/dist/rate-limit.js.map +1 -1
- package/dist/redis-events.d.ts +27 -0
- package/dist/redis-events.js +163 -0
- package/dist/redis-events.js.map +1 -0
- package/dist/redis-jobs.d.ts +24 -0
- package/dist/redis-jobs.js +203 -0
- package/dist/redis-jobs.js.map +1 -0
- package/dist/redis-sockets.d.ts +24 -0
- package/dist/redis-sockets.js +75 -0
- package/dist/redis-sockets.js.map +1 -0
- package/dist/redis.d.ts +30 -0
- package/dist/redis.js +106 -0
- package/dist/redis.js.map +1 -0
- package/dist/response-body.d.ts +6 -0
- package/dist/response-body.js +7 -0
- package/dist/response-body.js.map +1 -0
- package/dist/route.d.ts +117 -3
- package/dist/route.js +27 -0
- package/dist/route.js.map +1 -1
- package/dist/schema.d.ts +23 -3
- package/dist/schema.js +70 -0
- package/dist/schema.js.map +1 -1
- package/dist/serve.d.ts +24 -1
- package/dist/serve.js +200 -8
- package/dist/serve.js.map +1 -1
- package/dist/service-client.d.ts +91 -0
- package/dist/service-client.js +177 -0
- package/dist/service-client.js.map +1 -0
- package/dist/sessions.d.ts +2 -0
- package/dist/sessions.js +36 -4
- package/dist/sessions.js.map +1 -1
- package/dist/sockets.d.ts +58 -0
- package/dist/sockets.js +111 -0
- package/dist/sockets.js.map +1 -0
- package/dist/storage.d.ts +47 -0
- package/dist/storage.js +123 -0
- package/dist/storage.js.map +1 -0
- package/dist/tracing.d.ts +7 -3
- package/dist/tracing.js +8 -2
- package/dist/tracing.js.map +1 -1
- package/dist/websocket.d.ts +81 -0
- package/dist/websocket.js +251 -0
- package/dist/websocket.js.map +1 -0
- package/llms.txt +2 -0
- package/package.json +77 -5
- package/templates/app/AGENTS.md +9 -5
- package/templates/app/test/notes.test.ts +2 -0
package/dist/files.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File uploads: t.file() fields in multipart/form-data route bodies.
|
|
3
|
+
*
|
|
4
|
+
* route.post("/avatar", { body: t.object({ avatar: t.file({ maxBytes: 2_000_000, types: ["image/png", "image/jpeg"] }) }) })
|
|
5
|
+
* .handle(async ({ body }) => ({ name: body.avatar.name, size: body.avatar.size }))
|
|
6
|
+
*
|
|
7
|
+
* The body is read with a byte limit (maxBodySize plus every file field's maxBytes), so a too large upload is cut off
|
|
8
|
+
* while it streams in, and every size, type and content check runs before the handler.
|
|
9
|
+
*/
|
|
10
|
+
import { InferloError } from "./errors.js";
|
|
11
|
+
import { containsFile } from "./schema.js";
|
|
12
|
+
/** Where a t.file() is allowed in a route, checked once by createApp. */
|
|
13
|
+
export function checkFileFields(route) {
|
|
14
|
+
const options = route.options;
|
|
15
|
+
const where = `${route.method} ${route.path}`;
|
|
16
|
+
for (const key of ["query", "params", "response", "message"]) {
|
|
17
|
+
const schema = options[key];
|
|
18
|
+
if (schema && containsFile(schema)) {
|
|
19
|
+
throw new InferloError("IL1004", `Route ${where} uses t.file() in its ${key} schema; files can only be sent in a request body.`, {
|
|
20
|
+
fix: "Move the t.file() field to body: t.object({ file: t.file() }); the client sends it as multipart/form-data.",
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const body = options.body;
|
|
25
|
+
if (!body || !containsFile(body))
|
|
26
|
+
return;
|
|
27
|
+
if (body.def.kind !== "object") {
|
|
28
|
+
throw new InferloError("IL1004", `Route ${where}: a body with files must be t.object({ ... }) with t.file() fields.`, {
|
|
29
|
+
fix: "Use body: t.object({ file: t.file(), title: t.string() }).",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
for (const [name, field] of Object.entries(body.def.shape ?? {})) {
|
|
33
|
+
if (!containsFile(field))
|
|
34
|
+
continue;
|
|
35
|
+
const d = field.def;
|
|
36
|
+
if (d.kind === "file")
|
|
37
|
+
continue;
|
|
38
|
+
if (d.kind === "array" && d.item.def.kind === "file") {
|
|
39
|
+
if (d.max === undefined) {
|
|
40
|
+
throw new InferloError("IL1004", `Route ${where}: the file list "${name}" has no .max(n), so the size of an upload would have no limit.`, {
|
|
41
|
+
fix: `Limit the number of files: ${name}: t.array(t.file({ maxBytes: 5_000_000 })).max(10).`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
throw new InferloError("IL1004", `Route ${where}: "${name}" nests t.file() inside another schema; multipart form fields are flat.`, {
|
|
47
|
+
fix: `Make it a top-level field of the body: ${name}: t.file(), or ${name}: t.array(t.file()).max(10) for several files.`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (options.tool) {
|
|
51
|
+
throw new InferloError("IL1004", `Route ${where} takes files, so it cannot be an MCP or AI tool (tools send JSON).`, {
|
|
52
|
+
fix: "Remove tool from this route, or add a route that takes a URL or text instead of the file for agents.",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Bytes the file fields of a body may add on top of maxBodySize (0 without files). */
|
|
57
|
+
export function fileBudget(body) {
|
|
58
|
+
if (!body || body.def.kind !== "object")
|
|
59
|
+
return 0;
|
|
60
|
+
let total = 0;
|
|
61
|
+
for (const field of Object.values(body.def.shape ?? {})) {
|
|
62
|
+
const d = field.def;
|
|
63
|
+
if (d.kind === "file")
|
|
64
|
+
total += d.max ?? 0;
|
|
65
|
+
else if (d.kind === "array" && d.item.def.kind === "file")
|
|
66
|
+
total += (d.item.def.max ?? 0) * (d.max ?? 0);
|
|
67
|
+
}
|
|
68
|
+
return total;
|
|
69
|
+
}
|
|
70
|
+
export function isMultipart(contentType) {
|
|
71
|
+
return contentType.toLowerCase().startsWith("multipart/form-data");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The fields of a multipart/form-data body as an object for the body schema. Repeated fields become lists, a single
|
|
75
|
+
* value of a list field becomes a one-item list, empty file inputs (no file chosen) count as left out, and the
|
|
76
|
+
* sessions() CSRF field _csrf is dropped.
|
|
77
|
+
*/
|
|
78
|
+
export async function readMultipart(bytes, contentType, body) {
|
|
79
|
+
const invalid = () => new InferloError("IL2015", "Request body is not valid multipart/form-data.", {
|
|
80
|
+
status: 400,
|
|
81
|
+
fix: "Send a FormData body without setting Content-Type yourself (fetch adds the boundary), or a form with enctype=\"multipart/form-data\".",
|
|
82
|
+
});
|
|
83
|
+
if (bytes.byteLength === 0)
|
|
84
|
+
return {};
|
|
85
|
+
// Runtimes differ on bodies that are not multipart at all (some read them as an empty form), so the
|
|
86
|
+
// boundary is checked here: the body starts with it (after an optional preamble) and ends with its close.
|
|
87
|
+
const boundary = /boundary=(?:"([^"]+)"|([^;\s]+))/i.exec(contentType);
|
|
88
|
+
const delimiter = boundary ? `--${boundary[1] ?? boundary[2]}` : undefined;
|
|
89
|
+
const latin1 = new TextDecoder("latin1");
|
|
90
|
+
const head = latin1.decode(bytes.subarray(0, 1024));
|
|
91
|
+
const tail = latin1.decode(bytes.subarray(Math.max(0, bytes.byteLength - 1024)));
|
|
92
|
+
if (!delimiter || !head.includes(delimiter) || !tail.trimEnd().endsWith(`${delimiter}--`))
|
|
93
|
+
throw invalid();
|
|
94
|
+
let form;
|
|
95
|
+
try {
|
|
96
|
+
form = await new Response(bytes, { headers: { "content-type": contentType } }).formData();
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
throw invalid();
|
|
100
|
+
}
|
|
101
|
+
const shape = body.def.kind === "object" ? (body.def.shape ?? {}) : {};
|
|
102
|
+
const out = {};
|
|
103
|
+
for (const [key, value] of form.entries()) {
|
|
104
|
+
if (key === "_csrf")
|
|
105
|
+
continue;
|
|
106
|
+
// A file input with no file chosen is sent as an empty part with an empty filename, which some runtimes read
|
|
107
|
+
// as an empty file and others as an empty string.
|
|
108
|
+
if (typeof value !== "string" ? value.size === 0 && !value.name : value === "" && shape[key] && containsFile(shape[key]))
|
|
109
|
+
continue;
|
|
110
|
+
const current = out[key];
|
|
111
|
+
if (current === undefined)
|
|
112
|
+
out[key] = value;
|
|
113
|
+
else if (Array.isArray(current))
|
|
114
|
+
current.push(value);
|
|
115
|
+
else
|
|
116
|
+
out[key] = [current, value];
|
|
117
|
+
}
|
|
118
|
+
for (const [key, value] of Object.entries(out)) {
|
|
119
|
+
if (shape[key]?.def.kind === "array" && !Array.isArray(value))
|
|
120
|
+
out[key] = [value];
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
// The first bytes of the types whose content is checked against the declared type.
|
|
125
|
+
const SIGNATURES = {
|
|
126
|
+
"image/png": (b) => starts(b, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
127
|
+
"image/jpeg": (b) => starts(b, [0xff, 0xd8, 0xff]),
|
|
128
|
+
"image/gif": (b) => ascii(b, 0, "GIF87a") || ascii(b, 0, "GIF89a"),
|
|
129
|
+
"image/webp": (b) => ascii(b, 0, "RIFF") && ascii(b, 8, "WEBP"),
|
|
130
|
+
"application/pdf": (b) => ascii(b, 0, "%PDF-"),
|
|
131
|
+
"application/zip": (b) => starts(b, [0x50, 0x4b, 0x03, 0x04]) || starts(b, [0x50, 0x4b, 0x05, 0x06]),
|
|
132
|
+
};
|
|
133
|
+
function starts(bytes, prefix) {
|
|
134
|
+
return prefix.every((b, i) => bytes[i] === b);
|
|
135
|
+
}
|
|
136
|
+
function ascii(bytes, offset, text) {
|
|
137
|
+
for (let i = 0; i < text.length; i++)
|
|
138
|
+
if (bytes[offset + i] !== text.charCodeAt(i))
|
|
139
|
+
return false;
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
/** Media types whose first bytes Inferlo checks when a t.file() field limits its types. */
|
|
143
|
+
export const CHECKED_FILE_TYPES = Object.keys(SIGNATURES);
|
|
144
|
+
/**
|
|
145
|
+
* Checks that files of a field with types declare a type whose content matches (a PNG is a PNG), so a client cannot
|
|
146
|
+
* pass a script off as an image by naming its type. Returns validation issues; empty when every file passes.
|
|
147
|
+
*/
|
|
148
|
+
export async function checkFileContents(body, value) {
|
|
149
|
+
const issues = [];
|
|
150
|
+
for (const [key, field] of Object.entries(body.def.shape ?? {})) {
|
|
151
|
+
const fileDef = field.def.kind === "file" ? field.def : field.def.kind === "array" && field.def.item.def.kind === "file" ? field.def.item.def : undefined;
|
|
152
|
+
if (!fileDef?.fileTypes?.length)
|
|
153
|
+
continue;
|
|
154
|
+
const files = Array.isArray(value[key]) ? value[key] : value[key] === undefined || value[key] === null ? [] : [value[key]];
|
|
155
|
+
for (const [i, file] of files.entries()) {
|
|
156
|
+
const declared = file.type.split(";")[0].trim().toLowerCase();
|
|
157
|
+
const matches = SIGNATURES[declared];
|
|
158
|
+
if (!matches)
|
|
159
|
+
continue;
|
|
160
|
+
const head = new Uint8Array(await file.slice(0, 16).arrayBuffer());
|
|
161
|
+
if (!matches(head)) {
|
|
162
|
+
issues.push({ path: Array.isArray(value[key]) ? [key, i] : [key], code: "file_content", message: `File content does not match its type ${declared}.` });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return issues;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,41 +13,59 @@ export type { Module, ModuleOptions, AnyModule, ModuleModels } from "./module.ts
|
|
|
13
13
|
export { apiVersion } from "./api-version.ts";
|
|
14
14
|
export type { ApiVersionOptions } from "./api-version.ts";
|
|
15
15
|
export { route, isRoute } from "./route.ts";
|
|
16
|
-
export type { Register, Context, RouteDef, RouteOptions, Auth, Method, ToolOptions, AppUser, AppDb, AppPermission } from "./route.ts";
|
|
16
|
+
export type { Register, Context, RouteDef, RouteInput, RouteOptions, Auth, Method, ToolOptions, AppUser, AppDb, AppPermission, Socket, SocketContext, SocketRouteOptions } from "./route.ts";
|
|
17
17
|
export { t, Schema, ObjectSchema, ArraySchema, RefSchema, ValidationError, toJSONSchema } from "./schema.ts";
|
|
18
|
-
export type { Infer, InferInput, Issue, JSONSchema, ParseResult, Shape, AnySchema } from "./schema.ts";
|
|
18
|
+
export type { Infer, InferInput, Issue, JSONSchema, ParseResult, Shape, AnySchema, FileOptions } from "./schema.ts";
|
|
19
19
|
export { model, Model, columnName } from "./model.ts";
|
|
20
|
-
export type { Row, CreateInput, UpdateInput, AnyModel } from "./model.ts";
|
|
20
|
+
export type { Row, CreateInput, UpdateInput, AnyModel, ModelOptions } from "./model.ts";
|
|
21
21
|
export { memory } from "./db/memory.ts";
|
|
22
22
|
export { createDb, Table } from "./db/table.ts";
|
|
23
|
-
export type { Db, Where, OrderBy, FindManyOptions, FindOptions, PaginateOptions, Page, Include, Relations, ReverseRelations, WithInclude } from "./db/table.ts";
|
|
23
|
+
export type { Db, PgClient, Where, OrderBy, FindManyOptions, FindOptions, PaginateOptions, Page, Include, Relations, ReverseRelations, WithInclude } from "./db/table.ts";
|
|
24
24
|
export type { Adapter, Condition, Query, DbRecord } from "./db/types.ts";
|
|
25
25
|
export { planMigration, applyMigrations } from "./db/migrate.ts";
|
|
26
26
|
export type { ApplyMigrationsOptions, Migration, MigrationPlan, MigrationSnapshot, MigrationSnapshotColumn, MigrationSnapshotV1, PlanMigrationOptions, } from "./db/migrate.ts";
|
|
27
|
-
export { createAI, cosineSimilarity, extractJson, openai, openaiCompatible, anthropic, gemini, ollama, mockProvider, ProviderError } from "./ai/index.ts";
|
|
27
|
+
export { createAI, cosineSimilarity, extractJson, openai, openaiCompatible, anthropic, gemini, ollama, mockProvider, ProviderError, uiChatBody, fromUIMessages } from "./ai/index.ts";
|
|
28
28
|
export { tool, isTool, ToolBuilder } from "./ai/tool.ts";
|
|
29
|
+
export { aiSdk } from "./ai/ai-sdk.ts";
|
|
30
|
+
export type { AISdkProvider, AISdkLanguageModel, AISdkEmbeddingModel, AISdkOptions } from "./ai/ai-sdk.ts";
|
|
29
31
|
export type { ToolDef, FunctionToolOptions, ToolContext } from "./ai/tool.ts";
|
|
30
|
-
export type { AI, AIConfig, GenerateOptions, GenerateResult, StreamResult, Usage, Pricing, Provider, ProviderRequest, ProviderResponse, Image, ImageMediaType, Message, MockReply, Step, ToolCall, ToolCallResult, ToolSpec, } from "./ai/index.ts";
|
|
32
|
+
export type { AI, AIConfig, GenerateOptions, GenerateResult, StreamResult, StreamResponseInit, UIChatMessage, Usage, Pricing, Provider, ProviderRequest, ProviderResponse, Image, ImageMediaType, Message, MockReply, Step, ToolCall, ToolCallResult, ToolSpec, } from "./ai/index.ts";
|
|
31
33
|
export type { RateLimit, RateLimitConfig } from "./rate-limit.ts";
|
|
34
|
+
export type { RedisClient } from "./redis.ts";
|
|
32
35
|
export { job, isJob, retryDelayMs } from "./jobs.ts";
|
|
33
36
|
export { cron, isCron } from "./cron.ts";
|
|
37
|
+
export { event, isEvent, on } from "./events.ts";
|
|
38
|
+
export type { AppEvents, EventDef, EventMessage, EventOptions, EventPayload, Events, EventsConfig, EventTransport, OnDef, PublishedEvent, PublishOptions } from "./events.ts";
|
|
34
39
|
export type { CronDef } from "./cron.ts";
|
|
35
40
|
export type { JobTraceContext } from "./tracing.ts";
|
|
36
41
|
export type { JobDef, JobOptions, JobContext, JobInput, JobRecord, JobStatus, JobSource, JobQueueConfig, Jobs, AppJobs, EnqueueOptions, RunResult, Worker } from "./jobs.ts";
|
|
37
42
|
export { AuditLog, auditChanges } from "./audit.ts";
|
|
38
43
|
export type { Audit, AuditEntry, AuditChange } from "./audit.ts";
|
|
39
44
|
export type { Cache, CacheConfig, CacheSetOptions, RouteCache } from "./cache.ts";
|
|
45
|
+
export { memoryStorage } from "./storage.ts";
|
|
46
|
+
export type { Storage, StorageStore, StoredFile, StoragePutOptions } from "./storage.ts";
|
|
47
|
+
export { diskStorage } from "./disk-storage.ts";
|
|
48
|
+
export type { DiskStorageOptions } from "./disk-storage.ts";
|
|
40
49
|
export { permissions, isPermissions } from "./permissions.ts";
|
|
41
50
|
export type { Permissions, PermissionRule, PermissionInput } from "./permissions.ts";
|
|
42
51
|
export { bearer, hashToken, createToken, hashPassword, verifyPassword, safeEqual } from "./auth.ts";
|
|
43
52
|
export { sessions } from "./sessions.ts";
|
|
53
|
+
export { jwt } from "./jwt.ts";
|
|
54
|
+
export { oidc } from "./oidc.ts";
|
|
55
|
+
export type { Oidc, OidcOptions, OidcClaims, OidcTokens } from "./oidc.ts";
|
|
56
|
+
export type { JwtOptions, JwtClaims, JwtAlgorithm } from "./jwt.ts";
|
|
44
57
|
export type { TracingConfig, OtelApi, OtelSpan } from "./tracing.ts";
|
|
45
58
|
export type { Sessions, SessionsOptions, SessionData, SessionCookieOptions, SessionResponseContext } from "./sessions.ts";
|
|
46
59
|
export { env, setEnv } from "./env.ts";
|
|
47
60
|
export { config } from "./config.ts";
|
|
48
61
|
export type { Config, ConfigOptions } from "./config.ts";
|
|
49
62
|
export { InferloError, httpError, notFound, forbidden, badRequest, docsUrl } from "./errors.ts";
|
|
50
|
-
export {
|
|
51
|
-
export type {
|
|
63
|
+
export { serviceClient, ServiceCallError } from "./service-client.ts";
|
|
64
|
+
export type { ServiceClient, ServiceClientOptions, CallInput, CallOptions, CallContext, CallResult, TypedRoute } from "./service-client.ts";
|
|
65
|
+
export { serve, toNodeHandler, toNodeUpgradeHandler, fromNodeRequest } from "./serve.ts";
|
|
66
|
+
export { bunWebSocket } from "./websocket.ts";
|
|
67
|
+
export type { Sockets, AppSockets, BroadcastOptions } from "./sockets.ts";
|
|
68
|
+
export type { SocketsConfig, RedisSubscriber } from "./redis-sockets.ts";
|
|
69
|
+
export type { ServeOptions, Server, NodeRequest, NodeResponse, NodeHandler, NodeHandlerOptions, FromNodeRequestOptions, NodeUpgradeHandler, NodeSocket } from "./serve.ts";
|
|
52
70
|
export { INFERLO_VERSION } from "./describe.ts";
|
|
53
71
|
export type { AppDescription } from "./describe.ts";
|
package/dist/index.js
CHANGED
|
@@ -11,17 +11,25 @@ export { model, Model, columnName } from "./model.js";
|
|
|
11
11
|
export { memory } from "./db/memory.js";
|
|
12
12
|
export { createDb, Table } from "./db/table.js";
|
|
13
13
|
export { planMigration, applyMigrations } from "./db/migrate.js";
|
|
14
|
-
export { createAI, cosineSimilarity, extractJson, openai, openaiCompatible, anthropic, gemini, ollama, mockProvider, ProviderError } from "./ai/index.js";
|
|
14
|
+
export { createAI, cosineSimilarity, extractJson, openai, openaiCompatible, anthropic, gemini, ollama, mockProvider, ProviderError, uiChatBody, fromUIMessages } from "./ai/index.js";
|
|
15
15
|
export { tool, isTool, ToolBuilder } from "./ai/tool.js";
|
|
16
|
+
export { aiSdk } from "./ai/ai-sdk.js";
|
|
16
17
|
export { job, isJob, retryDelayMs } from "./jobs.js";
|
|
17
18
|
export { cron, isCron } from "./cron.js";
|
|
19
|
+
export { event, isEvent, on } from "./events.js";
|
|
18
20
|
export { AuditLog, auditChanges } from "./audit.js";
|
|
21
|
+
export { memoryStorage } from "./storage.js";
|
|
22
|
+
export { diskStorage } from "./disk-storage.js";
|
|
19
23
|
export { permissions, isPermissions } from "./permissions.js";
|
|
20
24
|
export { bearer, hashToken, createToken, hashPassword, verifyPassword, safeEqual } from "./auth.js";
|
|
21
25
|
export { sessions } from "./sessions.js";
|
|
26
|
+
export { jwt } from "./jwt.js";
|
|
27
|
+
export { oidc } from "./oidc.js";
|
|
22
28
|
export { env, setEnv } from "./env.js";
|
|
23
29
|
export { config } from "./config.js";
|
|
24
30
|
export { InferloError, httpError, notFound, forbidden, badRequest, docsUrl } from "./errors.js";
|
|
25
|
-
export {
|
|
31
|
+
export { serviceClient, ServiceCallError } from "./service-client.js";
|
|
32
|
+
export { serve, toNodeHandler, toNodeUpgradeHandler, fromNodeRequest } from "./serve.js";
|
|
33
|
+
export { bunWebSocket } from "./websocket.js";
|
|
26
34
|
export { INFERLO_VERSION } from "./describe.js";
|
|
27
35
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAOrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAWjE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAOrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG7G,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAWjE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACtL,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AA4BvC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAKjD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/jobs.d.ts
CHANGED
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
import type { AI } from "./ai/index.ts";
|
|
14
14
|
import type { Audit } from "./audit.ts";
|
|
15
15
|
import type { Cache } from "./cache.ts";
|
|
16
|
+
import { type Storage } from "./storage.ts";
|
|
16
17
|
import { type CronDef } from "./cron.ts";
|
|
17
18
|
import type { Adapter } from "./db/types.ts";
|
|
19
|
+
import { type AppEvents, type EventTransport, type Events, type OnDef } from "./events.ts";
|
|
18
20
|
import type { AppDb } from "./route.ts";
|
|
21
|
+
import { type SocketHub, type Sockets } from "./sockets.ts";
|
|
19
22
|
import { type AnySchema, type Infer, type InferInput } from "./schema.ts";
|
|
20
23
|
import type { JobTraceContext, JobTracing } from "./tracing.ts";
|
|
21
24
|
export interface JobOptions<I extends AnySchema> {
|
|
@@ -33,12 +36,23 @@ export interface JobContext<Input> {
|
|
|
33
36
|
ai: AI;
|
|
34
37
|
/** Enqueue follow-up jobs. */
|
|
35
38
|
jobs: Jobs;
|
|
39
|
+
/** Publish events: await events.publish(orderPaid, { orderId }) queues the jobs subscribed with on(event, job). */
|
|
40
|
+
events: Events;
|
|
36
41
|
/** The app cache, the same as ctx.cache in routes and app.cache. */
|
|
37
42
|
cache: Cache;
|
|
43
|
+
/** Files (createApp({ storage })), the same as ctx.storage in routes and app.storage. */
|
|
44
|
+
storage: Storage;
|
|
45
|
+
/** Send to WebSocket rooms of this process (the job's tenant's rooms with a tenant): await sockets.broadcast(room, data). */
|
|
46
|
+
sockets: Sockets;
|
|
38
47
|
/** Job id. */
|
|
39
48
|
id: string;
|
|
40
49
|
/** 1 on the first run, 2 on the first retry, and so on. */
|
|
41
50
|
attempt: number;
|
|
51
|
+
/**
|
|
52
|
+
* The tenant the job works for (the tenant of the request or job that queued it, or enqueue's tenantId), or null.
|
|
53
|
+
* ctx.db is scoped to it, and jobs and events queued from this job keep it.
|
|
54
|
+
*/
|
|
55
|
+
tenantId: string | null;
|
|
42
56
|
/**
|
|
43
57
|
* Write an audit log entry (needs AuditLog in createApp({ models })). Jobs have no signed-in user: pass the
|
|
44
58
|
* userId of the user who asked for the work, or leave it out for work the system does on its own.
|
|
@@ -58,6 +72,11 @@ export type JobInput<J> = J extends JobDef<infer I, any> ? I : never;
|
|
|
58
72
|
export interface EnqueueOptions {
|
|
59
73
|
/** Run no earlier than this time. Default: now. */
|
|
60
74
|
runAt?: Date;
|
|
75
|
+
/**
|
|
76
|
+
* The tenant the job works for: its ctx.db is scoped to it (tenant-scoped models). Default: the tenant of the
|
|
77
|
+
* request or job that enqueues it, none from app.jobs. Pass null to queue it without a tenant.
|
|
78
|
+
*/
|
|
79
|
+
tenantId?: string | null;
|
|
61
80
|
}
|
|
62
81
|
export type JobStatus = "pending" | "running" | "done" | "failed";
|
|
63
82
|
export interface JobRecord {
|
|
@@ -76,6 +95,8 @@ export interface JobRecord {
|
|
|
76
95
|
lastError?: string;
|
|
77
96
|
/** With createApp({ tracing }): the trace (W3C traceparent and tracestate) of the request or job that enqueued it, which its runs continue. */
|
|
78
97
|
trace?: JobTraceContext;
|
|
98
|
+
/** The tenant the job works for (multi-tenancy): its ctx.db is scoped to it. */
|
|
99
|
+
tenantId?: string;
|
|
79
100
|
createdAt: Date;
|
|
80
101
|
updatedAt: Date;
|
|
81
102
|
}
|
|
@@ -87,8 +108,9 @@ export interface JobQueueConfig {
|
|
|
87
108
|
/**
|
|
88
109
|
* Where queued jobs are kept. "memory" (default): in this process, for development and tests.
|
|
89
110
|
* "database": in the inferlo_jobs table of the app's Postgres database, shared by every instance.
|
|
111
|
+
* "redis": in the Redis of createApp({ redis }), shared by every instance.
|
|
90
112
|
*/
|
|
91
|
-
store?: "memory" | "database";
|
|
113
|
+
store?: "memory" | "database" | "redis";
|
|
92
114
|
}
|
|
93
115
|
/** Where queued jobs are kept. */
|
|
94
116
|
export interface JobStore {
|
|
@@ -98,7 +120,7 @@ export interface JobStore {
|
|
|
98
120
|
claim(now: Date, limit: number, names: readonly string[]): Promise<JobRecord[]>;
|
|
99
121
|
update(id: string, patch: Partial<Pick<JobRecord, "status" | "runAt" | "lastError">>): Promise<void>;
|
|
100
122
|
get(id: string): Promise<JobRecord | null>;
|
|
101
|
-
/** Record that a running job is still alive (database
|
|
123
|
+
/** Record that a running job is still alive (database and Redis stores), so it is not picked up again as stuck. */
|
|
102
124
|
touch?(id: string): Promise<void>;
|
|
103
125
|
}
|
|
104
126
|
export interface RunResult {
|
|
@@ -120,14 +142,17 @@ export interface AppJobs extends Jobs {
|
|
|
120
142
|
/** The registered crons: cron(schedule, job) values in createApp({ jobs }). */
|
|
121
143
|
readonly crons: readonly CronDef[];
|
|
122
144
|
/** Where queued jobs are kept (createApp({ jobQueue: { store } })). */
|
|
123
|
-
readonly queue: "memory" | "database";
|
|
145
|
+
readonly queue: "memory" | "database" | "redis";
|
|
124
146
|
/** A queued job by id, or null. */
|
|
125
147
|
get(id: string): Promise<JobRecord | null>;
|
|
126
148
|
/** Run every job that is due now (or at options.now), one after another, including follow-ups they enqueue, then return. For tests and scripts. */
|
|
127
149
|
runDue(options?: {
|
|
128
150
|
now?: Date;
|
|
129
151
|
}): Promise<RunResult>;
|
|
130
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Run due jobs in this process every pollMs (default 1000) until stop() is called. Also queues each cron's job at
|
|
154
|
+
* every tick after the start, and with an events transport, the jobs of the events it receives.
|
|
155
|
+
*/
|
|
131
156
|
start(options?: {
|
|
132
157
|
pollMs?: number;
|
|
133
158
|
}): Worker;
|
|
@@ -146,13 +171,15 @@ export declare class JobBuilder<I extends AnySchema> {
|
|
|
146
171
|
/** Define a background job: job("send-email", { input: t.object({ to: t.email() }) }).handle(fn). */
|
|
147
172
|
export declare function job<I extends AnySchema>(name: string, options: JobOptions<I>): JobBuilder<I>;
|
|
148
173
|
export declare function isJob(value: unknown): value is JobDef;
|
|
149
|
-
/** Anything that contains jobs: a job, a cron, an array, or a module (import * as jobs from "./jobs.ts"). */
|
|
150
|
-
export type JobSource = JobDef | CronDef | readonly JobSource[] | {
|
|
174
|
+
/** Anything that contains jobs: a job, a cron, an event subscription (on), an array, or a module (import * as jobs from "./jobs.ts"). */
|
|
175
|
+
export type JobSource = JobDef | CronDef | OnDef | readonly JobSource[] | {
|
|
151
176
|
readonly [name: string]: unknown;
|
|
152
177
|
};
|
|
153
178
|
/** The jobs and crons in createApp({ jobs }). A cron's job is registered with it. */
|
|
154
179
|
export declare function collectJobs(sources: readonly JobSource[] | undefined): JobDef[];
|
|
155
180
|
export declare function collectCrons(sources: readonly JobSource[] | undefined): CronDef[];
|
|
181
|
+
/** The event subscriptions, on(event, job), in createApp({ jobs }). */
|
|
182
|
+
export declare function collectSubscriptions(sources: readonly JobSource[] | undefined): OnDef[];
|
|
156
183
|
/** Jobs kept in this process. They are lost when it stops, so use it for development and tests. */
|
|
157
184
|
export declare function memoryJobStore(): JobStore;
|
|
158
185
|
/** A running job whose worker has not reported for this long is treated as stuck (its process stopped) and run again. */
|
|
@@ -168,20 +195,24 @@ export declare const STOPPED_MESSAGE = "The worker stopped while running this jo
|
|
|
168
195
|
export declare function databaseJobStore(adapter: Adapter, options?: {
|
|
169
196
|
staleAfterMs?: number;
|
|
170
197
|
}): JobStore;
|
|
171
|
-
|
|
172
|
-
export declare function jobStoreFor(config: JobQueueConfig | undefined, adapter: Adapter): JobStore;
|
|
198
|
+
export declare function jobStoreFor(config: JobQueueConfig | undefined, adapter: Adapter, redis?: () => JobStore): JobStore;
|
|
173
199
|
export interface JobRuntime {
|
|
174
200
|
db: AppDb;
|
|
175
201
|
ai: AI;
|
|
176
202
|
cache: Cache;
|
|
203
|
+
/** Files (app.storage). Default: none (ctx.storage throws IL6037). */
|
|
204
|
+
storage?: Storage;
|
|
205
|
+
/** WebSocket rooms (app.sockets). */
|
|
206
|
+
sockets?: SocketHub;
|
|
177
207
|
/** Builds ctx.audit for one run. */
|
|
178
208
|
audit(job: {
|
|
179
209
|
name: string;
|
|
180
210
|
id: string;
|
|
211
|
+
tenantId: string | null;
|
|
181
212
|
}): Audit;
|
|
182
213
|
store: JobStore;
|
|
183
214
|
/** Name of the store, shown as app.jobs.queue. Default "memory". */
|
|
184
|
-
queue?: "memory" | "database";
|
|
215
|
+
queue?: "memory" | "database" | "redis";
|
|
185
216
|
/** How often a running job is reported alive to stores that support it. Default HEARTBEAT_MS. */
|
|
186
217
|
heartbeatMs?: number;
|
|
187
218
|
logger: {
|
|
@@ -192,10 +223,25 @@ export interface JobRuntime {
|
|
|
192
223
|
onRun?(name: string, outcome: keyof RunResult, durationMs: number): void;
|
|
193
224
|
/** With createApp({ tracing }): a span per attempt that continues the trace the job was enqueued in. */
|
|
194
225
|
tracing?: JobTracing;
|
|
226
|
+
/** With createApp({ events: { transport } }): carries published events between services. */
|
|
227
|
+
eventTransport?: EventTransport;
|
|
195
228
|
}
|
|
196
229
|
/** app.jobs plus what the framework tests reach directly. */
|
|
197
230
|
export interface InternalJobs extends AppJobs {
|
|
198
231
|
/** Queue the job of each cron's latest tick in (from, to]. */
|
|
199
232
|
queueCrons(from: Date, to: Date): Promise<void>;
|
|
233
|
+
/** app.events: publishing queues the jobs subscribed with on(event, job). */
|
|
234
|
+
readonly events: AppEvents;
|
|
200
235
|
}
|
|
201
|
-
export declare function createJobs(list: readonly JobDef[], runtime: JobRuntime, crons?: readonly CronDef[]): InternalJobs;
|
|
236
|
+
export declare function createJobs(list: readonly JobDef[], runtime: JobRuntime, crons?: readonly CronDef[], subscriptions?: readonly OnDef[]): InternalJobs;
|
|
237
|
+
/**
|
|
238
|
+
* ctx.jobs and ctx.events for one tenant: jobs and events queued through them carry the tenant unless the call
|
|
239
|
+
* names another (tenantId) or none (null). Internal: used for requests and jobs with a tenant.
|
|
240
|
+
*/
|
|
241
|
+
export declare function withTenant(base: {
|
|
242
|
+
jobs: Jobs;
|
|
243
|
+
events: Events;
|
|
244
|
+
}, tenantId: string): {
|
|
245
|
+
jobs: Jobs;
|
|
246
|
+
events: Events;
|
|
247
|
+
};
|