better-call 0.0.0-experimental.06264e12

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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +254 -0
  3. package/dist/error.cjs +67 -0
  4. package/dist/error.cjs.map +1 -0
  5. package/dist/error.d.cts +46 -0
  6. package/dist/error.d.mts +46 -0
  7. package/dist/error.mjs +64 -0
  8. package/dist/error.mjs.map +1 -0
  9. package/dist/fn.cjs +335 -0
  10. package/dist/fn.cjs.map +1 -0
  11. package/dist/fn.d.cts +312 -0
  12. package/dist/fn.d.mts +312 -0
  13. package/dist/fn.mjs +335 -0
  14. package/dist/fn.mjs.map +1 -0
  15. package/dist/index.cjs +37 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +46 -0
  18. package/dist/index.d.mts +46 -0
  19. package/dist/index.mjs +24 -0
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/module.cjs +111 -0
  22. package/dist/module.cjs.map +1 -0
  23. package/dist/module.d.cts +249 -0
  24. package/dist/module.d.mts +249 -0
  25. package/dist/module.mjs +102 -0
  26. package/dist/module.mjs.map +1 -0
  27. package/dist/plugins/http.cjs +185 -0
  28. package/dist/plugins/http.cjs.map +1 -0
  29. package/dist/plugins/http.d.cts +1261 -0
  30. package/dist/plugins/http.d.mts +1261 -0
  31. package/dist/plugins/http.mjs +175 -0
  32. package/dist/plugins/http.mjs.map +1 -0
  33. package/dist/plugins/read-only.cjs +19 -0
  34. package/dist/plugins/read-only.cjs.map +1 -0
  35. package/dist/plugins/read-only.d.cts +17 -0
  36. package/dist/plugins/read-only.d.mts +17 -0
  37. package/dist/plugins/read-only.mjs +19 -0
  38. package/dist/plugins/read-only.mjs.map +1 -0
  39. package/dist/schema.cjs +167 -0
  40. package/dist/schema.cjs.map +1 -0
  41. package/dist/schema.d.cts +225 -0
  42. package/dist/schema.d.mts +225 -0
  43. package/dist/schema.mjs +159 -0
  44. package/dist/schema.mjs.map +1 -0
  45. package/dist/scope.d.cts +18 -0
  46. package/dist/scope.d.mts +18 -0
  47. package/dist/storage.cjs +256 -0
  48. package/dist/storage.cjs.map +1 -0
  49. package/dist/storage.d.cts +195 -0
  50. package/dist/storage.d.mts +195 -0
  51. package/dist/storage.mjs +253 -0
  52. package/dist/storage.mjs.map +1 -0
  53. package/dist/types.d.cts +8 -0
  54. package/dist/types.d.mts +8 -0
  55. package/dist/var.cjs +162 -0
  56. package/dist/var.cjs.map +1 -0
  57. package/dist/var.d.cts +36 -0
  58. package/dist/var.d.mts +36 -0
  59. package/dist/var.mjs +154 -0
  60. package/dist/var.mjs.map +1 -0
  61. package/package.json +92 -0
@@ -0,0 +1,175 @@
1
+ import { v } from "../index.mjs";
2
+ //#region src/plugins/http.ts
3
+ const parseQuery = (url) => {
4
+ const q = {};
5
+ for (const [key, value] of url.searchParams) {
6
+ const current = q[key];
7
+ q[key] = current === void 0 ? value : Array.isArray(current) ? [...current, value] : [current, value];
8
+ }
9
+ return q;
10
+ };
11
+ const parseCookies = (header) => {
12
+ const jar = {};
13
+ for (const part of (header ?? "").split(";")) {
14
+ const [name, ...rest] = part.trim().split("=");
15
+ if (name) jar[name] = decodeURIComponent(rest.join("="));
16
+ }
17
+ return jar;
18
+ };
19
+ /** Build the `req` value from a fetch Request. The body cannot be read
20
+ * synchronously, so it comes in from whoever already awaited it -
21
+ * `fromRequest` does that for you. */
22
+ const toHttpRequest = (raw, body) => {
23
+ const url = new URL(raw.url);
24
+ return {
25
+ raw,
26
+ method: raw.method.toUpperCase(),
27
+ path: url.pathname,
28
+ headers: raw.headers,
29
+ query: parseQuery(url),
30
+ cookies: parseCookies(raw.headers.get("cookie")),
31
+ body
32
+ };
33
+ };
34
+ const req = v.var("req", { default: null });
35
+ const res = v.var("res", { default: null });
36
+ const httpVars = {
37
+ req,
38
+ res
39
+ };
40
+ const fromRequest = v.fn({ use: [httpVars] }).fn("http.from_request", {
41
+ input: { request: v.any() },
42
+ provides: ["req"]
43
+ }, async (c) => {
44
+ const raw = c.input.request;
45
+ let body;
46
+ if (raw.method !== "GET" && raw.method !== "HEAD") {
47
+ const contentType = raw.headers.get("content-type") ?? "";
48
+ if (contentType.includes("json")) body = await raw.clone().json().catch(() => void 0);
49
+ else if (contentType.includes("text")) body = await raw.clone().text().catch(() => void 0);
50
+ }
51
+ const value = toHttpRequest(raw, body);
52
+ c.req = value;
53
+ c.res = { headers: new Headers() };
54
+ return {
55
+ method: value.method,
56
+ path: value.path
57
+ };
58
+ });
59
+ /** Cookie attributes as a SCHEMA - the source of truth. The TS type
60
+ * falls out of it, and everything crossing a fn door validates against
61
+ * it (enum-checked sameSite, `instanceof`-checked expires). */
62
+ const cookieShape = {
63
+ maxAge: v.number({ optional: true }),
64
+ expires: v.date({ optional: true }),
65
+ path: v.string({ optional: true }),
66
+ domain: v.string({ optional: true }),
67
+ secure: v.boolean({ optional: true }),
68
+ httpOnly: v.boolean({ optional: true }),
69
+ sameSite: v.string({
70
+ enum: [
71
+ "strict",
72
+ "lax",
73
+ "none"
74
+ ],
75
+ optional: true
76
+ })
77
+ };
78
+ /**
79
+ * Scope-level cookie DEFAULTS, as a var: whatever sets it - app setup, a
80
+ * module, an interceptor - every `setCookie` below merges its per-call
81
+ * options ON TOP. Config that travels down the call tree is exactly what
82
+ * a var is, so "change the global cookie config" is just a `.set()` at
83
+ * any point in the scope.
84
+ */
85
+ const cookieOptions = v.var("cookieOptions", {
86
+ default: {},
87
+ schema: v.object(cookieShape)
88
+ });
89
+ /** The per-call options field: the same shape, optional to send. */
90
+ const cookieOptionsField = v.object(cookieShape, { optional: true });
91
+ const serialize = (name, value, options = {}) => {
92
+ const parts = [`${name}=${encodeURIComponent(value)}`];
93
+ if (options.maxAge !== void 0) parts.push(`Max-Age=${options.maxAge}`);
94
+ if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);
95
+ if (options.path) parts.push(`Path=${options.path}`);
96
+ if (options.domain) parts.push(`Domain=${options.domain}`);
97
+ if (options.secure) parts.push("Secure");
98
+ if (options.httpOnly) parts.push("HttpOnly");
99
+ if (options.sameSite) parts.push(`SameSite=${options.sameSite.charAt(0).toUpperCase()}${options.sameSite.slice(1)}`);
100
+ return parts.join("; ");
101
+ };
102
+ const ck = v.fn("cookie.", { use: [{
103
+ req,
104
+ res,
105
+ cookieOptions
106
+ }] });
107
+ /** Read one cookie from the REQUEST jar. Positional: `getCookie("theme")`.
108
+ * Readonly - reading a cookie can never write the scope. */
109
+ const getCookie = ck.fn("get", {
110
+ input: [v.string()],
111
+ readonly: true
112
+ }, (c) => {
113
+ const [name] = c.input;
114
+ return c.req?.cookies[name] ?? null;
115
+ });
116
+ /** Queue a Set-Cookie on the scope's response headers: the scope's
117
+ * `cookieOptions` defaults, with per-call options merged on top. The
118
+ * written cookie also lands in the request jar, so a later `getCookie`
119
+ * in the same scope reads what was set. */
120
+ const setCookie = ck.fn("set", { input: {
121
+ name: v.string(),
122
+ value: v.string(),
123
+ options: cookieOptionsField
124
+ } }, (c) => {
125
+ const { name, value, options } = c.input;
126
+ let response = c.res;
127
+ if (!response) {
128
+ response = { headers: new Headers() };
129
+ c.res = response;
130
+ }
131
+ response.headers.append("set-cookie", serialize(name, value, {
132
+ ...c.cookieOptions,
133
+ ...options
134
+ }));
135
+ const current = c.req;
136
+ if (current) c.req = {
137
+ ...current,
138
+ cookies: {
139
+ ...current.cookies,
140
+ [name]: value
141
+ }
142
+ };
143
+ return { set: true };
144
+ });
145
+ /** Expire a cookie: a Set-Cookie with Max-Age=0 - the attributes (path,
146
+ * domain) must match the ones it was set with. */
147
+ const deleteCookie = ck.fn("delete", {
148
+ input: {
149
+ name: v.string(),
150
+ options: cookieOptionsField
151
+ },
152
+ use: [{ setCookie }]
153
+ }, (c) => {
154
+ const { name, options } = c.input;
155
+ return c.setCookie({
156
+ name,
157
+ value: "",
158
+ options: {
159
+ ...options,
160
+ maxAge: 0
161
+ }
162
+ });
163
+ });
164
+ const http = {
165
+ ...httpVars,
166
+ cookieOptions,
167
+ handler: fromRequest,
168
+ getCookie,
169
+ setCookie,
170
+ deleteCookie
171
+ };
172
+ //#endregion
173
+ export { cookieOptions, cookieShape, deleteCookie, fromRequest, getCookie, http, req, res, setCookie, toHttpRequest };
174
+
175
+ //# sourceMappingURL=http.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.mjs","names":[],"sources":["../../src/plugins/http.ts"],"sourcesContent":["import { v } from \"../index\";\nimport type { InferArgs } from \"../schema\";\n\nconst parseQuery = (url: URL) => {\n\tconst q: Record<string, string | string[]> = {};\n\tfor (const [key, value] of url.searchParams) {\n\t\tconst current = q[key];\n\t\tq[key] =\n\t\t\tcurrent === undefined\n\t\t\t\t? value\n\t\t\t\t: Array.isArray(current)\n\t\t\t\t\t? [...current, value]\n\t\t\t\t\t: [current, value];\n\t}\n\treturn q;\n};\n\nconst parseCookies = (header: string | null) => {\n\tconst jar: Record<string, string> = {};\n\tfor (const part of (header ?? \"\").split(\";\")) {\n\t\tconst [name, ...rest] = part.trim().split(\"=\");\n\t\tif (name) jar[name] = decodeURIComponent(rest.join(\"=\"));\n\t}\n\treturn jar;\n};\n\n/** The whole request-side state, as ONE value: `c.req` and\n * everything is there - no per-piece vars to require one by one. */\nexport type HttpRequest = {\n\t/** The fetch Request itself, untouched. */\n\traw: Request;\n\tmethod: string;\n\tpath: string;\n\theaders: Headers;\n\tquery: Record<string, string | string[]>;\n\tcookies: Record<string, string>;\n\t/** Parsed by `fromRequest` when the content type says json/text -\n\t * anything else stays on `raw`. */\n\tbody: unknown;\n};\n\n/** Build the `req` value from a fetch Request. The body cannot be read\n * synchronously, so it comes in from whoever already awaited it -\n * `fromRequest` does that for you. */\nexport const toHttpRequest = (raw: Request, body?: unknown): HttpRequest => {\n\tconst url = new URL(raw.url);\n\treturn {\n\t\traw,\n\t\tmethod: raw.method.toUpperCase(),\n\t\tpath: url.pathname,\n\t\theaders: raw.headers,\n\t\tquery: parseQuery(url),\n\t\tcookies: parseCookies(raw.headers.get(\"cookie\")),\n\t\tbody,\n\t};\n};\n\nexport const req = v.var(\"req\", { default: null as HttpRequest | null });\n\n/** The response side, as ONE value. `headers` and `status` are meant to\n * be MUTATED in place (`res.headers.set(...)`, `res.status = 201`) - the\n * object is shared with whoever builds the final Response, so in-place\n * writes are exactly what travels back. */\nexport type HttpResponse = {\n\theaders: Headers;\n\t/** Steers the answering Response's status - assign it in place. */\n\tstatus?: number;\n\tstatusText?: string;\n};\n\nexport const res = v.var(\"res\", { default: null as HttpResponse | null });\n\nconst httpVars = { req, res };\n\nconst h = v.fn({ use: [httpVars] });\n\nexport const fromRequest = h.fn(\n\t\"http.from_request\",\n\t{ input: { request: v.any<Request>() }, provides: [\"req\"] },\n\tasync (c) => {\n\t\tconst raw = c.input.request;\n\t\tlet body: unknown;\n\t\tif (raw.method !== \"GET\" && raw.method !== \"HEAD\") {\n\t\t\tconst contentType = raw.headers.get(\"content-type\") ?? \"\";\n\t\t\tif (contentType.includes(\"json\")) {\n\t\t\t\tbody = await raw\n\t\t\t\t\t.clone()\n\t\t\t\t\t.json()\n\t\t\t\t\t.catch(() => undefined);\n\t\t\t} else if (contentType.includes(\"text\")) {\n\t\t\t\tbody = await raw\n\t\t\t\t\t.clone()\n\t\t\t\t\t.text()\n\t\t\t\t\t.catch(() => undefined);\n\t\t\t}\n\t\t}\n\t\tconst value = toHttpRequest(raw, body);\n\t\tc.req = value;\n\t\tc.res = { headers: new Headers() };\n\t\treturn { method: value.method, path: value.path };\n\t},\n);\n\n/* --------------------------------- cookies --------------------------------- */\n\n/** Cookie attributes as a SCHEMA - the source of truth. The TS type\n * falls out of it, and everything crossing a fn door validates against\n * it (enum-checked sameSite, `instanceof`-checked expires). */\nexport const cookieShape = {\n\tmaxAge: v.number({ optional: true }),\n\texpires: v.date({ optional: true }),\n\tpath: v.string({ optional: true }),\n\tdomain: v.string({ optional: true }),\n\tsecure: v.boolean({ optional: true }),\n\thttpOnly: v.boolean({ optional: true }),\n\tsameSite: v.string({ enum: [\"strict\", \"lax\", \"none\"], optional: true }),\n};\n\nexport type CookieOptions = InferArgs<typeof cookieShape>;\n\n/**\n * Scope-level cookie DEFAULTS, as a var: whatever sets it - app setup, a\n * module, an interceptor - every `setCookie` below merges its per-call\n * options ON TOP. Config that travels down the call tree is exactly what\n * a var is, so \"change the global cookie config\" is just a `.set()` at\n * any point in the scope.\n */\nexport const cookieOptions = v.var(\"cookieOptions\", {\n\tdefault: {},\n\tschema: v.object(cookieShape),\n});\n\n/** The per-call options field: the same shape, optional to send. */\nconst cookieOptionsField = v.object(cookieShape, { optional: true });\n\nconst serialize = (\n\tname: string,\n\tvalue: string,\n\toptions: CookieOptions = {},\n) => {\n\tconst parts = [`${name}=${encodeURIComponent(value)}`];\n\tif (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n\tif (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n\tif (options.path) parts.push(`Path=${options.path}`);\n\tif (options.domain) parts.push(`Domain=${options.domain}`);\n\tif (options.secure) parts.push(\"Secure\");\n\tif (options.httpOnly) parts.push(\"HttpOnly\");\n\tif (options.sameSite) {\n\t\tparts.push(\n\t\t\t`SameSite=${options.sameSite.charAt(0).toUpperCase()}${options.sameSite.slice(1)}`,\n\t\t);\n\t}\n\treturn parts.join(\"; \");\n};\n\nconst ck = v.fn(\"cookie.\", {\n\tuse: [{ req, res, cookieOptions }],\n});\n\n/** Read one cookie from the REQUEST jar. Positional: `getCookie(\"theme\")`.\n * Readonly - reading a cookie can never write the scope. */\nexport const getCookie = ck.fn(\n\t\"get\",\n\t{ input: [v.string()], readonly: true },\n\t(c): string | null => {\n\t\tconst [name] = c.input;\n\t\treturn c.req?.cookies[name] ?? null;\n\t},\n);\n\n/** Queue a Set-Cookie on the scope's response headers: the scope's\n * `cookieOptions` defaults, with per-call options merged on top. The\n * written cookie also lands in the request jar, so a later `getCookie`\n * in the same scope reads what was set. */\nexport const setCookie = ck.fn(\n\t\"set\",\n\t{\n\t\tinput: {\n\t\t\tname: v.string(),\n\t\t\tvalue: v.string(),\n\t\t\toptions: cookieOptionsField,\n\t\t},\n\t},\n\t(c) => {\n\t\tconst { name, value, options } = c.input;\n\t\tlet response = c.res;\n\t\tif (!response) {\n\t\t\tresponse = { headers: new Headers() };\n\t\t\tc.res = response;\n\t\t}\n\t\tresponse.headers.append(\n\t\t\t\"set-cookie\",\n\t\t\tserialize(name, value, { ...c.cookieOptions, ...options }),\n\t\t);\n\t\tconst current = c.req;\n\t\tif (current) {\n\t\t\tc.req = {\n\t\t\t\t...current,\n\t\t\t\tcookies: { ...current.cookies, [name]: value },\n\t\t\t};\n\t\t}\n\t\treturn { set: true };\n\t},\n);\n\n/** Expire a cookie: a Set-Cookie with Max-Age=0 - the attributes (path,\n * domain) must match the ones it was set with. */\nexport const deleteCookie = ck.fn(\n\t\"delete\",\n\t{\n\t\tinput: {\n\t\t\tname: v.string(),\n\t\t\toptions: cookieOptionsField,\n\t\t},\n\t\tuse: [{ setCookie }],\n\t},\n\t(c) => {\n\t\tconst { name, options } = c.input;\n\t\treturn c.setCookie({\n\t\t\tname,\n\t\t\tvalue: \"\",\n\t\t\toptions: { ...options, maxAge: 0 },\n\t\t});\n\t},\n);\n\nexport const http = {\n\t...httpVars,\n\tcookieOptions,\n\thandler: fromRequest,\n\tgetCookie,\n\tsetCookie,\n\tdeleteCookie,\n};\n"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_error = require("../error.cjs");
3
+ //#region src/plugins/read-only.ts
4
+ /**
5
+ * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,
6
+ * any depth, interceptors included - cannot write vars: every set throws,
7
+ * naming the offender. Nothing here is privileged: var writes are events,
8
+ * and this module is one `v.on` listener.
9
+ *
10
+ * Pairs with the `readonly: true` fn option, which adds the TYPE half
11
+ * (vars readonly on `c`, declared writers uncallable).
12
+ */
13
+ const readOnly = { _readOnly: require("../index.cjs").v.on("var.set.*", (c) => {
14
+ throw new require_error.ValidationError(`${c.fn}.readonly`, `readonly scope: attempted to set var "${c.name}"`);
15
+ }) };
16
+ //#endregion
17
+ exports.readOnly = readOnly;
18
+
19
+ //# sourceMappingURL=read-only.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.cjs","names":["v","ValidationError"],"sources":["../../src/plugins/read-only.ts"],"sourcesContent":["import { ValidationError, v } from \"../index\";\n\n/**\n * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,\n * any depth, interceptors included - cannot write vars: every set throws,\n * naming the offender. Nothing here is privileged: var writes are events,\n * and this module is one `v.on` listener.\n *\n * Pairs with the `readonly: true` fn option, which adds the TYPE half\n * (vars readonly on `c`, declared writers uncallable).\n */\nexport const readOnly = {\n\t_readOnly: v.on(\"var.set.*\", (c) => {\n\t\tthrow new ValidationError(\n\t\t\t`${c.fn}.readonly`,\n\t\t\t`readonly scope: attempted to set var \"${c.name}\"`,\n\t\t);\n\t}),\n};\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,WAAW,EACvB,iCAAWA,CAAAA,CAAAA,EAAE,GAAG,cAAc,MAAM;CACnC,MAAM,IAAIC,cAAAA,gBACT,GAAG,EAAE,GAAG,YACR,yCAAyC,EAAE,KAAK,EACjD;AACD,CAAC,EACF"}
@@ -0,0 +1,17 @@
1
+ import { OnEntry } from "../module.cjs";
2
+ //#region src/plugins/read-only.d.ts
3
+ /**
4
+ * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,
5
+ * any depth, interceptors included - cannot write vars: every set throws,
6
+ * naming the offender. Nothing here is privileged: var writes are events,
7
+ * and this module is one `v.on` listener.
8
+ *
9
+ * Pairs with the `readonly: true` fn option, which adds the TYPE half
10
+ * (vars readonly on `c`, declared writers uncallable).
11
+ */
12
+ declare const readOnly: {
13
+ _readOnly: OnEntry<"var.set.*", unknown>;
14
+ };
15
+ //#endregion
16
+ export { readOnly };
17
+ //# sourceMappingURL=read-only.d.cts.map
@@ -0,0 +1,17 @@
1
+ import { OnEntry } from "../module.mjs";
2
+ //#region src/plugins/read-only.d.ts
3
+ /**
4
+ * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,
5
+ * any depth, interceptors included - cannot write vars: every set throws,
6
+ * naming the offender. Nothing here is privileged: var writes are events,
7
+ * and this module is one `v.on` listener.
8
+ *
9
+ * Pairs with the `readonly: true` fn option, which adds the TYPE half
10
+ * (vars readonly on `c`, declared writers uncallable).
11
+ */
12
+ declare const readOnly: {
13
+ _readOnly: OnEntry<"var.set.*", unknown>;
14
+ };
15
+ //#endregion
16
+ export { readOnly };
17
+ //# sourceMappingURL=read-only.d.mts.map
@@ -0,0 +1,19 @@
1
+ import { ValidationError } from "../error.mjs";
2
+ import { v } from "../index.mjs";
3
+ //#region src/plugins/read-only.ts
4
+ /**
5
+ * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,
6
+ * any depth, interceptors included - cannot write vars: every set throws,
7
+ * naming the offender. Nothing here is privileged: var writes are events,
8
+ * and this module is one `v.on` listener.
9
+ *
10
+ * Pairs with the `readonly: true` fn option, which adds the TYPE half
11
+ * (vars readonly on `c`, declared writers uncallable).
12
+ */
13
+ const readOnly = { _readOnly: v.on("var.set.*", (c) => {
14
+ throw new ValidationError(`${c.fn}.readonly`, `readonly scope: attempted to set var "${c.name}"`);
15
+ }) };
16
+ //#endregion
17
+ export { readOnly };
18
+
19
+ //# sourceMappingURL=read-only.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-only.mjs","names":[],"sources":["../../src/plugins/read-only.ts"],"sourcesContent":["import { ValidationError, v } from \"../index\";\n\n/**\n * Mount via `use: [readOnly]` and this fn - plus EVERYTHING it calls,\n * any depth, interceptors included - cannot write vars: every set throws,\n * naming the offender. Nothing here is privileged: var writes are events,\n * and this module is one `v.on` listener.\n *\n * Pairs with the `readonly: true` fn option, which adds the TYPE half\n * (vars readonly on `c`, declared writers uncallable).\n */\nexport const readOnly = {\n\t_readOnly: v.on(\"var.set.*\", (c) => {\n\t\tthrow new ValidationError(\n\t\t\t`${c.fn}.readonly`,\n\t\t\t`readonly scope: attempted to set var \"${c.name}\"`,\n\t\t);\n\t}),\n};\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,WAAW,EACvB,WAAW,EAAE,GAAG,cAAc,MAAM;CACnC,MAAM,IAAI,gBACT,GAAG,EAAE,GAAG,YACR,yCAAyC,EAAE,KAAK,EACjD;AACD,CAAC,EACF"}
@@ -0,0 +1,167 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_error = require("./error.cjs");
3
+ //#region src/schema.ts
4
+ /** The runtime unwrap: `def` is the documented schema (falls back to
5
+ * `validation`), `validation` is what the exit check runs - undefined
6
+ * means no check. A bare schema is both. */
7
+ const outputContract = (output) => {
8
+ if (output === void 0) return {};
9
+ if (output !== null && typeof output === "object" && !Array.isArray(output) && !isType(output) && !isVar(output) && !isFnSchema(output)) {
10
+ const keys = Object.keys(output);
11
+ if (keys.length > 0 && keys.every((k) => k === "def" || k === "validation")) {
12
+ const { def, validation } = output;
13
+ return {
14
+ def: def ?? validation,
15
+ validation
16
+ };
17
+ }
18
+ }
19
+ return {
20
+ def: output,
21
+ validation: output
22
+ };
23
+ };
24
+ const isType = (value) => typeof value?.name === "string";
25
+ /** A handler-less `v.fn(...)` builder doubles as a schema: the value it
26
+ * describes is a FN with the declared signature. The builder FN itself is
27
+ * branded too, so bare `v.fn` reads as "any function". */
28
+ const isFnSchema = (value) => typeof value?.$fnSchema === "object" && value.$fnSchema !== null;
29
+ const asType = (value) => isVar(value) ? asType(value.schema ?? {}) : isFnSchema(value) ? {
30
+ name: "function",
31
+ fnInput: value.$fnSchema.input
32
+ } : isType(value) ? value : {
33
+ name: "object",
34
+ shape: value
35
+ };
36
+ const typeOf = (value) => value === null ? "null" : Array.isArray(value) ? "array" : Number.isNaN(value) ? "NaN" : typeof value;
37
+ const isVar = (value) => value?.$var === true;
38
+ const EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
39
+ const fail = (path, message) => {
40
+ throw new require_error.ValidationError(path, message);
41
+ };
42
+ /** Constraint checks, run after the value's type is known to be right. */
43
+ const applyRules = (def, value, path) => {
44
+ if (def.enum && !def.enum.includes(value)) fail(path, `expected one of ${def.enum.join(", ")}, received ${value}`);
45
+ if (typeof value === "string") {
46
+ if (def.length !== void 0 && value.length !== def.length) fail(path, `expected length ${def.length}, received ${value.length}`);
47
+ if (def.min !== void 0 && value.length < def.min) fail(path, `expected at least ${def.min} characters, received ${value.length}`);
48
+ if (def.max !== void 0 && value.length > def.max) fail(path, `expected at most ${def.max} characters, received ${value.length}`);
49
+ if (def.regex && !def.regex.test(value)) fail(path, `does not match ${def.regex}`);
50
+ if (def.email && !EMAIL.test(value)) fail(path, "expected an email address");
51
+ if (def.url) try {
52
+ new URL(value);
53
+ } catch {
54
+ fail(path, "expected a URL");
55
+ }
56
+ if (def.startsWith !== void 0 && !value.startsWith(def.startsWith)) fail(path, `expected to start with "${def.startsWith}"`);
57
+ if (def.endsWith !== void 0 && !value.endsWith(def.endsWith)) fail(path, `expected to end with "${def.endsWith}"`);
58
+ }
59
+ if (Array.isArray(value)) {
60
+ if (def.length !== void 0 && value.length !== def.length) fail(path, `expected length ${def.length}, received ${value.length}`);
61
+ if (def.min !== void 0 && value.length < def.min) fail(path, `expected at least ${def.min} items, received ${value.length}`);
62
+ if (def.max !== void 0 && value.length > def.max) fail(path, `expected at most ${def.max} items, received ${value.length}`);
63
+ }
64
+ if (typeof value === "number") {
65
+ if (def.int && !Number.isInteger(value)) fail(path, `expected an integer, received ${value}`);
66
+ if (def.min !== void 0 && value < def.min) fail(path, `expected >= ${def.min}, received ${value}`);
67
+ if (def.max !== void 0 && value > def.max) fail(path, `expected <= ${def.max}, received ${value}`);
68
+ }
69
+ if (def.check) {
70
+ const result = def.check(value);
71
+ if (result !== true) fail(path, typeof result === "string" ? result : "failed check");
72
+ }
73
+ };
74
+ const validate = (def, value, path) => {
75
+ if (value === void 0) {
76
+ if (def.default !== void 0) value = def.default;
77
+ else if (def.optional) return void 0;
78
+ }
79
+ if (isVar(def)) {
80
+ if (value === void 0) return void 0;
81
+ const schema = def.schema;
82
+ return schema === void 0 ? value : validate(schema, value, path);
83
+ }
84
+ if (def.name === "any") return def.transform ? def.transform(value) : value;
85
+ if (def.name === "date") {
86
+ if (!(value instanceof Date)) throw new require_error.ValidationError(path, `expected date, received ${typeOf(value)}`);
87
+ return def.transform ? def.transform(value) : value;
88
+ }
89
+ if (def.name === "function") {
90
+ if (typeof value !== "function") throw new require_error.ValidationError(path, `expected function, received ${typeOf(value)}`);
91
+ const inner = def.fnInput;
92
+ if (inner === void 0 || value.$fn === true) return value;
93
+ const innerType = asType(inner);
94
+ return (input, parent) => value(validate(innerType, input, `${path}()`), parent);
95
+ }
96
+ if (def.name === "array") {
97
+ if (!Array.isArray(value)) throw new require_error.ValidationError(path, `expected array, received ${typeOf(value)}`);
98
+ applyRules(def, value, path);
99
+ if (def.shape === void 0) return def.transform ? def.transform(value) : value;
100
+ const elementType = asType(def.shape);
101
+ const items = [];
102
+ const problems = [];
103
+ for (let index = 0; index < value.length; index++) try {
104
+ items.push(validate(elementType, value[index], `${path}[${index}]`));
105
+ } catch (thrown) {
106
+ if (!(thrown instanceof require_error.ValidationError)) throw thrown;
107
+ problems.push(...thrown.issues);
108
+ }
109
+ const firstProblem = problems[0];
110
+ if (firstProblem) throw new require_error.ValidationError(firstProblem.path, firstProblem.message, problems);
111
+ return def.transform ? def.transform(items) : items;
112
+ }
113
+ if (def.name === "object") {
114
+ if (typeOf(value) !== "object") throw new require_error.ValidationError(path, `expected object, received ${typeOf(value)}`);
115
+ if (def.shape === void 0) return def.transform ? def.transform(value) : value;
116
+ const parsed = {};
117
+ const issues = [];
118
+ for (const [field, child] of Object.entries(def.shape)) try {
119
+ const parsedField = validate(asType(child), value[field], `${path}.${field}`);
120
+ if (parsedField !== void 0) parsed[field] = parsedField;
121
+ } catch (thrown) {
122
+ if (!(thrown instanceof require_error.ValidationError)) throw thrown;
123
+ issues.push(...thrown.issues);
124
+ }
125
+ const firstIssue = issues[0];
126
+ if (firstIssue) throw new require_error.ValidationError(firstIssue.path, firstIssue.message, issues);
127
+ return def.transform ? def.transform(parsed) : parsed;
128
+ }
129
+ if (typeOf(value) !== def.name) throw new require_error.ValidationError(path, `expected ${def.name}, received ${typeOf(value)}`);
130
+ applyRules(def, value, path);
131
+ return def.transform ? def.transform(value) : value;
132
+ };
133
+ /** Builds the runtime object; the declared return type is the contract. */
134
+ const build = (name, options, extra) => ({
135
+ name,
136
+ ...extra,
137
+ ...options
138
+ });
139
+ const vTypes = {
140
+ /** An `enum` narrows both sides to the literal union: `v.string({
141
+ * enum: ["a", "b"] })` types as `"a" | "b"`, not `string`. */
142
+ string: (options) => build("string", options),
143
+ number: (options) => build("number", options),
144
+ boolean: (options) => build("boolean", options),
145
+ /** A Date INSTANCE - checked with `instanceof`, never parsed. */
146
+ date: (options) => build("date", options),
147
+ /** Passthrough - validated as-is, never coerced or stripped. */
148
+ any: (options) => build("any", options),
149
+ /** With a SHAPE every field validates; with NO shape (`v.object()`)
150
+ * any object passes, as-is. */
151
+ object: (shape, options) => build("object", options, shape === void 0 ? {} : { shape }),
152
+ /** With an ELEMENT every item validates - all failures report
153
+ * together, like object fields; with NO element (`v.array()`) any
154
+ * array passes, as-is. `min`/`max`/`length` count items. */
155
+ array: (element, options) => build("array", options, element === void 0 ? {} : { shape: element })
156
+ };
157
+ //#endregion
158
+ exports.asType = asType;
159
+ exports.isFnSchema = isFnSchema;
160
+ exports.isType = isType;
161
+ exports.isVar = isVar;
162
+ exports.outputContract = outputContract;
163
+ exports.typeOf = typeOf;
164
+ exports.vTypes = vTypes;
165
+ exports.validate = validate;
166
+
167
+ //# sourceMappingURL=schema.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.cjs","names":["ValidationError"],"sources":["../src/schema.ts"],"sourcesContent":["import { type Issue, ValidationError } from \"./error\";\nimport type { LiteralString, Prettify } from \"./types\";\n\nexport type Rules = {\n\t/** Strings: length. Numbers: value. */\n\tmin?: number;\n\t/** Strings: length. Numbers: value. */\n\tmax?: number;\n\t/** Strings only: exact length. */\n\tlength?: number;\n\tregex?: RegExp;\n\temail?: boolean;\n\turl?: boolean;\n\tstartsWith?: string;\n\tendsWith?: string;\n\t/** Numbers only. */\n\tint?: boolean;\n\t/** Allowed values. */\n\tenum?: readonly unknown[];\n\t/** Escape hatch - return true, or a message to fail with. */\n\tcheck?: (value: any) => boolean | string;\n};\n\nexport interface TypeDefination<T, O, D = never> extends Rules {\n\tname: LiteralString;\n\ttype?: T;\n\toutput?: O;\n\tshape?: unknown;\n\t/** `function` types only: the declared input of the expected fn -\n\t * plain closures get it validated at their door on every call. */\n\tfnInput?: unknown;\n\t/** Used when the incoming value is `undefined`. */\n\tdefault?: D;\n\t/** When true, `undefined` passes straight through unvalidated. */\n\toptional?: boolean;\n\ttransform?: (value: any) => O;\n}\n\nexport type TypeOptions<T, O> = {\n\ttransform?: (value: T) => O;\n};\n\ntype WithDefault<D> = { default?: D };\n\ntype WithOptional<Opt> = { optional?: Opt };\n\n/**\n * `optional` widens the output; `default` keeps it narrow because a value\n * is always produced. Declaring both means optional to send, never absent.\n */\ntype OutOf<O, D, Opt> = [Opt] extends [true]\n\t? [D] extends [never]\n\t\t? O | undefined\n\t\t: O\n\t: O;\n\n/** Either marker makes the key omittable in `InferArgs`. */\ntype DefOf<D, Opt> = [Opt] extends [true]\n\t? [D] extends [never]\n\t\t? undefined\n\t\t: D\n\t: D;\n\ntype StringOptions<E extends string, O> = TypeOptions<E, O> &\n\tPick<\n\t\tRules,\n\t\t| \"min\"\n\t\t| \"max\"\n\t\t| \"length\"\n\t\t| \"regex\"\n\t\t| \"email\"\n\t\t| \"url\"\n\t\t| \"startsWith\"\n\t\t| \"endsWith\"\n\t\t| \"check\"\n\t> & { enum?: readonly E[] };\n\ntype ArrayOptions<E, O> = TypeOptions<FieldOut<E>[], O> &\n\tPick<Rules, \"min\" | \"max\" | \"length\" | \"check\">;\n\ntype NumberOptions<O> = TypeOptions<number, O> &\n\tPick<Rules, \"min\" | \"max\" | \"int\" | \"check\"> & {\n\t\tenum?: readonly number[];\n\t};\n\nexport type InferType<T> =\n\tT extends TypeDefination<infer T2, any, any> ? T2 : never;\n\nexport type InferOutput<T> =\n\tT extends TypeDefination<any, infer O, any> ? O : never;\n\nexport type DefineInput<I> = Prettify<{\n\t[K in keyof I]: FieldIn<I[K]>;\n}>;\n\n/** Keys whose field is OPTIONAL with no default: absent from the output\n * too, so they mark `?`. A defaulted field always produces a value and\n * stays required. */\ntype OutOptional<O> = {\n\t[K in keyof O]: [DefaultOf<O[K]>] extends [never]\n\t\t? never\n\t\t: [DefaultOf<O[K]>] extends [undefined]\n\t\t\t? K\n\t\t\t: never;\n}[keyof O];\n\nexport type DefineOutput<O> = Prettify<\n\t{ [K in keyof O as K extends OutOptional<O> ? never : K]: FieldOut<O[K]> } & {\n\t\t[K in keyof O as K extends OutOptional<O> ? K : never]?: FieldOut<O[K]>;\n\t}\n>;\n\n/**\n * A handler-less `v.fn({ input, output })` used as a schema describes\n * \"a fn from `input` to `output`\" - the VALUE is the fn itself. Two\n * views of the same signature:\n *\n * `SchemaFnIn` is the PROVIDER's side - what a caller must hand over.\n * Like any handler, their fn receives the PARSED input (validation runs\n * at its door) and returns the declared output, sync or async.\n *\n * `SchemaFnOut` is the CONSUMER's side (`c.input.x`) - the handler calls\n * it with RAW args, exactly like calling the fn it stands in for.\n *\n * No declared input means the signature is UNSPECIFIED, not zero-arg -\n * any fn fits (`create: v.fn`), so the args stay open.\n */\ntype SchemaFnIn<FI, FO> = (\n\t...args: unknown extends FI ? any[] : [input: InferInput<FI>]\n) => unknown extends FO\n\t? any\n\t: InferInput<OutputSchemaOf<FO>> | Promise<InferInput<OutputSchemaOf<FO>>>;\n\ntype SchemaFnOut<FI, FO> = (\n\t...args: unknown extends FI ? any[] : [input: InferArgs<FI>]\n) => unknown extends FO\n\t? any\n\t: InferInput<OutputSchemaOf<FO>> | Promise<InferInput<OutputSchemaOf<FO>>>;\n\n/**\n * A fn schema whose input IS a var carries that var's name as an optional\n * phantom (`$fnVar`, tuple-wrapped so a plain fn can never false-match).\n * Scope resolution reads it to WIDEN the fn's args with everything the\n * scope mounts on that var - see `WidenSchemaFns`. Optional, so any plain\n * closure still satisfies the type.\n */\nexport type FnVarBrand<FI> = FI extends {\n\t$var: true;\n\tname: infer N extends string;\n}\n\t? { readonly $fnVar?: [N] }\n\t: unknown;\n\n/**\n * A declared `output` comes in two forms: a bare schema (the signature\n * AND the exit check), or the wrapper `{ def?, validation? }` splitting\n * what the fn PROMISES from what gets CHECKED - `{ def }` documents\n * without paying runtime validation, `{ def, validation }` checks with a\n * different (usually looser) schema than it documents. The wrapper is\n * recognized by its keys, so an output that IS an object with only\n * `def`/`validation` fields must be written `v.object({...})`.\n *\n * `OutputSchemaOf` is the type-level unwrap - the schema the fn's return\n * type (and its rendered signature) comes from.\n */\nexport type OutputSchemaOf<O> =\n\tExclude<keyof O, \"def\" | \"validation\"> extends never\n\t\t? O extends { def: infer D }\n\t\t\t? D\n\t\t\t: O extends { validation: infer Vl }\n\t\t\t\t? Vl\n\t\t\t\t: O\n\t\t: O;\n\n/** The runtime unwrap: `def` is the documented schema (falls back to\n * `validation`), `validation` is what the exit check runs - undefined\n * means no check. A bare schema is both. */\nexport const outputContract = (\n\toutput: unknown,\n): { def?: unknown; validation?: unknown } => {\n\tif (output === undefined) return {};\n\tif (\n\t\toutput !== null &&\n\t\ttypeof output === \"object\" &&\n\t\t!Array.isArray(output) &&\n\t\t!isType(output) &&\n\t\t!isVar(output) &&\n\t\t!isFnSchema(output)\n\t) {\n\t\tconst keys = Object.keys(output);\n\t\tif (\n\t\t\tkeys.length > 0 &&\n\t\t\tkeys.every((k) => k === \"def\" || k === \"validation\")\n\t\t) {\n\t\t\tconst { def, validation } = output as {\n\t\t\t\tdef?: unknown;\n\t\t\t\tvalidation?: unknown;\n\t\t\t};\n\t\t\treturn { def: def ?? validation, validation };\n\t\t}\n\t}\n\treturn { def: output, validation: output };\n};\n\n/**\n * One input field, in four flavours:\n * - a `v.var()`, whose shape comes from the var's own `schema`\n * - a handler-less `v.fn(...)` builder, which types the field as a FN\n * - a type from `v.string()` / `v.object()` / ...\n * - a bare nested record, which recurses\n *\n * The record case has to come last: a TypeDefination is itself a record,\n * and so is a builder.\n */\ntype FieldOut<F> = F extends { $var: true; schema?: infer S }\n\t? InferInput<NonNullable<S>>\n\t: F extends { $fnSchema: { input?: infer FI; output?: infer FO } }\n\t\t? SchemaFnOut<FI, FO> & FnVarBrand<FI>\n\t\t: F extends TypeDefination<any, infer O, any>\n\t\t\t? O\n\t\t\t: F extends Record<string, unknown>\n\t\t\t\t? Prettify<{ [K in keyof F]: FieldOut<F[K]> }>\n\t\t\t\t: never;\n\ntype FieldIn<F> = F extends { $var: true; schema?: infer S }\n\t? InferArgs<NonNullable<S>>\n\t: F extends { $fnSchema: { input?: infer FI; output?: infer FO } }\n\t\t? SchemaFnIn<FI, FO> & FnVarBrand<FI>\n\t\t: F extends TypeDefination<infer T, any, any>\n\t\t\t? T\n\t\t\t: F extends Record<string, unknown>\n\t\t\t\t? ArgsShape<F>\n\t\t\t\t: never;\n\n/**\n * A field's declared default, looked through a var to its schema. Only a\n * TYPE's default counts - a var's own default is its initial value, not a\n * licence to omit the input. The `$fnSchema` guard mirrors `asType`'s\n * ordering: a bare `v.fn` is CALLABLE, and any callable duck-matches\n * TypeDefination (`.name` comes with every function), which would read a\n * phantom default off it and wrongly mark the field optional.\n */\ntype DefaultOf<F> = F extends { $var: true; schema?: infer S }\n\t? NonNullable<S> extends TypeDefination<any, any, infer D>\n\t\t? D\n\t\t: never\n\t: F extends { $fnSchema: unknown }\n\t\t? never\n\t\t: F extends TypeDefination<any, any, infer D>\n\t\t\t? D\n\t\t\t: never;\n\ntype Defaulted<I> = {\n\t[K in keyof I]: [DefaultOf<I[K]>] extends [never] ? never : K;\n}[keyof I];\n\n/** Defaulted keys are optional to send, but always present in the handler. */\ntype ArgsShape<I> = Prettify<\n\t{ [K in keyof I as K extends Defaulted<I> ? never : K]: FieldIn<I[K]> } & {\n\t\t[K in keyof I as K extends Defaulted<I> ? K : never]?: FieldIn<I[K]>;\n\t}\n>;\n\n/**\n * Post-transform shape - what a handler sees. The `$var` branch must come\n * first: a var's `name` property duck-matches TypeDefination, and falling\n * into that branch reads the var's VALUE type instead of its schema. A\n * TUPLE input maps position by position - the fn takes that many args.\n */\nexport type InferInput<I> = I extends { $var: true; schema?: infer S }\n\t? InferInput<NonNullable<S>>\n\t: I extends { $fnSchema: { input?: infer FI; output?: infer FO } }\n\t\t? SchemaFnOut<FI, FO> & FnVarBrand<FI>\n\t\t: I extends readonly unknown[]\n\t\t\t? { -readonly [K in keyof I]: InferInput<I[K]> }\n\t\t\t: I extends TypeDefination<any, infer O, any>\n\t\t\t\t? O\n\t\t\t\t: Prettify<{ [K in keyof I]: FieldOut<I[K]> }>;\n\n/** Pre-transform shape - what a caller sends. Same branch order. */\nexport type InferArgs<I> = I extends { $var: true; schema?: infer S }\n\t? InferArgs<NonNullable<S>>\n\t: I extends { $fnSchema: { input?: infer FI; output?: infer FO } }\n\t\t? SchemaFnIn<FI, FO> & FnVarBrand<FI>\n\t\t: I extends readonly unknown[]\n\t\t\t? { -readonly [K in keyof I]: InferArgs<I[K]> }\n\t\t\t: I extends TypeDefination<infer T, any, any>\n\t\t\t\t? T\n\t\t\t\t: ArgsShape<I>;\n\nexport const isType = (value: any): value is TypeDefination<any, any> =>\n\ttypeof value?.name === \"string\";\n\n/** A handler-less `v.fn(...)` builder doubles as a schema: the value it\n * describes is a FN with the declared signature. The builder FN itself is\n * branded too, so bare `v.fn` reads as \"any function\". */\nexport const isFnSchema = (\n\tvalue: any,\n): value is { $fnSchema: { input?: unknown; output?: unknown } } =>\n\ttypeof value?.$fnSchema === \"object\" && value.$fnSchema !== null;\n\nexport const asType = (value: any): TypeDefination<any, any> =>\n\t// A var's own `name` (\"user\") would duck-match isType, so unwrap first -\n\t// and a builder is a record, so it must be caught before the fallback.\n\tisVar(value)\n\t\t? asType(value.schema ?? {})\n\t\t: isFnSchema(value)\n\t\t\t? { name: \"function\", fnInput: value.$fnSchema.input }\n\t\t\t: isType(value)\n\t\t\t\t? value\n\t\t\t\t: { name: \"object\", shape: value };\n\nexport const typeOf = (value: unknown) =>\n\tvalue === null\n\t\t? \"null\"\n\t\t: Array.isArray(value)\n\t\t\t? \"array\"\n\t\t\t: Number.isNaN(value)\n\t\t\t\t? \"NaN\"\n\t\t\t\t: typeof value;\n\nexport const isVar = (value: any): boolean => value?.$var === true;\n\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nconst fail = (path: string, message: string): never => {\n\tthrow new ValidationError(path, message);\n};\n\n/** Constraint checks, run after the value's type is known to be right. */\nconst applyRules = (def: Rules, value: any, path: string) => {\n\tif (def.enum && !def.enum.includes(value)) {\n\t\tfail(path, `expected one of ${def.enum.join(\", \")}, received ${value}`);\n\t}\n\tif (typeof value === \"string\") {\n\t\tif (def.length !== undefined && value.length !== def.length) {\n\t\t\tfail(path, `expected length ${def.length}, received ${value.length}`);\n\t\t}\n\t\tif (def.min !== undefined && value.length < def.min) {\n\t\t\tfail(\n\t\t\t\tpath,\n\t\t\t\t`expected at least ${def.min} characters, received ${value.length}`,\n\t\t\t);\n\t\t}\n\t\tif (def.max !== undefined && value.length > def.max) {\n\t\t\tfail(\n\t\t\t\tpath,\n\t\t\t\t`expected at most ${def.max} characters, received ${value.length}`,\n\t\t\t);\n\t\t}\n\t\tif (def.regex && !def.regex.test(value)) {\n\t\t\tfail(path, `does not match ${def.regex}`);\n\t\t}\n\t\tif (def.email && !EMAIL.test(value))\n\t\t\tfail(path, \"expected an email address\");\n\t\tif (def.url) {\n\t\t\ttry {\n\t\t\t\tnew URL(value);\n\t\t\t} catch {\n\t\t\t\tfail(path, \"expected a URL\");\n\t\t\t}\n\t\t}\n\t\tif (def.startsWith !== undefined && !value.startsWith(def.startsWith)) {\n\t\t\tfail(path, `expected to start with \"${def.startsWith}\"`);\n\t\t}\n\t\tif (def.endsWith !== undefined && !value.endsWith(def.endsWith)) {\n\t\t\tfail(path, `expected to end with \"${def.endsWith}\"`);\n\t\t}\n\t}\n\tif (Array.isArray(value)) {\n\t\tif (def.length !== undefined && value.length !== def.length) {\n\t\t\tfail(path, `expected length ${def.length}, received ${value.length}`);\n\t\t}\n\t\tif (def.min !== undefined && value.length < def.min) {\n\t\t\tfail(\n\t\t\t\tpath,\n\t\t\t\t`expected at least ${def.min} items, received ${value.length}`,\n\t\t\t);\n\t\t}\n\t\tif (def.max !== undefined && value.length > def.max) {\n\t\t\tfail(path, `expected at most ${def.max} items, received ${value.length}`);\n\t\t}\n\t}\n\tif (typeof value === \"number\") {\n\t\tif (def.int && !Number.isInteger(value)) {\n\t\t\tfail(path, `expected an integer, received ${value}`);\n\t\t}\n\t\tif (def.min !== undefined && value < def.min) {\n\t\t\tfail(path, `expected >= ${def.min}, received ${value}`);\n\t\t}\n\t\tif (def.max !== undefined && value > def.max) {\n\t\t\tfail(path, `expected <= ${def.max}, received ${value}`);\n\t\t}\n\t}\n\tif (def.check) {\n\t\tconst result = def.check(value);\n\t\tif (result !== true) {\n\t\t\tfail(path, typeof result === \"string\" ? result : \"failed check\");\n\t\t}\n\t}\n};\n\nexport const validate = (\n\tdef: TypeDefination<any, any, any>,\n\tvalue: unknown,\n\tpath: string,\n): any => {\n\t// `undefined` falls back to the declared default before anything else,\n\t// then to `optional`, which passes it through untouched.\n\tif (value === undefined) {\n\t\tif (def.default !== undefined) value = def.default;\n\t\telse if (def.optional) return undefined;\n\t}\n\t// A var used as an input field validates against its own schema. An\n\t// absent value is left alone so the var keeps its default.\n\tif (isVar(def)) {\n\t\tif (value === undefined) return undefined;\n\t\tconst schema = (def as any).schema;\n\t\treturn schema === undefined ? value : validate(schema, value, path);\n\t}\n\tif (def.name === \"any\") {\n\t\treturn def.transform ? def.transform(value) : value;\n\t}\n\tif (def.name === \"date\") {\n\t\tif (!(value instanceof Date)) {\n\t\t\tthrow new ValidationError(\n\t\t\t\tpath,\n\t\t\t\t`expected date, received ${typeOf(value)}`,\n\t\t\t);\n\t\t}\n\t\treturn def.transform ? def.transform(value) : value;\n\t}\n\tif (def.name === \"function\") {\n\t\tif (typeof value !== \"function\") {\n\t\t\tthrow new ValidationError(\n\t\t\t\tpath,\n\t\t\t\t`expected function, received ${typeOf(value)}`,\n\t\t\t);\n\t\t}\n\t\t// A branded fn (`$fn`) validates its own declared input at its own\n\t\t// door; a plain closure gets THIS schema's input validated for it.\n\t\tconst inner = def.fnInput;\n\t\tif (inner === undefined || (value as { $fn?: boolean }).$fn === true) {\n\t\t\treturn value;\n\t\t}\n\t\tconst innerType = asType(inner);\n\t\treturn (input?: unknown, parent?: unknown) =>\n\t\t\t(value as (i: unknown, p: unknown) => unknown)(\n\t\t\t\tvalidate(innerType, input, `${path}()`),\n\t\t\t\tparent,\n\t\t\t);\n\t}\n\tif (def.name === \"array\") {\n\t\tif (!Array.isArray(value)) {\n\t\t\tthrow new ValidationError(\n\t\t\t\tpath,\n\t\t\t\t`expected array, received ${typeOf(value)}`,\n\t\t\t);\n\t\t}\n\t\tapplyRules(def, value, path);\n\t\t// No declared element (`v.array()`): ANY array - passed through\n\t\t// as-is, elements untouched.\n\t\tif (def.shape === undefined) {\n\t\t\treturn def.transform ? def.transform(value) : value;\n\t\t}\n\t\t// Every element validates - ALL failures report together, not\n\t\t// just the first, mirroring object fields.\n\t\tconst elementType = asType(def.shape);\n\t\tconst items: unknown[] = [];\n\t\tconst problems: Issue[] = [];\n\t\tfor (let index = 0; index < value.length; index++) {\n\t\t\ttry {\n\t\t\t\titems.push(validate(elementType, value[index], `${path}[${index}]`));\n\t\t\t} catch (thrown) {\n\t\t\t\tif (!(thrown instanceof ValidationError)) throw thrown;\n\t\t\t\tproblems.push(...thrown.issues);\n\t\t\t}\n\t\t}\n\t\tconst firstProblem = problems[0];\n\t\tif (firstProblem) {\n\t\t\tthrow new ValidationError(\n\t\t\t\tfirstProblem.path,\n\t\t\t\tfirstProblem.message,\n\t\t\t\tproblems,\n\t\t\t);\n\t\t}\n\t\treturn def.transform ? def.transform(items) : items;\n\t}\n\tif (def.name === \"object\") {\n\t\tif (typeOf(value) !== \"object\") {\n\t\t\tthrow new ValidationError(\n\t\t\t\tpath,\n\t\t\t\t`expected object, received ${typeOf(value)}`,\n\t\t\t);\n\t\t}\n\t\t// No declared shape (`v.object()`): ANY object - passed through\n\t\t// as-is, nothing stripped.\n\t\tif (def.shape === undefined) {\n\t\t\treturn def.transform ? def.transform(value) : value;\n\t\t}\n\t\t// Every field validates - ALL failures report together, not just\n\t\t// the first. Three bad fields is one error with three issues.\n\t\tconst parsed: Record<string, unknown> = {};\n\t\tconst issues: Issue[] = [];\n\t\tfor (const [field, child] of Object.entries(\n\t\t\tdef.shape as Record<string, unknown>,\n\t\t)) {\n\t\t\ttry {\n\t\t\t\tconst parsedField = validate(\n\t\t\t\t\tasType(child),\n\t\t\t\t\t(value as Record<string, unknown>)[field],\n\t\t\t\t\t`${path}.${field}`,\n\t\t\t\t);\n\t\t\t\t// An absent optional field stays ABSENT - materializing the key\n\t\t\t\t// as `undefined` would clobber values it gets spread over.\n\t\t\t\tif (parsedField !== undefined) parsed[field] = parsedField;\n\t\t\t} catch (thrown) {\n\t\t\t\tif (!(thrown instanceof ValidationError)) throw thrown;\n\t\t\t\tissues.push(...thrown.issues);\n\t\t\t}\n\t\t}\n\t\tconst firstIssue = issues[0];\n\t\tif (firstIssue) {\n\t\t\tthrow new ValidationError(firstIssue.path, firstIssue.message, issues);\n\t\t}\n\t\treturn def.transform ? def.transform(parsed) : parsed;\n\t}\n\tif (typeOf(value) !== def.name) {\n\t\tthrow new ValidationError(\n\t\t\tpath,\n\t\t\t`expected ${def.name}, received ${typeOf(value)}`,\n\t\t);\n\t}\n\tapplyRules(def, value, path);\n\treturn def.transform ? def.transform(value) : value;\n};\n\n/** Builds the runtime object; the declared return type is the contract. */\nconst build = (name: string, options: any, extra?: any): any => ({\n\tname,\n\t...extra,\n\t...options,\n});\n\nexport const vTypes = {\n\t/** An `enum` narrows both sides to the literal union: `v.string({\n\t * enum: [\"a\", \"b\"] })` types as `\"a\" | \"b\"`, not `string`. */\n\tstring: <\n\t\tconst E extends string = string,\n\t\tO = E,\n\t\tD = never,\n\t\tOpt extends boolean = false,\n\t>(\n\t\toptions?: StringOptions<E, O> & WithDefault<D> & WithOptional<Opt>,\n\t): TypeDefination<E, OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"string\", options),\n\tnumber: <O = number, D = never, Opt extends boolean = false>(\n\t\toptions?: NumberOptions<O> & WithDefault<D> & WithOptional<Opt>,\n\t): TypeDefination<number, OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"number\", options),\n\tboolean: <O = boolean, D = never, Opt extends boolean = false>(\n\t\toptions?: TypeOptions<boolean, O> & WithDefault<D> & WithOptional<Opt>,\n\t): TypeDefination<boolean, OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"boolean\", options),\n\t/** A Date INSTANCE - checked with `instanceof`, never parsed. */\n\tdate: <O = Date, D = never, Opt extends boolean = false>(\n\t\toptions?: TypeOptions<Date, O> & WithDefault<D> & WithOptional<Opt>,\n\t): TypeDefination<Date, OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"date\", options),\n\t/** Passthrough - validated as-is, never coerced or stripped. */\n\tany: <T = unknown, D = never, Opt extends boolean = false>(\n\t\toptions?: TypeOptions<T, T> & WithDefault<D> & WithOptional<Opt>,\n\t): TypeDefination<T, OutOf<T, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"any\", options),\n\t/** With a SHAPE every field validates; with NO shape (`v.object()`)\n\t * any object passes, as-is. */\n\tobject: <\n\t\tS = undefined,\n\t\tO = DefineOutput<S>,\n\t\tD = never,\n\t\tOpt extends boolean = false,\n\t>(\n\t\tshape?: S,\n\t\toptions?: TypeOptions<DefineOutput<S>, O> &\n\t\t\tWithDefault<D> &\n\t\t\tWithOptional<Opt>,\n\t\t// Args use ArgsShape, not DefineInput, so a defaulted field inside\n\t\t// an object is optional to send there too.\n\t): [S] extends [undefined]\n\t\t? TypeDefination<Record<string, any>, Record<string, any>>\n\t\t: TypeDefination<ArgsShape<S>, OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"object\", options, shape === undefined ? {} : { shape }),\n\t/** With an ELEMENT every item validates - all failures report\n\t * together, like object fields; with NO element (`v.array()`) any\n\t * array passes, as-is. `min`/`max`/`length` count items. */\n\tarray: <\n\t\tE = undefined,\n\t\tO = FieldOut<E>[],\n\t\tD = never,\n\t\tOpt extends boolean = false,\n\t>(\n\t\telement?: E,\n\t\toptions?: ArrayOptions<E, O> & WithDefault<D> & WithOptional<Opt>,\n\t): [E] extends [undefined]\n\t\t? TypeDefination<any[], OutOf<any[], D, Opt>, DefOf<D, Opt>>\n\t\t: TypeDefination<FieldIn<E>[], OutOf<O, D, Opt>, DefOf<D, Opt>> =>\n\t\tbuild(\"array\", options, element === undefined ? {} : { shape: element }),\n} satisfies Record<string, (...args: any[]) => TypeDefination<any, any>>;\n"],"mappings":"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"}