@browserlessapi/inferlo 0.0.0-stage → 0.3.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 (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +127 -2
  3. package/dist/ai/index.d.ts +96 -0
  4. package/dist/ai/index.js +327 -0
  5. package/dist/ai/index.js.map +1 -0
  6. package/dist/ai/providers.d.ts +97 -0
  7. package/dist/ai/providers.js +204 -0
  8. package/dist/ai/providers.js.map +1 -0
  9. package/dist/app.d.ts +94 -0
  10. package/dist/app.js +365 -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 +467 -0
  17. package/dist/cli/main.js.map +1 -0
  18. package/dist/db/memory.d.ts +2 -0
  19. package/dist/db/memory.js +128 -0
  20. package/dist/db/memory.js.map +1 -0
  21. package/dist/db/migrate.d.ts +84 -0
  22. package/dist/db/migrate.js +355 -0
  23. package/dist/db/migrate.js.map +1 -0
  24. package/dist/db/postgres.d.ts +37 -0
  25. package/dist/db/postgres.js +338 -0
  26. package/dist/db/postgres.js.map +1 -0
  27. package/dist/db/table.d.ts +72 -0
  28. package/dist/db/table.js +177 -0
  29. package/dist/db/table.js.map +1 -0
  30. package/dist/db/types.d.ts +36 -0
  31. package/dist/db/types.js +2 -0
  32. package/dist/db/types.js.map +1 -0
  33. package/dist/describe.d.ts +56 -0
  34. package/dist/describe.js +64 -0
  35. package/dist/describe.js.map +1 -0
  36. package/dist/env.d.ts +19 -0
  37. package/dist/env.js +72 -0
  38. package/dist/env.js.map +1 -0
  39. package/dist/errors.d.ts +40 -0
  40. package/dist/errors.js +99 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/index.d.ts +26 -0
  43. package/dist/index.js +18 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/mcp.d.ts +18 -0
  46. package/dist/mcp.js +166 -0
  47. package/dist/mcp.js.map +1 -0
  48. package/dist/model.d.ts +36 -0
  49. package/dist/model.js +76 -0
  50. package/dist/model.js.map +1 -0
  51. package/dist/openapi.d.ts +6 -0
  52. package/dist/openapi.js +71 -0
  53. package/dist/openapi.js.map +1 -0
  54. package/dist/route.d.ts +125 -0
  55. package/dist/route.js +28 -0
  56. package/dist/route.js.map +1 -0
  57. package/dist/schema.d.ts +156 -0
  58. package/dist/schema.js +430 -0
  59. package/dist/schema.js.map +1 -0
  60. package/dist/serve.d.ts +11 -0
  61. package/dist/serve.js +83 -0
  62. package/dist/serve.js.map +1 -0
  63. package/dist/testing.d.ts +16 -0
  64. package/dist/testing.js +30 -0
  65. package/dist/testing.js.map +1 -0
  66. package/llms.txt +27 -0
  67. package/package.json +82 -4
  68. package/templates/app/AGENTS.md +53 -0
  69. package/templates/app/CLAUDE.md +1 -0
  70. package/templates/app/README.md +14 -0
  71. package/templates/app/_env.example +5 -0
  72. package/templates/app/_gitignore +3 -0
  73. package/templates/app/package.json.tpl +31 -0
  74. package/templates/app/src/app.ts +38 -0
  75. package/templates/app/src/models.ts +31 -0
  76. package/templates/app/src/routes/health.ts +3 -0
  77. package/templates/app/src/routes/notes.ts +56 -0
  78. package/templates/app/src/server.ts +16 -0
  79. package/templates/app/test/notes.test.ts +50 -0
  80. package/templates/app/tsconfig.json +17 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { ObjectSchema, Schema, type Shape, type ShapeInput, type ShapeOutput, type PartialShape } from "./schema.ts";
2
+ export type SystemShape = {
3
+ id: Schema<string>;
4
+ createdAt: Schema<Date, Date | string>;
5
+ updatedAt: Schema<Date, Date | string>;
6
+ };
7
+ export declare class Model<N extends string = string, S extends Shape = Shape> {
8
+ /** Table name, also the property name on `db` (db.tickets). */
9
+ readonly name: N;
10
+ /** Fields you defined. */
11
+ readonly fields: S;
12
+ /** Full row schema including id, createdAt and updatedAt. */
13
+ readonly row: ObjectSchema<SystemShape & S>;
14
+ /** Input schema for inserts. Fields with defaults or .optional() may be left out. */
15
+ readonly create: ObjectSchema<S>;
16
+ /** Input schema for updates. Every field optional. */
17
+ readonly update: ObjectSchema<PartialShape<S>>;
18
+ /** Type-only: the row type. Prefer Row<typeof Model>. */
19
+ readonly $row: ShapeOutput<SystemShape & S>;
20
+ readonly $create: ShapeInput<S>;
21
+ constructor(name: N, fields: S);
22
+ /** Input schema with only some fields, e.g. for a route body: Ticket.pick("title", "body"). */
23
+ pick<K extends keyof S & string>(...keys: K[]): ObjectSchema<Pick<S, K>>;
24
+ /** Input schema without some fields, e.g. Ticket.omit("ownerId"). */
25
+ omit<K extends keyof S & string>(...keys: K[]): ObjectSchema<Omit<S, K>>;
26
+ }
27
+ export type AnyModel = Model<string, any>;
28
+ /** Row type of a model: Row<typeof Ticket>. */
29
+ export type Row<M extends AnyModel> = M["$row"];
30
+ /** Insert input type of a model. */
31
+ export type CreateInput<M extends AnyModel> = M["$create"];
32
+ /** Update input type of a model. */
33
+ export type UpdateInput<M extends AnyModel> = Partial<M["$create"]>;
34
+ export declare function model<const N extends string, S extends Shape>(name: N, fields: S): Model<N, S>;
35
+ /** camelCase field name to snake_case column name. */
36
+ export declare function columnName(field: string): string;
package/dist/model.js ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * A model is one schema that becomes a database table, validation for create and update,
3
+ * TypeScript types and JSON Schema.
4
+ *
5
+ * export const Ticket = model("tickets", {
6
+ * title: t.string().max(200),
7
+ * priority: t.enum(["low", "normal", "urgent"]).default("normal"),
8
+ * })
9
+ *
10
+ * Every model gets id (uuid), createdAt and updatedAt automatically.
11
+ */
12
+ import { InferloError } from "./errors.js";
13
+ import { ObjectSchema, Schema, t } from "./schema.js";
14
+ const TABLE_NAME = /^[a-z][a-z0-9_]{0,62}$/;
15
+ const FIELD_NAME = /^[a-zA-Z][a-zA-Z0-9]{0,62}$/;
16
+ const RESERVED = new Set(["id", "createdAt", "updatedAt"]);
17
+ function system(schema, kind) {
18
+ return new Schema({ ...schema.def, system: kind });
19
+ }
20
+ export class Model {
21
+ /** Table name, also the property name on `db` (db.tickets). */
22
+ name;
23
+ /** Fields you defined. */
24
+ fields;
25
+ /** Full row schema including id, createdAt and updatedAt. */
26
+ row;
27
+ /** Input schema for inserts. Fields with defaults or .optional() may be left out. */
28
+ create;
29
+ /** Input schema for updates. Every field optional. */
30
+ update;
31
+ constructor(name, fields) {
32
+ if (!TABLE_NAME.test(name)) {
33
+ throw new InferloError("IL4005", `Model name "${name}" is not a valid table name.`, {
34
+ fix: 'Use lowercase letters, digits and underscores, starting with a letter, e.g. model("support_tickets", {...}).',
35
+ });
36
+ }
37
+ for (const key of Object.keys(fields)) {
38
+ if (RESERVED.has(key)) {
39
+ throw new InferloError("IL4006", `Model "${name}" defines "${key}", which Inferlo adds automatically.`, {
40
+ fix: `Remove "${key}" from the model. Every model already has id, createdAt and updatedAt.`,
41
+ });
42
+ }
43
+ if (!FIELD_NAME.test(key)) {
44
+ throw new InferloError("IL4005", `Field "${name}.${key}" is not a valid field name.`, {
45
+ fix: "Use camelCase letters and digits, e.g. ownerId. Inferlo stores it as owner_id.",
46
+ });
47
+ }
48
+ }
49
+ this.name = name;
50
+ this.fields = fields;
51
+ this.create = t.object(fields);
52
+ this.update = this.create.partial();
53
+ const systemShape = {
54
+ id: system(t.uuid(), "id"),
55
+ createdAt: system(t.date(), "createdAt"),
56
+ updatedAt: system(t.date(), "updatedAt"),
57
+ };
58
+ this.row = t.object({ ...systemShape, ...fields });
59
+ }
60
+ /** Input schema with only some fields, e.g. for a route body: Ticket.pick("title", "body"). */
61
+ pick(...keys) {
62
+ return this.create.pick(...keys);
63
+ }
64
+ /** Input schema without some fields, e.g. Ticket.omit("ownerId"). */
65
+ omit(...keys) {
66
+ return this.create.omit(...keys);
67
+ }
68
+ }
69
+ export function model(name, fields) {
70
+ return new Model(name, fields);
71
+ }
72
+ /** camelCase field name to snake_case column name. */
73
+ export function columnName(field) {
74
+ return field.replace(/[A-Z]/g, (c) => "_" + c.toLowerCase());
75
+ }
76
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** OpenAPI 3.1 document generated from routes. Served at /openapi.json by default. */
2
+ import type { App } from "./app.ts";
3
+ export declare function buildOpenAPI(app: App<any>, options: {
4
+ description?: string;
5
+ auth: boolean;
6
+ }): Record<string, unknown>;
@@ -0,0 +1,71 @@
1
+ import { toolName } from "./mcp.js";
2
+ const errorSchema = {
3
+ type: "object",
4
+ properties: {
5
+ error: {
6
+ type: "object",
7
+ properties: {
8
+ code: { type: "string", examples: ["IL1001"] },
9
+ message: { type: "string" },
10
+ fix: { type: "string" },
11
+ details: {},
12
+ docs: { type: "string", format: "uri" },
13
+ },
14
+ required: ["code", "message", "docs"],
15
+ },
16
+ },
17
+ required: ["error"],
18
+ };
19
+ export function buildOpenAPI(app, options) {
20
+ const paths = {};
21
+ for (const route of app.routes) {
22
+ const o = route.options;
23
+ const openPath = route.path.replace(/:([^/]+)/g, "{$1}").replace(/\/\*$/, "/{wildcard}");
24
+ const parameters = [];
25
+ const paramProps = o.params?.toJSONSchema().properties ?? {};
26
+ for (const key of route.path.split("/").filter((p) => p.startsWith(":")).map((p) => p.slice(1))) {
27
+ parameters.push({ name: key, in: "path", required: true, schema: paramProps[key] ?? { type: "string" } });
28
+ }
29
+ if (o.query) {
30
+ const q = o.query.toJSONSchema();
31
+ const required = new Set(q.required ?? []);
32
+ for (const [name, schema] of Object.entries(q.properties ?? {})) {
33
+ parameters.push({ name, in: "query", required: required.has(name), schema });
34
+ }
35
+ }
36
+ const isPublic = (o.auth ?? "user") === "public";
37
+ const operation = {
38
+ operationId: route.name ?? toolName(route),
39
+ summary: o.summary,
40
+ description: o.description,
41
+ tags: o.tags,
42
+ parameters: parameters.length ? parameters : undefined,
43
+ requestBody: o.body ? { required: !o.body.def.optional, content: { "application/json": { schema: o.body.toJSONSchema() } } } : undefined,
44
+ responses: {
45
+ "200": { description: "Success", content: o.response ? { "application/json": { schema: o.response.toJSONSchema() } } : undefined },
46
+ ...(o.body || o.query || o.params ? { "422": { description: "Validation failed (IL1001)", content: { "application/json": { schema: errorSchema } } } } : {}),
47
+ ...(!isPublic ? { "401": { description: "Sign in required (IL3001)", content: { "application/json": { schema: errorSchema } } } } : {}),
48
+ },
49
+ security: !isPublic && options.auth ? [{ bearerAuth: [] }] : undefined,
50
+ "x-inferlo-auth": o.auth ?? "user",
51
+ "x-inferlo-tool": o.tool ? toolName(route) : undefined,
52
+ };
53
+ for (const key of Object.keys(operation))
54
+ if (operation[key] === undefined)
55
+ delete operation[key];
56
+ (paths[openPath] ??= {})[route.method.toLowerCase()] = operation;
57
+ }
58
+ const schemas = {};
59
+ for (const m of app.models)
60
+ schemas[m.name] = m.row.toJSONSchema();
61
+ return {
62
+ openapi: "3.1.0",
63
+ info: { title: app.name, version: app.version, description: options.description },
64
+ paths,
65
+ components: {
66
+ schemas: { ...schemas, Error: errorSchema },
67
+ ...(options.auth ? { securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } } } : {}),
68
+ },
69
+ };
70
+ }
71
+ //# sourceMappingURL=openapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Routes are plain values. Define them anywhere, export them, and pass the modules to createApp.
3
+ *
4
+ * export const createTicket = route.post("/tickets", {
5
+ * auth: "user",
6
+ * body: Ticket.pick("title", "body"),
7
+ * }).handle(({ body, user, db }) => db.tickets.insert({ ...body, ownerId: user.id }))
8
+ *
9
+ * Secure by default: routes require a signed-in user unless you set auth: "public".
10
+ */
11
+ import type { AI } from "./ai/index.ts";
12
+ import type { Db } from "./db/table.ts";
13
+ import type { AnyModel } from "./model.ts";
14
+ import type { AnySchema, Infer, ObjectSchema } from "./schema.ts";
15
+ /**
16
+ * Register your app's models and user type once, so every handler is fully typed:
17
+ *
18
+ * declare module "@browserlessapi/inferlo" {
19
+ * interface Register { models: typeof models; user: User }
20
+ * }
21
+ */
22
+ export interface Register {
23
+ }
24
+ type Registered<K extends string, Fallback> = Register extends {
25
+ [P in K]: infer V;
26
+ } ? V : Fallback;
27
+ export type AppModels = Registered<"models", readonly AnyModel[]> extends infer M extends readonly AnyModel[] ? M : readonly AnyModel[];
28
+ export type AppUser = Registered<"user", {
29
+ id: string;
30
+ roles?: string[];
31
+ }>;
32
+ export type AppDb = Db<AppModels>;
33
+ export type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
34
+ /** "public": anyone. "user": any signed-in user. Any other string: the user must have that role. */
35
+ export type Auth = "public" | "user" | (string & {});
36
+ export interface ToolOptions {
37
+ /** Tool name for MCP clients. Defaults to the exported route name (e.g. createTicket). */
38
+ name?: string;
39
+ /** What the tool does, written for an AI model. Defaults to the route description. */
40
+ description?: string;
41
+ }
42
+ export interface RouteOptions<B extends AnySchema | undefined, Q extends ObjectSchema<any> | undefined, P extends ObjectSchema<any> | undefined> {
43
+ /** Who may call this route. Default "user" (signed in). */
44
+ auth?: Auth;
45
+ /** Request body schema (JSON or form). */
46
+ body?: B;
47
+ /** Query string schema. Strings are converted to numbers and booleans automatically. */
48
+ query?: Q;
49
+ /** Path parameter schema. Without it, path params are strings. */
50
+ params?: P;
51
+ /** Response schema, used for OpenAPI and MCP docs. */
52
+ response?: AnySchema;
53
+ /** One line shown in OpenAPI, describe and MCP. */
54
+ summary?: string;
55
+ description?: string;
56
+ tags?: string[];
57
+ /** Expose this route as an MCP tool for AI agents. Same auth rules apply. */
58
+ tool?: boolean | ToolOptions;
59
+ }
60
+ type PathParams<P extends string> = P extends `${string}:${infer Param}/${infer Rest}` ? {
61
+ [K in Param | keyof PathParams<`/${Rest}`>]: string;
62
+ } : P extends `${string}:${infer Param}` ? {
63
+ [K in Param]: string;
64
+ } : {};
65
+ type UserFor<A> = A extends "public" ? AppUser | null : AppUser;
66
+ export interface Context<Body, Query, Params, User> {
67
+ body: Body;
68
+ query: Query;
69
+ params: Params;
70
+ /** The signed-in user (null only on public routes with no session). */
71
+ user: User;
72
+ db: AppDb;
73
+ ai: AI;
74
+ req: Request;
75
+ url: URL;
76
+ headers: Headers;
77
+ /** Set the response status code. */
78
+ status(code: number): void;
79
+ /** Set a response header. */
80
+ header(name: string, value: string): void;
81
+ /** Values shared by middleware for this request. */
82
+ state: Record<string, unknown>;
83
+ /** Run work after the response is sent (logging, webhooks). Errors are logged, not thrown. */
84
+ waitUntil(promise: Promise<unknown>): void;
85
+ }
86
+ export type AnyContext = Context<any, any, any, any>;
87
+ export type Handler<C, R> = (ctx: C) => R | Promise<R>;
88
+ export interface RouteDef {
89
+ readonly kind: "inferlo.route";
90
+ readonly method: Method;
91
+ readonly path: string;
92
+ readonly options: RouteOptions<any, any, any>;
93
+ readonly handler: Handler<AnyContext, unknown>;
94
+ /** Export name, filled in by createApp when routes are passed as modules. */
95
+ name?: string;
96
+ }
97
+ export declare class RouteBuilder<Path extends string, B extends AnySchema | undefined, Q extends ObjectSchema<any> | undefined, P extends ObjectSchema<any> | undefined, A> {
98
+ readonly method: Method;
99
+ readonly path: Path;
100
+ readonly options: RouteOptions<B, Q, P>;
101
+ constructor(method: Method, path: Path, options: RouteOptions<B, Q, P>);
102
+ /** The request handler. Return data (sent as JSON), a Response, or nothing (204). */
103
+ handle<R>(handler: Handler<Context<B extends AnySchema ? Infer<B> : undefined, Q extends AnySchema ? Infer<Q> : Record<string, string | undefined>, P extends AnySchema ? Infer<P> : PathParams<Path>, UserFor<A>>, R>): RouteDef & {
104
+ readonly $response: Awaited<R>;
105
+ };
106
+ }
107
+ export declare const route: {
108
+ get: <const Path extends string, B extends AnySchema | undefined = undefined, Q extends ObjectSchema<any> | undefined = undefined, P extends ObjectSchema<any> | undefined = undefined, const A extends Auth = "user">(path: Path, options?: RouteOptions<B, Q, P> & {
109
+ auth?: A;
110
+ }) => RouteBuilder<Path, B, Q, P, A>;
111
+ post: <const Path extends string, B extends AnySchema | undefined = undefined, Q extends ObjectSchema<any> | undefined = undefined, P extends ObjectSchema<any> | undefined = undefined, const A extends Auth = "user">(path: Path, options?: RouteOptions<B, Q, P> & {
112
+ auth?: A;
113
+ }) => RouteBuilder<Path, B, Q, P, A>;
114
+ put: <const Path extends string, B extends AnySchema | undefined = undefined, Q extends ObjectSchema<any> | undefined = undefined, P extends ObjectSchema<any> | undefined = undefined, const A extends Auth = "user">(path: Path, options?: RouteOptions<B, Q, P> & {
115
+ auth?: A;
116
+ }) => RouteBuilder<Path, B, Q, P, A>;
117
+ patch: <const Path extends string, B extends AnySchema | undefined = undefined, Q extends ObjectSchema<any> | undefined = undefined, P extends ObjectSchema<any> | undefined = undefined, const A extends Auth = "user">(path: Path, options?: RouteOptions<B, Q, P> & {
118
+ auth?: A;
119
+ }) => RouteBuilder<Path, B, Q, P, A>;
120
+ delete: <const Path extends string, B extends AnySchema | undefined = undefined, Q extends ObjectSchema<any> | undefined = undefined, P extends ObjectSchema<any> | undefined = undefined, const A extends Auth = "user">(path: Path, options?: RouteOptions<B, Q, P> & {
121
+ auth?: A;
122
+ }) => RouteBuilder<Path, B, Q, P, A>;
123
+ };
124
+ export declare function isRoute(value: unknown): value is RouteDef;
125
+ export {};
package/dist/route.js ADDED
@@ -0,0 +1,28 @@
1
+ export class RouteBuilder {
2
+ method;
3
+ path;
4
+ options;
5
+ constructor(method, path, options) {
6
+ this.method = method;
7
+ this.path = path;
8
+ this.options = options;
9
+ }
10
+ /** The request handler. Return data (sent as JSON), a Response, or nothing (204). */
11
+ handle(handler) {
12
+ return { kind: "inferlo.route", method: this.method, path: this.path, options: this.options, handler: handler };
13
+ }
14
+ }
15
+ function builder(method) {
16
+ return (path, options = {}) => new RouteBuilder(method, path, options);
17
+ }
18
+ export const route = {
19
+ get: builder("GET"),
20
+ post: builder("POST"),
21
+ put: builder("PUT"),
22
+ patch: builder("PATCH"),
23
+ delete: builder("DELETE"),
24
+ };
25
+ export function isRoute(value) {
26
+ return typeof value === "object" && value !== null && value.kind === "inferlo.route";
27
+ }
28
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AAuGA,MAAM,OAAO,YAAY;IACd,MAAM,CAAS;IACf,IAAI,CAAO;IACX,OAAO,CAAwB;IAExC,YAAY,MAAc,EAAE,IAAU,EAAE,OAA8B;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,qFAAqF;IACrF,MAAM,CACJ,OAQC;QAED,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAuC,EAE5I,CAAC;IACJ,CAAC;CACF;AAED,SAAS,OAAO,CAAC,MAAc;IAC7B,OAAO,CAOL,IAAU,EACV,UAAgD,EAAE,EAClD,EAAE,CAAC,IAAI,YAAY,CAAmB,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC;CAC1B,CAAC;AAEF,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAAkB,CAAC,IAAI,KAAK,eAAe,CAAC;AACrG,CAAC"}
@@ -0,0 +1,156 @@
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 } from "./errors.ts";
9
+ export type Kind = "string" | "text" | "email" | "url" | "uuid" | "ref" | "number" | "int" | "boolean" | "date" | "enum" | "literal" | "json" | "array" | "object" | "any";
10
+ export interface Def {
11
+ kind: Kind;
12
+ optional: boolean;
13
+ nullable: boolean;
14
+ hasDefault: boolean;
15
+ defaultValue?: unknown;
16
+ min?: number;
17
+ max?: number;
18
+ pattern?: RegExp;
19
+ values?: readonly (string | number | boolean)[];
20
+ item?: AnySchema;
21
+ shape?: Shape;
22
+ unknownKeys?: "strict" | "strip";
23
+ refTable?: string;
24
+ onDelete?: "restrict" | "cascade" | "set null";
25
+ description?: string;
26
+ example?: unknown;
27
+ unique?: boolean;
28
+ index?: boolean;
29
+ /** Filled in by the framework (id, createdAt, updatedAt). Never accepted as input. */
30
+ system?: "id" | "createdAt" | "updatedAt";
31
+ }
32
+ export interface Issue {
33
+ path: (string | number)[];
34
+ code: string;
35
+ message: string;
36
+ }
37
+ export type ParseResult<T> = {
38
+ ok: true;
39
+ value: T;
40
+ } | {
41
+ ok: false;
42
+ issues: Issue[];
43
+ };
44
+ export interface ParseOptions {
45
+ /** Convert strings to numbers, booleans and dates (used for query strings and path params). */
46
+ coerce?: boolean;
47
+ }
48
+ export declare class ValidationError extends InferloError {
49
+ readonly issues: Issue[];
50
+ constructor(issues: Issue[], where?: string);
51
+ }
52
+ export type JSONSchema = Record<string, unknown>;
53
+ export type AnySchema = Schema<any, any>;
54
+ export type Shape = Record<string, AnySchema>;
55
+ /** The parsed (output) type of a schema. */
56
+ export type Infer<S> = S extends Schema<infer O, any> ? O : never;
57
+ /** The accepted input type of a schema (fields with defaults are optional). */
58
+ export type InferInput<S> = S extends Schema<any, infer I> ? I : never;
59
+ type Simplify<T> = {
60
+ [K in keyof T]: T[K];
61
+ } & {};
62
+ type OptionalKeys<T> = {
63
+ [K in keyof T]-?: undefined extends T[K] ? K : never;
64
+ }[keyof T];
65
+ type Objectify<T> = Simplify<{
66
+ [K in Exclude<keyof T, OptionalKeys<T>>]: T[K];
67
+ } & {
68
+ [K in OptionalKeys<T>]?: T[K];
69
+ }>;
70
+ export type ShapeOutput<S extends Shape> = Objectify<{
71
+ [K in keyof S]: Infer<S[K]>;
72
+ }>;
73
+ export type ShapeInput<S extends Shape> = Objectify<{
74
+ [K in keyof S]: InferInput<S[K]>;
75
+ }>;
76
+ export type PartialShape<S extends Shape> = {
77
+ [K in keyof S]: Schema<Infer<S[K]> | undefined, InferInput<S[K]> | undefined>;
78
+ };
79
+ export declare class Schema<Out, In = Out> {
80
+ readonly def: Def;
81
+ /** Type-only markers. Use Infer<typeof schema> instead of reading these. */
82
+ readonly _output: Out;
83
+ readonly _input: In;
84
+ constructor(def: Def);
85
+ protected with(changes: Partial<Def>): this;
86
+ /** Field may be left out. */
87
+ optional(): Schema<Out | undefined, In | undefined>;
88
+ /** Field may be null. */
89
+ nullable(): Schema<Out | null, In | null>;
90
+ /** Value used when the field is left out. Pass a function for values like dates. */
91
+ default(value: Exclude<Out, undefined> | (() => Exclude<Out, undefined>)): Schema<Exclude<Out, undefined>, In | undefined>;
92
+ /** Minimum length (strings, arrays) or minimum value (numbers). */
93
+ min(n: number): this;
94
+ /** Maximum length (strings, arrays) or maximum value (numbers). */
95
+ max(n: number): this;
96
+ /** Strings must match this regular expression. */
97
+ regex(pattern: RegExp): this;
98
+ /** Shown in OpenAPI, MCP tool definitions and AI prompts. */
99
+ describe(description: string): this;
100
+ example(value: Out): this;
101
+ /** Database: unique column. */
102
+ unique(): this;
103
+ /** Database: add an index on this column. */
104
+ index(): this;
105
+ /** Validate and return typed data, or throw ValidationError (HTTP 422). */
106
+ parse(input: unknown, options?: ParseOptions): Out;
107
+ /** Validate without throwing. */
108
+ safeParse(input: unknown, options?: ParseOptions): ParseResult<Out>;
109
+ /** JSON Schema (draft 2020-12 compatible) for OpenAPI, MCP and AI structured output. */
110
+ toJSONSchema(): JSONSchema;
111
+ }
112
+ export declare class ObjectSchema<S extends Shape> extends Schema<ShapeOutput<S>, ShapeInput<S>> {
113
+ get shape(): S;
114
+ /** Keep only some fields. */
115
+ pick<K extends keyof S & string>(...keys: K[]): ObjectSchema<Pick<S, K>>;
116
+ /** Drop some fields. */
117
+ omit<K extends keyof S & string>(...keys: K[]): ObjectSchema<Omit<S, K>>;
118
+ /** Every field optional (for PATCH bodies). Defaults are not applied. */
119
+ partial(): ObjectSchema<PartialShape<S>>;
120
+ /** Add fields. */
121
+ extend<E extends Shape>(extra: E): ObjectSchema<Omit<S, keyof E> & E>;
122
+ /** Silently drop unknown keys instead of rejecting them (the default is to reject). */
123
+ strip(): this;
124
+ }
125
+ export declare class ArraySchema<I extends AnySchema> extends Schema<Infer<I>[], InferInput<I>[]> {
126
+ get item(): I;
127
+ }
128
+ export declare const t: {
129
+ /** Short text. Stored as text (or varchar(max) when .max() is set). */
130
+ string: () => Schema<string, string>;
131
+ /** Long text such as a post body. */
132
+ text: () => Schema<string, string>;
133
+ email: () => Schema<string, string>;
134
+ url: () => Schema<string, string>;
135
+ uuid: () => Schema<string, string>;
136
+ number: () => Schema<number, number>;
137
+ /** Whole number. */
138
+ int: () => Schema<number, number>;
139
+ boolean: () => Schema<boolean, boolean>;
140
+ /** Accepts a Date or an ISO 8601 string, always returns a Date. */
141
+ date: () => Schema<Date, string | Date>;
142
+ /** One of a fixed list of strings: t.enum(["low", "normal", "urgent"]). */
143
+ enum: <const V extends readonly [string, ...string[]]>(values: V) => Schema<V[number], V[number]>;
144
+ literal: <const V extends string | number | boolean>(value: V) => Schema<V, V>;
145
+ /** Any JSON value. Stored as jsonb. */
146
+ json: <T = unknown>() => Schema<T, T>;
147
+ array: <I extends AnySchema>(item: I) => ArraySchema<I>;
148
+ object: <S extends Shape>(shape: S) => ObjectSchema<S>;
149
+ /** Id of a row in another model's table: t.ref("users"). */
150
+ ref: (table: string, options?: {
151
+ onDelete?: "restrict" | "cascade" | "set null";
152
+ }) => Schema<string, string>;
153
+ any: () => Schema<unknown, unknown>;
154
+ };
155
+ export declare function toJSONSchema(schema: AnySchema): JSONSchema;
156
+ export {};