@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/schema.js ADDED
@@ -0,0 +1,442 @@
1
+ /**
2
+ * Inferlo schemas. One definition gives you runtime validation, TypeScript types,
3
+ * JSON Schema (for OpenAPI, MCP tools and AI structured output) and database columns.
4
+ *
5
+ * const User = t.object({ name: t.string().max(80), age: t.int().optional() })
6
+ * type User = Infer<typeof User>
7
+ */
8
+ import { InferloError, didYouMean } from "./errors.js";
9
+ export class ValidationError extends InferloError {
10
+ issues;
11
+ constructor(issues, where = "input") {
12
+ const first = issues[0];
13
+ const summary = first ? `${first.path.length ? first.path.join(".") + ": " : ""}${first.message}` : "invalid";
14
+ super("IL1001", `Invalid ${where}. ${summary}${issues.length > 1 ? ` (and ${issues.length - 1} more)` : ""}`, {
15
+ status: 422,
16
+ details: issues,
17
+ fix: "Send data that matches the schema. Each entry in details names the exact path and problem.",
18
+ });
19
+ this.issues = issues;
20
+ }
21
+ }
22
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}([Tt ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?([Zz]|[+-]\d{2}:?\d{2})?)?$/;
23
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
24
+ const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
25
+ // ---------------------------------------------------------------------------------------------
26
+ // Schema
27
+ // ---------------------------------------------------------------------------------------------
28
+ export class Schema {
29
+ def;
30
+ constructor(def) {
31
+ this.def = def;
32
+ }
33
+ with(changes) {
34
+ const Ctor = this.constructor;
35
+ return new Ctor({ ...this.def, ...changes });
36
+ }
37
+ /** Field may be left out. */
38
+ optional() {
39
+ return this.with({ optional: true });
40
+ }
41
+ /** Field may be null. */
42
+ nullable() {
43
+ return this.with({ nullable: true });
44
+ }
45
+ /** Value used when the field is left out. Pass a function for values like dates. */
46
+ default(value) {
47
+ return this.with({ hasDefault: true, defaultValue: value, optional: false });
48
+ }
49
+ /** Minimum length (strings, arrays) or minimum value (numbers). */
50
+ min(n) {
51
+ return this.with({ min: n });
52
+ }
53
+ /** Maximum length (strings, arrays) or maximum value (numbers). */
54
+ max(n) {
55
+ return this.with({ max: n });
56
+ }
57
+ /** Strings must match this regular expression. */
58
+ regex(pattern) {
59
+ return this.with({ pattern });
60
+ }
61
+ /** Shown in OpenAPI, MCP tool definitions and AI prompts. */
62
+ describe(description) {
63
+ return this.with({ description });
64
+ }
65
+ example(value) {
66
+ return this.with({ example: value });
67
+ }
68
+ /** Database: unique column. */
69
+ unique() {
70
+ return this.with({ unique: true });
71
+ }
72
+ /** Database: add an index on this column. */
73
+ index() {
74
+ return this.with({ index: true });
75
+ }
76
+ /** Validate and return typed data, or throw ValidationError (HTTP 422). */
77
+ parse(input, options) {
78
+ const result = this.safeParse(input, options);
79
+ if (!result.ok)
80
+ throw new ValidationError(result.issues);
81
+ return result.value;
82
+ }
83
+ /** Validate without throwing. */
84
+ safeParse(input, options = {}) {
85
+ const issues = [];
86
+ const value = check(this, input, [], issues, options);
87
+ return issues.length ? { ok: false, issues } : { ok: true, value: value };
88
+ }
89
+ /** JSON Schema (draft 2020-12 compatible) for OpenAPI, MCP and AI structured output. */
90
+ toJSONSchema() {
91
+ return toJSONSchema(this);
92
+ }
93
+ }
94
+ export class ObjectSchema extends Schema {
95
+ get shape() {
96
+ return this.def.shape;
97
+ }
98
+ /** Keep only some fields. */
99
+ pick(...keys) {
100
+ const shape = {};
101
+ for (const key of keys) {
102
+ if (!(key in this.shape)) {
103
+ throw new InferloError("IL1003", `pick(): field "${key}" does not exist.${didYouMean(key, Object.keys(this.shape))}`, {
104
+ fix: `Use one of: ${Object.keys(this.shape).join(", ")}`,
105
+ });
106
+ }
107
+ shape[key] = this.shape[key];
108
+ }
109
+ return new ObjectSchema({ ...this.def, shape });
110
+ }
111
+ /** Drop some fields. */
112
+ omit(...keys) {
113
+ const shape = { ...this.shape };
114
+ for (const key of keys)
115
+ delete shape[key];
116
+ return new ObjectSchema({ ...this.def, shape });
117
+ }
118
+ /** Every field optional (for PATCH bodies). Defaults are not applied. */
119
+ partial() {
120
+ const shape = {};
121
+ for (const [key, field] of Object.entries(this.shape)) {
122
+ shape[key] = new field.constructor({ ...field.def, optional: true, hasDefault: false });
123
+ }
124
+ return new ObjectSchema({ ...this.def, shape });
125
+ }
126
+ /** Add fields. */
127
+ extend(extra) {
128
+ return new ObjectSchema({ ...this.def, shape: { ...this.shape, ...extra } });
129
+ }
130
+ /** Silently drop unknown keys instead of rejecting them (the default is to reject). */
131
+ strip() {
132
+ return this.with({ unknownKeys: "strip" });
133
+ }
134
+ }
135
+ export class ArraySchema extends Schema {
136
+ get item() {
137
+ return this.def.item;
138
+ }
139
+ }
140
+ /** t.ref("users"): the id of a row in another table. The table name is kept in the type for include. */
141
+ export class RefSchema extends Schema {
142
+ optional() {
143
+ return this.with({ optional: true });
144
+ }
145
+ nullable() {
146
+ return this.with({ nullable: true });
147
+ }
148
+ default(value) {
149
+ return this.with({ hasDefault: true, defaultValue: value, optional: false });
150
+ }
151
+ }
152
+ // ---------------------------------------------------------------------------------------------
153
+ // Builders
154
+ // ---------------------------------------------------------------------------------------------
155
+ function base(kind, extra = {}) {
156
+ return { kind, optional: false, nullable: false, hasDefault: false, ...extra };
157
+ }
158
+ export const t = {
159
+ /** Short text. Stored as text (or varchar(max) when .max() is set). */
160
+ string: () => new Schema(base("string")),
161
+ /** Long text such as a post body. */
162
+ text: () => new Schema(base("text")),
163
+ email: () => new Schema(base("email", { max: 254 })),
164
+ url: () => new Schema(base("url", { max: 2048 })),
165
+ uuid: () => new Schema(base("uuid")),
166
+ number: () => new Schema(base("number")),
167
+ /** Whole number. */
168
+ int: () => new Schema(base("int")),
169
+ boolean: () => new Schema(base("boolean")),
170
+ /** Accepts a Date or an ISO 8601 string, always returns a Date. */
171
+ date: () => new Schema(base("date")),
172
+ /** One of a fixed list of strings: t.enum(["low", "normal", "urgent"]). */
173
+ enum: (values) => new Schema(base("enum", { values })),
174
+ literal: (value) => new Schema(base("literal", { values: [value] })),
175
+ /** Any JSON value. Stored as jsonb. */
176
+ json: () => new Schema(base("json")),
177
+ array: (item) => new ArraySchema(base("array", { item })),
178
+ object: (shape) => new ObjectSchema(base("object", { shape, unknownKeys: "strict" })),
179
+ /** Id of a row in another model's table: t.ref("users"). */
180
+ ref: (table, options = {}) => new RefSchema(base("ref", { refTable: table, onDelete: options.onDelete ?? "restrict" })),
181
+ any: () => new Schema(base("any", { optional: true })),
182
+ };
183
+ // ---------------------------------------------------------------------------------------------
184
+ // Validation
185
+ // ---------------------------------------------------------------------------------------------
186
+ function describeType(value) {
187
+ if (value === null)
188
+ return "null";
189
+ if (Array.isArray(value))
190
+ return "array";
191
+ if (value instanceof Date)
192
+ return "date";
193
+ return typeof value;
194
+ }
195
+ function coerceValue(kind, value) {
196
+ if (typeof value !== "string")
197
+ return value;
198
+ if ((kind === "number" || kind === "int") && value.trim() !== "" && !Number.isNaN(Number(value)))
199
+ return Number(value);
200
+ if (kind === "boolean") {
201
+ if (value === "true" || value === "1")
202
+ return true;
203
+ if (value === "false" || value === "0")
204
+ return false;
205
+ }
206
+ if (kind === "literal" || kind === "enum")
207
+ return value;
208
+ return value;
209
+ }
210
+ function check(schema, raw, path, issues, options) {
211
+ const def = schema.def;
212
+ let value = raw;
213
+ if (value === undefined) {
214
+ if (def.hasDefault) {
215
+ const d = def.defaultValue;
216
+ return typeof d === "function" ? d() : structuredCloneSafe(d);
217
+ }
218
+ if (def.optional)
219
+ return undefined;
220
+ issues.push({ path, code: "required", message: "Required." });
221
+ return undefined;
222
+ }
223
+ if (value === null) {
224
+ if (def.nullable)
225
+ return null;
226
+ issues.push({ path, code: "invalid_type", message: "Expected a value, got null." });
227
+ return undefined;
228
+ }
229
+ if (options.coerce)
230
+ value = coerceValue(def.kind, value);
231
+ const fail = (code, message) => {
232
+ issues.push({ path, code, message });
233
+ return undefined;
234
+ };
235
+ switch (def.kind) {
236
+ case "any":
237
+ case "json":
238
+ return value;
239
+ case "string":
240
+ case "text":
241
+ case "email":
242
+ case "url":
243
+ case "uuid":
244
+ case "ref": {
245
+ if (typeof value !== "string")
246
+ return fail("invalid_type", `Expected a string, got ${describeType(value)}.`);
247
+ if (def.kind === "email" && !EMAIL.test(value))
248
+ return fail("invalid_email", "Expected an email address.");
249
+ if ((def.kind === "uuid" || def.kind === "ref") && !UUID.test(value))
250
+ return fail("invalid_uuid", "Expected a UUID.");
251
+ if (def.kind === "url") {
252
+ try {
253
+ const u = new URL(value);
254
+ if (u.protocol !== "http:" && u.protocol !== "https:")
255
+ return fail("invalid_url", "Expected an http or https URL.");
256
+ }
257
+ catch {
258
+ return fail("invalid_url", "Expected a URL.");
259
+ }
260
+ }
261
+ if (def.min !== undefined && value.length < def.min)
262
+ return fail("too_short", `Must be at least ${def.min} characters.`);
263
+ if (def.max !== undefined && value.length > def.max)
264
+ return fail("too_long", `Must be at most ${def.max} characters.`);
265
+ if (def.pattern && !def.pattern.test(value))
266
+ return fail("invalid_format", `Must match ${def.pattern}.`);
267
+ return value;
268
+ }
269
+ case "number":
270
+ case "int": {
271
+ if (typeof value !== "number" || !Number.isFinite(value))
272
+ return fail("invalid_type", `Expected a number, got ${describeType(value)}.`);
273
+ if (def.kind === "int" && !Number.isInteger(value))
274
+ return fail("invalid_type", "Expected a whole number.");
275
+ if (def.min !== undefined && value < def.min)
276
+ return fail("too_small", `Must be at least ${def.min}.`);
277
+ if (def.max !== undefined && value > def.max)
278
+ return fail("too_big", `Must be at most ${def.max}.`);
279
+ return value;
280
+ }
281
+ case "boolean":
282
+ if (typeof value !== "boolean")
283
+ return fail("invalid_type", `Expected true or false, got ${describeType(value)}.`);
284
+ return value;
285
+ case "date": {
286
+ let date;
287
+ if (value instanceof Date)
288
+ date = value;
289
+ else if (typeof value === "string" && ISO_DATE.test(value))
290
+ date = new Date(value);
291
+ if (!date || Number.isNaN(date.getTime()))
292
+ return fail("invalid_date", "Expected an ISO 8601 date string.");
293
+ return date;
294
+ }
295
+ case "enum":
296
+ case "literal": {
297
+ const values = def.values ?? [];
298
+ if (!values.includes(value)) {
299
+ const hint = typeof value === "string" ? didYouMean(value, values.map(String)) : "";
300
+ return fail("invalid_enum", `Expected one of ${values.map((v) => JSON.stringify(v)).join(", ")}.${hint}`);
301
+ }
302
+ return value;
303
+ }
304
+ case "array": {
305
+ if (!Array.isArray(value)) {
306
+ if (options.coerce && typeof value === "string")
307
+ value = value === "" ? [] : value.split(",");
308
+ else
309
+ return fail("invalid_type", `Expected an array, got ${describeType(value)}.`);
310
+ }
311
+ const list = value;
312
+ if (def.min !== undefined && list.length < def.min)
313
+ return fail("too_short", `Must have at least ${def.min} items.`);
314
+ if (def.max !== undefined && list.length > def.max)
315
+ return fail("too_long", `Must have at most ${def.max} items.`);
316
+ return list.map((item, i) => check(def.item, item, [...path, i], issues, options));
317
+ }
318
+ case "object": {
319
+ if (typeof value !== "object" || Array.isArray(value) || value instanceof Date) {
320
+ return fail("invalid_type", `Expected an object, got ${describeType(value)}.`);
321
+ }
322
+ const shape = def.shape ?? {};
323
+ const input = value;
324
+ const out = {};
325
+ for (const [key, field] of Object.entries(shape)) {
326
+ if (field.def.system && input[key] !== undefined) {
327
+ issues.push({ path: [...path, key], code: "read_only", message: `"${key}" is set by the framework and cannot be sent.` });
328
+ continue;
329
+ }
330
+ const parsed = check(field, input[key], [...path, key], issues, options);
331
+ if (parsed !== undefined)
332
+ out[key] = parsed;
333
+ }
334
+ if (def.unknownKeys !== "strip") {
335
+ for (const key of Object.keys(input)) {
336
+ if (!(key in shape) && input[key] !== undefined) {
337
+ issues.push({
338
+ path: [...path, key],
339
+ code: "unknown_key",
340
+ message: `Unknown field "${key}".${didYouMean(key, Object.keys(shape))}`,
341
+ });
342
+ }
343
+ }
344
+ }
345
+ return out;
346
+ }
347
+ }
348
+ }
349
+ function structuredCloneSafe(value) {
350
+ if (value === null || typeof value !== "object")
351
+ return value;
352
+ return structuredClone(value);
353
+ }
354
+ // ---------------------------------------------------------------------------------------------
355
+ // JSON Schema
356
+ // ---------------------------------------------------------------------------------------------
357
+ export function toJSONSchema(schema) {
358
+ const def = schema.def;
359
+ let out;
360
+ switch (def.kind) {
361
+ case "string":
362
+ case "text":
363
+ out = { type: "string" };
364
+ if (def.min !== undefined)
365
+ out.minLength = def.min;
366
+ if (def.max !== undefined)
367
+ out.maxLength = def.max;
368
+ if (def.pattern)
369
+ out.pattern = def.pattern.source;
370
+ break;
371
+ case "email":
372
+ out = { type: "string", format: "email", maxLength: def.max };
373
+ break;
374
+ case "url":
375
+ out = { type: "string", format: "uri", maxLength: def.max };
376
+ break;
377
+ case "uuid":
378
+ case "ref":
379
+ out = { type: "string", format: "uuid" };
380
+ break;
381
+ case "number":
382
+ case "int":
383
+ out = { type: def.kind === "int" ? "integer" : "number" };
384
+ if (def.min !== undefined)
385
+ out.minimum = def.min;
386
+ if (def.max !== undefined)
387
+ out.maximum = def.max;
388
+ break;
389
+ case "boolean":
390
+ out = { type: "boolean" };
391
+ break;
392
+ case "date":
393
+ out = { type: "string", format: "date-time" };
394
+ break;
395
+ case "enum":
396
+ out = { type: "string", enum: [...(def.values ?? [])] };
397
+ break;
398
+ case "literal":
399
+ out = { const: def.values?.[0] };
400
+ break;
401
+ case "array":
402
+ out = { type: "array", items: toJSONSchema(def.item) };
403
+ if (def.min !== undefined)
404
+ out.minItems = def.min;
405
+ if (def.max !== undefined)
406
+ out.maxItems = def.max;
407
+ break;
408
+ case "object": {
409
+ const properties = {};
410
+ const required = [];
411
+ for (const [key, field] of Object.entries(def.shape ?? {})) {
412
+ properties[key] = toJSONSchema(field);
413
+ if (!field.def.optional && !field.def.hasDefault)
414
+ required.push(key);
415
+ }
416
+ out = { type: "object", properties, additionalProperties: def.unknownKeys === "strip" };
417
+ if (required.length)
418
+ out.required = required;
419
+ break;
420
+ }
421
+ case "json":
422
+ case "any":
423
+ out = {};
424
+ break;
425
+ }
426
+ if (def.nullable) {
427
+ out = out.type ? { ...out, type: [out.type, "null"] } : { anyOf: [out, { type: "null" }] };
428
+ }
429
+ if (def.description)
430
+ out.description = def.description;
431
+ if (def.hasDefault && typeof def.defaultValue !== "function")
432
+ out.default = def.defaultValue;
433
+ if (def.example !== undefined)
434
+ out.examples = [def.example];
435
+ if (def.system)
436
+ out.readOnly = true;
437
+ for (const key of Object.keys(out))
438
+ if (out[key] === undefined)
439
+ delete out[key];
440
+ return out;
441
+ }
442
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** Start an HTTP server on Bun, Deno or Node using the app's fetch handler. */
2
+ import type { App } from "./app.ts";
3
+ export interface ServeOptions {
4
+ port?: number;
5
+ hostname?: string;
6
+ }
7
+ export interface Server {
8
+ port: number;
9
+ close(): Promise<void>;
10
+ }
11
+ export declare function serve(app: Pick<App<any>, "fetch">, options?: ServeOptions): Promise<Server>;
package/dist/serve.js ADDED
@@ -0,0 +1,86 @@
1
+ import { clientIps } from "./client-ip.js";
2
+ export async function serve(app, options = {}) {
3
+ const port = options.port ?? 3000;
4
+ const hostname = options.hostname ?? "0.0.0.0";
5
+ const g = globalThis;
6
+ if (g.Bun) {
7
+ const server = g.Bun.serve({ port, hostname, fetch: (req, bunServer) => app.fetch(req, bunServer) });
8
+ return { port: server.port, close: async () => server.stop(true) };
9
+ }
10
+ if (g.Deno) {
11
+ const server = g.Deno.serve({ port, hostname }, (req, info) => app.fetch(req, info));
12
+ return { port: server.addr.port, close: () => server.shutdown() };
13
+ }
14
+ const http = await import("node:http");
15
+ const { Readable } = await import("node:stream");
16
+ const server = http.createServer(async (req, res) => {
17
+ try {
18
+ const host = req.headers.host ?? `localhost:${port}`;
19
+ const url = new URL(req.url ?? "/", `http://${host}`);
20
+ const headers = new Headers();
21
+ for (const [k, v] of Object.entries(req.headers)) {
22
+ if (v === undefined)
23
+ continue;
24
+ if (Array.isArray(v))
25
+ for (const item of v)
26
+ headers.append(k, item);
27
+ else
28
+ headers.set(k, v);
29
+ }
30
+ const hasBody = req.method !== "GET" && req.method !== "HEAD";
31
+ const controller = new AbortController();
32
+ res.on("close", () => {
33
+ if (!res.writableFinished)
34
+ controller.abort();
35
+ });
36
+ const request = new Request(url, {
37
+ method: req.method,
38
+ headers,
39
+ body: hasBody ? Readable.toWeb(req) : undefined,
40
+ signal: controller.signal,
41
+ // @ts-expect-error duplex is required by Node for streaming bodies
42
+ duplex: "half",
43
+ });
44
+ if (req.socket.remoteAddress)
45
+ clientIps.set(request, req.socket.remoteAddress);
46
+ const response = await app.fetch(request);
47
+ const outHeaders = {};
48
+ response.headers.forEach((value, key) => {
49
+ if (key === "set-cookie")
50
+ return;
51
+ outHeaders[key] = value;
52
+ });
53
+ const cookies = response.headers.getSetCookie?.() ?? [];
54
+ if (cookies.length)
55
+ outHeaders["set-cookie"] = cookies;
56
+ res.writeHead(response.status, outHeaders);
57
+ if (!response.body || req.method === "HEAD")
58
+ return void res.end();
59
+ const reader = response.body.getReader();
60
+ while (true) {
61
+ const { value, done } = await reader.read();
62
+ if (done)
63
+ break;
64
+ if (!res.write(value))
65
+ await new Promise((r) => res.once("drain", r));
66
+ }
67
+ res.end();
68
+ }
69
+ catch (error) {
70
+ console.error("[inferlo] server error", error);
71
+ if (!res.headersSent)
72
+ res.writeHead(500, { "content-type": "application/json" });
73
+ res.end(JSON.stringify({ error: { code: "IL9000", message: "Internal server error" } }));
74
+ }
75
+ });
76
+ await new Promise((resolve, reject) => {
77
+ server.once("error", reject);
78
+ server.listen(port, hostname, () => resolve());
79
+ });
80
+ const address = server.address();
81
+ return {
82
+ port: typeof address === "object" && address ? address.port : port,
83
+ close: () => new Promise((resolve) => server.close(() => resolve())),
84
+ };
85
+ }
86
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Test helpers.
3
+ *
4
+ * import { readJson } from "@browserlessapi/inferlo/testing"
5
+ * const res = await app.request("/tickets", { method: "POST", json: { title: "Hi" }, as: user })
6
+ * const data = await readJson(res, 200)
7
+ */
8
+ export { mockProvider } from "./ai/providers.ts";
9
+ export { memory } from "./db/memory.ts";
10
+ /** Parse a JSON response and assert its status, with the body in the error message on mismatch. */
11
+ export declare function readJson<T = any>(response: Response, expectedStatus?: number): Promise<T>;
12
+ /** Collect server-sent events from a streaming response. */
13
+ export declare function readEvents(response: Response): Promise<{
14
+ event: string;
15
+ data: unknown;
16
+ }[]>;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Test helpers.
3
+ *
4
+ * import { readJson } from "@browserlessapi/inferlo/testing"
5
+ * const res = await app.request("/tickets", { method: "POST", json: { title: "Hi" }, as: user })
6
+ * const data = await readJson(res, 200)
7
+ */
8
+ export { mockProvider } from "./ai/providers.js";
9
+ export { memory } from "./db/memory.js";
10
+ /** Parse a JSON response and assert its status, with the body in the error message on mismatch. */
11
+ export async function readJson(response, expectedStatus) {
12
+ const text = await response.text();
13
+ if (expectedStatus !== undefined && response.status !== expectedStatus) {
14
+ throw new Error(`Expected status ${expectedStatus}, got ${response.status}: ${text}`);
15
+ }
16
+ return (text ? JSON.parse(text) : undefined);
17
+ }
18
+ /** Collect server-sent events from a streaming response. */
19
+ export async function readEvents(response) {
20
+ const text = await response.text();
21
+ return text
22
+ .split("\n\n")
23
+ .filter(Boolean)
24
+ .map((block) => {
25
+ const event = /^event: (.*)$/m.exec(block)?.[1] ?? "message";
26
+ const data = /^data: (.*)$/m.exec(block)?.[1];
27
+ return { event, data: data === undefined ? undefined : JSON.parse(data) };
28
+ });
29
+ }
30
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAU,QAAkB,EAAE,cAAuB;IACjF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,cAAc,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,mBAAmB,cAAc,SAAS,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAM,CAAC;AACpD,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAkB;IACjD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,IAAI;SACR,KAAK,CAAC,MAAM,CAAC;SACb,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;QAC7D,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5E,CAAC,CAAC,CAAC;AACP,CAAC"}