mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
Project zod 4 and @hono/zod-validator values at the declaration boundary
The declaration-typed boundary already reaches zod 4 schemas and hono's
c.req.valid(): zod 4's z.infer and hono's validator Input generics resolve
to plain object types in the declaration world. Three gaps remained:
- Boolean literal types printed as `false` (the TS7 facade leaves
intrinsicName unset), so `{ ok: true } | { ok: false }` lost its true
arm and `boolean | undefined` became `undefined | false`. The printer
reads the literal's value.
- `r.data` after `const r = S.safeParse(x); if (r.success)` never
crossed: zod 4's result union is not data (its error arm is a class),
and reads on projectable receivers were skipped on the assumption that
something else types the receiver. Such reads now cross when the
receiver is a package call whose type does not project, or a const
bound to one.
- Reads through bindings annotated with a projected type no longer get a
redundant cast, and aliases are named only for casts that survive.
New npm cases zod4-boundary and hono-zod-validator run real zod 4.6.7,
hono 4.13.13 and @hono/zod-validator 0.9.1 (vendored file closures) under
Node and natively; decl-boundary.test.ts checks that c.req.valid() is a
checked cast with a path TypeError.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5bb9fc556d
commit
dddcbed335
@@ -185,8 +185,24 @@ class TypePrinter {
|
||||
readonly declarations: string[] = [];
|
||||
private readonly inProgress = new Map<number, { name: string | null }>();
|
||||
|
||||
/** While set, printing registers no recursive alias (projectable()). */
|
||||
private dry = false;
|
||||
|
||||
constructor(private readonly checker: ts.TypeChecker) {}
|
||||
|
||||
/** Whether a type projects, without naming it in the generated file. */
|
||||
projectable(type: ts.Type): boolean {
|
||||
if (type.flags & ANYISH) return false;
|
||||
const was = this.dry;
|
||||
this.dry = true;
|
||||
try {
|
||||
const text = this.print(type, 0);
|
||||
return text !== null && text !== "unknown";
|
||||
} finally {
|
||||
this.dry = was;
|
||||
}
|
||||
}
|
||||
|
||||
/** The alias naming a projectable type, or null. Top-level any/unknown
|
||||
* never projects. */
|
||||
project(type: ts.Type): string | null {
|
||||
@@ -212,7 +228,12 @@ class TypePrinter {
|
||||
if (f & ts.TypeFlags.Null) return "null";
|
||||
if (f & ts.TypeFlags.Undefined) return "undefined";
|
||||
if (f & ts.TypeFlags.EnumLiteral || f & ts.TypeFlags.Enum) return null;
|
||||
if (f & ts.TypeFlags.BooleanLiteral) return type.intrinsicName === "true" ? "true" : "false";
|
||||
// A boolean literal type carries its value (`intrinsicName` is not
|
||||
// set for it by every checker facade).
|
||||
if (f & ts.TypeFlags.BooleanLiteral)
|
||||
return (type as ts.BooleanLiteralType).value === true || type.intrinsicName === "true"
|
||||
? "true"
|
||||
: "false";
|
||||
if (f & ts.TypeFlags.StringLiteral) return JSON.stringify(String(type.value));
|
||||
if (f & ts.TypeFlags.NumberLiteral) {
|
||||
const v = Number(type.value);
|
||||
@@ -341,7 +362,7 @@ class TypePrinter {
|
||||
if (props.length > 0 && readonlyCount === props.length) return null;
|
||||
const text = `{ ${members.join("; ")} }`;
|
||||
if (frame.name !== null) {
|
||||
this.declarations.push(`type ${frame.name} = ${text};`);
|
||||
if (!this.dry) this.declarations.push(`type ${frame.name} = ${text};`);
|
||||
return frame.name;
|
||||
}
|
||||
return text;
|
||||
@@ -517,9 +538,17 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
const declSf = input.declProgram.getSourceFile(file);
|
||||
if (jsSf === undefined || declSf === undefined || jsSf.text !== declSf.text) continue;
|
||||
const fileEdits: Edit[] = [];
|
||||
/** Candidate expressions (by js node) with their alias. */
|
||||
const exprCandidates = new Map<ts.Node, string>();
|
||||
/** Candidate expressions (by js node) with their declared type, named
|
||||
* only for the casts that survive suppression. */
|
||||
const exprCandidates = new Map<ts.Node, ts.Type>();
|
||||
const exprOrder: ts.Node[] = [];
|
||||
/** Reads whose projectable receiver the JavaScript world types `any`:
|
||||
* kept only when nothing types the receiver. */
|
||||
const deferred = new Set<ts.Node>();
|
||||
/** Package calls whose declared type does not project. */
|
||||
const unprojected = new Set<ts.Node>();
|
||||
/** The declaration-world twin of every walked node. */
|
||||
const twins = new Map<ts.Node, ts.Node>();
|
||||
|
||||
const considerType = (jsNode: ts.Node, declNode: ts.Node): boolean => {
|
||||
if (
|
||||
@@ -603,8 +632,18 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
} else if (ts.isPropertyAccessExpression(d) || ts.isElementAccessExpression(d)) {
|
||||
const recvDecl = typeAt(declChecker, d.expression);
|
||||
const recvJs = typeAt(jsChecker, (jsNode as ts.PropertyAccessExpression).expression);
|
||||
const recvProjectable = recvDecl !== null && printer.project(recvDecl) !== null;
|
||||
const recvProjectable = recvDecl !== null && printer.projectable(recvDecl);
|
||||
produced = !recvProjectable || (recvJs !== null && !isAnyish(recvJs));
|
||||
// A projectable receiver the JavaScript world types `any` is
|
||||
// usually typed by another candidate. One that is a package value
|
||||
// nothing projects stays `any`, such as a safeParse result narrowed
|
||||
// to its success arm (the whole result is not data: its error arm
|
||||
// is a class): the read crosses here instead, if the suppression
|
||||
// below confirms the receiver stays untyped.
|
||||
if (!produced) {
|
||||
produced = true;
|
||||
deferred.add(jsNode);
|
||||
}
|
||||
} else if (ts.isAwaitExpression(d)) {
|
||||
const inner = unwrapTransparent(d.expression);
|
||||
produced =
|
||||
@@ -633,6 +672,12 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
declaredInPackage(resolveAlias(raw));
|
||||
}
|
||||
if (!produced) return;
|
||||
if (isCall && !deferred.has(jsNode)) {
|
||||
// Recorded before the contextual-type test below: a package value
|
||||
// whose type does not project stays `any` wherever it flows.
|
||||
const t = typeAt(declChecker, d);
|
||||
if (t === null || !printer.projectable(t)) unprojected.add(jsNode);
|
||||
}
|
||||
// A consumer that takes anything needs no conversion.
|
||||
try {
|
||||
const ctx = declChecker.getContextualType(d);
|
||||
@@ -641,10 +686,8 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
// no contextual type
|
||||
}
|
||||
const declType = typeAt(declChecker, d);
|
||||
if (declType === null) return;
|
||||
const alias = printer.project(declType);
|
||||
if (alias === null) return;
|
||||
exprCandidates.set(jsNode, alias);
|
||||
if (declType === null || !printer.projectable(declType)) return;
|
||||
exprCandidates.set(jsNode, declType);
|
||||
exprOrder.push(jsNode);
|
||||
};
|
||||
|
||||
@@ -703,6 +746,7 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
|
||||
const walk = (jsNode: ts.Node, declNode: ts.Node): void => {
|
||||
if (jsNode.kind !== declNode.kind) return;
|
||||
twins.set(jsNode, declNode);
|
||||
if (ts.isTypeNode(jsNode) || ts.isExpressionWithTypeArguments(jsNode)) {
|
||||
if (considerType(jsNode, declNode)) return;
|
||||
} else {
|
||||
@@ -749,21 +793,67 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
result = willBeTyped(decl.initializer, depth + 1);
|
||||
else if (ts.isParameter(decl) && annotated.has(decl)) result = true;
|
||||
else if (ts.isBindingElement(decl)) result = false;
|
||||
else if (
|
||||
(ts.isVariableDeclaration(decl) || ts.isParameter(decl)) &&
|
||||
decl.type !== undefined
|
||||
)
|
||||
result = annotationWillBeTyped(decl.type);
|
||||
}
|
||||
symbolTyped.set(sym, result);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/** An annotation in this file whose declaration-world type projects:
|
||||
* after the rewrite it names the projected structure (a package type
|
||||
* is replaced by its alias, a user alias of one has its right-hand
|
||||
* side replaced). */
|
||||
const annotationWillBeTyped = (type: ts.TypeNode): boolean => {
|
||||
const twin = twins.get(type);
|
||||
if (twin === undefined) return false;
|
||||
let declType: ts.Type | null;
|
||||
try {
|
||||
declType = declChecker.getTypeFromTypeNode(twin as ts.TypeNode);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return declType !== null && printer.projectable(declType);
|
||||
};
|
||||
const receiverOf = (e: ts.Node): ts.Node | null => {
|
||||
if (ts.isPropertyAccessExpression(e) || ts.isElementAccessExpression(e)) return e.expression;
|
||||
if (ts.isIdentifier(e)) return null;
|
||||
return null;
|
||||
};
|
||||
const kept: ts.Node[] = [];
|
||||
/** A receiver that stays `any` after the rewrite: a package call whose
|
||||
* type does not project, or a user const bound to one. */
|
||||
const staysUntyped = (e: ts.Node): boolean => {
|
||||
const u = unwrapTransparent(e as ts.Expression);
|
||||
if (unprojected.has(u)) return true;
|
||||
if (!ts.isIdentifier(u)) return false;
|
||||
let sym: ts.Symbol | undefined;
|
||||
try {
|
||||
sym = jsChecker.getSymbolAtLocation(u);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const decls = sym?.declarations ?? [];
|
||||
if (decls.length !== 1) return false;
|
||||
const decl = decls[0]!;
|
||||
return (
|
||||
ts.isVariableDeclaration(decl) &&
|
||||
decl.type === undefined &&
|
||||
decl.initializer !== undefined &&
|
||||
decl.parent !== undefined &&
|
||||
ts.isVariableDeclarationList(decl.parent) &&
|
||||
(decl.parent.flags & ts.NodeFlags.Const) !== 0 &&
|
||||
unprojected.has(unwrapTransparent(decl.initializer))
|
||||
);
|
||||
};
|
||||
for (const e of exprOrder) {
|
||||
const recv = receiverOf(e);
|
||||
if (recv !== null && willBeTyped(recv)) continue;
|
||||
if (deferred.has(e) && (recv === null || !staysUntyped(recv))) continue;
|
||||
// An identifier candidate that is a user binding never gets here
|
||||
// (only package imports are candidates).
|
||||
kept.push(e);
|
||||
@@ -800,7 +890,8 @@ export function planDeclProjection(input: DeclProjectionInput): DeclProjection |
|
||||
)
|
||||
continue;
|
||||
}
|
||||
const alias = exprCandidates.get(e)!;
|
||||
const alias = printer.project(exprCandidates.get(e)!);
|
||||
if (alias === null) continue;
|
||||
const start = ts.tokenStartOfNode(e);
|
||||
const stmt = e.parent;
|
||||
let prefix = "(";
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/fixtures/npm/cases/hono-zod-validator/main.ts"
|
||||
],
|
||||
"diags": [
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'WebSocket'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts",
|
||||
"start": 1398,
|
||||
"end": 1407
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'WebSocket'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts",
|
||||
"start": 1413,
|
||||
"end": 1422
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'WebSocket'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts",
|
||||
"start": 3716,
|
||||
"end": 3725
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'FormData'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts",
|
||||
"start": 4798,
|
||||
"end": 4806
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'FormData'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/request.d.ts",
|
||||
"start": 549,
|
||||
"end": 557
|
||||
}
|
||||
},
|
||||
{
|
||||
"code": "SC0001",
|
||||
"message": "Cannot find name 'FormData'.",
|
||||
"loc": {
|
||||
"file": "<repo>/tests/fixtures/npm/node_modules/hono/dist/types/request.d.ts",
|
||||
"start": 5572,
|
||||
"end": 5580
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/fixtures/npm/cases/zod4-boundary/main.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Native-only (decl-boundary.test.ts): `c.req.valid()` is a checked
|
||||
// boundary. z.custom checks nothing, so a body its declared type
|
||||
// misdescribes fails the cast with a path TypeError, which hono's error
|
||||
// handler reports; Node does not check. A union discriminated by boolean
|
||||
// literals keeps both arms.
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { Hono } from "hono";
|
||||
import { z } from "zod";
|
||||
|
||||
const Liar = z.custom<{ n: number }>();
|
||||
const Outcome = z.discriminatedUnion("ok", [
|
||||
z.object({ ok: z.literal(true), value: z.number() }),
|
||||
z.object({ ok: z.literal(false), reason: z.string() }),
|
||||
]);
|
||||
|
||||
const app = new Hono();
|
||||
app.onError((err, c) => c.text(`${err instanceof TypeError} ${err.message}`, 500));
|
||||
app.post("/liar", zValidator("json", Liar), (c) => c.text(String(c.req.valid("json").n + 1)));
|
||||
app.post("/outcome", zValidator("json", Outcome), (c) => {
|
||||
const outcome = c.req.valid("json");
|
||||
return c.text(outcome.ok ? `value ${outcome.value + 1}` : `reason ${outcome.reason}`);
|
||||
});
|
||||
|
||||
const requests: [string, unknown][] = [
|
||||
["/liar", { n: 1 }],
|
||||
["/liar", { n: "x" }],
|
||||
["/outcome", { ok: true, value: 41 }],
|
||||
["/outcome", { ok: false, reason: "late" }],
|
||||
];
|
||||
|
||||
async function main(): Promise<void> {
|
||||
for (const [path, body] of requests) {
|
||||
const res = await app.request(path, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(body),
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
console.log(path, res.status, await res.text());
|
||||
}
|
||||
}
|
||||
|
||||
void main();
|
||||
@@ -0,0 +1,96 @@
|
||||
// A Hono app validated by @hono/zod-validator and zod 4.6, all compiled
|
||||
// from their JavaScript: `c.req.valid(target)` hands the handler the
|
||||
// parsed value, typed by the schema's z.infer through hono's declarations.
|
||||
// Requests go through app.request, so no socket is involved.
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { Hono, type Context } from "hono";
|
||||
import { z } from "zod";
|
||||
|
||||
const Book = z.strictObject({
|
||||
title: z.string().trim().min(1),
|
||||
year: z.number().int().min(1450),
|
||||
tags: z.array(z.string()).max(4).default([]),
|
||||
rating: z.number().min(0).max(5).optional(),
|
||||
});
|
||||
type Book = z.infer<typeof Book>;
|
||||
const ListQuery = z.object({
|
||||
minYear: z.coerce.number().int().optional(),
|
||||
sort: z.enum(["title", "year"]).default("title"),
|
||||
limit: z.coerce.number().int().min(1).max(10).default(3),
|
||||
});
|
||||
const IdParam = z.object({ id: z.string().regex(/^b\d+$/) });
|
||||
|
||||
// Failed checks answer with the issues' paths and codes.
|
||||
const reject = (
|
||||
result: { success: true } | { success: false; error: z.core.$ZodError },
|
||||
c: Context,
|
||||
): Response | undefined => {
|
||||
if (result.success) return undefined;
|
||||
const paths = result.error.issues.map((i) => `${i.path.join(".")}:${i.code}`);
|
||||
return c.json({ error: "invalid", paths }, 400);
|
||||
};
|
||||
|
||||
const books = new Map<string, Book>();
|
||||
let nextId = 1;
|
||||
|
||||
const app = new Hono();
|
||||
app.post(
|
||||
"/books",
|
||||
zValidator("json", Book, (result, c) => {
|
||||
if (!result.success) {
|
||||
const paths = result.error.issues.map((i) => `${i.path.join(".")}:${i.code}`);
|
||||
return c.json({ error: "invalid", paths }, 400);
|
||||
}
|
||||
}),
|
||||
(c) => {
|
||||
const book = c.req.valid("json");
|
||||
book.tags.push("new");
|
||||
const id = `b${nextId++}`;
|
||||
books.set(id, book);
|
||||
const score = (book.rating ?? 0) * 2 + book.tags.length;
|
||||
return c.json({ id, title: book.title.toUpperCase(), year: book.year, score }, 201);
|
||||
},
|
||||
);
|
||||
app.get("/books", zValidator("query", ListQuery, reject), (c) => {
|
||||
const { minYear, sort, limit } = c.req.valid("query");
|
||||
const rows = [...books.values()]
|
||||
.filter((b) => minYear === undefined || b.year >= minYear)
|
||||
.sort((a, b) => (sort === "year" ? a.year - b.year : a.title < b.title ? -1 : 1))
|
||||
.slice(0, limit)
|
||||
.map((b) => `${b.title}/${b.year}`);
|
||||
return c.json({ sort, limit, rows });
|
||||
});
|
||||
app.get("/books/:id", zValidator("param", IdParam, reject), (c) => {
|
||||
const id = c.req.valid("param").id;
|
||||
const book = books.get(id);
|
||||
if (book === undefined) return c.json({ error: "missing", id }, 404);
|
||||
return c.json({ id, ...book });
|
||||
});
|
||||
|
||||
async function call(method: string, path: string, body?: unknown): Promise<void> {
|
||||
const init: RequestInit = { method };
|
||||
if (body !== undefined) {
|
||||
init.body = JSON.stringify(body);
|
||||
init.headers = { "content-type": "application/json" };
|
||||
}
|
||||
const res = await app.request(path, init);
|
||||
console.log(method, path, res.status, await res.text());
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
await call("POST", "/books", { title: " Dune ", year: 1965, tags: ["sf"], rating: 4.5 });
|
||||
await call("POST", "/books", { title: "Emma", year: 1815 });
|
||||
await call("POST", "/books", { title: "Ulysses", year: 1922, tags: ["modern"] });
|
||||
await call("POST", "/books", { title: "", year: 1200, extra: true });
|
||||
await call("POST", "/books", { title: "Bad", year: "x", tags: [1, 2, 3, 4, 5] });
|
||||
await call("GET", "/books");
|
||||
await call("GET", "/books?minYear=1900&sort=year&limit=5");
|
||||
await call("GET", "/books?limit=99");
|
||||
await call("GET", "/books/b2");
|
||||
await call("GET", "/books/b9");
|
||||
await call("GET", "/books/nope");
|
||||
const kept = books.get("b1")!;
|
||||
console.log("stored", kept.tags.join(","), kept.title);
|
||||
}
|
||||
|
||||
void main();
|
||||
@@ -0,0 +1 @@
|
||||
{ "name": "hono-zod-validator-case", "private": true, "type": "module" }
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
// Values that cross from zod 4.6 (compiled from its JavaScript) into code
|
||||
// typed by zod's declarations: z.infer, z.input and z.output, identity,
|
||||
// aliasing and mutation after parse, values zod hands back unchanged,
|
||||
// callbacks zod calls, typed array work, and caught failures.
|
||||
import { z } from "zod";
|
||||
|
||||
const show = (label: string, value: unknown): void => {
|
||||
console.log(label + " " + JSON.stringify(value));
|
||||
};
|
||||
|
||||
// Typed records: field reads, writes and array work on parsed data.
|
||||
const Item = z.object({
|
||||
sku: z.string(),
|
||||
price: z.number().nonnegative(),
|
||||
qty: z.number().int(),
|
||||
tags: z.array(z.string()).default([]),
|
||||
note: z.string().optional(),
|
||||
owner: z.string().nullable(),
|
||||
});
|
||||
type Item = z.infer<typeof Item>;
|
||||
const items: Item[] = z.array(Item).parse([
|
||||
{ sku: "a", price: 2.5, qty: 4, tags: ["x"], owner: null },
|
||||
{ sku: "b", price: 10, qty: 1, owner: "ann", note: "fragile" },
|
||||
{ sku: "c", price: 0.5, qty: 10, tags: ["x", "y"], owner: null },
|
||||
]);
|
||||
const total = items.reduce((sum, it) => sum + it.price * it.qty, 0);
|
||||
console.log("total", total);
|
||||
const byTag = new Map<string, number>();
|
||||
for (const it of items) for (const t of it.tags) byTag.set(t, (byTag.get(t) ?? 0) + it.qty);
|
||||
console.log("byTag", [...byTag].map(([k, v]) => `${k}=${v}`).join(","));
|
||||
const sorted = [...items].sort((a, b) => b.price - a.price).map((it) => it.sku);
|
||||
console.log("sorted", sorted.join(","));
|
||||
console.log("optional", items.map((it) => `${it.note ?? "-"}/${it.owner ?? "nobody"}`).join(","));
|
||||
console.log("keys", items.map((it) => Object.keys(it).join("+")).join(" "));
|
||||
|
||||
// Mutation after parse is visible through every reference.
|
||||
const first = items[0]!;
|
||||
first.qty += 1;
|
||||
first.tags.push("z");
|
||||
console.log("mutated", items[0]!.qty, items[0]!.tags.join("|"), first === items[0]);
|
||||
show("item", items[0]);
|
||||
|
||||
// Strict objects reject unknown keys; the error is zod's, caught.
|
||||
const Strict = z.strictObject({ name: z.string().trim().min(1), email: z.email() });
|
||||
type Strict = z.infer<typeof Strict>;
|
||||
const person: Strict = Strict.parse({ name: " Ada ", email: "ada@example.com" });
|
||||
console.log("strict", person.name.length, person.email.toUpperCase());
|
||||
const rejected = Strict.safeParse({ name: "x", email: "x@example.com", extra: 1 });
|
||||
console.log("strict bad", rejected.success, rejected.error?.issues.map((i) => i.code).join(","));
|
||||
|
||||
// z.input and z.output differ across a transform and a default.
|
||||
const Config = z.object({
|
||||
port: z.string().transform((s) => Number(s)),
|
||||
host: z.string().default("localhost"),
|
||||
debug: z.enum(["true", "false"]).transform((v) => v === "true"),
|
||||
});
|
||||
type ConfigIn = z.input<typeof Config>;
|
||||
type ConfigOut = z.output<typeof Config>;
|
||||
const raw: ConfigIn = { port: "8080", debug: "true" };
|
||||
const config: ConfigOut = Config.parse(raw);
|
||||
console.log("config", config.port + 1, config.host, config.debug, typeof config.port);
|
||||
|
||||
// A value zod hands back unchanged keeps its identity and its mutations.
|
||||
const Point = z.custom<{ x: number; y: number }>();
|
||||
const original = { x: 1, y: 2 };
|
||||
const same = Point.parse(original);
|
||||
same.x = 10;
|
||||
console.log("custom", original.x, same === original);
|
||||
original.y = 20;
|
||||
console.log("custom back", same.y);
|
||||
|
||||
// A shared object returned by a transform: every parse sees the same one.
|
||||
const shared = { hits: 0 };
|
||||
const Counter = z.string().transform(() => shared);
|
||||
const c1 = Counter.parse("a");
|
||||
const c2 = Counter.parse("b");
|
||||
c1.hits += 1;
|
||||
console.log("shared", c2.hits, shared.hits, c1 === c2);
|
||||
|
||||
// A refine callback reads typed fields of the value zod checks.
|
||||
const Range = z
|
||||
.object({ lo: z.number(), hi: z.number() })
|
||||
.refine((r) => r.lo <= r.hi, { message: "lo must not exceed hi" });
|
||||
console.log("range ok", JSON.stringify(Range.parse({ lo: 1, hi: 3 })));
|
||||
const bad = Range.safeParse({ lo: 5, hi: 3 });
|
||||
console.log("range bad", bad.success ? "?" : bad.error.issues[0]?.message);
|
||||
|
||||
// safeParse data, a discriminated union, and loose objects' extra keys.
|
||||
const Event = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("click"), x: z.number(), y: z.number() }),
|
||||
z.object({ type: z.literal("key"), key: z.string() }),
|
||||
]);
|
||||
type Event = z.infer<typeof Event>;
|
||||
const describe = (e: Event): string => (e.type === "click" ? `click@${e.x},${e.y}` : `key:${e.key}`);
|
||||
const r = Event.safeParse({ type: "key", key: "Enter" });
|
||||
if (r.success) console.log("event", describe(r.data));
|
||||
const events = z.array(Event).parse([
|
||||
{ type: "click", x: 1, y: 2 },
|
||||
{ type: "key", key: "a" },
|
||||
]);
|
||||
console.log("events", events.map(describe).join(" "));
|
||||
const Loose = z.looseObject({ id: z.number() });
|
||||
const loose = Loose.parse({ extra: true, id: 3, more: "m" });
|
||||
console.log("loose", loose.id, Object.keys(loose).join(","), JSON.stringify(loose));
|
||||
|
||||
// A union discriminated by boolean literals, read through a safeParse
|
||||
// result narrowed to its success arm.
|
||||
const Outcome = z.discriminatedUnion("ok", [
|
||||
z.object({ ok: z.literal(true), value: z.number() }),
|
||||
z.object({ ok: z.literal(false), reason: z.string() }),
|
||||
]);
|
||||
type Outcome = z.infer<typeof Outcome>;
|
||||
const outcomes: Outcome[] = [];
|
||||
for (const input of [{ ok: true, value: 41 }, { ok: false, reason: "late" }, { ok: "maybe" }]) {
|
||||
const parsed = Outcome.safeParse(input);
|
||||
if (parsed.success) outcomes.push(parsed.data);
|
||||
else console.log("outcome bad", parsed.error.issues.length);
|
||||
}
|
||||
console.log("outcomes", outcomes.map((o) => (o.ok ? `value ${o.value + 1}` : `reason ${o.reason}`)).join(", "));
|
||||
const Flags = z.object({ beta: z.boolean().optional(), mode: z.enum(["a", "b"]) });
|
||||
const flagged = Flags.safeParse({ beta: true, mode: "b" });
|
||||
if (flagged.success) {
|
||||
const flags = flagged.data;
|
||||
console.log("flags", flags.beta === true ? "beta on" : "beta off", flags.mode);
|
||||
}
|
||||
|
||||
// Tuples, brands and coerced query-style input.
|
||||
const Pair = z.tuple([z.string(), z.number()]);
|
||||
const [label, count] = Pair.parse(["n", 4]);
|
||||
console.log("tuple", label, count + 1);
|
||||
const UserId = z.string().brand<"UserId">();
|
||||
const uid = UserId.parse("u_1");
|
||||
console.log("brand", uid.length, uid);
|
||||
const Query = z.object({ page: z.coerce.number().int().min(1).default(1), q: z.string().optional() });
|
||||
const query = Query.parse({ page: "3" });
|
||||
console.log("query", query.page * 10, query.q === undefined, "q" in query);
|
||||
|
||||
// async parse
|
||||
async function main(): Promise<void> {
|
||||
const it = await Item.parseAsync({ sku: "d", price: 1, qty: 2, owner: null });
|
||||
console.log("async", it.sku, it.price * it.qty, it.tags.length);
|
||||
const failed = await Item.safeParseAsync({ sku: 1, price: -1, qty: 0.5, owner: null });
|
||||
console.log("async bad", failed.success, failed.error?.issues.map((i) => i.path.join(".")).join(","));
|
||||
}
|
||||
|
||||
void main();
|
||||
@@ -0,0 +1 @@
|
||||
{ "name": "zod4-boundary-case", "private": true, "type": "module" }
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import { InferInput } from "hono/validator";
|
||||
import { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from "hono";
|
||||
import * as v3 from "zod/v3";
|
||||
import { ZodSafeParseResult } from "zod/v4";
|
||||
import * as v4 from "zod/v4/core";
|
||||
//#region src/index.d.ts
|
||||
type ZodSchema = v3.ZodType | v4.$ZodType;
|
||||
type ZodError<T extends ZodSchema> = T extends v4.$ZodType ? v4.$ZodError<v4.output<T>> : v3.ZodError;
|
||||
type ZodSafeParseResult$1<T, T2, T3 extends ZodSchema> = T3 extends v4.$ZodType ? ZodSafeParseResult<T> : v3.SafeParseReturnType<T, T2>;
|
||||
type zInput<T> = T extends v3.ZodType ? v3.input<T> : T extends v4.$ZodType ? v4.input<T> : never;
|
||||
type zOutput<T> = T extends v3.ZodType ? v3.output<T> : T extends v4.$ZodType ? v4.output<T> : never;
|
||||
type zInfer<T> = T extends v3.ZodType ? v3.infer<T> : T extends v4.$ZodType ? v4.infer<T> : never;
|
||||
type ZodValidatorFailureBody<T extends ZodSchema> = T extends v4.$ZodType ? Extract<ZodSafeParseResult<v4.output<T>>, {
|
||||
success: false;
|
||||
}> : T extends v3.ZodType ? Extract<v3.SafeParseReturnType<v3.input<T>, v3.output<T>>, {
|
||||
success: false;
|
||||
}> : never;
|
||||
type ZodValidatorFailureResponse<T extends ZodSchema> = Response & TypedResponse<ZodValidatorFailureBody<T>, 400, "json">;
|
||||
type Hook<T, E extends Env, P extends string, Target extends keyof ValidationTargets = keyof ValidationTargets, O = {}, Schema extends ZodSchema = any> = (result: ({
|
||||
success: true;
|
||||
data: T;
|
||||
} | {
|
||||
success: false;
|
||||
error: ZodError<Schema>;
|
||||
data: T;
|
||||
}) & {
|
||||
target: Target;
|
||||
}, c: Context<E, P>) => Response | void | TypedResponse<O> | Promise<Response | void | TypedResponse<O>>;
|
||||
type HasUndefined<T> = undefined extends T ? true : false;
|
||||
type ExtractValidationResponse<VF> = VF extends ((value: any, c: any) => infer R) ? R extends Promise<infer PR> ? PR extends TypedResponse<infer T, infer S, infer F> ? Response & TypedResponse<T, S, F> : PR extends Response ? PR : PR extends undefined ? never : never : R extends TypedResponse<infer T, infer S, infer F> ? Response & TypedResponse<T, S, F> : R extends Response ? R : R extends undefined ? never : never : never;
|
||||
type ValidationFunctionOption<T extends ZodSchema, Target extends keyof ValidationTargets> = {
|
||||
validationFunction: (schema: T, value: ValidationTargets[Target]) => ZodSafeParseResult$1<any, any, T> | Promise<ZodSafeParseResult$1<any, any, T>>;
|
||||
};
|
||||
type DefaultInput<Target extends keyof ValidationTargets, In, Out> = {
|
||||
in: HasUndefined<In> extends true ? { [K in Target]?: [In] extends [ValidationTargets[K]] ? In : InferInput<In, K>; } : { [K in Target]: [In] extends [ValidationTargets[K]] ? In : InferInput<In, K>; };
|
||||
out: { [K in Target]: Out; };
|
||||
};
|
||||
declare function zValidatorFunction<T extends ZodSchema, Target extends keyof ValidationTargets, E extends Env, P extends string, In = zInput<T>, Out = zOutput<T>, I extends Input = DefaultInput<Target, In, Out>, V extends I = I>(target: Target, schema: T, hook?: undefined, options?: ValidationFunctionOption<T, Target>): MiddlewareHandler<E, P, V, ZodValidatorFailureResponse<T>>;
|
||||
declare function zValidatorFunction<T extends ZodSchema, Target extends keyof ValidationTargets, E extends Env, P extends string, HookFn extends Hook<InferredValue, E, P, Target, {}, T>, In = zInput<T>, Out = zOutput<T>, I extends Input = DefaultInput<Target, In, Out>, V extends I = I, InferredValue = zInfer<T>>(target: Target, schema: T, hook?: HookFn, options?: ValidationFunctionOption<T, Target>): MiddlewareHandler<E, P, V, ExtractValidationResponse<HookFn>>;
|
||||
declare const zValidator: typeof zValidatorFunction;
|
||||
//#endregion
|
||||
export { Hook, zValidator };
|
||||
//# sourceMappingURL=index.d.mts.map
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { validator } from "hono/validator";
|
||||
//#region src/index.ts
|
||||
function zValidatorFunction(target, schema, hook, options) {
|
||||
const caseInsensitiveKeymap = target === "header" && ("_def" in schema || "_zod" in schema) ? Object.fromEntries(Object.keys("in" in schema ? schema.in.shape : schema.shape).map((key) => [key.toLowerCase(), key])) : void 0;
|
||||
return validator(target, async (value, c) => {
|
||||
let validatorValue = value;
|
||||
if (caseInsensitiveKeymap) validatorValue = Object.fromEntries(Object.entries(value).map(([key, value]) => [caseInsensitiveKeymap[key] || key, value]));
|
||||
const result = options && options.validationFunction ? await options.validationFunction(schema, validatorValue) : await schema.safeParseAsync(validatorValue);
|
||||
if (hook) {
|
||||
const hookResult = await hook({
|
||||
data: validatorValue,
|
||||
...result,
|
||||
target
|
||||
}, c);
|
||||
if (hookResult) {
|
||||
if (hookResult instanceof Response) return hookResult;
|
||||
if ("response" in hookResult) return hookResult.response;
|
||||
}
|
||||
}
|
||||
if (!result.success) return c.json(result, 400);
|
||||
return result.data;
|
||||
});
|
||||
}
|
||||
const zValidator = zValidatorFunction;
|
||||
//#endregion
|
||||
export { zValidator };
|
||||
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@hono/zod-validator",
|
||||
"version": "0.9.1",
|
||||
"description": "Test fixture: the ESM build and its declarations.",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"import": "./dist/index.mjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
//#region src/compose.ts
|
||||
/**
|
||||
* Compose middleware functions into a single function based on `koa-compose` package.
|
||||
*
|
||||
* @template E - The environment type.
|
||||
*
|
||||
* @param {[[Function, unknown], unknown][] | [[Function]][]} middleware - An array of middleware functions and their corresponding parameters.
|
||||
* @param {ErrorHandler<E>} [onError] - An optional error handler function.
|
||||
* @param {NotFoundHandler<E>} [onNotFound] - An optional not-found handler function.
|
||||
*
|
||||
* @returns {(context: Context, next?: Next) => Promise<Context>} - A composed middleware function.
|
||||
*/
|
||||
const compose = (middleware, onError, onNotFound) => {
|
||||
return (context, next) => {
|
||||
let index = -1;
|
||||
return dispatch(0);
|
||||
/**
|
||||
* Dispatch the middleware functions.
|
||||
*
|
||||
* @param {number} i - The current index in the middleware array.
|
||||
*
|
||||
* @returns {Promise<Context>} - A promise that resolves to the context.
|
||||
*/
|
||||
async function dispatch(i) {
|
||||
if (i <= index) throw new Error("next() called multiple times");
|
||||
index = i;
|
||||
let res;
|
||||
let isError = false;
|
||||
let handler;
|
||||
if (middleware[i]) {
|
||||
handler = middleware[i][0][0];
|
||||
context.req.routeIndex = i;
|
||||
} else handler = i === middleware.length && next || void 0;
|
||||
if (handler) try {
|
||||
res = await handler(context, () => dispatch(i + 1));
|
||||
} catch (err) {
|
||||
if (err instanceof Error && onError) {
|
||||
context.error = err;
|
||||
res = await onError(err, context);
|
||||
isError = true;
|
||||
} else throw err;
|
||||
}
|
||||
else if (context.finalized === false && onNotFound) res = await onNotFound(context);
|
||||
if (res && (context.finalized === false || isError)) context.res = res;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
};
|
||||
//#endregion
|
||||
export { compose };
|
||||
+381
@@ -0,0 +1,381 @@
|
||||
import { HonoRequest } from "./request.js";
|
||||
import { HtmlEscapedCallbackPhase, resolveCallback } from "./utils/html.js";
|
||||
//#region src/context.ts
|
||||
const TEXT_PLAIN = "text/plain; charset=UTF-8";
|
||||
const setDefaultContentType = (contentType, headers) => {
|
||||
return {
|
||||
"Content-Type": contentType,
|
||||
...headers
|
||||
};
|
||||
};
|
||||
const createResponseInstance = (body, init) => new Response(body, init);
|
||||
var Context = class {
|
||||
#rawRequest;
|
||||
#req;
|
||||
/**
|
||||
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#env}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Environment object for Cloudflare Workers
|
||||
* app.get('*', async c => {
|
||||
* const counter = c.env.COUNTER
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
env = {};
|
||||
#var;
|
||||
finalized = false;
|
||||
/**
|
||||
* `.error` can get the error object from the middleware if the Handler throws an error.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#error}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async (c, next) => {
|
||||
* await next()
|
||||
* if (c.error) {
|
||||
* // do something...
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
error;
|
||||
#status;
|
||||
#executionCtx;
|
||||
#res;
|
||||
#layout;
|
||||
#renderer;
|
||||
#notFoundHandler;
|
||||
#preparedHeaders;
|
||||
#matchResult;
|
||||
#path;
|
||||
/**
|
||||
* Creates an instance of the Context class.
|
||||
*
|
||||
* @param req - The Request object.
|
||||
* @param options - Optional configuration options for the context.
|
||||
*/
|
||||
constructor(req, options) {
|
||||
this.#rawRequest = req;
|
||||
if (options) {
|
||||
this.#executionCtx = options.executionCtx;
|
||||
this.env = options.env;
|
||||
this.#notFoundHandler = options.notFoundHandler;
|
||||
this.#path = options.path;
|
||||
this.#matchResult = options.matchResult;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* `.req` is the instance of {@link HonoRequest}.
|
||||
*/
|
||||
get req() {
|
||||
this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
|
||||
return this.#req;
|
||||
}
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#event}
|
||||
* The FetchEvent associated with the current request.
|
||||
*
|
||||
* @throws Will throw an error if the context does not have a FetchEvent.
|
||||
*/
|
||||
get event() {
|
||||
if (this.#executionCtx && "respondWith" in this.#executionCtx) return this.#executionCtx;
|
||||
else throw Error("This context has no FetchEvent");
|
||||
}
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#executionctx}
|
||||
* The ExecutionContext associated with the current request.
|
||||
*
|
||||
* @throws Will throw an error if the context does not have an ExecutionContext.
|
||||
*/
|
||||
get executionCtx() {
|
||||
if (this.#executionCtx) return this.#executionCtx;
|
||||
else throw Error("This context has no ExecutionContext");
|
||||
}
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#res}
|
||||
* The Response object for the current request.
|
||||
*/
|
||||
get res() {
|
||||
return this.#res ||= createResponseInstance(null, { headers: this.#preparedHeaders ??= new Headers() });
|
||||
}
|
||||
/**
|
||||
* Sets the Response object for the current request.
|
||||
*
|
||||
* @param _res - The Response object to set.
|
||||
*/
|
||||
set res(_res) {
|
||||
if (this.#res && _res) {
|
||||
_res = createResponseInstance(_res.body, _res);
|
||||
for (const [k, v] of this.#res.headers.entries()) {
|
||||
if (k === "content-type") continue;
|
||||
if (k === "set-cookie") {
|
||||
const cookies = this.#res.headers.getSetCookie();
|
||||
_res.headers.delete("set-cookie");
|
||||
for (const cookie of cookies) _res.headers.append("set-cookie", cookie);
|
||||
} else _res.headers.set(k, v);
|
||||
}
|
||||
}
|
||||
this.#res = _res;
|
||||
this.finalized = true;
|
||||
}
|
||||
/**
|
||||
* `.render()` can create a response within a layout.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/', (c) => {
|
||||
* return c.render('Hello!')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
render = (...args) => {
|
||||
this.#renderer ??= (content) => this.html(content);
|
||||
return this.#renderer(...args);
|
||||
};
|
||||
/**
|
||||
* Sets the layout for the response.
|
||||
*
|
||||
* @param layout - The layout to set.
|
||||
* @returns The layout function.
|
||||
*/
|
||||
setLayout = (layout) => this.#layout = layout;
|
||||
/**
|
||||
* Gets the current layout for the response.
|
||||
*
|
||||
* @returns The current layout function.
|
||||
*/
|
||||
getLayout = () => this.#layout;
|
||||
/**
|
||||
* `.setRenderer()` can set the layout in the custom middleware.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* app.use('*', async (c, next) => {
|
||||
* c.setRenderer((content) => {
|
||||
* return c.html(
|
||||
* <html>
|
||||
* <body>
|
||||
* <p>{content}</p>
|
||||
* </body>
|
||||
* </html>
|
||||
* )
|
||||
* })
|
||||
* await next()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
setRenderer = (renderer) => {
|
||||
this.#renderer = renderer;
|
||||
};
|
||||
/**
|
||||
* `.header()` can set headers.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#header}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/welcome', (c) => {
|
||||
* // Set headers
|
||||
* c.header('X-Message', 'Hello!')
|
||||
* c.header('Content-Type', 'text/plain')
|
||||
*
|
||||
* // Append multiple headers using the append option (e.g. Vary)
|
||||
* c.header('Vary', 'Accept-Encoding', { append: true })
|
||||
* c.header('Vary', 'User-Agent', { append: true })
|
||||
*
|
||||
* return c.body('Thank you for coming')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
header = (name, value, options) => {
|
||||
if (this.finalized) this.#res = createResponseInstance(this.#res.body, this.#res);
|
||||
const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
|
||||
if (value === void 0) headers.delete(name);
|
||||
else if (options?.append) headers.append(name, value);
|
||||
else headers.set(name, value);
|
||||
};
|
||||
status = (status) => {
|
||||
this.#status = status;
|
||||
};
|
||||
/**
|
||||
* `.set()` can set the value specified by the key.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#set-get}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async (c, next) => {
|
||||
* c.set('message', 'Hono is hot!!')
|
||||
* await next()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
set = (key, value) => {
|
||||
this.#var ??= /* @__PURE__ */ new Map();
|
||||
this.#var.set(key, value);
|
||||
};
|
||||
/**
|
||||
* `.get()` can use the value specified by the key.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#set-get}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/', (c) => {
|
||||
* const message = c.get('message')
|
||||
* return c.text(`The message is "${message}"`)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get = (key) => {
|
||||
return this.#var ? this.#var.get(key) : void 0;
|
||||
};
|
||||
/**
|
||||
* `.var` can access the value of a variable.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#var}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const result = c.var.client.oneMethod()
|
||||
* ```
|
||||
*/
|
||||
get var() {
|
||||
if (!this.#var) return {};
|
||||
return Object.fromEntries(this.#var);
|
||||
}
|
||||
#newResponse(data, arg, headers) {
|
||||
let responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders;
|
||||
if (typeof arg === "object" && arg.headers) {
|
||||
responseHeaders ??= new Headers();
|
||||
for (const [key, value] of new Headers(arg.headers)) if (key === "set-cookie") responseHeaders.append(key, value);
|
||||
else responseHeaders.set(key, value);
|
||||
}
|
||||
if (headers) {
|
||||
if (!responseHeaders) {
|
||||
let count = 0;
|
||||
for (const k in headers) if (++count > 1 || typeof headers[k] !== "string") {
|
||||
responseHeaders = new Headers();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (responseHeaders) for (const k in headers) {
|
||||
const v = headers[k];
|
||||
if (typeof v === "string") responseHeaders.set(k, v);
|
||||
else {
|
||||
responseHeaders.delete(k);
|
||||
for (const v2 of v) responseHeaders.append(k, v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
|
||||
return createResponseInstance(data, {
|
||||
status,
|
||||
headers: responseHeaders ?? headers
|
||||
});
|
||||
}
|
||||
newResponse = (...args) => this.#newResponse(...args);
|
||||
/**
|
||||
* `.body()` can return the HTTP response.
|
||||
* You can set headers with `.header()` and set HTTP status code with `.status`.
|
||||
* This can also be set in `.text()`, `.json()` and so on.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#body}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/welcome', (c) => {
|
||||
* // Set headers
|
||||
* c.header('X-Message', 'Hello!')
|
||||
* c.header('Content-Type', 'text/plain')
|
||||
* // Set HTTP status code
|
||||
* c.status(201)
|
||||
*
|
||||
* // Return the response body
|
||||
* return c.body('Thank you for coming')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
body = (data, arg, headers) => this.#newResponse(data, arg, headers);
|
||||
/**
|
||||
* `.text()` can render text as `Content-Type:text/plain`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#text}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/say', (c) => {
|
||||
* return c.text('Hello!')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
text = (text, arg, headers) => {
|
||||
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(text, arg, setDefaultContentType(TEXT_PLAIN, headers));
|
||||
};
|
||||
/**
|
||||
* `.json()` can render JSON as `Content-Type:application/json`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#json}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/api', (c) => {
|
||||
* return c.json({ message: 'Hello!' })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
json = (object, arg, headers) => {
|
||||
return this.#newResponse(JSON.stringify(object), arg, setDefaultContentType("application/json", headers));
|
||||
};
|
||||
html = (html, arg, headers) => {
|
||||
const res = (html) => this.#newResponse(html, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
|
||||
return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
|
||||
};
|
||||
/**
|
||||
* `.redirect()` can Redirect, default status code is 302.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#redirect}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/redirect', (c) => {
|
||||
* return c.redirect('/')
|
||||
* })
|
||||
* app.get('/redirect-permanently', (c) => {
|
||||
* return c.redirect('/', 301)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
redirect = (location, status) => {
|
||||
const locationString = String(location);
|
||||
this.header("Location", !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString));
|
||||
return this.newResponse(null, status ?? 302);
|
||||
};
|
||||
/**
|
||||
* `.notFound()` can return the Not Found Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#notfound}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/notfound', (c) => {
|
||||
* return c.notFound()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
notFound = () => {
|
||||
this.#notFoundHandler ??= () => createResponseInstance();
|
||||
return this.#notFoundHandler(this);
|
||||
};
|
||||
};
|
||||
//#endregion
|
||||
export { Context, TEXT_PLAIN };
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import { parse, parseSigned, serialize, serializeSigned } from "../../utils/cookie.js";
|
||||
//#region src/helper/cookie/index.ts
|
||||
const getCookie = (c, key, prefix) => {
|
||||
const cookie = c.req.raw.headers.get("Cookie");
|
||||
if (typeof key === "string") {
|
||||
if (!cookie) return;
|
||||
let finalKey = key;
|
||||
if (prefix === "secure") finalKey = "__Secure-" + key;
|
||||
else if (prefix === "host") finalKey = "__Host-" + key;
|
||||
return parse(cookie, finalKey)[finalKey];
|
||||
}
|
||||
if (!cookie) return {};
|
||||
return parse(cookie);
|
||||
};
|
||||
const getSignedCookie = async (c, secret, key, prefix) => {
|
||||
const cookie = c.req.raw.headers.get("Cookie");
|
||||
if (typeof key === "string") {
|
||||
if (!cookie) return;
|
||||
let finalKey = key;
|
||||
if (prefix === "secure") finalKey = "__Secure-" + key;
|
||||
else if (prefix === "host") finalKey = "__Host-" + key;
|
||||
return (await parseSigned(cookie, secret, finalKey))[finalKey];
|
||||
}
|
||||
if (!cookie) return {};
|
||||
return await parseSigned(cookie, secret);
|
||||
};
|
||||
const generateCookie = (name, value, opt) => {
|
||||
let cookie;
|
||||
if (opt?.prefix === "secure") cookie = serialize("__Secure-" + name, value, {
|
||||
path: "/",
|
||||
...opt,
|
||||
secure: true
|
||||
});
|
||||
else if (opt?.prefix === "host") cookie = serialize("__Host-" + name, value, {
|
||||
...opt,
|
||||
path: "/",
|
||||
secure: true,
|
||||
domain: void 0
|
||||
});
|
||||
else cookie = serialize(name, value, {
|
||||
path: "/",
|
||||
...opt
|
||||
});
|
||||
return cookie;
|
||||
};
|
||||
const setCookie = (c, name, value, opt) => {
|
||||
const cookie = generateCookie(name, value, opt);
|
||||
c.header("Set-Cookie", cookie, { append: true });
|
||||
};
|
||||
const generateSignedCookie = async (name, value, secret, opt) => {
|
||||
let cookie;
|
||||
if (opt?.prefix === "secure") cookie = await serializeSigned("__Secure-" + name, value, secret, {
|
||||
path: "/",
|
||||
...opt,
|
||||
secure: true
|
||||
});
|
||||
else if (opt?.prefix === "host") cookie = await serializeSigned("__Host-" + name, value, secret, {
|
||||
...opt,
|
||||
path: "/",
|
||||
secure: true,
|
||||
domain: void 0
|
||||
});
|
||||
else cookie = await serializeSigned(name, value, secret, {
|
||||
path: "/",
|
||||
...opt
|
||||
});
|
||||
return cookie;
|
||||
};
|
||||
const setSignedCookie = async (c, name, value, secret, opt) => {
|
||||
const cookie = await generateSignedCookie(name, value, secret, opt);
|
||||
c.header("set-cookie", cookie, { append: true });
|
||||
};
|
||||
const deleteCookie = (c, name, opt) => {
|
||||
const deletedCookie = getCookie(c, name, opt?.prefix);
|
||||
setCookie(c, name, "", {
|
||||
...opt,
|
||||
maxAge: 0
|
||||
});
|
||||
return deletedCookie;
|
||||
};
|
||||
//#endregion
|
||||
export { deleteCookie, generateCookie, generateSignedCookie, getCookie, getSignedCookie, setCookie, setSignedCookie };
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
import { compose } from "./compose.js";
|
||||
import { getPath, getPathNoStrict, mergePath } from "./utils/url.js";
|
||||
import { Context } from "./context.js";
|
||||
import { METHODS } from "./router.js";
|
||||
import { COMPOSED_HANDLER } from "./utils/constants.js";
|
||||
//#region src/hono-base.ts
|
||||
/**
|
||||
* @module
|
||||
* This module is the base module for the Hono object.
|
||||
*/
|
||||
const notFoundHandler = (c) => {
|
||||
return c.text("404 Not Found", 404);
|
||||
};
|
||||
const errorHandler = (err, c) => {
|
||||
if ("getResponse" in err) {
|
||||
const res = err.getResponse();
|
||||
return c.newResponse(res.body, res);
|
||||
}
|
||||
console.error(err);
|
||||
return c.text("Internal Server Error", 500);
|
||||
};
|
||||
var Hono = class Hono {
|
||||
get;
|
||||
post;
|
||||
put;
|
||||
delete;
|
||||
options;
|
||||
patch;
|
||||
query;
|
||||
all;
|
||||
on;
|
||||
use;
|
||||
router;
|
||||
getPath;
|
||||
_basePath = "/";
|
||||
#path = "/";
|
||||
routes = [];
|
||||
constructor(options = {}) {
|
||||
[...METHODS, "all"].forEach((method) => {
|
||||
this[method] = (args1, ...args) => {
|
||||
const methodName = method.toUpperCase();
|
||||
if (typeof args1 === "string") this.#path = args1;
|
||||
else this.#addRoute(methodName, this.#path, args1);
|
||||
args.forEach((handler) => {
|
||||
this.#addRoute(methodName, this.#path, handler);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
});
|
||||
this.on = (method, path, ...handlers) => {
|
||||
for (const p of [path].flat()) {
|
||||
this.#path = p;
|
||||
for (const m of [method].flat()) {
|
||||
const methodName = m.toUpperCase();
|
||||
for (const handler of handlers) this.#addRoute(methodName, this.#path, handler);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
this.use = (arg1, ...handlers) => {
|
||||
if (typeof arg1 === "string") this.#path = arg1;
|
||||
else {
|
||||
this.#path = "*";
|
||||
handlers.unshift(arg1);
|
||||
}
|
||||
handlers.forEach((handler) => {
|
||||
this.#addRoute("ALL", this.#path, handler);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
const { strict, ...optionsWithoutStrict } = options;
|
||||
Object.assign(this, optionsWithoutStrict);
|
||||
this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
|
||||
}
|
||||
#clone() {
|
||||
const clone = new Hono({
|
||||
router: this.router,
|
||||
getPath: this.getPath
|
||||
});
|
||||
clone.errorHandler = this.errorHandler;
|
||||
clone.#notFoundHandler = this.#notFoundHandler;
|
||||
clone.routes = this.routes;
|
||||
return clone;
|
||||
}
|
||||
#notFoundHandler = notFoundHandler;
|
||||
errorHandler = errorHandler;
|
||||
/**
|
||||
* `.route()` allows grouping other Hono instance in routes.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#grouping}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @param {Hono} app - other Hono instance
|
||||
* @returns {Hono} routed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono()
|
||||
* const app2 = new Hono()
|
||||
*
|
||||
* app2.get("/user", (c) => c.text("user"))
|
||||
* app.route("/api", app2) // GET /api/user
|
||||
* ```
|
||||
*/
|
||||
route(path, app) {
|
||||
const subApp = this.basePath(path);
|
||||
app.routes.map((r) => {
|
||||
let handler;
|
||||
if (app.errorHandler === errorHandler) handler = r.handler;
|
||||
else {
|
||||
handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
|
||||
handler[COMPOSED_HANDLER] = r.handler;
|
||||
}
|
||||
subApp.#addRoute(r.method, r.path, handler, r.basePath);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* `.basePath()` allows base paths to be specified.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#base-path}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const api = new Hono().basePath('/api')
|
||||
* ```
|
||||
*/
|
||||
basePath(path) {
|
||||
const subApp = this.#clone();
|
||||
subApp._basePath = mergePath(this._basePath, path);
|
||||
return subApp;
|
||||
}
|
||||
/**
|
||||
* `.onError()` handles an error and returns a customized Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#error-handling}
|
||||
*
|
||||
* @param {ErrorHandler} handler - request Handler for error
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.onError((err, c) => {
|
||||
* console.error(`${err}`)
|
||||
* return c.text('Custom Error Message', 500)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
onError = (handler) => {
|
||||
this.errorHandler = handler;
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* `.notFound()` allows you to customize a Not Found Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#not-found}
|
||||
*
|
||||
* @param {NotFoundHandler} handler - request handler for not-found
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.notFound((c) => {
|
||||
* return c.text('Custom 404 Message', 404)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
notFound = (handler) => {
|
||||
this.#notFoundHandler = handler;
|
||||
return this;
|
||||
};
|
||||
/**
|
||||
* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
|
||||
*
|
||||
* @deprecated Use `mount()` from `hono/mount` instead. `.mount()` will be removed in v5.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#mount}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @param {Function} applicationHandler - other Request Handler
|
||||
* @param {MountOptions} [options] - options of `.mount()`
|
||||
* @returns {Hono} mounted Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Router as IttyRouter } from 'itty-router'
|
||||
* import { Hono } from 'hono'
|
||||
* // Create itty-router application
|
||||
* const ittyRouter = IttyRouter()
|
||||
* // GET /itty-router/hello
|
||||
* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
|
||||
*
|
||||
* const app = new Hono()
|
||||
* app.mount('/itty-router', ittyRouter.handle)
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono()
|
||||
* // Send the request to another application without modification.
|
||||
* app.mount('/app', anotherApp, {
|
||||
* replaceRequest: (req) => req,
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
mount(path, applicationHandler, options) {
|
||||
let replaceRequest;
|
||||
let optionHandler;
|
||||
if (options) {
|
||||
if (typeof options === "function") optionHandler = options;
|
||||
else {
|
||||
optionHandler = options.optionHandler;
|
||||
if (options.replaceRequest === false) replaceRequest = (request) => request;
|
||||
else replaceRequest = options.replaceRequest;
|
||||
}
|
||||
}
|
||||
const getOptions = optionHandler ? (c) => {
|
||||
const options = optionHandler(c);
|
||||
return Array.isArray(options) ? options : [options];
|
||||
} : (c) => {
|
||||
let executionContext = void 0;
|
||||
try {
|
||||
executionContext = c.executionCtx;
|
||||
} catch {}
|
||||
return [c.env, executionContext];
|
||||
};
|
||||
replaceRequest ||= (() => {
|
||||
const mergedPath = mergePath(this._basePath, path);
|
||||
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
||||
return (request) => {
|
||||
const url = new URL(request.url);
|
||||
url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
|
||||
return new Request(url, request);
|
||||
};
|
||||
})();
|
||||
const handler = async (c, next) => {
|
||||
const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
|
||||
if (res) return res;
|
||||
await next();
|
||||
};
|
||||
this.#addRoute("ALL", mergePath(path, "*"), handler);
|
||||
return this;
|
||||
}
|
||||
#addRoute(method, path, handler, baseRoutePath) {
|
||||
path = mergePath(this._basePath, path);
|
||||
const r = {
|
||||
basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
|
||||
path,
|
||||
method,
|
||||
handler
|
||||
};
|
||||
this.router.add(method, path, [handler, r]);
|
||||
this.routes.push(r);
|
||||
}
|
||||
#handleError(err, c) {
|
||||
if (err instanceof Error) return this.errorHandler(err, c);
|
||||
throw err;
|
||||
}
|
||||
#dispatch(request, executionCtx, env, method) {
|
||||
if (method === "HEAD") return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
|
||||
const path = this.getPath(request, { env });
|
||||
const matchResult = this.router.match(method, path);
|
||||
const c = new Context(request, {
|
||||
path,
|
||||
matchResult,
|
||||
env,
|
||||
executionCtx,
|
||||
notFoundHandler: this.#notFoundHandler
|
||||
});
|
||||
if (matchResult[0].length === 1) {
|
||||
let res;
|
||||
try {
|
||||
res = matchResult[0][0][0][0](c, async () => {
|
||||
c.res = await this.#notFoundHandler(c);
|
||||
});
|
||||
} catch (err) {
|
||||
return this.#handleError(err, c);
|
||||
}
|
||||
return res instanceof Promise ? res.then((resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
|
||||
}
|
||||
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
|
||||
return (async () => {
|
||||
try {
|
||||
const context = await composed(c);
|
||||
if (!context.finalized) throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");
|
||||
return context.res;
|
||||
} catch (err) {
|
||||
return this.#handleError(err, c);
|
||||
}
|
||||
})();
|
||||
}
|
||||
/**
|
||||
* `.fetch()` will be entry point of your app.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#fetch}
|
||||
*
|
||||
* @param {Request} request - request Object of request
|
||||
* @param {Env} env - env Object
|
||||
* @param {ExecutionContext} executionCtx - context of execution
|
||||
* @returns {Response | Promise<Response>} response of request
|
||||
*
|
||||
*/
|
||||
fetch = (request, ...rest) => {
|
||||
return this.#dispatch(request, rest[1], rest[0], request.method);
|
||||
};
|
||||
/**
|
||||
* `.request()` is a useful method for testing.
|
||||
* You can pass a URL or pathname to send a GET request.
|
||||
* app will return a Response object.
|
||||
* ```ts
|
||||
* test('GET /hello is ok', async () => {
|
||||
* const res = await app.request('/hello')
|
||||
* expect(res.status).toBe(200)
|
||||
* })
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/hono#request
|
||||
*/
|
||||
request = (input, requestInit, Env, executionCtx) => {
|
||||
if (input instanceof Request) return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
|
||||
input = input.toString();
|
||||
return this.fetch(new Request(/^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`, requestInit), Env, executionCtx);
|
||||
};
|
||||
/**
|
||||
* `.fire()` automatically adds a global fetch event listener.
|
||||
* This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
|
||||
* @deprecated
|
||||
* Use `fire` from `hono/service-worker` instead.
|
||||
* ```ts
|
||||
* import { Hono } from 'hono'
|
||||
* import { fire } from 'hono/service-worker'
|
||||
*
|
||||
* const app = new Hono()
|
||||
* // ...
|
||||
* fire(app)
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/hono#fire
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
|
||||
* @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
|
||||
*/
|
||||
fire = () => {
|
||||
addEventListener("fetch", (event) => {
|
||||
event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
|
||||
});
|
||||
};
|
||||
};
|
||||
//#endregion
|
||||
export { Hono as HonoBase };
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
import { HonoBase as Hono$1 } from "./hono-base.js";
|
||||
import { RegExpRouter } from "./router/reg-exp-router/router.js";
|
||||
import "./router/reg-exp-router/index.js";
|
||||
import { SmartRouter } from "./router/smart-router/router.js";
|
||||
import { TrieRouter } from "./router/trie-router/router.js";
|
||||
import "./router/trie-router/index.js";
|
||||
//#region src/hono.ts
|
||||
/**
|
||||
* The Hono class extends the functionality of the HonoBase class.
|
||||
* It sets up routing and allows for custom options to be passed.
|
||||
*
|
||||
* @template E - The environment type.
|
||||
* @template S - The schema type.
|
||||
* @template BasePath - The base path type.
|
||||
*/
|
||||
var Hono = class extends Hono$1 {
|
||||
/**
|
||||
* Creates an instance of the Hono class.
|
||||
*
|
||||
* @param options - Optional configuration options for the Hono instance.
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
this.router = options.router ?? new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()] });
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { Hono };
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
//#region src/http-exception.ts
|
||||
/**
|
||||
* `HTTPException` must be used when a fatal error such as authentication failure occurs.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/exception}
|
||||
*
|
||||
* @param {StatusCode} status - status code of HTTPException
|
||||
* @param {HTTPExceptionOptions} options - options of HTTPException
|
||||
* @param {HTTPExceptionOptions["res"]} options.res - response of options of HTTPException
|
||||
* @param {HTTPExceptionOptions["message"]} options.message - message of options of HTTPException
|
||||
* @param {HTTPExceptionOptions["cause"]} options.cause - cause of options of HTTPException
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { HTTPException } from 'hono/http-exception'
|
||||
*
|
||||
* // ...
|
||||
*
|
||||
* app.post('/auth', async (c, next) => {
|
||||
* // authentication
|
||||
* if (authorized === false) {
|
||||
* throw new HTTPException(401, { message: 'Custom error message' })
|
||||
* }
|
||||
* await next()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
var HTTPException = class extends Error {
|
||||
res;
|
||||
status;
|
||||
/**
|
||||
* Creates an instance of `HTTPException`.
|
||||
* @param status - HTTP status code for the exception. Defaults to 500.
|
||||
* @param options - Additional options for the exception.
|
||||
*/
|
||||
constructor(status = 500, options) {
|
||||
super(options?.message, { cause: options?.cause });
|
||||
this.res = options?.res;
|
||||
this.status = status;
|
||||
}
|
||||
/**
|
||||
* Returns the response object associated with the exception.
|
||||
* If a response object is not provided, a new response is created with the error message and status code.
|
||||
* @returns The response object.
|
||||
*/
|
||||
getResponse() {
|
||||
if (this.res) return new Response(this.res.body, {
|
||||
status: this.status,
|
||||
headers: this.res.headers
|
||||
});
|
||||
return new Response(this.message, { status: this.status });
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { HTTPException };
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import { Context } from "./context.js";
|
||||
import { Hono } from "./hono.js";
|
||||
//#region src/index.ts
|
||||
/**
|
||||
* @module
|
||||
*
|
||||
* Hono - Web Framework built on Web Standards
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Hono } from 'hono'
|
||||
* const app = new Hono()
|
||||
*
|
||||
* app.get('/', (c) => c.text('Hono!'))
|
||||
*
|
||||
* export default app
|
||||
* ```
|
||||
*/
|
||||
//#endregion
|
||||
export { Context, Hono };
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
import { HTTPException } from "./http-exception.js";
|
||||
import { GET_MATCH_RESULT } from "./request/constants.js";
|
||||
import { parseBody } from "./utils/body.js";
|
||||
import { getQueryParam, getQueryParams, tryDecodeURIComponent } from "./utils/url.js";
|
||||
//#region src/request.ts
|
||||
var HonoRequest = class {
|
||||
/**
|
||||
* `.raw` can get the raw Request object.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#raw}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // For Cloudflare Workers
|
||||
* app.post('/', async (c) => {
|
||||
* const metadata = c.req.raw.cf?.hostMetadata?
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
raw;
|
||||
#validatedData;
|
||||
#matchResult;
|
||||
routeIndex = 0;
|
||||
/**
|
||||
* `.path` can get the pathname of the request.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#path}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const pathname = c.req.path // `/about/me`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
path;
|
||||
bodyCache = {};
|
||||
constructor(request, path = "/", matchResult = [[]]) {
|
||||
this.raw = request;
|
||||
this.path = path;
|
||||
this.#matchResult = matchResult;
|
||||
}
|
||||
param(key) {
|
||||
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
|
||||
}
|
||||
#getDecodedParam(key) {
|
||||
const paramKey = this.#matchResult[0][this.routeIndex]?.[1][key];
|
||||
const param = this.#getParamValue(paramKey);
|
||||
return param && tryDecodeURIComponent(param);
|
||||
}
|
||||
#getAllDecodedParams() {
|
||||
const decoded = {};
|
||||
const keys = Object.keys(this.#matchResult[0][this.routeIndex]?.[1] ?? {});
|
||||
for (const key of keys) {
|
||||
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
||||
if (value !== void 0) decoded[key] = tryDecodeURIComponent(value);
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
#getParamValue(paramKey) {
|
||||
return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
|
||||
}
|
||||
query(key) {
|
||||
return getQueryParam(this.url, key);
|
||||
}
|
||||
queries(key) {
|
||||
return getQueryParams(this.url, key);
|
||||
}
|
||||
header(name) {
|
||||
if (name) return this.raw.headers.get(name) ?? void 0;
|
||||
const headerData = Object.create(null);
|
||||
this.raw.headers.forEach((value, key) => {
|
||||
headerData[key] = value;
|
||||
});
|
||||
return headerData;
|
||||
}
|
||||
async parseBody(options) {
|
||||
return parseBody(this, options);
|
||||
}
|
||||
#cachedBody = (key) => {
|
||||
const { bodyCache, raw } = this;
|
||||
const cachedBody = bodyCache[key];
|
||||
if (cachedBody) return cachedBody;
|
||||
for (const anyCachedKey in bodyCache) return bodyCache[anyCachedKey].then((body) => {
|
||||
if (anyCachedKey === "json") body = JSON.stringify(body);
|
||||
const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
|
||||
return new Response(body, { headers: contentType ? { "Content-Type": contentType } : void 0 })[key]();
|
||||
});
|
||||
return bodyCache[key] = raw[key]();
|
||||
};
|
||||
/**
|
||||
* `.json()` can parse Request body of type `application/json`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#json}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.json()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
json() {
|
||||
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
||||
}
|
||||
/**
|
||||
* `.text()` can parse Request body of type `text/plain`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#text}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.text()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
text() {
|
||||
return this.#cachedBody("text");
|
||||
}
|
||||
/**
|
||||
* `.arrayBuffer()` parse Request body as an `ArrayBuffer`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#arraybuffer}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.arrayBuffer()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer() {
|
||||
return this.#cachedBody("arrayBuffer");
|
||||
}
|
||||
/**
|
||||
* `.bytes()` parses the request body as a `Uint8Array`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#bytes}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.bytes()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
bytes() {
|
||||
return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
|
||||
}
|
||||
/**
|
||||
* Parses the request body as a `Blob`.
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.blob();
|
||||
* });
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/request#blob
|
||||
*/
|
||||
blob() {
|
||||
return this.#cachedBody("blob");
|
||||
}
|
||||
/**
|
||||
* Parses the request body as `FormData`.
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.formData();
|
||||
* });
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/request#formdata
|
||||
*/
|
||||
formData() {
|
||||
return this.#cachedBody("formData");
|
||||
}
|
||||
/**
|
||||
* Adds validated data to the request.
|
||||
*
|
||||
* @param target - The target of the validation.
|
||||
* @param data - The validated data to add.
|
||||
*/
|
||||
addValidatedData(target, data) {
|
||||
(this.#validatedData ??= {})[target] = data;
|
||||
}
|
||||
valid(target) {
|
||||
return this.#validatedData?.[target];
|
||||
}
|
||||
/**
|
||||
* `.url` can get the request url strings.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#url}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const url = c.req.url // `http://localhost:8787/about/me`
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get url() {
|
||||
return this.raw.url;
|
||||
}
|
||||
/**
|
||||
* `.method` can get the method name of the request.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#method}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const method = c.req.method // `GET`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get method() {
|
||||
return this.raw.method;
|
||||
}
|
||||
get [GET_MATCH_RESULT]() {
|
||||
return this.#matchResult;
|
||||
}
|
||||
/**
|
||||
* `.matchedRoutes` can return a matched route in the handler
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* Use matchedRoutes helper defined in "hono/route" instead.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#matchedroutes}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async function logger(c, next) {
|
||||
* await next()
|
||||
* c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
|
||||
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
|
||||
* console.log(
|
||||
* method,
|
||||
* ' ',
|
||||
* path,
|
||||
* ' '.repeat(Math.max(10 - path.length, 0)),
|
||||
* name,
|
||||
* i === c.req.routeIndex ? '<- respond from here' : ''
|
||||
* )
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get matchedRoutes() {
|
||||
return this.#matchResult[0].map(([[, route]]) => route);
|
||||
}
|
||||
/**
|
||||
* `.routePath` can retrieve the path registered within the handler
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* Use routePath helper defined in "hono/route" instead.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#routepath}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/posts/:id', (c) => {
|
||||
* return c.json({ path: c.req.routePath })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get routePath() {
|
||||
return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Clones a HonoRequest's underlying raw Request object.
|
||||
*
|
||||
* This utility handles both consumed and unconsumed request bodies:
|
||||
* - If the request body hasn't been consumed, it uses the native `clone()` method
|
||||
* - If the request body has been consumed, it reconstructs a new Request using cached body data
|
||||
*
|
||||
* This is particularly useful when you need to:
|
||||
* - Process the same request body multiple times
|
||||
* - Pass requests to external services after validation
|
||||
*
|
||||
* @param req - The HonoRequest object to clone
|
||||
* @returns A Promise that resolves to a new Request object with the same properties
|
||||
* @throws {HTTPException} If the request body was consumed directly via `req.raw`
|
||||
* without using HonoRequest methods (e.g., `req.json()`, `req.text()`), making it
|
||||
* impossible to reconstruct the body from cache
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Clone after consuming the body (e.g., after validation)
|
||||
* app.post('/forward',
|
||||
* validator('json', (data) => data),
|
||||
* async (c) => {
|
||||
* const validated = c.req.valid('json')
|
||||
* // Body has been consumed, but cloneRawRequest still works
|
||||
* const clonedReq = await cloneRawRequest(c.req)
|
||||
* return fetch('http://backend-service.com', clonedReq)
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
const cloneRawRequest = async (req) => {
|
||||
if (!req.raw.bodyUsed) return req.raw.clone();
|
||||
const cacheKey = Object.keys(req.bodyCache)[0];
|
||||
if (!cacheKey) throw new HTTPException(500, { message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly." });
|
||||
let body = await req[cacheKey]();
|
||||
const headers = req.header();
|
||||
if (cacheKey === "json") {
|
||||
body = JSON.stringify(body);
|
||||
delete headers["content-length"];
|
||||
} else if (body instanceof FormData) {
|
||||
delete headers["content-type"];
|
||||
delete headers["content-length"];
|
||||
}
|
||||
const requestInit = {
|
||||
body,
|
||||
cache: req.raw.cache,
|
||||
credentials: req.raw.credentials,
|
||||
headers,
|
||||
integrity: req.raw.integrity,
|
||||
keepalive: req.raw.keepalive,
|
||||
method: req.method,
|
||||
mode: req.raw.mode,
|
||||
redirect: req.raw.redirect,
|
||||
referrer: req.raw.referrer,
|
||||
referrerPolicy: req.raw.referrerPolicy,
|
||||
signal: req.raw.signal
|
||||
};
|
||||
return new Request(req.url, requestInit);
|
||||
};
|
||||
//#endregion
|
||||
export { HonoRequest, cloneRawRequest };
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
//#region src/request/constants.ts
|
||||
const GET_MATCH_RESULT = Symbol();
|
||||
//#endregion
|
||||
export { GET_MATCH_RESULT };
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
//#region src/router.ts
|
||||
/**
|
||||
* @module
|
||||
* This module provides types definitions and variables for the routers.
|
||||
*/
|
||||
/**
|
||||
* Constant representing all HTTP methods in uppercase.
|
||||
*/
|
||||
const METHOD_NAME_ALL = "ALL";
|
||||
/**
|
||||
* Constant representing all HTTP methods in lowercase.
|
||||
*/
|
||||
const METHOD_NAME_ALL_LOWERCASE = "all";
|
||||
/**
|
||||
* Array of supported HTTP methods.
|
||||
*/
|
||||
const METHODS = [
|
||||
"get",
|
||||
"post",
|
||||
"put",
|
||||
"delete",
|
||||
"options",
|
||||
"patch",
|
||||
"query"
|
||||
];
|
||||
/**
|
||||
* Error message indicating that a route cannot be added because the matcher is already built.
|
||||
*/
|
||||
const MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
||||
/**
|
||||
* Error class representing an unsupported path error.
|
||||
*/
|
||||
var UnsupportedPathError = class extends Error {};
|
||||
//#endregion
|
||||
export { MESSAGE_MATCHER_IS_ALREADY_BUILT, METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE, UnsupportedPathError };
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { RegExpRouter } from "./router.js";
|
||||
import { PreparedRegExpRouter, buildInitParams, serializeInitParams } from "./prepared-router.js";
|
||||
export { PreparedRegExpRouter, RegExpRouter, buildInitParams, serializeInitParams };
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import "../../router.js";
|
||||
//#region src/router/reg-exp-router/matcher.ts
|
||||
const emptyParam = [];
|
||||
function match(method, path) {
|
||||
const matchers = this.buildAllMatchers();
|
||||
const match = ((method, path) => {
|
||||
const matcher = matchers[method] || matchers["ALL"];
|
||||
const staticMatch = matcher[2][path];
|
||||
if (staticMatch) return staticMatch;
|
||||
const match = path.match(matcher[0]);
|
||||
if (!match) return [[], emptyParam];
|
||||
const index = match.indexOf("", 1);
|
||||
return [matcher[1][index], match];
|
||||
});
|
||||
this.match = match;
|
||||
return match(method, path);
|
||||
}
|
||||
//#endregion
|
||||
export { emptyParam, match };
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
import { createNullObject } from "../utils.js";
|
||||
//#region src/router/reg-exp-router/node.ts
|
||||
const LABEL_REG_EXP_STR = "[^/]+";
|
||||
const ONLY_WILDCARD_REG_EXP_STR = ".*";
|
||||
const TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
|
||||
const PATH_ERROR = Symbol();
|
||||
const regExpMetaChars = /* @__PURE__ */ new Set(".\\+*[^]$()");
|
||||
/**
|
||||
* Sort order:
|
||||
* 1. literal
|
||||
* 2. special pattern (e.g. :label{[0-9]+})
|
||||
* 3. common label pattern (e.g. :label)
|
||||
* 4. wildcard
|
||||
*/
|
||||
function compareKey(a, b) {
|
||||
if (a.length === 1) return b.length === 1 ? a < b ? -1 : 1 : -1;
|
||||
if (b.length === 1) return 1;
|
||||
if (a === ".*" || a === "(?:|/.*)") return b === "(?:|/.*)" ? -1 : 1;
|
||||
else if (b === ".*" || b === "(?:|/.*)") return -1;
|
||||
if (a === "[^/]+") return 1;
|
||||
else if (b === "[^/]+") return -1;
|
||||
return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
|
||||
}
|
||||
var Node = class Node {
|
||||
#index;
|
||||
#varIndex;
|
||||
#children = createNullObject();
|
||||
insert(tokens, index, paramMap, context, isStatic) {
|
||||
let node = this;
|
||||
for (let i = 0, len = tokens.length; i < len; i++) {
|
||||
const token = tokens[i];
|
||||
const pattern = token.length === 1 ? token === "*" ? i === len - 1 ? [
|
||||
"",
|
||||
"",
|
||||
".*"
|
||||
] : [
|
||||
"",
|
||||
"",
|
||||
LABEL_REG_EXP_STR
|
||||
] : null : token === "/*" ? [
|
||||
"",
|
||||
"",
|
||||
TAIL_WILDCARD_REG_EXP_STR
|
||||
] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
||||
let nextNode;
|
||||
if (pattern) {
|
||||
const name = pattern[1];
|
||||
let regexpStr = pattern[2] || "[^/]+";
|
||||
if (name && pattern[2]) {
|
||||
if (regexpStr === ".*") throw PATH_ERROR;
|
||||
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
||||
if (/\((?!\?:)/.test(regexpStr)) throw PATH_ERROR;
|
||||
if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) throw PATH_ERROR;
|
||||
}
|
||||
nextNode = node.#children[regexpStr];
|
||||
if (!nextNode) {
|
||||
if (regexpStr !== ".*" && regexpStr !== "(?:|/.*)") {
|
||||
for (const k in node.#children) if ((regexpStr.length > 1 || k.length > 1) && k !== ".*" && k !== "(?:|/.*)") throw PATH_ERROR;
|
||||
}
|
||||
nextNode = node.#children[regexpStr] = new Node();
|
||||
}
|
||||
if (name !== "") {
|
||||
nextNode.#varIndex ??= context.varIndex++;
|
||||
paramMap.push([name, nextNode.#varIndex]);
|
||||
}
|
||||
} else {
|
||||
nextNode = node.#children[token];
|
||||
if (!nextNode) {
|
||||
for (const k in node.#children) if (k.length > 1 && k !== ".*" && k !== "(?:|/.*)") throw PATH_ERROR;
|
||||
nextNode = node.#children[token] = new Node();
|
||||
}
|
||||
}
|
||||
node = nextNode;
|
||||
}
|
||||
if (node.#index !== void 0) throw PATH_ERROR;
|
||||
node.#index = isStatic ? -1 : index;
|
||||
}
|
||||
buildRegExpStr() {
|
||||
const strList = Object.keys(this.#children).sort(compareKey).map((k) => {
|
||||
const c = this.#children[k];
|
||||
const childStr = c.buildRegExpStr();
|
||||
return childStr === "" ? "" : (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + childStr;
|
||||
}).filter(Boolean);
|
||||
if (typeof this.#index === "number" && this.#index !== -1) strList.unshift(`#${this.#index}`);
|
||||
if (strList.length === 0) return "";
|
||||
if (strList.length === 1) return strList[0];
|
||||
return "(?:" + strList.join("|") + ")";
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { LABEL_REG_EXP_STR, Node, ONLY_WILDCARD_REG_EXP_STR, PATH_ERROR, TAIL_WILDCARD_REG_EXP_STR };
|
||||
Generated
Vendored
+94
@@ -0,0 +1,94 @@
|
||||
import "../../router.js";
|
||||
import { emptyParam, match } from "./matcher.js";
|
||||
import { RegExpRouter } from "./router.js";
|
||||
//#region src/router/reg-exp-router/prepared-router.ts
|
||||
var PreparedRegExpRouter = class {
|
||||
name = "PreparedRegExpRouter";
|
||||
#matchers;
|
||||
#relocateMap;
|
||||
constructor(matchers, relocateMap) {
|
||||
this.#matchers = matchers;
|
||||
this.#relocateMap = relocateMap;
|
||||
}
|
||||
#addWildcard(method, handlerData) {
|
||||
const matcher = this.#matchers[method];
|
||||
matcher[1].forEach((list) => list && list.push(handlerData));
|
||||
Object.values(matcher[2]).forEach((list) => list[0].push(handlerData));
|
||||
}
|
||||
#addPath(method, path, handler, indexes, map) {
|
||||
const matcher = this.#matchers[method];
|
||||
if (!map) matcher[2][path][0].push([handler, {}]);
|
||||
else indexes.forEach((index) => {
|
||||
if (typeof index === "number") matcher[1][index].push([handler, map]);
|
||||
else matcher[2][index || path][0].push([handler, map]);
|
||||
});
|
||||
}
|
||||
add(method, path, handler) {
|
||||
if (!this.#matchers[method]) {
|
||||
const all = this.#matchers["ALL"];
|
||||
const staticMap = {};
|
||||
for (const key in all[2]) staticMap[key] = [all[2][key][0].slice(), emptyParam];
|
||||
this.#matchers[method] = [
|
||||
all[0],
|
||||
all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
|
||||
staticMap
|
||||
];
|
||||
}
|
||||
if (path === "/*" || path === "*") {
|
||||
const handlerData = [handler, {}];
|
||||
if (method === "ALL") for (const m in this.#matchers) this.#addWildcard(m, handlerData);
|
||||
else this.#addWildcard(method, handlerData);
|
||||
return;
|
||||
}
|
||||
const data = this.#relocateMap[path];
|
||||
if (!data) throw new Error(`Path ${path} is not registered`);
|
||||
for (const [indexes, map] of data) if (method === "ALL") for (const m in this.#matchers) this.#addPath(m, path, handler, indexes, map);
|
||||
else this.#addPath(method, path, handler, indexes, map);
|
||||
}
|
||||
buildAllMatchers() {
|
||||
return this.#matchers;
|
||||
}
|
||||
match = match;
|
||||
};
|
||||
const buildInitParams = ({ paths }) => {
|
||||
const RegExpRouterWithMatcherExport = class extends RegExpRouter {
|
||||
buildAndExportAllMatchers() {
|
||||
return this.buildAllMatchers();
|
||||
}
|
||||
};
|
||||
const router = new RegExpRouterWithMatcherExport();
|
||||
for (const path of paths) router.add("ALL", path, path);
|
||||
const matchers = router.buildAndExportAllMatchers();
|
||||
const all = matchers["ALL"];
|
||||
const relocateMap = {};
|
||||
for (const path of paths) {
|
||||
if (path === "/*" || path === "*") continue;
|
||||
all[1].forEach((list, i) => {
|
||||
list.forEach(([p, map]) => {
|
||||
if (p === path) {
|
||||
if (relocateMap[path]) relocateMap[path][0][1] = {
|
||||
...relocateMap[path][0][1],
|
||||
...map
|
||||
};
|
||||
else relocateMap[path] = [[[], map]];
|
||||
if (relocateMap[path][0][0].findIndex((j) => j === i) === -1) relocateMap[path][0][0].push(i);
|
||||
}
|
||||
});
|
||||
});
|
||||
for (const path2 in all[2]) all[2][path2][0].forEach(([p]) => {
|
||||
if (p === path) {
|
||||
relocateMap[path] ||= [[[]]];
|
||||
const value = path2 === path ? "" : path2;
|
||||
if (relocateMap[path][0][0].findIndex((v) => v === value) === -1) relocateMap[path][0][0].push(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = all[1].length; i < len; i++) all[1][i] = all[1][i] ? [] : 0;
|
||||
for (const path in all[2]) all[2][path][0] = [];
|
||||
return [matchers, relocateMap];
|
||||
};
|
||||
const serializeInitParams = ([matchers, relocateMap]) => {
|
||||
return `[${JSON.stringify(matchers, (_, value) => value instanceof RegExp ? `##${value.toString()}##` : value).replace(/"##(.+?)##"/g, (_, str) => str.replace(/\\\\/g, "\\"))},${JSON.stringify(relocateMap)}]`;
|
||||
};
|
||||
//#endregion
|
||||
export { PreparedRegExpRouter, buildInitParams, serializeInitParams };
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
import { checkOptionalParameter } from "../../utils/url.js";
|
||||
import { MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError } from "../../router.js";
|
||||
import { createNullObject } from "../utils.js";
|
||||
import { emptyParam, match } from "./matcher.js";
|
||||
import { LABEL_REG_EXP_STR, PATH_ERROR, TAIL_WILDCARD_REG_EXP_STR } from "./node.js";
|
||||
import { Trie } from "./trie.js";
|
||||
//#region src/router/reg-exp-router/router.ts
|
||||
let wildcardRegExpCache = createNullObject();
|
||||
function buildWildcardRegExp(path) {
|
||||
return wildcardRegExpCache[path] ??= new RegExp(`^${path.replace(/\/:[^/{}]+(?:\{\[\^\/]\+})?(?=[/{]|$)|\/?\*$|([.\\+*[^\]$()?{}|])/g, (match, metaChar) => metaChar ? `\\${metaChar}` : match === "/*" ? TAIL_WILDCARD_REG_EXP_STR : match === "*" ? ".*" : `/:${LABEL_REG_EXP_STR}`)}$`);
|
||||
}
|
||||
function findMiddleware(middleware, path) {
|
||||
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) if (buildWildcardRegExp(k).test(path)) return [...middleware[k]];
|
||||
}
|
||||
var RegExpRouter = class {
|
||||
name = "RegExpRouter";
|
||||
#middleware;
|
||||
#routes;
|
||||
#tries;
|
||||
constructor() {
|
||||
this.#middleware = { ["ALL"]: createNullObject() };
|
||||
this.#routes = { ["ALL"]: createNullObject() };
|
||||
this.#tries = { ["ALL"]: new Trie() };
|
||||
}
|
||||
#insertPath(method, path) {
|
||||
try {
|
||||
this.#tries[method].insert(path, !/\*|\/:/.test(path));
|
||||
} catch (e) {
|
||||
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
|
||||
}
|
||||
}
|
||||
add(method, path, handler) {
|
||||
const middleware = this.#middleware;
|
||||
const routes = this.#routes;
|
||||
if (!middleware) throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
||||
if (!middleware[method]) {
|
||||
this.#tries[method] = new Trie();
|
||||
for (const handlerMap of [middleware, routes]) {
|
||||
handlerMap[method] = createNullObject();
|
||||
for (const p in handlerMap["ALL"]) {
|
||||
handlerMap[method][p] = [...handlerMap["ALL"][p]];
|
||||
this.#insertPath(method, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (path === "/*") path = "*";
|
||||
const methods = method === "ALL" ? Object.keys(middleware) : [method];
|
||||
if (/\*$/.test(path)) {
|
||||
const re = buildWildcardRegExp(path);
|
||||
for (const m of methods) if (!middleware[m][path]) {
|
||||
this.#insertPath(m, path);
|
||||
middleware[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware["ALL"], path) || [];
|
||||
}
|
||||
for (const handlerMap of [middleware, routes]) for (const m of methods) for (const p in handlerMap[m]) re.test(p) && handlerMap[m][p].push([handler, path]);
|
||||
return;
|
||||
}
|
||||
const paths = checkOptionalParameter(path) || [path];
|
||||
for (const path of paths) for (const m of methods) {
|
||||
if (!routes[m][path]) {
|
||||
this.#insertPath(m, path);
|
||||
routes[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware["ALL"], path) || [];
|
||||
}
|
||||
routes[m][path].push([handler, path]);
|
||||
}
|
||||
}
|
||||
match = match;
|
||||
buildAllMatchers() {
|
||||
const matchers = createNullObject();
|
||||
for (const method of Object.keys(this.#routes)) matchers[method] = this.#buildMatcher(method);
|
||||
this.#middleware = this.#routes = this.#tries = void 0;
|
||||
wildcardRegExpCache = createNullObject();
|
||||
return matchers;
|
||||
}
|
||||
#buildMatcher(method) {
|
||||
const middleware = this.#middleware[method];
|
||||
const routes = this.#routes[method];
|
||||
const trie = this.#tries[method];
|
||||
const staticMap = createNullObject();
|
||||
const handlerData = [];
|
||||
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
||||
for (const r of [middleware, routes]) for (const path in r) {
|
||||
const handlers = r[path];
|
||||
const pathData = trie.paths[path];
|
||||
if (!pathData) {
|
||||
staticMap[path] = [handlers.map(([h]) => [h, createNullObject()]), emptyParam];
|
||||
continue;
|
||||
}
|
||||
handlerData[pathData[0]] = handlers.map(([h, handlerPath]) => [h, trie.paths[handlerPath][1].reduceRight((map, [key], i) => {
|
||||
map[key] = paramReplacementMap[pathData[1][i][1]];
|
||||
return map;
|
||||
}, createNullObject())]);
|
||||
}
|
||||
return [
|
||||
regexp,
|
||||
indexReplacementMap.map((i) => handlerData[i]),
|
||||
staticMap
|
||||
];
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { RegExpRouter };
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
import { createNullObject } from "../utils.js";
|
||||
import { Node } from "./node.js";
|
||||
//#region src/router/reg-exp-router/trie.ts
|
||||
var Trie = class {
|
||||
#context = { varIndex: 0 };
|
||||
#root = new Node();
|
||||
#index = 0;
|
||||
paths = createNullObject();
|
||||
insert(path, isStatic) {
|
||||
if (isStatic) {
|
||||
this.#root.insert(path.split(""), 0, [], this.#context, true);
|
||||
return;
|
||||
}
|
||||
const paramAssoc = [];
|
||||
const groups = [];
|
||||
let markedPath = path;
|
||||
for (let i = 0;;) {
|
||||
let replaced = false;
|
||||
markedPath = markedPath.replace(/\{[^}]+\}/g, (m) => {
|
||||
const mark = `@\\${i}`;
|
||||
groups[i] = [mark, m];
|
||||
i++;
|
||||
replaced = true;
|
||||
return mark;
|
||||
});
|
||||
if (!replaced) break;
|
||||
}
|
||||
/**
|
||||
* - pattern (:label, :label{0-9]+}, ...)
|
||||
* - /* wildcard
|
||||
* - character
|
||||
*/
|
||||
const tokens = markedPath.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
|
||||
for (let i = groups.length - 1; i >= 0; i--) {
|
||||
const [mark] = groups[i];
|
||||
for (let j = tokens.length - 1; j >= 0; j--) if (tokens[j].indexOf(mark) !== -1) {
|
||||
tokens[j] = tokens[j].replace(mark, groups[i][1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.#root.insert(tokens, this.#index, paramAssoc, this.#context, false);
|
||||
this.paths[path] = [this.#index++, paramAssoc];
|
||||
}
|
||||
buildRegExp() {
|
||||
let regexp = this.#root.buildRegExpStr();
|
||||
if (regexp === "") return [
|
||||
/^$/,
|
||||
[],
|
||||
[]
|
||||
];
|
||||
let captureIndex = 0;
|
||||
const indexReplacementMap = [];
|
||||
const paramReplacementMap = [];
|
||||
regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
|
||||
if (handlerIndex !== void 0) {
|
||||
indexReplacementMap[++captureIndex] = Number(handlerIndex);
|
||||
return "$()";
|
||||
}
|
||||
if (paramIndex !== void 0) {
|
||||
paramReplacementMap[Number(paramIndex)] = ++captureIndex;
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
});
|
||||
return [
|
||||
new RegExp(`^${regexp}`),
|
||||
indexReplacementMap,
|
||||
paramReplacementMap
|
||||
];
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { Trie };
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError } from "../../router.js";
|
||||
//#region src/router/smart-router/router.ts
|
||||
var SmartRouter = class {
|
||||
name = "SmartRouter";
|
||||
#routers = [];
|
||||
#routes = [];
|
||||
constructor(init) {
|
||||
this.#routers = init.routers;
|
||||
}
|
||||
add(method, path, handler) {
|
||||
if (!this.#routes) throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
||||
this.#routes.push([
|
||||
method,
|
||||
path,
|
||||
handler
|
||||
]);
|
||||
}
|
||||
match(method, path) {
|
||||
if (!this.#routes) throw new Error("Fatal error");
|
||||
const routers = this.#routers;
|
||||
const routes = this.#routes;
|
||||
const len = routers.length;
|
||||
let i = 0;
|
||||
let res;
|
||||
for (; i < len; i++) {
|
||||
const router = routers[i];
|
||||
try {
|
||||
for (let i = 0, len = routes.length; i < len; i++) router.add(...routes[i]);
|
||||
res = router.match(method, path);
|
||||
} catch (e) {
|
||||
if (e instanceof UnsupportedPathError) continue;
|
||||
throw e;
|
||||
}
|
||||
this.match = router.match.bind(router);
|
||||
this.#routers = [router];
|
||||
this.#routes = void 0;
|
||||
break;
|
||||
}
|
||||
if (i === len) throw new Error("Fatal error");
|
||||
this.name = `SmartRouter + ${this.activeRouter.name}`;
|
||||
return res;
|
||||
}
|
||||
get activeRouter() {
|
||||
if (this.#routes || this.#routers.length !== 1) throw new Error("No active router has been determined yet.");
|
||||
return this.#routers[0];
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { SmartRouter };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { TrieRouter } from "./router.js";
|
||||
export { TrieRouter };
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
import { getPattern, splitPath, splitRoutingPath } from "../../utils/url.js";
|
||||
import "../../router.js";
|
||||
import { createNullObject } from "../utils.js";
|
||||
//#region src/router/trie-router/node.ts
|
||||
const emptyParams = createNullObject();
|
||||
let order = 0;
|
||||
var Node = class Node {
|
||||
#methods = [];
|
||||
#children = createNullObject();
|
||||
#patterns = [];
|
||||
#pattern;
|
||||
#params = emptyParams;
|
||||
insert(method, path, handler) {
|
||||
let curNode = this;
|
||||
const parts = splitRoutingPath(path);
|
||||
const possibleKeys = /* @__PURE__ */ new Set();
|
||||
let i = 0;
|
||||
for (const p of parts) {
|
||||
const nextP = parts[++i];
|
||||
const pattern = getPattern(p, nextP) || (nextP === void 0 && p && p.indexOf("*") === p.length - 1 ? p : null);
|
||||
const isParam = Array.isArray(pattern);
|
||||
const key = isParam ? pattern[0] : pattern || p;
|
||||
const child = curNode.#children[key] ||= new Node();
|
||||
if (pattern && !child.#pattern) {
|
||||
child.#pattern = pattern;
|
||||
curNode.#patterns.push(child);
|
||||
}
|
||||
curNode = child;
|
||||
if (isParam) possibleKeys.add(pattern[1]);
|
||||
}
|
||||
curNode.#methods.push({ [method]: {
|
||||
handler,
|
||||
possibleKeys: [...possibleKeys],
|
||||
score: ++order
|
||||
} });
|
||||
}
|
||||
#pushHandlerSets(handlerSets, node, method, nodeParams, params) {
|
||||
for (let i = 0, len = node.#methods.length; i < len; i++) {
|
||||
const m = node.#methods[i];
|
||||
const handlerSet = m[method] || m["ALL"];
|
||||
if (handlerSet) {
|
||||
handlerSet.params = createNullObject();
|
||||
handlerSets.push(handlerSet);
|
||||
for (let i = 0, len = handlerSet.possibleKeys.length; i < len; i++) {
|
||||
const key = handlerSet.possibleKeys[i];
|
||||
handlerSet.params[key] = params?.[key] && !i ? params[key] : nodeParams[key] ?? params?.[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
search(method, path) {
|
||||
const handlerSets = [];
|
||||
this.#params = emptyParams;
|
||||
let curNodes = [this];
|
||||
const parts = splitPath(path);
|
||||
const curNodesQueue = [];
|
||||
const len = parts.length;
|
||||
let partOffsets = null;
|
||||
for (let i = 0; i < len; i++) {
|
||||
const part = parts[i];
|
||||
const isLast = i === len - 1;
|
||||
const tempNodes = [];
|
||||
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
||||
const node = curNodes[j];
|
||||
const nextNode = node.#children[part];
|
||||
if (nextNode) {
|
||||
nextNode.#params = node.#params;
|
||||
if (isLast) {
|
||||
if (nextNode.#children["*"]) this.#pushHandlerSets(handlerSets, nextNode.#children["*"], method, node.#params);
|
||||
this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);
|
||||
} else tempNodes.push(nextNode);
|
||||
}
|
||||
for (const child of node.#patterns) {
|
||||
const pattern = child.#pattern;
|
||||
const params = node.#params === emptyParams ? {} : { ...node.#params };
|
||||
if (typeof pattern === "string") {
|
||||
if (pattern === "*" || part.startsWith(pattern.slice(0, -1))) {
|
||||
this.#pushHandlerSets(handlerSets, child, method, node.#params);
|
||||
if (pattern === "*") {
|
||||
child.#params = params;
|
||||
tempNodes.push(child);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const [, name, matcher] = pattern;
|
||||
if (!part && matcher === true) continue;
|
||||
if (matcher !== true) {
|
||||
if (!partOffsets) {
|
||||
partOffsets = [];
|
||||
let offset = path[0] === "/" ? 1 : 0;
|
||||
for (let p = 0; p < len; p++) {
|
||||
partOffsets[p] = offset;
|
||||
offset += parts[p].length + 1;
|
||||
}
|
||||
}
|
||||
const restPathString = path.slice(partOffsets[i]);
|
||||
const m = matcher.exec(restPathString);
|
||||
if (m) {
|
||||
params[name] = m[0];
|
||||
this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
|
||||
if (m[0].length === restPathString.length && child.#children["*"]) this.#pushHandlerSets(handlerSets, child.#children["*"], method, node.#params, params);
|
||||
for (const _ in child.#children) {
|
||||
child.#params = params;
|
||||
const componentCount = m[0].match(/\//g)?.length ?? 0;
|
||||
(curNodesQueue[componentCount] ||= []).push(child);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (matcher === true || matcher.test(part)) {
|
||||
params[name] = part;
|
||||
if (isLast) {
|
||||
this.#pushHandlerSets(handlerSets, child, method, params, node.#params);
|
||||
if (child.#children["*"]) this.#pushHandlerSets(handlerSets, child.#children["*"], method, params, node.#params);
|
||||
} else {
|
||||
child.#params = params;
|
||||
tempNodes.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const shifted = curNodesQueue.shift();
|
||||
curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
|
||||
}
|
||||
if (handlerSets[1]) handlerSets.sort((a, b) => {
|
||||
return a.score - b.score;
|
||||
});
|
||||
return [handlerSets.map(({ handler, params }) => [handler, params])];
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { Node };
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { checkOptionalParameter } from "../../utils/url.js";
|
||||
import { Node } from "./node.js";
|
||||
//#region src/router/trie-router/router.ts
|
||||
var TrieRouter = class {
|
||||
name = "TrieRouter";
|
||||
#node = new Node();
|
||||
add(method, path, handler) {
|
||||
for (const result of checkOptionalParameter(path) || [path]) this.#node.insert(method, result, handler);
|
||||
}
|
||||
match(method, path) {
|
||||
return this.#node.search(method, path);
|
||||
}
|
||||
};
|
||||
//#endregion
|
||||
export { TrieRouter };
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
//#region src/router/utils.ts
|
||||
const createNullObject = () => Object.create(null);
|
||||
//#endregion
|
||||
export { createNullObject };
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
import { METHODS, METHOD_NAME_ALL_LOWERCASE } from "../router.js";
|
||||
import { HonoBase as Hono } from "../hono-base.js";
|
||||
import { StatusCode, SuccessStatusCode } from "../utils/http-status.js";
|
||||
import { HasRequiredKeys } from "../utils/types.js";
|
||||
import { Endpoint, ExtractSchema, KnownResponseFormat, ResponseFormat, Schema } from "../types.js";
|
||||
import { Hono as Hono$1 } from "../hono.js";
|
||||
//#region src/client/types.d.ts
|
||||
/**
|
||||
* Type representing the '$all' method name
|
||||
*/
|
||||
type MethodNameAll = `$${typeof METHOD_NAME_ALL_LOWERCASE}`;
|
||||
/**
|
||||
* Type representing all standard HTTP methods prefixed with '$'
|
||||
* e.g., '$get' | '$post' | '$put' | '$delete' | '$options' | '$patch' | '$query'
|
||||
*/
|
||||
type StandardMethods = `$${(typeof METHODS)[number]}`;
|
||||
/**
|
||||
* Expands '$all' into all standard HTTP methods.
|
||||
* If the schema contains '$all', it creates a type where all standard HTTP methods
|
||||
* point to the same endpoint definition as '$all', while removing '$all' itself.
|
||||
*/
|
||||
type ExpandAllMethod<S> = MethodNameAll extends keyof S ? { [M in StandardMethods]: S[MethodNameAll]; } & Omit<S, MethodNameAll> : S;
|
||||
type HonoRequest = (typeof Hono$1.prototype)['request'];
|
||||
export type BuildSearchParamsFn = (query: Record<string, string | string[]>) => URLSearchParams;
|
||||
export type ClientRequestOptions<T = unknown> = {
|
||||
fetch?: typeof fetch | HonoRequest;
|
||||
webSocket?: (...args: ConstructorParameters<typeof WebSocket>) => WebSocket;
|
||||
/**
|
||||
* Standard `RequestInit`, caution that this take highest priority
|
||||
* and could be used to overwrite things that Hono sets for you, like `body | method | headers`.
|
||||
*
|
||||
* If you want to add some headers, use in `headers` instead of `init`
|
||||
*/
|
||||
init?: RequestInit;
|
||||
/**
|
||||
* Custom function to serialize query parameters into URLSearchParams.
|
||||
* By default, arrays are serialized as multiple parameters with the same key (e.g., `key=a&key=b`).
|
||||
* You can provide a custom function to change this behavior, for example to use bracket notation (e.g., `key[]=a&key[]=b`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const client = hc('http://localhost', {
|
||||
* buildSearchParams: (query) => {
|
||||
* return new URLSearchParams(qs.stringify(query))
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
buildSearchParams?: BuildSearchParamsFn;
|
||||
} & (keyof T extends never ? {
|
||||
headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
||||
} : {
|
||||
headers: T | (() => T | Promise<T>);
|
||||
});
|
||||
export type ClientRequest<Prefix extends string, Path extends string, S extends Schema> = { [M in keyof ExpandAllMethod<S>]: ExpandAllMethod<S>[M] extends Endpoint & {
|
||||
input: infer R;
|
||||
} ? R extends object ? HasRequiredKeys<R> extends true ? (args: R, options?: ClientRequestOptions) => Promise<ClientResponseOfEndpoint<ExpandAllMethod<S>[M]>> : (args?: R, options?: ClientRequestOptions) => Promise<ClientResponseOfEndpoint<ExpandAllMethod<S>[M]>> : never : never; } & {
|
||||
$url: <const Arg extends (S[keyof S] extends {
|
||||
input: infer R;
|
||||
} ? R extends {
|
||||
param: infer P;
|
||||
} ? R extends {
|
||||
query: infer Q;
|
||||
} ? {
|
||||
param: P;
|
||||
query: Q;
|
||||
} : {
|
||||
param: P;
|
||||
} : R extends {
|
||||
query: infer Q;
|
||||
} ? {
|
||||
query: Q;
|
||||
} : {} : {}) | undefined = undefined>(arg?: Arg) => HonoURL<Prefix, Path, Arg>;
|
||||
$path: <const Arg extends (S[keyof S] extends {
|
||||
input: infer R;
|
||||
} ? R extends {
|
||||
param: infer P;
|
||||
} ? R extends {
|
||||
query: infer Q;
|
||||
} ? {
|
||||
param: P;
|
||||
query: Q;
|
||||
} : {
|
||||
param: P;
|
||||
} : R extends {
|
||||
query: infer Q;
|
||||
} ? {
|
||||
query: Q;
|
||||
} : {} : {}) | undefined = undefined>(arg?: Arg) => BuildPath<Path, Arg>;
|
||||
} & (S['$get'] extends {
|
||||
outputFormat: 'ws';
|
||||
} ? S['$get'] extends {
|
||||
input: infer I;
|
||||
} ? {
|
||||
$ws: (args?: I) => WebSocket;
|
||||
} : {} : {});
|
||||
type ClientResponseOfEndpoint<T extends Endpoint = Endpoint> = T extends {
|
||||
output: infer O;
|
||||
outputFormat: infer F;
|
||||
status: infer S;
|
||||
} ? ClientResponse<O, S extends number ? S : never, F extends ResponseFormat ? F : never> : never;
|
||||
export interface ClientResponse<T, U extends number = StatusCode, F extends ResponseFormat = ResponseFormat> {
|
||||
readonly body: ReadableStream | null;
|
||||
readonly bodyUsed: boolean;
|
||||
ok: U extends SuccessStatusCode ? true : U extends Exclude<StatusCode, SuccessStatusCode> ? false : boolean;
|
||||
redirected: boolean;
|
||||
status: U;
|
||||
statusText: string;
|
||||
type: 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';
|
||||
headers: Headers;
|
||||
url: string;
|
||||
redirect(url: string, status: number): Response;
|
||||
clone(): Response;
|
||||
bytes(): Promise<Uint8Array<ArrayBuffer>>;
|
||||
json(): F extends 'text' ? Promise<never> : F extends 'json' ? Promise<T> : Promise<unknown>;
|
||||
text(): F extends 'text' ? (T extends string ? Promise<T> : Promise<never>) : Promise<string>;
|
||||
blob(): Promise<Blob>;
|
||||
formData(): Promise<FormData>;
|
||||
arrayBuffer(): Promise<ArrayBuffer>;
|
||||
}
|
||||
type BuildSearch<Arg, Key extends 'query'> = Arg extends { [K in Key]: infer Query; } ? IsEmptyObject<Query> extends true ? '' : `?${string}` : '';
|
||||
type BuildPathname<P extends string, Arg> = Arg extends {
|
||||
param: infer Param;
|
||||
} ? `${ApplyParam<TrimStartSlash<P>, Param>}` : `/${TrimStartSlash<P>}`;
|
||||
type BuildPath<P extends string, Arg> = `${BuildPathname<P, Arg>}${BuildSearch<Arg, 'query'>}`;
|
||||
type BuildTypedURL<Protocol extends string, Host extends string, Port extends string, P extends string, Arg> = TypedURL<`${Protocol}:`, Host, Port, BuildPathname<P, Arg>, BuildSearch<Arg, 'query'>>;
|
||||
type HonoURL<Prefix extends string, Path extends string, Arg> = IsLiteral<Prefix> extends true ? TrimEndSlash<Prefix> extends `${infer Protocol}://${infer Rest}` ? Rest extends `${infer Hostname}/${infer P}` ? ParseHostName<Hostname> extends [infer Host extends string, infer Port extends string] ? BuildTypedURL<Protocol, Host, Port, P, Arg> : never : ParseHostName<Rest> extends [infer Host extends string, infer Port extends string] ? BuildTypedURL<Protocol, Host, Port, Path, Arg> : never : URL : URL;
|
||||
type ParseHostName<T extends string> = T extends `${infer Host}:${infer Port}` ? [Host, Port] : [T, ''];
|
||||
type TrimStartSlash<T extends string> = T extends `/${infer R}` ? TrimStartSlash<R> : T;
|
||||
type TrimEndSlash<T extends string> = T extends `${infer R}/` ? TrimEndSlash<R> : T;
|
||||
type IsLiteral<T extends string> = [T] extends [never] ? false : string extends T ? false : true;
|
||||
type ApplyParam<Path extends string, P, Result extends string = ''> = Path extends `${infer Head}/${infer Rest}` ? Head extends `:${infer Param}` ? P extends Record<Param, infer Value extends string> ? IsLiteral<Value> extends true ? ApplyParam<Rest, P, `${Result}/${Value & string}`> : ApplyParam<Rest, P, `${Result}/${Head}`> : ApplyParam<Rest, P, `${Result}/${Head}`> : ApplyParam<Rest, P, `${Result}/${Head}`> : Path extends `:${infer Param}` ? P extends Record<Param, infer Value extends string> ? IsLiteral<Value> extends true ? `${Result}/${Value & string}` : `${Result}/${Path}` : `${Result}/${Path}` : `${Result}/${Path}`;
|
||||
type IsEmptyObject<T> = keyof T extends never ? true : false;
|
||||
export interface TypedURL<Protocol extends string, Hostname extends string, Port extends string, Pathname extends string, Search extends string> extends URL {
|
||||
protocol: Protocol;
|
||||
hostname: Hostname;
|
||||
port: Port;
|
||||
host: Port extends '' ? Hostname : `${Hostname}:${Port}`;
|
||||
origin: `${Protocol}//${Hostname}${Port extends '' ? '' : `:${Port}`}`;
|
||||
pathname: Pathname;
|
||||
search: Search;
|
||||
href: `${Protocol}//${Hostname}${Port extends '' ? '' : `:${Port}`}${Pathname}${Search}`;
|
||||
}
|
||||
export interface Response extends ClientResponse<unknown> {}
|
||||
export type Fetch<T> = (args?: InferRequestType<T>, opt?: ClientRequestOptions) => Promise<ClientResponseOfEndpoint<InferEndpointType<T>>>;
|
||||
type InferEndpointType<T> = T extends ((args: infer R, options: any | undefined) => Promise<infer U>) ? U extends ClientResponse<infer O, infer S, infer F> ? {
|
||||
input: NonNullable<R>;
|
||||
output: O;
|
||||
outputFormat: F;
|
||||
status: S;
|
||||
} extends Endpoint ? {
|
||||
input: NonNullable<R>;
|
||||
output: O;
|
||||
outputFormat: F;
|
||||
status: S;
|
||||
} : never : never : never;
|
||||
export type InferResponseType<T, U extends StatusCode = StatusCode> = InferResponseTypeFromEndpoint<InferEndpointType<T>, U>;
|
||||
type InferResponseTypeFromEndpoint<T extends Endpoint, U extends StatusCode> = T extends {
|
||||
output: infer O;
|
||||
status: infer S;
|
||||
} ? S extends U ? O : never : never;
|
||||
export type InferRequestType<T> = T extends ((args: infer R, options: any | undefined) => Promise<ClientResponse<unknown>>) ? NonNullable<R> : never;
|
||||
export type InferRequestOptionsType<T> = T extends ((args: any, options: infer R) => Promise<ClientResponse<unknown>>) ? NonNullable<R> : never;
|
||||
/**
|
||||
* Filter a ClientResponse type so it only includes responses of specific status codes.
|
||||
*/
|
||||
export type FilterClientResponseByStatusCode<T extends ClientResponse<any, any, any>, U extends number = StatusCode> = T extends ClientResponse<infer RT, infer RC, infer RF> ? RC extends U ? ClientResponse<RT, RC, RF> : never : never;
|
||||
type PathToChain<Prefix extends string, Path extends string, E extends Schema, Original extends string = Path> = Path extends `/${infer P}` ? PathToChain<Prefix, P, E, Path> : Path extends `${infer P}/${infer R}` ? { [K in P]: PathToChain<Prefix, R, E, Original>; } : { [K in Path extends '' ? 'index' : Path]: ClientRequest<Prefix, Original, E extends Record<string, unknown> ? E[Original] : never>; };
|
||||
export type Client<T, Prefix extends string> = T extends Hono<any, infer S, any> ? S extends Record<infer K, Schema> ? K extends string ? PathToChain<Prefix, K, S> : never : never : never;
|
||||
export type Callback = (opts: CallbackOptions) => unknown;
|
||||
interface CallbackOptions {
|
||||
path: string[];
|
||||
args: any[];
|
||||
}
|
||||
export type ObjectType<T = unknown> = {
|
||||
[key: string]: T;
|
||||
};
|
||||
type GlobalResponseDefinition = { [S in StatusCode]?: { [F in KnownResponseFormat]?: unknown; }; };
|
||||
type ToEndpoints<Def extends GlobalResponseDefinition, R> = { [S in keyof Def & StatusCode]: { [F in keyof Def[S] & KnownResponseFormat]: Omit<R, 'output' | 'status' | 'outputFormat'> & {
|
||||
output: Def[S][F];
|
||||
status: S;
|
||||
outputFormat: F;
|
||||
}; }[keyof Def[S] & KnownResponseFormat]; }[keyof Def & StatusCode];
|
||||
type ModRoute<R, Def extends GlobalResponseDefinition> = R extends Endpoint ? R | ToEndpoints<Def, R> : R;
|
||||
type ModSchema<D, Def extends GlobalResponseDefinition> = { [K in keyof D]: { [M in keyof D[K]]: ModRoute<D[K][M], Def>; }; };
|
||||
export type ApplyGlobalResponse<App, Def extends GlobalResponseDefinition> = App extends Hono<infer E, infer _ extends Schema, infer B> ? ModSchema<ExtractSchema<App>, Def> extends (infer S extends Schema) ? Hono$1<E, S, B> : never : never;
|
||||
type PickRoute<R, U extends StatusCode> = R extends Endpoint ? R extends {
|
||||
status: U;
|
||||
} ? R : never : R;
|
||||
type PickSchema<D, U extends StatusCode> = { [K in keyof D]: { [M in keyof D[K]]: PickRoute<D[K][M], U>; }; };
|
||||
/**
|
||||
* Keep only specific status code responses from all routes of an app.
|
||||
* Useful when error responses are handled centrally (e.g., via custom fetch)
|
||||
* and you want the client to only expose success response types.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* type AppSuccessOnly = PickResponseByStatusCode<typeof app, 200>
|
||||
* const client = hc<AppSuccessOnly>('http://localhost')
|
||||
* ```
|
||||
*/
|
||||
export type PickResponseByStatusCode<App, U extends StatusCode> = App extends Hono<infer E, infer _ extends Schema, infer B> ? PickSchema<ExtractSchema<App>, U> extends (infer S extends Schema) ? Hono$1<E, S, B> : never : never;
|
||||
//#endregion
|
||||
export {};
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
import { Result } from "./router.js";
|
||||
import { ResponseHeader } from "./utils/headers.js";
|
||||
import { ContentfulStatusCode, RedirectStatusCode, StatusCode } from "./utils/http-status.js";
|
||||
import { InvalidJSONValue, IsAny, JSONParsed, JSONValue } from "./utils/types.js";
|
||||
import { Env, FetchEventLike, H, Input, NotFoundHandler, RouterRoute, TypedResponse } from "./types.js";
|
||||
import { HonoRequest } from "./request.js";
|
||||
import { BaseMime } from "./utils/mime.js";
|
||||
//#region src/context.d.ts
|
||||
type HeaderRecord = Record<'Content-Type', BaseMime> | Record<ResponseHeader, string | string[]> | Record<string, string | string[]>;
|
||||
/**
|
||||
* Data type can be a string, ArrayBuffer, Blob, Uint8Array (buffer), or ReadableStream.
|
||||
*/
|
||||
export type Data = string | ArrayBuffer | Blob | ReadableStream | Uint8Array<ArrayBuffer>;
|
||||
/**
|
||||
* Interface for the execution context in a web worker or similar environment.
|
||||
*/
|
||||
export interface ExecutionContext {
|
||||
/**
|
||||
* Extends the lifetime of the event callback until the promise is settled.
|
||||
*
|
||||
* @param promise - A promise to wait for.
|
||||
*/
|
||||
waitUntil(promise: Promise<unknown>): void;
|
||||
/**
|
||||
* Allows the event to be passed through to subsequent event listeners.
|
||||
*/
|
||||
passThroughOnException(): void;
|
||||
/**
|
||||
* For compatibility with Wrangler 4.x.
|
||||
*/
|
||||
props: any;
|
||||
/**
|
||||
* For compatibility with Wrangler 4.x.
|
||||
*/
|
||||
exports?: any;
|
||||
}
|
||||
/**
|
||||
* Interface for context variable mapping.
|
||||
*/
|
||||
export interface ContextVariableMap {}
|
||||
/**
|
||||
* Interface for context renderer.
|
||||
*/
|
||||
export interface ContextRenderer {}
|
||||
/**
|
||||
* Interface representing a renderer for content.
|
||||
*
|
||||
* @interface DefaultRenderer
|
||||
* @param {string | Promise<string>} content - The content to be rendered, which can be either a string or a Promise resolving to a string.
|
||||
* @returns {Response | Promise<Response>} - The response after rendering the content, which can be either a Response or a Promise resolving to a Response.
|
||||
*/
|
||||
interface DefaultRenderer {
|
||||
(content: string | Promise<string>): Response | Promise<Response>;
|
||||
}
|
||||
/**
|
||||
* Renderer type which can either be a ContextRenderer or DefaultRenderer.
|
||||
*/
|
||||
export type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer;
|
||||
/**
|
||||
* Extracts the props for the renderer.
|
||||
*/
|
||||
export type PropsForRenderer = [...Required<Parameters<Renderer>>] extends [unknown, infer Props] ? Props : unknown;
|
||||
export type Layout<T = Record<string, any>> = (props: T) => any;
|
||||
/**
|
||||
* Interface for getting context variables.
|
||||
*
|
||||
* @template E - Environment type.
|
||||
*/
|
||||
interface Get<E extends Env> {
|
||||
<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
|
||||
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
||||
}
|
||||
/**
|
||||
* Interface for setting context variables.
|
||||
*
|
||||
* @template E - Environment type.
|
||||
*/
|
||||
interface Set<E extends Env> {
|
||||
<Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void;
|
||||
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
|
||||
}
|
||||
/**
|
||||
* Interface for creating a new response.
|
||||
*/
|
||||
interface NewResponse {
|
||||
(data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response;
|
||||
(data: Data | null, init?: ResponseOrInit): Response;
|
||||
}
|
||||
/**
|
||||
* Interface for responding with a body.
|
||||
*/
|
||||
interface BodyRespond {
|
||||
<T extends Data, U extends ContentfulStatusCode>(data: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<T, U, 'body'>;
|
||||
<T extends Data, U extends ContentfulStatusCode>(data: T, init?: ResponseOrInit<U>): Response & TypedResponse<T, U, 'body'>;
|
||||
<T extends null, U extends StatusCode>(data: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<null, U, 'body'>;
|
||||
<T extends null, U extends StatusCode>(data: T, init?: ResponseOrInit<U>): Response & TypedResponse<null, U, 'body'>;
|
||||
}
|
||||
/**
|
||||
* Interface for responding with text.
|
||||
*
|
||||
* @interface TextRespond
|
||||
* @template T - The type of the text content.
|
||||
* @template U - The type of the status code.
|
||||
*
|
||||
* @param {T} text - The text content to be included in the response.
|
||||
* @param {U} [status] - An optional status code for the response.
|
||||
* @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
|
||||
*
|
||||
* @returns {Response & TypedResponse<T, U, 'text'>} - The response after rendering the text content, typed with the provided text and status code types.
|
||||
*/
|
||||
interface TextRespond {
|
||||
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<T, U, 'text'>;
|
||||
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, init?: ResponseOrInit<U>): Response & TypedResponse<T, U, 'text'>;
|
||||
}
|
||||
/**
|
||||
* Interface for responding with JSON.
|
||||
*
|
||||
* @interface JSONRespond
|
||||
* @template T - The type of the JSON value or simplified unknown type.
|
||||
* @template U - The type of the status code.
|
||||
*
|
||||
* @param {T} object - The JSON object to be included in the response.
|
||||
* @param {U} [status] - An optional status code for the response.
|
||||
* @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
|
||||
*
|
||||
* @returns {JSONRespondReturn<T, U>} - The response after rendering the JSON object, typed with the provided object and status code types.
|
||||
*/
|
||||
interface JSONRespond {
|
||||
<T extends JSONValue | {} | InvalidJSONValue, U extends ContentfulStatusCode = ContentfulStatusCode>(object: T, status?: U, headers?: HeaderRecord): JSONRespondReturn<T, U>;
|
||||
<T extends JSONValue | {} | InvalidJSONValue, U extends ContentfulStatusCode = ContentfulStatusCode>(object: T, init?: ResponseOrInit<U>): JSONRespondReturn<T, U>;
|
||||
}
|
||||
/**
|
||||
* @template T - The type of the JSON value or simplified unknown type.
|
||||
* @template U - The type of the status code.
|
||||
*
|
||||
* @returns {Response & TypedResponse<JSONParsed<T>, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
|
||||
*/
|
||||
type JSONRespondReturn<T extends JSONValue | {} | InvalidJSONValue, U extends ContentfulStatusCode> = Response & TypedResponse<JSONParsed<T>, U, 'json'>;
|
||||
/**
|
||||
* Interface representing a function that responds with HTML content.
|
||||
*
|
||||
* @param html - The HTML content to respond with, which can be a string or a Promise that resolves to a string.
|
||||
* @param status - (Optional) The HTTP status code for the response.
|
||||
* @param headers - (Optional) A record of headers to include in the response.
|
||||
* @param init - (Optional) The response initialization object.
|
||||
*
|
||||
* @returns A Response object or a Promise that resolves to a Response object.
|
||||
*/
|
||||
interface HTMLRespond {
|
||||
<T extends string | Promise<string>>(html: T, status?: ContentfulStatusCode, headers?: HeaderRecord): T extends string ? Response : Promise<Response>;
|
||||
<T extends string | Promise<string>>(html: T, init?: ResponseOrInit<ContentfulStatusCode>): T extends string ? Response : Promise<Response>;
|
||||
}
|
||||
/**
|
||||
* Options for configuring the context.
|
||||
*
|
||||
* @template E - Environment type.
|
||||
*/
|
||||
type ContextOptions<E extends Env> = {
|
||||
/**
|
||||
* Bindings for the environment.
|
||||
*/
|
||||
env: E['Bindings'];
|
||||
/**
|
||||
* Execution context for the request.
|
||||
*/
|
||||
executionCtx?: FetchEventLike | ExecutionContext | undefined;
|
||||
/**
|
||||
* Handler for not found responses.
|
||||
*/
|
||||
notFoundHandler?: NotFoundHandler<E>;
|
||||
matchResult?: Result<[H, RouterRoute]>;
|
||||
path?: string;
|
||||
};
|
||||
interface SetHeadersOptions {
|
||||
append?: boolean;
|
||||
}
|
||||
interface SetHeaders {
|
||||
(name: 'Content-Type', value?: BaseMime, options?: SetHeadersOptions): void;
|
||||
(name: ResponseHeader, value?: string, options?: SetHeadersOptions): void;
|
||||
(name: string, value?: string, options?: SetHeadersOptions): void;
|
||||
}
|
||||
type ResponseHeadersInit = [string, string][] | Record<'Content-Type', BaseMime> | Record<ResponseHeader, string> | Record<string, string> | Headers;
|
||||
interface ResponseInit<T extends StatusCode = StatusCode> {
|
||||
headers?: ResponseHeadersInit;
|
||||
status?: T;
|
||||
statusText?: string;
|
||||
}
|
||||
type ResponseOrInit<T extends StatusCode = StatusCode> = ResponseInit<T> | Response;
|
||||
export declare const TEXT_PLAIN = "text/plain; charset=UTF-8";
|
||||
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
|
||||
|
||||
/**
|
||||
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#env}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Environment object for Cloudflare Workers
|
||||
* app.get('*', async c => {
|
||||
* const counter = c.env.COUNTER
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
env: E['Bindings'];
|
||||
finalized: boolean;
|
||||
/**
|
||||
* `.error` can get the error object from the middleware if the Handler throws an error.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#error}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async (c, next) => {
|
||||
* await next()
|
||||
* if (c.error) {
|
||||
* // do something...
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
error: Error | undefined;
|
||||
/**
|
||||
* Creates an instance of the Context class.
|
||||
*
|
||||
* @param req - The Request object.
|
||||
* @param options - Optional configuration options for the context.
|
||||
*/
|
||||
constructor(req: Request, options?: ContextOptions<E>);
|
||||
/**
|
||||
* `.req` is the instance of {@link HonoRequest}.
|
||||
*/
|
||||
get req(): HonoRequest<P, I['out']>;
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#event}
|
||||
* The FetchEvent associated with the current request.
|
||||
*
|
||||
* @throws Will throw an error if the context does not have a FetchEvent.
|
||||
*/
|
||||
get event(): FetchEventLike;
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#executionctx}
|
||||
* The ExecutionContext associated with the current request.
|
||||
*
|
||||
* @throws Will throw an error if the context does not have an ExecutionContext.
|
||||
*/
|
||||
get executionCtx(): ExecutionContext;
|
||||
/**
|
||||
* @see {@link https://hono.dev/docs/api/context#res}
|
||||
* The Response object for the current request.
|
||||
*/
|
||||
get res(): Response;
|
||||
/**
|
||||
* Sets the Response object for the current request.
|
||||
*
|
||||
* @param _res - The Response object to set.
|
||||
*/
|
||||
set res(_res: Response | undefined);
|
||||
/**
|
||||
* `.render()` can create a response within a layout.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/', (c) => {
|
||||
* return c.render('Hello!')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
render: Renderer;
|
||||
/**
|
||||
* Sets the layout for the response.
|
||||
*
|
||||
* @param layout - The layout to set.
|
||||
* @returns The layout function.
|
||||
*/
|
||||
setLayout: (layout: Layout<PropsForRenderer & {
|
||||
Layout: Layout;
|
||||
}>) => Layout<PropsForRenderer & {
|
||||
Layout: Layout;
|
||||
}>;
|
||||
/**
|
||||
* Gets the current layout for the response.
|
||||
*
|
||||
* @returns The current layout function.
|
||||
*/
|
||||
getLayout: () => Layout<PropsForRenderer & {
|
||||
Layout: Layout;
|
||||
}> | undefined;
|
||||
/**
|
||||
* `.setRenderer()` can set the layout in the custom middleware.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* app.use('*', async (c, next) => {
|
||||
* c.setRenderer((content) => {
|
||||
* return c.html(
|
||||
* <html>
|
||||
* <body>
|
||||
* <p>{content}</p>
|
||||
* </body>
|
||||
* </html>
|
||||
* )
|
||||
* })
|
||||
* await next()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
setRenderer: (renderer: Renderer) => void;
|
||||
/**
|
||||
* `.header()` can set headers.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#header}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/welcome', (c) => {
|
||||
* // Set headers
|
||||
* c.header('X-Message', 'Hello!')
|
||||
* c.header('Content-Type', 'text/plain')
|
||||
*
|
||||
* // Append multiple headers using the append option (e.g. Vary)
|
||||
* c.header('Vary', 'Accept-Encoding', { append: true })
|
||||
* c.header('Vary', 'User-Agent', { append: true })
|
||||
*
|
||||
* return c.body('Thank you for coming')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
header: SetHeaders;
|
||||
status: (status: StatusCode) => void;
|
||||
/**
|
||||
* `.set()` can set the value specified by the key.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#set-get}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async (c, next) => {
|
||||
* c.set('message', 'Hono is hot!!')
|
||||
* await next()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
set: Set<IsAny<E> extends true ? {
|
||||
Variables: ContextVariableMap & Record<PropertyKey, any>;
|
||||
} : E>;
|
||||
/**
|
||||
* `.get()` can use the value specified by the key.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#set-get}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/', (c) => {
|
||||
* const message = c.get('message')
|
||||
* return c.text(`The message is "${message}"`)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get: Get<IsAny<E> extends true ? {
|
||||
Variables: ContextVariableMap & Record<PropertyKey, any>;
|
||||
} : E>;
|
||||
/**
|
||||
* `.var` can access the value of a variable.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#var}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const result = c.var.client.oneMethod()
|
||||
* ```
|
||||
*/
|
||||
get var(): Readonly<ContextVariableMap & (IsAny<E['Variables']> extends true ? Record<string, any> : E['Variables'])>;
|
||||
newResponse: NewResponse;
|
||||
/**
|
||||
* `.body()` can return the HTTP response.
|
||||
* You can set headers with `.header()` and set HTTP status code with `.status`.
|
||||
* This can also be set in `.text()`, `.json()` and so on.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#body}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/welcome', (c) => {
|
||||
* // Set headers
|
||||
* c.header('X-Message', 'Hello!')
|
||||
* c.header('Content-Type', 'text/plain')
|
||||
* // Set HTTP status code
|
||||
* c.status(201)
|
||||
*
|
||||
* // Return the response body
|
||||
* return c.body('Thank you for coming')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
body: BodyRespond;
|
||||
/**
|
||||
* `.text()` can render text as `Content-Type:text/plain`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#text}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/say', (c) => {
|
||||
* return c.text('Hello!')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
text: TextRespond;
|
||||
/**
|
||||
* `.json()` can render JSON as `Content-Type:application/json`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#json}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/api', (c) => {
|
||||
* return c.json({ message: 'Hello!' })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
json: JSONRespond;
|
||||
html: HTMLRespond;
|
||||
/**
|
||||
* `.redirect()` can Redirect, default status code is 302.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#redirect}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/redirect', (c) => {
|
||||
* return c.redirect('/')
|
||||
* })
|
||||
* app.get('/redirect-permanently', (c) => {
|
||||
* return c.redirect('/', 301)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
redirect: <T extends RedirectStatusCode = 302>(location: string | URL, status?: T) => Response & TypedResponse<undefined, T, "redirect">;
|
||||
/**
|
||||
* `.notFound()` can return the Not Found Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/context#notfound}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/notfound', (c) => {
|
||||
* return c.notFound()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
notFound: () => ReturnType<NotFoundHandler>;
|
||||
}
|
||||
//#endregion
|
||||
export {};
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
import { Router } from "./router.js";
|
||||
import { Env, ErrorHandler, H, HandlerInterface, MergePath, MergeSchemaPath, MiddlewareHandlerInterface, NotFoundHandler, OnHandlerInterface, RouterRoute, Schema } from "./types.js";
|
||||
import { Context, ExecutionContext } from "./context.js";
|
||||
//#region src/hono-base.d.ts
|
||||
type GetPath<E extends Env> = (request: Request, options?: {
|
||||
env?: E['Bindings'];
|
||||
}) => string;
|
||||
export type HonoOptions<E extends Env> = {
|
||||
/**
|
||||
* `strict` option specifies whether to distinguish whether the last path is a directory or not.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#strict-mode}
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
strict?: boolean;
|
||||
/**
|
||||
* `router` option specifies which router to use.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#router-option}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono({ router: new RegExpRouter() })
|
||||
* ```
|
||||
*/
|
||||
router?: Router<[H, RouterRoute]>;
|
||||
/**
|
||||
* `getPath` can handle the host header value.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#routing-with-host-header-value}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono({
|
||||
* getPath: (req) =>
|
||||
* '/' + req.headers.get('host') + req.url.replace(/^https?:\/\/[^/]+(\/[^?]*)/, '$1'),
|
||||
* })
|
||||
*
|
||||
* app.get('/www1.example.com/hello', () => c.text('hello www1'))
|
||||
*
|
||||
* // A following request will match the route:
|
||||
* // new Request('http://www1.example.com/hello', {
|
||||
* // headers: { host: 'www1.example.com' },
|
||||
* // })
|
||||
* ```
|
||||
*/
|
||||
getPath?: GetPath<E>;
|
||||
};
|
||||
type MountOptionHandler = (c: Context) => unknown;
|
||||
type MountReplaceRequest = (originalRequest: Request) => Request;
|
||||
type MountOptions = MountOptionHandler | {
|
||||
optionHandler?: MountOptionHandler;
|
||||
replaceRequest?: MountReplaceRequest | false;
|
||||
};
|
||||
declare class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/', CurrentPath extends string = BasePath> {
|
||||
|
||||
get: HandlerInterface<E, 'get', S, BasePath, CurrentPath>;
|
||||
post: HandlerInterface<E, 'post', S, BasePath, CurrentPath>;
|
||||
put: HandlerInterface<E, 'put', S, BasePath, CurrentPath>;
|
||||
delete: HandlerInterface<E, 'delete', S, BasePath, CurrentPath>;
|
||||
options: HandlerInterface<E, 'options', S, BasePath, CurrentPath>;
|
||||
patch: HandlerInterface<E, 'patch', S, BasePath, CurrentPath>;
|
||||
query: HandlerInterface<E, 'query', S, BasePath, CurrentPath>;
|
||||
all: HandlerInterface<E, 'all', S, BasePath, CurrentPath>;
|
||||
on: OnHandlerInterface<E, S, BasePath>;
|
||||
use: MiddlewareHandlerInterface<E, S, BasePath>;
|
||||
router: Router<[H, RouterRoute]>;
|
||||
readonly getPath: GetPath<E>;
|
||||
private _basePath;
|
||||
routes: RouterRoute[];
|
||||
constructor(options?: HonoOptions<E>);
|
||||
private errorHandler;
|
||||
/**
|
||||
* `.route()` allows grouping other Hono instance in routes.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#grouping}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @param {Hono} app - other Hono instance
|
||||
* @returns {Hono} routed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono()
|
||||
* const app2 = new Hono()
|
||||
*
|
||||
* app2.get("/user", (c) => c.text("user"))
|
||||
* app.route("/api", app2) // GET /api/user
|
||||
* ```
|
||||
*/
|
||||
route<SubPath extends string, SubEnv extends Env, SubSchema extends Schema, SubBasePath extends string, SubCurrentPath extends string>(path: SubPath, app: Hono<SubEnv, SubSchema, SubBasePath, SubCurrentPath>): Hono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> | S, BasePath, CurrentPath>;
|
||||
/**
|
||||
* `.basePath()` allows base paths to be specified.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#base-path}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const api = new Hono().basePath('/api')
|
||||
* ```
|
||||
*/
|
||||
basePath<SubPath extends string>(path: SubPath): Hono<E, S, MergePath<BasePath, SubPath>, MergePath<BasePath, SubPath>>;
|
||||
/**
|
||||
* `.onError()` handles an error and returns a customized Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#error-handling}
|
||||
*
|
||||
* @param {ErrorHandler} handler - request Handler for error
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.onError((err, c) => {
|
||||
* console.error(`${err}`)
|
||||
* return c.text('Custom Error Message', 500)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
onError: (handler: ErrorHandler<E>) => Hono<E, S, BasePath, CurrentPath>;
|
||||
/**
|
||||
* `.notFound()` allows you to customize a Not Found Response.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#not-found}
|
||||
*
|
||||
* @param {NotFoundHandler} handler - request handler for not-found
|
||||
* @returns {Hono} changed Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.notFound((c) => {
|
||||
* return c.text('Custom 404 Message', 404)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
notFound: (handler: NotFoundHandler<E>) => Hono<E, S, BasePath, CurrentPath>;
|
||||
/**
|
||||
* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
|
||||
*
|
||||
* @deprecated Use `mount()` from `hono/mount` instead. `.mount()` will be removed in v5.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#mount}
|
||||
*
|
||||
* @param {string} path - base Path
|
||||
* @param {Function} applicationHandler - other Request Handler
|
||||
* @param {MountOptions} [options] - options of `.mount()`
|
||||
* @returns {Hono} mounted Hono instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Router as IttyRouter } from 'itty-router'
|
||||
* import { Hono } from 'hono'
|
||||
* // Create itty-router application
|
||||
* const ittyRouter = IttyRouter()
|
||||
* // GET /itty-router/hello
|
||||
* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
|
||||
*
|
||||
* const app = new Hono()
|
||||
* app.mount('/itty-router', ittyRouter.handle)
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const app = new Hono()
|
||||
* // Send the request to another application without modification.
|
||||
* app.mount('/app', anotherApp, {
|
||||
* replaceRequest: (req) => req,
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
mount(path: string, applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>, options?: MountOptions): Hono<E, S, BasePath, CurrentPath>;
|
||||
/**
|
||||
* `.fetch()` will be entry point of your app.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/hono#fetch}
|
||||
*
|
||||
* @param {Request} request - request Object of request
|
||||
* @param {Env} env - env Object
|
||||
* @param {ExecutionContext} executionCtx - context of execution
|
||||
* @returns {Response | Promise<Response>} response of request
|
||||
*
|
||||
*/
|
||||
fetch: (request: Request, env?: E['Bindings'] | {}, executionCtx?: ExecutionContext) => Response | Promise<Response>;
|
||||
/**
|
||||
* `.request()` is a useful method for testing.
|
||||
* You can pass a URL or pathname to send a GET request.
|
||||
* app will return a Response object.
|
||||
* ```ts
|
||||
* test('GET /hello is ok', async () => {
|
||||
* const res = await app.request('/hello')
|
||||
* expect(res.status).toBe(200)
|
||||
* })
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/hono#request
|
||||
*/
|
||||
request: (input: Request | string | URL, requestInit?: RequestInit, Env?: E["Bindings"] | {}, executionCtx?: ExecutionContext) => Response | Promise<Response>;
|
||||
/**
|
||||
* `.fire()` automatically adds a global fetch event listener.
|
||||
* This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
|
||||
* @deprecated
|
||||
* Use `fire` from `hono/service-worker` instead.
|
||||
* ```ts
|
||||
* import { Hono } from 'hono'
|
||||
* import { fire } from 'hono/service-worker'
|
||||
*
|
||||
* const app = new Hono()
|
||||
* // ...
|
||||
* fire(app)
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/hono#fire
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
|
||||
* @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
|
||||
*/
|
||||
fire: () => void;
|
||||
}
|
||||
//#endregion
|
||||
export { Hono as HonoBase };
|
||||
export {};
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import { HonoBase as Hono$1, HonoOptions } from "./hono-base.js";
|
||||
import { BlankEnv, BlankSchema, Env, Schema } from "./types.js";
|
||||
//#region src/hono.d.ts
|
||||
/**
|
||||
* The Hono class extends the functionality of the HonoBase class.
|
||||
* It sets up routing and allows for custom options to be passed.
|
||||
*
|
||||
* @template E - The environment type.
|
||||
* @template S - The schema type.
|
||||
* @template BasePath - The base path type.
|
||||
*/
|
||||
export declare class Hono<E extends Env = BlankEnv, S extends Schema = BlankSchema, BasePath extends string = '/'> extends Hono$1<E, S, BasePath> {
|
||||
/**
|
||||
* Creates an instance of the Hono class.
|
||||
*
|
||||
* @param options - Optional configuration options for the Hono instance.
|
||||
*/
|
||||
constructor(options?: HonoOptions<E>);
|
||||
}
|
||||
//#endregion
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { Env, ErrorHandler, Handler, Input, MiddlewareHandler, Next, NotFoundHandler, NotFoundResponse, Schema, ToSchema, TypedResponse, ValidationTargets } from "./types.js";
|
||||
import { HonoRequest } from "./request.js";
|
||||
import { Context, ContextRenderer, ContextVariableMap, ExecutionContext } from "./context.js";
|
||||
import { Hono } from "./hono.js";
|
||||
import { ClientRequestOptions, InferRequestType, InferResponseType } from "./client/types.js";
|
||||
export { type ClientRequestOptions, Context, type ContextRenderer, type ContextVariableMap, type Env, type ErrorHandler, type ExecutionContext, type Handler, Hono, type HonoRequest, type InferRequestType, type InferResponseType, type Input, type MiddlewareHandler, type Next, type NotFoundHandler, type NotFoundResponse, type Schema, type ToSchema, type TypedResponse, type ValidationTargets };
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
import { GET_MATCH_RESULT } from "./request/constants.js";
|
||||
import { Result } from "./router.js";
|
||||
import { CustomHeader, RequestHeader } from "./utils/headers.js";
|
||||
import { Simplify, UnionToIntersection } from "./utils/types.js";
|
||||
import { Input, InputToDataByTarget, ParamKeyToRecord, ParamKeys, RemoveQuestion, RouterRoute, ValidationTargets } from "./types.js";
|
||||
import { BodyData, ParseBodyOptions } from "./utils/body.js";
|
||||
//#region src/request.d.ts
|
||||
type Body = {
|
||||
json: any;
|
||||
text: string;
|
||||
arrayBuffer: ArrayBuffer;
|
||||
blob: Blob;
|
||||
formData: FormData;
|
||||
};
|
||||
type BodyCache = Partial<Body>;
|
||||
export declare class HonoRequest<P extends string = '/', I extends Input['out'] = {}> {
|
||||
|
||||
/**
|
||||
* `.raw` can get the raw Request object.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#raw}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // For Cloudflare Workers
|
||||
* app.post('/', async (c) => {
|
||||
* const metadata = c.req.raw.cf?.hostMetadata?
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
raw: Request;
|
||||
routeIndex: number;
|
||||
/**
|
||||
* `.path` can get the pathname of the request.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#path}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const pathname = c.req.path // `/about/me`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
path: string;
|
||||
bodyCache: BodyCache;
|
||||
constructor(request: Request, path?: string, matchResult?: Result<[unknown, RouterRoute]>);
|
||||
/**
|
||||
* `.req.param()` gets the path parameters.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/routing#path-parameter}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const name = c.req.param('name')
|
||||
* // or all parameters at once
|
||||
* const { id, comment_id } = c.req.param()
|
||||
* ```
|
||||
*/
|
||||
param<P2 extends ParamKeys<P> = ParamKeys<P>>(key: string extends P ? never : P2 extends `${infer _}?` ? never : P2): string;
|
||||
param<P2 extends RemoveQuestion<ParamKeys<P>> = RemoveQuestion<ParamKeys<P>>>(key: P2): string | undefined;
|
||||
param(key: string): string | undefined;
|
||||
param<P2 extends string = P>(): Simplify<UnionToIntersection<ParamKeyToRecord<ParamKeys<P2>>>>;
|
||||
/**
|
||||
* `.query()` can get querystring parameters.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#query}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Query params
|
||||
* app.get('/search', (c) => {
|
||||
* const query = c.req.query('q')
|
||||
* })
|
||||
*
|
||||
* // Get all params at once
|
||||
* app.get('/search', (c) => {
|
||||
* const { q, limit, offset } = c.req.query()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
query(key: string): string | undefined;
|
||||
query(): Record<string, string>;
|
||||
/**
|
||||
* `.queries()` can get multiple querystring parameter values, e.g. /search?tags=A&tags=B
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#queries}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/search', (c) => {
|
||||
* // tags will be string[]
|
||||
* const tags = c.req.queries('tags')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
queries(key: string): string[] | undefined;
|
||||
queries(): Record<string, string[]>;
|
||||
/**
|
||||
* `.header()` can get the request header value.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#header}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/', (c) => {
|
||||
* const userAgent = c.req.header('User-Agent')
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
header(name: RequestHeader): string | undefined;
|
||||
header(name: string): string | undefined;
|
||||
header(): Record<RequestHeader | (string & CustomHeader), string>;
|
||||
/**
|
||||
* `.parseBody()` can parse Request body of type `multipart/form-data` or `application/x-www-form-urlencoded`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#parsebody}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.parseBody()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
parseBody<Options extends Partial<ParseBodyOptions>, T extends BodyData<Options>>(options?: Options): Promise<T>;
|
||||
parseBody<T extends BodyData>(options?: Partial<ParseBodyOptions>): Promise<T>;
|
||||
/**
|
||||
* `.json()` can parse Request body of type `application/json`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#json}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.json()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
json<T = any>(): Promise<T>;
|
||||
/**
|
||||
* `.text()` can parse Request body of type `text/plain`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#text}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.text()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
text(): Promise<string>;
|
||||
/**
|
||||
* `.arrayBuffer()` parse Request body as an `ArrayBuffer`
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#arraybuffer}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.arrayBuffer()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer(): Promise<ArrayBuffer>;
|
||||
/**
|
||||
* `.bytes()` parses the request body as a `Uint8Array`.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#bytes}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.bytes()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
bytes(): Promise<Uint8Array>;
|
||||
/**
|
||||
* Parses the request body as a `Blob`.
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.blob();
|
||||
* });
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/request#blob
|
||||
*/
|
||||
blob(): Promise<Blob>;
|
||||
/**
|
||||
* Parses the request body as `FormData`.
|
||||
* @example
|
||||
* ```ts
|
||||
* app.post('/entry', async (c) => {
|
||||
* const body = await c.req.formData();
|
||||
* });
|
||||
* ```
|
||||
* @see https://hono.dev/docs/api/request#formdata
|
||||
*/
|
||||
formData(): Promise<FormData>;
|
||||
/**
|
||||
* Adds validated data to the request.
|
||||
*
|
||||
* @param target - The target of the validation.
|
||||
* @param data - The validated data to add.
|
||||
*/
|
||||
addValidatedData(target: keyof ValidationTargets, data: {}): void;
|
||||
/**
|
||||
* Gets validated data from the request.
|
||||
*
|
||||
* @param target - The target of the validation.
|
||||
* @returns The validated data.
|
||||
*
|
||||
* @see https://hono.dev/docs/api/request#valid
|
||||
*/
|
||||
valid<T extends keyof I & keyof ValidationTargets>(target: T): InputToDataByTarget<I, T>;
|
||||
/**
|
||||
* `.url` can get the request url strings.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#url}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const url = c.req.url // `http://localhost:8787/about/me`
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get url(): string;
|
||||
/**
|
||||
* `.method` can get the method name of the request.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#method}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/about/me', (c) => {
|
||||
* const method = c.req.method // `GET`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get method(): string;
|
||||
get [GET_MATCH_RESULT](): Result<[unknown, RouterRoute]>;
|
||||
/**
|
||||
* `.matchedRoutes` can return a matched route in the handler
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* Use matchedRoutes helper defined in "hono/route" instead.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#matchedroutes}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.use('*', async function logger(c, next) {
|
||||
* await next()
|
||||
* c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
|
||||
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
|
||||
* console.log(
|
||||
* method,
|
||||
* ' ',
|
||||
* path,
|
||||
* ' '.repeat(Math.max(10 - path.length, 0)),
|
||||
* name,
|
||||
* i === c.req.routeIndex ? '<- respond from here' : ''
|
||||
* )
|
||||
* })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get matchedRoutes(): RouterRoute[];
|
||||
/**
|
||||
* `.routePath` can retrieve the path registered within the handler
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* Use routePath helper defined in "hono/route" instead.
|
||||
*
|
||||
* @see {@link https://hono.dev/docs/api/request#routepath}
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* app.get('/posts/:id', (c) => {
|
||||
* return c.json({ path: c.req.routePath })
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
get routePath(): string;
|
||||
}
|
||||
/**
|
||||
* Clones a HonoRequest's underlying raw Request object.
|
||||
*
|
||||
* This utility handles both consumed and unconsumed request bodies:
|
||||
* - If the request body hasn't been consumed, it uses the native `clone()` method
|
||||
* - If the request body has been consumed, it reconstructs a new Request using cached body data
|
||||
*
|
||||
* This is particularly useful when you need to:
|
||||
* - Process the same request body multiple times
|
||||
* - Pass requests to external services after validation
|
||||
*
|
||||
* @param req - The HonoRequest object to clone
|
||||
* @returns A Promise that resolves to a new Request object with the same properties
|
||||
* @throws {HTTPException} If the request body was consumed directly via `req.raw`
|
||||
* without using HonoRequest methods (e.g., `req.json()`, `req.text()`), making it
|
||||
* impossible to reconstruct the body from cache
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Clone after consuming the body (e.g., after validation)
|
||||
* app.post('/forward',
|
||||
* validator('json', (data) => data),
|
||||
* async (c) => {
|
||||
* const validated = c.req.valid('json')
|
||||
* // Body has been consumed, but cloneRawRequest still works
|
||||
* const clonedReq = await cloneRawRequest(c.req)
|
||||
* return fetch('http://backend-service.com', clonedReq)
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
export declare const cloneRawRequest: (req: HonoRequest) => Promise<Request>;
|
||||
//#endregion
|
||||
export {};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
//#region src/request/constants.d.ts
|
||||
export declare const GET_MATCH_RESULT: unique symbol;
|
||||
//#endregion
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
//#region src/router.d.ts
|
||||
/**
|
||||
* @module
|
||||
* This module provides types definitions and variables for the routers.
|
||||
*/
|
||||
/**
|
||||
* Constant representing all HTTP methods in uppercase.
|
||||
*/
|
||||
export declare const METHOD_NAME_ALL: "ALL";
|
||||
/**
|
||||
* Constant representing all HTTP methods in lowercase.
|
||||
*/
|
||||
export declare const METHOD_NAME_ALL_LOWERCASE: "all";
|
||||
/**
|
||||
* Array of supported HTTP methods.
|
||||
*/
|
||||
export declare const METHODS: readonly ["get", "post", "put", "delete", "options", "patch", "query"];
|
||||
/**
|
||||
* Error message indicating that a route cannot be added because the matcher is already built.
|
||||
*/
|
||||
export declare const MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
||||
/**
|
||||
* Interface representing a router.
|
||||
*
|
||||
* @template T - The type of the handler.
|
||||
*/
|
||||
export interface Router<T> {
|
||||
/**
|
||||
* The name of the router.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Adds a route to the router.
|
||||
*
|
||||
* @param method - The HTTP method (e.g., 'get', 'post').
|
||||
* @param path - The path for the route.
|
||||
* @param handler - The handler for the route.
|
||||
*/
|
||||
add(method: string, path: string, handler: T): void;
|
||||
/**
|
||||
* Matches a route based on the given method and path.
|
||||
*
|
||||
* @param method - The HTTP method (e.g., 'get', 'post').
|
||||
* @param path - The path to match.
|
||||
* @returns The result of the match.
|
||||
*/
|
||||
match(method: string, path: string): Result<T>;
|
||||
}
|
||||
/**
|
||||
* Type representing a map of parameter indices.
|
||||
*/
|
||||
export type ParamIndexMap = Record<string, number>;
|
||||
/**
|
||||
* Type representing a stash of parameters.
|
||||
*/
|
||||
export type ParamStash = string[];
|
||||
/**
|
||||
* Type representing a map of parameters.
|
||||
*/
|
||||
export type Params = Record<string, string>;
|
||||
/**
|
||||
* Type representing the result of a route match.
|
||||
*
|
||||
* The result can be in one of two formats:
|
||||
* 1. An array of handlers with their corresponding parameter index maps, followed by a parameter stash.
|
||||
* 2. An array of handlers with their corresponding parameter maps.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* [[handler, paramIndexMap][], paramArray]
|
||||
* ```typescript
|
||||
* [
|
||||
* [
|
||||
* [middlewareA, {}], // '*'
|
||||
* [funcA, {'id': 0}], // '/user/:id/*'
|
||||
* [funcB, {'id': 0, 'action': 1}], // '/user/:id/:action'
|
||||
* ],
|
||||
* ['123', 'abc']
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* [[handler, params][]]
|
||||
* ```typescript
|
||||
* [
|
||||
* [
|
||||
* [middlewareA, {}], // '*'
|
||||
* [funcA, {'id': '123'}], // '/user/:id/*'
|
||||
* [funcB, {'id': '123', 'action': 'abc'}], // '/user/:id/:action'
|
||||
* ]
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
export type Result<T> = [[T, ParamIndexMap][], ParamStash] | [[T, Params][]];
|
||||
/**
|
||||
* Error class representing an unsupported path error.
|
||||
*/
|
||||
export declare class UnsupportedPathError extends Error {}
|
||||
//#endregion
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
import { HonoBase as Hono } from "./hono-base.js";
|
||||
import { CustomHeader, RequestHeader } from "./utils/headers.js";
|
||||
import { StatusCode } from "./utils/http-status.js";
|
||||
import { IfAnyThenEmptyObject, IsAny, JSONValue, RemoveBlankRecord, Simplify, UnionToIntersection } from "./utils/types.js";
|
||||
import { Context } from "./context.js";
|
||||
//#region src/types.d.ts
|
||||
export type Bindings = object;
|
||||
export type Variables = object;
|
||||
export type BlankEnv = {};
|
||||
export type Env = {
|
||||
Bindings?: Bindings;
|
||||
Variables?: Variables;
|
||||
};
|
||||
export type Next = () => Promise<void>;
|
||||
export type ExtractInput<I extends Input | Input['in']> = I extends Input ? unknown extends I['in'] ? {} : I['in'] : I;
|
||||
export type Input = {
|
||||
in?: {};
|
||||
out?: {};
|
||||
outputFormat?: ResponseFormat;
|
||||
};
|
||||
export type BlankSchema = {};
|
||||
export type BlankInput = {};
|
||||
export interface RouterRoute {
|
||||
basePath: string;
|
||||
path: string;
|
||||
method: string;
|
||||
handler: H;
|
||||
}
|
||||
export type HandlerResponse<O> = Response | TypedResponse<O> | Promise<Response | TypedResponse<O>> | Promise<void>;
|
||||
export type Handler<E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse<any> = any> = (c: Context<E, P, I>, next: Next) => R;
|
||||
export type MiddlewareHandler<E extends Env = any, P extends string = string, I extends Input = {}, R extends HandlerResponse<any> = Response> = (c: Context<E, P, I>, next: Next) => Promise<R | void>;
|
||||
export type H<E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse<any> = any> = Handler<E, P, I, R> | MiddlewareHandler<E, P, I, R>;
|
||||
/**
|
||||
* You can extend this interface to define a custom `c.notFound()` Response type.
|
||||
*
|
||||
* @example
|
||||
* declare module 'hono' {
|
||||
* interface NotFoundResponse extends Response, TypedResponse<string, 404, 'text'> {}
|
||||
* }
|
||||
*/
|
||||
export interface NotFoundResponse {}
|
||||
export type NotFoundHandler<E extends Env = any> = (c: Context<E>) => NotFoundResponse extends Response ? NotFoundResponse | Promise<NotFoundResponse> : Response | Promise<Response>;
|
||||
export interface HTTPResponseError extends Error {
|
||||
getResponse: () => Response;
|
||||
}
|
||||
export type ErrorHandler<E extends Env = any> = (err: Error | HTTPResponseError, c: Context<E>) => Response | Promise<Response>;
|
||||
export interface HandlerInterface<E extends Env = Env, M extends string = string, S extends Schema = BlankSchema, BasePath extends string = '/', CurrentPath extends string = BasePath> {
|
||||
<P extends string = CurrentPath, I extends Input = BlankInput, R extends HandlerResponse<any> = any, E2 extends Env = E>(handler: H<E2, P, I, R>): Hono<IntersectNonAnyTypes<[E, E2]>, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath, CurrentPath>;
|
||||
<P extends string = CurrentPath, I extends Input = BlankInput, I2 extends Input = I, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, M1 extends H<E2, P, I> = H<E2, P, I>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema<M, P, I2, MergeTypedResponse<R> | MergeMiddlewareResponse<M1>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(path: P, handler: H<E2, MergedPath, I, R>): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R>, S, M, P, I, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema<M, P, I3, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1>, S, M, P, I2, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema<M, P, I4, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>, S, M, P, I3, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema<M, P, I5, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>, S, M, P, I4, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>, M5 extends H<E6, P, I5> = H<E6, P, I5>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5> & M5, H<E7, P, I6, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema<M, P, I6, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>, S, M, P, I5, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>, M5 extends H<E6, P, I5> = H<E6, P, I5>, M6 extends H<E7, P, I6> = H<E7, P, I6>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5> & M5, H<E7, P, I6> & M6, H<E8, P, I7, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema<M, P, I7, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>, S, M, P, I6, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>, M5 extends H<E6, P, I5> = H<E6, P, I5>, M6 extends H<E7, P, I6> = H<E7, P, I6>, M7 extends H<E8, P, I7> = H<E8, P, I7>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5> & M5, H<E7, P, I6> & M6, H<E8, P, I7> & M7, H<E9, P, I8, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema<M, P, I8, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>, S, M, P, I7, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>, M5 extends H<E6, P, I5> = H<E6, P, I5>, M6 extends H<E7, P, I6> = H<E7, P, I6>, M7 extends H<E8, P, I7> = H<E8, P, I7>, M8 extends H<E9, P, I8> = H<E9, P, I8>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5> & M5, H<E7, P, I6> & M6, H<E8, P, I7> & M7, H<E9, P, I8> & M8, H<E10, P, I9, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema<M, P, I9, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>, S, M, P, I8, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, M1 extends H<E2, P, I> = H<E2, P, I>, M2 extends H<E3, P, I2> = H<E3, P, I2>, M3 extends H<E4, P, I3> = H<E4, P, I3>, M4 extends H<E5, P, I4> = H<E5, P, I4>, M5 extends H<E6, P, I5> = H<E6, P, I5>, M6 extends H<E7, P, I6> = H<E7, P, I6>, M7 extends H<E8, P, I7> = H<E8, P, I7>, M8 extends H<E9, P, I8> = H<E9, P, I8>, M9 extends H<E10, P, I9> = H<E10, P, I9>>(...handlers: [H<E2, P, I> & M1, H<E3, P, I2> & M2, H<E4, P, I3> & M3, H<E5, P, I4> & M4, H<E6, P, I5> & M5, H<E7, P, I6> & M6, H<E8, P, I7> & M7, H<E9, P, I8> & M8, H<E10, P, I9> & M9, H<E11, P, I10, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema<M, P, I10, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>>, BasePath, CurrentPath>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>, S, M, P, I9, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>, M9 extends H<E10, MergedPath, I9> = H<E10, MergedPath, I9>>(path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9> & M9, H<E11, MergedPath, I10, R>]): Hono<E, AddSchemaIfHasResponse<MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>, S, M, P, I10, BasePath>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string = CurrentPath, I extends Input = BlankInput, R extends HandlerResponse<any> = any>(...handlers: H<E, P, I, R>[]): Hono<E, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath, CurrentPath>;
|
||||
<P extends string, I extends Input = BlankInput, R extends HandlerResponse<any> = any>(path: P, ...handlers: [H<E, MergePath<BasePath, P>, I, R>, ...H<E, MergePath<BasePath, P>, I, R>[]]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
<P extends string, R extends HandlerResponse<any> = any, I extends Input = BlankInput>(path: P): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
}
|
||||
export interface MiddlewareHandlerInterface<E extends Env = Env, S extends Schema = BlankSchema, BasePath extends string = '/'> {
|
||||
<E2 extends Env = E>(...handlers: MiddlewareHandler<E2, MergePath<BasePath, '*'>>[]): Hono<IntersectNonAnyTypes<[E, E2]>, S, BasePath, MergePath<BasePath, '*'>>;
|
||||
<E2 extends Env = E>(handler: MiddlewareHandler<E2, MergePath<BasePath, '*'>>): Hono<IntersectNonAnyTypes<[E, E2]>, S, BasePath, MergePath<BasePath, '*'>>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E>(path: P, handler: MiddlewareHandler<E2, MergedPath, any, any>): Hono<IntersectNonAnyTypes<[E, E2]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P, any, any>, MiddlewareHandler<E3, P, any, any>, MiddlewareHandler<E4, P, any, any>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>, MiddlewareHandler<E9, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>, MiddlewareHandler<E9, P>, MiddlewareHandler<E10, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>, MiddlewareHandler<E9, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S, BasePath, MergedPath>;
|
||||
<E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, P extends string = MergePath<BasePath, '*'>>(...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>, MiddlewareHandler<E9, P>, MiddlewareHandler<E10, P>, MiddlewareHandler<E11, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S, BasePath, P>;
|
||||
<P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>>(path: P, ...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>, MiddlewareHandler<E4, P>, MiddlewareHandler<E5, P>, MiddlewareHandler<E6, P>, MiddlewareHandler<E7, P>, MiddlewareHandler<E8, P>, MiddlewareHandler<E9, P>, MiddlewareHandler<E10, P>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S, BasePath, MergedPath>;
|
||||
<P extends string, E2 extends Env = E>(path: P, ...handlers: MiddlewareHandler<E2, MergePath<BasePath, P>>[]): Hono<E, S, BasePath, MergePath<BasePath, P>>;
|
||||
}
|
||||
export interface OnHandlerInterface<E extends Env = Env, S extends Schema = BlankSchema, BasePath extends string = '/'> {
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(method: M, path: P, handler: H<E2, MergedPath, I, R>): Hono<IntersectNonAnyTypes<[E, E2]>, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R> | MergeMiddlewareResponse<M1>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>, M9 extends H<E10, MergedPath, I9> = H<E10, MergedPath, I9>>(method: M, path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9> & M9, H<E11, MergedPath, I10, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = BlankInput>(method: M, path: P, ...handlers: [H<E, MergePath<BasePath, P>, I, R>, ...H<E, MergePath<BasePath, P>, I, R>[]]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(methods: M[], path: P, handler: H<E2, MergedPath, I, R>): Hono<IntersectNonAnyTypes<[E, E2]>, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R> | MergeMiddlewareResponse<M1>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, M1 extends H<E2, MergedPath, I> = H<E2, MergedPath, I>, M2 extends H<E3, MergedPath, I2> = H<E3, MergedPath, I2>, M3 extends H<E4, MergedPath, I3> = H<E4, MergedPath, I3>, M4 extends H<E5, MergedPath, I4> = H<E5, MergedPath, I4>, M5 extends H<E6, MergedPath, I5> = H<E6, MergedPath, I5>, M6 extends H<E7, MergedPath, I6> = H<E7, MergedPath, I6>, M7 extends H<E8, MergedPath, I7> = H<E8, MergedPath, I7>, M8 extends H<E9, MergedPath, I8> = H<E9, MergedPath, I8>, M9 extends H<E10, MergedPath, I9> = H<E10, MergedPath, I9>>(methods: M[], path: P, ...handlers: [H<E2, MergedPath, I> & M1, H<E3, MergedPath, I2> & M2, H<E4, MergedPath, I3> & M3, H<E5, MergedPath, I4> & M4, H<E6, MergedPath, I5> & M5, H<E7, MergedPath, I6> & M6, H<E8, MergedPath, I7> & M7, H<E9, MergedPath, I8> & M8, H<E10, MergedPath, I9> & M9, H<E11, MergedPath, I10, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = BlankInput>(methods: M[], path: P, ...handlers: [H<E, MergePath<BasePath, P>, I, R>, ...H<E, MergePath<BasePath, P>, I, R>[]]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath, MergePath<BasePath, P>>;
|
||||
<M extends string, const Ps extends string[], I extends Input = BlankInput, R extends HandlerResponse<any> = any, E2 extends Env = E>(methods: M | M[], paths: Ps, ...handlers: H<E2, MergePath<BasePath, Ps[number]>, I, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, Ps[number]>, I, MergeTypedResponse<R>>, BasePath, Ps extends [...string[], infer LastPath extends string] ? MergePath<BasePath, LastPath> : never>;
|
||||
}
|
||||
type ToSchemaOutput<RorO, I extends Input | Input['in']> = RorO extends TypedResponse<infer T, infer U, infer F> ? {
|
||||
output: unknown extends T ? {} : T;
|
||||
outputFormat: I extends {
|
||||
outputFormat: string;
|
||||
} ? I['outputFormat'] : F;
|
||||
status: U;
|
||||
} : {
|
||||
output: unknown extends RorO ? {} : RorO;
|
||||
outputFormat: unknown extends RorO ? 'json' : I extends {
|
||||
outputFormat: string;
|
||||
} ? I['outputFormat'] : 'json';
|
||||
status: StatusCode;
|
||||
};
|
||||
export type ToSchema<M extends string, P extends string, I extends Input | Input['in'], RorO> = IsAny<RorO> extends true ? { [K in P]: { [K2 in M as AddDollar<K2>]: {
|
||||
input: AddParam<ExtractInput<I>, P>;
|
||||
output: {};
|
||||
outputFormat: ResponseFormat;
|
||||
status: StatusCode;
|
||||
}; }; } : [RorO] extends [never] ? {} : [RorO] extends [Promise<void>] ? {} : { [K in P]: { [K2 in M as AddDollar<K2>]: Simplify<{
|
||||
input: AddParam<ExtractInput<I>, P>;
|
||||
} & ToSchemaOutput<RorO, I>>; }; };
|
||||
export type Schema = {
|
||||
[Path: string]: {
|
||||
[Method: `$${Lowercase<string>}`]: Endpoint;
|
||||
};
|
||||
};
|
||||
type AddSchemaIfHasResponse<Merged, S extends Schema, M extends string, P extends string, I extends Input | Input['in'], BasePath extends string> = [Merged] extends [Promise<void>] ? S : S & ToSchema<M, MergePath<BasePath, P>, I, Merged>;
|
||||
export type Endpoint = {
|
||||
input: any;
|
||||
output: any;
|
||||
outputFormat: ResponseFormat;
|
||||
status: StatusCode;
|
||||
};
|
||||
type ExtractParams<Path extends string> = string extends Path ? Record<string, string> : Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string; } : Path extends `${infer _Start}:${infer Param}` ? { [K in Param]: string; } : never;
|
||||
type FlattenIfIntersect<T> = T extends (infer O) ? { [K in keyof O]: O[K]; } : never;
|
||||
export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> = { [P in keyof OrigSchema as MergePath<SubPath, P & string>]: [OrigSchema[P]] extends [Record<string, Endpoint>] ? { [M in keyof OrigSchema[P]]: MergeEndpointParamsWithPath<OrigSchema[P][M], SubPath>; } : never; };
|
||||
type MergeEndpointParamsWithPath<T extends Endpoint, SubPath extends string> = T extends unknown ? {
|
||||
input: T['input'] extends {
|
||||
param: infer _;
|
||||
} ? ExtractParams<SubPath> extends never ? T['input'] : FlattenIfIntersect<T['input'] & {
|
||||
param: { [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}` ? Prefix : K]: string; };
|
||||
}> : RemoveBlankRecord<ExtractParams<SubPath>> extends never ? T['input'] : T['input'] & {
|
||||
param: { [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}` ? Prefix : K]: string; };
|
||||
};
|
||||
output: T['output'];
|
||||
outputFormat: T['outputFormat'];
|
||||
status: T['status'];
|
||||
} : never;
|
||||
export type AddParam<I, P extends string> = ParamKeys<P> extends never ? I : I extends {
|
||||
param: infer _;
|
||||
} ? I : I & {
|
||||
param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>>;
|
||||
};
|
||||
type AddDollar<T extends string> = `$${Lowercase<T>}`;
|
||||
export type MergePath<A extends string, B extends string> = B extends '' ? MergePath<A, '/'> : A extends '' ? B : A extends '/' ? B : A extends `${infer P}/` ? B extends `/${infer Q}` ? `${P}/${Q}` : `${P}/${B}` : B extends `/${infer Q}` ? Q extends '' ? A : `${A}/${Q}` : `${A}/${B}`;
|
||||
export type KnownResponseFormat = 'json' | 'text' | 'redirect';
|
||||
export type ResponseFormat = KnownResponseFormat | string;
|
||||
export type TypedResponse<T = unknown, U extends StatusCode = StatusCode, F extends ResponseFormat = T extends string ? 'text' : T extends JSONValue ? 'json' : ResponseFormat> = {
|
||||
_data: T;
|
||||
_status: U;
|
||||
_format: F;
|
||||
};
|
||||
type MergeTypedResponse<T> = T extends Promise<void> ? T : T extends Promise<infer T2> ? T2 extends TypedResponse ? T2 : TypedResponse : T extends TypedResponse ? T : TypedResponse;
|
||||
type ExtractTypedResponseOnly<T> = T extends TypedResponse ? T : never;
|
||||
type MergeMiddlewareResponse<T> = T extends ((c: any, next: any) => Promise<infer R>) ? Exclude<R, void> extends never ? never : Exclude<R, void> extends Response | TypedResponse<any, any, any> ? ExtractTypedResponseOnly<Exclude<R, void>> : never : T extends ((c: any, next: any) => infer R) ? R extends Response | TypedResponse<any, any, any> ? ExtractTypedResponseOnly<R> : never : never;
|
||||
export type FormValue = string | Blob;
|
||||
export type ParsedFormValue = string | File;
|
||||
export type ValidationTargets<T extends FormValue = ParsedFormValue, P extends string = string> = {
|
||||
json: any;
|
||||
form: Record<string, T | T[]>;
|
||||
query: Record<string, string | string[]>;
|
||||
param: Record<P, P extends `${infer _}?` ? string | undefined : string>;
|
||||
header: Record<RequestHeader | CustomHeader, string>;
|
||||
cookie: Record<string, string>;
|
||||
};
|
||||
type ParamKey<Component> = Component extends `:${infer NameWithPattern}` ? NameWithPattern extends `${infer Name}{${infer Rest}` ? Rest extends `${infer _Pattern}?` ? `${Name}?` : Name : NameWithPattern : never;
|
||||
export type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
|
||||
export type ParamKeyToRecord<T extends string> = T extends `${infer R}?` ? Record<R, string | undefined> : { [K in T]: string; };
|
||||
export type InputToDataByTarget<T extends Input['out'], Target extends keyof ValidationTargets> = T extends { [K in Target]: infer R; } ? R : never;
|
||||
export type RemoveQuestion<T> = T extends `${infer R}?` ? R : T;
|
||||
export type ExtractSchema<T> = UnionToIntersection<T extends Hono<infer _, infer S, any, any> ? S : never>;
|
||||
export type ExtractSchemaForStatusCode<T, Status extends number> = { [Path in keyof ExtractSchema<T>]: { [Method in keyof ExtractSchema<T>[Path]]: Extract<ExtractSchema<T>[Path][Method], {
|
||||
status: Status;
|
||||
}>; }; };
|
||||
export type ExtractHandlerResponse<T> = T extends ((c: any, next: any) => Promise<infer R>) ? Exclude<R, void> extends never ? never : Exclude<R, void> extends Response | TypedResponse<any, any, any> ? Exclude<R, void> : never : T extends ((c: any, next: any) => infer R) ? R extends Response | TypedResponse<any, any, any> ? R : never : never;
|
||||
type ProcessHead<T> = IfAnyThenEmptyObject<T extends Env ? (Env extends T ? {} : T) : T>;
|
||||
export type IntersectNonAnyTypes<T extends any[]> = T extends [infer Head, ...infer Rest] ? ProcessHead<Head> & IntersectNonAnyTypes<Rest> : {};
|
||||
export declare abstract class FetchEventLike {
|
||||
abstract readonly request: Request;
|
||||
abstract respondWith(promise: Response | Promise<Response>): void;
|
||||
abstract passThroughOnException(): void;
|
||||
abstract waitUntil(promise: Promise<void>): void;
|
||||
}
|
||||
//#endregion
|
||||
export {};
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { HonoRequest } from "../request.js";
|
||||
//#region src/utils/body.d.ts
|
||||
type BodyDataValueDot = {
|
||||
[x: string]: string | File | BodyDataValueDot;
|
||||
};
|
||||
type BodyDataValueDotAll = {
|
||||
[x: string]: string | File | (string | File)[] | BodyDataValueDotAll;
|
||||
};
|
||||
type SimplifyBodyData<T> = { [K in keyof T]: string | File | (string | File)[] | BodyDataValueDotAll extends T[K] ? string | File | (string | File)[] | BodyDataValueDotAll : string | File | BodyDataValueDot extends T[K] ? string | File | BodyDataValueDot : string | File | (string | File)[] extends T[K] ? string | File | (string | File)[] : string | File; } & {};
|
||||
type BodyDataValueComponent<T> = string | File | (T extends {
|
||||
all: false;
|
||||
} ? never : T extends {
|
||||
all: true;
|
||||
} | {
|
||||
all: boolean;
|
||||
} ? (string | File)[] : never);
|
||||
type BodyDataValueObject<T> = {
|
||||
[key: string]: BodyDataValueComponent<T> | BodyDataValueObject<T>;
|
||||
};
|
||||
type BodyDataValue<T> = BodyDataValueComponent<T> | (T extends {
|
||||
dot: false;
|
||||
} ? never : T extends {
|
||||
dot: true;
|
||||
} | {
|
||||
dot: boolean;
|
||||
} ? BodyDataValueObject<T> : never);
|
||||
export type BodyData<T extends Partial<ParseBodyOptions> = {}> = SimplifyBodyData<Record<string, BodyDataValue<T>>>;
|
||||
export type ParseBodyOptions = {
|
||||
/**
|
||||
* Determines whether all fields with multiple values should be parsed as arrays.
|
||||
* @default false
|
||||
* @example
|
||||
* const data = new FormData()
|
||||
* data.append('file', 'aaa')
|
||||
* data.append('file', 'bbb')
|
||||
* data.append('message', 'hello')
|
||||
*
|
||||
* If all is false:
|
||||
* parseBody should return { file: 'bbb', message: 'hello' }
|
||||
*
|
||||
* If all is true:
|
||||
* parseBody should return { file: ['aaa', 'bbb'], message: 'hello' }
|
||||
*/
|
||||
all: boolean;
|
||||
/**
|
||||
* Determines whether all fields with dot notation should be parsed as nested objects.
|
||||
* @default false
|
||||
* @example
|
||||
* const data = new FormData()
|
||||
* data.append('obj.key1', 'value1')
|
||||
* data.append('obj.key2', 'value2')
|
||||
*
|
||||
* If dot is false:
|
||||
* parseBody should return { 'obj.key1': 'value1', 'obj.key2': 'value2' }
|
||||
*
|
||||
* If dot is true:
|
||||
* parseBody should return { obj: { key1: 'value1', key2: 'value2' } }
|
||||
*/
|
||||
dot: boolean;
|
||||
};
|
||||
/**
|
||||
* Parses the body of a request based on the provided options.
|
||||
*
|
||||
* @template T - The type of the parsed body data.
|
||||
* @param {HonoRequest | Request} request - The request object to parse.
|
||||
* @param {Partial<ParseBodyOptions>} [options] - Options for parsing the body.
|
||||
* @returns {Promise<T>} The parsed body data.
|
||||
*/
|
||||
interface ParseBody {
|
||||
<Options extends Partial<ParseBodyOptions>, T extends BodyData<Options>>(request: HonoRequest | Request, options?: Options): Promise<T>;
|
||||
<T extends BodyData>(request: HonoRequest | Request, options?: Partial<ParseBodyOptions>): Promise<T>;
|
||||
}
|
||||
export declare const parseBody: ParseBody;
|
||||
//#endregion
|
||||
export {};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//#region src/utils/headers.d.ts
|
||||
/**
|
||||
* @module
|
||||
* HTTP Headers utility.
|
||||
*/
|
||||
export type RequestHeader = 'A-IM' | 'Accept' | 'Accept-Additions' | 'Accept-CH' | 'Accept-Charset' | 'Accept-Datetime' | 'Accept-Encoding' | 'Accept-Features' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Query' | 'Accept-Ranges' | 'Accept-Signature' | 'Access-Control' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Activate-Storage-Access' | 'Age' | 'Allow' | 'ALPN' | 'Alt-Svc' | 'Alt-Used' | 'Alternates' | 'AMP-Cache-Transform' | 'Apply-To-Redirect-Ref' | 'Authentication-Control' | 'Authentication-Info' | 'Authorization' | 'Available-Dictionary' | 'C-Ext' | 'C-Man' | 'C-Opt' | 'C-PEP' | 'C-PEP-Info' | 'Cache-Control' | 'Cache-Group-Invalidation' | 'Cache-Groups' | 'Cache-Status' | 'Cal-Managed-ID' | 'CalDAV-Timezones' | 'Capsule-Protocol' | 'CDN-Cache-Control' | 'CDN-Loop' | 'Cert-Not-After' | 'Cert-Not-Before' | 'Clear-Site-Data' | 'Client-Cert' | 'Client-Cert-Chain' | 'Close' | 'CMCD-Object' | 'CMCD-Request' | 'CMCD-Session' | 'CMCD-Status' | 'CMSD-Dynamic' | 'CMSD-Static' | 'Concealed-Auth-Export' | 'Configuration-Context' | 'Connection' | 'Content-Base' | 'Content-Digest' | 'Content-Disposition' | 'Content-Encoding' | 'Content-ID' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-MD5' | 'Content-Range' | 'Content-Script-Type' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Style-Type' | 'Content-Type' | 'Content-Version' | 'Cookie' | 'Cookie2' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Embedder-Policy-Report-Only' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Opener-Policy-Report-Only' | 'Cross-Origin-Resource-Policy' | 'CTA-Common-Access-Token' | 'DASL' | 'Date' | 'DAV' | 'Default-Style' | 'Delta-Base' | 'Deprecation' | 'Depth' | 'Derived-From' | 'Destination' | 'Detached-JWS' | 'Differential-ID' | 'Dictionary-ID' | 'Digest' | 'DPoP' | 'DPoP-Nonce' | 'Early-Data' | 'EDIINT-Features' | 'ETag' | 'Expect' | 'Expect-CT' | 'Expires' | 'Ext' | 'Forwarded' | 'From' | 'GetProfile' | 'Hobareg' | 'Host' | 'HTTP2-Settings' | 'If' | 'If-Match' | 'If-Modified-Since' | 'If-None-Match' | 'If-Range' | 'If-Schedule-Tag-Match' | 'If-Unmodified-Since' | 'IM' | 'Include-Referred-Token-Binding-ID' | 'Incremental' | 'Isolation' | 'Keep-Alive' | 'Label' | 'Last-Event-ID' | 'Last-Modified' | 'Link' | 'Link-Template' | 'Location' | 'Lock-Token' | 'Man' | 'Max-Forwards' | 'Memento-Datetime' | 'Meter' | 'Method-Check' | 'Method-Check-Expires' | 'MIME-Version' | 'Negotiate' | 'NEL' | 'OData-EntityId' | 'OData-Isolation' | 'OData-MaxVersion' | 'OData-Version' | 'Opt' | 'Optional-WWW-Authenticate' | 'Ordering-Type' | 'Origin' | 'Origin-Agent-Cluster' | 'OSCORE' | 'OSLC-Core-Version' | 'Overwrite' | 'P3P' | 'PEP' | 'PEP-Info' | 'Permissions-Policy' | 'PICS-Label' | 'Ping-From' | 'Ping-To' | 'Position' | 'Pragma' | 'Prefer' | 'Preference-Applied' | 'Priority' | 'ProfileObject' | 'Protocol' | 'Protocol-Info' | 'Protocol-Query' | 'Protocol-Request' | 'Proxy-Authenticate' | 'Proxy-Authentication-Info' | 'Proxy-Authorization' | 'Proxy-Features' | 'Proxy-Instruction' | 'Proxy-Status' | 'Public' | 'Public-Key-Pins' | 'Public-Key-Pins-Report-Only' | 'Range' | 'Redirect-Ref' | 'Referer' | 'Referer-Root' | 'Referrer-Policy' | 'Refresh' | 'Repeatability-Client-ID' | 'Repeatability-First-Sent' | 'Repeatability-Request-ID' | 'Repeatability-Result' | 'Replay-Nonce' | 'Reporting-Endpoints' | 'Repr-Digest' | 'Retry-After' | 'Safe' | 'Schedule-Reply' | 'Schedule-Tag' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-Storage-Access' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Sec-Purpose' | 'Sec-Token-Binding' | 'Sec-WebSocket-Accept' | 'Sec-WebSocket-Extensions' | 'Sec-WebSocket-Key' | 'Sec-WebSocket-Protocol' | 'Sec-WebSocket-Version' | 'Security-Scheme' | 'Server' | 'Server-Timing' | 'Set-Cookie' | 'Set-Cookie2' | 'Set-Txn' | 'SetProfile' | 'Signature' | 'Signature-Input' | 'SLUG' | 'SoapAction' | 'Status-URI' | 'Strict-Transport-Security' | 'Sunset' | 'Surrogate-Capability' | 'Surrogate-Control' | 'TCN' | 'TE' | 'Timeout' | 'Timing-Allow-Origin' | 'Topic' | 'Traceparent' | 'Tracestate' | 'Trailer' | 'Transfer-Encoding' | 'TTL' | 'Unencoded-Digest' | 'Upgrade' | 'Urgency' | 'URI' | 'Use-As-Dictionary' | 'User-Agent' | 'Variant-Vary' | 'Vary' | 'Via' | 'Want-Content-Digest' | 'Want-Digest' | 'Want-Repr-Digest' | 'Want-Unencoded-Digest' | 'Warning' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-Frame-Options';
|
||||
export type ResponseHeader = 'Accept-Query' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Activate-Storage-Access' | 'Age' | 'Allow' | 'Cache-Control' | 'Cache-Group-Invalidation' | 'Cache-Groups' | 'Clear-Site-Data' | 'Content-Disposition' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Range' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Type' | 'Cookie' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Resource-Policy' | 'Date' | 'ETag' | 'Expires' | 'Incremental' | 'Last-Modified' | 'Location' | 'Permissions-Policy' | 'Pragma' | 'Retry-After' | 'Save-Data' | 'Sec-CH-Prefers-Color-Scheme' | 'Sec-CH-Prefers-Reduced-Motion' | 'Sec-CH-UA' | 'Sec-CH-UA-Arch' | 'Sec-CH-UA-Bitness' | 'Sec-CH-UA-Form-Factor' | 'Sec-CH-UA-Full-Version' | 'Sec-CH-UA-Full-Version-List' | 'Sec-CH-UA-Mobile' | 'Sec-CH-UA-Model' | 'Sec-CH-UA-Platform' | 'Sec-CH-UA-Platform-Version' | 'Sec-CH-UA-WoW64' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Server' | 'Server-Timing' | 'Service-Worker-Navigation-Preload' | 'Set-Cookie' | 'Set-Txn' | 'Strict-Transport-Security' | 'Timing-Allow-Origin' | 'Trailer' | 'Transfer-Encoding' | 'Unencoded-Digest' | 'Upgrade' | 'Vary' | 'Want-Unencoded-Digest' | 'Warning' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-DNS-Prefetch-Control' | 'X-Frame-Options' | 'X-Permitted-Cross-Domain-Policies' | 'X-Powered-By' | 'X-Robots-Tag' | 'X-XSS-Protection';
|
||||
export type AcceptHeader = 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Ranges';
|
||||
export type CustomHeader = string & {};
|
||||
//#endregion
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//#region src/utils/http-status.d.ts
|
||||
/**
|
||||
* @module
|
||||
* HTTP Status utility.
|
||||
*/
|
||||
export type InfoStatusCode = 100 | 101 | 102 | 103;
|
||||
export type SuccessStatusCode = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226;
|
||||
export type DeprecatedStatusCode = 305 | 306;
|
||||
export type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | DeprecatedStatusCode | 307 | 308;
|
||||
export type ClientErrorStatusCode = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451;
|
||||
export type ServerErrorStatusCode = 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511;
|
||||
/**
|
||||
* `UnofficialStatusCode` can be used to specify an unofficial status code.
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* app.get('/unknown', (c) => {
|
||||
* return c.text("Unknown Error", 520 as UnofficialStatusCode)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export type UnofficialStatusCode = -1;
|
||||
/**
|
||||
* @deprecated
|
||||
* Use `UnofficialStatusCode` instead.
|
||||
*/
|
||||
export type UnOfficalStatusCode = UnofficialStatusCode;
|
||||
/**
|
||||
* If you want to use an unofficial status, use `UnofficialStatusCode`.
|
||||
*/
|
||||
export type StatusCode = InfoStatusCode | SuccessStatusCode | RedirectStatusCode | ClientErrorStatusCode | ServerErrorStatusCode | UnofficialStatusCode;
|
||||
export type ContentlessStatusCode = 101 | 204 | 205 | 304;
|
||||
export type ContentfulStatusCode = Exclude<StatusCode, ContentlessStatusCode>;
|
||||
//#endregion
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
//#region src/utils/mime.d.ts
|
||||
/**
|
||||
* @module
|
||||
* MIME utility.
|
||||
*/
|
||||
export declare const getMimeType: (filename: string, mimes?: Record<string, string>) => string | undefined;
|
||||
export declare const getExtension: (mimeType: string) => string | undefined;
|
||||
/**
|
||||
* Union types for BaseMime
|
||||
*/
|
||||
export type BaseMime = (typeof _baseMimes)[keyof typeof _baseMimes];
|
||||
declare const _baseMimes: {
|
||||
readonly aac: "audio/aac";
|
||||
readonly avi: "video/x-msvideo";
|
||||
readonly avif: "image/avif";
|
||||
readonly av1: "video/av1";
|
||||
readonly bin: "application/octet-stream";
|
||||
readonly bmp: "image/bmp";
|
||||
readonly css: "text/css; charset=utf-8";
|
||||
readonly csv: "text/csv; charset=utf-8";
|
||||
readonly eot: "application/vnd.ms-fontobject";
|
||||
readonly epub: "application/epub+zip";
|
||||
readonly gif: "image/gif";
|
||||
readonly gz: "application/gzip";
|
||||
readonly htm: "text/html; charset=utf-8";
|
||||
readonly html: "text/html; charset=utf-8";
|
||||
readonly ico: "image/x-icon";
|
||||
readonly ics: "text/calendar; charset=utf-8";
|
||||
readonly jpeg: "image/jpeg";
|
||||
readonly jpg: "image/jpeg";
|
||||
readonly js: "text/javascript; charset=utf-8";
|
||||
readonly json: "application/json";
|
||||
readonly jsonld: "application/ld+json";
|
||||
readonly map: "application/json";
|
||||
readonly mid: "audio/x-midi";
|
||||
readonly midi: "audio/x-midi";
|
||||
readonly mjs: "text/javascript; charset=utf-8";
|
||||
readonly mp3: "audio/mpeg";
|
||||
readonly mp4: "video/mp4";
|
||||
readonly mpeg: "video/mpeg";
|
||||
readonly oga: "audio/ogg";
|
||||
readonly ogv: "video/ogg";
|
||||
readonly ogx: "application/ogg";
|
||||
readonly opus: "audio/opus";
|
||||
readonly otf: "font/otf";
|
||||
readonly pdf: "application/pdf";
|
||||
readonly png: "image/png";
|
||||
readonly rtf: "application/rtf";
|
||||
readonly svg: "image/svg+xml; charset=utf-8";
|
||||
readonly tif: "image/tiff";
|
||||
readonly tiff: "image/tiff";
|
||||
readonly ts: "video/mp2t";
|
||||
readonly ttf: "font/ttf";
|
||||
readonly txt: "text/plain; charset=utf-8";
|
||||
readonly wasm: "application/wasm";
|
||||
readonly webm: "video/webm";
|
||||
readonly weba: "audio/webm";
|
||||
readonly webmanifest: "application/manifest+json";
|
||||
readonly webp: "image/webp";
|
||||
readonly woff: "font/woff";
|
||||
readonly woff2: "font/woff2";
|
||||
readonly xhtml: "application/xhtml+xml; charset=utf-8";
|
||||
readonly xml: "application/xml; charset=utf-8";
|
||||
readonly zip: "application/zip";
|
||||
readonly '3gp': "video/3gpp";
|
||||
readonly '3g2': "video/3gpp2";
|
||||
readonly gltf: "model/gltf+json";
|
||||
readonly glb: "model/gltf-binary";
|
||||
};
|
||||
declare const baseMimes: Record<string, BaseMime>;
|
||||
//#endregion
|
||||
export { baseMimes as mimes };
|
||||
export {};
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
//#region src/utils/types.d.ts
|
||||
/**
|
||||
* @module
|
||||
* Types utility.
|
||||
*/
|
||||
export type Expect<T extends true> = T;
|
||||
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
|
||||
export type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true;
|
||||
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
||||
export type RemoveBlankRecord<T> = T extends Record<infer K, unknown> ? (K extends string ? T : never) : never;
|
||||
export type IfAnyThenEmptyObject<T> = 0 extends 1 & T ? {} : T;
|
||||
export type JSONPrimitive = string | boolean | number | null;
|
||||
export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[];
|
||||
export type JSONObject = {
|
||||
[key: string]: JSONPrimitive | JSONArray | JSONObject | object | InvalidJSONValue;
|
||||
};
|
||||
export type InvalidJSONValue = undefined | symbol | ((...args: unknown[]) => unknown);
|
||||
type InvalidToNull<T> = T extends InvalidJSONValue ? null : T;
|
||||
type IsInvalid<T> = T extends InvalidJSONValue ? true : false;
|
||||
/**
|
||||
* symbol keys are omitted through `JSON.stringify`
|
||||
*/
|
||||
type OmitSymbolKeys<T> = { [K in keyof T as K extends symbol ? never : K]: T[K]; };
|
||||
export type JSONValue = JSONObject | JSONArray | JSONPrimitive;
|
||||
/**
|
||||
* Convert a type to a JSON-compatible type.
|
||||
*
|
||||
* Non-JSON values such as `Date` implement `.toJSON()`,
|
||||
* so they can be transformed to a value assignable to `JSONObject`
|
||||
*
|
||||
* `JSON.stringify()` throws a `TypeError` when it encounters a `bigint` value,
|
||||
* unless a custom `replacer` function or `.toJSON()` method is provided.
|
||||
*
|
||||
* This behavior can be controlled by the `TError` generic type parameter,
|
||||
* which defaults to `bigint | ReadonlyArray<bigint>`.
|
||||
* You can set it to `never` to disable this check.
|
||||
*/
|
||||
export type JSONParsed<T, TError = bigint | ReadonlyArray<bigint>> = T extends {
|
||||
toJSON(): infer J;
|
||||
} ? (() => J) extends (() => JSONPrimitive) ? J : (() => J) extends (() => {
|
||||
toJSON(): unknown;
|
||||
}) ? {} : JSONParsed<J, TError> : T extends JSONPrimitive ? T : T extends InvalidJSONValue ? never : T extends ReadonlyArray<unknown> ? { [K in keyof T]: JSONParsed<InvalidToNull<T[K]>, TError>; } extends (infer A) ? A extends ReadonlyArray<unknown> ? A : JSONParsed<InvalidToNull<T[number]>, TError>[] : never : T extends Set<unknown> | Map<unknown, unknown> | Record<string, never> ? {} : T extends object ? T[keyof T] extends TError ? never : { [K in keyof OmitSymbolKeys<T> as IsInvalid<T[K]> extends true ? never : K]: boolean extends IsInvalid<T[K]> ? JSONParsed<T[K], TError> | undefined : JSONParsed<T[K], TError>; } : T extends unknown ? T extends TError ? never : JSONValue : never;
|
||||
/**
|
||||
* Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
|
||||
* @copyright from sindresorhus/type-fest
|
||||
*/
|
||||
export type Simplify<T> = { [KeyType in keyof T]: T[KeyType]; } & {};
|
||||
/**
|
||||
* A simple extension of Simplify that will deeply traverse array elements.
|
||||
*/
|
||||
export type SimplifyDeepArray<T> = T extends any[] ? { [E in keyof T]: SimplifyDeepArray<T[E]>; } : Simplify<T>;
|
||||
export type InterfaceToType<T> = T extends Function ? T : { [K in keyof T]: InterfaceToType<T[K]>; };
|
||||
export type RequiredKeysOf<BaseType extends object> = Exclude<{ [Key in keyof BaseType]: BaseType extends Record<Key, BaseType[Key]> ? Key : never; }[keyof BaseType], undefined>;
|
||||
export type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
|
||||
export type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false;
|
||||
/**
|
||||
* String literal types with auto-completion
|
||||
* @see https://github.com/Microsoft/TypeScript/issues/29729
|
||||
*/
|
||||
export type StringLiteralUnion<T> = T | (string & Record<never, never>);
|
||||
//#endregion
|
||||
export {};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { InferInput } from "./utils.js";
|
||||
import { ValidationFunction, validator } from "./validator.js";
|
||||
export { type InferInput, type ValidationFunction, validator };
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { UnionToIntersection } from "../utils/types.js";
|
||||
import { FormValue, ParsedFormValue, ValidationTargets } from "../types.js";
|
||||
//#region src/validator/utils.d.ts
|
||||
/**
|
||||
* Checks if T is a literal union type (e.g., 'asc' | 'desc')
|
||||
* that should be preserved in input types.
|
||||
* Returns true for union literals, false for single literals or wide types.
|
||||
*/
|
||||
export type IsLiteralUnion<T, Base> = [Exclude<T, undefined>] extends [Base] ? [Exclude<T, undefined>] extends [UnionToIntersection<Exclude<T, undefined>>] ? false : true : false;
|
||||
type IsOptionalUnion<T> = [unknown] extends [T] ? false : undefined extends T ? true : false;
|
||||
type SimplifyDeep<T> = { [K in keyof T]: T[K]; } & {};
|
||||
type InferInputInner<Output, Target extends keyof ValidationTargets, T extends FormValue> = SimplifyDeep<{ [K in keyof Output]: IsLiteralUnion<Output[K], string> extends true ? Output[K] : IsOptionalUnion<Output[K]> extends true ? Output[K] : Target extends 'form' ? T | T[] : Target extends 'query' ? string | string[] : Target extends 'param' ? string : Target extends 'header' ? string : Target extends 'cookie' ? string : unknown; }>;
|
||||
/**
|
||||
* Utility type to infer input types for validation targets.
|
||||
* Preserves literal union types (e.g., 'asc' | 'desc') while using
|
||||
* the default ValidationTargets type for other values.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // In @hono/zod-validator or similar:
|
||||
* type Input = InferInput<z.input<Schema>, 'query'>
|
||||
* // { orderBy: 'asc' | 'desc', page: string | string[] }
|
||||
* ```
|
||||
*/
|
||||
export type InferInput<Output, Target extends keyof ValidationTargets, T extends FormValue = ParsedFormValue> = [Exclude<Output, undefined>] extends [never] ? {} : [Exclude<Output, undefined>] extends [object] ? undefined extends Output ? SimplifyDeep<InferInputInner<Exclude<Output, undefined>, Target, T>> | undefined : SimplifyDeep<InferInputInner<Output, Target, T>> : {};
|
||||
//#endregion
|
||||
export {};
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { Env, FormValue, MiddlewareHandler, TypedResponse, ValidationTargets } from "../types.js";
|
||||
import { Context } from "../context.js";
|
||||
import { InferInput } from "./utils.js";
|
||||
//#region src/validator/validator.d.ts
|
||||
type ValidationTargetKeysWithBody = 'form' | 'json';
|
||||
type ValidationTargetByMethod<M> = M extends 'get' | 'head' ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody> : keyof ValidationTargets;
|
||||
export type ValidationFunction<InputType, OutputType, E extends Env = {}, P extends string = string> = (value: InputType, c: Context<E, P>) => OutputType | TypedResponse | Promise<OutputType> | Promise<TypedResponse>;
|
||||
export type ExtractValidationResponse<VF> = VF extends ((value: any, c: any) => infer R) ? R extends Promise<infer PR> ? PR extends TypedResponse<infer T, infer S, infer F> ? TypedResponse<T, S, F> : PR extends Response ? PR : PR extends undefined ? never : never : R extends TypedResponse<infer T, infer S, infer F> ? TypedResponse<T, S, F> : R extends Response ? R : R extends undefined ? never : never : never;
|
||||
export declare const validator: <InputType, P extends string, M extends string, U extends ValidationTargetByMethod<M>, P2 extends string = P, VF extends (value: unknown extends InputType ? ValidationTargets[U] : InputType, c: Context<any, P2>) => any = (value: unknown extends InputType ? ValidationTargets[U] : InputType, c: Context<any, P2>) => any, V extends {
|
||||
in: { [K in U]: K extends "json" ? unknown extends InputType ? ExtractValidatorOutput<VF> : InputType : InferInput<ExtractValidatorOutput<VF>, K, FormValue>; };
|
||||
out: { [K in U]: ExtractValidatorOutput<VF>; };
|
||||
} = {
|
||||
in: { [K in U]: K extends "json" ? unknown extends InputType ? ExtractValidatorOutput<VF> : InputType : InferInput<ExtractValidatorOutput<VF>, K, FormValue>; };
|
||||
out: { [K in U]: ExtractValidatorOutput<VF>; };
|
||||
}, E extends Env = any>(target: U, validationFunc: VF) => MiddlewareHandler<E, P, V, ExtractValidationResponse<VF>>;
|
||||
export type ExtractValidatorOutput<VF> = VF extends ((value: any, c: any) => infer R) ? R extends Promise<infer PR> ? PR extends Response | TypedResponse<any, any, any> ? never : PR : R extends Response | TypedResponse<any, any, any> ? never : R : never;
|
||||
//#endregion
|
||||
export {};
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
import { bufferToFormData } from "./buffer.js";
|
||||
//#region src/utils/body.ts
|
||||
const MAX_NESTED_OBJECTS = 1e4;
|
||||
const isRawRequest = (request) => "headers" in request;
|
||||
const parseBody = async (request, options = Object.create(null)) => {
|
||||
const { all = false, dot = false } = options;
|
||||
const mediaType = (isRawRequest(request) ? request.headers : request.raw.headers).get("Content-Type")?.split(";")[0].trim().toLowerCase();
|
||||
if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") return parseFormData(request, {
|
||||
all,
|
||||
dot
|
||||
});
|
||||
return {};
|
||||
};
|
||||
/**
|
||||
* Parses form data from a request.
|
||||
*
|
||||
* @template T - The type of the parsed body data.
|
||||
* @param {HonoRequest | Request} request - The request object containing form data.
|
||||
* @param {ParseBodyOptions} options - Options for parsing the form data.
|
||||
* @returns {Promise<T>} The parsed body data.
|
||||
*/
|
||||
async function parseFormData(request, options) {
|
||||
if (!isRawRequest(request) && request.bodyCache.formData) return convertFormDataToBodyData(await request.bodyCache.formData, options);
|
||||
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
||||
const arrayBuffer = await request.arrayBuffer();
|
||||
const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
|
||||
if (!isRawRequest(request)) request.bodyCache.formData = formDataPromise;
|
||||
const formData = await formDataPromise;
|
||||
if (formData) return convertFormDataToBodyData(formData, options);
|
||||
return {};
|
||||
}
|
||||
/**
|
||||
* Converts form data to body data based on the provided options.
|
||||
*
|
||||
* @template T - The type of the parsed body data.
|
||||
* @param {FormData} formData - The form data to convert.
|
||||
* @param {ParseBodyOptions} options - Options for parsing the form data.
|
||||
* @returns {T} The converted body data.
|
||||
*/
|
||||
function convertFormDataToBodyData(formData, options) {
|
||||
const form = Object.create(null);
|
||||
const nestingState = { count: 0 };
|
||||
formData.forEach((value, key) => {
|
||||
if (!(options.all || key.endsWith("[]"))) form[key] = value;
|
||||
else handleParsingAllValues(form, key, value);
|
||||
});
|
||||
if (options.dot) Object.entries(form).forEach(([key, value]) => {
|
||||
if (key.includes(".")) {
|
||||
handleParsingNestedValues(form, key, value, nestingState);
|
||||
delete form[key];
|
||||
}
|
||||
});
|
||||
return form;
|
||||
}
|
||||
/**
|
||||
* Handles parsing all values for a given key, supporting multiple values as arrays.
|
||||
*
|
||||
* @param {BodyData} form - The form data object.
|
||||
* @param {string} key - The key to parse.
|
||||
* @param {FormDataEntryValue} value - The value to assign.
|
||||
*/
|
||||
const handleParsingAllValues = (form, key, value) => {
|
||||
if (form[key] !== void 0) {
|
||||
if (Array.isArray(form[key])) form[key].push(value);
|
||||
else form[key] = [form[key], value];
|
||||
} else if (!key.endsWith("[]")) form[key] = value;
|
||||
else form[key] = [value];
|
||||
};
|
||||
/**
|
||||
* Handles parsing nested values using dot notation keys.
|
||||
*
|
||||
* @param {BodyData} form - The form data object.
|
||||
* @param {string} key - The dot notation key.
|
||||
* @param {BodyDataValue} value - The value to assign.
|
||||
*/
|
||||
const handleParsingNestedValues = (form, key, value, state) => {
|
||||
if (/(?:^|\.)__proto__\./.test(key)) return;
|
||||
let nestedForm = form;
|
||||
const keys = key.split(".", 34);
|
||||
if (keys.length > 33) throwNestingLimitExceeded();
|
||||
keys.forEach((key, index) => {
|
||||
if (index === keys.length - 1) nestedForm[key] = value;
|
||||
else {
|
||||
if (!nestedForm[key] || typeof nestedForm[key] !== "object" || Array.isArray(nestedForm[key]) || nestedForm[key] instanceof File) {
|
||||
if (state.count++ >= MAX_NESTED_OBJECTS) throwNestingLimitExceeded();
|
||||
nestedForm[key] = Object.create(null);
|
||||
}
|
||||
nestedForm = nestedForm[key];
|
||||
}
|
||||
});
|
||||
};
|
||||
const throwNestingLimitExceeded = () => {
|
||||
throw new Error("Nesting limit exceeded");
|
||||
};
|
||||
//#endregion
|
||||
export { parseBody };
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { sha256 } from "./crypto.js";
|
||||
//#region src/utils/buffer.ts
|
||||
/**
|
||||
* @module
|
||||
* Buffer utility.
|
||||
*/
|
||||
const equal = (a, b) => {
|
||||
if (a === b) return true;
|
||||
if (a.byteLength !== b.byteLength) return false;
|
||||
const va = new DataView(a);
|
||||
const vb = new DataView(b);
|
||||
let i = va.byteLength;
|
||||
while (i--) if (va.getUint8(i) !== vb.getUint8(i)) return false;
|
||||
return true;
|
||||
};
|
||||
const constantTimeEqualString = (a, b) => {
|
||||
const aLen = a.length;
|
||||
const bLen = b.length;
|
||||
const maxLen = Math.max(aLen, bLen);
|
||||
let out = aLen ^ bLen;
|
||||
for (let i = 0; i < maxLen; i++) {
|
||||
const aChar = i < aLen ? a.charCodeAt(i) : 0;
|
||||
const bChar = i < bLen ? b.charCodeAt(i) : 0;
|
||||
out |= aChar ^ bChar;
|
||||
}
|
||||
return out === 0;
|
||||
};
|
||||
const timingSafeEqualString = async (a, b, hashFunction) => {
|
||||
if (!hashFunction) hashFunction = sha256;
|
||||
const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);
|
||||
if (sa == null || sb == null || typeof sa !== "string" || typeof sb !== "string") return false;
|
||||
const hashEqual = constantTimeEqualString(sa, sb);
|
||||
const originalEqual = constantTimeEqualString(a, b);
|
||||
return hashEqual && originalEqual;
|
||||
};
|
||||
const timingSafeEqual = async (a, b, hashFunction) => {
|
||||
if (typeof a === "string" && typeof b === "string") return timingSafeEqualString(a, b, hashFunction);
|
||||
if (!hashFunction) hashFunction = sha256;
|
||||
const [sa, sb] = await Promise.all([hashFunction(a), hashFunction(b)]);
|
||||
if (!sa || !sb || typeof sa !== "string" || typeof sb !== "string") return false;
|
||||
return timingSafeEqualString(sa, sb);
|
||||
};
|
||||
const bufferToString = (buffer) => {
|
||||
if (buffer instanceof ArrayBuffer) return new TextDecoder("utf-8").decode(buffer);
|
||||
return buffer;
|
||||
};
|
||||
const bufferToFormData = (arrayBuffer, contentType) => {
|
||||
return new Response(arrayBuffer, { headers: { "Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase()) } }).formData();
|
||||
};
|
||||
//#endregion
|
||||
export { bufferToFormData, bufferToString, equal, timingSafeEqual };
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
//#region src/utils/constants.ts
|
||||
/**
|
||||
* Constant used to mark a composed handler.
|
||||
*/
|
||||
const COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
||||
//#endregion
|
||||
export { COMPOSED_HANDLER };
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
import { tryDecodeURIComponent } from "./url.js";
|
||||
//#region src/utils/cookie.ts
|
||||
/**
|
||||
* @module
|
||||
* Cookie utility.
|
||||
*/
|
||||
const algorithm = {
|
||||
name: "HMAC",
|
||||
hash: "SHA-256"
|
||||
};
|
||||
const getCryptoKey = async (secret) => {
|
||||
const secretBuf = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
||||
return await crypto.subtle.importKey("raw", secretBuf, algorithm, false, ["sign", "verify"]);
|
||||
};
|
||||
const makeSignature = async (value, secret) => {
|
||||
const key = await getCryptoKey(secret);
|
||||
const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));
|
||||
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
||||
};
|
||||
const verifySignature = async (base64Signature, value, secret) => {
|
||||
try {
|
||||
const signatureBinStr = atob(base64Signature);
|
||||
const signature = new Uint8Array(signatureBinStr.length);
|
||||
for (let i = 0, len = signatureBinStr.length; i < len; i++) signature[i] = signatureBinStr.charCodeAt(i);
|
||||
return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
|
||||
const relaxedCookieNameRegEx = /^[!#-:<>-[\]-~]+$/;
|
||||
const validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/;
|
||||
const trimCookieWhitespace = (value) => {
|
||||
let start = 0;
|
||||
let end = value.length;
|
||||
while (start < end) {
|
||||
const charCode = value.charCodeAt(start);
|
||||
if (charCode !== 32 && charCode !== 9) break;
|
||||
start++;
|
||||
}
|
||||
while (end > start) {
|
||||
const charCode = value.charCodeAt(end - 1);
|
||||
if (charCode !== 32 && charCode !== 9) break;
|
||||
end--;
|
||||
}
|
||||
return start === 0 && end === value.length ? value : value.slice(start, end);
|
||||
};
|
||||
const parse = (cookie, name) => {
|
||||
if (name && cookie.indexOf(name) === -1) return {};
|
||||
const pairs = cookie.split(";");
|
||||
const parsedCookie = Object.create(null);
|
||||
for (const pairStr of pairs) {
|
||||
const valueStartPos = pairStr.indexOf("=");
|
||||
if (valueStartPos === -1) continue;
|
||||
const cookieName = trimCookieWhitespace(pairStr.substring(0, valueStartPos));
|
||||
if (name && name !== cookieName || !relaxedCookieNameRegEx.test(cookieName) || cookieName in parsedCookie) continue;
|
||||
let cookieValue = trimCookieWhitespace(pairStr.substring(valueStartPos + 1));
|
||||
if (cookieValue.startsWith("\"") && cookieValue.endsWith("\"")) cookieValue = cookieValue.slice(1, -1);
|
||||
if (validCookieValueRegEx.test(cookieValue)) {
|
||||
parsedCookie[cookieName] = tryDecodeURIComponent(cookieValue);
|
||||
if (name) break;
|
||||
}
|
||||
}
|
||||
return parsedCookie;
|
||||
};
|
||||
const parseSigned = async (cookie, secret, name) => {
|
||||
const parsedCookie = Object.create(null);
|
||||
const secretKey = await getCryptoKey(secret);
|
||||
for (const [key, value] of Object.entries(parse(cookie, name))) {
|
||||
const signatureStartPos = value.lastIndexOf(".");
|
||||
if (signatureStartPos < 0) continue;
|
||||
const signedValue = value.substring(0, signatureStartPos);
|
||||
const signature = value.substring(signatureStartPos + 1);
|
||||
if (signature.length !== 44 || !signature.endsWith("=")) continue;
|
||||
parsedCookie[key] = await verifySignature(signature, signedValue, secretKey) ? signedValue : false;
|
||||
}
|
||||
return parsedCookie;
|
||||
};
|
||||
const _serialize = (name, value, opt = {}) => {
|
||||
if (!validCookieNameRegEx.test(name)) throw new Error("Invalid cookie name");
|
||||
let cookie = `${name}=${value}`;
|
||||
if (name.startsWith("__Secure-") && !opt.secure) throw new Error("__Secure- Cookie must have Secure attributes");
|
||||
if (name.startsWith("__Host-")) {
|
||||
if (!opt.secure) throw new Error("__Host- Cookie must have Secure attributes");
|
||||
if (opt.path !== "/") throw new Error("__Host- Cookie must have Path attributes with \"/\"");
|
||||
if (opt.domain) throw new Error("__Host- Cookie must not have Domain attributes");
|
||||
}
|
||||
for (const key of [
|
||||
"domain",
|
||||
"path",
|
||||
"sameSite",
|
||||
"priority"
|
||||
]) if (opt[key] && /[;\r\n]/.test(opt[key])) throw new Error(`${key} must not contain ";", "\\r", or "\\n"`);
|
||||
if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
|
||||
if (opt.maxAge > 3456e4) throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");
|
||||
cookie += `; Max-Age=${opt.maxAge | 0}`;
|
||||
}
|
||||
if (opt.domain && opt.prefix !== "host") cookie += `; Domain=${opt.domain}`;
|
||||
if (opt.path) cookie += `; Path=${opt.path}`;
|
||||
if (opt.expires) {
|
||||
if (opt.expires.getTime() - Date.now() > 3456e7) throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");
|
||||
cookie += `; Expires=${opt.expires.toUTCString()}`;
|
||||
}
|
||||
if (opt.httpOnly) cookie += "; HttpOnly";
|
||||
if (opt.secure) cookie += "; Secure";
|
||||
if (opt.sameSite) cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`;
|
||||
if (opt.priority) cookie += `; Priority=${opt.priority.charAt(0).toUpperCase() + opt.priority.slice(1)}`;
|
||||
if (opt.partitioned) {
|
||||
if (!opt.secure) throw new Error("Partitioned Cookie must have Secure attributes");
|
||||
cookie += "; Partitioned";
|
||||
}
|
||||
return cookie;
|
||||
};
|
||||
const serialize = (name, value, opt) => {
|
||||
value = encodeURIComponent(value);
|
||||
return _serialize(name, value, opt);
|
||||
};
|
||||
const serializeSigned = async (name, value, secret, opt = {}) => {
|
||||
const signature = await makeSignature(value, secret);
|
||||
value = `${value}.${signature}`;
|
||||
value = encodeURIComponent(value);
|
||||
return _serialize(name, value, opt);
|
||||
};
|
||||
//#endregion
|
||||
export { parse, parseSigned, serialize, serializeSigned };
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//#region src/utils/crypto.ts
|
||||
const sha256 = async (data) => {
|
||||
return await createHash(data, {
|
||||
name: "SHA-256",
|
||||
alias: "sha256"
|
||||
});
|
||||
};
|
||||
const sha1 = async (data) => {
|
||||
return await createHash(data, {
|
||||
name: "SHA-1",
|
||||
alias: "sha1"
|
||||
});
|
||||
};
|
||||
const md5 = async (data) => {
|
||||
return await createHash(data, {
|
||||
name: "MD5",
|
||||
alias: "md5"
|
||||
});
|
||||
};
|
||||
const createHash = async (data, algorithm) => {
|
||||
let sourceBuffer;
|
||||
if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) sourceBuffer = data;
|
||||
else {
|
||||
if (typeof data === "object") data = JSON.stringify(data);
|
||||
sourceBuffer = new TextEncoder().encode(String(data));
|
||||
}
|
||||
if (crypto && crypto.subtle) {
|
||||
const buffer = await crypto.subtle.digest({ name: algorithm.name }, sourceBuffer);
|
||||
return Array.prototype.map.call(new Uint8Array(buffer), (x) => ("00" + x.toString(16)).slice(-2)).join("");
|
||||
}
|
||||
return null;
|
||||
};
|
||||
//#endregion
|
||||
export { createHash, md5, sha1, sha256 };
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
//#region src/utils/html.ts
|
||||
/**
|
||||
* @module
|
||||
* HTML utility.
|
||||
*/
|
||||
const HtmlEscapedCallbackPhase = {
|
||||
Stringify: 1,
|
||||
BeforeStream: 2,
|
||||
Stream: 3
|
||||
};
|
||||
const raw = (value, callbacks) => {
|
||||
const escapedString = new String(value);
|
||||
escapedString.isEscaped = true;
|
||||
escapedString.callbacks = callbacks;
|
||||
return escapedString;
|
||||
};
|
||||
const escapeRe = /[&<>'"]/;
|
||||
const stringBufferToString = async (buffer, callbacks) => {
|
||||
let str = "";
|
||||
callbacks ||= [];
|
||||
const resolvedBuffer = await Promise.all(buffer);
|
||||
for (let i = resolvedBuffer.length - 1;; i--) {
|
||||
str += resolvedBuffer[i];
|
||||
i--;
|
||||
if (i < 0) break;
|
||||
let r = resolvedBuffer[i];
|
||||
if (typeof r === "object") callbacks.push(...r.callbacks || []);
|
||||
const isEscaped = r.isEscaped;
|
||||
r = await (typeof r === "object" ? r.toString() : r);
|
||||
if (typeof r === "object") callbacks.push(...r.callbacks || []);
|
||||
if (r.isEscaped ?? isEscaped) str += r;
|
||||
else {
|
||||
const buf = [str];
|
||||
escapeToBuffer(r, buf);
|
||||
str = buf[0];
|
||||
}
|
||||
}
|
||||
return raw(str, callbacks);
|
||||
};
|
||||
const escapeToBuffer = (str, buffer) => {
|
||||
const match = str.search(escapeRe);
|
||||
if (match === -1) {
|
||||
buffer[0] += str;
|
||||
return;
|
||||
}
|
||||
let escape;
|
||||
let index;
|
||||
let lastIndex = 0;
|
||||
for (index = match; index < str.length; index++) {
|
||||
switch (str.charCodeAt(index)) {
|
||||
case 34:
|
||||
escape = """;
|
||||
break;
|
||||
case 39:
|
||||
escape = "'";
|
||||
break;
|
||||
case 38:
|
||||
escape = "&";
|
||||
break;
|
||||
case 60:
|
||||
escape = "<";
|
||||
break;
|
||||
case 62:
|
||||
escape = ">";
|
||||
break;
|
||||
default: continue;
|
||||
}
|
||||
buffer[0] += str.substring(lastIndex, index) + escape;
|
||||
lastIndex = index + 1;
|
||||
}
|
||||
buffer[0] += str.substring(lastIndex, index);
|
||||
};
|
||||
const resolveCallbackSync = (str) => {
|
||||
const callbacks = str.callbacks;
|
||||
if (!callbacks?.length) return str;
|
||||
const buffer = [str];
|
||||
const context = {};
|
||||
callbacks.forEach((c) => c({
|
||||
phase: HtmlEscapedCallbackPhase.Stringify,
|
||||
buffer,
|
||||
context
|
||||
}));
|
||||
return buffer[0];
|
||||
};
|
||||
const resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
|
||||
if (typeof str === "object" && !(str instanceof String)) {
|
||||
if (!(str instanceof Promise)) str = str.toString();
|
||||
if (str instanceof Promise) str = await str;
|
||||
}
|
||||
const callbacks = str.callbacks;
|
||||
if (!callbacks?.length) return Promise.resolve(str);
|
||||
if (buffer) buffer[0] += str;
|
||||
else buffer = [str];
|
||||
const resStr = Promise.all(callbacks.map((c) => c({
|
||||
phase,
|
||||
buffer,
|
||||
context
|
||||
}))).then((res) => Promise.all(res.filter(Boolean).map((str) => resolveCallback(str, phase, false, context, buffer))).then(() => buffer[0]));
|
||||
if (preserveCallbacks) return raw(await resStr, callbacks);
|
||||
else return resStr;
|
||||
};
|
||||
//#endregion
|
||||
export { HtmlEscapedCallbackPhase, escapeToBuffer, raw, resolveCallback, resolveCallbackSync, stringBufferToString };
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
//#region src/utils/url.ts
|
||||
const splitPath = (path) => {
|
||||
const paths = path.split("/");
|
||||
if (paths[0] === "") paths.shift();
|
||||
return paths;
|
||||
};
|
||||
const splitRoutingPath = (routePath) => {
|
||||
const { groups, path } = extractGroupsFromPath(routePath);
|
||||
const paths = splitPath(path);
|
||||
return replaceGroupMarks(paths, groups);
|
||||
};
|
||||
const extractGroupsFromPath = (path) => {
|
||||
const groups = [];
|
||||
path = path.replace(/\{[^}]+\}/g, (match, index) => {
|
||||
const mark = `@${index}`;
|
||||
groups.push([mark, match]);
|
||||
return mark;
|
||||
});
|
||||
return {
|
||||
groups,
|
||||
path
|
||||
};
|
||||
};
|
||||
const replaceGroupMarks = (paths, groups) => {
|
||||
for (let i = groups.length - 1; i >= 0; i--) {
|
||||
const [mark] = groups[i];
|
||||
for (let j = paths.length - 1; j >= 0; j--) if (paths[j].includes(mark)) {
|
||||
paths[j] = paths[j].replace(mark, groups[i][1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
};
|
||||
const patternCache = {};
|
||||
const getPattern = (label, next) => {
|
||||
if (label === "*") return "*";
|
||||
const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
||||
if (match) {
|
||||
const cacheKey = `${label}#${next}`;
|
||||
if (!patternCache[cacheKey]) {
|
||||
if (match[2]) patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [
|
||||
cacheKey,
|
||||
match[1],
|
||||
new RegExp(`^${match[2]}(?=/${next})`)
|
||||
] : [
|
||||
label,
|
||||
match[1],
|
||||
new RegExp(`^${match[2]}$`)
|
||||
];
|
||||
else patternCache[cacheKey] = [
|
||||
label,
|
||||
match[1],
|
||||
true
|
||||
];
|
||||
}
|
||||
return patternCache[cacheKey];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const tryDecode = (str, decoder) => {
|
||||
try {
|
||||
return decoder(str);
|
||||
} catch {
|
||||
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
|
||||
try {
|
||||
return decoder(match);
|
||||
} catch {
|
||||
return match;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Try to apply decodeURI() to given string.
|
||||
* If it fails, skip invalid percent encoding or invalid UTF-8 sequences, and apply decodeURI() to the rest as much as possible.
|
||||
* @param str The string to decode.
|
||||
* @returns The decoded string that sometimes contains undecodable percent encoding.
|
||||
* @example
|
||||
* tryDecodeURI('Hello%20World') // 'Hello World'
|
||||
* tryDecodeURI('Hello%20World/%A4%A2') // 'Hello World/%A4%A2'
|
||||
*/
|
||||
const tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
||||
const getPath = (request) => {
|
||||
const url = request.url;
|
||||
const start = url.indexOf("/", url.indexOf(":") + 4);
|
||||
let i = start;
|
||||
for (; i < url.length; i++) {
|
||||
const charCode = url.charCodeAt(i);
|
||||
if (charCode === 37) {
|
||||
const queryIndex = url.indexOf("?", i);
|
||||
const hashIndex = url.indexOf("#", i);
|
||||
const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
|
||||
const path = url.slice(start, end);
|
||||
return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
|
||||
} else if (charCode === 63 || charCode === 35) break;
|
||||
}
|
||||
return url.slice(start, i);
|
||||
};
|
||||
/**
|
||||
* @deprecated
|
||||
* Use the `URL` API instead.
|
||||
*/
|
||||
const getQueryStrings = (url) => {
|
||||
const queryIndex = url.indexOf("?", 8);
|
||||
if (queryIndex === -1) return "";
|
||||
const hashIndex = url.indexOf("#", 8);
|
||||
return hashIndex === -1 ? url.slice(queryIndex) : queryIndex < hashIndex ? url.slice(queryIndex, hashIndex) : "";
|
||||
};
|
||||
const getPathNoStrict = (request) => {
|
||||
const result = getPath(request);
|
||||
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
|
||||
};
|
||||
/**
|
||||
* Merge paths.
|
||||
* @param {string[]} ...paths - The paths to merge.
|
||||
* @returns {string} The merged path.
|
||||
* @example
|
||||
* mergePath('/api', '/users') // '/api/users'
|
||||
* mergePath('/api/', '/users') // '/api/users'
|
||||
* mergePath('/api', '/') // '/api'
|
||||
* mergePath('/api/', '/') // '/api/'
|
||||
*/
|
||||
const mergePath = (base, sub, ...rest) => {
|
||||
if (rest.length) sub = mergePath(sub, ...rest);
|
||||
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
|
||||
};
|
||||
const checkOptionalParameter = (path) => {
|
||||
if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) return null;
|
||||
const segments = path.split("/");
|
||||
const results = [];
|
||||
let basePath = "";
|
||||
segments.forEach((segment) => {
|
||||
if (segment !== "" && !/\:/.test(segment)) basePath += "/" + segment;
|
||||
else if (/\:/.test(segment)) {
|
||||
if (segment.charCodeAt(segment.length - 1) === 63) {
|
||||
if (results.length === 0 && basePath === "") results.push("/");
|
||||
else results.push(basePath);
|
||||
const optionalSegment = segment.slice(0, -1);
|
||||
basePath += "/" + optionalSegment;
|
||||
results.push(basePath);
|
||||
} else basePath += "/" + segment;
|
||||
}
|
||||
});
|
||||
return results.filter((v, i, a) => a.indexOf(v) === i);
|
||||
};
|
||||
const tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str;
|
||||
const _decodeURI = (value) => {
|
||||
if (value.indexOf("+") !== -1) value = value.replace(/\+/g, " ");
|
||||
return tryDecodeURIComponent(value);
|
||||
};
|
||||
const _getQueryParam = (url, key, multiple) => {
|
||||
const hashIndex = url.indexOf("#", 8);
|
||||
if (hashIndex !== -1) url = url.slice(0, hashIndex);
|
||||
let encoded;
|
||||
if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) {
|
||||
let keyIndex = url.indexOf("?", 8);
|
||||
if (keyIndex === -1) return;
|
||||
if (!url.startsWith(key, keyIndex + 1)) keyIndex = url.indexOf(`&${key}`, keyIndex + 1);
|
||||
while (keyIndex !== -1) {
|
||||
const trailingKeyCode = url.charCodeAt(keyIndex + key.length + 1);
|
||||
if (trailingKeyCode === 61) {
|
||||
const valueIndex = keyIndex + key.length + 2;
|
||||
const endIndex = url.indexOf("&", valueIndex);
|
||||
return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
|
||||
} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) return "";
|
||||
keyIndex = url.indexOf(`&${key}`, keyIndex + 1);
|
||||
}
|
||||
encoded = /[%+]/.test(url);
|
||||
if (!encoded) return;
|
||||
}
|
||||
const results = Object.create(null);
|
||||
encoded ??= /[%+]/.test(url);
|
||||
let keyIndex = url.indexOf("?", 8);
|
||||
while (keyIndex !== -1) {
|
||||
const nextKeyIndex = url.indexOf("&", keyIndex + 1);
|
||||
let valueIndex = url.indexOf("=", keyIndex);
|
||||
if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) valueIndex = -1;
|
||||
let name = url.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex);
|
||||
if (encoded) name = _decodeURI(name);
|
||||
keyIndex = nextKeyIndex;
|
||||
if (name === "") continue;
|
||||
let value;
|
||||
if (valueIndex === -1) value = "";
|
||||
else {
|
||||
value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
|
||||
if (encoded) value = _decodeURI(value);
|
||||
}
|
||||
if (multiple) {
|
||||
if (!(results[name] && Array.isArray(results[name]))) results[name] = [];
|
||||
results[name].push(value);
|
||||
} else results[name] ??= value;
|
||||
}
|
||||
return key ? results[key] : results;
|
||||
};
|
||||
const getQueryParam = _getQueryParam;
|
||||
const getQueryParams = (url, key) => {
|
||||
return _getQueryParam(url, key, true);
|
||||
};
|
||||
const decodeURIComponent_ = decodeURIComponent;
|
||||
//#endregion
|
||||
export { checkOptionalParameter, decodeURIComponent_, getPath, getPathNoStrict, getPattern, getQueryParam, getQueryParams, getQueryStrings, mergePath, splitPath, splitRoutingPath, tryDecode, tryDecodeURI, tryDecodeURIComponent };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { validator } from "./validator.js";
|
||||
export { validator };
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
import { HTTPException } from "../http-exception.js";
|
||||
import { bufferToFormData } from "../utils/buffer.js";
|
||||
import { getCookie } from "../helper/cookie/index.js";
|
||||
//#region src/validator/validator.ts
|
||||
const jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i;
|
||||
const multipartRegex = /^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/i;
|
||||
const urlencodedRegex = /^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i;
|
||||
const validator = (target, validationFunc) => {
|
||||
return async (c, next) => {
|
||||
let value = {};
|
||||
const contentType = c.req.header("Content-Type");
|
||||
switch (target) {
|
||||
case "json":
|
||||
if (!contentType || !jsonRegex.test(contentType)) break;
|
||||
try {
|
||||
value = await c.req.json();
|
||||
} catch {
|
||||
throw new HTTPException(400, { message: "Malformed JSON in request body" });
|
||||
}
|
||||
break;
|
||||
case "form": {
|
||||
if (!contentType || !(multipartRegex.test(contentType) || urlencodedRegex.test(contentType))) break;
|
||||
let formData;
|
||||
if (c.req.bodyCache.formData) formData = await c.req.bodyCache.formData;
|
||||
else try {
|
||||
const arrayBuffer = await c.req.arrayBuffer();
|
||||
formData = await bufferToFormData(arrayBuffer, contentType);
|
||||
c.req.bodyCache.formData = formData;
|
||||
} catch (e) {
|
||||
let message = "Malformed FormData request.";
|
||||
message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
|
||||
throw new HTTPException(400, { message });
|
||||
}
|
||||
const form = Object.create(null);
|
||||
formData.forEach((value, key) => {
|
||||
if (key.endsWith("[]")) (form[key] ??= []).push(value);
|
||||
else if (Array.isArray(form[key])) form[key].push(value);
|
||||
else if (Object.hasOwn(form, key)) form[key] = [form[key], value];
|
||||
else form[key] = value;
|
||||
});
|
||||
value = form;
|
||||
break;
|
||||
}
|
||||
case "query":
|
||||
value = Object.fromEntries(Object.entries(c.req.queries()).map(([k, v]) => {
|
||||
return v.length === 1 ? [k, v[0]] : [k, v];
|
||||
}));
|
||||
break;
|
||||
case "param":
|
||||
value = c.req.param();
|
||||
break;
|
||||
case "header":
|
||||
value = c.req.header();
|
||||
break;
|
||||
case "cookie": value = getCookie(c);
|
||||
}
|
||||
const res = await validationFunc(value, c);
|
||||
if (res instanceof Response) return res;
|
||||
c.req.addValidatedData(target, res);
|
||||
return await next();
|
||||
};
|
||||
};
|
||||
//#endregion
|
||||
export { validator };
|
||||
+9
-1
@@ -1,10 +1,18 @@
|
||||
{
|
||||
"name": "hono",
|
||||
"version": "4.13.13",
|
||||
"description": "Test fixture: only the hono/ws helper that @hono/node-server's index imports.",
|
||||
"description": "Test fixture: the hono core and validator (with their declarations) and the hono/ws helper that @hono/node-server's index imports.",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"import": "./dist/index.js"
|
||||
},
|
||||
"./validator": {
|
||||
"types": "./dist/types/validator/index.d.ts",
|
||||
"import": "./dist/validator/index.js"
|
||||
},
|
||||
"./ws": {
|
||||
"import": "./dist/helper/websocket/index.js"
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Colin McDonnell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import * as z from "./v4/classic/external.cjs";
|
||||
export * from "./v4/classic/external.cjs";
|
||||
export { z, z as default };
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import * as z from "./v4/classic/external.js";
|
||||
export * from "./v4/classic/external.js";
|
||||
// Aliasing the binding, instead of `export default z`, keeps the default export a
|
||||
// re-export of `z` rather than a fresh namespace value. Rollup and Webpack can then
|
||||
// shake `import z from "zod"` as they already shake `import { z } from "zod"` — without
|
||||
// this they pull in every locale. See #6050.
|
||||
export { z, z as default };
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "zod",
|
||||
"version": "4.6.7",
|
||||
"description": "Test fixture: zod 4's classic API, its core and locales, and the declarations @hono/zod-validator reads (the files the npm cases load).",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"types": "./index.d.cts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.cts",
|
||||
"import": "./index.js"
|
||||
},
|
||||
"./v3": {
|
||||
"types": "./v3/index.d.cts"
|
||||
},
|
||||
"./v4": {
|
||||
"types": "./v4/index.d.cts"
|
||||
},
|
||||
"./v4/core": {
|
||||
"types": "./v4/core/index.d.cts"
|
||||
}
|
||||
}
|
||||
}
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
import type { Primitive } from "./helpers/typeAliases.cjs";
|
||||
import { util, type ZodParsedType } from "./helpers/util.cjs";
|
||||
import type { TypeOf, ZodType } from "./index.cjs";
|
||||
type allKeys<T> = T extends any ? keyof T : never;
|
||||
export type inferFlattenedErrors<T extends ZodType<any, any, any>, U = string> = typeToFlattenedError<TypeOf<T>, U>;
|
||||
export type typeToFlattenedError<T, U = string> = {
|
||||
formErrors: U[];
|
||||
fieldErrors: {
|
||||
[P in allKeys<T>]?: U[];
|
||||
};
|
||||
};
|
||||
export declare const ZodIssueCode: {
|
||||
invalid_type: "invalid_type";
|
||||
too_big: "too_big";
|
||||
too_small: "too_small";
|
||||
not_multiple_of: "not_multiple_of";
|
||||
unrecognized_keys: "unrecognized_keys";
|
||||
invalid_union: "invalid_union";
|
||||
custom: "custom";
|
||||
invalid_literal: "invalid_literal";
|
||||
invalid_union_discriminator: "invalid_union_discriminator";
|
||||
invalid_enum_value: "invalid_enum_value";
|
||||
invalid_arguments: "invalid_arguments";
|
||||
invalid_return_type: "invalid_return_type";
|
||||
invalid_date: "invalid_date";
|
||||
invalid_string: "invalid_string";
|
||||
invalid_intersection_types: "invalid_intersection_types";
|
||||
not_finite: "not_finite";
|
||||
};
|
||||
export type ZodIssueCode = keyof typeof ZodIssueCode;
|
||||
export type ZodIssueBase = {
|
||||
path: (string | number)[];
|
||||
message?: string | undefined;
|
||||
};
|
||||
export interface ZodInvalidTypeIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_type;
|
||||
expected: ZodParsedType;
|
||||
received: ZodParsedType;
|
||||
}
|
||||
export interface ZodInvalidLiteralIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_literal;
|
||||
expected: unknown;
|
||||
received: unknown;
|
||||
}
|
||||
export interface ZodUnrecognizedKeysIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.unrecognized_keys;
|
||||
keys: string[];
|
||||
}
|
||||
export interface ZodInvalidUnionIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_union;
|
||||
unionErrors: ZodError[];
|
||||
}
|
||||
export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_union_discriminator;
|
||||
options: Primitive[];
|
||||
}
|
||||
export interface ZodInvalidEnumValueIssue extends ZodIssueBase {
|
||||
received: string | number;
|
||||
code: typeof ZodIssueCode.invalid_enum_value;
|
||||
options: (string | number)[];
|
||||
}
|
||||
export interface ZodInvalidArgumentsIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_arguments;
|
||||
argumentsError: ZodError;
|
||||
}
|
||||
export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_return_type;
|
||||
returnTypeError: ZodError;
|
||||
}
|
||||
export interface ZodInvalidDateIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_date;
|
||||
}
|
||||
export type StringValidation = "email" | "url" | "emoji" | "uuid" | "nanoid" | "regex" | "cuid" | "cuid2" | "ulid" | "datetime" | "date" | "time" | "duration" | "ip" | "cidr" | "base64" | "jwt" | "base64url" | {
|
||||
includes: string;
|
||||
position?: number | undefined;
|
||||
} | {
|
||||
startsWith: string;
|
||||
} | {
|
||||
endsWith: string;
|
||||
};
|
||||
export interface ZodInvalidStringIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_string;
|
||||
validation: StringValidation;
|
||||
}
|
||||
export interface ZodTooSmallIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.too_small;
|
||||
minimum: number | bigint;
|
||||
inclusive: boolean;
|
||||
exact?: boolean;
|
||||
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
||||
}
|
||||
export interface ZodTooBigIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.too_big;
|
||||
maximum: number | bigint;
|
||||
inclusive: boolean;
|
||||
exact?: boolean;
|
||||
type: "array" | "string" | "number" | "set" | "date" | "bigint";
|
||||
}
|
||||
export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.invalid_intersection_types;
|
||||
}
|
||||
export interface ZodNotMultipleOfIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.not_multiple_of;
|
||||
multipleOf: number | bigint;
|
||||
}
|
||||
export interface ZodNotFiniteIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.not_finite;
|
||||
}
|
||||
export interface ZodCustomIssue extends ZodIssueBase {
|
||||
code: typeof ZodIssueCode.custom;
|
||||
params?: {
|
||||
[k: string]: any;
|
||||
};
|
||||
}
|
||||
export type DenormalizedError = {
|
||||
[k: string]: DenormalizedError | string[];
|
||||
};
|
||||
export type ZodIssueOptionalMessage = ZodInvalidTypeIssue | ZodInvalidLiteralIssue | ZodUnrecognizedKeysIssue | ZodInvalidUnionIssue | ZodInvalidUnionDiscriminatorIssue | ZodInvalidEnumValueIssue | ZodInvalidArgumentsIssue | ZodInvalidReturnTypeIssue | ZodInvalidDateIssue | ZodInvalidStringIssue | ZodTooSmallIssue | ZodTooBigIssue | ZodInvalidIntersectionTypesIssue | ZodNotMultipleOfIssue | ZodNotFiniteIssue | ZodCustomIssue;
|
||||
export type ZodIssue = ZodIssueOptionalMessage & {
|
||||
fatal?: boolean | undefined;
|
||||
message: string;
|
||||
};
|
||||
export declare const quotelessJson: (obj: any) => string;
|
||||
type recursiveZodFormattedError<T> = T extends [any, ...any[]] ? {
|
||||
[K in keyof T]?: ZodFormattedError<T[K]>;
|
||||
} : T extends any[] ? {
|
||||
[k: number]: ZodFormattedError<T[number]>;
|
||||
} : T extends object ? {
|
||||
[K in keyof T]?: ZodFormattedError<T[K]>;
|
||||
} : unknown;
|
||||
export type ZodFormattedError<T, U = string> = {
|
||||
_errors: U[];
|
||||
} & recursiveZodFormattedError<NonNullable<T>>;
|
||||
export type inferFormattedError<T extends ZodType<any, any, any>, U = string> = ZodFormattedError<TypeOf<T>, U>;
|
||||
export declare class ZodError<T = any> extends Error {
|
||||
issues: ZodIssue[];
|
||||
get errors(): ZodIssue[];
|
||||
constructor(issues: ZodIssue[]);
|
||||
format(): ZodFormattedError<T>;
|
||||
format<U>(mapper: (issue: ZodIssue) => U): ZodFormattedError<T, U>;
|
||||
static create: (issues: ZodIssue[]) => ZodError<any>;
|
||||
static assert(value: unknown): asserts value is ZodError;
|
||||
toString(): string;
|
||||
get message(): string;
|
||||
get isEmpty(): boolean;
|
||||
addIssue: (sub: ZodIssue) => void;
|
||||
addIssues: (subs?: ZodIssue[]) => void;
|
||||
flatten(): typeToFlattenedError<T>;
|
||||
flatten<U>(mapper?: (issue: ZodIssue) => U): typeToFlattenedError<T, U>;
|
||||
get formErrors(): typeToFlattenedError<T, string>;
|
||||
}
|
||||
type stripPath<T extends object> = T extends any ? util.OmitKeys<T, "path"> : never;
|
||||
export type IssueData = stripPath<ZodIssueOptionalMessage> & {
|
||||
path?: (string | number)[];
|
||||
fatal?: boolean | undefined;
|
||||
};
|
||||
export type ErrorMapCtx = {
|
||||
defaultError: string;
|
||||
data: any;
|
||||
};
|
||||
export type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => {
|
||||
message: string;
|
||||
};
|
||||
export {};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import type { ZodErrorMap } from "./ZodError.cjs";
|
||||
import defaultErrorMap from "./locales/en.cjs";
|
||||
export { defaultErrorMap };
|
||||
export declare function setErrorMap(map: ZodErrorMap): void;
|
||||
export declare function getErrorMap(): ZodErrorMap;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
export * from "./errors.cjs";
|
||||
export * from "./helpers/parseUtil.cjs";
|
||||
export * from "./helpers/typeAliases.cjs";
|
||||
export * from "./helpers/util.cjs";
|
||||
export * from "./types.cjs";
|
||||
export * from "./ZodError.cjs";
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
export declare namespace enumUtil {
|
||||
type UnionToIntersectionFn<T> = (T extends unknown ? (k: () => T) => void : never) extends (k: infer Intersection) => void ? Intersection : never;
|
||||
type GetUnionLast<T> = UnionToIntersectionFn<T> extends () => infer Last ? Last : never;
|
||||
type UnionToTuple<T, Tuple extends unknown[] = []> = [T] extends [never] ? Tuple : UnionToTuple<Exclude<T, GetUnionLast<T>>, [GetUnionLast<T>, ...Tuple]>;
|
||||
type CastToStringTuple<T> = T extends [string, ...string[]] ? T : never;
|
||||
export type UnionToTupleString<T> = CastToStringTuple<UnionToTuple<T>>;
|
||||
export {};
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export declare namespace errorUtil {
|
||||
type ErrMessage = string | {
|
||||
message?: string | undefined;
|
||||
};
|
||||
const errToObj: (message?: ErrMessage) => {
|
||||
message?: string | undefined;
|
||||
};
|
||||
const toString: (message?: ErrMessage) => string | undefined;
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import type { IssueData, ZodErrorMap, ZodIssue } from "../ZodError.cjs";
|
||||
import type { ZodParsedType } from "./util.cjs";
|
||||
export declare const makeIssue: (params: {
|
||||
data: any;
|
||||
path: (string | number)[];
|
||||
errorMaps: ZodErrorMap[];
|
||||
issueData: IssueData;
|
||||
}) => ZodIssue;
|
||||
export type ParseParams = {
|
||||
path: (string | number)[];
|
||||
errorMap: ZodErrorMap;
|
||||
async: boolean;
|
||||
};
|
||||
export type ParsePathComponent = string | number;
|
||||
export type ParsePath = ParsePathComponent[];
|
||||
export declare const EMPTY_PATH: ParsePath;
|
||||
export interface ParseContext {
|
||||
readonly common: {
|
||||
readonly issues: ZodIssue[];
|
||||
readonly contextualErrorMap?: ZodErrorMap | undefined;
|
||||
readonly async: boolean;
|
||||
};
|
||||
readonly path: ParsePath;
|
||||
readonly schemaErrorMap?: ZodErrorMap | undefined;
|
||||
readonly parent: ParseContext | null;
|
||||
readonly data: any;
|
||||
readonly parsedType: ZodParsedType;
|
||||
}
|
||||
export type ParseInput = {
|
||||
data: any;
|
||||
path: (string | number)[];
|
||||
parent: ParseContext;
|
||||
};
|
||||
export declare function addIssueToContext(ctx: ParseContext, issueData: IssueData): void;
|
||||
export type ObjectPair = {
|
||||
key: SyncParseReturnType<any>;
|
||||
value: SyncParseReturnType<any>;
|
||||
};
|
||||
export declare class ParseStatus {
|
||||
value: "aborted" | "dirty" | "valid";
|
||||
dirty(): void;
|
||||
abort(): void;
|
||||
static mergeArray(status: ParseStatus, results: SyncParseReturnType<any>[]): SyncParseReturnType;
|
||||
static mergeObjectAsync(status: ParseStatus, pairs: {
|
||||
key: ParseReturnType<any>;
|
||||
value: ParseReturnType<any>;
|
||||
}[]): Promise<SyncParseReturnType<any>>;
|
||||
static mergeObjectSync(status: ParseStatus, pairs: {
|
||||
key: SyncParseReturnType<any>;
|
||||
value: SyncParseReturnType<any>;
|
||||
alwaysSet?: boolean;
|
||||
}[]): SyncParseReturnType;
|
||||
}
|
||||
export interface ParseResult {
|
||||
status: "aborted" | "dirty" | "valid";
|
||||
data: any;
|
||||
}
|
||||
export type INVALID = {
|
||||
status: "aborted";
|
||||
};
|
||||
export declare const INVALID: INVALID;
|
||||
export type DIRTY<T> = {
|
||||
status: "dirty";
|
||||
value: T;
|
||||
};
|
||||
export declare const DIRTY: <T>(value: T) => DIRTY<T>;
|
||||
export type OK<T> = {
|
||||
status: "valid";
|
||||
value: T;
|
||||
};
|
||||
export declare const OK: <T>(value: T) => OK<T>;
|
||||
export type SyncParseReturnType<T = any> = OK<T> | DIRTY<T> | INVALID;
|
||||
export type AsyncParseReturnType<T> = Promise<SyncParseReturnType<T>>;
|
||||
export type ParseReturnType<T> = SyncParseReturnType<T> | AsyncParseReturnType<T>;
|
||||
export declare const isAborted: (x: ParseReturnType<any>) => x is INVALID;
|
||||
export declare const isDirty: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
|
||||
export declare const isValid: <T>(x: ParseReturnType<T>) => x is OK<T>;
|
||||
export declare const isAsync: <T>(x: ParseReturnType<T>) => x is AsyncParseReturnType<T>;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import type { ZodArray, ZodNullable, ZodObject, ZodOptional, ZodRawShape, ZodTuple, ZodTupleItems, ZodTypeAny } from "../types.cjs";
|
||||
export declare namespace partialUtil {
|
||||
type DeepPartial<T extends ZodTypeAny> = T extends ZodObject<ZodRawShape> ? ZodObject<{
|
||||
[k in keyof T["shape"]]: ZodOptional<DeepPartial<T["shape"][k]>>;
|
||||
}, T["_def"]["unknownKeys"], T["_def"]["catchall"]> : T extends ZodArray<infer Type, infer Card> ? ZodArray<DeepPartial<Type>, Card> : T extends ZodOptional<infer Type> ? ZodOptional<DeepPartial<Type>> : T extends ZodNullable<infer Type> ? ZodNullable<DeepPartial<Type>> : T extends ZodTuple<infer Items> ? {
|
||||
[k in keyof Items]: Items[k] extends ZodTypeAny ? DeepPartial<Items[k]> : never;
|
||||
} extends infer PI ? PI extends ZodTupleItems ? ZodTuple<PI> : never : never : T;
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export type Primitive = string | number | symbol | bigint | boolean | null | undefined;
|
||||
export type Scalars = Primitive | Primitive[];
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
export declare namespace util {
|
||||
type AssertEqual<T, U> = (<V>() => V extends T ? 1 : 2) extends <V>() => V extends U ? 1 : 2 ? true : false;
|
||||
export type isAny<T> = 0 extends 1 & T ? true : false;
|
||||
export const assertEqual: <A, B>(_: AssertEqual<A, B>) => void;
|
||||
export function assertIs<T>(_arg: T): void;
|
||||
export function assertNever(_x: never): never;
|
||||
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
|
||||
export type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
|
||||
export type MakePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
||||
export type Exactly<T, X> = T & Record<Exclude<keyof X, keyof T>, never>;
|
||||
export type InexactPartial<T> = {
|
||||
[k in keyof T]?: T[k] | undefined;
|
||||
};
|
||||
export const arrayToEnum: <T extends string, U extends [T, ...T[]]>(items: U) => { [k in U[number]]: k; };
|
||||
export const getValidEnumValues: (obj: any) => any[];
|
||||
export const objectValues: (obj: any) => any[];
|
||||
export const objectKeys: ObjectConstructor["keys"];
|
||||
export const find: <T>(arr: T[], checker: (arg: T) => any) => T | undefined;
|
||||
export type identity<T> = objectUtil.identity<T>;
|
||||
export type flatten<T> = objectUtil.flatten<T>;
|
||||
export type noUndefined<T> = T extends undefined ? never : T;
|
||||
export const isInteger: NumberConstructor["isInteger"];
|
||||
export function joinValues<T extends any[]>(array: T, separator?: string): string;
|
||||
export const jsonStringifyReplacer: (_: string, value: any) => any;
|
||||
export {};
|
||||
}
|
||||
export declare namespace objectUtil {
|
||||
export type MergeShapes<U, V> = keyof U & keyof V extends never ? U & V : {
|
||||
[k in Exclude<keyof U, keyof V>]: U[k];
|
||||
} & V;
|
||||
type optionalKeys<T extends object> = {
|
||||
[k in keyof T]: undefined extends T[k] ? k : never;
|
||||
}[keyof T];
|
||||
type requiredKeys<T extends object> = {
|
||||
[k in keyof T]: undefined extends T[k] ? never : k;
|
||||
}[keyof T];
|
||||
export type addQuestionMarks<T extends object, _O = any> = {
|
||||
[K in requiredKeys<T>]: T[K];
|
||||
} & {
|
||||
[K in optionalKeys<T>]?: T[K];
|
||||
} & {
|
||||
[k in keyof T]?: unknown;
|
||||
};
|
||||
export type identity<T> = T;
|
||||
export type flatten<T> = identity<{
|
||||
[k in keyof T]: T[k];
|
||||
}>;
|
||||
export type noNeverKeys<T> = {
|
||||
[k in keyof T]: [T[k]] extends [never] ? never : k;
|
||||
}[keyof T];
|
||||
export type noNever<T> = identity<{
|
||||
[k in noNeverKeys<T>]: k extends keyof T ? T[k] : never;
|
||||
}>;
|
||||
export const mergeShapes: <U, T>(first: U, second: T) => T & U;
|
||||
export type extendShape<A extends object, B extends object> = keyof A & keyof B extends never ? A & B : {
|
||||
[K in keyof A as K extends keyof B ? never : K]: A[K];
|
||||
} & {
|
||||
[K in keyof B]: B[K];
|
||||
};
|
||||
export {};
|
||||
}
|
||||
export declare const ZodParsedType: {
|
||||
string: "string";
|
||||
nan: "nan";
|
||||
number: "number";
|
||||
integer: "integer";
|
||||
float: "float";
|
||||
boolean: "boolean";
|
||||
date: "date";
|
||||
bigint: "bigint";
|
||||
symbol: "symbol";
|
||||
function: "function";
|
||||
undefined: "undefined";
|
||||
null: "null";
|
||||
array: "array";
|
||||
object: "object";
|
||||
unknown: "unknown";
|
||||
promise: "promise";
|
||||
void: "void";
|
||||
never: "never";
|
||||
map: "map";
|
||||
set: "set";
|
||||
};
|
||||
export type ZodParsedType = keyof typeof ZodParsedType;
|
||||
export declare const getParsedType: (data: any) => ZodParsedType;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import * as z from "./external.cjs";
|
||||
export * from "./external.cjs";
|
||||
export { z };
|
||||
export default z;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { type ZodErrorMap } from "../ZodError.cjs";
|
||||
declare const errorMap: ZodErrorMap;
|
||||
export = errorMap;
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* The Standard Schema interface.
|
||||
*/
|
||||
export type StandardSchemaV1<Input = unknown, Output = Input> = {
|
||||
/**
|
||||
* The Standard Schema properties.
|
||||
*/
|
||||
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
||||
};
|
||||
export declare namespace StandardSchemaV1 {
|
||||
/**
|
||||
* The Standard Schema properties interface.
|
||||
*/
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The version number of the standard.
|
||||
*/
|
||||
readonly version: 1;
|
||||
/**
|
||||
* The vendor name of the schema library.
|
||||
*/
|
||||
readonly vendor: string;
|
||||
/**
|
||||
* Validates unknown input values.
|
||||
*/
|
||||
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
||||
/**
|
||||
* Inferred types associated with the schema.
|
||||
*/
|
||||
readonly types?: Types<Input, Output> | undefined;
|
||||
}
|
||||
/**
|
||||
* The result interface of the validate function.
|
||||
*/
|
||||
export type Result<Output> = SuccessResult<Output> | FailureResult;
|
||||
/**
|
||||
* The result interface if validation succeeds.
|
||||
*/
|
||||
export interface SuccessResult<Output> {
|
||||
/**
|
||||
* The typed output value.
|
||||
*/
|
||||
readonly value: Output;
|
||||
/**
|
||||
* The non-existent issues.
|
||||
*/
|
||||
readonly issues?: undefined;
|
||||
}
|
||||
/**
|
||||
* The result interface if validation fails.
|
||||
*/
|
||||
export interface FailureResult {
|
||||
/**
|
||||
* The issues of failed validation.
|
||||
*/
|
||||
readonly issues: ReadonlyArray<Issue>;
|
||||
}
|
||||
/**
|
||||
* The issue interface of the failure output.
|
||||
*/
|
||||
export interface Issue {
|
||||
/**
|
||||
* The error message of the issue.
|
||||
*/
|
||||
readonly message: string;
|
||||
/**
|
||||
* The path of the issue, if any.
|
||||
*/
|
||||
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
||||
}
|
||||
/**
|
||||
* The path segment interface of the issue.
|
||||
*/
|
||||
export interface PathSegment {
|
||||
/**
|
||||
* The key representing a path segment.
|
||||
*/
|
||||
readonly key: PropertyKey;
|
||||
}
|
||||
/**
|
||||
* The Standard Schema types interface.
|
||||
*/
|
||||
export interface Types<Input = unknown, Output = Input> {
|
||||
/**
|
||||
* The input type of the schema.
|
||||
*/
|
||||
readonly input: Input;
|
||||
/**
|
||||
* The output type of the schema.
|
||||
*/
|
||||
readonly output: Output;
|
||||
}
|
||||
/**
|
||||
* Infers the input type of a Standard Schema.
|
||||
*/
|
||||
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
|
||||
/**
|
||||
* Infers the output type of a Standard Schema.
|
||||
*/
|
||||
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
||||
export {};
|
||||
}
|
||||
+1034
File diff suppressed because it is too large
Load Diff
+1
@@ -0,0 +1 @@
|
||||
export { _lt as lt, _lte as lte, _gt as gt, _gte as gte, _positive as positive, _negative as negative, _nonpositive as nonpositive, _nonnegative as nonnegative, _multipleOf as multipleOf, _maxSize as maxSize, _minSize as minSize, _size as size, _maxLength as maxLength, _minLength as minLength, _length as length, _regex as regex, _lowercase as lowercase, _uppercase as uppercase, _includes as includes, _startsWith as startsWith, _endsWith as endsWith, _property as property, _properties as properties, _mime as mime, _overwrite as overwrite, _normalize as normalize, _trim as trim, _toLowerCase as toLowerCase, _toUpperCase as toUpperCase, _slugify as slugify, type $RefinementCtx as RefinementCtx, } from "../core/index.cjs";
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { _lt as lt, _lte as lte, _gt as gt, _gte as gte, _positive as positive, _negative as negative, _nonpositive as nonpositive, _nonnegative as nonnegative, _multipleOf as multipleOf, _maxSize as maxSize, _minSize as minSize, _size as size, _maxLength as maxLength, _minLength as minLength, _length as length, _regex as regex, _lowercase as lowercase, _uppercase as uppercase, _includes as includes, _startsWith as startsWith, _endsWith as endsWith, _property as property, _properties as properties, _mime as mime, _overwrite as overwrite, _normalize as normalize, _trim as trim, _toLowerCase as toLowerCase, _toUpperCase as toUpperCase, _slugify as slugify, } from "../core/index.js";
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import * as core from "../core/index.cjs";
|
||||
import * as schemas from "./schemas.cjs";
|
||||
export interface ZodCoercedString<T = unknown> extends schemas._ZodString<core.$ZodStringInternals<T>> {
|
||||
}
|
||||
export declare function string<T = unknown>(params?: string | core.$ZodStringParams): ZodCoercedString<T>;
|
||||
export interface ZodCoercedNumber<T = unknown> extends schemas._ZodNumber<core.$ZodNumberInternals<T>> {
|
||||
}
|
||||
export declare function number<T = unknown>(params?: string | core.$ZodNumberParams): ZodCoercedNumber<T>;
|
||||
export interface ZodCoercedBoolean<T = unknown> extends schemas._ZodBoolean<core.$ZodBooleanInternals<T>> {
|
||||
}
|
||||
export declare function boolean<T = unknown>(params?: string | core.$ZodBooleanParams): ZodCoercedBoolean<T>;
|
||||
export interface ZodCoercedBigInt<T = unknown> extends schemas._ZodBigInt<core.$ZodBigIntInternals<T>> {
|
||||
}
|
||||
export declare function bigint<T = unknown>(params?: string | core.$ZodBigIntParams): ZodCoercedBigInt<T>;
|
||||
export interface ZodCoercedDate<T = unknown> extends schemas._ZodDate<core.$ZodDateInternals<T>> {
|
||||
}
|
||||
export declare function date<T = unknown>(params?: string | core.$ZodDateParams): ZodCoercedDate<T>;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import * as core from "../core/index.js";
|
||||
import * as schemas from "./schemas.js";
|
||||
export function string(params) {
|
||||
return core._coercedString(schemas.ZodString, params);
|
||||
}
|
||||
export function number(params) {
|
||||
return core._coercedNumber(schemas.ZodNumber, params);
|
||||
}
|
||||
export function boolean(params) {
|
||||
return core._coercedBoolean(schemas.ZodBoolean, params);
|
||||
}
|
||||
export function bigint(params) {
|
||||
return core._coercedBigint(schemas.ZodBigInt, params);
|
||||
}
|
||||
export function date(params) {
|
||||
return core._coercedDate(schemas.ZodDate, params);
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import * as core from "../core/index.cjs";
|
||||
import type { ZodType } from "./schemas.cjs";
|
||||
/** @deprecated Use `z.output<T>` instead. */
|
||||
export type TypeOf<T> = core.output<T>;
|
||||
/** @deprecated Use `z.output<T>` instead. */
|
||||
export type Infer<T> = core.output<T>;
|
||||
/** @deprecated Use `z.core.$ZodTypes` instead */
|
||||
export type ZodFirstPartySchemaTypes = core.$ZodTypes;
|
||||
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
||||
export declare const ZodIssueCode: {
|
||||
readonly invalid_type: "invalid_type";
|
||||
readonly too_big: "too_big";
|
||||
readonly too_small: "too_small";
|
||||
readonly invalid_format: "invalid_format";
|
||||
readonly not_multiple_of: "not_multiple_of";
|
||||
readonly unrecognized_keys: "unrecognized_keys";
|
||||
readonly invalid_union: "invalid_union";
|
||||
readonly invalid_key: "invalid_key";
|
||||
readonly invalid_element: "invalid_element";
|
||||
readonly invalid_value: "invalid_value";
|
||||
readonly custom: "custom";
|
||||
};
|
||||
/** @deprecated Use `z.core.$ZodFlattenedError<z.output<T>>` instead; it takes an inferred type, not a schema. */
|
||||
export type inferFlattenedErrors<T extends core.$ZodType, U = string> = core.$ZodFlattenedError<core.output<T>, U>;
|
||||
/** @deprecated Use `z.core.$ZodFormattedError<z.output<T>>` instead; it takes an inferred type, not a schema. */
|
||||
export type inferFormattedError<T extends core.$ZodType<any, any>, U = string> = core.$ZodFormattedError<core.output<T>, U>;
|
||||
/** Use `z.$brand` instead */
|
||||
export type BRAND<T extends string | number | symbol = string | number | symbol> = {
|
||||
[core.$brand]: {
|
||||
[k in T]: true;
|
||||
};
|
||||
};
|
||||
export { $brand, config } from "../core/index.cjs";
|
||||
/** @deprecated Use `z.config(params)` instead. */
|
||||
export declare function setErrorMap(map: core.$ZodErrorMap): void;
|
||||
/** @deprecated Use `z.config()` instead. */
|
||||
export declare function getErrorMap(): core.$ZodErrorMap<core.$ZodIssue> | undefined;
|
||||
/** @deprecated Use z.ZodType (without generics) instead. */
|
||||
export type ZodTypeAny<Output = unknown, Input = unknown, Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> = ZodType<Output, Input, Internals>;
|
||||
/** @deprecated Use `z.ZodType` */
|
||||
export type ZodSchema<Output = unknown, Input = unknown, Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> = ZodType<Output, Input, Internals>;
|
||||
/** @deprecated Use `z.ZodType` */
|
||||
export type Schema<Output = unknown, Input = unknown, Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> = ZodType<Output, Input, Internals>;
|
||||
/** Included for Zod 3 compatibility */
|
||||
export type ZodRawShape = core.$ZodShape;
|
||||
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
||||
export declare enum ZodFirstPartyTypeKind {
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Zod 3 compat layer
|
||||
import * as core from "../core/index.js";
|
||||
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
||||
export const ZodIssueCode = {
|
||||
invalid_type: "invalid_type",
|
||||
too_big: "too_big",
|
||||
too_small: "too_small",
|
||||
invalid_format: "invalid_format",
|
||||
not_multiple_of: "not_multiple_of",
|
||||
unrecognized_keys: "unrecognized_keys",
|
||||
invalid_union: "invalid_union",
|
||||
invalid_key: "invalid_key",
|
||||
invalid_element: "invalid_element",
|
||||
invalid_value: "invalid_value",
|
||||
custom: "custom",
|
||||
};
|
||||
export { $brand, config } from "../core/index.js";
|
||||
/** @deprecated Use `z.config(params)` instead. */
|
||||
export function setErrorMap(map) {
|
||||
core.config({
|
||||
customError: map,
|
||||
});
|
||||
}
|
||||
/** @deprecated Use `z.config()` instead. */
|
||||
export function getErrorMap() {
|
||||
return core.config().customError;
|
||||
}
|
||||
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
||||
export var ZodFirstPartyTypeKind;
|
||||
(function (ZodFirstPartyTypeKind) {
|
||||
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import type * as core from "../core/index.cjs";
|
||||
import * as schemas from "./schemas.cjs";
|
||||
/** Distributes `.partial()` through every object in a schema type, preserving the wrappers around them. */
|
||||
export type DeepPartial<T extends core.SomeType> = T extends schemas.ZodObject<infer Shape, infer Config> ? schemas.ZodObject<{
|
||||
-readonly [K in keyof Shape]: schemas.ZodOptional<DeepPartial<Shape[K]>>;
|
||||
}, Config> : T extends schemas.ZodDiscriminatedUnion<infer Options, any> ? schemas.ZodUnion<{
|
||||
-readonly [I in keyof Options]: Options[I] extends core.SomeType ? DeepPartial<Options[I]> : Options[I];
|
||||
}> : T extends schemas.ZodUnion<infer Options> ? schemas.ZodUnion<{
|
||||
-readonly [I in keyof Options]: Options[I] extends core.SomeType ? DeepPartial<Options[I]> : Options[I];
|
||||
}> : T extends schemas.ZodArray<infer El> ? schemas.ZodArray<DeepPartial<El>> : T extends schemas.ZodTuple<infer Items, infer Rest> ? schemas.ZodTuple<{
|
||||
-readonly [K in keyof Items]: Items[K] extends core.SomeType ? DeepPartial<Items[K]> : Items[K];
|
||||
}, Rest extends core.SomeType ? DeepPartial<Rest> : Rest> : T extends schemas.ZodIntersection<infer A, infer B> ? schemas.ZodIntersection<DeepPartial<A>, DeepPartial<B>> : T extends schemas.ZodRecord<infer K, infer V> ? schemas.ZodRecord<K, DeepPartial<V>> : T extends schemas.ZodMap<infer K, infer V> ? schemas.ZodMap<K, DeepPartial<V>> : T extends schemas.ZodSet<infer El> ? schemas.ZodSet<DeepPartial<El>> : T extends schemas.ZodOptional<infer Inner> ? schemas.ZodOptional<DeepPartial<Inner>> : T extends schemas.ZodNullable<infer Inner> ? schemas.ZodNullable<DeepPartial<Inner>> : T extends schemas.ZodDefault<infer Inner> ? schemas.ZodDefault<DeepPartial<Inner>> : T extends schemas.ZodPrefault<infer Inner> ? schemas.ZodPrefault<DeepPartial<Inner>> : T extends schemas.ZodNonOptional<infer Inner> ? schemas.ZodNonOptional<DeepPartial<Inner>> : T extends schemas.ZodCatch<infer Inner> ? schemas.ZodCatch<DeepPartial<Inner>> : T extends schemas.ZodReadonly<infer Inner> ? schemas.ZodReadonly<DeepPartial<Inner>> : T extends schemas.ZodSuccess<infer Inner> ? schemas.ZodSuccess<DeepPartial<Inner>> : T extends schemas.ZodPromise<infer Inner> ? schemas.ZodPromise<DeepPartial<Inner>> : T extends schemas.ZodCodec<infer A, infer B> ? schemas.ZodCodec<DeepPartial<A>, DeepPartial<B>> : T extends schemas.ZodPreprocess<infer B> ? schemas.ZodPreprocess<DeepPartial<B>> : T extends schemas.ZodPipe<infer A, infer B> ? schemas.ZodPipe<DeepPartial<A>, DeepPartial<B>> : T extends schemas.ZodLazy<infer Inner> ? schemas.ZodLazy<DeepPartial<Inner>> : T;
|
||||
/** Returns a copy of the schema with every nested object's properties made optional. */
|
||||
export declare function deepPartial<T extends core.SomeType>(schema: T): DeepPartial<T>;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import { visit } from "../core/visit.js";
|
||||
import * as schemas from "./schemas.js";
|
||||
/** Returns a copy of the schema with every nested object's properties made optional. */
|
||||
export function deepPartial(schema) {
|
||||
return visit(schema, {
|
||||
object: (s) => s.partial(),
|
||||
// Every partialed option now admits `undefined`, which the constructor rejects as a duplicate.
|
||||
union: (s) => {
|
||||
const def = s._zod.def;
|
||||
return def.discriminator === undefined ? s : schemas.union(def.options);
|
||||
},
|
||||
});
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import * as core from "../core/index.cjs";
|
||||
import { $ZodError } from "../core/index.cjs";
|
||||
/** @deprecated Use `z.core.$ZodIssue` from `@zod/core` instead, especially if you are building a library on top of Zod. */
|
||||
export type ZodIssue = core.$ZodIssue;
|
||||
/** An Error-like class used to store Zod validation issues. */
|
||||
export interface ZodError<T = unknown> extends $ZodError<T> {
|
||||
/** @deprecated Use the `z.treeifyError(err)` function instead. */
|
||||
format(): core.$ZodFormattedError<T>;
|
||||
format<U>(mapper: (issue: core.$ZodIssue) => U): core.$ZodFormattedError<T, U>;
|
||||
/** @deprecated Use the `z.treeifyError(err)` function instead. */
|
||||
flatten(): core.$ZodFlattenedError<T>;
|
||||
flatten<U>(mapper: (issue: core.$ZodIssue) => U): core.$ZodFlattenedError<T, U>;
|
||||
/** @deprecated Push directly to `.issues` instead. */
|
||||
addIssue(issue: core.$ZodIssue): void;
|
||||
/** @deprecated Push directly to `.issues` instead. */
|
||||
addIssues(issues: core.$ZodIssue[]): void;
|
||||
/** @deprecated Check `err.issues.length === 0` instead. */
|
||||
isEmpty: boolean;
|
||||
}
|
||||
export declare const ZodError: core.$constructor<ZodError>;
|
||||
export declare const ZodRealError: core.$constructor<ZodError>;
|
||||
/** @deprecated Use `z.core.$ZodFlattenedError` instead. */
|
||||
export type ZodFlattenedError<T, U = string> = core.$ZodFlattenedError<T, U>;
|
||||
/** @deprecated Use `z.core.$ZodFormattedError` instead. */
|
||||
export type ZodFormattedError<T, U = string> = core.$ZodFormattedError<T, U>;
|
||||
/** @deprecated Use `z.core.$ZodErrorMap` instead. */
|
||||
export type ZodErrorMap<T extends core.$ZodIssueBase = core.$ZodIssue> = core.$ZodErrorMap<T>;
|
||||
/** @deprecated Use `z.core.$ZodRawIssue` instead. */
|
||||
export type IssueData = core.$ZodRawIssue;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import * as core from "../core/index.js";
|
||||
import { $ZodError } from "../core/index.js";
|
||||
import * as util from "../core/util.js";
|
||||
/* Prototypes that already carry the lazy helper methods. Seeded with the
|
||||
* intrinsics so that `init` on a foreign object — it accepts any object —
|
||||
* can never install an accessor onto a prototype we do not own. */
|
||||
const _installedErrorProtos = /* @__PURE__ */ new WeakSet([Object.prototype, Error.prototype]);
|
||||
/* Helper methods live as non-enumerable lazy getters on the shared
|
||||
* prototype instead of own properties on every instance. On first
|
||||
* access the getter allocates the per-instance closure and caches it
|
||||
* as a non-enumerable own property, so detached usage still works and
|
||||
* the allocation only happens for methods actually touched. */
|
||||
function _lazyMethod(proto, key, make) {
|
||||
Object.defineProperty(proto, key, {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
get() {
|
||||
const value = make(this);
|
||||
Object.defineProperty(this, key, { value, configurable: true, writable: true });
|
||||
return value;
|
||||
},
|
||||
set(value) {
|
||||
Object.defineProperty(this, key, { value, configurable: true, writable: true });
|
||||
},
|
||||
});
|
||||
}
|
||||
const initializer = (inst, issues) => {
|
||||
$ZodError.init(inst, issues);
|
||||
inst.name = "ZodError";
|
||||
const proto = Object.getPrototypeOf(inst);
|
||||
if (_installedErrorProtos.has(proto))
|
||||
return;
|
||||
_installedErrorProtos.add(proto);
|
||||
_lazyMethod(proto, "format", (self) => (mapper) => core.formatError(self, mapper));
|
||||
_lazyMethod(proto, "flatten", (self) => (mapper) => core.flattenError(self, mapper));
|
||||
_lazyMethod(proto, "addIssue", (self) => (issue) => {
|
||||
self.issues.push(issue);
|
||||
self.message = JSON.stringify(self.issues, util.jsonStringifyReplacer, 2);
|
||||
});
|
||||
_lazyMethod(proto, "addIssues", (self) => (issues) => {
|
||||
self.issues.push(...issues);
|
||||
self.message = JSON.stringify(self.issues, util.jsonStringifyReplacer, 2);
|
||||
});
|
||||
Object.defineProperty(proto, "isEmpty", {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
get() {
|
||||
return this.issues.length === 0;
|
||||
},
|
||||
});
|
||||
};
|
||||
export const ZodError = /*@__PURE__*/ core.$constructor("ZodError", initializer);
|
||||
export const ZodRealError = /*@__PURE__*/ core.$constructor("ZodError", initializer, undefined, {
|
||||
Parent: Error,
|
||||
});
|
||||
// /** @deprecated Use `z.core.$ZodErrorMapCtx` instead. */
|
||||
// export type ErrorMapCtx = core.$ZodErrorMapCtx;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
export * as core from "../core/index.cjs";
|
||||
export * from "./schemas.cjs";
|
||||
export * from "./checks.cjs";
|
||||
export * from "./errors.cjs";
|
||||
export * from "./parse.cjs";
|
||||
export * from "./compat.cjs";
|
||||
export type { infer } from "../core/index.cjs";
|
||||
export type { JSONType } from "../core/util.cjs";
|
||||
export type { CompileOptions } from "../core/index.cjs";
|
||||
export { globalRegistry, type GlobalMeta, registry, config, memoizer, $output, $input, $brand, clone, regexes, treeifyError, prettifyError, formatError, flattenError, TimePrecision, util, NEVER, INVALID, toZod, compile, withParser, ZodCompileAsyncError, ZodCompileUnsupportedError, getDiscriminatedOption, } from "../core/index.cjs";
|
||||
export { toJSONSchema } from "../core/json-schema-processors.cjs";
|
||||
export { fromJSONSchema } from "./from-json-schema.cjs";
|
||||
export { deepPartial } from "./deep-partial.cjs";
|
||||
export { input, output } from "./in-out.cjs";
|
||||
export * as locales from "../locales/index.cjs";
|
||||
export { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from "./iso.cjs";
|
||||
export * as iso from "./iso.cjs";
|
||||
export type { ZodCoercedString, ZodCoercedNumber, ZodCoercedBigInt, ZodCoercedBoolean, ZodCoercedDate, } from "./coerce.cjs";
|
||||
export * as coerce from "./coerce.cjs";
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
export * as core from "../core/index.js";
|
||||
export * from "./schemas.js";
|
||||
export * from "./checks.js";
|
||||
export * from "./errors.js";
|
||||
export * from "./parse.js";
|
||||
export * from "./compat.js";
|
||||
export { globalRegistry, registry, config, memoizer, $output, $input, $brand, clone, regexes, treeifyError, prettifyError, formatError, flattenError, TimePrecision, util, NEVER, INVALID, toZod, compile, withParser, ZodCompileAsyncError, ZodCompileUnsupportedError, getDiscriminatedOption, } from "../core/index.js";
|
||||
export { toJSONSchema } from "../core/json-schema-processors.js";
|
||||
export { fromJSONSchema } from "./from-json-schema.js";
|
||||
export { deepPartial } from "./deep-partial.js";
|
||||
// Types and values both, from one module — re-exporting the types from core would collide.
|
||||
export { input, output } from "./in-out.js";
|
||||
export * as locales from "../locales/index.js";
|
||||
// iso must be exported from top-level https://github.com/colinhacks/zod/issues/4491
|
||||
export { ZodISODateTime, ZodISODate, ZodISOTime, ZodISODuration } from "./iso.js";
|
||||
export * as iso from "./iso.js";
|
||||
export * as coerce from "./coerce.js";
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import type * as JSONSchema from "../core/json-schema.cjs";
|
||||
import { type $ZodRegistry } from "../core/registries.cjs";
|
||||
import type { ZodType } from "./schemas.cjs";
|
||||
type JSONSchemaVersion = "draft-2020-12" | "draft-7" | "draft-4" | "openapi-3.0";
|
||||
interface FromJSONSchemaParams {
|
||||
defaultTarget?: JSONSchemaVersion;
|
||||
registry?: $ZodRegistry<any>;
|
||||
}
|
||||
/**
|
||||
* Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */
|
||||
export declare function fromJSONSchema(schema: JSONSchema.JSONSchema | boolean, params?: FromJSONSchemaParams): ZodType;
|
||||
export {};
|
||||
+881
@@ -0,0 +1,881 @@
|
||||
import { globalRegistry } from "../core/registries.js";
|
||||
import { assignProp, isPlainObject } from "../core/util.js";
|
||||
import * as _checks from "./checks.js";
|
||||
import * as _iso from "./iso.js";
|
||||
import * as _schemas from "./schemas.js";
|
||||
// Local z object to avoid circular dependency with ../index.js
|
||||
const z = {
|
||||
..._schemas,
|
||||
..._checks,
|
||||
iso: _iso,
|
||||
};
|
||||
// Keys that are recognized and handled by the conversion logic
|
||||
const RECOGNIZED_KEYS = /*@__PURE__*/ new Set([
|
||||
// Schema identification
|
||||
"$schema",
|
||||
"$ref",
|
||||
"$defs",
|
||||
"definitions",
|
||||
// Core schema keywords
|
||||
"$id",
|
||||
"id",
|
||||
"$comment",
|
||||
"$anchor",
|
||||
"$vocabulary",
|
||||
"$dynamicRef",
|
||||
"$dynamicAnchor",
|
||||
// Type
|
||||
"type",
|
||||
"enum",
|
||||
"const",
|
||||
// Composition
|
||||
"anyOf",
|
||||
"oneOf",
|
||||
"allOf",
|
||||
"not",
|
||||
// Object
|
||||
"properties",
|
||||
"required",
|
||||
"additionalProperties",
|
||||
"patternProperties",
|
||||
"propertyNames",
|
||||
"minProperties",
|
||||
"maxProperties",
|
||||
// Array
|
||||
"items",
|
||||
"prefixItems",
|
||||
"additionalItems",
|
||||
"minItems",
|
||||
"maxItems",
|
||||
"uniqueItems",
|
||||
"contains",
|
||||
"minContains",
|
||||
"maxContains",
|
||||
// String
|
||||
"minLength",
|
||||
"maxLength",
|
||||
"pattern",
|
||||
"format",
|
||||
// Number
|
||||
"minimum",
|
||||
"maximum",
|
||||
"exclusiveMinimum",
|
||||
"exclusiveMaximum",
|
||||
"multipleOf",
|
||||
// Already handled metadata
|
||||
"description",
|
||||
"default",
|
||||
// Content
|
||||
"contentEncoding",
|
||||
"contentMediaType",
|
||||
"contentSchema",
|
||||
// Unsupported (error-throwing)
|
||||
"unevaluatedItems",
|
||||
"unevaluatedProperties",
|
||||
"if",
|
||||
"then",
|
||||
"else",
|
||||
"dependentSchemas",
|
||||
"dependentRequired",
|
||||
// OpenAPI
|
||||
"nullable",
|
||||
"readOnly",
|
||||
]);
|
||||
function detectVersion(schema, defaultTarget) {
|
||||
const $schema = schema.$schema;
|
||||
if ($schema === "https://json-schema.org/draft/2020-12/schema") {
|
||||
return "draft-2020-12";
|
||||
}
|
||||
if ($schema === "http://json-schema.org/draft-07/schema#") {
|
||||
return "draft-7";
|
||||
}
|
||||
if ($schema === "http://json-schema.org/draft-04/schema#") {
|
||||
return "draft-4";
|
||||
}
|
||||
// Use defaultTarget if provided, otherwise default to draft-2020-12
|
||||
return defaultTarget ?? "draft-2020-12";
|
||||
}
|
||||
// Positional schemas constrain the elements that are present; only minItems makes them required.
|
||||
function applyMinItems(items, minItems) {
|
||||
return items.map((item, index) => (index < minItems ? item : item.optional()));
|
||||
}
|
||||
// Inverse of the encoding applied to $ref pointer segments in to-json-schema.ts. Per RFC 6901 the `~1` replacement must run before `~0`.
|
||||
function decodeJSONPointerSegment(segment) {
|
||||
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
||||
}
|
||||
function resolveRef(ref, ctx) {
|
||||
if (!ref.startsWith("#")) {
|
||||
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
||||
}
|
||||
const path = ref.slice(1).split("/").filter(Boolean);
|
||||
// Handle root reference "#"
|
||||
if (path.length === 0) {
|
||||
return ctx.rootSchema;
|
||||
}
|
||||
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
||||
if (path[0] === defsKey) {
|
||||
const key = path[1] === undefined ? undefined : decodeJSONPointerSegment(path[1]);
|
||||
if (!key || !ctx.defs[key]) {
|
||||
throw new Error(`Reference not found: ${ref}`);
|
||||
}
|
||||
return ctx.defs[key];
|
||||
}
|
||||
throw new Error(`Reference not found: ${ref}`);
|
||||
}
|
||||
/**
|
||||
* Enforces the keywords that constrain an object's own keys — `propertyNames`,
|
||||
* `minProperties`, `maxProperties` — before `objectSchema` runs. The guard has
|
||||
* to see the raw input: an object parse drops `__proto__` and can add keys from
|
||||
* a property `default`, so its output is not the set of names the instance
|
||||
* actually carried.
|
||||
*/
|
||||
function checkObjectGuards(objectSchema, guards) {
|
||||
// An identity transform, not z.any(), so `toJSONSchema` reports the object on both the input and the output side of the pipe.
|
||||
const guard = z
|
||||
.transform((value) => value)
|
||||
.check((payload) => {
|
||||
const value = payload.value;
|
||||
if (typeof value !== "object" || value === null || Array.isArray(value))
|
||||
return;
|
||||
const keys = Object.getOwnPropertyNames(value);
|
||||
if (guards.minProperties !== undefined && keys.length < guards.minProperties) {
|
||||
payload.issues.push({
|
||||
origin: "object",
|
||||
code: "too_small",
|
||||
minimum: guards.minProperties,
|
||||
inclusive: true,
|
||||
message: `Too small: expected object to have >=${guards.minProperties} properties`,
|
||||
input: value,
|
||||
inst: objectSchema,
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
if (guards.maxProperties !== undefined && keys.length > guards.maxProperties) {
|
||||
payload.issues.push({
|
||||
origin: "object",
|
||||
code: "too_big",
|
||||
maximum: guards.maxProperties,
|
||||
inclusive: true,
|
||||
message: `Too big: expected object to have <=${guards.maxProperties} properties`,
|
||||
input: value,
|
||||
inst: objectSchema,
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
if (guards.keySchema) {
|
||||
for (const key of keys) {
|
||||
const result = guards.keySchema.safeParse(key);
|
||||
if (result.success)
|
||||
continue;
|
||||
payload.issues.push({
|
||||
code: "invalid_key",
|
||||
origin: "record",
|
||||
issues: result.error.issues,
|
||||
input: key,
|
||||
path: [key],
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return guard.pipe(objectSchema);
|
||||
}
|
||||
/**
|
||||
* An injective string for JSON data: two values share a key exactly when `uniqueItems` calls them
|
||||
* equal, so duplicate detection is a Map lookup rather than a pairwise walk. Strings and keys are
|
||||
* length-prefixed so no value can spell another one. `null` means "never equal to anything" — a
|
||||
* cycle or a NaN, neither of which JSON can express.
|
||||
*/
|
||||
function canonicalKey(value, seen) {
|
||||
if (value === null)
|
||||
return "z";
|
||||
const type = typeof value;
|
||||
if (type !== "object") {
|
||||
if (type === "number" && Number.isNaN(value))
|
||||
return null;
|
||||
const raw = String(value);
|
||||
return `${type[0]}${raw.length}:${raw}`;
|
||||
}
|
||||
if (seen.has(value))
|
||||
return null;
|
||||
seen.add(value);
|
||||
try {
|
||||
if (Array.isArray(value)) {
|
||||
const parts = [];
|
||||
for (const item of value) {
|
||||
const key = canonicalKey(item, seen);
|
||||
if (key === null)
|
||||
return null;
|
||||
parts.push(key);
|
||||
}
|
||||
return `a${parts.length}:[${parts.join(",")}]`;
|
||||
}
|
||||
const keys = Object.keys(value).sort();
|
||||
const parts = [];
|
||||
for (const k of keys) {
|
||||
const key = canonicalKey(value[k], seen);
|
||||
if (key === null)
|
||||
return null;
|
||||
parts.push(`${k.length}:${k}=${key}`);
|
||||
}
|
||||
return `o${parts.length}:{${parts.join(",")}}`;
|
||||
}
|
||||
finally {
|
||||
seen.delete(value);
|
||||
}
|
||||
}
|
||||
// keywords whose value is a schema or an array of them
|
||||
const SCHEMA_KEYWORDS = /*@__PURE__*/ new Set([
|
||||
"items",
|
||||
"prefixItems",
|
||||
"additionalItems",
|
||||
"additionalProperties",
|
||||
"contains",
|
||||
"propertyNames",
|
||||
"not",
|
||||
"if",
|
||||
"then",
|
||||
"else",
|
||||
"allOf",
|
||||
"anyOf",
|
||||
"oneOf",
|
||||
"unevaluatedItems",
|
||||
"unevaluatedProperties",
|
||||
"contentSchema",
|
||||
]);
|
||||
// keywords whose value maps names to schemas. draft-7 `dependencies` also allows an array of property names, which holds no schema to walk
|
||||
const SCHEMA_MAP_KEYWORDS = /*@__PURE__*/ new Set([
|
||||
"properties",
|
||||
"patternProperties",
|
||||
"dependentSchemas",
|
||||
"dependencies",
|
||||
"$defs",
|
||||
"definitions",
|
||||
]);
|
||||
/**
|
||||
* True when a subschema holds a `$ref` anywhere a schema can appear. Only those positions are
|
||||
* walked: `$ref` under `default` or an `x-` annotation is instance data with an ordinary key, and
|
||||
* reading it as a reference would drop a constraint that resolves perfectly well.
|
||||
*/
|
||||
function containsRef(value) {
|
||||
if (typeof value !== "object" || value === null)
|
||||
return false;
|
||||
if (Array.isArray(value))
|
||||
return value.some(containsRef);
|
||||
if (typeof value.$ref === "string")
|
||||
return true;
|
||||
return Object.entries(value).some(([key, sub]) => {
|
||||
if (SCHEMA_KEYWORDS.has(key))
|
||||
return containsRef(sub);
|
||||
if (!SCHEMA_MAP_KEYWORDS.has(key) || typeof sub !== "object" || sub === null)
|
||||
return false;
|
||||
return Object.values(sub).some(containsRef);
|
||||
});
|
||||
}
|
||||
function plural(n) {
|
||||
return n === 1 ? "element" : "elements";
|
||||
}
|
||||
/**
|
||||
* Enforces `uniqueItems` and the `contains` family before `arraySchema` runs, for the same reason
|
||||
* `checkObjectGuards` runs pre-pipe: an item parse can apply a nested `default`, so the parsed
|
||||
* array is not the instance the keywords are defined over. A guard issue aborts the pipe, so
|
||||
* `minItems`/`maxItems` are not also reported on the same parse — instance correctness is worth
|
||||
* more than co-reporting two issues.
|
||||
*/
|
||||
function checkArrayGuards(arraySchema, guards) {
|
||||
// An identity transform, not z.any(), so `toJSONSchema` reports the array on both the input and the output side of the pipe.
|
||||
const guard = z
|
||||
.transform((value) => value)
|
||||
.check((payload) => {
|
||||
const items = payload.value;
|
||||
if (!Array.isArray(items))
|
||||
return;
|
||||
if (guards.uniqueItems === true) {
|
||||
const firstSeen = new Map();
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const key = canonicalKey(items[i], new Set());
|
||||
if (key === null)
|
||||
continue;
|
||||
const first = firstSeen.get(key);
|
||||
if (first === undefined) {
|
||||
firstSeen.set(key, i);
|
||||
continue;
|
||||
}
|
||||
payload.issues.push({
|
||||
code: "custom",
|
||||
message: `Array items must be unique: element at index ${i} duplicates the one at index ${first}`,
|
||||
input: items,
|
||||
path: [i],
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (guards.containsSchema) {
|
||||
const minContains = guards.minContains ?? 1;
|
||||
// one past the ceiling already proves the failure, and nothing above it changes the verdict
|
||||
const ceiling = guards.maxContains !== undefined ? guards.maxContains + 1 : Number.POSITIVE_INFINITY;
|
||||
let matches = 0;
|
||||
for (const item of items) {
|
||||
if (guards.containsSchema.safeParse(item).success && ++matches >= ceiling)
|
||||
break;
|
||||
}
|
||||
if (matches < minContains) {
|
||||
// the scan ran to the end, so this count is exact
|
||||
payload.issues.push({
|
||||
code: "custom",
|
||||
message: `Array must contain at least ${minContains} matching ${plural(minContains)}; found ${matches}`,
|
||||
input: items,
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
if (guards.maxContains !== undefined && matches > guards.maxContains) {
|
||||
payload.issues.push({
|
||||
code: "custom",
|
||||
message: `Array must contain at most ${guards.maxContains} matching ${plural(guards.maxContains)}`,
|
||||
input: items,
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return guard.pipe(arraySchema);
|
||||
}
|
||||
function getTupleRest(restSchema, ctx) {
|
||||
if (restSchema === false) {
|
||||
return undefined;
|
||||
}
|
||||
if (restSchema === undefined || restSchema === true) {
|
||||
return z.any();
|
||||
}
|
||||
return convertSchema(restSchema, ctx);
|
||||
}
|
||||
// the RFC 3339 full-time keyword, narrower than `z.iso.time()`; local because sharing it via `timeSource` pins that builder into every bundle (+139 B gzipped on a mini `z.boolean()`)
|
||||
const fullTime = /^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
||||
function convertBaseSchema(schema, ctx) {
|
||||
// Handle unsupported features
|
||||
if (schema.not !== undefined) {
|
||||
// Special case: { not: {} } represents never
|
||||
if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) {
|
||||
return z.never();
|
||||
}
|
||||
throw new Error("not is not supported in Zod (except { not: {} } for never)");
|
||||
}
|
||||
if (schema.unevaluatedItems !== undefined) {
|
||||
throw new Error("unevaluatedItems is not supported");
|
||||
}
|
||||
if (schema.unevaluatedProperties !== undefined) {
|
||||
throw new Error("unevaluatedProperties is not supported");
|
||||
}
|
||||
if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) {
|
||||
throw new Error("Conditional schemas (if/then/else) are not supported");
|
||||
}
|
||||
if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) {
|
||||
throw new Error("dependentSchemas and dependentRequired are not supported");
|
||||
}
|
||||
// Handle $ref
|
||||
if (schema.$ref) {
|
||||
const refPath = schema.$ref;
|
||||
if (ctx.refs.has(refPath)) {
|
||||
return ctx.refs.get(refPath);
|
||||
}
|
||||
if (ctx.processing.has(refPath)) {
|
||||
// Circular reference - use lazy
|
||||
return z.lazy(() => {
|
||||
if (!ctx.refs.has(refPath)) {
|
||||
throw new Error(`Circular reference not resolved: ${refPath}`);
|
||||
}
|
||||
return ctx.refs.get(refPath);
|
||||
});
|
||||
}
|
||||
ctx.processing.add(refPath);
|
||||
const resolved = resolveRef(refPath, ctx);
|
||||
const zodSchema = convertSchema(resolved, ctx);
|
||||
ctx.refs.set(refPath, zodSchema);
|
||||
ctx.processing.delete(refPath);
|
||||
return zodSchema;
|
||||
}
|
||||
// Handle enum
|
||||
if (schema.enum !== undefined) {
|
||||
const enumValues = schema.enum;
|
||||
// Special case: OpenAPI 3.0 null representation { type: "string", nullable: true, enum: [null] }
|
||||
if (ctx.version === "openapi-3.0" &&
|
||||
schema.nullable === true &&
|
||||
enumValues.length === 1 &&
|
||||
enumValues[0] === null) {
|
||||
return z.null();
|
||||
}
|
||||
if (enumValues.length === 0) {
|
||||
return z.never();
|
||||
}
|
||||
if (enumValues.length === 1) {
|
||||
return z.literal(enumValues[0]);
|
||||
}
|
||||
// Check if all values are strings
|
||||
if (enumValues.every((v) => typeof v === "string")) {
|
||||
return z.enum(enumValues);
|
||||
}
|
||||
// Mixed types - use union of literals
|
||||
const literalSchemas = enumValues.map((v) => z.literal(v));
|
||||
if (literalSchemas.length < 2) {
|
||||
return literalSchemas[0];
|
||||
}
|
||||
return z.union([literalSchemas[0], literalSchemas[1], ...literalSchemas.slice(2)]);
|
||||
}
|
||||
// Handle const
|
||||
if (schema.const !== undefined) {
|
||||
return z.literal(schema.const);
|
||||
}
|
||||
// Handle type
|
||||
const type = schema.type;
|
||||
if (Array.isArray(type)) {
|
||||
// Expand type array into anyOf union
|
||||
const typeSchemas = type.map((t) => {
|
||||
const typeSchema = { ...schema, type: t };
|
||||
return convertBaseSchema(typeSchema, ctx);
|
||||
});
|
||||
if (typeSchemas.length === 0) {
|
||||
return z.never();
|
||||
}
|
||||
if (typeSchemas.length === 1) {
|
||||
return typeSchemas[0];
|
||||
}
|
||||
return z.union(typeSchemas);
|
||||
}
|
||||
if (!type) {
|
||||
// No type specified - empty schema (any)
|
||||
return z.any();
|
||||
}
|
||||
let zodSchema;
|
||||
switch (type) {
|
||||
case "string": {
|
||||
let stringSchema = z.string();
|
||||
// Apply format using .check() with Zod format functions
|
||||
if (schema.format) {
|
||||
const format = schema.format;
|
||||
// Map common formats to Zod check functions
|
||||
if (format === "email") {
|
||||
stringSchema = stringSchema.check(z.email());
|
||||
}
|
||||
else if (format === "uri" || format === "uri-reference") {
|
||||
stringSchema = stringSchema.check(z.url());
|
||||
}
|
||||
else if (format === "uuid" || format === "guid") {
|
||||
stringSchema = stringSchema.check(z.uuid());
|
||||
}
|
||||
else if (format === "date-time") {
|
||||
stringSchema = stringSchema.check(z.iso.datetime({ offset: true }));
|
||||
}
|
||||
else if (format === "date") {
|
||||
stringSchema = stringSchema.check(z.iso.date());
|
||||
}
|
||||
else if (format === "time") {
|
||||
stringSchema = stringSchema.check(z.regex(fullTime));
|
||||
}
|
||||
else if (format === "duration") {
|
||||
stringSchema = stringSchema.check(z.iso.duration());
|
||||
}
|
||||
else if (format === "hostname") {
|
||||
stringSchema = stringSchema.check(z.hostname());
|
||||
}
|
||||
else if (format === "ipv4") {
|
||||
stringSchema = stringSchema.check(z.ipv4());
|
||||
}
|
||||
else if (format === "ipv6") {
|
||||
stringSchema = stringSchema.check(z.ipv6());
|
||||
}
|
||||
else if (format === "mac") {
|
||||
stringSchema = stringSchema.check(z.mac());
|
||||
}
|
||||
else if (format === "cidr") {
|
||||
stringSchema = stringSchema.check(z.cidrv4());
|
||||
}
|
||||
else if (format === "cidr-v6") {
|
||||
stringSchema = stringSchema.check(z.cidrv6());
|
||||
}
|
||||
else if (format === "base64") {
|
||||
stringSchema = stringSchema.check(z.base64());
|
||||
}
|
||||
else if (format === "base64url") {
|
||||
stringSchema = stringSchema.check(z.base64url());
|
||||
}
|
||||
else if (format === "e164") {
|
||||
stringSchema = stringSchema.check(z.e164());
|
||||
}
|
||||
else if (format === "credit_card") {
|
||||
stringSchema = stringSchema.check(z.creditCard());
|
||||
}
|
||||
else if (format === "iban") {
|
||||
stringSchema = stringSchema.check(z.iban());
|
||||
}
|
||||
else if (format === "jwt") {
|
||||
stringSchema = stringSchema.check(z.jwt());
|
||||
}
|
||||
else if (format === "emoji") {
|
||||
stringSchema = stringSchema.check(z.emoji());
|
||||
}
|
||||
else if (format === "nanoid") {
|
||||
stringSchema = stringSchema.check(z.nanoid());
|
||||
}
|
||||
else if (format === "cuid") {
|
||||
stringSchema = stringSchema.check(z.cuid());
|
||||
}
|
||||
else if (format === "cuid2") {
|
||||
stringSchema = stringSchema.check(z.cuid2());
|
||||
}
|
||||
else if (format === "ulid") {
|
||||
stringSchema = stringSchema.check(z.ulid());
|
||||
}
|
||||
else if (format === "xid") {
|
||||
stringSchema = stringSchema.check(z.xid());
|
||||
}
|
||||
else if (format === "ksuid") {
|
||||
stringSchema = stringSchema.check(z.ksuid());
|
||||
}
|
||||
// Note: json-string format is not currently supported by Zod
|
||||
// Custom formats are ignored - keep as plain string
|
||||
}
|
||||
// Apply constraints
|
||||
if (typeof schema.minLength === "number") {
|
||||
stringSchema = stringSchema.min(schema.minLength);
|
||||
}
|
||||
if (typeof schema.maxLength === "number") {
|
||||
stringSchema = stringSchema.max(schema.maxLength);
|
||||
}
|
||||
if (schema.pattern) {
|
||||
// JSON Schema patterns are not implicitly anchored (match anywhere in string)
|
||||
stringSchema = stringSchema.regex(new RegExp(schema.pattern));
|
||||
}
|
||||
zodSchema = stringSchema;
|
||||
break;
|
||||
}
|
||||
case "number":
|
||||
case "integer": {
|
||||
let numberSchema = type === "integer" ? z.number().int() : z.number();
|
||||
// Apply constraints
|
||||
// In draft-04, `exclusiveMinimum: true` makes the sibling `minimum` exclusive rather than an independent bound, so the inclusive `.min()` is skipped; emitting it too would be dominated by the exclusive check and report a second, weaker issue.
|
||||
if (typeof schema.minimum === "number" && schema.exclusiveMinimum !== true) {
|
||||
numberSchema = numberSchema.min(schema.minimum);
|
||||
}
|
||||
if (typeof schema.maximum === "number" && schema.exclusiveMaximum !== true) {
|
||||
numberSchema = numberSchema.max(schema.maximum);
|
||||
}
|
||||
if (typeof schema.exclusiveMinimum === "number") {
|
||||
numberSchema = numberSchema.gt(schema.exclusiveMinimum);
|
||||
}
|
||||
else if (schema.exclusiveMinimum === true && typeof schema.minimum === "number") {
|
||||
numberSchema = numberSchema.gt(schema.minimum);
|
||||
}
|
||||
if (typeof schema.exclusiveMaximum === "number") {
|
||||
numberSchema = numberSchema.lt(schema.exclusiveMaximum);
|
||||
}
|
||||
else if (schema.exclusiveMaximum === true && typeof schema.maximum === "number") {
|
||||
numberSchema = numberSchema.lt(schema.maximum);
|
||||
}
|
||||
if (typeof schema.multipleOf === "number") {
|
||||
numberSchema = numberSchema.multipleOf(schema.multipleOf);
|
||||
}
|
||||
zodSchema = numberSchema;
|
||||
break;
|
||||
}
|
||||
case "boolean": {
|
||||
zodSchema = z.boolean();
|
||||
break;
|
||||
}
|
||||
case "null": {
|
||||
zodSchema = z.null();
|
||||
break;
|
||||
}
|
||||
case "object": {
|
||||
const shape = {};
|
||||
const properties = schema.properties || {};
|
||||
const requiredSet = new Set(schema.required || []);
|
||||
const additionalSchema = typeof schema.additionalProperties === "object"
|
||||
? convertSchema(schema.additionalProperties, ctx)
|
||||
: undefined;
|
||||
// Convert properties - mark optional ones
|
||||
for (const [key, propSchema] of Object.entries(properties)) {
|
||||
const propZodSchema = convertSchema(propSchema, ctx);
|
||||
// If not in required array, make it optional. assignProp so a __proto__ key becomes an own property instead of hitting the inherited setter
|
||||
assignProp(shape, key, requiredSet.has(key) ? propZodSchema : propZodSchema.optional());
|
||||
}
|
||||
// Handle patternProperties
|
||||
if (schema.patternProperties) {
|
||||
// patternProperties: keys matching pattern must satisfy corresponding schema. Use loose records so non-matching keys pass through
|
||||
const patternProps = schema.patternProperties;
|
||||
const patternKeys = Object.keys(patternProps);
|
||||
const looseRecords = [];
|
||||
for (const pattern of patternKeys) {
|
||||
const patternValue = convertSchema(patternProps[pattern], ctx);
|
||||
const keySchema = z.string().regex(new RegExp(pattern));
|
||||
looseRecords.push(z.looseRecord(keySchema, patternValue));
|
||||
}
|
||||
// Build intersection: object schema + all pattern property records
|
||||
const schemasToIntersect = [];
|
||||
if (Object.keys(shape).length > 0) {
|
||||
// Use passthrough so patternProperties can validate additional keys
|
||||
schemasToIntersect.push(z.object(shape).passthrough());
|
||||
}
|
||||
schemasToIntersect.push(...looseRecords);
|
||||
if (schemasToIntersect.length === 0) {
|
||||
zodSchema = z.object({}).passthrough();
|
||||
}
|
||||
else if (schemasToIntersect.length === 1) {
|
||||
zodSchema = schemasToIntersect[0];
|
||||
}
|
||||
else {
|
||||
// Chain intersections: (A & B) & C & D ...
|
||||
let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);
|
||||
for (let i = 2; i < schemasToIntersect.length; i++) {
|
||||
result = z.intersection(result, schemasToIntersect[i]);
|
||||
}
|
||||
zodSchema = result;
|
||||
}
|
||||
// When additionalProperties is false, reject keys that are neither defined in properties nor matched by any patternProperty.
|
||||
if (schema.additionalProperties === false) {
|
||||
const propertyKeys = Object.keys(shape);
|
||||
const patterns = patternKeys.map((p) => new RegExp(p));
|
||||
const basePatternSchema = zodSchema;
|
||||
zodSchema = zodSchema.check((payload) => {
|
||||
if (!isPlainObject(payload.value))
|
||||
return;
|
||||
const unrecognized = [];
|
||||
for (const key of Object.keys(payload.value)) {
|
||||
if (propertyKeys.includes(key))
|
||||
continue;
|
||||
if (patterns.some((regex) => regex.test(key)))
|
||||
continue;
|
||||
unrecognized.push(key);
|
||||
}
|
||||
if (unrecognized.length) {
|
||||
payload.issues.push({
|
||||
code: "unrecognized_keys",
|
||||
keys: unrecognized,
|
||||
input: payload.value,
|
||||
inst: basePatternSchema,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Handle additionalProperties. In JSON Schema, additionalProperties defaults to true (allow any extra properties). In Zod, objects strip unknown keys by default, so we need to handle this explicitly
|
||||
const objectSchema = z.object(shape);
|
||||
if (schema.additionalProperties === false) {
|
||||
// Strict mode - no extra properties allowed
|
||||
zodSchema = objectSchema.strict();
|
||||
}
|
||||
else if (additionalSchema) {
|
||||
// Extra properties must match the specified schema
|
||||
zodSchema = objectSchema.catchall(additionalSchema);
|
||||
}
|
||||
else {
|
||||
// additionalProperties is true or undefined - allow any extra properties (passthrough)
|
||||
zodSchema = objectSchema.passthrough();
|
||||
}
|
||||
}
|
||||
// propertyNames constrains key *names* only, and says nothing about which keys are required or how their values validate. Layering it on top of the result keeps properties/patternProperties/additionalProperties composing underneath. `true` allows every name, so it needs no guard.
|
||||
const hasKeyGuard = schema.propertyNames !== undefined && schema.propertyNames !== true;
|
||||
const minProperties = typeof schema.minProperties === "number" ? schema.minProperties : undefined;
|
||||
const maxProperties = typeof schema.maxProperties === "number" ? schema.maxProperties : undefined;
|
||||
if (hasKeyGuard || minProperties !== undefined || maxProperties !== undefined) {
|
||||
let keySchema;
|
||||
if (hasKeyGuard) {
|
||||
// Keys are always strings, so a propertyNames subschema that omits `type` still constrains them — without this it would convert to z.any().
|
||||
const keyJSONSchema = typeof schema.propertyNames === "object" && schema.propertyNames.type === undefined
|
||||
? { type: "string", ...schema.propertyNames }
|
||||
: schema.propertyNames;
|
||||
keySchema = convertSchema(keyJSONSchema, ctx);
|
||||
}
|
||||
zodSchema = checkObjectGuards(zodSchema, { keySchema, minProperties, maxProperties });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "array": {
|
||||
// Check if this is a tuple (prefixItems or items as array)
|
||||
const prefixItems = schema.prefixItems;
|
||||
const items = schema.items;
|
||||
if (prefixItems && Array.isArray(prefixItems)) {
|
||||
// Tuple with prefixItems (draft-2020-12)
|
||||
const minItems = typeof schema.minItems === "number" ? schema.minItems : 0;
|
||||
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
||||
const positionalItems = applyMinItems(tupleItems, minItems);
|
||||
const rest = !Array.isArray(items) ? getTupleRest(items, ctx) : undefined;
|
||||
const tupleSchema = z.tuple(positionalItems);
|
||||
zodSchema = rest ? tupleSchema.rest(rest) : tupleSchema;
|
||||
// Apply minItems/maxItems constraints to tuples
|
||||
if (typeof schema.minItems === "number") {
|
||||
zodSchema = zodSchema.check(z.minLength(schema.minItems));
|
||||
}
|
||||
if (typeof schema.maxItems === "number") {
|
||||
zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
|
||||
}
|
||||
}
|
||||
else if (Array.isArray(items)) {
|
||||
// Tuple with items array (draft-7)
|
||||
const minItems = typeof schema.minItems === "number" ? schema.minItems : 0;
|
||||
const tupleItems = items.map((item) => convertSchema(item, ctx));
|
||||
const positionalItems = applyMinItems(tupleItems, minItems);
|
||||
const rest = getTupleRest(schema.additionalItems, ctx);
|
||||
const tupleSchema = z.tuple(positionalItems);
|
||||
zodSchema = rest ? tupleSchema.rest(rest) : tupleSchema;
|
||||
// Apply minItems/maxItems constraints to tuples
|
||||
if (typeof schema.minItems === "number") {
|
||||
zodSchema = zodSchema.check(z.minLength(schema.minItems));
|
||||
}
|
||||
if (typeof schema.maxItems === "number") {
|
||||
zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
|
||||
}
|
||||
}
|
||||
else if (items !== undefined) {
|
||||
// Regular array
|
||||
const element = convertSchema(items, ctx);
|
||||
let arraySchema = z.array(element);
|
||||
// Apply constraints
|
||||
if (typeof schema.minItems === "number") {
|
||||
arraySchema = arraySchema.min(schema.minItems);
|
||||
}
|
||||
if (typeof schema.maxItems === "number") {
|
||||
arraySchema = arraySchema.max(schema.maxItems);
|
||||
}
|
||||
zodSchema = arraySchema;
|
||||
}
|
||||
else {
|
||||
// No items specified - array of any
|
||||
zodSchema = z.array(z.any());
|
||||
}
|
||||
// minContains/maxContains only constrain anything when `contains` itself is present
|
||||
if (schema.uniqueItems === true || schema.contains !== undefined) {
|
||||
zodSchema = checkArrayGuards(zodSchema, {
|
||||
uniqueItems: schema.uniqueItems === true,
|
||||
containsSchema: schema.contains !== undefined ? convertSchema(schema.contains, ctx) : undefined,
|
||||
minContains: typeof schema.minContains === "number" ? schema.minContains : undefined,
|
||||
maxContains: typeof schema.maxContains === "number" ? schema.maxContains : undefined,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unsupported type: ${type}`);
|
||||
}
|
||||
return zodSchema;
|
||||
}
|
||||
function convertSchema(schema, ctx) {
|
||||
if (typeof schema === "boolean") {
|
||||
return schema ? z.any() : z.never();
|
||||
}
|
||||
// Convert base schema first (ignoring composition keywords)
|
||||
let baseSchema = convertBaseSchema(schema, ctx);
|
||||
const hasExplicitType = schema.type || schema.enum !== undefined || schema.const !== undefined;
|
||||
// Process composition keywords LAST (they can appear together)
|
||||
// Handle anyOf - wrap base schema with union
|
||||
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
||||
const options = schema.anyOf.map((s) => convertSchema(s, ctx));
|
||||
const anyOfUnion = z.union(options);
|
||||
baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
|
||||
}
|
||||
// Handle oneOf - exclusive union (exactly one must match)
|
||||
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
||||
const options = schema.oneOf.map((s) => convertSchema(s, ctx));
|
||||
const oneOfUnion = z.xor(options);
|
||||
baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
|
||||
}
|
||||
// Handle allOf - wrap base schema with intersection
|
||||
if (schema.allOf && Array.isArray(schema.allOf)) {
|
||||
if (schema.allOf.length === 0) {
|
||||
baseSchema = hasExplicitType ? baseSchema : z.any();
|
||||
}
|
||||
else {
|
||||
let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
|
||||
const startIdx = hasExplicitType ? 0 : 1;
|
||||
for (let i = startIdx; i < schema.allOf.length; i++) {
|
||||
result = z.intersection(result, convertSchema(schema.allOf[i], ctx));
|
||||
}
|
||||
baseSchema = result;
|
||||
}
|
||||
}
|
||||
// Handle nullable (OpenAPI 3.0)
|
||||
if (schema.nullable === true && ctx.version === "openapi-3.0") {
|
||||
baseSchema = z.nullable(baseSchema);
|
||||
}
|
||||
// Handle readOnly
|
||||
if (schema.readOnly === true) {
|
||||
baseSchema = z.readonly(baseSchema);
|
||||
}
|
||||
// Apply `default` so it wraps the fully-composed schema. This ensures `parse(undefined) -> default` works regardless of which branch of `convertBaseSchema` produced the inner schema (enum/const/not/typed/etc.).
|
||||
if (schema.default !== undefined) {
|
||||
baseSchema = baseSchema.default(schema.default);
|
||||
}
|
||||
// Collect non-description annotation metadata into the user-supplied registry. Description is handled separately below via `.describe()` to preserve the contract that `schema.description` reads from globalRegistry.
|
||||
const extraMeta = {};
|
||||
const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
|
||||
for (const key of coreMetadataKeys) {
|
||||
if (key in schema) {
|
||||
extraMeta[key] = schema[key];
|
||||
}
|
||||
}
|
||||
const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
|
||||
for (const key of contentMetadataKeys) {
|
||||
if (key in schema) {
|
||||
extraMeta[key] = schema[key];
|
||||
}
|
||||
}
|
||||
// `propertyNames` and `contains` are enforced by a guard, which `toJSONSchema` cannot infer, so the original keyword is carried as metadata to keep the round-trip lossless. Only where it was actually applied: on any other type it is inert, and on a `$ref` the metadata would land on the target every reference shares. A carried subschema is copied verbatim while the root `$defs` stay behind, so one holding a `$ref` is dropped rather than emitted as a dangling reference.
|
||||
if (schema.type === "object" && schema.$ref === undefined) {
|
||||
if (schema.propertyNames !== undefined && !containsRef(schema.propertyNames)) {
|
||||
extraMeta.propertyNames = schema.propertyNames;
|
||||
}
|
||||
for (const key of ["minProperties", "maxProperties"]) {
|
||||
if (schema[key] !== undefined)
|
||||
extraMeta[key] = schema[key];
|
||||
}
|
||||
}
|
||||
if (schema.type === "array" && schema.$ref === undefined) {
|
||||
if (schema.contains !== undefined && !containsRef(schema.contains)) {
|
||||
extraMeta.contains = schema.contains;
|
||||
}
|
||||
for (const key of ["uniqueItems", "minContains", "maxContains"]) {
|
||||
if (schema[key] !== undefined)
|
||||
extraMeta[key] = schema[key];
|
||||
}
|
||||
}
|
||||
for (const key of Object.keys(schema)) {
|
||||
if (!RECOGNIZED_KEYS.has(key)) {
|
||||
assignProp(extraMeta, key, schema[key]);
|
||||
}
|
||||
}
|
||||
if (Object.keys(extraMeta).length > 0) {
|
||||
ctx.registry.add(baseSchema, extraMeta);
|
||||
}
|
||||
// Apply description last. `.describe()` clones the schema and sets `_zod.parent` on the clone, so registry lookups on the returned reference still resolve `extraMeta` via parent inheritance.
|
||||
if (schema.description) {
|
||||
baseSchema = baseSchema.describe(schema.description);
|
||||
}
|
||||
return baseSchema;
|
||||
}
|
||||
/**
|
||||
* Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */
|
||||
export function fromJSONSchema(schema, params) {
|
||||
// Handle boolean schemas
|
||||
if (typeof schema === "boolean") {
|
||||
return schema ? z.any() : z.never();
|
||||
}
|
||||
// Normalize input via a JSON round-trip. This guarantees the converter walks a plain, finite, JSON-valid object graph: cyclic inputs fail here, getter/Proxy-based properties are materialized into static values, and class instances collapse to plain objects.
|
||||
let normalized;
|
||||
try {
|
||||
normalized = JSON.parse(JSON.stringify(schema));
|
||||
}
|
||||
catch {
|
||||
throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
|
||||
}
|
||||
const version = detectVersion(normalized, params?.defaultTarget);
|
||||
const defs = (normalized.$defs || normalized.definitions || {});
|
||||
const ctx = {
|
||||
version,
|
||||
defs,
|
||||
refs: new Map(),
|
||||
processing: new Set(),
|
||||
rootSchema: normalized,
|
||||
registry: params?.registry ?? globalRegistry,
|
||||
};
|
||||
return convertSchema(normalized, ctx);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import type * as core from "../core/index.cjs";
|
||||
import * as schemas from "./schemas.cjs";
|
||||
export type input<T> = core.input<T>;
|
||||
export type output<T> = core.output<T>;
|
||||
/** Returns a copy of the schema with every pipe replaced by its input side. A codec's checks are dropped: they constrain the decoded value the input side never produces. */
|
||||
export declare function input<T extends core.$ZodType>(schema: T): schemas.ZodType<core.input<T>, core.input<T>>;
|
||||
/** Returns a copy of the schema with every pipe replaced by its output side, carrying over the pipe's own checks. */
|
||||
export declare function output<T extends core.$ZodType>(schema: T): schemas.ZodType<core.output<T>, core.output<T>>;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { clone, mergeDefs } from "../core/util.js";
|
||||
import { visit } from "../core/visit.js";
|
||||
import * as schemas from "./schemas.js";
|
||||
/** Appends a pipe's own checks to the side that replaces it, mirroring how `.check()` clones. */
|
||||
function withChecks(side, checks) {
|
||||
if (!checks?.length)
|
||||
return side;
|
||||
const def = side._zod.def;
|
||||
return clone(side, mergeDefs(def, { checks: [...(def.checks ?? []), ...checks] }), { parent: true });
|
||||
}
|
||||
/** The out side, carrying the pipe's own checks: those run against the decoded value, which is what `out` produces. */
|
||||
function outSide(def) {
|
||||
return withChecks(def.out, def.checks);
|
||||
}
|
||||
/** The in side. `z.preprocess` pipes a transform into a schema, and a bare transform validates nothing, so the schema it feeds is the real input side — the resolution `toJSONSchema` already makes for this case. */
|
||||
function inSide(def) {
|
||||
return def.in._zod.traits.has("$ZodTransform") ? outSide(def) : def.in;
|
||||
}
|
||||
/** Returns a copy of the schema with every pipe replaced by its input side. A codec's checks are dropped: they constrain the decoded value the input side never produces. */
|
||||
export function input(schema) {
|
||||
return visit(schema, {
|
||||
pipe: (s) => inSide(s._zod.def),
|
||||
// A default value belongs to the output side, so a rewritten inner type leaves it stranded. `.default()` widens the declared input type with `undefined`, and `optional` is what carries that across.
|
||||
default: (s, rewritten) => (rewritten ? schemas.optional(s._zod.def.innerType) : s),
|
||||
// A catch value is output-side too, but `.catch()` leaves the declared input type alone, so the inner schema stands on its own.
|
||||
catch: (s, rewritten) => (rewritten ? s._zod.def.innerType : s),
|
||||
});
|
||||
}
|
||||
/** Returns a copy of the schema with every pipe replaced by its output side, carrying over the pipe's own checks. */
|
||||
export function output(schema) {
|
||||
return visit(schema, {
|
||||
pipe: (s) => outSide(s._zod.def),
|
||||
// A prefault value is fed through the schema, which makes it input-side, so a rewritten inner type leaves it stranded.
|
||||
prefault: (s, rewritten) => (rewritten ? s._zod.def.innerType : s),
|
||||
});
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import * as z from "./external.cjs";
|
||||
export * from "./external.cjs";
|
||||
export { z, z as default };
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import * as core from "../core/index.cjs";
|
||||
import { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from "./schemas.cjs";
|
||||
export { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from "./schemas.cjs";
|
||||
export declare function datetime(params?: string | core.$ZodISODateTimeParams): ZodISODateTime;
|
||||
export declare function date(params?: string | core.$ZodISODateParams): ZodISODate;
|
||||
export declare function time(params?: string | core.$ZodISOTimeParams): ZodISOTime;
|
||||
export declare function duration(params?: string | core.$ZodISODurationParams): ZodISODuration;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import * as core from "../core/index.js";
|
||||
import { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from "./schemas.js";
|
||||
export { ZodISODate, ZodISODateTime, ZodISODuration, ZodISOTime } from "./schemas.js";
|
||||
export function datetime(params) {
|
||||
return core._isoDateTime(ZodISODateTime, params);
|
||||
}
|
||||
export function date(params) {
|
||||
return core._isoDate(ZodISODate, params);
|
||||
}
|
||||
export function time(params) {
|
||||
return core._isoTime(ZodISOTime, params);
|
||||
}
|
||||
export function duration(params) {
|
||||
return core._isoDuration(ZodISODuration, params);
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import * as core from "../core/index.cjs";
|
||||
import { type ZodError } from "./errors.cjs";
|
||||
export type ZodSafeParseResult<T> = ZodSafeParseSuccess<T> | ZodSafeParseError<T>;
|
||||
export type ZodSafeParseSuccess<T> = {
|
||||
success: true;
|
||||
data: T;
|
||||
error?: never;
|
||||
};
|
||||
export type ZodSafeParseError<T> = {
|
||||
success: false;
|
||||
data?: never;
|
||||
error: ZodError<T>;
|
||||
};
|
||||
export declare const parse: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => core.output<T>;
|
||||
export declare const parseAsync: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => Promise<core.output<T>>;
|
||||
export declare const safeParse: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.output<T>>;
|
||||
export declare const safeParseAsync: <T extends core.$ZodType>(schema: T, value: unknown, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.output<T>>>;
|
||||
export { validate, validateAsync } from "../core/index.cjs";
|
||||
export declare const encode: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => core.input<T>;
|
||||
export declare const decode: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => core.output<T>;
|
||||
export declare const encodeAsync: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => Promise<core.input<T>>;
|
||||
export declare const decodeAsync: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>, _params?: {
|
||||
callee?: core.util.AnyFunc;
|
||||
Err?: core.$ZodErrorClass;
|
||||
}) => Promise<core.output<T>>;
|
||||
export declare const safeEncode: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.input<T>>;
|
||||
export declare const safeDecode: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => ZodSafeParseResult<core.output<T>>;
|
||||
export declare const safeEncodeAsync: <T extends core.$ZodType>(schema: T, value: core.output<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.input<T>>>;
|
||||
export declare const safeDecodeAsync: <T extends core.$ZodType>(schema: T, value: core.input<T>, _ctx?: core.ParseContext<core.$ZodIssue>) => Promise<ZodSafeParseResult<core.output<T>>>;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import * as core from "../core/index.js";
|
||||
import { ZodRealError } from "./errors.js";
|
||||
export const parse = /* @__PURE__ */ core._parse(ZodRealError);
|
||||
export const parseAsync = /* @__PURE__ */ core._parseAsync(ZodRealError);
|
||||
export const safeParse = /* @__PURE__ */ core._safeParse(ZodRealError);
|
||||
export const safeParseAsync = /* @__PURE__ */ core._safeParseAsync(ZodRealError);
|
||||
export { validate, validateAsync } from "../core/index.js";
|
||||
// Codec functions
|
||||
export const encode = /* @__PURE__ */ core._encode(ZodRealError);
|
||||
export const decode = /* @__PURE__ */ core._decode(ZodRealError);
|
||||
export const encodeAsync = /* @__PURE__ */ core._encodeAsync(ZodRealError);
|
||||
export const decodeAsync = /* @__PURE__ */ core._decodeAsync(ZodRealError);
|
||||
export const safeEncode = /* @__PURE__ */ core._safeEncode(ZodRealError);
|
||||
export const safeDecode = /* @__PURE__ */ core._safeDecode(ZodRealError);
|
||||
export const safeEncodeAsync = /* @__PURE__ */ core._safeEncodeAsync(ZodRealError);
|
||||
export const safeDecodeAsync = /* @__PURE__ */ core._safeDecodeAsync(ZodRealError);
|
||||
+816
@@ -0,0 +1,816 @@
|
||||
import type { $ZodBigIntFormats } from "../core/checks.cjs";
|
||||
import * as core from "../core/index.cjs";
|
||||
import { util, type $ZodNumberFormats } from "../core/index.cjs";
|
||||
import type { StandardSchemaWithJSONProps } from "../core/standard-schema.cjs";
|
||||
import * as parse from "./parse.cjs";
|
||||
export type ZodStandardSchemaWithJSON<T> = StandardSchemaWithJSONProps<core.input<T>, core.output<T>>;
|
||||
export interface ZodType<out Output = unknown, out Input = unknown, out Internals extends core.$ZodTypeInternals<Output, Input> = core.$ZodTypeInternals<Output, Input>> extends core.$ZodType<Output, Input, Internals> {
|
||||
def: Internals["def"];
|
||||
type: Internals["def"]["type"];
|
||||
/** @deprecated Use `.def` instead. */
|
||||
_def: Internals["def"];
|
||||
/** @deprecated Use `z.output<typeof schema>` instead. */
|
||||
_output: Internals["output"];
|
||||
/** @deprecated Use `z.input<typeof schema>` instead. */
|
||||
_input: Internals["input"];
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
/** Converts this schema to a JSON Schema representation. */
|
||||
toJSONSchema(params?: core.ToJSONSchemaParams): core.ZodStandardJSONSchemaPayload<this>;
|
||||
check(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
|
||||
with(...checks: (core.CheckFn<core.output<this>> | core.$ZodCheck<core.output<this>>)[]): this;
|
||||
clone(def?: Internals["def"], params?: {
|
||||
parent: boolean;
|
||||
}): this;
|
||||
register<R extends core.$ZodRegistry>(registry: R, ...meta: this extends R["_schema"] ? undefined extends R["_meta"] ? [core.$replace<R["_meta"], this>?] : [core.$replace<R["_meta"], this>] : ["Incompatible schema"]): this;
|
||||
brand<T extends PropertyKey = PropertyKey, Dir extends "in" | "out" | "inout" = "out">(value?: T): PropertyKey extends T ? this : core.$ZodBranded<this, T, Dir>;
|
||||
parse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
||||
safeParse(data: unknown, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
|
||||
parseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
|
||||
safeParseAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
|
||||
spa: (data: unknown, params?: core.ParseContext<core.$ZodIssue>) => Promise<parse.ZodSafeParseResult<core.output<this>>>;
|
||||
validate(data: unknown, params?: core.ParseContext<core.$ZodIssue>): data is core.input<this>;
|
||||
validateAsync(data: unknown, params?: core.ParseContext<core.$ZodIssue>): Promise<boolean>;
|
||||
encode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): core.input<this>;
|
||||
decode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): core.output<this>;
|
||||
encodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.input<this>>;
|
||||
decodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<core.output<this>>;
|
||||
safeEncode(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.input<this>>;
|
||||
safeDecode(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): parse.ZodSafeParseResult<core.output<this>>;
|
||||
safeEncodeAsync(data: core.output<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.input<this>>>;
|
||||
safeDecodeAsync(data: core.input<this>, params?: core.ParseContext<core.$ZodIssue>): Promise<parse.ZodSafeParseResult<core.output<this>>>;
|
||||
refine<Ch extends (arg: core.output<this>) => unknown | Promise<unknown>>(check: Ch, params?: string | core.$ZodCustomParams): Ch extends (arg: any) => arg is infer R ? this & ZodType<R, core.input<this>> : this;
|
||||
superRefine(refinement: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => void | Promise<void>, params?: core.$ZodSuperRefineParams): this;
|
||||
overwrite(fn: (x: core.output<this>) => core.output<this>): this;
|
||||
optional(): ZodOptional<this>;
|
||||
exactOptional(): ZodExactOptional<this>;
|
||||
nonoptional(params?: string | core.$ZodNonOptionalParams): ZodNonOptional<this>;
|
||||
nullable(): ZodNullable<this>;
|
||||
nullish(): ZodOptional<ZodNullable<this>>;
|
||||
default(def: util.NoUndefined<core.output<this>>): ZodDefault<this>;
|
||||
default(def: () => util.NoUndefined<core.output<this>>): ZodDefault<this>;
|
||||
prefault(def: () => core.input<this>): ZodPrefault<this>;
|
||||
prefault(def: core.input<this>): ZodPrefault<this>;
|
||||
array(): ZodArray<this>;
|
||||
or<T extends core.SomeType>(option: T): ZodUnion<[this, T]>;
|
||||
and<T extends core.SomeType>(incoming: T): ZodIntersection<this, T>;
|
||||
transform<NewOut>(transform: (arg: core.output<this>, ctx: core.$RefinementCtx<core.output<this>>) => NewOut | Promise<NewOut>): ZodPipe<this, ZodTransform<Awaited<NewOut>, core.output<this>>>;
|
||||
catch(def: core.output<this>): ZodCatch<this>;
|
||||
catch(def: (ctx: core.$ZodCatchCtx) => core.output<this>): ZodCatch<this>;
|
||||
pipe<T extends core.$ZodType<any, core.output<this>>>(target: T | core.$ZodType<any, core.output<this>>): ZodPipe<this, T>;
|
||||
readonly(): ZodReadonly<this>;
|
||||
/** Returns a new instance that has been registered in `z.globalRegistry` with the specified description */
|
||||
describe(description: string): this;
|
||||
description?: string;
|
||||
/** Returns the metadata associated with this instance in `z.globalRegistry` */
|
||||
meta(): core.$replace<core.GlobalMeta, this> | undefined;
|
||||
/** Returns a new instance that has been registered in `z.globalRegistry` with the specified metadata */
|
||||
meta(data: core.$replace<core.GlobalMeta, this>): this;
|
||||
/** @deprecated Try safe-parsing `undefined` (this is what `isOptional` does internally):
|
||||
*
|
||||
* ```ts
|
||||
* const schema = z.string().optional();
|
||||
* const isOptional = schema.safeParse(undefined).success; // true
|
||||
* ```
|
||||
*/
|
||||
isOptional(): boolean;
|
||||
/**
|
||||
* @deprecated Try safe-parsing `null` (this is what `isNullable` does internally):
|
||||
*
|
||||
* ```ts
|
||||
* const schema = z.string().nullable();
|
||||
* const isNullable = schema.safeParse(null).success; // true
|
||||
* ```
|
||||
*/
|
||||
isNullable(): boolean;
|
||||
apply<T, TArgs extends unknown[] = []>(fn: (schema: this, ...args: TArgs) => T, ...args: TArgs): T;
|
||||
}
|
||||
export interface _ZodType<out Internals extends core.$ZodTypeInternals = core.$ZodTypeInternals> extends ZodType<any, any, Internals> {
|
||||
}
|
||||
export declare const ZodType: core.$constructor<ZodType>;
|
||||
export interface _ZodString<T extends core.$ZodStringInternals<unknown> = core.$ZodStringInternals<unknown>> extends _ZodType<T> {
|
||||
format: string | null;
|
||||
minLength: number | null;
|
||||
maxLength: number | null;
|
||||
regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
|
||||
includes(value: string, params?: string | core.$ZodCheckIncludesParams): this;
|
||||
startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
|
||||
endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
|
||||
min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
|
||||
max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this;
|
||||
length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this;
|
||||
nonempty(params?: string | core.$ZodCheckMinLengthParams): this;
|
||||
lowercase(params?: string | core.$ZodCheckLowerCaseParams): this;
|
||||
uppercase(params?: string | core.$ZodCheckUpperCaseParams): this;
|
||||
trim(): this;
|
||||
normalize(form?: "NFC" | "NFD" | "NFKC" | "NFKD" | (string & {})): this;
|
||||
toLowerCase(): this;
|
||||
toUpperCase(): this;
|
||||
slugify(): this;
|
||||
}
|
||||
/** @internal */
|
||||
export declare const _ZodString: core.$constructor<_ZodString>;
|
||||
export interface ZodString extends _ZodString<core.$ZodStringInternals<string>> {
|
||||
/** @deprecated Use `z.email()` instead. */
|
||||
email(params?: string | core.$ZodCheckEmailParams): this;
|
||||
/** @deprecated Use `z.url()` instead. */
|
||||
url(params?: string | core.$ZodCheckURLParams): this;
|
||||
/** @deprecated Use `z.jwt()` instead. */
|
||||
jwt(params?: string | core.$ZodCheckJWTParams): this;
|
||||
/** @deprecated Use `z.emoji()` instead. */
|
||||
emoji(params?: string | core.$ZodCheckEmojiParams): this;
|
||||
/** @deprecated Use `z.guid()` instead. */
|
||||
guid(params?: string | core.$ZodCheckGUIDParams): this;
|
||||
/** @deprecated Use `z.uuid()` instead. */
|
||||
uuid(params?: string | core.$ZodCheckUUIDParams): this;
|
||||
/** @deprecated Use `z.uuid()` instead. */
|
||||
uuidv4(params?: string | core.$ZodCheckUUIDParams): this;
|
||||
/** @deprecated Use `z.uuid()` instead. */
|
||||
uuidv6(params?: string | core.$ZodCheckUUIDParams): this;
|
||||
/** @deprecated Use `z.uuid()` instead. */
|
||||
uuidv7(params?: string | core.$ZodCheckUUIDParams): this;
|
||||
/** @deprecated Use `z.nanoid()` instead. */
|
||||
nanoid(params?: string | core.$ZodCheckNanoIDParams): this;
|
||||
/** @deprecated Use `z.guid()` instead. */
|
||||
guid(params?: string | core.$ZodCheckGUIDParams): this;
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use `z.cuid2()` instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
cuid(params?: string | core.$ZodCheckCUIDParams): this;
|
||||
/** @deprecated Use `z.cuid2()` instead. */
|
||||
cuid2(params?: string | core.$ZodCheckCUID2Params): this;
|
||||
/** @deprecated Use `z.ulid()` instead. */
|
||||
ulid(params?: string | core.$ZodCheckULIDParams): this;
|
||||
/** @deprecated Use `z.base64()` instead. */
|
||||
base64(params?: string | core.$ZodCheckBase64Params): this;
|
||||
/** @deprecated Use `z.base64url()` instead. */
|
||||
base64url(params?: string | core.$ZodCheckBase64URLParams): this;
|
||||
/** @deprecated Use `z.xid()` instead. */
|
||||
xid(params?: string | core.$ZodCheckXIDParams): this;
|
||||
/** @deprecated Use `z.ksuid()` instead. */
|
||||
ksuid(params?: string | core.$ZodCheckKSUIDParams): this;
|
||||
/** @deprecated Use `z.ipv4()` instead. */
|
||||
ipv4(params?: string | core.$ZodCheckIPv4Params): this;
|
||||
/** @deprecated Use `z.ipv6()` instead. */
|
||||
ipv6(params?: string | core.$ZodCheckIPv6Params): this;
|
||||
/** @deprecated Use `z.cidrv4()` instead. */
|
||||
cidrv4(params?: string | core.$ZodCheckCIDRv4Params): this;
|
||||
/** @deprecated Use `z.cidrv6()` instead. */
|
||||
cidrv6(params?: string | core.$ZodCheckCIDRv6Params): this;
|
||||
/** @deprecated Use `z.e164()` instead. */
|
||||
e164(params?: string | core.$ZodCheckE164Params): this;
|
||||
/** @deprecated Use `z.iso.datetime()` instead. */
|
||||
datetime(params?: string | core.$ZodCheckISODateTimeParams): this;
|
||||
/** @deprecated Use `z.iso.date()` instead. */
|
||||
date(params?: string | core.$ZodCheckISODateParams): this;
|
||||
/** @deprecated Use `z.iso.time()` instead. */
|
||||
time(params?: string | core.$ZodCheckISOTimeParams): this;
|
||||
/** @deprecated Use `z.iso.duration()` instead. */
|
||||
duration(params?: string | core.$ZodCheckISODurationParams): this;
|
||||
}
|
||||
export declare const ZodString: core.$constructor<ZodString>;
|
||||
export declare function string(params?: string | core.$ZodStringParams): ZodString;
|
||||
export declare function string<T extends string>(params?: string | core.$ZodStringParams): core.$ZodType<T, T>;
|
||||
export interface ZodStringFormat<Format extends string = string> extends _ZodString<core.$ZodStringFormatInternals<Format>> {
|
||||
}
|
||||
export declare const ZodStringFormat: core.$constructor<ZodStringFormat>;
|
||||
export interface ZodISODateTime extends ZodStringFormat {
|
||||
_zod: core.$ZodISODateTimeInternals;
|
||||
}
|
||||
export declare const ZodISODateTime: core.$constructor<ZodISODateTime>;
|
||||
export interface ZodISODate extends ZodStringFormat {
|
||||
_zod: core.$ZodISODateInternals;
|
||||
}
|
||||
export declare const ZodISODate: core.$constructor<ZodISODate>;
|
||||
export interface ZodISOTime extends ZodStringFormat {
|
||||
_zod: core.$ZodISOTimeInternals;
|
||||
}
|
||||
export declare const ZodISOTime: core.$constructor<ZodISOTime>;
|
||||
export interface ZodISODuration extends ZodStringFormat {
|
||||
_zod: core.$ZodISODurationInternals;
|
||||
}
|
||||
export declare const ZodISODuration: core.$constructor<ZodISODuration>;
|
||||
export interface ZodEmail extends ZodStringFormat<"email"> {
|
||||
_zod: core.$ZodEmailInternals;
|
||||
}
|
||||
export declare const ZodEmail: core.$constructor<ZodEmail>;
|
||||
export declare function email(params?: string | core.$ZodEmailParams): ZodEmail;
|
||||
export interface ZodGUID extends ZodStringFormat<"guid"> {
|
||||
_zod: core.$ZodGUIDInternals;
|
||||
}
|
||||
export declare const ZodGUID: core.$constructor<ZodGUID>;
|
||||
export declare function guid(params?: string | core.$ZodGUIDParams): ZodGUID;
|
||||
export interface ZodUUID extends ZodStringFormat<"uuid"> {
|
||||
_zod: core.$ZodUUIDInternals;
|
||||
}
|
||||
export declare const ZodUUID: core.$constructor<ZodUUID>;
|
||||
export declare function uuid(params?: string | core.$ZodUUIDParams): ZodUUID;
|
||||
export declare function uuidv4(params?: string | core.$ZodUUIDv4Params): ZodUUID;
|
||||
export declare function uuidv6(params?: string | core.$ZodUUIDv6Params): ZodUUID;
|
||||
export declare function uuidv7(params?: string | core.$ZodUUIDv7Params): ZodUUID;
|
||||
export interface ZodURL extends ZodStringFormat<"url"> {
|
||||
_zod: core.$ZodURLInternals;
|
||||
}
|
||||
export declare const ZodURL: core.$constructor<ZodURL>;
|
||||
export declare function url(params?: string | core.$ZodURLParams): ZodURL;
|
||||
export declare function httpUrl(params?: string | Omit<core.$ZodURLParams, "protocol" | "hostname">): ZodURL;
|
||||
export interface ZodEmoji extends ZodStringFormat<"emoji"> {
|
||||
_zod: core.$ZodEmojiInternals;
|
||||
}
|
||||
export declare const ZodEmoji: core.$constructor<ZodEmoji>;
|
||||
export declare function emoji(params?: string | core.$ZodEmojiParams): ZodEmoji;
|
||||
export interface ZodNanoID extends ZodStringFormat<"nanoid"> {
|
||||
_zod: core.$ZodNanoIDInternals;
|
||||
}
|
||||
export declare const ZodNanoID: core.$constructor<ZodNanoID>;
|
||||
export declare function nanoid(params?: string | core.$ZodNanoIDParams): ZodNanoID;
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link ZodCUID2} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export interface ZodCUID extends ZodStringFormat<"cuid"> {
|
||||
_zod: core.$ZodCUIDInternals;
|
||||
}
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link ZodCUID2} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export declare const ZodCUID: core.$constructor<ZodCUID>;
|
||||
/**
|
||||
* Validates a CUID v1 string.
|
||||
*
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link cuid2 | `z.cuid2()`} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export declare function cuid(params?: string | core.$ZodCUIDParams): ZodCUID;
|
||||
export interface ZodCUID2 extends ZodStringFormat<"cuid2"> {
|
||||
_zod: core.$ZodCUID2Internals;
|
||||
}
|
||||
export declare const ZodCUID2: core.$constructor<ZodCUID2>;
|
||||
export declare function cuid2(params?: string | core.$ZodCUID2Params): ZodCUID2;
|
||||
export interface ZodULID extends ZodStringFormat<"ulid"> {
|
||||
_zod: core.$ZodULIDInternals;
|
||||
}
|
||||
export declare const ZodULID: core.$constructor<ZodULID>;
|
||||
export declare function ulid(params?: string | core.$ZodULIDParams): ZodULID;
|
||||
export interface ZodXID extends ZodStringFormat<"xid"> {
|
||||
_zod: core.$ZodXIDInternals;
|
||||
}
|
||||
export declare const ZodXID: core.$constructor<ZodXID>;
|
||||
export declare function xid(params?: string | core.$ZodXIDParams): ZodXID;
|
||||
export interface ZodKSUID extends ZodStringFormat<"ksuid"> {
|
||||
_zod: core.$ZodKSUIDInternals;
|
||||
}
|
||||
export declare const ZodKSUID: core.$constructor<ZodKSUID>;
|
||||
export declare function ksuid(params?: string | core.$ZodKSUIDParams): ZodKSUID;
|
||||
export interface ZodIPv4 extends ZodStringFormat<"ipv4"> {
|
||||
_zod: core.$ZodIPv4Internals;
|
||||
}
|
||||
export declare const ZodIPv4: core.$constructor<ZodIPv4>;
|
||||
export declare function ipv4(params?: string | core.$ZodIPv4Params): ZodIPv4;
|
||||
export interface ZodMAC extends ZodStringFormat<"mac"> {
|
||||
_zod: core.$ZodMACInternals;
|
||||
}
|
||||
export declare const ZodMAC: core.$constructor<ZodMAC>;
|
||||
export declare function mac(params?: string | core.$ZodMACParams): ZodMAC;
|
||||
export interface ZodIPv6 extends ZodStringFormat<"ipv6"> {
|
||||
_zod: core.$ZodIPv6Internals;
|
||||
}
|
||||
export declare const ZodIPv6: core.$constructor<ZodIPv6>;
|
||||
export declare function ipv6(params?: string | core.$ZodIPv6Params): ZodIPv6;
|
||||
export interface ZodCIDRv4 extends ZodStringFormat<"cidrv4"> {
|
||||
_zod: core.$ZodCIDRv4Internals;
|
||||
}
|
||||
export declare const ZodCIDRv4: core.$constructor<ZodCIDRv4>;
|
||||
export declare function cidrv4(params?: string | core.$ZodCIDRv4Params): ZodCIDRv4;
|
||||
export interface ZodCIDRv6 extends ZodStringFormat<"cidrv6"> {
|
||||
_zod: core.$ZodCIDRv6Internals;
|
||||
}
|
||||
export declare const ZodCIDRv6: core.$constructor<ZodCIDRv6>;
|
||||
export declare function cidrv6(params?: string | core.$ZodCIDRv6Params): ZodCIDRv6;
|
||||
export interface ZodBase64 extends ZodStringFormat<"base64"> {
|
||||
_zod: core.$ZodBase64Internals;
|
||||
}
|
||||
export declare const ZodBase64: core.$constructor<ZodBase64>;
|
||||
export declare function base64(params?: string | core.$ZodBase64Params): ZodBase64;
|
||||
export interface ZodBase64URL extends ZodStringFormat<"base64url"> {
|
||||
_zod: core.$ZodBase64URLInternals;
|
||||
}
|
||||
export declare const ZodBase64URL: core.$constructor<ZodBase64URL>;
|
||||
export declare function base64url(params?: string | core.$ZodBase64URLParams): ZodBase64URL;
|
||||
export interface ZodE164 extends ZodStringFormat<"e164"> {
|
||||
_zod: core.$ZodE164Internals;
|
||||
}
|
||||
export declare const ZodE164: core.$constructor<ZodE164>;
|
||||
export declare function e164(params?: string | core.$ZodE164Params): ZodE164;
|
||||
export interface ZodCreditCard extends ZodStringFormat<"credit_card"> {
|
||||
_zod: core.$ZodCreditCardInternals;
|
||||
}
|
||||
export declare const ZodCreditCard: core.$constructor<ZodCreditCard>;
|
||||
export declare function creditCard(params?: string | core.$ZodCreditCardParams): ZodCreditCard;
|
||||
export interface ZodIBAN extends ZodStringFormat<"iban"> {
|
||||
_zod: core.$ZodIBANInternals;
|
||||
}
|
||||
export declare const ZodIBAN: core.$constructor<ZodIBAN>;
|
||||
export declare function iban(params?: string | core.$ZodIBANParams): ZodIBAN;
|
||||
export interface ZodJWT extends ZodStringFormat<"jwt"> {
|
||||
_zod: core.$ZodJWTInternals;
|
||||
}
|
||||
export declare const ZodJWT: core.$constructor<ZodJWT>;
|
||||
export declare function jwt(params?: string | core.$ZodJWTParams): ZodJWT;
|
||||
export interface ZodCustomStringFormat<Format extends string = string> extends ZodStringFormat<Format>, core.$ZodCustomStringFormat<Format> {
|
||||
_zod: core.$ZodCustomStringFormatInternals<Format>;
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodCustomStringFormat: core.$constructor<ZodCustomStringFormat>;
|
||||
export declare function stringFormat<Format extends string>(format: Format, fnOrRegex: ((arg: string) => util.MaybeAsync<unknown>) | RegExp, _params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<Format>;
|
||||
export declare function hostname(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"hostname">;
|
||||
export declare function hex(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"hex">;
|
||||
export declare function currencyCode(_params?: string | core.$ZodStringFormatParams): ZodCustomStringFormat<"currency_code">;
|
||||
export declare function hash<Alg extends util.HashAlgorithm, Enc extends util.HashEncoding = "hex">(alg: Alg, params?: {
|
||||
enc?: Enc;
|
||||
} & core.$ZodStringFormatParams): ZodCustomStringFormat<`${Alg}_${Enc}`>;
|
||||
export interface _ZodNumber<Internals extends core.$ZodNumberInternals = core.$ZodNumberInternals> extends _ZodType<Internals> {
|
||||
gt(value: number, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
/** Identical to .min() */
|
||||
gte(value: number, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
min(value: number, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
lt(value: number, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
/** Identical to .max() */
|
||||
lte(value: number, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
max(value: number, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
/** Consider `z.int()` instead. This API is considered *legacy*; it will never be removed but a better alternative exists. */
|
||||
int(params?: string | core.$ZodCheckNumberFormatParams): this;
|
||||
/** @deprecated This is now identical to `.int()`. Only numbers in the safe integer range are accepted. */
|
||||
safe(params?: string | core.$ZodCheckNumberFormatParams): this;
|
||||
positive(params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
nonnegative(params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
negative(params?: string | core.$ZodCheckLessThanParams): this;
|
||||
nonpositive(params?: string | core.$ZodCheckLessThanParams): this;
|
||||
multipleOf(value: number, params?: string | core.$ZodCheckMultipleOfParams): this;
|
||||
/** @deprecated Use `.multipleOf()` instead. */
|
||||
step(value: number, params?: string | core.$ZodCheckMultipleOfParams): this;
|
||||
/** @deprecated In v4 and later, z.number() does not allow infinite values by default. This is a no-op. */
|
||||
finite(params?: unknown): this;
|
||||
minValue: number | null;
|
||||
maxValue: number | null;
|
||||
/** @deprecated Check the `format` property instead. */
|
||||
isInt: boolean;
|
||||
/** @deprecated Number schemas no longer accept infinite values, so this always returns `true`. */
|
||||
isFinite: boolean;
|
||||
format: string | null;
|
||||
}
|
||||
export interface ZodNumber extends _ZodNumber<core.$ZodNumberInternals<number>> {
|
||||
}
|
||||
export declare const ZodNumber: core.$constructor<ZodNumber>;
|
||||
export declare function number(params?: string | core.$ZodNumberParams): ZodNumber;
|
||||
export interface ZodNumberFormat<Format extends $ZodNumberFormats = $ZodNumberFormats> extends ZodNumber {
|
||||
_zod: core.$ZodNumberFormatInternals<Format>;
|
||||
}
|
||||
export declare const ZodNumberFormat: core.$constructor<ZodNumberFormat>;
|
||||
export interface ZodInt extends ZodNumberFormat<"safeint"> {
|
||||
}
|
||||
export declare function int(params?: string | core.$ZodCheckNumberFormatParams): ZodInt;
|
||||
export interface ZodFloat32 extends ZodNumberFormat<"float32"> {
|
||||
}
|
||||
export declare function float32(params?: string | core.$ZodCheckNumberFormatParams): ZodFloat32;
|
||||
export interface ZodFloat64 extends ZodNumberFormat<"float64"> {
|
||||
}
|
||||
export declare function float64(params?: string | core.$ZodCheckNumberFormatParams): ZodFloat64;
|
||||
export interface ZodInt32 extends ZodNumberFormat<"int32"> {
|
||||
}
|
||||
export declare function int32(params?: string | core.$ZodCheckNumberFormatParams): ZodInt32;
|
||||
export interface ZodUInt32 extends ZodNumberFormat<"uint32"> {
|
||||
}
|
||||
export declare function uint32(params?: string | core.$ZodCheckNumberFormatParams): ZodUInt32;
|
||||
export interface _ZodBoolean<T extends core.$ZodBooleanInternals = core.$ZodBooleanInternals> extends _ZodType<T> {
|
||||
}
|
||||
export interface ZodBoolean extends _ZodBoolean<core.$ZodBooleanInternals<boolean>> {
|
||||
}
|
||||
export declare const ZodBoolean: core.$constructor<ZodBoolean>;
|
||||
export declare function boolean(params?: string | core.$ZodBooleanParams): ZodBoolean;
|
||||
export interface _ZodBigInt<T extends core.$ZodBigIntInternals = core.$ZodBigIntInternals> extends _ZodType<T> {
|
||||
gte(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
/** Alias of `.gte()` */
|
||||
min(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
gt(value: bigint, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
/** Alias of `.lte()` */
|
||||
lte(value: bigint, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
max(value: bigint, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
lt(value: bigint, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
positive(params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
negative(params?: string | core.$ZodCheckLessThanParams): this;
|
||||
nonpositive(params?: string | core.$ZodCheckLessThanParams): this;
|
||||
nonnegative(params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
multipleOf(value: bigint, params?: string | core.$ZodCheckMultipleOfParams): this;
|
||||
minValue: bigint | null;
|
||||
maxValue: bigint | null;
|
||||
format: string | null;
|
||||
}
|
||||
export interface ZodBigInt extends _ZodBigInt<core.$ZodBigIntInternals<bigint>> {
|
||||
}
|
||||
export declare const ZodBigInt: core.$constructor<ZodBigInt>;
|
||||
export declare function bigint(params?: string | core.$ZodBigIntParams): ZodBigInt;
|
||||
export interface ZodBigIntFormat<Format extends $ZodBigIntFormats = $ZodBigIntFormats> extends ZodBigInt {
|
||||
_zod: core.$ZodBigIntFormatInternals<Format>;
|
||||
}
|
||||
export declare const ZodBigIntFormat: core.$constructor<ZodBigIntFormat>;
|
||||
export interface ZodInt64 extends ZodBigIntFormat<"int64"> {
|
||||
}
|
||||
export declare function int64(params?: string | core.$ZodBigIntFormatParams): ZodInt64;
|
||||
export interface ZodUInt64 extends ZodBigIntFormat<"uint64"> {
|
||||
}
|
||||
export declare function uint64(params?: string | core.$ZodBigIntFormatParams): ZodUInt64;
|
||||
export interface ZodSymbol extends _ZodType<core.$ZodSymbolInternals> {
|
||||
}
|
||||
export declare const ZodSymbol: core.$constructor<ZodSymbol>;
|
||||
export declare function symbol(params?: string | core.$ZodSymbolParams): ZodSymbol;
|
||||
export interface ZodUndefined extends _ZodType<core.$ZodUndefinedInternals> {
|
||||
}
|
||||
export declare const ZodUndefined: core.$constructor<ZodUndefined>;
|
||||
declare function _undefined(params?: string | core.$ZodUndefinedParams): ZodUndefined;
|
||||
export { _undefined as undefined };
|
||||
export interface ZodNull extends _ZodType<core.$ZodNullInternals> {
|
||||
}
|
||||
export declare const ZodNull: core.$constructor<ZodNull>;
|
||||
declare function _null(params?: string | core.$ZodNullParams): ZodNull;
|
||||
export { _null as null };
|
||||
export interface ZodAny extends _ZodType<core.$ZodAnyInternals> {
|
||||
}
|
||||
export declare const ZodAny: core.$constructor<ZodAny>;
|
||||
export declare function any(): ZodAny;
|
||||
export interface ZodUnknown extends _ZodType<core.$ZodUnknownInternals> {
|
||||
}
|
||||
export declare const ZodUnknown: core.$constructor<ZodUnknown>;
|
||||
export declare function unknown(): ZodUnknown;
|
||||
export interface ZodNever extends _ZodType<core.$ZodNeverInternals> {
|
||||
}
|
||||
export declare const ZodNever: core.$constructor<ZodNever>;
|
||||
export declare function never(params?: string | core.$ZodNeverParams): ZodNever;
|
||||
export interface ZodVoid extends _ZodType<core.$ZodVoidInternals> {
|
||||
}
|
||||
export declare const ZodVoid: core.$constructor<ZodVoid>;
|
||||
declare function _void(params?: string | core.$ZodVoidParams): ZodVoid;
|
||||
export { _void as void };
|
||||
export interface _ZodDate<T extends core.$ZodDateInternals = core.$ZodDateInternals> extends _ZodType<T> {
|
||||
min(value: number | Date, params?: string | core.$ZodCheckGreaterThanParams): this;
|
||||
max(value: number | Date, params?: string | core.$ZodCheckLessThanParams): this;
|
||||
/** @deprecated Not recommended. */
|
||||
minDate: Date | null;
|
||||
/** @deprecated Not recommended. */
|
||||
maxDate: Date | null;
|
||||
}
|
||||
export interface ZodDate extends _ZodDate<core.$ZodDateInternals<Date>> {
|
||||
}
|
||||
export declare const ZodDate: core.$constructor<ZodDate>;
|
||||
export declare function date(params?: string | core.$ZodDateParams): ZodDate;
|
||||
export interface ZodArray<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodArrayInternals<T>>, core.$ZodArray<T> {
|
||||
element: T;
|
||||
min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
|
||||
nonempty(params?: string | core.$ZodCheckMinLengthParams): this;
|
||||
max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this;
|
||||
length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this;
|
||||
unwrap(): T;
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodArray: core.$constructor<ZodArray>;
|
||||
export declare function array<T extends core.SomeType>(element: T, params?: string | core.$ZodArrayParams): ZodArray<T>;
|
||||
export declare function keyof<T extends ZodObject>(schema: T): ZodEnum<util.KeysEnum<T["_zod"]["output"]>>;
|
||||
export type SafeExtendShape<Base extends core.$ZodShape, Ext extends core.$ZodLooseShape> = {
|
||||
[K in keyof Ext]: K extends keyof Base ? core.output<Ext[K]> extends core.output<Base[K]> ? core.input<Ext[K]> extends core.input<Base[K]> ? Ext[K] : never : never : Ext[K];
|
||||
};
|
||||
export interface ZodObject<
|
||||
/** @ts-ignore Cast variance */
|
||||
out Shape extends core.$ZodShape = core.$ZodLooseShape, out Config extends core.$ZodObjectConfig = core.$strip> extends _ZodType<core.$ZodObjectInternals<Shape, Config>>, core.$ZodObject<Shape, Config> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
shape: Shape;
|
||||
keyof(): ZodEnum<util.ToEnum<keyof Shape & string>>;
|
||||
/** Define a schema to validate all unrecognized keys. This overrides the existing strict/loose behavior. */
|
||||
catchall<T extends core.SomeType>(schema: T): ZodObject<Shape, core.$catchall<T>>;
|
||||
/** @deprecated Use `z.looseObject()` or `.loose()` instead. */
|
||||
passthrough(): ZodObject<Shape, core.$loose>;
|
||||
/** Consider `z.looseObject(A.shape)` instead */
|
||||
loose(): ZodObject<Shape, core.$loose>;
|
||||
/** Consider `z.strictObject(A.shape)` instead */
|
||||
strict(): ZodObject<Shape, core.$strict>;
|
||||
/** This is the default behavior. This method call is likely unnecessary. */
|
||||
strip(): ZodObject<Shape, core.$strip>;
|
||||
extend<U extends core.$ZodLooseShape>(shape: U): ZodObject<util.Extend<Shape, util.Writeable<U>>, Config>;
|
||||
safeExtend<U extends core.$ZodLooseShape>(shape: SafeExtendShape<Shape, U> & Partial<Record<keyof Shape, core.SomeType>>): ZodObject<util.Extend<Shape, util.Writeable<U>>, Config>;
|
||||
/**
|
||||
* @deprecated Use [`A.extend(B.shape)`](https://zod.dev/api?id=extend) instead.
|
||||
*/
|
||||
merge<U extends ZodObject>(other: U): ZodObject<util.Extend<Shape, U["shape"]>, U["_zod"]["config"]>;
|
||||
pick<M extends util.Mask<keyof Shape>>(mask: M & Record<Exclude<keyof M, keyof Shape>, never>): ZodObject<util.Flatten<Pick<Shape, Extract<keyof Shape, keyof M>>>, Config>;
|
||||
omit<M extends util.Mask<keyof Shape>>(mask: M & Record<Exclude<keyof M, keyof Shape>, never>): ZodObject<util.Flatten<Omit<Shape, Extract<keyof Shape, keyof M>>>, Config>;
|
||||
partial(): ZodObject<{
|
||||
-readonly [k in keyof Shape]: ZodOptional<Shape[k]>;
|
||||
}, Config>;
|
||||
partial<M extends util.Mask<keyof Shape>>(mask: M & Record<Exclude<keyof M, keyof Shape>, never>): ZodObject<{
|
||||
-readonly [k in keyof Shape]: k extends keyof M ? ZodOptional<Shape[k]> : Shape[k];
|
||||
}, Config>;
|
||||
exactPartial(): ZodObject<{
|
||||
-readonly [k in keyof Shape]: ZodExactOptional<Shape[k]>;
|
||||
}, Config>;
|
||||
exactPartial<M extends util.Mask<keyof Shape>>(mask: M & Record<Exclude<keyof M, keyof Shape>, never>): ZodObject<{
|
||||
-readonly [k in keyof Shape]: k extends keyof M ? ZodExactOptional<Shape[k]> : Shape[k];
|
||||
}, Config>;
|
||||
required(): ZodObject<{
|
||||
-readonly [k in keyof Shape]: ZodNonOptional<Shape[k]>;
|
||||
}, Config>;
|
||||
required<M extends util.Mask<keyof Shape>>(mask: M & Record<Exclude<keyof M, keyof Shape>, never>): ZodObject<{
|
||||
-readonly [k in keyof Shape]: k extends keyof M ? ZodNonOptional<Shape[k]> : Shape[k];
|
||||
}, Config>;
|
||||
}
|
||||
export declare const ZodObject: core.$constructor<ZodObject>;
|
||||
export declare function object<T extends core.$ZodLooseShape = Partial<Record<never, core.SomeType>>>(shape?: T, params?: string | core.$ZodObjectParams): ZodObject<util.Writeable<T>, core.$strip>;
|
||||
export declare function strictObject<T extends core.$ZodLooseShape>(shape: T, params?: string | core.$ZodObjectParams): ZodObject<util.Writeable<T>, core.$strict>;
|
||||
export declare function looseObject<T extends core.$ZodLooseShape>(shape: T, params?: string | core.$ZodObjectParams): ZodObject<util.Writeable<T>, core.$loose>;
|
||||
export interface ZodUnion<T extends readonly core.SomeType[] = readonly core.$ZodType[]> extends _ZodType<core.$ZodUnionInternals<T>>, core.$ZodUnion<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
options: T;
|
||||
}
|
||||
export declare const ZodUnion: core.$constructor<ZodUnion>;
|
||||
export declare function union<const T extends readonly core.SomeType[]>(options: T, params?: string | core.$ZodUnionParams): ZodUnion<T>;
|
||||
export interface ZodXor<T extends readonly core.SomeType[] = readonly core.$ZodType[]> extends _ZodType<core.$ZodXorInternals<T>>, core.$ZodXor<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
options: T;
|
||||
}
|
||||
export declare const ZodXor: core.$constructor<ZodXor>;
|
||||
/** Creates an exclusive union (XOR) where exactly one option must match.
|
||||
* Unlike regular unions that succeed when any option matches, xor fails if
|
||||
* zero or more than one option matches the input. */
|
||||
export declare function xor<const T extends readonly core.SomeType[]>(options: T, params?: string | core.$ZodXorParams): ZodXor<T>;
|
||||
export interface ZodDiscriminatedUnion<Options extends readonly core.SomeType[] = readonly core.$ZodType[], Disc extends string = string> extends ZodUnion<Options>, core.$ZodDiscriminatedUnion<Options, Disc> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
_zod: core.$ZodDiscriminatedUnionInternals<Options, Disc>;
|
||||
def: core.$ZodDiscriminatedUnionDef<Options, Disc>;
|
||||
}
|
||||
export declare const ZodDiscriminatedUnion: core.$constructor<ZodDiscriminatedUnion>;
|
||||
export declare function discriminatedUnion<Types extends readonly [core.$ZodTypeDiscriminable, ...core.$ZodTypeDiscriminable[]], Disc extends string>(discriminator: Disc, options: Types, params?: string | core.$ZodDiscriminatedUnionParams): ZodDiscriminatedUnion<Types, Disc>;
|
||||
export interface ZodIntersection<A extends core.SomeType = core.$ZodType, B extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodIntersectionInternals<A, B>>, core.$ZodIntersection<A, B> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodIntersection: core.$constructor<ZodIntersection>;
|
||||
export declare function intersection<T extends core.SomeType, U extends core.SomeType>(left: T, right: U): ZodIntersection<T, U>;
|
||||
export interface ZodTuple<T extends util.TupleItems = readonly core.$ZodType[], Rest extends core.SomeType | null = core.$ZodType | null> extends _ZodType<core.$ZodTupleInternals<T, Rest>>, core.$ZodTuple<T, Rest> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
rest<Rest extends core.SomeType = core.$ZodType>(rest: Rest): ZodTuple<T, Rest>;
|
||||
partial(): ZodTuple<{
|
||||
-readonly [k in keyof T]: ZodOptional<T[k]>;
|
||||
}, Rest>;
|
||||
}
|
||||
export declare const ZodTuple: core.$constructor<ZodTuple>;
|
||||
export declare function tuple<T extends readonly [core.SomeType, ...core.SomeType[]]>(items: T, params?: string | core.$ZodTupleParams): ZodTuple<T, null>;
|
||||
export declare function tuple<T extends readonly [core.SomeType, ...core.SomeType[]], Rest extends core.SomeType>(items: T, rest: Rest, params?: string | core.$ZodTupleParams): ZodTuple<T, Rest>;
|
||||
export declare function tuple(items: [], params?: string | core.$ZodTupleParams): ZodTuple<[], null>;
|
||||
export interface ZodRecord<Key extends core.$ZodRecordKey = core.$ZodRecordKey, Value extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodRecordInternals<Key, Value>>, core.$ZodRecord<Key, Value> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
keyType: Key;
|
||||
valueType: Value;
|
||||
}
|
||||
export declare const ZodRecord: core.$constructor<ZodRecord>;
|
||||
export declare function record<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key, Value>;
|
||||
export declare function partialRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key & core.$partial, Value>;
|
||||
export declare function looseRecord<Key extends core.$ZodRecordKey, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodRecordParams): ZodRecord<Key, Value>;
|
||||
export interface ZodMap<Key extends core.SomeType = core.$ZodType, Value extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodMapInternals<Key, Value>>, core.$ZodMap<Key, Value> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
keyType: Key;
|
||||
valueType: Value;
|
||||
min(minSize: number, params?: string | core.$ZodCheckMinSizeParams): this;
|
||||
nonempty(params?: string | core.$ZodCheckMinSizeParams): this;
|
||||
max(maxSize: number, params?: string | core.$ZodCheckMaxSizeParams): this;
|
||||
size(size: number, params?: string | core.$ZodCheckSizeEqualsParams): this;
|
||||
}
|
||||
export declare const ZodMap: core.$constructor<ZodMap>;
|
||||
export declare function map<Key extends core.SomeType, Value extends core.SomeType>(keyType: Key, valueType: Value, params?: string | core.$ZodMapParams): ZodMap<Key, Value>;
|
||||
export interface ZodSet<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodSetInternals<T>>, core.$ZodSet<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
min(minSize: number, params?: string | core.$ZodCheckMinSizeParams): this;
|
||||
nonempty(params?: string | core.$ZodCheckMinSizeParams): this;
|
||||
max(maxSize: number, params?: string | core.$ZodCheckMaxSizeParams): this;
|
||||
size(size: number, params?: string | core.$ZodCheckSizeEqualsParams): this;
|
||||
}
|
||||
export declare const ZodSet: core.$constructor<ZodSet>;
|
||||
export declare function set<Value extends core.SomeType>(valueType: Value, params?: string | core.$ZodSetParams): ZodSet<Value>;
|
||||
export interface ZodEnum<
|
||||
/** @ts-ignore Cast variance */
|
||||
out T extends util.EnumLike = util.EnumLike> extends _ZodType<core.$ZodEnumInternals<T>>, core.$ZodEnum<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
enum: T;
|
||||
options: Array<T[keyof T]>;
|
||||
extract<const U extends readonly (keyof T)[]>(values: U, params?: string | core.$ZodEnumParams): ZodEnum<util.Flatten<Pick<T, U[number]>>>;
|
||||
exclude<const U extends readonly (keyof T)[]>(values: U, params?: string | core.$ZodEnumParams): ZodEnum<util.Flatten<Omit<T, U[number]>>>;
|
||||
}
|
||||
export declare const ZodEnum: core.$constructor<ZodEnum>;
|
||||
declare function _enum<const T extends readonly string[]>(values: T, params?: string | core.$ZodEnumParams): ZodEnum<util.ToEnum<T[number]>>;
|
||||
declare function _enum<const T extends util.EnumLike>(entries: T, params?: string | core.$ZodEnumParams): ZodEnum<T>;
|
||||
export { _enum as enum };
|
||||
/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.
|
||||
*
|
||||
* ```ts
|
||||
* enum Colors { red, green, blue }
|
||||
* z.enum(Colors);
|
||||
* ```
|
||||
*/
|
||||
export declare function nativeEnum<T extends util.EnumLike>(entries: T, params?: string | core.$ZodEnumParams): ZodEnum<T>;
|
||||
export interface ZodLiteral<T extends util.Literal = util.Literal> extends _ZodType<core.$ZodLiteralInternals<T>>, core.$ZodLiteral<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
values: Set<T>;
|
||||
/** @legacy Use `.values` instead. Accessing this property will throw an error if the literal accepts multiple values. */
|
||||
value: T;
|
||||
}
|
||||
export declare const ZodLiteral: core.$constructor<ZodLiteral>;
|
||||
export declare function literal<const T extends ReadonlyArray<util.Literal>>(value: T, params?: string | core.$ZodLiteralParams): ZodLiteral<T[number]>;
|
||||
export declare function literal<const T extends util.Literal>(value: T, params?: string | core.$ZodLiteralParams): ZodLiteral<T>;
|
||||
export interface ZodFile extends _ZodType<core.$ZodFileInternals>, core.$ZodFile {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
min(size: number, params?: string | core.$ZodCheckMinSizeParams): this;
|
||||
max(size: number, params?: string | core.$ZodCheckMaxSizeParams): this;
|
||||
mime(types: util.MimeTypes | Array<util.MimeTypes>, params?: string | core.$ZodCheckMimeTypeParams): this;
|
||||
}
|
||||
export declare const ZodFile: core.$constructor<ZodFile>;
|
||||
export declare function file(params?: string | core.$ZodFileParams): ZodFile;
|
||||
export interface ZodTransform<O = unknown, I = unknown> extends _ZodType<core.$ZodTransformInternals<O, I>>, core.$ZodTransform<O, I> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodTransform: core.$constructor<ZodTransform>;
|
||||
export declare function transform<I = unknown, O = I>(fn: (input: I, ctx: core.$RefinementCtx) => O): ZodTransform<Awaited<O>, I>;
|
||||
export interface ZodOptional<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodOptionalInternals<T>>, core.$ZodOptional<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodOptional: core.$constructor<ZodOptional>;
|
||||
export declare function optional<T extends core.SomeType>(innerType: T): ZodOptional<T>;
|
||||
export interface ZodExactOptional<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodExactOptionalInternals<T>>, core.$ZodExactOptional<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodExactOptional: core.$constructor<ZodExactOptional>;
|
||||
export declare function exactOptional<T extends core.SomeType>(innerType: T): ZodExactOptional<T>;
|
||||
export interface ZodNullable<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodNullableInternals<T>>, core.$ZodNullable<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodNullable: core.$constructor<ZodNullable>;
|
||||
export declare function nullable<T extends core.SomeType>(innerType: T): ZodNullable<T>;
|
||||
export declare function nullish<T extends core.SomeType>(innerType: T): ZodOptional<ZodNullable<T>>;
|
||||
export interface ZodDefault<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodDefaultInternals<T>>, core.$ZodDefault<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
/** @deprecated Use `.unwrap()` instead. */
|
||||
removeDefault(): T;
|
||||
}
|
||||
export declare const ZodDefault: core.$constructor<ZodDefault>;
|
||||
export declare function _default<T extends core.SomeType>(innerType: T, defaultValue: util.NoUndefined<core.output<T>> | (() => util.NoUndefined<core.output<T>>)): ZodDefault<T>;
|
||||
export interface ZodPrefault<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodPrefaultInternals<T>>, core.$ZodPrefault<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodPrefault: core.$constructor<ZodPrefault>;
|
||||
export declare function prefault<T extends core.SomeType>(innerType: T, defaultValue: core.input<T> | (() => core.input<T>)): ZodPrefault<T>;
|
||||
export interface ZodNonOptional<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodNonOptionalInternals<T>>, core.$ZodNonOptional<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodNonOptional: core.$constructor<ZodNonOptional>;
|
||||
export declare function nonoptional<T extends core.SomeType>(innerType: T, params?: string | core.$ZodNonOptionalParams): ZodNonOptional<T>;
|
||||
export interface ZodSuccess<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodSuccessInternals<T>>, core.$ZodSuccess<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodSuccess: core.$constructor<ZodSuccess>;
|
||||
export declare function success<T extends core.SomeType>(innerType: T): ZodSuccess<T>;
|
||||
export interface ZodCatch<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodCatchInternals<T>>, core.$ZodCatch<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
/** @deprecated Use `.unwrap()` instead. */
|
||||
removeCatch(): T;
|
||||
}
|
||||
export declare const ZodCatch: core.$constructor<ZodCatch>;
|
||||
declare function _catch<T extends core.SomeType>(innerType: T, catchValue: core.output<T> | ((ctx: core.$ZodCatchCtx) => core.output<T>)): ZodCatch<T>;
|
||||
export { _catch as catch };
|
||||
export interface ZodNaN extends _ZodType<core.$ZodNaNInternals>, core.$ZodNaN {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodNaN: core.$constructor<ZodNaN>;
|
||||
export declare function nan(params?: string | core.$ZodNaNParams): ZodNaN;
|
||||
export interface ZodPipe<A extends core.SomeType = core.$ZodType, B extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodPipeInternals<A, B>>, core.$ZodPipe<A, B> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
in: A;
|
||||
out: B;
|
||||
}
|
||||
export declare const ZodPipe: core.$constructor<ZodPipe>;
|
||||
export declare function pipe<const A extends core.SomeType, B extends core.$ZodType<unknown, core.output<A>> = core.$ZodType<unknown, core.output<A>>>(in_: A, out: B | core.$ZodType<unknown, core.output<A>>): ZodPipe<A, B>;
|
||||
export interface ZodCodec<A extends core.SomeType = core.$ZodType, B extends core.SomeType = core.$ZodType> extends ZodPipe<A, B>, core.$ZodCodec<A, B> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
_zod: core.$ZodCodecInternals<A, B>;
|
||||
def: core.$ZodCodecDef<A, B>;
|
||||
}
|
||||
export declare const ZodCodec: core.$constructor<ZodCodec>;
|
||||
export declare function codec<const A extends core.SomeType, B extends core.SomeType = core.$ZodType>(in_: A, out: B, params: {
|
||||
decode: (value: core.output<A>, payload: core.ParsePayload<core.output<A>>) => core.util.MaybeAsync<core.input<B>>;
|
||||
encode: (value: core.input<B>, payload: core.ParsePayload<core.input<B>>) => core.util.MaybeAsync<core.output<A>>;
|
||||
}): ZodCodec<A, B>;
|
||||
export declare function invertCodec<A extends core.SomeType, B extends core.SomeType>(codec: ZodCodec<A, B>): ZodCodec<B, A>;
|
||||
export interface ZodPreprocess<B extends core.SomeType = core.$ZodType, I = unknown> extends ZodPipe<core.$ZodTransform<unknown, I>, B>, core.$ZodPreprocess<B, I> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
_zod: core.$ZodPreprocessInternals<B, I>;
|
||||
def: core.$ZodPreprocessDef<B, I>;
|
||||
}
|
||||
export declare const ZodPreprocess: core.$constructor<ZodPreprocess>;
|
||||
export interface ZodReadonly<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodReadonlyInternals<T>>, core.$ZodReadonly<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodReadonly: core.$constructor<ZodReadonly>;
|
||||
export declare function readonly<T extends core.SomeType>(innerType: T): ZodReadonly<T>;
|
||||
export interface ZodTemplateLiteral<Template extends string = string> extends _ZodType<core.$ZodTemplateLiteralInternals<Template>>, core.$ZodTemplateLiteral<Template> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodTemplateLiteral: core.$constructor<ZodTemplateLiteral>;
|
||||
export declare function templateLiteral<const Parts extends core.$ZodTemplateLiteralPart[]>(parts: Parts, params?: string | core.$ZodTemplateLiteralParams): ZodTemplateLiteral<core.$PartsToTemplateLiteral<Parts>>;
|
||||
export interface ZodLazy<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodLazyInternals<T>>, core.$ZodLazy<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodLazy: core.$constructor<ZodLazy>;
|
||||
export declare function lazy<T extends core.SomeType>(getter: () => T): ZodLazy<T>;
|
||||
export interface ZodPromise<T extends core.SomeType = core.$ZodType> extends _ZodType<core.$ZodPromiseInternals<T>>, core.$ZodPromise<T> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
unwrap(): T;
|
||||
}
|
||||
export declare const ZodPromise: core.$constructor<ZodPromise>;
|
||||
export declare function promise<T extends core.SomeType>(innerType: T): ZodPromise<T>;
|
||||
export interface ZodFunction<Args extends core.$ZodFunctionIn = core.$ZodFunctionIn, Returns extends core.$ZodFunctionOut = core.$ZodFunctionOut> extends _ZodType<core.$ZodFunctionInternals<Args, Returns>>, core.$ZodFunction<Args, Returns> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
_def: core.$ZodFunctionDef<Args, Returns>;
|
||||
_input: core.$InferInnerFunctionType<Args, Returns>;
|
||||
_output: core.$InferOuterFunctionType<Args, Returns>;
|
||||
input<const Items extends util.TupleItems, const Rest extends core.$ZodFunctionOut = core.$ZodFunctionOut>(args: Items, rest?: Rest): ZodFunction<core.$ZodTuple<Items, Rest>, Returns>;
|
||||
input<NewArgs extends core.$ZodFunctionIn>(args: NewArgs): ZodFunction<NewArgs, Returns>;
|
||||
input(...args: any[]): ZodFunction<any, Returns>;
|
||||
output<NewReturns extends core.$ZodType>(output: NewReturns): ZodFunction<Args, NewReturns>;
|
||||
}
|
||||
export declare const ZodFunction: core.$constructor<ZodFunction>;
|
||||
export declare function _function(): ZodFunction;
|
||||
export declare function _function<const In extends ReadonlyArray<core.$ZodType>>(params: {
|
||||
input: In;
|
||||
}): ZodFunction<ZodTuple<In, null>, core.$ZodFunctionOut>;
|
||||
export declare function _function<const In extends ReadonlyArray<core.$ZodType>, const Out extends core.$ZodFunctionOut = core.$ZodFunctionOut>(params: {
|
||||
input: In;
|
||||
output: Out;
|
||||
}): ZodFunction<ZodTuple<In, null>, Out>;
|
||||
export declare function _function<const In extends core.$ZodFunctionIn = core.$ZodFunctionIn>(params: {
|
||||
input: In;
|
||||
}): ZodFunction<In, core.$ZodFunctionOut>;
|
||||
export declare function _function<const Out extends core.$ZodFunctionOut = core.$ZodFunctionOut>(params: {
|
||||
output: Out;
|
||||
}): ZodFunction<core.$ZodFunctionIn, Out>;
|
||||
export declare function _function<In extends core.$ZodFunctionIn = core.$ZodFunctionIn, Out extends core.$ZodType = core.$ZodType>(params?: {
|
||||
input: In;
|
||||
output: Out;
|
||||
}): ZodFunction<In, Out>;
|
||||
export { _function as function };
|
||||
export interface ZodCustom<O = unknown, I = unknown> extends _ZodType<core.$ZodCustomInternals<O, I>>, core.$ZodCustom<O, I> {
|
||||
"~standard": ZodStandardSchemaWithJSON<this>;
|
||||
}
|
||||
export declare const ZodCustom: core.$constructor<ZodCustom>;
|
||||
export declare function check<O = unknown>(fn: core.CheckFn<O>): core.$ZodCheck<O>;
|
||||
export declare function custom<O>(fn?: (data: unknown) => unknown, _params?: string | core.$ZodCustomParams | undefined): ZodCustom<O, O>;
|
||||
export declare function refine<T>(fn: (arg: NoInfer<T>) => util.MaybeAsync<unknown>, _params?: string | core.$ZodCustomParams): core.$ZodCheck<T>;
|
||||
export declare function superRefine<T>(fn: (arg: T, payload: core.$RefinementCtx<T>) => void | Promise<void>, params?: core.$ZodSuperRefineParams): core.$ZodCheck<T>;
|
||||
export declare const describe: typeof core.describe;
|
||||
export declare const meta: typeof core.meta;
|
||||
type ZodInstanceOfParams = core.Params<ZodCustom, core.$ZodIssueCustom, "type" | "check" | "checks" | "fn" | "abort" | "error" | "params" | "path">;
|
||||
export interface ZodInstanceOf<T = unknown> extends ZodCustom<T, T> {
|
||||
properties<Shape extends {
|
||||
[k in keyof T as T[k] extends Function ? never : k]?: core.$ZodType<unknown, T[k]>;
|
||||
}>(shape: Shape, params?: string | core.$ZodCheckPropertiesParams): ZodInstanceOf<T & core.$InferObjectInput<Shape, {}>>;
|
||||
}
|
||||
export declare const ZodInstanceOf: core.$constructor<ZodInstanceOf>;
|
||||
declare function _instanceof<T extends typeof util.Class>(cls: T, params?: ZodInstanceOfParams): ZodInstanceOf<InstanceType<T>>;
|
||||
export { _instanceof as instanceof };
|
||||
export declare const stringbool: (_params?: string | core.$ZodStringBoolParams) => ZodCodec<ZodString, ZodBoolean>;
|
||||
type _ZodJSONSchema = ZodUnion<[
|
||||
ZodString,
|
||||
ZodNumber,
|
||||
ZodBoolean,
|
||||
ZodNull,
|
||||
ZodArray<ZodJSONSchema>,
|
||||
ZodRecord<ZodString, ZodJSONSchema>
|
||||
]>;
|
||||
type _ZodJSONSchemaInternals = _ZodJSONSchema["_zod"];
|
||||
export interface ZodJSONSchemaInternals extends _ZodJSONSchemaInternals {
|
||||
output: util.JSONType;
|
||||
input: util.JSONType;
|
||||
}
|
||||
export interface ZodJSONSchema extends _ZodJSONSchema {
|
||||
_zod: ZodJSONSchemaInternals;
|
||||
}
|
||||
export declare function json(params?: string | core.$ZodCustomParams): ZodJSONSchema;
|
||||
export declare function preprocess<A, U extends core.SomeType, B = unknown>(fn: (arg: B, ctx: core.$RefinementCtx) => A, schema: U): ZodPreprocess<U, B>;
|
||||
+1535
File diff suppressed because it is too large
Load Diff
+335
@@ -0,0 +1,335 @@
|
||||
import * as checks from "./checks.cjs";
|
||||
import type * as core from "./core.cjs";
|
||||
import type * as errors from "./errors.cjs";
|
||||
import * as registries from "./registries.cjs";
|
||||
import * as schemas from "./schemas.cjs";
|
||||
import * as util from "./util.cjs";
|
||||
export type Params<T extends schemas.$ZodType | checks.$ZodCheck, IssueTypes extends errors.$ZodIssueBase, OmitKeys extends keyof T["_zod"]["def"] = never> = util.Flatten<Partial<util.EmptyToNever<Omit<T["_zod"]["def"], OmitKeys> & ([IssueTypes] extends [never] ? {} : {
|
||||
error?: string | errors.$ZodErrorMap<IssueTypes> | undefined;
|
||||
/** @deprecated This parameter is deprecated. Use `error` instead. */
|
||||
message?: string | undefined;
|
||||
})>>>;
|
||||
export type TypeParams<T extends schemas.$ZodType = schemas.$ZodType & {
|
||||
_isst: never;
|
||||
}, AlsoOmit extends Exclude<keyof T["_zod"]["def"], "type" | "checks" | "error"> = never> = Params<T, NonNullable<T["_zod"]["isst"]>, "type" | "checks" | "error" | AlsoOmit>;
|
||||
export type CheckParams<T extends checks.$ZodCheck = checks.$ZodCheck, // & { _issc: never },
|
||||
AlsoOmit extends Exclude<keyof T["_zod"]["def"], "check" | "error"> = never> = Params<T, NonNullable<T["_zod"]["issc"]>, "check" | "error" | AlsoOmit>;
|
||||
export type StringFormatParams<T extends schemas.$ZodStringFormat = schemas.$ZodStringFormat, AlsoOmit extends Exclude<keyof T["_zod"]["def"], "type" | "coerce" | "checks" | "error" | "check" | "format"> = never> = Params<T, NonNullable<T["_zod"]["isst"] | T["_zod"]["issc"]>, "type" | "coerce" | "checks" | "error" | "check" | "format" | AlsoOmit>;
|
||||
export type CheckStringFormatParams<T extends schemas.$ZodStringFormat = schemas.$ZodStringFormat, AlsoOmit extends Exclude<keyof T["_zod"]["def"], "type" | "coerce" | "checks" | "error" | "check" | "format"> = never> = Params<T, NonNullable<T["_zod"]["issc"]>, "type" | "coerce" | "checks" | "error" | "check" | "format" | AlsoOmit>;
|
||||
export type CheckTypeParams<T extends schemas.$ZodType & checks.$ZodCheck = schemas.$ZodType & checks.$ZodCheck, AlsoOmit extends Exclude<keyof T["_zod"]["def"], "type" | "checks" | "error" | "check"> = never> = Params<T, NonNullable<T["_zod"]["isst"] | T["_zod"]["issc"]>, "type" | "checks" | "error" | "check" | AlsoOmit>;
|
||||
export type $ZodStringParams = TypeParams<schemas.$ZodString<string>, "coerce"> & {
|
||||
checks?: readonly checks.$ZodCheck<string>[];
|
||||
};
|
||||
export declare function _string<T extends schemas.$ZodString>(Class: util.SchemaClass<T>, params?: string | $ZodStringParams): T;
|
||||
export declare function _coercedString<T extends schemas.$ZodString>(Class: util.SchemaClass<T>, params?: string | $ZodStringParams): T;
|
||||
export type $ZodStringFormatParams = CheckTypeParams<schemas.$ZodStringFormat, "format" | "coerce" | "when" | "pattern">;
|
||||
export type $ZodCheckStringFormatParams = CheckParams<checks.$ZodCheckStringFormat, "format">;
|
||||
export type $ZodEmailParams = StringFormatParams<schemas.$ZodEmail, "when">;
|
||||
export type $ZodCheckEmailParams = CheckStringFormatParams<schemas.$ZodEmail, "when">;
|
||||
export declare function _email<T extends schemas.$ZodEmail>(Class: util.SchemaClass<T>, params?: string | $ZodEmailParams | $ZodCheckEmailParams): T;
|
||||
export type $ZodGUIDParams = StringFormatParams<schemas.$ZodGUID, "pattern" | "when">;
|
||||
export type $ZodCheckGUIDParams = CheckStringFormatParams<schemas.$ZodGUID, "pattern" | "when">;
|
||||
export declare function _guid<T extends schemas.$ZodGUID>(Class: util.SchemaClass<T>, params?: string | $ZodGUIDParams | $ZodCheckGUIDParams): T;
|
||||
export type $ZodUUIDParams = StringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export type $ZodCheckUUIDParams = CheckStringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export declare function _uuid<T extends schemas.$ZodUUID>(Class: util.SchemaClass<T>, params?: string | $ZodUUIDParams | $ZodCheckUUIDParams): T;
|
||||
export type $ZodUUIDv4Params = StringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export type $ZodCheckUUIDv4Params = CheckStringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export declare function _uuidv4<T extends schemas.$ZodUUID>(Class: util.SchemaClass<T>, params?: string | $ZodUUIDv4Params | $ZodCheckUUIDv4Params): T;
|
||||
export type $ZodUUIDv6Params = StringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export type $ZodCheckUUIDv6Params = CheckStringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export declare function _uuidv6<T extends schemas.$ZodUUID>(Class: util.SchemaClass<T>, params?: string | $ZodUUIDv6Params | $ZodCheckUUIDv6Params): T;
|
||||
export type $ZodUUIDv7Params = StringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export type $ZodCheckUUIDv7Params = CheckStringFormatParams<schemas.$ZodUUID, "pattern" | "when">;
|
||||
export declare function _uuidv7<T extends schemas.$ZodUUID>(Class: util.SchemaClass<T>, params?: string | $ZodUUIDv7Params | $ZodCheckUUIDv7Params): T;
|
||||
export type $ZodURLParams = StringFormatParams<schemas.$ZodURL, "when">;
|
||||
export type $ZodCheckURLParams = CheckStringFormatParams<schemas.$ZodURL, "when">;
|
||||
export declare function _url<T extends schemas.$ZodURL>(Class: util.SchemaClass<T>, params?: string | $ZodURLParams | $ZodCheckURLParams): T;
|
||||
export type $ZodEmojiParams = StringFormatParams<schemas.$ZodEmoji, "when">;
|
||||
export type $ZodCheckEmojiParams = CheckStringFormatParams<schemas.$ZodEmoji, "when">;
|
||||
export declare function _emoji<T extends schemas.$ZodEmoji>(Class: util.SchemaClass<T>, params?: string | $ZodEmojiParams | $ZodCheckEmojiParams): T;
|
||||
export type $ZodNanoIDParams = StringFormatParams<schemas.$ZodNanoID, "when" | "pattern">;
|
||||
export type $ZodCheckNanoIDParams = CheckStringFormatParams<schemas.$ZodNanoID, "when" | "pattern">;
|
||||
export declare function _nanoid<T extends schemas.$ZodNanoID>(Class: util.SchemaClass<T>, params?: string | $ZodNanoIDParams | $ZodCheckNanoIDParams): T;
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export type $ZodCUIDParams = StringFormatParams<schemas.$ZodCUID, "when">;
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export type $ZodCheckCUIDParams = CheckStringFormatParams<schemas.$ZodCUID, "when">;
|
||||
/**
|
||||
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
||||
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
||||
* See https://github.com/paralleldrive/cuid.
|
||||
*/
|
||||
export declare function _cuid<T extends schemas.$ZodCUID>(Class: util.SchemaClass<T>, params?: string | $ZodCUIDParams | $ZodCheckCUIDParams): T;
|
||||
export type $ZodCUID2Params = StringFormatParams<schemas.$ZodCUID2, "when">;
|
||||
export type $ZodCheckCUID2Params = CheckStringFormatParams<schemas.$ZodCUID2, "when">;
|
||||
export declare function _cuid2<T extends schemas.$ZodCUID2>(Class: util.SchemaClass<T>, params?: string | $ZodCUID2Params | $ZodCheckCUID2Params): T;
|
||||
export type $ZodULIDParams = StringFormatParams<schemas.$ZodULID, "when">;
|
||||
export type $ZodCheckULIDParams = CheckStringFormatParams<schemas.$ZodULID, "when">;
|
||||
export declare function _ulid<T extends schemas.$ZodULID>(Class: util.SchemaClass<T>, params?: string | $ZodULIDParams | $ZodCheckULIDParams): T;
|
||||
export type $ZodXIDParams = StringFormatParams<schemas.$ZodXID, "when">;
|
||||
export type $ZodCheckXIDParams = CheckStringFormatParams<schemas.$ZodXID, "when">;
|
||||
export declare function _xid<T extends schemas.$ZodXID>(Class: util.SchemaClass<T>, params?: string | $ZodXIDParams | $ZodCheckXIDParams): T;
|
||||
export type $ZodKSUIDParams = StringFormatParams<schemas.$ZodKSUID, "when">;
|
||||
export type $ZodCheckKSUIDParams = CheckStringFormatParams<schemas.$ZodKSUID, "when">;
|
||||
export declare function _ksuid<T extends schemas.$ZodKSUID>(Class: util.SchemaClass<T>, params?: string | $ZodKSUIDParams | $ZodCheckKSUIDParams): T;
|
||||
export type $ZodIPv4Params = StringFormatParams<schemas.$ZodIPv4, "pattern" | "when" | "version">;
|
||||
export type $ZodCheckIPv4Params = CheckStringFormatParams<schemas.$ZodIPv4, "pattern" | "when" | "version">;
|
||||
export declare function _ipv4<T extends schemas.$ZodIPv4>(Class: util.SchemaClass<T>, params?: string | $ZodIPv4Params | $ZodCheckIPv4Params): T;
|
||||
export type $ZodIPv6Params = StringFormatParams<schemas.$ZodIPv6, "pattern" | "when" | "version">;
|
||||
export type $ZodCheckIPv6Params = CheckStringFormatParams<schemas.$ZodIPv6, "pattern" | "when" | "version">;
|
||||
export declare function _ipv6<T extends schemas.$ZodIPv6>(Class: util.SchemaClass<T>, params?: string | $ZodIPv6Params | $ZodCheckIPv6Params): T;
|
||||
export type $ZodMACParams = StringFormatParams<schemas.$ZodMAC, "pattern" | "when">;
|
||||
export type $ZodCheckMACParams = CheckStringFormatParams<schemas.$ZodMAC, "pattern" | "when">;
|
||||
export declare function _mac<T extends schemas.$ZodMAC>(Class: util.SchemaClass<T>, params?: string | $ZodMACParams | $ZodCheckMACParams): T;
|
||||
export type $ZodCIDRv4Params = StringFormatParams<schemas.$ZodCIDRv4, "pattern" | "when">;
|
||||
export type $ZodCheckCIDRv4Params = CheckStringFormatParams<schemas.$ZodCIDRv4, "pattern" | "when">;
|
||||
export declare function _cidrv4<T extends schemas.$ZodCIDRv4>(Class: util.SchemaClass<T>, params?: string | $ZodCIDRv4Params | $ZodCheckCIDRv4Params): T;
|
||||
export type $ZodCIDRv6Params = StringFormatParams<schemas.$ZodCIDRv6, "pattern" | "when">;
|
||||
export type $ZodCheckCIDRv6Params = CheckStringFormatParams<schemas.$ZodCIDRv6, "pattern" | "when">;
|
||||
export declare function _cidrv6<T extends schemas.$ZodCIDRv6>(Class: util.SchemaClass<T>, params?: string | $ZodCIDRv6Params | $ZodCheckCIDRv6Params): T;
|
||||
export type $ZodBase64Params = StringFormatParams<schemas.$ZodBase64, "pattern" | "when">;
|
||||
export type $ZodCheckBase64Params = CheckStringFormatParams<schemas.$ZodBase64, "pattern" | "when">;
|
||||
export declare function _base64<T extends schemas.$ZodBase64>(Class: util.SchemaClass<T>, params?: string | $ZodBase64Params | $ZodCheckBase64Params): T;
|
||||
export type $ZodBase64URLParams = StringFormatParams<schemas.$ZodBase64URL, "pattern" | "when">;
|
||||
export type $ZodCheckBase64URLParams = CheckStringFormatParams<schemas.$ZodBase64URL, "pattern" | "when">;
|
||||
export declare function _base64url<T extends schemas.$ZodBase64URL>(Class: util.SchemaClass<T>, params?: string | $ZodBase64URLParams | $ZodCheckBase64URLParams): T;
|
||||
export type $ZodE164Params = StringFormatParams<schemas.$ZodE164, "when">;
|
||||
export type $ZodCheckE164Params = CheckStringFormatParams<schemas.$ZodE164, "when">;
|
||||
export declare function _e164<T extends schemas.$ZodE164>(Class: util.SchemaClass<T>, params?: string | $ZodE164Params | $ZodCheckE164Params): T;
|
||||
export type $ZodCreditCardParams = StringFormatParams<schemas.$ZodCreditCard, "pattern" | "when">;
|
||||
export type $ZodCheckCreditCardParams = CheckStringFormatParams<schemas.$ZodCreditCard, "pattern" | "when">;
|
||||
export declare function _creditCard<T extends schemas.$ZodCreditCard>(Class: util.SchemaClass<T>, params?: string | $ZodCreditCardParams | $ZodCheckCreditCardParams): T;
|
||||
export type $ZodIBANParams = StringFormatParams<schemas.$ZodIBAN, "pattern" | "when">;
|
||||
export type $ZodCheckIBANParams = CheckStringFormatParams<schemas.$ZodIBAN, "pattern" | "when">;
|
||||
export declare function _iban<T extends schemas.$ZodIBAN>(Class: util.SchemaClass<T>, params?: string | $ZodIBANParams | $ZodCheckIBANParams): T;
|
||||
export type $ZodJWTParams = StringFormatParams<schemas.$ZodJWT, "pattern" | "when">;
|
||||
export type $ZodCheckJWTParams = CheckStringFormatParams<schemas.$ZodJWT, "pattern" | "when">;
|
||||
export declare function _jwt<T extends schemas.$ZodJWT>(Class: util.SchemaClass<T>, params?: string | $ZodJWTParams | $ZodCheckJWTParams): T;
|
||||
export declare const TimePrecision: {
|
||||
readonly Any: null;
|
||||
readonly Minute: -1;
|
||||
readonly Second: 0;
|
||||
readonly Millisecond: 3;
|
||||
readonly Microsecond: 6;
|
||||
};
|
||||
export type $ZodISODateTimeParams = StringFormatParams<schemas.$ZodISODateTime, "pattern" | "when">;
|
||||
export type $ZodCheckISODateTimeParams = CheckStringFormatParams<schemas.$ZodISODateTime, "pattern" | "when">;
|
||||
export declare function _isoDateTime<T extends schemas.$ZodISODateTime>(Class: util.SchemaClass<T>, params?: string | $ZodISODateTimeParams | $ZodCheckISODateTimeParams): T;
|
||||
export type $ZodISODateParams = StringFormatParams<schemas.$ZodISODate, "pattern" | "when">;
|
||||
export type $ZodCheckISODateParams = CheckStringFormatParams<schemas.$ZodISODate, "pattern" | "when">;
|
||||
export declare function _isoDate<T extends schemas.$ZodISODate>(Class: util.SchemaClass<T>, params?: string | $ZodISODateParams | $ZodCheckISODateParams): T;
|
||||
export type $ZodISOTimeParams = StringFormatParams<schemas.$ZodISOTime, "pattern" | "when">;
|
||||
export type $ZodCheckISOTimeParams = CheckStringFormatParams<schemas.$ZodISOTime, "pattern" | "when">;
|
||||
export declare function _isoTime<T extends schemas.$ZodISOTime>(Class: util.SchemaClass<T>, params?: string | $ZodISOTimeParams | $ZodCheckISOTimeParams): T;
|
||||
export type $ZodISODurationParams = StringFormatParams<schemas.$ZodISODuration, "when">;
|
||||
export type $ZodCheckISODurationParams = CheckStringFormatParams<schemas.$ZodISODuration, "when">;
|
||||
export declare function _isoDuration<T extends schemas.$ZodISODuration>(Class: util.SchemaClass<T>, params?: string | $ZodISODurationParams | $ZodCheckISODurationParams): T;
|
||||
export type $ZodNumberParams = TypeParams<schemas.$ZodNumber<number>, "coerce"> & {
|
||||
checks?: readonly checks.$ZodCheck<number>[];
|
||||
};
|
||||
export type $ZodNumberFormatParams = CheckTypeParams<schemas.$ZodNumberFormat, "format" | "coerce">;
|
||||
export type $ZodCheckNumberFormatParams = CheckParams<checks.$ZodCheckNumberFormat, "format" | "when">;
|
||||
export declare function _number<T extends schemas.$ZodNumber>(Class: util.SchemaClass<T>, params?: string | $ZodNumberParams): T;
|
||||
export declare function _coercedNumber<T extends schemas.$ZodNumber>(Class: util.SchemaClass<T>, params?: string | $ZodNumberParams): T;
|
||||
export declare function _int<T extends schemas.$ZodNumberFormat>(Class: util.SchemaClass<T>, params?: string | $ZodCheckNumberFormatParams): T;
|
||||
export declare function _float32<T extends schemas.$ZodNumberFormat>(Class: util.SchemaClass<T>, params?: string | $ZodCheckNumberFormatParams): T;
|
||||
export declare function _float64<T extends schemas.$ZodNumberFormat>(Class: util.SchemaClass<T>, params?: string | $ZodCheckNumberFormatParams): T;
|
||||
export declare function _int32<T extends schemas.$ZodNumberFormat>(Class: util.SchemaClass<T>, params?: string | $ZodCheckNumberFormatParams): T;
|
||||
export declare function _uint32<T extends schemas.$ZodNumberFormat>(Class: util.SchemaClass<T>, params?: string | $ZodCheckNumberFormatParams): T;
|
||||
export type $ZodBooleanParams = TypeParams<schemas.$ZodBoolean<boolean>, "coerce">;
|
||||
export declare function _boolean<T extends schemas.$ZodBoolean>(Class: util.SchemaClass<T>, params?: string | $ZodBooleanParams): T;
|
||||
export declare function _coercedBoolean<T extends schemas.$ZodBoolean>(Class: util.SchemaClass<T>, params?: string | $ZodBooleanParams): T;
|
||||
export type $ZodBigIntParams = TypeParams<schemas.$ZodBigInt<bigint>>;
|
||||
export type $ZodBigIntFormatParams = CheckTypeParams<schemas.$ZodBigIntFormat, "format" | "coerce">;
|
||||
export type $ZodCheckBigIntFormatParams = CheckParams<checks.$ZodCheckBigIntFormat, "format" | "when">;
|
||||
export declare function _bigint<T extends schemas.$ZodBigInt>(Class: util.SchemaClass<T>, params?: string | $ZodBigIntParams): T;
|
||||
export declare function _coercedBigint<T extends schemas.$ZodBigInt>(Class: util.SchemaClass<T>, params?: string | $ZodBigIntParams): T;
|
||||
export declare function _int64<T extends schemas.$ZodBigIntFormat>(Class: util.SchemaClass<T>, params?: string | $ZodBigIntFormatParams): T;
|
||||
export declare function _uint64<T extends schemas.$ZodBigIntFormat>(Class: util.SchemaClass<T>, params?: string | $ZodBigIntFormatParams): T;
|
||||
export type $ZodSymbolParams = TypeParams<schemas.$ZodSymbol>;
|
||||
export declare function _symbol<T extends schemas.$ZodSymbol>(Class: util.SchemaClass<T>, params?: string | $ZodSymbolParams): T;
|
||||
export type $ZodUndefinedParams = TypeParams<schemas.$ZodUndefined>;
|
||||
export declare function _undefined<T extends schemas.$ZodUndefined>(Class: util.SchemaClass<T>, params?: string | $ZodUndefinedParams): T;
|
||||
export type $ZodNullParams = TypeParams<schemas.$ZodNull>;
|
||||
export declare function _null<T extends schemas.$ZodNull>(Class: util.SchemaClass<T>, params?: string | $ZodNullParams): T;
|
||||
export type $ZodAnyParams = TypeParams<schemas.$ZodAny>;
|
||||
export declare function _any<T extends schemas.$ZodAny>(Class: util.SchemaClass<T>): T;
|
||||
export type $ZodUnknownParams = TypeParams<schemas.$ZodUnknown>;
|
||||
export declare function _unknown<T extends schemas.$ZodUnknown>(Class: util.SchemaClass<T>): T;
|
||||
export type $ZodNeverParams = TypeParams<schemas.$ZodNever>;
|
||||
export declare function _never<T extends schemas.$ZodNever>(Class: util.SchemaClass<T>, params?: string | $ZodNeverParams): T;
|
||||
export type $ZodVoidParams = TypeParams<schemas.$ZodVoid>;
|
||||
export declare function _void<T extends schemas.$ZodVoid>(Class: util.SchemaClass<T>, params?: string | $ZodVoidParams): T;
|
||||
export type $ZodDateParams = TypeParams<schemas.$ZodDate, "coerce">;
|
||||
export declare function _date<T extends schemas.$ZodDate>(Class: util.SchemaClass<T>, params?: string | $ZodDateParams): T;
|
||||
export declare function _coercedDate<T extends schemas.$ZodDate>(Class: util.SchemaClass<T>, params?: string | $ZodDateParams): T;
|
||||
export type $ZodNaNParams = TypeParams<schemas.$ZodNaN>;
|
||||
export declare function _nan<T extends schemas.$ZodNaN>(Class: util.SchemaClass<T>, params?: string | $ZodNaNParams): T;
|
||||
export type $ZodCheckLessThanParams = CheckParams<checks.$ZodCheckLessThan, "inclusive" | "value" | "when">;
|
||||
export declare function _lt(value: util.Numeric, params?: string | $ZodCheckLessThanParams): checks.$ZodCheckLessThan<util.Numeric>;
|
||||
export declare function _lte(value: util.Numeric, params?: string | $ZodCheckLessThanParams): checks.$ZodCheckLessThan<util.Numeric>;
|
||||
export {
|
||||
/** @deprecated Use `z.lte()` instead. */
|
||||
_lte as _max, };
|
||||
export type $ZodCheckGreaterThanParams = CheckParams<checks.$ZodCheckGreaterThan, "inclusive" | "value" | "when">;
|
||||
export declare function _gt(value: util.Numeric, params?: string | $ZodCheckGreaterThanParams): checks.$ZodCheckGreaterThan;
|
||||
export declare function _gte(value: util.Numeric, params?: string | $ZodCheckGreaterThanParams): checks.$ZodCheckGreaterThan;
|
||||
export {
|
||||
/** @deprecated Use `z.gte()` instead. */
|
||||
_gte as _min, };
|
||||
export declare function _positive(params?: string | $ZodCheckGreaterThanParams): checks.$ZodCheckGreaterThan;
|
||||
export declare function _negative(params?: string | $ZodCheckLessThanParams): checks.$ZodCheckLessThan;
|
||||
export declare function _nonpositive(params?: string | $ZodCheckLessThanParams): checks.$ZodCheckLessThan;
|
||||
export declare function _nonnegative(params?: string | $ZodCheckGreaterThanParams): checks.$ZodCheckGreaterThan;
|
||||
export type $ZodCheckMultipleOfParams = CheckParams<checks.$ZodCheckMultipleOf, "value" | "when">;
|
||||
export declare function _multipleOf(value: number | bigint, params?: string | $ZodCheckMultipleOfParams): checks.$ZodCheckMultipleOf;
|
||||
export type $ZodCheckMaxSizeParams = CheckParams<checks.$ZodCheckMaxSize, "maximum" | "when">;
|
||||
export declare function _maxSize(maximum: number, params?: string | $ZodCheckMaxSizeParams): checks.$ZodCheckMaxSize<util.HasSize>;
|
||||
export type $ZodCheckMinSizeParams = CheckParams<checks.$ZodCheckMinSize, "minimum" | "when">;
|
||||
export declare function _minSize(minimum: number, params?: string | $ZodCheckMinSizeParams): checks.$ZodCheckMinSize<util.HasSize>;
|
||||
export type $ZodCheckSizeEqualsParams = CheckParams<checks.$ZodCheckSizeEquals, "size" | "when">;
|
||||
export declare function _size(size: number, params?: string | $ZodCheckSizeEqualsParams): checks.$ZodCheckSizeEquals<util.HasSize>;
|
||||
export type $ZodCheckMaxLengthParams = CheckParams<checks.$ZodCheckMaxLength, "maximum" | "when">;
|
||||
export declare function _maxLength(maximum: number, params?: string | $ZodCheckMaxLengthParams): checks.$ZodCheckMaxLength<util.HasLength>;
|
||||
export type $ZodCheckMinLengthParams = CheckParams<checks.$ZodCheckMinLength, "minimum" | "when">;
|
||||
export declare function _minLength(minimum: number, params?: string | $ZodCheckMinLengthParams): checks.$ZodCheckMinLength<util.HasLength>;
|
||||
export type $ZodCheckLengthEqualsParams = CheckParams<checks.$ZodCheckLengthEquals, "length" | "when">;
|
||||
export declare function _length(length: number, params?: string | $ZodCheckLengthEqualsParams): checks.$ZodCheckLengthEquals<util.HasLength>;
|
||||
export type $ZodCheckRegexParams = CheckParams<checks.$ZodCheckRegex, "format" | "pattern" | "when">;
|
||||
export declare function _regex(pattern: RegExp, params?: string | $ZodCheckRegexParams): checks.$ZodCheckRegex;
|
||||
export type $ZodCheckLowerCaseParams = CheckParams<checks.$ZodCheckLowerCase, "format" | "when">;
|
||||
export declare function _lowercase(params?: string | $ZodCheckLowerCaseParams): checks.$ZodCheckLowerCase;
|
||||
export type $ZodCheckUpperCaseParams = CheckParams<checks.$ZodCheckUpperCase, "format" | "when">;
|
||||
export declare function _uppercase(params?: string | $ZodCheckUpperCaseParams): checks.$ZodCheckUpperCase;
|
||||
export type $ZodCheckIncludesParams = CheckParams<checks.$ZodCheckIncludes, "includes" | "format" | "when" | "pattern">;
|
||||
export declare function _includes(includes: string, params?: string | $ZodCheckIncludesParams): checks.$ZodCheckIncludes;
|
||||
export type $ZodCheckStartsWithParams = CheckParams<checks.$ZodCheckStartsWith, "prefix" | "format" | "when" | "pattern">;
|
||||
export declare function _startsWith(prefix: string, params?: string | $ZodCheckStartsWithParams): checks.$ZodCheckStartsWith;
|
||||
export type $ZodCheckEndsWithParams = CheckParams<checks.$ZodCheckEndsWith, "suffix" | "format" | "pattern" | "when">;
|
||||
export declare function _endsWith(suffix: string, params?: string | $ZodCheckEndsWithParams): checks.$ZodCheckEndsWith;
|
||||
export type $ZodCheckPropertyParams = CheckParams<checks.$ZodCheckProperty, "property" | "schema" | "when">;
|
||||
export declare function _property<K extends string, T extends schemas.$ZodType>(property: K, schema: T, params?: string | $ZodCheckPropertyParams): checks.$ZodCheckProperty<{
|
||||
[k in K]: util.Widen<core.input<T>>;
|
||||
}>;
|
||||
export type $ZodCheckPropertiesParams = CheckParams<checks.$ZodCheckProperties, "shape" | "when">;
|
||||
export declare function _properties<Shape extends schemas.$ZodShape>(shape: Shape, params?: string | $ZodCheckPropertiesParams): checks.$ZodCheckProperties<Shape>;
|
||||
export type $ZodCheckMimeTypeParams = CheckParams<checks.$ZodCheckMimeType, "mime" | "when">;
|
||||
export declare function _mime(types: util.MimeTypes[], params?: string | $ZodCheckMimeTypeParams): checks.$ZodCheckMimeType;
|
||||
export declare function _overwrite<T>(tx: (input: T) => T): checks.$ZodCheckOverwrite<T>;
|
||||
export declare function _normalize(form?: "NFC" | "NFD" | "NFKC" | "NFKD" | (string & {})): checks.$ZodCheckOverwrite<string>;
|
||||
export declare function _trim(): checks.$ZodCheckOverwrite<string>;
|
||||
export declare function _toLowerCase(): checks.$ZodCheckOverwrite<string>;
|
||||
export declare function _toUpperCase(): checks.$ZodCheckOverwrite<string>;
|
||||
export declare function _slugify(): checks.$ZodCheckOverwrite<string>;
|
||||
export type $ZodArrayParams = TypeParams<schemas.$ZodArray, "element">;
|
||||
export declare function _array<T extends schemas.$ZodType>(Class: util.SchemaClass<schemas.$ZodArray>, element: T, params?: string | $ZodArrayParams): schemas.$ZodArray<T>;
|
||||
export type $ZodObjectParams = TypeParams<schemas.$ZodObject, "shape" | "catchall">;
|
||||
export type $ZodUnionParams = TypeParams<schemas.$ZodUnion, "options">;
|
||||
export declare function _union<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodUnion>, options: T, params?: string | $ZodUnionParams): schemas.$ZodUnion<T>;
|
||||
export type $ZodXorParams = TypeParams<schemas.$ZodXor, "options">;
|
||||
export declare function _xor<const T extends readonly schemas.$ZodObject[]>(Class: util.SchemaClass<schemas.$ZodXor>, options: T, params?: string | $ZodXorParams): schemas.$ZodXor<T>;
|
||||
export interface $ZodTypeDiscriminableInternals<_Disc extends string = string> extends schemas._$ZodTypeInternals {
|
||||
propValues: util.PropValues;
|
||||
}
|
||||
export interface $ZodTypeDiscriminable<_Disc extends string = string> extends schemas.SomeType {
|
||||
_zod: $ZodTypeDiscriminableInternals;
|
||||
}
|
||||
export type $ZodDiscriminatedUnionParams = TypeParams<schemas.$ZodDiscriminatedUnion, "options" | "discriminator">;
|
||||
export declare function _discriminatedUnion<Types extends [$ZodTypeDiscriminable, ...$ZodTypeDiscriminable[]], Disc extends string>(Class: util.SchemaClass<schemas.$ZodDiscriminatedUnion>, discriminator: Disc, options: Types, params?: string | $ZodDiscriminatedUnionParams): schemas.$ZodDiscriminatedUnion<Types, Disc>;
|
||||
export type $ZodIntersectionParams = TypeParams<schemas.$ZodIntersection, "left" | "right">;
|
||||
export declare function _intersection<T extends schemas.$ZodObject, U extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodIntersection>, left: T, right: U): schemas.$ZodIntersection<T, U>;
|
||||
export type $ZodTupleParams = TypeParams<schemas.$ZodTuple, "items" | "rest">;
|
||||
export declare function _tuple<T extends readonly [schemas.$ZodType, ...schemas.$ZodType[]]>(Class: util.SchemaClass<schemas.$ZodTuple>, items: T, params?: string | $ZodTupleParams): schemas.$ZodTuple<T, null>;
|
||||
export declare function _tuple<T extends readonly [schemas.$ZodType, ...schemas.$ZodType[]], Rest extends schemas.$ZodType>(Class: util.SchemaClass<schemas.$ZodTuple>, items: T, rest: Rest, params?: string | $ZodTupleParams): schemas.$ZodTuple<T, Rest>;
|
||||
export type $ZodRecordParams = TypeParams<schemas.$ZodRecord, "keyType" | "valueType" | "partial">;
|
||||
export declare function _record<Key extends schemas.$ZodRecordKey, Value extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodRecord>, keyType: Key, valueType: Value, params?: string | $ZodRecordParams): schemas.$ZodRecord<Key, Value>;
|
||||
export type $ZodMapParams = TypeParams<schemas.$ZodMap, "keyType" | "valueType">;
|
||||
export declare function _map<Key extends schemas.$ZodObject, Value extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodMap>, keyType: Key, valueType: Value, params?: string | $ZodMapParams): schemas.$ZodMap<Key, Value>;
|
||||
export type $ZodSetParams = TypeParams<schemas.$ZodSet, "valueType">;
|
||||
export declare function _set<Value extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodSet>, valueType: Value, params?: string | $ZodSetParams): schemas.$ZodSet<Value>;
|
||||
export type $ZodEnumParams = TypeParams<schemas.$ZodEnum, "entries">;
|
||||
export declare function _enum<const T extends string[]>(Class: util.SchemaClass<schemas.$ZodEnum>, values: T, params?: string | $ZodEnumParams): schemas.$ZodEnum<util.ToEnum<T[number]>>;
|
||||
export declare function _enum<T extends util.EnumLike>(Class: util.SchemaClass<schemas.$ZodEnum>, entries: T, params?: string | $ZodEnumParams): schemas.$ZodEnum<T>;
|
||||
/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.
|
||||
*
|
||||
* ```ts
|
||||
* enum Colors { red, green, blue }
|
||||
* z.enum(Colors);
|
||||
* ```
|
||||
*/
|
||||
export declare function _nativeEnum<T extends util.EnumLike>(Class: util.SchemaClass<schemas.$ZodEnum>, entries: T, params?: string | $ZodEnumParams): schemas.$ZodEnum<T>;
|
||||
export type $ZodLiteralParams = TypeParams<schemas.$ZodLiteral, "values">;
|
||||
export declare function _literal<const T extends Array<util.Literal>>(Class: util.SchemaClass<schemas.$ZodLiteral>, value: T, params?: string | $ZodLiteralParams): schemas.$ZodLiteral<T[number]>;
|
||||
export declare function _literal<const T extends util.Literal>(Class: util.SchemaClass<schemas.$ZodLiteral>, value: T, params?: string | $ZodLiteralParams): schemas.$ZodLiteral<T>;
|
||||
export type $ZodFileParams = TypeParams<schemas.$ZodFile>;
|
||||
export declare function _file(Class: util.SchemaClass<schemas.$ZodFile>, params?: string | $ZodFileParams): schemas.$ZodFile;
|
||||
export type $ZodTransformParams = TypeParams<schemas.$ZodTransform, "transform">;
|
||||
export declare function _transform<I = unknown, O = I>(Class: util.SchemaClass<schemas.$ZodTransform>, fn: (input: I, ctx?: schemas.ParsePayload) => O): schemas.$ZodTransform<Awaited<O>, I>;
|
||||
export type $ZodOptionalParams = TypeParams<schemas.$ZodOptional, "innerType">;
|
||||
export declare function _optional<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodOptional>, innerType: T): schemas.$ZodOptional<T>;
|
||||
export type $ZodNullableParams = TypeParams<schemas.$ZodNullable, "innerType">;
|
||||
export declare function _nullable<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodNullable>, innerType: T): schemas.$ZodNullable<T>;
|
||||
export type $ZodDefaultParams = TypeParams<schemas.$ZodDefault, "innerType" | "defaultValue">;
|
||||
export declare function _default<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodDefault>, innerType: T, defaultValue: util.NoUndefined<core.output<T>> | (() => util.NoUndefined<core.output<T>>)): schemas.$ZodDefault<T>;
|
||||
export type $ZodNonOptionalParams = TypeParams<schemas.$ZodNonOptional, "innerType">;
|
||||
export declare function _nonoptional<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodNonOptional>, innerType: T, params?: string | $ZodNonOptionalParams): schemas.$ZodNonOptional<T>;
|
||||
export type $ZodSuccessParams = TypeParams<schemas.$ZodSuccess, "innerType">;
|
||||
export declare function _success<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodSuccess>, innerType: T): schemas.$ZodSuccess<T>;
|
||||
export type $ZodCatchParams = TypeParams<schemas.$ZodCatch, "innerType" | "catchValue">;
|
||||
export declare function _catch<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodCatch>, innerType: T, catchValue: core.output<T> | ((ctx: schemas.$ZodCatchCtx) => core.output<T>)): schemas.$ZodCatch<T>;
|
||||
export type $ZodPipeParams = TypeParams<schemas.$ZodPipe, "in" | "out">;
|
||||
export declare function _pipe<const A extends schemas.$ZodType, B extends schemas.$ZodType<unknown, core.output<A>> = schemas.$ZodType<unknown, core.output<A>>>(Class: util.SchemaClass<schemas.$ZodPipe>, in_: A, out: B | schemas.$ZodType<unknown, core.output<A>>): schemas.$ZodPipe<A, B>;
|
||||
export type $ZodReadonlyParams = TypeParams<schemas.$ZodReadonly, "innerType">;
|
||||
export declare function _readonly<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodReadonly>, innerType: T): schemas.$ZodReadonly<T>;
|
||||
export type $ZodTemplateLiteralParams = TypeParams<schemas.$ZodTemplateLiteral, "parts">;
|
||||
export declare function _templateLiteral<const Parts extends schemas.$ZodTemplateLiteralPart[]>(Class: util.SchemaClass<schemas.$ZodTemplateLiteral>, parts: Parts, params?: string | $ZodTemplateLiteralParams): schemas.$ZodTemplateLiteral<schemas.$PartsToTemplateLiteral<Parts>>;
|
||||
export type $ZodLazyParams = TypeParams<schemas.$ZodLazy, "getter">;
|
||||
export declare function _lazy<T extends schemas.$ZodType>(Class: util.SchemaClass<schemas.$ZodLazy>, getter: () => T): schemas.$ZodLazy<T>;
|
||||
export type $ZodPromiseParams = TypeParams<schemas.$ZodPromise, "innerType">;
|
||||
export declare function _promise<T extends schemas.$ZodObject>(Class: util.SchemaClass<schemas.$ZodPromise>, innerType: T): schemas.$ZodPromise<T>;
|
||||
export type $ZodCustomParams = CheckTypeParams<schemas.$ZodCustom, "fn">;
|
||||
export declare function _custom<O = unknown, I = O>(Class: util.SchemaClass<schemas.$ZodCustom>, fn: (data: O) => unknown, _params: string | $ZodCustomParams | undefined): schemas.$ZodCustom<O, I>;
|
||||
export declare function _refine<O = unknown, I = O>(Class: util.SchemaClass<schemas.$ZodCustom>, fn: (data: O) => unknown, _params: string | $ZodCustomParams | undefined): schemas.$ZodCustom<O, I>;
|
||||
export type $ZodSuperRefineIssue<T extends errors.$ZodIssueBase = errors.$ZodIssue> = T extends any ? RawIssue<T> : never;
|
||||
type RawIssue<T extends errors.$ZodIssueBase> = T extends any ? util.Flatten<util.MakePartial<T, "message" | "path"> & {
|
||||
/** The schema or check that originated this issue. */
|
||||
readonly inst?: schemas.$ZodType | checks.$ZodCheck;
|
||||
/** If `true`, Zod will execute subsequent checks/refinements instead of immediately aborting */
|
||||
readonly continue?: boolean | undefined;
|
||||
} & Record<string, unknown>> : never;
|
||||
export interface $RefinementCtx<T = unknown> extends schemas.ParsePayload<T> {
|
||||
addIssue(arg: string | $ZodSuperRefineIssue): void;
|
||||
}
|
||||
export interface $ZodSuperRefineParams {
|
||||
/** If provided, the refinement runs only when this returns `true`. By default, it is skipped if prior parsing produced aborting issues. */
|
||||
when?: ((payload: schemas.ParsePayload) => boolean) | undefined;
|
||||
}
|
||||
export declare function _superRefine<T>(fn: (arg: T, payload: $RefinementCtx<T>) => void | Promise<void>, params?: $ZodSuperRefineParams): checks.$ZodCheck<T>;
|
||||
export declare function _check<O = unknown>(fn: schemas.CheckFn<O>, params?: string | $ZodCustomParams): checks.$ZodCheck<O>;
|
||||
export declare function describe<T>(description: string): checks.$ZodCheck<T>;
|
||||
export declare function meta<T>(metadata: registries.GlobalMeta): checks.$ZodCheck<T>;
|
||||
export interface $ZodStringBoolParams extends TypeParams {
|
||||
truthy?: string[];
|
||||
falsy?: string[];
|
||||
/**
|
||||
* Options: `"sensitive"`, `"insensitive"`
|
||||
*
|
||||
* @default `"insensitive"`
|
||||
*/
|
||||
case?: "sensitive" | "insensitive" | undefined;
|
||||
}
|
||||
export declare function _stringbool(Classes: {
|
||||
Codec?: typeof schemas.$ZodCodec;
|
||||
Boolean?: typeof schemas.$ZodBoolean;
|
||||
String?: typeof schemas.$ZodString;
|
||||
}, _params?: string | $ZodStringBoolParams): schemas.$ZodCodec<schemas.$ZodString, schemas.$ZodBoolean>;
|
||||
export declare function _stringFormat<Format extends string>(Class: typeof schemas.$ZodCustomStringFormat, format: Format, fnOrRegex: ((arg: string) => util.MaybeAsync<unknown>) | RegExp, _params?: string | $ZodStringFormatParams): schemas.$ZodCustomStringFormat<Format>;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user