@tetsujs/openapi 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,11 +9,11 @@
9
9
  "/**\n * One route table entry, described as an OpenAPI operation.\n *\n * Bodies and responses live here; parameters are in `parameters.ts`. The\n * error responses a route can produce without the author writing anything\n * — a rejected schema, an unparsable body, a body over the limit — are\n * derived from what the route declares and from the options the\n * application actually runs with.\n *\n * @module\n */\n\nimport type {\n AnySchema,\n AppOptions,\n BodyType,\n RouteTableEntry,\n} from \"@tetsujs/core\";\nimport { errorBody } from \"@tetsujs/core\";\nimport type {\n DocumentedResponse,\n HookContributions,\n SecurityRequirement,\n} from \"./annotations.ts\";\nimport { contributionsOf } from \"./annotations.ts\";\nimport type { SchemaComponents } from \"./components.ts\";\nimport { failureName } from \"./components.ts\";\nimport type {\n ContentMap,\n HeaderObject,\n OperationObject,\n ResponseObject,\n} from \"./document.ts\";\nimport type { JsonSchemaObject } from \"./emit.ts\";\nimport { emitted } from \"./emit.ts\";\nimport type { Envelopes } from \"./envelopes.ts\";\nimport { branchesOf } from \"./envelopes.ts\";\nimport type { JsonSchema } from \"./json-schema.ts\";\nimport { partParameters, pathParameters } from \"./parameters.ts\";\n\n/** Describes one route. */\nexport function operationOf(\n entry: RouteTableEntry,\n options: AppOptions,\n components: SchemaComponents,\n envelopes: Envelopes,\n ids: OperationIds,\n warn: (message: string) => void,\n): OperationObject {\n const schema = entry.def.schema;\n\n const parameters = [\n ...pathParameters(entry.path, schema?.params, warn),\n ...partParameters(schema?.query, \"query\", warn),\n ...partParameters(schema?.headers, \"header\", warn),\n ...partParameters(schema?.cookies, \"cookie\", warn),\n ];\n\n const body = requestBody(entry, warn);\n const contributed = contributionsOf(entry.hooks, warn);\n\n return {\n operationId: ids.take(entry),\n ...(entry.def.docs?.summary === undefined\n ? {}\n : { summary: entry.def.docs.summary }),\n ...(entry.def.docs?.description === undefined\n ? {}\n : { description: entry.def.docs.description }),\n ...(entry.def.docs?.tags === undefined\n ? {}\n : { tags: entry.def.docs.tags }),\n ...(entry.def.docs?.deprecated === undefined\n ? {}\n : { deprecated: entry.def.docs.deprecated }),\n ...(parameters.length > 0 ? { parameters } : {}),\n ...(body ? { requestBody: body } : {}),\n ...(contributed.security.length > 0\n ? { security: securityOf(contributed.conditions) }\n : {}),\n responses: responses(\n entry,\n options,\n contributed,\n components,\n envelopes,\n warn,\n ),\n };\n}\n\n/**\n * Records the envelopes a route declares, so that its definitions are the\n * ones the document keeps — whichever operation refers to them first.\n *\n * Runs before any operation is built. A schema that cannot describe itself\n * is skipped without a word: building the operation says so, once.\n */\nexport function declareEnvelopes(\n entry: RouteTableEntry,\n envelopes: Envelopes,\n): void {\n for (const [status, schema] of declaredResponses(entry)) {\n const described =\n schema === null ? undefined : emitted(schema, \"\", () => {});\n\n const code = envelopes.format.code;\n\n for (const branch of described ? branchesOf(described, code) : []) {\n const found = code(branch);\n\n if (found !== undefined) {\n envelopes.declare(Number(status), found, branch);\n }\n }\n }\n}\n\n/** The route's response map as pairs; a single schema is its `200`. */\nfunction declaredResponses(\n entry: RouteTableEntry,\n): [status: string, schema: AnySchema | null][] {\n const response = entry.def.schema?.response;\n\n if (!response) {\n return [];\n }\n\n if (\"~standard\" in response) {\n return [[\"200\", response as AnySchema]];\n }\n\n return Object.entries(response) as [string, AnySchema | null][];\n}\n\n/**\n * A described body as the alternatives the document lists: every envelope\n * in it a reference to the one definition of its status and code, and a\n * union taken apart into its branches, so that it joins the other answers\n * of its status rather than nesting inside them.\n */\nfunction branchesFor(\n schema: JsonSchemaObject,\n status: number,\n envelopes: Envelopes,\n warn: (message: string) => void,\n): Record<string, unknown>[] {\n return branchesOf(schema, envelopes.format.code).map((branch) => {\n const code = envelopes.format.code(branch);\n\n return code === undefined\n ? branch\n : (envelopes.ref(status, code, branch, warn) as unknown as Record<\n string,\n unknown\n >);\n });\n}\n\n/**\n * The security a route asks for, as OpenAPI spells it.\n *\n * OpenAPI reads the entries of an operation's `security` as alternatives —\n * any one of them authorizes a request — and the schemes inside one entry\n * as all required. A route's conditions are the other way round: every\n * hook runs, so every condition is required, and a condition is satisfied\n * by any one of its alternatives. The entries are therefore the\n * combinations — one alternative from each condition, taken together:\n * a hook accepting a cookie *or* a token, next to a CSRF check, is\n * `[{ cookie, csrf }, { token, csrf }]`. With no alternatives anywhere\n * that is a single entry holding every scheme, which is the usual case.\n *\n * Two alternatives of one scheme in a combination ask for the scopes of\n * both; a combination that comes out twice is listed once.\n */\nfunction securityOf(\n conditions: readonly (readonly SecurityRequirement[])[],\n): Record<string, readonly string[]>[] {\n let combinations: Record<string, readonly string[]>[] = [{}];\n\n for (const alternatives of conditions) {\n combinations = combinations.flatMap((combination) =>\n alternatives.map((requirement) => ({\n ...combination,\n [requirement.name]: joined(\n combination[requirement.name],\n requirement.scopes,\n ),\n })),\n );\n }\n\n const seen = new Set<string>();\n\n return combinations.filter((combination) => {\n const key = JSON.stringify(\n Object.entries(combination)\n .map(([name, scopes]) => [name, [...scopes].sort()])\n .sort(),\n );\n\n if (seen.has(key)) {\n return false;\n }\n\n seen.add(key);\n\n return true;\n });\n}\n\n/** The scopes of a scheme already in a combination, and another's. */\nfunction joined(\n present: readonly string[] | undefined,\n added: readonly string[] | undefined,\n): readonly string[] {\n const scopes = [...(present ?? [])];\n\n for (const scope of added ?? []) {\n if (!scopes.includes(scope)) {\n scopes.push(scope);\n }\n }\n\n return scopes;\n}\n\n/**\n * Hands out the `operationId` of every route in one document.\n *\n * An `operationId` is a contract: a generated client names its methods\n * after them, so an id that moves breaks code nobody reviewing the change\n * sees. The id is therefore always stated or derived from names the\n * author wrote — never from where a route happened to land:\n *\n * | | |\n * | --- | --- |\n * | `docs.operationId` on the route | taken as written |\n * | a route of a named controller | the name and the field — `authRequestCode` |\n * | a route of an unnamed object | the field — `requestCode` |\n * | a route mounted standalone | its method and path — `postAuthCode` |\n *\n * Two routes arriving at one id is an error, not something to route\n * around. Falling back to the method and path, or numbering the second\n * one, would hand one of them an id that changes when a path is edited or\n * a route is added — silently, in someone else's SDK. The error names\n * both routes and the two ways out: a controller name of its own, or an\n * id stated on the route. The core already refuses two controllers of\n * one name; what reaches this is two stated ids, or a stated id meeting a\n * derived one.\n */\nexport interface OperationIds {\n /** The id for this route, unique within the document being built. */\n take(entry: RouteTableEntry): string;\n}\n\nexport function operationIds(): OperationIds {\n const taken = new Map<string, RouteTableEntry>();\n\n return {\n take(entry: RouteTableEntry): string {\n const id = idOf(entry);\n const holder = taken.get(id);\n\n if (holder !== undefined) {\n throw new Error(\n `operationId \"${id}\" is taken by both ${describe(holder)} and ${describe(entry)} — a generated client would get one method for two operations. Give one of them docs.operationId, or its controller a name of its own.`,\n );\n }\n\n taken.set(id, entry);\n\n return id;\n },\n };\n}\n\n/** The id a route asks for, before anything checks it is free. */\nfunction idOf(entry: RouteTableEntry): string {\n const stated = entry.def.docs?.operationId;\n\n if (stated !== undefined) {\n return stated;\n }\n\n if (entry.name === undefined) {\n return derivedId(entry);\n }\n\n if (entry.controller === undefined) {\n return entry.name;\n }\n\n const controller = entry.controller.replace(/Controller$/, \"\");\n\n return `${lowerFirst(controller)}${capitalize(entry.name)}`;\n}\n\n/** How the error above names a route: the one line that finds it. */\nfunction describe(entry: RouteTableEntry): string {\n return `${entry.method} ${entry.path}`;\n}\n\n/**\n * What a route mounted standalone is named by: it has no field and no\n * controller, and its method and path are what it has.\n */\nfunction derivedId(entry: RouteTableEntry): string {\n return `${entry.method.toLowerCase()}${entry.path\n .split(/[/:*]/)\n .filter(Boolean)\n .map(capitalize)\n .join(\"\")}`;\n}\n\n/**\n * Describes the request body, when the route reads one.\n *\n * The media type follows the declaration, not a guess: `\"form\"` accepts\n * both multipart and urlencoded at runtime, so both are listed — unless\n * the schema declares a binary field, which only multipart can carry.\n */\nfunction requestBody(\n entry: RouteTableEntry,\n warn: (message: string) => void,\n): { required: boolean; content: ContentMap } | undefined {\n const declared = entry.def.schema?.body;\n const bodyType = entry.def.bodyType ?? (declared ? \"json\" : undefined);\n\n if (!bodyType) {\n return undefined;\n }\n\n const described = declared\n ? emitted(declared, \"the body\", warn, \"input\")\n : undefined;\n\n const schema = described ? { schema: described } : {};\n\n // Whether a body must be sent is a question about the wire, not about\n // the schema: `json` and `form` parse it before anything is validated,\n // and an empty one fails that parse with a `400` — so the client has to\n // send something whether or not a shape was declared. `text` has no such\n // step, because an absent body reads as `\"\"` just like an empty one; if\n // that string is unacceptable, the schema is where it says so. Neither\n // has `stream`: an absent body is handed over as an empty stream.\n const required = bodyType !== \"text\" && bodyType !== \"stream\";\n\n if (bodyType === \"stream\") {\n /**\n * Bytes with no shape to describe: the route takes the body unread, so\n * the document says what it is rather than what is in it. A `stream`\n * route cannot carry a body schema at all — the compiler refuses the\n * pair — so there is never a `schema` to attach here.\n */\n return { required, content: { \"application/octet-stream\": {} } };\n }\n\n if (bodyType === \"text\") {\n return { required, content: { \"text/plain\": schema } };\n }\n\n if (bodyType === \"json\") {\n return { required, content: { \"application/json\": schema } };\n }\n\n const content: ContentMap = { \"multipart/form-data\": schema };\n\n if (!described || !carriesBinary(described)) {\n content[\"application/x-www-form-urlencoded\"] = schema;\n }\n\n return { required, content };\n}\n\n/**\n * Whether any part of an emitted schema describes binary content.\n *\n * Walked with a stack rather than by recursion, and remembering what it has\n * already seen: the shape comes from an adapter, so its depth is the\n * author's to choose and nothing says it is a tree. Recursion would answer\n * a deep one by overflowing the stack, and a self-referential one by never\n * returning — both while `createApp` is still assembling the application.\n */\nfunction carriesBinary(root: unknown): boolean {\n const pending: unknown[] = [root];\n const seen = new Set<unknown>();\n\n while (pending.length > 0) {\n const node = pending.pop();\n\n if (node === null || typeof node !== \"object\" || seen.has(node)) {\n continue;\n }\n\n seen.add(node);\n\n if ((node as { contentEncoding?: unknown }).contentEncoding === \"binary\") {\n return true;\n }\n\n for (const value of Object.values(node)) {\n pending.push(value);\n }\n }\n\n return false;\n}\n\n/**\n * Describes what the route answers with.\n *\n * The declared responses come first; the framework's own failures fill in\n * around them, and never over them — an author who documented `422`\n * himself has said something more specific than this could.\n */\nfunction responses(\n entry: RouteTableEntry,\n options: AppOptions,\n contributed: HookContributions,\n components: SchemaComponents,\n envelopes: Envelopes,\n warn: (message: string) => void,\n): Record<string, ResponseObject> {\n const answers = new Map<string, Answer[]>();\n\n const add = (status: string, answer: Answer): void => {\n answers.set(status, [...(answers.get(status) ?? []), answer]);\n };\n\n for (const [status, schema] of declaredResponses(entry)) {\n const described =\n schema === null ? undefined : emitted(schema, \"a response\", warn);\n\n add(status, {\n placeholder: describeStatus(status),\n said: described ? wordsOf(described, envelopes) : [],\n schemas: described\n ? branchesFor(unionOnly(described), Number(status), envelopes, warn)\n : [],\n });\n }\n\n if (![...answers.keys()].some((status) => status.startsWith(\"2\"))) {\n add(\"200\", { placeholder: \"Successful response\", said: [], schemas: [] });\n }\n\n for (const [status, answer] of failures(\n entry,\n options,\n contributed,\n components,\n envelopes,\n warn,\n )) {\n add(String(status), answer);\n }\n\n const described: Record<string, ResponseObject> = {};\n\n for (const [status, list] of answers) {\n described[status] = merge(list, envelopes);\n }\n\n return described;\n}\n\n/**\n * Everything the route can answer with that its own schema does not say:\n * what its hooks declare, and what the framework itself answers.\n */\nfunction failures(\n entry: RouteTableEntry,\n options: AppOptions,\n contributed: HookContributions,\n components: SchemaComponents,\n envelopes: Envelopes,\n warn: (message: string) => void,\n): [status: number, answer: Answer][] {\n const schema = entry.def.schema;\n const found: [number, Answer][] = [];\n\n /**\n * Refers to the definition of one failure: the one of its status and\n * code, or — for a failure whose code only the hook knows and did not\n * declare — one of its own, named after the status.\n */\n const envelopeRef = (\n status: number,\n error?: string,\n message?: string,\n fields?: DocumentedResponse[\"fields\"],\n ): Record<string, unknown> => {\n const described = envelopes.format.describe({\n status,\n ...(error === undefined ? {} : { error }),\n ...(message === undefined ? {} : { message }),\n fields: fields ?? {},\n });\n\n const ref =\n error === undefined\n ? components.ref(failureName(status), described)\n : envelopes.ref(status, error, described, warn);\n\n return ref as unknown as Record<string, unknown>;\n };\n\n if (schema?.params || schema?.query || schema?.headers || schema?.body) {\n found.push([\n options.validationStatus,\n {\n said: [\n {\n code: \"VALIDATION_FAILED\",\n text: \"Request failed schema validation\",\n },\n ],\n schemas: [\n envelopes.ref(\n options.validationStatus,\n \"VALIDATION_FAILED\",\n envelopes.format.describe({\n status: options.validationStatus,\n error: \"VALIDATION_FAILED\",\n message: \"Validation failed\",\n fields: { issues },\n }),\n warn,\n ) as unknown as Record<string, unknown>,\n ],\n },\n ]);\n }\n\n for (const requirement of contributed.security) {\n const status = requirement.status ?? 401;\n\n found.push([\n status,\n {\n said: [\n said(\n requirement.error,\n requirement.description ??\n `Request did not satisfy ${requirement.name}`,\n ),\n ],\n schemas: [envelopeRef(status, requirement.error, requirement.message)],\n },\n ]);\n }\n\n for (const response of contributed.responses) {\n const described = response.schema\n ? emitted(response.schema, \"a hook's response\", warn)\n : undefined;\n\n found.push([\n response.status,\n {\n said: [said(response.error, response.description)],\n schemas: described\n ? branchesFor(described, response.status, envelopes, warn)\n : [\n envelopeRef(\n response.status,\n response.error,\n response.message,\n response.fields,\n ),\n ],\n ...(response.headers ? { headers: response.headers } : {}),\n },\n ]);\n }\n\n if (schema?.body || entry.def.bodyType) {\n const unparsable = parseFailure(entry.def.bodyType);\n\n if (unparsable) {\n found.push([\n 400,\n {\n said: [\n said(\n unparsable.error,\n \"Body could not be parsed in the declared shape\",\n ),\n ],\n schemas: [envelopeRef(400, unparsable.error, unparsable.message)],\n },\n ]);\n }\n\n found.push([\n 413,\n {\n said: [\n said(\"BODY_TOO_LARGE\", \"Body exceeded the configured size limit\"),\n ],\n schemas: [\n envelopeRef(\n 413,\n \"BODY_TOO_LARGE\",\n \"Body exceeds the configured limit\",\n ),\n ],\n },\n ]);\n }\n\n found.push([\n 500,\n {\n said: [\n said(\n \"INTERNAL_SERVER_ERROR\",\n \"The request failed and nothing mapped the failure\",\n ),\n ],\n schemas: [\n envelopeRef(500, \"INTERNAL_SERVER_ERROR\", \"Internal Server Error\"),\n ],\n },\n ]);\n\n return found;\n}\n\n/**\n * One way a route can answer with a status: what the route declared, what\n * a hook declared, or what the framework answers by itself.\n *\n * `schemas` are the alternatives of the body, each envelope already a\n * reference to its definition; empty when the answer has no body to\n * describe.\n *\n * `said` is what the answer says about itself, with the code each part is\n * about when it is known: a hook's description, the framework's, what a\n * route's schema says. A route whose schema says nothing has only its\n * `placeholder` — the reason phrase — which stands for the status when\n * nothing else describes it.\n */\ninterface Answer {\n readonly said: readonly Said[];\n readonly placeholder?: string;\n readonly schemas: readonly Record<string, unknown>[];\n readonly headers?: Readonly<Record<string, HeaderObject>>;\n}\n\n/** One description, and the code it describes when that is known. */\ninterface Said {\n readonly code?: string;\n readonly text: string;\n}\n\nfunction said(code: string | undefined, text: string): Said {\n return code === undefined ? { text } : { code, text };\n}\n\n/**\n * What a route's schema says about the status it is declared for: its own\n * `description`, or — for a union that has none — each branch's, with the\n * branch's code. A schema that says nothing says nothing here either.\n */\nfunction wordsOf(schema: JsonSchemaObject, envelopes: Envelopes): Said[] {\n if (typeof schema.description === \"string\") {\n return [said(envelopes.format.code(schema), schema.description)];\n }\n\n return branchesOf(unionOnly(schema), envelopes.format.code).flatMap(\n (branch) =>\n typeof branch.description === \"string\"\n ? [said(envelopes.format.code(branch), branch.description)]\n : [],\n );\n}\n\n/**\n * A union without the `description` it carried as a whole — which says\n * what the status is, and is used as the status's description — so its\n * branches can join the status's own alternatives. Anything but a union\n * is kept as it is, its description included, for its definition.\n */\nfunction unionOnly(schema: JsonSchemaObject): JsonSchemaObject {\n if (\n typeof schema.description !== \"string\" ||\n (!Array.isArray(schema.anyOf) && !Array.isArray(schema.oneOf))\n ) {\n return schema;\n }\n\n const { description: _, ...union } = schema;\n\n return union;\n}\n\n/**\n * Folds everything that answers with one status into one response.\n *\n * Three things can meet on a status: what the route declared, and any\n * number of failures the framework fills in — a rejected schema and an\n * unparsable body collide on `400` as soon as an application configures\n * `validation: { status: 400 }`, and a route that answers `404` itself\n * shares that status with nothing while sharing `400` with the parser.\n *\n * All of them are true at once, so the document says so with an `anyOf`\n * rather than picking a winner. The route's own body comes first: it is\n * the answer the endpoint is about, and the failures are what can happen\n * to it. Identical bodies are folded together — a `$ref` repeated is one\n * alternative, not two.\n *\n * Headers are gathered the same way, the first description of a name\n * standing for all of them; descriptions as {@link wording} words them.\n */\nfunction merge(list: readonly Answer[], envelopes: Envelopes): ResponseObject {\n const schemas = distinct(list.flatMap((answer) => answer.schemas));\n const headers: Record<string, HeaderObject> = {};\n\n for (const answer of list) {\n for (const [name, header] of Object.entries(answer.headers ?? {})) {\n headers[name] ??= header;\n }\n }\n\n return {\n description: wording(list),\n ...(Object.keys(headers).length > 0 ? { headers } : {}),\n ...(schemas.length > 0\n ? {\n content: {\n \"application/json\": { schema: unionOf(schemas, envelopes) },\n },\n }\n : {}),\n };\n}\n\n/**\n * The description of a status, from everything that answers with it.\n *\n * One thing said is the description. Several are a list, each item led\n * by the code it is about, so a reader sees which description goes with\n * which code — descriptions are CommonMark, and every renderer draws the\n * list. The same code said the same way twice, by the route and a hook,\n * is one item. With nothing said at all, the route's placeholder stands.\n */\nfunction wording(list: readonly Answer[]): string {\n const seen = new Set<string>();\n const items: Said[] = [];\n\n for (const answer of list) {\n for (const item of answer.said) {\n const key = `${item.code ?? \"\"}\\n${item.text}`;\n\n if (!seen.has(key)) {\n seen.add(key);\n items.push(item);\n }\n }\n }\n\n const [only] = items;\n\n if (items.length === 1 && only) {\n return only.text;\n }\n\n if (items.length > 1) {\n return items\n .map((item) =>\n item.code === undefined\n ? `- ${item.text}`\n : `- \\`${item.code}\\`: ${item.text}`,\n )\n .join(\"\\n\");\n }\n\n return list.find((answer) => answer.placeholder)?.placeholder ?? \"\";\n}\n\n/**\n * The alternatives of a body as one schema.\n *\n * When every alternative is an envelope, each with its own code, the union\n * says so with a `discriminator` on `error`: a generated client then\n * builds a tagged union and narrows on the code, instead of trying the\n * shapes in turn. The mapping is spelled out, because without it OpenAPI\n * matches the value against the component's name — `Unauthorized`, where\n * the body says `UNAUTHORIZED`. The field is the error format's; a format\n * that names none — its code nested below the top — has no discriminator.\n */\nfunction unionOf(\n schemas: readonly Record<string, unknown>[],\n envelopes: Envelopes,\n): Record<string, unknown> {\n const [only] = schemas;\n\n if (schemas.length === 1 && only) {\n return only;\n }\n\n const propertyName = envelopes.format.discriminator;\n\n if (propertyName === undefined) {\n return { anyOf: schemas };\n }\n\n const mapping: Record<string, string> = {};\n\n for (const schema of schemas) {\n const ref = (schema as { $ref?: unknown }).$ref;\n const code = typeof ref === \"string\" ? envelopes.codeOf(ref) : undefined;\n\n if (typeof ref !== \"string\" || code === undefined) {\n return { anyOf: schemas };\n }\n\n mapping[code] = ref;\n }\n\n return {\n anyOf: schemas,\n discriminator: { propertyName, mapping },\n };\n}\n\nfunction distinct(\n schemas: readonly Record<string, unknown>[],\n): Record<string, unknown>[] {\n const seen = new Set<string>();\n\n return schemas.filter((schema) => {\n const fingerprint = JSON.stringify(schema);\n\n if (seen.has(fingerprint)) {\n return false;\n }\n\n seen.add(fingerprint);\n\n return true;\n });\n}\n\nfunction describeStatus(status: string): string {\n if (status === \"204\") {\n return \"No content\";\n }\n\n return status.startsWith(\"2\")\n ? \"Successful response\"\n : errorBody(Number(status)).message;\n}\n\n/**\n * What a validation failure carries besides the code and the message: every\n * issue, with where it is. Handed to the error format as a field, for the\n * format to place.\n */\nconst issues: JsonSchema = {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"message\", \"path\"],\n properties: {\n message: { type: \"string\" },\n path: { type: \"array\", items: { type: [\"string\", \"number\"] } },\n },\n },\n};\n\n/**\n * How a body of this type fails to parse — or nothing, for a text or a\n * stream body: one is whatever bytes arrived, the other is handed over\n * unread, and neither can be malformed.\n */\nfunction parseFailure(\n bodyType: BodyType | undefined,\n): { error: string; message: string } | undefined {\n if (bodyType === \"text\" || bodyType === \"stream\") {\n return undefined;\n }\n\n return bodyType === \"form\"\n ? { error: \"MALFORMED_FORM\", message: \"Body is not a valid form\" }\n : { error: \"MALFORMED_JSON\", message: \"Body is not valid JSON\" };\n}\n\nfunction capitalize(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction lowerFirst(value: string): string {\n return value.charAt(0).toLowerCase() + value.slice(1);\n}\n",
10
10
  "/**\n * Asking a schema to describe itself, without letting it stop the document.\n *\n * Internal to the package.\n *\n * @module\n */\n\nimport { toJsonSchema } from \"@tetsujs/core\";\n\n/**\n * The JSON Schema dialect a schema is asked for.\n *\n * OpenAPI 3.1 takes JSON Schema 2020-12 as it is, and `draft-2020-12` is a\n * target the Standard JSON Schema specification names — so every library\n * that implements it answers. This used to be `openapi-3.1`, which only\n * Zod accepts: ArkType and Valibot refused it, and their bodies went into\n * the document without a shape and with a warning each.\n */\nconst target = { target: \"draft-2020-12\" } as const;\n\n/**\n * A JSON Schema as the generator reads it: any keyword, with the ones it\n * looks into named, so reading them does not depend on the reader's\n * `noPropertyAccessFromIndexSignature`.\n */\nexport interface JsonSchemaObject {\n properties?: unknown;\n required?: unknown;\n anyOf?: unknown;\n oneOf?: unknown;\n description?: unknown;\n [keyword: string]: unknown;\n}\n\n/** Which shape of a schema to describe: what arrives, or what leaves. */\ntype Direction = \"input\" | \"output\";\n\n/**\n * The JSON Schema of a declaration, or `undefined` and a warning saying why.\n *\n * A schema can fail to describe itself in two ways, and the generator owes\n * the same answer to both: an adapter without JSON Schema support returns\n * nothing, and an adapter that has it can still throw — a converter meeting\n * a shape it cannot express, a structure too deep to walk, a `$ref` that\n * leads back to where it started.\n *\n * Only the first was handled, and the difference between them is not the\n * document: it is whether the application starts at all. `docs()` builds\n * the document from `onMount`, which `createApp` calls while it is still\n * assembling itself, so an escaping error is not a gap in a description —\n * it is a server that never listens, over a route that would have worked.\n *\n * `subject` names the declaration for the message, as the reader of a\n * warning would name it: `\"the body\"`, `\"a response\"`.\n */\nexport function emitted(\n schema: unknown,\n subject: string,\n warn: (message: string) => void,\n direction: Direction = \"output\",\n): JsonSchemaObject | undefined {\n let described: JsonSchemaObject | undefined;\n\n try {\n described = toJsonSchema(schema, target, direction);\n } catch (error) {\n warn(`${subject} schema failed to emit JSON Schema: ${reason(error)}`);\n\n return undefined;\n }\n\n if (!described) {\n warn(`${subject} schema does not emit JSON Schema`);\n\n return undefined;\n }\n\n return withoutDialect(described);\n}\n\n/**\n * A schema as the document embeds it: without its own `$schema`.\n *\n * Asked for draft 2020-12, Zod and ArkType name the dialect at the root of\n * every schema they emit. The document declares it once for all of them,\n * and the same line on every body and response is noise.\n */\nfunction withoutDialect(schema: JsonSchemaObject): JsonSchemaObject {\n if (!(\"$schema\" in schema)) {\n return schema;\n }\n\n const { $schema: _, ...rest } = schema;\n\n return rest;\n}\n\nfunction reason(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n",
11
11
  "/**\n * Path templates and request parameters.\n *\n * The framework's path syntax is Bun's — `:param` and a trailing `*` —\n * while OpenAPI templates variables as `{param}`. The conversion happens\n * here, together with the parameter objects the template then requires:\n * OpenAPI demands that every variable in a path be declared.\n *\n * @module\n */\n\nimport type { AnySchema } from \"@tetsujs/core\";\nimport type { ParameterObject } from \"./document.ts\";\nimport { emitted } from \"./emit.ts\";\n\n/** The name a wildcard segment is documented under. */\nexport const wildcardName = \"wildcard\";\n\n/**\n * Rewrites a route path as an OpenAPI path template.\n *\n * A wildcard becomes an ordinary variable: OpenAPI has no syntax for\n * \"everything below here\", so the closest honest template is a named\n * segment, documented as such.\n */\nexport function toTemplate(path: string): string {\n return path\n .split(\"/\")\n .map((segment) => {\n if (segment.startsWith(\":\")) {\n return `{${segment.slice(1)}}`;\n }\n\n return segment === \"*\" ? `{${wildcardName}}` : segment;\n })\n .join(\"/\");\n}\n\n/** The variables a path template declares, in order. */\nexport function templateNames(path: string): string[] {\n const names: string[] = [];\n\n for (const segment of path.split(\"/\")) {\n if (segment.startsWith(\":\")) {\n names.push(segment.slice(1));\n } else if (segment === \"*\") {\n names.push(wildcardName);\n }\n }\n\n return names;\n}\n\n/**\n * Describes the path parameters of a route.\n *\n * A `params` schema describes the whole object, so each variable takes the\n * property of the same name; without one — or without a property for a\n * given variable — the value is what the router captured: a string.\n */\nexport function pathParameters(\n path: string,\n schema: AnySchema | undefined,\n warn: (message: string) => void,\n): ParameterObject[] {\n const properties = objectProperties(schema, \"params\", warn);\n\n return templateNames(path).map((name) => ({\n name,\n in: \"path\" as const,\n required: true,\n ...(name === wildcardName\n ? {\n description:\n \"Matches the rest of the path, including further segments.\",\n }\n : {}),\n schema: properties[name] ?? { type: \"string\" },\n }));\n}\n\n/**\n * Describes the query, header or cookie parameters of a route.\n *\n * All three are objects at the schema level and lists of parameters in a\n * document, so each declared property becomes one parameter, required when\n * the schema says so.\n *\n * A session cookie is the exception the specification makes itself: a\n * credential belongs in `securitySchemes` as `apiKey in: cookie`, not\n * among the parameters. Nothing here can tell one cookie from the other —\n * that is what an annotation on the hook reading it is for, the same way\n * `secured()` marks an authenticating hook.\n */\nexport function partParameters(\n schema: AnySchema | undefined,\n where: \"query\" | \"header\" | \"cookie\",\n warn: (message: string) => void,\n): ParameterObject[] {\n if (!schema) {\n return [];\n }\n\n const described = emitted(schema, `the ${where}`, warn, \"input\");\n\n if (!described) {\n return [];\n }\n\n const properties = (described.properties ?? {}) as Record<\n string,\n Record<string, unknown>\n >;\n const required = new Set(\n Array.isArray(described.required) ? (described.required as string[]) : [],\n );\n\n return Object.entries(properties).map(([name, property]) => ({\n name,\n in: where,\n required: required.has(name),\n schema: property,\n }));\n}\n\nfunction objectProperties(\n schema: AnySchema | undefined,\n where: string,\n warn: (message: string) => void,\n): Record<string, Record<string, unknown>> {\n if (!schema) {\n return {};\n }\n\n const described = emitted(schema, `the ${where}`, warn, \"input\");\n\n if (!described) {\n return {};\n }\n\n return (described.properties ?? {}) as Record<\n string,\n Record<string, unknown>\n >;\n}\n",
12
- "/**\n * The documentation endpoints as a mountable controller.\n *\n * `openapi()` returns data and mounts nothing, which is the right default\n * for a generator but a chore in the ordinary case: every application ends\n * up writing the same controller, holding the same application, to serve\n * the same two routes. {@link docs} is that controller, written once.\n *\n * It is a controller like any other — mounted in `routes`, groupable,\n * hookable — that receives the application through `onMount` and generates\n * the document from it at startup.\n *\n * @module\n */\n\nimport type { App, RouteDef, SchemaConfig, ValidatePath } from \"@tetsujs/core\";\nimport { onMount, route } from \"@tetsujs/core\";\nimport type { OpenApiDocument } from \"./document.ts\";\nimport type { ErrorFormat } from \"./errors.ts\";\nimport type { GeneratorWarning } from \"./index.ts\";\nimport { openapi } from \"./index.ts\";\nimport type { DocsAssets, DocsUi } from \"./page.ts\";\nimport { docsPage } from \"./page.ts\";\n\n/** What the documentation controller serves, and from where. */\nexport interface DocsOptions<\n Path extends string,\n UiPath extends string,\n Ui extends DocsUi | false = DocsUi | false,\n> {\n /** Title, version and the rest of the document's `info` block. */\n readonly info: OpenApiDocument[\"info\"];\n\n /** Servers the API is reachable at. */\n readonly servers?: OpenApiDocument[\"servers\"];\n\n /**\n * How the application's errors look, when not like the framework's\n * envelope — see `errors` on {@link openapi}.\n */\n readonly errors?: ErrorFormat;\n\n /** Where the document is served. Defaults to `/openapi.json`. */\n readonly path?: Path & ValidatePath<Path>;\n\n /** Where the page is served. Defaults to `/docs`. */\n readonly uiPath?: UiPath & ValidatePath<UiPath>;\n\n /**\n * Which renderer the page bootstraps. Defaults to `\"scalar\"`.\n *\n * `false` serves the document without a page — what production wants\n * on an origin that carries a session. The page runs its renderer on the\n * application's origin, so a renderer that is not what it should be acts\n * in the signed-in user's name there; the document alone runs nothing.\n * `uiPath`, `title` and `assets` are then unused.\n */\n readonly ui?: Ui;\n\n /** Browser title of the page. Defaults to the document's own title. */\n readonly title?: string;\n\n /** Overrides the renderer's CDN URLs, for a pinned or self-hosted copy. */\n readonly assets?: DocsAssets;\n\n /**\n * Documents the two endpoints this controller serves.\n *\n * Off by default: a reader who is looking at the document has already\n * found the document, and an operation for \"the page you are reading\"\n * is one a generated client would happily produce a method for.\n */\n readonly documentSelf?: boolean;\n\n /**\n * What to do with what the generator could not describe.\n *\n * Defaults to one `console.warn` per warning, at startup — a document\n * that silently omits a body is worse than a noisy one.\n */\n readonly onWarning?: (warning: GeneratorWarning) => void;\n}\n\n/**\n * The controller {@link docs} returns: two routes and the `onMount` that\n * fills them.\n *\n * Instantiated through the factory, never directly — the routes carry the\n * configured paths in their types, which only the factory can infer.\n */\nexport class DocsController<\n Path extends string,\n UiPath extends string,\n Page extends boolean = true,\n> {\n /** The document itself, as `application/json`. */\n readonly json: RouteDef<Path, SchemaConfig, never, undefined, \"GET\">;\n\n /** The page that renders it — none with `ui: false`. */\n readonly ui: Page extends true\n ? RouteDef<UiPath, SchemaConfig, never, undefined, \"GET\">\n : undefined;\n\n private document: OpenApiDocument | undefined;\n\n private page: string | undefined;\n\n constructor(\n private readonly options: DocsOptions<Path, UiPath>,\n documentPath: string,\n uiPath: string,\n ) {\n const hidden = !options.documentSelf;\n\n const json = route({\n method: \"GET\",\n path: \"/openapi.json\",\n docs: { summary: \"This document\", tags: [\"docs\"], hidden },\n handler: () => this.document,\n });\n\n const ui = route({\n method: \"GET\",\n path: \"/docs\",\n docs: { summary: \"Rendered documentation\", tags: [\"docs\"], hidden },\n handler: () =>\n new Response(this.page, {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n }),\n });\n\n /**\n * The configured paths, put back on the routes.\n *\n * `route()` validates its path at the type level, and that check\n * cannot be satisfied by a type variable — `ValidatePath<Path>` stays\n * unresolved while `Path` is generic. The routes are therefore built\n * with the default literals and re-typed here, which is also where the\n * configured path lands at runtime.\n */\n this.json = { ...json, path: documentPath } as unknown as this[\"json\"];\n this.ui = (\n options.ui === false ? undefined : { ...ui, path: uiPath }\n ) as this[\"ui\"];\n }\n\n /**\n * Generates the document of the application this was mounted in, and\n * the page that renders it.\n *\n * The page is built here rather than with the routes because only the\n * application knows where the document ended up: a group this controller\n * is mounted under prefixes its path, and a page pointing at the path as\n * configured would fetch a `404`.\n */\n [onMount](app: App): void {\n const generated = openapi(app, {\n info: this.options.info,\n ...(this.options.servers ? { servers: this.options.servers } : {}),\n ...(this.options.errors ? { errors: this.options.errors } : {}),\n });\n\n this.document = generated.document;\n\n const ui = this.options.ui ?? \"scalar\";\n const json: unknown = this.json;\n const served = app.entries.find((entry) => entry.def === json);\n\n if (ui !== false && served) {\n this.page = docsPage({\n ui,\n documentUrl: served.path,\n title: this.options.title ?? this.options.info.title,\n ...(this.options.assets ? { assets: this.options.assets } : {}),\n });\n }\n\n const report = this.options.onWarning ?? warn;\n\n for (const warning of generated.warnings) {\n report(warning);\n }\n }\n}\n\n/**\n * The documentation of an application, as a controller to mount.\n *\n * @example\n * ```ts\n * createApp({\n * routes: [\n * group(\"/api\", { children: [usersController({ users })] }),\n * docs({ info: { title: \"Users API\", version: \"1.0.0\" } }),\n * ],\n * });\n * ```\n *\n * The document is generated once, at startup, from the application the\n * controller was mounted in. Its own two routes stay out of it — pass\n * `documentSelf` to put them in.\n *\n * The page loads its renderer from a CDN; see {@link docsPage} for the\n * trade and for how to point it at a self-hosted copy.\n */\nexport function docs<\n const Path extends string = \"/openapi.json\",\n const UiPath extends string = \"/docs\",\n const Ui extends DocsUi | false = \"scalar\",\n>(\n options: DocsOptions<Path, UiPath, Ui>,\n): DocsController<Path, UiPath, Ui extends false ? false : true> {\n return new DocsController(\n options,\n options.path ?? \"/openapi.json\",\n options.uiPath ?? \"/docs\",\n ) as DocsController<Path, UiPath, Ui extends false ? false : true>;\n}\n\nfunction warn(warning: GeneratorWarning): void {\n console.warn(`[openapi] ${warning.route}: ${warning.message}`);\n}\n",
12
+ "/**\n * The documentation endpoints as a mountable controller.\n *\n * `openapi()` returns data and mounts nothing, which is the right default\n * for a generator but a chore in the ordinary case: every application ends\n * up writing the same controller, holding the same application, to serve\n * the same two routes. {@link docs} is that controller, written once.\n *\n * It is a controller like any other — mounted in `routes`, groupable,\n * hookable — that receives the application through `onMount` and generates\n * the document from it at startup.\n *\n * @module\n */\n\nimport type { App, RouteDef, SchemaConfig, ValidatePath } from \"@tetsujs/core\";\nimport { onMount, route } from \"@tetsujs/core\";\nimport type { OpenApiDocument } from \"./document.ts\";\nimport type { ErrorFormat } from \"./errors.ts\";\nimport type { GeneratorWarning } from \"./index.ts\";\nimport { openapi } from \"./index.ts\";\nimport type { DocsAssets, DocsUi } from \"./page.ts\";\nimport { docsPage } from \"./page.ts\";\n\n/** What the documentation controller serves, and from where. */\nexport interface DocsOptions<\n Path extends string,\n UiPath extends string,\n Ui extends DocsUi | false = DocsUi | false,\n> {\n /** Title, version and the rest of the document's `info` block. */\n readonly info: OpenApiDocument[\"info\"];\n\n /** Servers the API is reachable at. */\n readonly servers?: OpenApiDocument[\"servers\"];\n\n /**\n * How the application's errors look, when not like the framework's\n * envelope — see `errors` on {@link openapi}.\n */\n readonly errors?: ErrorFormat;\n\n /**\n * What each tag is — see `tags` on {@link openapi}. The controller's own\n * tag, `docs`, is described for you when its routes are in the document\n * (`documentSelf`) and you did not describe it.\n */\n readonly tags?: Readonly<Record<string, string>>;\n\n /** Where the document is served. Defaults to `/openapi.json`. */\n readonly path?: Path & ValidatePath<Path>;\n\n /** Where the page is served. Defaults to `/docs`. */\n readonly uiPath?: UiPath & ValidatePath<UiPath>;\n\n /**\n * Which renderer the page bootstraps. Defaults to `\"scalar\"`.\n *\n * `false` serves the document without a page — what production wants\n * on an origin that carries a session. The page runs its renderer on the\n * application's origin, so a renderer that is not what it should be acts\n * in the signed-in user's name there; the document alone runs nothing.\n * `uiPath`, `title` and `assets` are then unused.\n */\n readonly ui?: Ui;\n\n /** Browser title of the page. Defaults to the document's own title. */\n readonly title?: string;\n\n /** Overrides the renderer's CDN URLs, for a pinned or self-hosted copy. */\n readonly assets?: DocsAssets;\n\n /**\n * Documents the two endpoints this controller serves.\n *\n * Off by default: a reader who is looking at the document has already\n * found the document, and an operation for \"the page you are reading\"\n * is one a generated client would happily produce a method for.\n */\n readonly documentSelf?: boolean;\n\n /**\n * What to do with what the generator could not describe.\n *\n * Defaults to one `console.warn` per warning, at startup — a document\n * that silently omits a body is worse than a noisy one.\n */\n readonly onWarning?: (warning: GeneratorWarning) => void;\n}\n\n/**\n * The controller {@link docs} returns: two routes and the `onMount` that\n * fills them.\n *\n * Instantiated through the factory, never directly — the routes carry the\n * configured paths in their types, which only the factory can infer.\n */\nexport class DocsController<\n Path extends string,\n UiPath extends string,\n Page extends boolean = true,\n> {\n /** The document itself, as `application/json`. */\n readonly json: RouteDef<Path, SchemaConfig, never, undefined, \"GET\">;\n\n /** The page that renders it — none with `ui: false`. */\n readonly ui: Page extends true\n ? RouteDef<UiPath, SchemaConfig, never, undefined, \"GET\">\n : undefined;\n\n private document: OpenApiDocument | undefined;\n\n private page: string | undefined;\n\n constructor(\n private readonly options: DocsOptions<Path, UiPath>,\n documentPath: string,\n uiPath: string,\n ) {\n const hidden = !options.documentSelf;\n\n const json = route({\n method: \"GET\",\n path: \"/openapi.json\",\n docs: { summary: \"This document\", tags: [\"docs\"], hidden },\n handler: () => this.document,\n });\n\n const ui = route({\n method: \"GET\",\n path: \"/docs\",\n docs: { summary: \"Rendered documentation\", tags: [\"docs\"], hidden },\n handler: () =>\n new Response(this.page, {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n }),\n });\n\n /**\n * The configured paths, put back on the routes.\n *\n * `route()` validates its path at the type level, and that check\n * cannot be satisfied by a type variable — `ValidatePath<Path>` stays\n * unresolved while `Path` is generic. The routes are therefore built\n * with the default literals and re-typed here, which is also where the\n * configured path lands at runtime.\n */\n this.json = { ...json, path: documentPath } as unknown as this[\"json\"];\n this.ui = (\n options.ui === false ? undefined : { ...ui, path: uiPath }\n ) as this[\"ui\"];\n }\n\n /**\n * The tags to describe: the application's, and this controller's own when\n * its routes are in the document — without it, a described set of tags\n * would report `docs` as a tag nobody described.\n */\n private tagsOf(\n tags: Readonly<Record<string, string>>,\n ): Readonly<Record<string, string>> {\n if (!this.options.documentSelf || Object.hasOwn(tags, \"docs\")) {\n return tags;\n }\n\n return { ...tags, docs: \"This documentation\" };\n }\n\n /**\n * Generates the document of the application this was mounted in, and\n * the page that renders it.\n *\n * The page is built here rather than with the routes because only the\n * application knows where the document ended up: a group this controller\n * is mounted under prefixes its path, and a page pointing at the path as\n * configured would fetch a `404`.\n */\n [onMount](app: App): void {\n const generated = openapi(app, {\n info: this.options.info,\n ...(this.options.servers ? { servers: this.options.servers } : {}),\n ...(this.options.errors ? { errors: this.options.errors } : {}),\n ...(this.options.tags ? { tags: this.tagsOf(this.options.tags) } : {}),\n });\n\n this.document = generated.document;\n\n const ui = this.options.ui ?? \"scalar\";\n const json: unknown = this.json;\n const served = app.entries.find((entry) => entry.def === json);\n\n if (ui !== false && served) {\n this.page = docsPage({\n ui,\n documentUrl: served.path,\n title: this.options.title ?? this.options.info.title,\n ...(this.options.assets ? { assets: this.options.assets } : {}),\n });\n }\n\n const report = this.options.onWarning ?? warn;\n\n for (const warning of generated.warnings) {\n report(warning);\n }\n }\n}\n\n/**\n * The documentation of an application, as a controller to mount.\n *\n * @example\n * ```ts\n * createApp({\n * routes: [\n * group(\"/api\", { children: [usersController({ users })] }),\n * docs({ info: { title: \"Users API\", version: \"1.0.0\" } }),\n * ],\n * });\n * ```\n *\n * The document is generated once, at startup, from the application the\n * controller was mounted in. Its own two routes stay out of it — pass\n * `documentSelf` to put them in.\n *\n * The page loads its renderer from a CDN; see {@link docsPage} for the\n * trade and for how to point it at a self-hosted copy.\n */\nexport function docs<\n const Path extends string = \"/openapi.json\",\n const UiPath extends string = \"/docs\",\n const Ui extends DocsUi | false = \"scalar\",\n>(\n options: DocsOptions<Path, UiPath, Ui>,\n): DocsController<Path, UiPath, Ui extends false ? false : true> {\n return new DocsController(\n options,\n options.path ?? \"/openapi.json\",\n options.uiPath ?? \"/docs\",\n ) as DocsController<Path, UiPath, Ui extends false ? false : true>;\n}\n\nfunction warn(warning: GeneratorWarning): void {\n console.warn(\n warning.route === \"\"\n ? `[openapi] ${warning.message}`\n : `[openapi] ${warning.route}: ${warning.message}`,\n );\n}\n",
13
13
  "/**\n * The HTML page that renders a document.\n *\n * Returns a string and mounts nothing: which path serves the page, and\n * whether one is served at all, is the application's decision like every\n * other route.\n *\n * The renderers themselves are loaded from a CDN. Vendoring Scalar or\n * Swagger UI would put megabytes of somebody else's bundle into a\n * dependency-free repository, so the trade is stated instead of hidden:\n * the documentation page — and only it — needs the network, and the URL is\n * a parameter, so a self-hosted copy is one option away. Nothing is\n * fetched unless this function is called.\n *\n * What the CDN serves runs on the application's origin, with its cookies.\n * The default renderers are therefore pinned to an exact version and\n * carry the hash of that file: a CDN, or a package release, that serves\n * something else is refused by the browser rather than run. A page on an\n * origin with a session is still somebody else's application in the\n * user's session — which is why `docs()` can serve the document alone.\n *\n * @module\n */\n\n/** The renderers this package knows how to bootstrap. */\nexport type DocsUi = \"scalar\" | \"swagger-ui\" | \"redoc\";\n\n/** Where a renderer is loaded from. */\nexport interface DocsAssets {\n readonly script: string;\n readonly style?: string;\n\n /**\n * Subresource Integrity hashes of the two files, for a copy that is not\n * on the application's own origin: the browser runs the file only if it\n * hashes to this. Absent, the files are loaded as they are.\n *\n * One line computes one:\n * `curl -s <url> | openssl dgst -sha384 -binary | openssl base64 -A`,\n * prefixed with `sha384-`.\n */\n readonly integrity?: {\n readonly script?: string;\n readonly style?: string;\n };\n}\n\n/** What the page needs to know. */\nexport interface DocsPageOptions {\n /** Which renderer to bootstrap. */\n readonly ui: DocsUi;\n\n /** Where the document is served — the page fetches it from there. */\n readonly documentUrl: string;\n\n /** Browser title; defaults to `\"API documentation\"`. */\n readonly title?: string;\n\n /** Overrides the CDN URLs, for a pinned version or a self-hosted copy. */\n readonly assets?: DocsAssets;\n}\n\n/**\n * The renderers by default: an exact version, the file by its full path,\n * and the hash of that file.\n *\n * The full path because a bare package URL is not a file — jsDelivr\n * answers it with a build of its own, whose bytes differ from the file's.\n * Moving to a newer version means a new hash, computed as\n * {@link DocsAssets.integrity} describes.\n */\nconst defaults: Record<DocsUi, DocsAssets> = {\n scalar: {\n script:\n \"https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.72.1/dist/browser/standalone.js\",\n integrity: {\n script:\n \"sha384-U11tb2XnKvmwt8RlTvnwUnYgrN+ur4Xyh9htLhjajWNR/Oyl5AX5DEz00qRmlrmK\",\n },\n },\n \"swagger-ui\": {\n script:\n \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.33.0/swagger-ui-bundle.js\",\n style: \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.33.0/swagger-ui.css\",\n integrity: {\n script:\n \"sha384-YDALVcy8kj8yltLBVi1vBiBAUqdxvus673gM8XKwiy6aDUJFXivF/KCufekjYbVf\",\n style:\n \"sha384-Ov4/wv3j2bmct8cDc5X4ngJZohVPzEmc6uDPH8WeljUxO5vtoykvMEfbu9Vh6RaW\",\n },\n },\n redoc: {\n script:\n \"https://cdn.jsdelivr.net/npm/redoc@2.5.4/bundles/redoc.standalone.js\",\n integrity: {\n script:\n \"sha384-w447zOpYfw/1Tv/5AK9NfHTlQIqE3RVR6KY62jCyy9zNDgO64cMwGGP1Fj0zJVf5\",\n },\n },\n};\n\n/**\n * Builds the documentation page.\n *\n * Called by `docs()` for the page it serves; call it directly to serve one\n * from somewhere else.\n *\n * @example\n * ```ts\n * const page = docsPage({ ui: \"scalar\", documentUrl: \"/openapi.json\" });\n *\n * const ui = route({\n * method: \"GET\",\n * path: \"/docs\",\n * handler: () =>\n * new Response(page, { headers: { \"content-type\": \"text/html\" } }),\n * });\n * ```\n */\nexport function docsPage(options: DocsPageOptions): string {\n const assets = options.assets ?? defaults[options.ui];\n const title = escapeHtml(options.title ?? \"API documentation\");\n const url = escapeHtml(options.documentUrl);\n\n return [\n \"<!doctype html>\",\n '<html lang=\"en\">',\n \"<head>\",\n '<meta charset=\"utf-8\" />',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n `<title>${title}</title>`,\n assets.style\n ? `<link rel=\"stylesheet\" href=\"${escapeHtml(assets.style)}\"${verified(assets.integrity?.style)} />`\n : \"\",\n \"</head>\",\n \"<body>\",\n body(options.ui, url),\n `<script src=\"${escapeHtml(assets.script)}\"${verified(assets.integrity?.script)}></script>`,\n bootstrap(options.ui, url),\n \"</body>\",\n \"</html>\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction body(ui: DocsUi, url: string): string {\n if (ui === \"scalar\") {\n return `<script id=\"api-reference\" data-url=\"${url}\"></script>`;\n }\n\n if (ui === \"redoc\") {\n return `<redoc spec-url=\"${url}\"></redoc>`;\n }\n\n return '<div id=\"swagger-ui\"></div>';\n}\n\nfunction bootstrap(ui: DocsUi, url: string): string {\n if (ui !== \"swagger-ui\") {\n return \"\";\n }\n\n return [\n \"<script>\",\n `SwaggerUIBundle({ url: \"${url}\", dom_id: \"#swagger-ui\" });`,\n \"</script>\",\n ].join(\"\\n\");\n}\n\n/**\n * The attributes that make the browser check a file against its hash.\n *\n * `crossorigin` comes with it: a file from another origin is checked only\n * when fetched with CORS, and without the attribute the browser refuses\n * it outright rather than skip the check.\n */\nfunction verified(integrity: string | undefined): string {\n return integrity\n ? ` integrity=\"${escapeHtml(integrity)}\" crossorigin=\"anonymous\"`\n : \"\";\n}\n\n/**\n * Escapes the values that reach the markup.\n *\n * The document URL and the title come from the application, but they are\n * still values interpolated into HTML — a quote in either would break out\n * of the attribute it sits in.\n */\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n",
14
- "/**\n * OpenAPI generation for the framework.\n *\n * Reads a compiled application — `app.entries` and the options it actually\n * runs with — and returns an OpenAPI 3.1 document. Nothing is registered,\n * served or mutated: the document is data, and serving it is a route the\n * application declares like any other.\n *\n * Serving it is a route the application declares — or `docs()`, the\n * controller that declares those routes for you.\n *\n * @example\n * ```ts\n * const { document, warnings } = openapi(app, {\n * info: { title: \"Users API\", version: \"1.0.0\" },\n * });\n * ```\n *\n * @module\n */\n\nimport type { App } from \"@tetsujs/core\";\nimport { contributionsOf } from \"./annotations.ts\";\nimport { schemaComponents } from \"./components.ts\";\nimport type { OpenApiDocument, PathItemObject } from \"./document.ts\";\nimport { envelopes as envelopeDefinitions } from \"./envelopes.ts\";\nimport type { ErrorFormat } from \"./errors.ts\";\nimport { resolveFormat } from \"./errors.ts\";\nimport { declareEnvelopes, operationIds, operationOf } from \"./operation.ts\";\nimport { toTemplate } from \"./parameters.ts\";\n\nexport type {\n DocumentedHeader,\n DocumentedResponse,\n HookContributions,\n HookDocs,\n SecurityAlternatives,\n SecurityRequirement,\n SecurityScheme,\n} from \"./annotations.ts\";\nexport { documented, secured } from \"./annotations.ts\";\nexport type { DocsOptions } from \"./controller.ts\";\nexport { DocsController, docs } from \"./controller.ts\";\nexport type {\n ContentMap,\n DocumentInfo,\n DocumentServer,\n HeaderObject,\n OpenApiDocument,\n OperationObject,\n ParameterObject,\n PathItemObject,\n ResponseObject,\n} from \"./document.ts\";\nexport type { DocumentedFailure, ErrorFormat } from \"./errors.ts\";\nexport type {\n JsonSchema,\n JsonSchemaKeywords,\n JsonSchemaType,\n} from \"./json-schema.ts\";\nexport type { DocsAssets, DocsPageOptions, DocsUi } from \"./page.ts\";\nexport { docsPage } from \"./page.ts\";\n\n/**\n * What the generator cannot read off the application.\n */\nexport interface OpenApiOptions {\n /** Title, version and the rest of the document's `info` block. */\n readonly info: OpenApiDocument[\"info\"];\n\n /** Servers the API is reachable at. */\n readonly servers?: OpenApiDocument[\"servers\"];\n\n /**\n * How the application's errors look, when not like the framework's\n * envelope — for an application whose `onError` hook answers in a format\n * of its own. The framework's failures, the hooks' refusals and the\n * routes' own envelopes are then described in it.\n *\n * @example `{ code, message }`, discriminated on `code`\n * ```ts\n * openapi(app, {\n * info,\n * errors: {\n * schema: ({ error, message, fields }) => ({\n * type: \"object\",\n * required: [\"code\", \"message\", ...Object.keys(fields)],\n * properties: {\n * code: error ? { type: \"string\", const: error } : { type: \"string\" },\n * message: { type: \"string\", ...(message ? { examples: [message] } : {}) },\n * ...fields,\n * },\n * }),\n * discriminator: \"code\",\n * },\n * });\n * ```\n */\n readonly errors?: ErrorFormat;\n}\n\n/**\n * What the generator could not describe faithfully.\n *\n * Each entry names a route and what was missing — almost always a schema\n * from a validator that emits no JSON Schema. Documentation that silently\n * omits a body is worse than documentation that says it does not know, so\n * these are returned rather than swallowed.\n */\nexport interface GeneratorWarning {\n readonly route: string;\n readonly message: string;\n}\n\n/** A generated document together with what could not be described. */\nexport interface GeneratorResult {\n readonly document: OpenApiDocument;\n readonly warnings: readonly GeneratorWarning[];\n}\n\n/**\n * Generates the OpenAPI document of an application.\n *\n * Socket endpoints are skipped: a handshake is a `GET` in the table, but\n * OpenAPI has no way to describe what happens after it, and documenting\n * the upgrade as an ordinary operation would describe a request that\n * clients must not make. AsyncAPI is that format, and a separate document.\n *\n * So are routes marked `docs: { hidden: true }`, and everything they would\n * have contributed with them: a security scheme only a hidden route\n * requires has nothing left to describe.\n *\n * Every route of the table becomes an operation under its path template,\n * with the parameters, body and responses its schemas describe. What the\n * framework itself can answer — a validation failure, an unparsable body,\n * a body over the limit — is filled in from the options the application\n * runs with, so the document states the status actually configured.\n */\nexport function openapi(app: App, options: OpenApiOptions): GeneratorResult {\n const paths: Record<string, PathItemObject> = {};\n const warnings: GeneratorWarning[] = [];\n const schemes: Record<string, unknown> = {};\n const components = schemaComponents();\n const envelopes = envelopeDefinitions(\n components,\n resolveFormat(options.errors),\n );\n const ids = operationIds();\n const described = app.entries.filter(\n (entry) => !entry.ws && !entry.def.docs?.hidden,\n );\n\n for (const entry of described) {\n declareEnvelopes(entry, envelopes);\n }\n\n // Which route already occupies each slot of the document. Two routes the\n // router keeps apart can still meet here, because a template says less\n // than a path does: `/files/*` and `/files/:wildcard` both become\n // `/files/{wildcard}`, and a literal `/users/{id}` — which Bun matches as\n // the string it is — is spelled the same as `/users/:id`. The second one\n // then replaces the first, and the document quietly loses an endpoint\n // that works. It still loses it; it no longer does so without saying.\n const occupied = new Map<string, string>();\n\n for (const entry of described) {\n const template = toTemplate(entry.path);\n const route = `${entry.method} ${entry.path}`;\n\n const operation = operationOf(\n entry,\n app.options,\n components,\n envelopes,\n ids,\n (message) => {\n warnings.push({ route, message });\n },\n );\n\n // First definition wins, as it does among the hooks of one route: a\n // name is the identity of a scheme, and the operations that reference\n // it say only the name. A second, different scheme under that name\n // cannot be described without renaming it out from under everything\n // already pointing at it, so it is refused rather than silently\n // swapped in — which used to make every earlier operation describe an\n // authentication its route does not perform.\n for (const requirement of contributionsOf(entry.hooks).security) {\n const defined = schemes[requirement.name];\n\n if (defined === undefined) {\n schemes[requirement.name] = requirement.scheme;\n\n continue;\n }\n\n if (JSON.stringify(defined) !== JSON.stringify(requirement.scheme)) {\n warnings.push({\n route,\n message: `the security scheme \"${requirement.name}\" is already defined differently; this definition is ignored`,\n });\n }\n }\n\n const slot = `${entry.method.toLowerCase()} ${template}`;\n const taken = occupied.get(slot);\n\n if (taken) {\n warnings.push({\n route,\n message: `${template} is already described by ${taken}, whose operation this replaces`,\n });\n }\n\n occupied.set(slot, route);\n\n paths[template] = {\n ...paths[template],\n [entry.method.toLowerCase()]: operation,\n };\n }\n\n return {\n document: {\n openapi: \"3.1.0\",\n info: options.info,\n ...(options.servers ? { servers: options.servers } : {}),\n paths,\n ...componentsOf(schemes, components.schemas),\n },\n warnings,\n };\n}\n\n/**\n * The `components` block, present only when something goes in it: the\n * security schemes the guards registered, and the failure envelopes the\n * operations refer to.\n */\nfunction componentsOf(\n securitySchemes: Record<string, unknown>,\n schemas: Record<string, unknown>,\n): { components?: Record<string, unknown> } {\n const components = {\n ...(Object.keys(securitySchemes).length > 0 ? { securitySchemes } : {}),\n ...(Object.keys(schemas).length > 0 ? { schemas } : {}),\n };\n\n return Object.keys(components).length > 0 ? { components } : {};\n}\n"
14
+ "/**\n * OpenAPI generation for the framework.\n *\n * Reads a compiled application — `app.entries` and the options it actually\n * runs with — and returns an OpenAPI 3.1 document. Nothing is registered,\n * served or mutated: the document is data, and serving it is a route the\n * application declares like any other.\n *\n * Serving it is a route the application declares — or `docs()`, the\n * controller that declares those routes for you.\n *\n * @example\n * ```ts\n * const { document, warnings } = openapi(app, {\n * info: { title: \"Users API\", version: \"1.0.0\" },\n * });\n * ```\n *\n * @module\n */\n\nimport type { App } from \"@tetsujs/core\";\nimport { contributionsOf } from \"./annotations.ts\";\nimport { schemaComponents } from \"./components.ts\";\nimport type { OpenApiDocument, PathItemObject, TagObject } from \"./document.ts\";\nimport { envelopes as envelopeDefinitions } from \"./envelopes.ts\";\nimport type { ErrorFormat } from \"./errors.ts\";\nimport { resolveFormat } from \"./errors.ts\";\nimport { declareEnvelopes, operationIds, operationOf } from \"./operation.ts\";\nimport { toTemplate } from \"./parameters.ts\";\n\nexport type {\n DocumentedHeader,\n DocumentedResponse,\n HookContributions,\n HookDocs,\n SecurityAlternatives,\n SecurityRequirement,\n SecurityScheme,\n} from \"./annotations.ts\";\nexport { documented, secured } from \"./annotations.ts\";\nexport type { DocsOptions } from \"./controller.ts\";\nexport { DocsController, docs } from \"./controller.ts\";\nexport type {\n ContentMap,\n DocumentInfo,\n DocumentServer,\n HeaderObject,\n OpenApiDocument,\n OperationObject,\n ParameterObject,\n PathItemObject,\n ResponseObject,\n TagObject,\n} from \"./document.ts\";\nexport type { DocumentedFailure, ErrorFormat } from \"./errors.ts\";\nexport type {\n JsonSchema,\n JsonSchemaKeywords,\n JsonSchemaType,\n} from \"./json-schema.ts\";\nexport type { DocsAssets, DocsPageOptions, DocsUi } from \"./page.ts\";\nexport { docsPage } from \"./page.ts\";\n\n/**\n * What the generator cannot read off the application.\n */\nexport interface OpenApiOptions {\n /** Title, version and the rest of the document's `info` block. */\n readonly info: OpenApiDocument[\"info\"];\n\n /** Servers the API is reachable at. */\n readonly servers?: OpenApiDocument[\"servers\"];\n\n /**\n * How the application's errors look, when not like the framework's\n * envelope — for an application whose `onError` hook answers in a format\n * of its own. The framework's failures, the hooks' refusals and the\n * routes' own envelopes are then described in it.\n *\n * @example `{ code, message }`, discriminated on `code`\n * ```ts\n * openapi(app, {\n * info,\n * errors: {\n * schema: ({ error, message, fields }) => ({\n * type: \"object\",\n * required: [\"code\", \"message\", ...Object.keys(fields)],\n * properties: {\n * code: error ? { type: \"string\", const: error } : { type: \"string\" },\n * message: { type: \"string\", ...(message ? { examples: [message] } : {}) },\n * ...fields,\n * },\n * }),\n * discriminator: \"code\",\n * },\n * });\n * ```\n */\n readonly errors?: ErrorFormat;\n\n /**\n * What each tag is, by name — the sections a renderer's sidebar shows,\n * in the order given here.\n *\n * A tag the routes use and this leaves out is listed after these, in the\n * order the routes first use it, without a description; so is reported,\n * as a likely misspelling — `sign_in` for `sign-in` makes a section of its\n * own. So is a tag described here that no operation uses. Without\n * `tags`, the document lists none and nothing is reported.\n *\n * @example\n * ```ts\n * openapi(app, {\n * info,\n * tags: {\n * \"sign-in\": \"Signing in with a code sent by email, and signing out\",\n * me: \"The signed-in user\",\n * },\n * });\n * ```\n */\n readonly tags?: Readonly<Record<string, string>>;\n}\n\n/**\n * What the generator could not describe faithfully.\n *\n * Each entry names a route and what was missing — almost always a schema\n * from a validator that emits no JSON Schema. Documentation that silently\n * omits a body is worse than documentation that says it does not know, so\n * these are returned rather than swallowed.\n */\nexport interface GeneratorWarning {\n /**\n * The route the warning is about, as `GET /path` — empty for a warning\n * about the document as a whole, such as a described tag nothing uses.\n */\n readonly route: string;\n readonly message: string;\n}\n\n/** A generated document together with what could not be described. */\nexport interface GeneratorResult {\n readonly document: OpenApiDocument;\n readonly warnings: readonly GeneratorWarning[];\n}\n\n/**\n * Generates the OpenAPI document of an application.\n *\n * Socket endpoints are skipped: a handshake is a `GET` in the table, but\n * OpenAPI has no way to describe what happens after it, and documenting\n * the upgrade as an ordinary operation would describe a request that\n * clients must not make. AsyncAPI is that format, and a separate document.\n *\n * So are routes marked `docs: { hidden: true }`, and everything they would\n * have contributed with them: a security scheme only a hidden route\n * requires has nothing left to describe.\n *\n * Every route of the table becomes an operation under its path template,\n * with the parameters, body and responses its schemas describe. What the\n * framework itself can answer — a validation failure, an unparsable body,\n * a body over the limit — is filled in from the options the application\n * runs with, so the document states the status actually configured.\n */\nexport function openapi(app: App, options: OpenApiOptions): GeneratorResult {\n const paths: Record<string, PathItemObject> = {};\n const warnings: GeneratorWarning[] = [];\n const schemes: Record<string, unknown> = {};\n const components = schemaComponents();\n const envelopes = envelopeDefinitions(\n components,\n resolveFormat(options.errors),\n );\n const ids = operationIds();\n const described = app.entries.filter(\n (entry) => !entry.ws && !entry.def.docs?.hidden,\n );\n\n for (const entry of described) {\n declareEnvelopes(entry, envelopes);\n }\n\n // Which route already occupies each slot of the document. Two routes the\n // router keeps apart can still meet here, because a template says less\n // than a path does: `/files/*` and `/files/:wildcard` both become\n // `/files/{wildcard}`, and a literal `/users/{id}` — which Bun matches as\n // the string it is — is spelled the same as `/users/:id`. The second one\n // then replaces the first, and the document quietly loses an endpoint\n // that works. It still loses it; it no longer does so without saying.\n const occupied = new Map<string, string>();\n\n // Every tag the operations use, with the first route using it: the\n // order undescribed tags are listed in, and where each is reported.\n const used = new Map<string, string>();\n\n for (const entry of described) {\n const template = toTemplate(entry.path);\n const route = `${entry.method} ${entry.path}`;\n\n const operation = operationOf(\n entry,\n app.options,\n components,\n envelopes,\n ids,\n (message) => {\n warnings.push({ route, message });\n },\n );\n\n // First definition wins, as it does among the hooks of one route: a\n // name is the identity of a scheme, and the operations that reference\n // it say only the name. A second, different scheme under that name\n // cannot be described without renaming it out from under everything\n // already pointing at it, so it is refused rather than silently\n // swapped in — which used to make every earlier operation describe an\n // authentication its route does not perform.\n for (const requirement of contributionsOf(entry.hooks).security) {\n const defined = schemes[requirement.name];\n\n if (defined === undefined) {\n schemes[requirement.name] = requirement.scheme;\n\n continue;\n }\n\n if (JSON.stringify(defined) !== JSON.stringify(requirement.scheme)) {\n warnings.push({\n route,\n message: `the security scheme \"${requirement.name}\" is already defined differently; this definition is ignored`,\n });\n }\n }\n\n const slot = `${entry.method.toLowerCase()} ${template}`;\n const taken = occupied.get(slot);\n\n if (taken) {\n warnings.push({\n route,\n message: `${template} is already described by ${taken}, whose operation this replaces`,\n });\n }\n\n occupied.set(slot, route);\n\n for (const tag of operation.tags ?? []) {\n if (!used.has(tag)) {\n used.set(tag, route);\n }\n }\n\n paths[template] = {\n ...paths[template],\n [entry.method.toLowerCase()]: operation,\n };\n }\n\n const tags = options.tags ? tagsOf(options.tags, used, warnings) : undefined;\n\n return {\n document: {\n openapi: \"3.1.0\",\n info: options.info,\n ...(options.servers ? { servers: options.servers } : {}),\n ...(tags ? { tags } : {}),\n paths,\n ...componentsOf(schemes, components.schemas),\n },\n warnings,\n };\n}\n\n/**\n * The document's tags: the described ones in the order given, then those\n * the operations use and the description leaves out, in the order they are\n * first used — so the order of the sections is the application's, not\n * whatever a renderer does with a tag it was not told about.\n *\n * Both kinds of mismatch are reported, since either is usually one tag\n * spelled two ways: a tag used and not described, at the first route\n * using it, and a tag described and not used, for the document.\n */\nfunction tagsOf(\n described: Readonly<Record<string, string>>,\n used: ReadonlyMap<string, string>,\n warnings: GeneratorWarning[],\n): TagObject[] {\n const tags: TagObject[] = Object.entries(described).map(\n ([name, description]) => ({ name, description }),\n );\n\n for (const [name, route] of used) {\n if (Object.hasOwn(described, name)) {\n continue;\n }\n\n tags.push({ name });\n warnings.push({\n route,\n message: `the tag \"${name}\" is not in tags; it is listed after them, without a description`,\n });\n }\n\n for (const name of Object.keys(described)) {\n if (!used.has(name)) {\n warnings.push({\n route: \"\",\n message: `the tag \"${name}\" is described in tags, but no operation uses it`,\n });\n }\n }\n\n return tags;\n}\n\n/**\n * The `components` block, present only when something goes in it: the\n * security schemes the guards registered, and the failure envelopes the\n * operations refer to.\n */\nfunction componentsOf(\n securitySchemes: Record<string, unknown>,\n schemas: Record<string, unknown>,\n): { components?: Record<string, unknown> } {\n const components = {\n ...(Object.keys(securitySchemes).length > 0 ? { securitySchemes } : {}),\n ...(Object.keys(schemas).length > 0 ? { schemas } : {}),\n };\n\n return Object.keys(components).length > 0 ? { components } : {};\n}\n"
15
15
  ],
16
- "mappings": "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",
17
- "debugId": "4A68DE756C1883B864756E2164756E21",
16
+ "mappings": ";;AA2JA,IAAM,UAAU;AAmBT,SAAS,UAA6B,CAAC,MAAS,MAAmB;AAAA,EACxE,MAAM,YAAY,KAAK,KAAK;AAAA,EAE5B,OAAO,eAAe,WAAW,SAAS;AAAA,IACxC,YAAY;AAAA,IACZ,OAAO,KAAK,OAAO,IAAI,MAAM,KAAK;AAAA,EACpC,CAAC;AAAA,EAED,OAAO;AAAA;AAsCF,SAAS,OAA0B,CACxC,MACA,aACG;AAAA,EACH,OAAO,WAAW,MAAM,EAAE,UAAU,YAAY,CAAC;AAAA;AAI5C,SAAS,MAAM,CAAC,MAAqC;AAAA,EAC1D,OAAQ,KAAyD;AAAA;AA0C5D,SAAS,eAAe,CAC7B,QACA,MACmB;AAAA,EACnB,MAAM,WAAW,IAAI;AAAA,EACrB,MAAM,aAAa,IAAI;AAAA,EACvB,MAAM,YAAY,IAAI;AAAA,EAEtB,WAAW,QAAQ,OAAO,OAAO,MAAM,GAAG;AAAA,IACxC,WAAW,QAAQ,MAAM;AAAA,MACvB,MAAM,OAAO,OAAO,IAAI;AAAA,MAExB,IAAI,CAAC,MAAM;AAAA,QACT;AAAA,MACF;AAAA,MAEA,IAAI,KAAK,UAAU;AAAA,QACjB,MAAM,eAAe,eAAe,KAAK,QAAQ;AAAA,QAEjD,WAAW,IAAI,aAAa,YAAY,GAAG,YAAY;AAAA,QAEvD,WAAW,eAAe,cAAc;AAAA,UACtC,MAAM,UAAU,SAAS,IAAI,YAAY,IAAI;AAAA,UAE7C,IAAI,CAAC,SAAS;AAAA,YACZ,SAAS,IAAI,YAAY,MAAM,WAAW;AAAA,UAC5C,EAAO,SACL,KAAK,UAAU,QAAQ,MAAM,MAC7B,KAAK,UAAU,YAAY,MAAM,GACjC;AAAA,YACA,SAAS,IAAI,YAAY,MAAM;AAAA,iBAC1B;AAAA,cACH,QAAQ,WAAW,QAAQ,QAAQ,YAAY,MAAM;AAAA,YACvD,CAAC;AAAA,UACH,EAAO;AAAA,YACL,OACE,wCAAwC,YAAY,gEACtD;AAAA;AAAA,QAEJ;AAAA,MACF;AAAA,MAEA,WAAW,YAAY,KAAK,aAAa,CAAC,GAAG;AAAA,QAC3C,MAAM,MAAM,GAAG,SAAS,UAAU,SAAS;AAAA,QAE3C,IAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AAAA,UACvB,UAAU,IAAI,KAAK,QAAQ;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,UAAU,CAAC,GAAG,SAAS,OAAO,CAAC;AAAA,IAC/B,YAAY,CAAC,GAAG,WAAW,OAAO,CAAC;AAAA,IACnC,WAAW,CAAC,GAAG,UAAU,OAAO,CAAC;AAAA,EACnC;AAAA;AAIF,SAAS,cAAc,CACrB,UACgC;AAAA,EAChC,OAAO,WAAW,WAAW,SAAS,QAAQ,CAAC,QAAQ;AAAA;AAQzD,SAAS,YAAY,CAAC,cAAsD;AAAA,EAC1E,OAAO,KAAK,UACV,aAAa,IAAI,CAAC,gBAAgB;AAAA,IAChC,YAAY;AAAA,IACZ,CAAC,GAAI,YAAY,UAAU,CAAC,CAAE,EAAE,KAAK;AAAA,EACvC,CAAC,CACH;AAAA;AAIF,SAAS,UAAU,CACjB,OACA,QACmB;AAAA,EACnB,MAAM,SAAS,CAAC,GAAI,SAAS,CAAC,CAAE;AAAA,EAEhC,WAAW,SAAS,UAAU,CAAC,GAAG;AAAA,IAChC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,MAC3B,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;;;ACtUF,SAAS,gBAAgB,GAAqB;AAAA,EACnD,MAAM,UAAmC,CAAC;AAAA,EAC1C,MAAM,aAAa,IAAI;AAAA,EAEvB,OAAO;AAAA,IACL;AAAA,IAEA,GAAG,CAAC,WAAmB,QAA4C;AAAA,MACjE,MAAM,cAAc,KAAK,UAAU,MAAM;AAAA,MACzC,MAAM,UAAU,WAAW,IAAI,WAAW;AAAA,MAE1C,IAAI,SAAS;AAAA,QACX,OAAO,EAAE,MAAM,wBAAwB,UAAU;AAAA,MACnD;AAAA,MAEA,IAAI,OAAO;AAAA,MAEX,SAAS,UAAU,EAAG,QAAQ,SAAS,WAAW,GAAG;AAAA,QACnD,OAAO,GAAG,YAAY;AAAA,MACxB;AAAA,MAEA,QAAQ,QAAQ;AAAA,MAChB,WAAW,IAAI,aAAa,IAAI;AAAA,MAEhC,OAAO,EAAE,MAAM,wBAAwB,OAAO;AAAA;AAAA,EAElD;AAAA;AAWK,SAAS,WAAW,CAAC,QAAgB,OAAwB;AAAA,EAClE,MAAM,QAAQ,SAAS,IACpB,YAAY,EACZ,MAAM,YAAY,EAClB,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,EAAE;AAAA,EAOV,OAAO,QAAQ,UAAU;AAAA;;;ACnBpB,SAAS,SAAS,CACvB,YACA,QACW;AAAA,EACX,MAAM,WAAW,IAAI;AAAA,EACrB,MAAM,UAAU,IAAI;AAAA,EACpB,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,QAAQ,IAAI;AAAA,EAClB,MAAM,QAAQ,IAAI;AAAA,EAClB,MAAM,WAAW,IAAI;AAAA,EAErB,OAAO;AAAA,IACL;AAAA,IAEA,OAAO,CAAC,QAAQ,MAAM,QAAQ;AAAA,MAC5B,MAAM,MAAM,MAAM,QAAQ,IAAI;AAAA,MAE9B,IAAI,CAAC,SAAS,IAAI,GAAG,GAAG;AAAA,QACtB,SAAS,IAAI,KAAK,MAAM;AAAA,MAC1B;AAAA;AAAA,IAGF,GAAG,CAAC,QAAQ,MAAM,QAAQ,MAAM;AAAA,MAC9B,MAAM,MAAM,MAAM,QAAQ,IAAI;AAAA,MAC9B,MAAM,aAAa,SAAS,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK;AAAA,MAE5D,QAAQ,IAAI,KAAK,UAAU;AAAA,MAE3B,MAAM,aAAa,aAAa,YAAY,MAAM;AAAA,MAElD,IAAI,cAAc,CAAC,SAAS,IAAI,GAAG,OAAO,YAAY,GAAG;AAAA,QACvD,SAAS,IAAI,GAAG,OAAO,YAAY;AAAA,QACnC,KACE,OAAO,WAAW,kGAAkG,6BACtH;AAAA,MACF;AAAA,MAEA,MAAM,WAAW,KAAK,IAAI,GAAG;AAAA,MAE7B,IAAI,UAAU;AAAA,QACZ,OAAO;AAAA,MACT;AAAA,MAEA,MAAM,UAAU,WAAW,IAAI,OAAO,QAAQ,IAAI,GAAG,UAAU;AAAA,MAE/D,KAAK,IAAI,KAAK,OAAO;AAAA,MACrB,MAAM,IAAI,QAAQ,MAAM,IAAI;AAAA,MAE5B,OAAO;AAAA;AAAA,IAGT,MAAM,CAAC,KAAK;AAAA,MACV,OAAO,MAAM,IAAI,GAAG;AAAA;AAAA,EAExB;AAAA,EAOA,SAAS,MAAM,CAAC,QAAgB,MAAsB;AAAA,IACpD,MAAM,OAAO,YAAY,QAAQ,IAAI;AAAA,IACrC,MAAM,SAAS,MAAM,IAAI,IAAI;AAAA,IAE7B,IAAI,WAAW,aAAa,WAAW,MAAM,QAAQ,IAAI,GAAG;AAAA,MAC1D,MAAM,IAAI,MAAM,MAAM,QAAQ,IAAI,CAAC;AAAA,MAEnC,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,GAAG,OAAO;AAAA;AAAA;AAgBd,SAAS,UAAU,CACxB,QACA,MACoB;AAAA,EACpB,MAAM,OAAO,OAAO,KAAK,MAAM;AAAA,EAE/B,IAAI,KAAK,WAAW,GAAG;AAAA,IACrB,OAAO,CAAC,MAAM;AAAA,EAChB;AAAA,EAEA,MAAM,SAAS,CAAC,WAA6B,WAAW,QAAQ,IAAI;AAAA,EAEpE,IAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAAA,IAC/B,OAAQ,OAAO,MAA6B,QAAQ,MAAM;AAAA,EAC5D;AAAA,EAEA,IAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAAA,IAC/B,MAAM,WAAY,OAAO,MAA6B,QAAQ,MAAM;AAAA,IACpE,MAAM,QAAQ,SAAS,IAAI,IAAI;AAAA,IAE/B,IACE,MAAM,MAAM,CAAC,SAAS,SAAS,SAAS,KACxC,IAAI,IAAI,KAAK,EAAE,SAAS,MAAM,QAC9B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,CAAC,MAAM;AAAA;AAGhB,SAAS,KAAK,CAAC,QAAgB,MAAsB;AAAA,EACnD,OAAO,GAAG,UAAU;AAAA;AAWtB,SAAS,YAAY,CACnB,MACA,OACoB;AAAA,EACpB,MAAM,YAAY,QAAQ,IAAI;AAAA,EAC9B,MAAM,aAAa,QAAQ,KAAK;AAAA,EAEhC,MAAM,UAAU;AAAA,IACd,GAAG,WAAW,OAAO,OAAO,CAAC,SAAS,CAAC,UAAU,OAAO,SAAS,IAAI,CAAC;AAAA,IACtE,GAAG,UAAU,OAAO,OAAO,CAAC,SAAS,CAAC,WAAW,OAAO,SAAS,IAAI,CAAC;AAAA,EACxE;AAAA,EAEA,IAAI,QAAQ,SAAS,GAAG;AAAA,IACtB,OAAO,WAAW,QAAQ,KAAK,IAAI;AAAA,EACrC;AAAA,EAEA,OAAO,KAAK,UAAU,UAAU,QAAQ,MACtC,KAAK,UAAU,WAAW,QAAQ,IAChC,YACA;AAAA;AAIN,IAAM,aAAa;AAOnB,SAAS,OAAO,CAAC,QAGf;AAAA,EACA,MAAM,SAAmB,CAAC;AAAA,EAC1B,MAAM,WAAqB,CAAC;AAAA,EAE5B,MAAM,OAAO,CAAC,MAAwB,QAAgB,UAAkB;AAAA,IACtE,MAAM,aAAa,KAAK;AAAA,IAExB,IACE,QAAQ,cACR,eAAe,QACf,OAAO,eAAe,UACtB;AAAA,MACA;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,MAAM,QAAQ,KAAK,QAAQ,IAAI,KAAK,WAAW,CAAC;AAAA,IAErE,YAAY,MAAM,UAAU,OAAO,QAAQ,UAAU,GAAG;AAAA,MACtD,MAAM,OAAO,GAAG,SAAS;AAAA,MAEzB,OAAO,KAAK,IAAI;AAAA,MAEhB,IAAI,aAAa,SAAS,IAAI,GAAG;AAAA,QAC/B,SAAS,KAAK,IAAI;AAAA,MACpB;AAAA,MAEA,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAAA,QAC/C,KAAK,OAA2B,GAAG,SAAS,QAAQ,CAAC;AAAA,MACvD;AAAA,IACF;AAAA;AAAA,EAGF,KAAK,QAAQ,IAAI,CAAC;AAAA,EAElB,OAAO,EAAE,QAAQ,OAAO,KAAK,GAAG,UAAU,SAAS,KAAK,EAAE;AAAA;;;ACxLrD,SAAS,aAAa,CAAC,QAAiD;AAAA,EAC7E,IAAI,WAAW,WAAW;AAAA,IACxB,OAAO;AAAA,MACL,UAAU;AAAA,MACV,MAAM,OAAO,OAAO;AAAA,MACpB,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,OAAO;AAAA,EAC7B,MAAM,OAAO,OAAO;AAAA,EAEpB,OAAO;AAAA,IACL,UAAU,CAAC,YAAY,OAAO,OAAO,OAAO;AAAA,IAC5C,MAAM,OACF,CAAC,WAAW,KAAK,MAA4B,IAC7C,kBAAkB,YAChB,MAAG;AAAA,MAAG;AAAA,QACN,OAAO,aAAa;AAAA,IAC1B;AAAA,EACF;AAAA;AAkBF,SAAS,QAAQ,CAAC,SAA8C;AAAA,EAC9D,MAAM,MAAM;AAAA,IACV,QAAQ,EAAE,MAAM,WAAW,OAAO,QAAQ,OAAO;AAAA,IACjD,SAAS,QAAQ,UACb,EAAE,MAAM,UAAU,UAAU,CAAC,QAAQ,OAAO,EAAE,IAC9C,EAAE,MAAM,SAAS;AAAA,IACrB,OAAO,QAAQ,QACX,EAAE,MAAM,UAAU,OAAO,QAAQ,MAAM,IACvC,EAAE,MAAM,SAAS;AAAA,EACvB;AAAA,EAEA,MAAM,QAAQ,OAAO,KAAK,QAAQ,MAAM,EAAE,OACxC,CAAC,SAAS,CAAC,OAAO,OAAO,KAAK,IAAI,CACpC;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,CAAC,UAAU,WAAW,SAAS,GAAG,KAAK;AAAA,IACjD,YAAY,KAAK,QAAQ,WAAW,IAAI;AAAA,EAC1C;AAAA;AAOF,SAAS,MAAM,CACb,OACkD;AAAA,EAClD,OAAO,CAAC,WAAW;AAAA,IACjB,MAAM,WAAW,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AAAA,IAErE,IAAI,CAAC,SAAS,SAAS,KAAK,GAAG;AAAA,MAC7B;AAAA,IACF;AAAA,IAEA,MAAM,QACJ,OAAO,aAGL;AAAA,IAEJ,IAAI,OAAO,OAAO,UAAU,UAAU;AAAA,MACpC,OAAO,MAAM;AAAA,IACf;AAAA,IAEA,IACE,MAAM,QAAQ,OAAO,IAAI,KACzB,MAAM,KAAK,WAAW,KACtB,OAAO,MAAM,KAAK,OAAO,UACzB;AAAA,MACA,OAAO,MAAM,KAAK;AAAA,IACpB;AAAA,IAEA;AAAA;AAAA;;;AC5JJ;;;ACVA;AAWA,IAAM,SAAS,EAAE,QAAQ,gBAAgB;AAqClC,SAAS,OAAO,CACrB,QACA,SACA,MACA,YAAuB,UACO;AAAA,EAC9B,IAAI;AAAA,EAEJ,IAAI;AAAA,IACF,YAAY,aAAa,QAAQ,QAAQ,SAAS;AAAA,IAClD,OAAO,OAAO;AAAA,IACd,KAAK,GAAG,8CAA8C,OAAO,KAAK,GAAG;AAAA,IAErE;AAAA;AAAA,EAGF,IAAI,CAAC,WAAW;AAAA,IACd,KAAK,GAAG,0CAA0C;AAAA,IAElD;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,SAAS;AAAA;AAUjC,SAAS,cAAc,CAAC,QAA4C;AAAA,EAClE,IAAI,EAAE,aAAa,SAAS;AAAA,IAC1B,OAAO;AAAA,EACT;AAAA,EAEA,QAAQ,SAAS,MAAM,SAAS;AAAA,EAEhC,OAAO;AAAA;AAGT,SAAS,MAAM,CAAC,OAAwB;AAAA,EACtC,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA;;;ACnFvD,IAAM,eAAe;AASrB,SAAS,UAAU,CAAC,MAAsB;AAAA,EAC/C,OAAO,KACJ,MAAM,GAAG,EACT,IAAI,CAAC,YAAY;AAAA,IAChB,IAAI,QAAQ,WAAW,GAAG,GAAG;AAAA,MAC3B,OAAO,IAAI,QAAQ,MAAM,CAAC;AAAA,IAC5B;AAAA,IAEA,OAAO,YAAY,MAAM,IAAI,kBAAkB;AAAA,GAChD,EACA,KAAK,GAAG;AAAA;AAIN,SAAS,aAAa,CAAC,MAAwB;AAAA,EACpD,MAAM,QAAkB,CAAC;AAAA,EAEzB,WAAW,WAAW,KAAK,MAAM,GAAG,GAAG;AAAA,IACrC,IAAI,QAAQ,WAAW,GAAG,GAAG;AAAA,MAC3B,MAAM,KAAK,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC7B,EAAO,SAAI,YAAY,KAAK;AAAA,MAC1B,MAAM,KAAK,YAAY;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAUF,SAAS,cAAc,CAC5B,MACA,QACA,MACmB;AAAA,EACnB,MAAM,aAAa,iBAAiB,QAAQ,UAAU,IAAI;AAAA,EAE1D,OAAO,cAAc,IAAI,EAAE,IAAI,CAAC,UAAU;AAAA,IACxC;AAAA,IACA,IAAI;AAAA,IACJ,UAAU;AAAA,OACN,SAAS,eACT;AAAA,MACE,aACE;AAAA,IACJ,IACA,CAAC;AAAA,IACL,QAAQ,WAAW,SAAS,EAAE,MAAM,SAAS;AAAA,EAC/C,EAAE;AAAA;AAgBG,SAAS,cAAc,CAC5B,QACA,OACA,MACmB;AAAA,EACnB,IAAI,CAAC,QAAQ;AAAA,IACX,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,YAAY,QAAQ,QAAQ,OAAO,SAAS,MAAM,OAAO;AAAA,EAE/D,IAAI,CAAC,WAAW;AAAA,IACd,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,aAAc,UAAU,cAAc,CAAC;AAAA,EAI7C,MAAM,WAAW,IAAI,IACnB,MAAM,QAAQ,UAAU,QAAQ,IAAK,UAAU,WAAwB,CAAC,CAC1E;AAAA,EAEA,OAAO,OAAO,QAAQ,UAAU,EAAE,IAAI,EAAE,MAAM,eAAe;AAAA,IAC3D;AAAA,IACA,IAAI;AAAA,IACJ,UAAU,SAAS,IAAI,IAAI;AAAA,IAC3B,QAAQ;AAAA,EACV,EAAE;AAAA;AAGJ,SAAS,gBAAgB,CACvB,QACA,OACA,MACyC;AAAA,EACzC,IAAI,CAAC,QAAQ;AAAA,IACX,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,YAAY,QAAQ,QAAQ,OAAO,SAAS,MAAM,OAAO;AAAA,EAE/D,IAAI,CAAC,WAAW;AAAA,IACd,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,OAAQ,UAAU,cAAc,CAAC;AAAA;;;AFnG5B,SAAS,WAAW,CACzB,OACA,SACA,YACA,WACA,KACA,MACiB;AAAA,EACjB,MAAM,SAAS,MAAM,IAAI;AAAA,EAEzB,MAAM,aAAa;AAAA,IACjB,GAAG,eAAe,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAAA,IAClD,GAAG,eAAe,QAAQ,OAAO,SAAS,IAAI;AAAA,IAC9C,GAAG,eAAe,QAAQ,SAAS,UAAU,IAAI;AAAA,IACjD,GAAG,eAAe,QAAQ,SAAS,UAAU,IAAI;AAAA,EACnD;AAAA,EAEA,MAAM,OAAO,YAAY,OAAO,IAAI;AAAA,EACpC,MAAM,cAAc,gBAAgB,MAAM,OAAO,IAAI;AAAA,EAErD,OAAO;AAAA,IACL,aAAa,IAAI,KAAK,KAAK;AAAA,OACvB,MAAM,IAAI,MAAM,YAAY,YAC5B,CAAC,IACD,EAAE,SAAS,MAAM,IAAI,KAAK,QAAQ;AAAA,OAClC,MAAM,IAAI,MAAM,gBAAgB,YAChC,CAAC,IACD,EAAE,aAAa,MAAM,IAAI,KAAK,YAAY;AAAA,OAC1C,MAAM,IAAI,MAAM,SAAS,YACzB,CAAC,IACD,EAAE,MAAM,MAAM,IAAI,KAAK,KAAK;AAAA,OAC5B,MAAM,IAAI,MAAM,eAAe,YAC/B,CAAC,IACD,EAAE,YAAY,MAAM,IAAI,KAAK,WAAW;AAAA,OACxC,WAAW,SAAS,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA,OAC1C,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;AAAA,OAChC,YAAY,SAAS,SAAS,IAC9B,EAAE,UAAU,WAAW,YAAY,UAAU,EAAE,IAC/C,CAAC;AAAA,IACL,WAAW,UACT,OACA,SACA,aACA,YACA,WACA,IACF;AAAA,EACF;AAAA;AAUK,SAAS,gBAAgB,CAC9B,OACA,WACM;AAAA,EACN,YAAY,QAAQ,WAAW,kBAAkB,KAAK,GAAG;AAAA,IACvD,MAAM,YACJ,WAAW,OAAO,YAAY,QAAQ,QAAQ,IAAI,MAAM,EAAE;AAAA,IAE5D,MAAM,OAAO,UAAU,OAAO;AAAA,IAE9B,WAAW,UAAU,YAAY,WAAW,WAAW,IAAI,IAAI,CAAC,GAAG;AAAA,MACjE,MAAM,QAAQ,KAAK,MAAM;AAAA,MAEzB,IAAI,UAAU,WAAW;AAAA,QACvB,UAAU,QAAQ,OAAO,MAAM,GAAG,OAAO,MAAM;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA;AAIF,SAAS,iBAAiB,CACxB,OAC8C;AAAA,EAC9C,MAAM,WAAW,MAAM,IAAI,QAAQ;AAAA,EAEnC,IAAI,CAAC,UAAU;AAAA,IACb,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,IAAI,eAAe,UAAU;AAAA,IAC3B,OAAO,CAAC,CAAC,OAAO,QAAqB,CAAC;AAAA,EACxC;AAAA,EAEA,OAAO,OAAO,QAAQ,QAAQ;AAAA;AAShC,SAAS,WAAW,CAClB,QACA,QACA,WACA,MAC2B;AAAA,EAC3B,OAAO,WAAW,QAAQ,UAAU,OAAO,IAAI,EAAE,IAAI,CAAC,WAAW;AAAA,IAC/D,MAAM,OAAO,UAAU,OAAO,KAAK,MAAM;AAAA,IAEzC,OAAO,SAAS,YACZ,SACC,UAAU,IAAI,QAAQ,MAAM,QAAQ,IAAI;AAAA,GAI9C;AAAA;AAmBH,SAAS,UAAU,CACjB,YACqC;AAAA,EACrC,IAAI,eAAoD,CAAC,CAAC,CAAC;AAAA,EAE3D,WAAW,gBAAgB,YAAY;AAAA,IACrC,eAAe,aAAa,QAAQ,CAAC,gBACnC,aAAa,IAAI,CAAC,iBAAiB;AAAA,SAC9B;AAAA,OACF,YAAY,OAAO,OAClB,YAAY,YAAY,OACxB,YAAY,MACd;AAAA,IACF,EAAE,CACJ;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAAI;AAAA,EAEjB,OAAO,aAAa,OAAO,CAAC,gBAAgB;AAAA,IAC1C,MAAM,MAAM,KAAK,UACf,OAAO,QAAQ,WAAW,EACvB,IAAI,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,EAClD,KAAK,CACV;AAAA,IAEA,IAAI,KAAK,IAAI,GAAG,GAAG;AAAA,MACjB,OAAO;AAAA,IACT;AAAA,IAEA,KAAK,IAAI,GAAG;AAAA,IAEZ,OAAO;AAAA,GACR;AAAA;AAIH,SAAS,MAAM,CACb,SACA,OACmB;AAAA,EACnB,MAAM,SAAS,CAAC,GAAI,WAAW,CAAC,CAAE;AAAA,EAElC,WAAW,SAAS,SAAS,CAAC,GAAG;AAAA,IAC/B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,MAC3B,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAgCF,SAAS,YAAY,GAAiB;AAAA,EAC3C,MAAM,QAAQ,IAAI;AAAA,EAElB,OAAO;AAAA,IACL,IAAI,CAAC,OAAgC;AAAA,MACnC,MAAM,KAAK,KAAK,KAAK;AAAA,MACrB,MAAM,SAAS,MAAM,IAAI,EAAE;AAAA,MAE3B,IAAI,WAAW,WAAW;AAAA,QACxB,MAAM,IAAI,MACR,gBAAgB,wBAAwB,SAAS,MAAM,SAAS,SAAS,KAAK,8IAChF;AAAA,MACF;AAAA,MAEA,MAAM,IAAI,IAAI,KAAK;AAAA,MAEnB,OAAO;AAAA;AAAA,EAEX;AAAA;AAIF,SAAS,IAAI,CAAC,OAAgC;AAAA,EAC5C,MAAM,SAAS,MAAM,IAAI,MAAM;AAAA,EAE/B,IAAI,WAAW,WAAW;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,MAAM,SAAS,WAAW;AAAA,IAC5B,OAAO,UAAU,KAAK;AAAA,EACxB;AAAA,EAEA,IAAI,MAAM,eAAe,WAAW;AAAA,IAClC,OAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,aAAa,MAAM,WAAW,QAAQ,eAAe,EAAE;AAAA,EAE7D,OAAO,GAAG,WAAW,UAAU,IAAI,WAAW,MAAM,IAAI;AAAA;AAI1D,SAAS,QAAQ,CAAC,OAAgC;AAAA,EAChD,OAAO,GAAG,MAAM,UAAU,MAAM;AAAA;AAOlC,SAAS,SAAS,CAAC,OAAgC;AAAA,EACjD,OAAO,GAAG,MAAM,OAAO,YAAY,IAAI,MAAM,KAC1C,MAAM,OAAO,EACb,OAAO,OAAO,EACd,IAAI,UAAU,EACd,KAAK,EAAE;AAAA;AAUZ,SAAS,WAAW,CAClB,OACA,MACwD;AAAA,EACxD,MAAM,WAAW,MAAM,IAAI,QAAQ;AAAA,EACnC,MAAM,WAAW,MAAM,IAAI,aAAa,WAAW,SAAS;AAAA,EAE5D,IAAI,CAAC,UAAU;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,WACd,QAAQ,UAAU,YAAY,MAAM,OAAO,IAC3C;AAAA,EAEJ,MAAM,SAAS,YAAY,EAAE,QAAQ,UAAU,IAAI,CAAC;AAAA,EASpD,MAAM,WAAW,aAAa,UAAU,aAAa;AAAA,EAErD,IAAI,aAAa,UAAU;AAAA,IAOzB,OAAO,EAAE,UAAU,SAAS,EAAE,4BAA4B,CAAC,EAAE,EAAE;AAAA,EACjE;AAAA,EAEA,IAAI,aAAa,QAAQ;AAAA,IACvB,OAAO,EAAE,UAAU,SAAS,EAAE,cAAc,OAAO,EAAE;AAAA,EACvD;AAAA,EAEA,IAAI,aAAa,QAAQ;AAAA,IACvB,OAAO,EAAE,UAAU,SAAS,EAAE,oBAAoB,OAAO,EAAE;AAAA,EAC7D;AAAA,EAEA,MAAM,UAAsB,EAAE,uBAAuB,OAAO;AAAA,EAE5D,IAAI,CAAC,aAAa,CAAC,cAAc,SAAS,GAAG;AAAA,IAC3C,QAAQ,uCAAuC;AAAA,EACjD;AAAA,EAEA,OAAO,EAAE,UAAU,QAAQ;AAAA;AAY7B,SAAS,aAAa,CAAC,MAAwB;AAAA,EAC7C,MAAM,UAAqB,CAAC,IAAI;AAAA,EAChC,MAAM,OAAO,IAAI;AAAA,EAEjB,OAAO,QAAQ,SAAS,GAAG;AAAA,IACzB,MAAM,OAAO,QAAQ,IAAI;AAAA,IAEzB,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,KAAK,IAAI,IAAI,GAAG;AAAA,MAC/D;AAAA,IACF;AAAA,IAEA,KAAK,IAAI,IAAI;AAAA,IAEb,IAAK,KAAuC,oBAAoB,UAAU;AAAA,MACxE,OAAO;AAAA,IACT;AAAA,IAEA,WAAW,SAAS,OAAO,OAAO,IAAI,GAAG;AAAA,MACvC,QAAQ,KAAK,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAUT,SAAS,SAAS,CAChB,OACA,SACA,aACA,YACA,WACA,MACgC;AAAA,EAChC,MAAM,UAAU,IAAI;AAAA,EAEpB,MAAM,MAAM,CAAC,QAAgB,WAAyB;AAAA,IACpD,QAAQ,IAAI,QAAQ,CAAC,GAAI,QAAQ,IAAI,MAAM,KAAK,CAAC,GAAI,MAAM,CAAC;AAAA;AAAA,EAG9D,YAAY,QAAQ,WAAW,kBAAkB,KAAK,GAAG;AAAA,IACvD,MAAM,YACJ,WAAW,OAAO,YAAY,QAAQ,QAAQ,cAAc,IAAI;AAAA,IAElE,IAAI,QAAQ;AAAA,MACV,aAAa,eAAe,MAAM;AAAA,MAClC,MAAM,YAAY,QAAQ,WAAW,SAAS,IAAI,CAAC;AAAA,MACnD,SAAS,YACL,YAAY,UAAU,SAAS,GAAG,OAAO,MAAM,GAAG,WAAW,IAAI,IACjE,CAAC;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,CAAC,CAAC,GAAG,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,WAAW,OAAO,WAAW,GAAG,CAAC,GAAG;AAAA,IACjE,IAAI,OAAO,EAAE,aAAa,uBAAuB,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;AAAA,EAC1E;AAAA,EAEA,YAAY,QAAQ,WAAW,SAC7B,OACA,SACA,aACA,YACA,WACA,IACF,GAAG;AAAA,IACD,IAAI,OAAO,MAAM,GAAG,MAAM;AAAA,EAC5B;AAAA,EAEA,MAAM,YAA4C,CAAC;AAAA,EAEnD,YAAY,QAAQ,SAAS,SAAS;AAAA,IACpC,UAAU,UAAU,MAAM,MAAM,SAAS;AAAA,EAC3C;AAAA,EAEA,OAAO;AAAA;AAOT,SAAS,QAAQ,CACf,OACA,SACA,aACA,YACA,WACA,MACoC;AAAA,EACpC,MAAM,SAAS,MAAM,IAAI;AAAA,EACzB,MAAM,QAA4B,CAAC;AAAA,EAOnC,MAAM,cAAc,CAClB,QACA,OACA,SACA,WAC4B;AAAA,IAC5B,MAAM,YAAY,UAAU,OAAO,SAAS;AAAA,MAC1C;AAAA,SACI,UAAU,YAAY,CAAC,IAAI,EAAE,MAAM;AAAA,SACnC,YAAY,YAAY,CAAC,IAAI,EAAE,QAAQ;AAAA,MAC3C,QAAQ,UAAU,CAAC;AAAA,IACrB,CAAC;AAAA,IAED,MAAM,MACJ,UAAU,YACN,WAAW,IAAI,YAAY,MAAM,GAAG,SAAS,IAC7C,UAAU,IAAI,QAAQ,OAAO,WAAW,IAAI;AAAA,IAElD,OAAO;AAAA;AAAA,EAGT,IAAI,QAAQ,UAAU,QAAQ,SAAS,QAAQ,WAAW,QAAQ,MAAM;AAAA,IACtE,MAAM,KAAK;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,QACE,MAAM;AAAA,UACJ;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,UAAU,IACR,QAAQ,kBACR,qBACA,UAAU,OAAO,SAAS;AAAA,YACxB,QAAQ,QAAQ;AAAA,YAChB,OAAO;AAAA,YACP,SAAS;AAAA,YACT,QAAQ,EAAE,OAAO;AAAA,UACnB,CAAC,GACD,IACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,eAAe,YAAY,UAAU;AAAA,IAC9C,MAAM,SAAS,YAAY,UAAU;AAAA,IAErC,MAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM;AAAA,UACJ,KACE,YAAY,OACZ,YAAY,eACV,2BAA2B,YAAY,MAC3C;AAAA,QACF;AAAA,QACA,SAAS,CAAC,YAAY,QAAQ,YAAY,OAAO,YAAY,OAAO,CAAC;AAAA,MACvE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,YAAY,YAAY,WAAW;AAAA,IAC5C,MAAM,YAAY,SAAS,SACvB,QAAQ,SAAS,QAAQ,qBAAqB,IAAI,IAClD;AAAA,IAEJ,MAAM,KAAK;AAAA,MACT,SAAS;AAAA,MACT;AAAA,QACE,MAAM,CAAC,KAAK,SAAS,OAAO,SAAS,WAAW,CAAC;AAAA,QACjD,SAAS,YACL,YAAY,WAAW,SAAS,QAAQ,WAAW,IAAI,IACvD;AAAA,UACE,YACE,SAAS,QACT,SAAS,OACT,SAAS,SACT,SAAS,MACX;AAAA,QACF;AAAA,WACA,SAAS,UAAU,EAAE,SAAS,SAAS,QAAQ,IAAI,CAAC;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,QAAQ,QAAQ,MAAM,IAAI,UAAU;AAAA,IACtC,MAAM,aAAa,aAAa,MAAM,IAAI,QAAQ;AAAA,IAElD,IAAI,YAAY;AAAA,MACd,MAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,UACE,MAAM;AAAA,YACJ,KACE,WAAW,OACX,gDACF;AAAA,UACF;AAAA,UACA,SAAS,CAAC,YAAY,KAAK,WAAW,OAAO,WAAW,OAAO,CAAC;AAAA,QAClE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM;AAAA,UACJ,KAAK,kBAAkB,yCAAyC;AAAA,QAClE;AAAA,QACA,SAAS;AAAA,UACP,YACE,KACA,kBACA,mCACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KAAK;AAAA,IACT;AAAA,IACA;AAAA,MACE,MAAM;AAAA,QACJ,KACE,yBACA,mDACF;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP,YAAY,KAAK,yBAAyB,uBAAuB;AAAA,MACnE;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,OAAO;AAAA;AA8BT,SAAS,IAAI,CAAC,MAA0B,MAAoB;AAAA,EAC1D,OAAO,SAAS,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK;AAAA;AAQtD,SAAS,OAAO,CAAC,QAA0B,WAA8B;AAAA,EACvE,IAAI,OAAO,OAAO,gBAAgB,UAAU;AAAA,IAC1C,OAAO,CAAC,KAAK,UAAU,OAAO,KAAK,MAAM,GAAG,OAAO,WAAW,CAAC;AAAA,EACjE;AAAA,EAEA,OAAO,WAAW,UAAU,MAAM,GAAG,UAAU,OAAO,IAAI,EAAE,QAC1D,CAAC,WACC,OAAO,OAAO,gBAAgB,WAC1B,CAAC,KAAK,UAAU,OAAO,KAAK,MAAM,GAAG,OAAO,WAAW,CAAC,IACxD,CAAC,CACT;AAAA;AASF,SAAS,SAAS,CAAC,QAA4C;AAAA,EAC7D,IACE,OAAO,OAAO,gBAAgB,YAC7B,CAAC,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC,MAAM,QAAQ,OAAO,KAAK,GAC5D;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAEA,QAAQ,aAAa,MAAM,UAAU;AAAA,EAErC,OAAO;AAAA;AAqBT,SAAS,KAAK,CAAC,MAAyB,WAAsC;AAAA,EAC5E,MAAM,UAAU,SAAS,KAAK,QAAQ,CAAC,WAAW,OAAO,OAAO,CAAC;AAAA,EACjE,MAAM,UAAwC,CAAC;AAAA,EAE/C,WAAW,UAAU,MAAM;AAAA,IACzB,YAAY,MAAM,WAAW,OAAO,QAAQ,OAAO,WAAW,CAAC,CAAC,GAAG;AAAA,MACjE,QAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,aAAa,QAAQ,IAAI;AAAA,OACrB,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,OACjD,QAAQ,SAAS,IACjB;AAAA,MACE,SAAS;AAAA,QACP,oBAAoB,EAAE,QAAQ,QAAQ,SAAS,SAAS,EAAE;AAAA,MAC5D;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAAA;AAYF,SAAS,OAAO,CAAC,MAAiC;AAAA,EAChD,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,QAAgB,CAAC;AAAA,EAEvB,WAAW,UAAU,MAAM;AAAA,IACzB,WAAW,QAAQ,OAAO,MAAM;AAAA,MAC9B,MAAM,MAAM,GAAG,KAAK,QAAQ;AAAA,EAAO,KAAK;AAAA,MAExC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAAA,QAClB,KAAK,IAAI,GAAG;AAAA,QACZ,MAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ;AAAA,EAEf,IAAI,MAAM,WAAW,KAAK,MAAM;AAAA,IAC9B,OAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM,SAAS,GAAG;AAAA,IACpB,OAAO,MACJ,IAAI,CAAC,SACJ,KAAK,SAAS,YACV,KAAK,KAAK,SACV,OAAO,KAAK,WAAW,KAAK,MAClC,EACC,KAAK;AAAA,CAAI;AAAA,EACd;AAAA,EAEA,OAAO,KAAK,KAAK,CAAC,WAAW,OAAO,WAAW,GAAG,eAAe;AAAA;AAcnE,SAAS,OAAO,CACd,SACA,WACyB;AAAA,EACzB,OAAO,QAAQ;AAAA,EAEf,IAAI,QAAQ,WAAW,KAAK,MAAM;AAAA,IAChC,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,UAAU,OAAO;AAAA,EAEtC,IAAI,iBAAiB,WAAW;AAAA,IAC9B,OAAO,EAAE,OAAO,QAAQ;AAAA,EAC1B;AAAA,EAEA,MAAM,UAAkC,CAAC;AAAA,EAEzC,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,MAAO,OAA8B;AAAA,IAC3C,MAAM,OAAO,OAAO,QAAQ,WAAW,UAAU,OAAO,GAAG,IAAI;AAAA,IAE/D,IAAI,OAAO,QAAQ,YAAY,SAAS,WAAW;AAAA,MACjD,OAAO,EAAE,OAAO,QAAQ;AAAA,IAC1B;AAAA,IAEA,QAAQ,QAAQ;AAAA,EAClB;AAAA,EAEA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,eAAe,EAAE,cAAc,QAAQ;AAAA,EACzC;AAAA;AAGF,SAAS,QAAQ,CACf,SAC2B;AAAA,EAC3B,MAAM,OAAO,IAAI;AAAA,EAEjB,OAAO,QAAQ,OAAO,CAAC,WAAW;AAAA,IAChC,MAAM,cAAc,KAAK,UAAU,MAAM;AAAA,IAEzC,IAAI,KAAK,IAAI,WAAW,GAAG;AAAA,MACzB,OAAO;AAAA,IACT;AAAA,IAEA,KAAK,IAAI,WAAW;AAAA,IAEpB,OAAO;AAAA,GACR;AAAA;AAGH,SAAS,cAAc,CAAC,QAAwB;AAAA,EAC9C,IAAI,WAAW,OAAO;AAAA,IACpB,OAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAO,WAAW,GAAG,IACxB,wBACA,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA;AAQhC,IAAM,SAAqB;AAAA,EACzB,MAAM;AAAA,EACN,OAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,CAAC,WAAW,MAAM;AAAA,IAC5B,YAAY;AAAA,MACV,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,MAAM,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,CAAC,UAAU,QAAQ,EAAE,EAAE;AAAA,IAC/D;AAAA,EACF;AACF;AAOA,SAAS,YAAY,CACnB,UACgD;AAAA,EAChD,IAAI,aAAa,UAAU,aAAa,UAAU;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,OAAO,aAAa,SAChB,EAAE,OAAO,kBAAkB,SAAS,2BAA2B,IAC/D,EAAE,OAAO,kBAAkB,SAAS,yBAAyB;AAAA;AAGnE,SAAS,UAAU,CAAC,OAAuB;AAAA,EACzC,OAAO,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AAAA;AAGtD,SAAS,UAAU,CAAC,OAAuB;AAAA,EACzC,OAAO,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AAAA;;AG/2BtD;;;ACuDA,IAAM,WAAuC;AAAA,EAC3C,QAAQ;AAAA,IACN,QACE;AAAA,IACF,WAAW;AAAA,MACT,QACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,QACE;AAAA,IACF,OAAO;AAAA,IACP,WAAW;AAAA,MACT,QACE;AAAA,MACF,OACE;AAAA,IACJ;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,QACE;AAAA,IACF,WAAW;AAAA,MACT,QACE;AAAA,IACJ;AAAA,EACF;AACF;AAoBO,SAAS,QAAQ,CAAC,SAAkC;AAAA,EACzD,MAAM,SAAS,QAAQ,UAAU,SAAS,QAAQ;AAAA,EAClD,MAAM,QAAQ,WAAW,QAAQ,SAAS,mBAAmB;AAAA,EAC7D,MAAM,MAAM,WAAW,QAAQ,WAAW;AAAA,EAE1C,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,QACH,gCAAgC,WAAW,OAAO,KAAK,KAAK,SAAS,OAAO,WAAW,KAAK,SAC5F;AAAA,IACJ;AAAA,IACA;AAAA,IACA,KAAK,QAAQ,IAAI,GAAG;AAAA,IACpB,gBAAgB,WAAW,OAAO,MAAM,KAAK,SAAS,OAAO,WAAW,MAAM;AAAA,IAC9E,UAAU,QAAQ,IAAI,GAAG;AAAA,IACzB;AAAA,IACA;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK;AAAA,CAAI;AAAA;AAGd,SAAS,IAAI,CAAC,IAAY,KAAqB;AAAA,EAC7C,IAAI,OAAO,UAAU;AAAA,IACnB,OAAO,wCAAwC;AAAA,EACjD;AAAA,EAEA,IAAI,OAAO,SAAS;AAAA,IAClB,OAAO,oBAAoB;AAAA,EAC7B;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,SAAS,CAAC,IAAY,KAAqB;AAAA,EAClD,IAAI,OAAO,cAAc;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EAEA,OAAO;AAAA,IACL;AAAA,IACA,2BAA2B;AAAA,IAC3B;AAAA,EACF,EAAE,KAAK;AAAA,CAAI;AAAA;AAUb,SAAS,QAAQ,CAAC,WAAuC;AAAA,EACvD,OAAO,YACH,eAAe,WAAW,SAAS,+BACnC;AAAA;AAUN,SAAS,UAAU,CAAC,OAAuB;AAAA,EACzC,OAAO,MACJ,WAAW,KAAK,OAAO,EACvB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,QAAQ,EACxB,WAAW,KAAK,OAAO;AAAA;;;ADnGrB,MAAM,eAIX;AAAA,EAcmB;AAAA,EAZV;AAAA,EAGA;AAAA,EAID;AAAA,EAEA;AAAA,EAER,WAAW,CACQ,SACjB,cACA,QACA;AAAA,IAHiB;AAAA,IAIjB,MAAM,SAAS,CAAC,QAAQ;AAAA,IAExB,MAAM,OAAO,MAAM;AAAA,MACjB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,EAAE,SAAS,iBAAiB,MAAM,CAAC,MAAM,GAAG,OAAO;AAAA,MACzD,SAAS,MAAM,KAAK;AAAA,IACtB,CAAC;AAAA,IAED,MAAM,KAAK,MAAM;AAAA,MACf,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM,EAAE,SAAS,0BAA0B,MAAM,CAAC,MAAM,GAAG,OAAO;AAAA,MAClE,SAAS,MACP,IAAI,SAAS,KAAK,MAAM;AAAA,QACtB,SAAS,EAAE,gBAAgB,2BAA2B;AAAA,MACxD,CAAC;AAAA,IACL,CAAC;AAAA,IAWD,KAAK,OAAO,KAAK,MAAM,MAAM,aAAa;AAAA,IAC1C,KAAK,KACH,QAAQ,OAAO,QAAQ,YAAY,KAAK,IAAI,MAAM,OAAO;AAAA;AAAA,EASrD,MAAM,CACZ,MACkC;AAAA,IAClC,IAAI,CAAC,KAAK,QAAQ,gBAAgB,OAAO,OAAO,MAAM,MAAM,GAAG;AAAA,MAC7D,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,KAAK,MAAM,MAAM,qBAAqB;AAAA;AAAA,GAY9C,QAAQ,CAAC,KAAgB;AAAA,IACxB,MAAM,YAAY,QAAQ,KAAK;AAAA,MAC7B,MAAM,KAAK,QAAQ;AAAA,SACf,KAAK,QAAQ,UAAU,EAAE,SAAS,KAAK,QAAQ,QAAQ,IAAI,CAAC;AAAA,SAC5D,KAAK,QAAQ,SAAS,EAAE,QAAQ,KAAK,QAAQ,OAAO,IAAI,CAAC;AAAA,SACzD,KAAK,QAAQ,OAAO,EAAE,MAAM,KAAK,OAAO,KAAK,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,IACtE,CAAC;AAAA,IAED,KAAK,WAAW,UAAU;AAAA,IAE1B,MAAM,KAAK,KAAK,QAAQ,MAAM;AAAA,IAC9B,MAAM,OAAgB,KAAK;AAAA,IAC3B,MAAM,SAAS,IAAI,QAAQ,KAAK,CAAC,UAAU,MAAM,QAAQ,IAAI;AAAA,IAE7D,IAAI,OAAO,SAAS,QAAQ;AAAA,MAC1B,KAAK,OAAO,SAAS;AAAA,QACnB;AAAA,QACA,aAAa,OAAO;AAAA,QACpB,OAAO,KAAK,QAAQ,SAAS,KAAK,QAAQ,KAAK;AAAA,WAC3C,KAAK,QAAQ,SAAS,EAAE,QAAQ,KAAK,QAAQ,OAAO,IAAI,CAAC;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,SAAS,KAAK,QAAQ,aAAa;AAAA,IAEzC,WAAW,WAAW,UAAU,UAAU;AAAA,MACxC,OAAO,OAAO;AAAA,IAChB;AAAA;AAEJ;AAsBO,SAAS,IAIf,CACC,SAC+D;AAAA,EAC/D,OAAO,IAAI,eACT,SACA,QAAQ,QAAQ,iBAChB,QAAQ,UAAU,OACpB;AAAA;AAGF,SAAS,IAAI,CAAC,SAAiC;AAAA,EAC7C,QAAQ,KACN,QAAQ,UAAU,KACd,aAAa,QAAQ,YACrB,aAAa,QAAQ,UAAU,QAAQ,SAC7C;AAAA;;;AEjFK,SAAS,OAAO,CAAC,KAAU,SAA0C;AAAA,EAC1E,MAAM,QAAwC,CAAC;AAAA,EAC/C,MAAM,WAA+B,CAAC;AAAA,EACtC,MAAM,UAAmC,CAAC;AAAA,EAC1C,MAAM,aAAa,iBAAiB;AAAA,EACpC,MAAM,aAAY,UAChB,YACA,cAAc,QAAQ,MAAM,CAC9B;AAAA,EACA,MAAM,MAAM,aAAa;AAAA,EACzB,MAAM,YAAY,IAAI,QAAQ,OAC5B,CAAC,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,IAAI,MAAM,MAC3C;AAAA,EAEA,WAAW,SAAS,WAAW;AAAA,IAC7B,iBAAiB,OAAO,UAAS;AAAA,EACnC;AAAA,EASA,MAAM,WAAW,IAAI;AAAA,EAIrB,MAAM,OAAO,IAAI;AAAA,EAEjB,WAAW,SAAS,WAAW;AAAA,IAC7B,MAAM,WAAW,WAAW,MAAM,IAAI;AAAA,IACtC,MAAM,QAAQ,GAAG,MAAM,UAAU,MAAM;AAAA,IAEvC,MAAM,YAAY,YAChB,OACA,IAAI,SACJ,YACA,YACA,KACA,CAAC,YAAY;AAAA,MACX,SAAS,KAAK,EAAE,OAAO,QAAQ,CAAC;AAAA,KAEpC;AAAA,IASA,WAAW,eAAe,gBAAgB,MAAM,KAAK,EAAE,UAAU;AAAA,MAC/D,MAAM,UAAU,QAAQ,YAAY;AAAA,MAEpC,IAAI,YAAY,WAAW;AAAA,QACzB,QAAQ,YAAY,QAAQ,YAAY;AAAA,QAExC;AAAA,MACF;AAAA,MAEA,IAAI,KAAK,UAAU,OAAO,MAAM,KAAK,UAAU,YAAY,MAAM,GAAG;AAAA,QAClE,SAAS,KAAK;AAAA,UACZ;AAAA,UACA,SAAS,wBAAwB,YAAY;AAAA,QAC/C,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,GAAG,MAAM,OAAO,YAAY,KAAK;AAAA,IAC9C,MAAM,QAAQ,SAAS,IAAI,IAAI;AAAA,IAE/B,IAAI,OAAO;AAAA,MACT,SAAS,KAAK;AAAA,QACZ;AAAA,QACA,SAAS,GAAG,oCAAoC;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,IAEA,SAAS,IAAI,MAAM,KAAK;AAAA,IAExB,WAAW,OAAO,UAAU,QAAQ,CAAC,GAAG;AAAA,MACtC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAAA,QAClB,KAAK,IAAI,KAAK,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,MAAM,YAAY;AAAA,SACb,MAAM;AAAA,OACR,MAAM,OAAO,YAAY,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAAQ,OAAO,OAAO,QAAQ,MAAM,MAAM,QAAQ,IAAI;AAAA,EAEnE,OAAO;AAAA,IACL,UAAU;AAAA,MACR,SAAS;AAAA,MACT,MAAM,QAAQ;AAAA,SACV,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,SAClD,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACvB;AAAA,SACG,aAAa,SAAS,WAAW,OAAO;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AAAA;AAaF,SAAS,MAAM,CACb,WACA,MACA,UACa;AAAA,EACb,MAAM,OAAoB,OAAO,QAAQ,SAAS,EAAE,IAClD,EAAE,MAAM,kBAAkB,EAAE,MAAM,YAAY,EAChD;AAAA,EAEA,YAAY,MAAM,UAAU,MAAM;AAAA,IAChC,IAAI,OAAO,OAAO,WAAW,IAAI,GAAG;AAAA,MAClC;AAAA,IACF;AAAA,IAEA,KAAK,KAAK,EAAE,KAAK,CAAC;AAAA,IAClB,SAAS,KAAK;AAAA,MACZ;AAAA,MACA,SAAS,YAAY;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,QAAQ,OAAO,KAAK,SAAS,GAAG;AAAA,IACzC,IAAI,CAAC,KAAK,IAAI,IAAI,GAAG;AAAA,MACnB,SAAS,KAAK;AAAA,QACZ,OAAO;AAAA,QACP,SAAS,YAAY;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAQT,SAAS,YAAY,CACnB,iBACA,SAC0C;AAAA,EAC1C,MAAM,aAAa;AAAA,OACb,OAAO,KAAK,eAAe,EAAE,SAAS,IAAI,EAAE,gBAAgB,IAAI,CAAC;AAAA,OACjE,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvD;AAAA,EAEA,OAAO,OAAO,KAAK,UAAU,EAAE,SAAS,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA;",
17
+ "debugId": "3A3B60517CA111D464756E2164756E21",
18
18
  "names": []
19
19
  }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Checking a response against the document, in a test.
3
+ *
4
+ * The document describes what every operation can answer; a test provokes
5
+ * one answer. `assertDescribed` holds the two together: the status is
6
+ * declared, the body is one the status describes, a header asked about is
7
+ * documented. What it catches is what a client generated from the document
8
+ * would trip over — an error code nobody declared, a field the schema says
9
+ * is always there and is not.
10
+ *
11
+ * It checks only what a test provoked, which is why it can be strict: the
12
+ * core does not compare a thrown error with the route's response map,
13
+ * because a guard's refusal would be reported on every route it runs on;
14
+ * a test that provoked the refusal asks about that one response.
15
+ *
16
+ * ```ts
17
+ * import { assertDescribed } from "@tetsujs/openapi/testing";
18
+ *
19
+ * const { document } = openapi(app, { info });
20
+ *
21
+ * test("a wrong code is what the document says", async () => {
22
+ * const res = await request("/session", { method: "POST", body });
23
+ *
24
+ * await assertDescribed(document, "POST /session", res);
25
+ * });
26
+ * ```
27
+ *
28
+ * @module
29
+ */
30
+ import type { OpenApiDocument } from "./document.ts";
31
+ /** What `assertDescribed` checks besides the status and the body's shape. */
32
+ export interface AssertDescribedOptions {
33
+ /**
34
+ * Checks the body against its schema in full, with the JSON Schema
35
+ * validator of your choice — this package has none, and without one
36
+ * only the top level is compared: required fields, fields that are a
37
+ * `const`. Return `true` when the body is valid, or what is wrong.
38
+ *
39
+ * The schema stands on its own: every `$ref` into the document's
40
+ * components points into its own `$defs`.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const ajv = new Ajv2020();
45
+ *
46
+ * await assertDescribed(document, "POST /session", res, {
47
+ * validate: (schema, body) => ajv.validate(schema, body) || ajv.errorsText(),
48
+ * });
49
+ * ```
50
+ */
51
+ readonly validate?: (schema: Record<string, unknown>, body: unknown) => true | string;
52
+ /**
53
+ * Headers the status must declare when the response carries them —
54
+ * `retry-after`. Only those named: a response carries headers no
55
+ * document describes, `content-type` and `x-request-id` among them.
56
+ */
57
+ readonly headers?: readonly string[];
58
+ }
59
+ /**
60
+ * Throws unless the response is one the document describes for the
61
+ * operation, listing every way it is not.
62
+ *
63
+ * `request` names the operation as the test called it — a method and the
64
+ * path it requested, `"GET /users/42"` — matched against the document's
65
+ * path templates. The body is read from a clone, and the test can still
66
+ * read the response.
67
+ */
68
+ export declare function assertDescribed(document: OpenApiDocument, request: string, response: Response, options?: AssertDescribedOptions): Promise<void>;
69
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,eAAe,CAAC;AAErE,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,OAAO,KACV,IAAI,GAAG,MAAM,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,203 @@
1
+ // @bun
2
+ // packages/openapi/src/testing.ts
3
+ async function assertDescribed(document, request, response, options = {}) {
4
+ const problems = await problemsOf(document, request, response, options);
5
+ if (problems.length > 0) {
6
+ throw new Error(`${request} answered ${response.status}, which the document does not describe:
7
+ ${problems.map((problem) => `- ${problem}`).join(`
8
+ `)}`);
9
+ }
10
+ }
11
+ async function problemsOf(document, request, response, options) {
12
+ const [method = "", target = ""] = request.split(" ");
13
+ const path = target.split("?")[0] ?? "";
14
+ const template = templateOf(document, path);
15
+ const operation = template === undefined ? undefined : document.paths[template]?.[method.toLowerCase()];
16
+ if (operation === undefined) {
17
+ return [`there is no operation for ${method.toUpperCase()} ${path}`];
18
+ }
19
+ const status = String(response.status);
20
+ const described = operation.responses[status];
21
+ if (described === undefined) {
22
+ return [
23
+ `${status}, which the operation does not declare: it declares ${Object.keys(operation.responses).join(", ")}`
24
+ ];
25
+ }
26
+ return [
27
+ ...await bodyProblems(document, status, described, response, options),
28
+ ...headerProblems(status, described, response, options.headers ?? [])
29
+ ];
30
+ }
31
+ function templateOf(document, path) {
32
+ const segments = path.split("/").filter(Boolean);
33
+ let best;
34
+ for (const template of Object.keys(document.paths)) {
35
+ const parts = template.split("/").filter(Boolean);
36
+ const last = parts.at(-1) ?? "";
37
+ const rest = isParameter(last) && segments.length > parts.length;
38
+ if (parts.length !== segments.length && !rest) {
39
+ continue;
40
+ }
41
+ let literals = 0;
42
+ let matches = true;
43
+ for (const [index, part] of parts.entries()) {
44
+ if (isParameter(part)) {
45
+ continue;
46
+ }
47
+ if (part !== segments[index]) {
48
+ matches = false;
49
+ break;
50
+ }
51
+ literals += 1;
52
+ }
53
+ if (matches && (best === undefined || literals > best.literals)) {
54
+ best = { template, literals };
55
+ }
56
+ }
57
+ return best?.template;
58
+ }
59
+ function isParameter(segment) {
60
+ return segment.startsWith("{") && segment.endsWith("}");
61
+ }
62
+ async function bodyProblems(document, status, described, response, options) {
63
+ const text = await response.clone().text();
64
+ const content = described.content ?? {};
65
+ const mediaTypes = Object.keys(content);
66
+ if (text === "") {
67
+ return [];
68
+ }
69
+ if (mediaTypes.length === 0) {
70
+ return [`a body, where its ${status} describes none`];
71
+ }
72
+ const mediaType = (response.headers.get("content-type") ?? "").split(";")[0]?.trim();
73
+ if (mediaType === undefined || !mediaTypes.includes(mediaType)) {
74
+ return [
75
+ `a body of type "${mediaType ?? ""}", where its ${status} describes ${mediaTypes.join(", ")}`
76
+ ];
77
+ }
78
+ const schema = content[mediaType]?.schema;
79
+ if (schema === undefined || !mediaType.endsWith("json")) {
80
+ return [];
81
+ }
82
+ let body;
83
+ try {
84
+ body = JSON.parse(text);
85
+ } catch {
86
+ return [`a body that is not the JSON its ${status} describes`];
87
+ }
88
+ const problems = shapeProblems(document, status, schema, body);
89
+ if (options.validate) {
90
+ const verdict = options.validate(standalone(document, schema), body);
91
+ if (verdict !== true) {
92
+ problems.push(verdict);
93
+ }
94
+ }
95
+ return problems;
96
+ }
97
+ function shapeProblems(document, status, schema, body) {
98
+ const alternatives = alternativesOf(document, schema);
99
+ const misfits = alternatives.map((alternative) => misfitOf(alternative, body));
100
+ if (misfits.some((misfit) => misfit === undefined)) {
101
+ return [];
102
+ }
103
+ const field = tellingField(alternatives);
104
+ if (field !== undefined && isRecord(body) && field in body) {
105
+ const listed = alternatives.map((alternative) => constOf(propertiesOf(alternative)[field])).filter((value) => value !== undefined);
106
+ if (!listed.includes(body[field])) {
107
+ return [
108
+ `${field} ${JSON.stringify(body[field])}, which its ${status} does not list: ${listed.map(String).join(", ")}`
109
+ ];
110
+ }
111
+ }
112
+ const reasons = [...new Set(misfits)];
113
+ return [
114
+ reasons.length === 1 ? `a body that ${reasons[0]}` : `a body that fits none of the ${alternatives.length} its ${status} describes: ${reasons.join("; ")}`
115
+ ];
116
+ }
117
+ function alternativesOf(document, schema) {
118
+ const resolved = resolve(document, schema);
119
+ const union = resolved.anyOf ?? resolved.oneOf;
120
+ if (Array.isArray(union)) {
121
+ return union.flatMap((branch) => isRecord(branch) ? alternativesOf(document, branch) : []);
122
+ }
123
+ return [resolved];
124
+ }
125
+ function resolve(document, schema) {
126
+ const ref = schema.$ref;
127
+ if (typeof ref !== "string" || !ref.startsWith("#/components/schemas/")) {
128
+ return schema;
129
+ }
130
+ const target = document.components?.schemas?.[ref.slice("#/components/schemas/".length)];
131
+ return isRecord(target) ? target : schema;
132
+ }
133
+ function misfitOf(alternative, body) {
134
+ const properties = propertiesOf(alternative);
135
+ const required = Array.isArray(alternative.required) ? alternative.required : [];
136
+ if (alternative.type === "object" || required.length > 0) {
137
+ if (!isRecord(body)) {
138
+ return "is not an object";
139
+ }
140
+ const missing = required.filter((name) => !(name in body));
141
+ if (missing.length > 0) {
142
+ return `lacks ${missing.join(", ")}`;
143
+ }
144
+ for (const [name, property] of Object.entries(properties)) {
145
+ const expected = constOf(property);
146
+ if (expected !== undefined && name in body && body[name] !== expected) {
147
+ return `has ${name} ${JSON.stringify(body[name])} where it is ${JSON.stringify(expected)}`;
148
+ }
149
+ }
150
+ }
151
+ return;
152
+ }
153
+ function tellingField(alternatives) {
154
+ const [first] = alternatives;
155
+ if (first === undefined) {
156
+ return;
157
+ }
158
+ return Object.keys(propertiesOf(first)).find((name) => name !== "status" && alternatives.every((alternative) => typeof constOf(propertiesOf(alternative)[name]) === "string"));
159
+ }
160
+ function propertiesOf(schema) {
161
+ return isRecord(schema.properties) ? schema.properties : {};
162
+ }
163
+ function constOf(value) {
164
+ if (!isRecord(value)) {
165
+ return;
166
+ }
167
+ const property = value;
168
+ if ("const" in property) {
169
+ return property.const;
170
+ }
171
+ return Array.isArray(property.enum) && property.enum.length === 1 ? property.enum[0] : undefined;
172
+ }
173
+ function standalone(document, schema) {
174
+ const repoint = (value) => {
175
+ if (Array.isArray(value)) {
176
+ return value.map(repoint);
177
+ }
178
+ if (!isRecord(value)) {
179
+ return value;
180
+ }
181
+ return Object.fromEntries(Object.entries(value).map(([key, inner]) => [
182
+ key,
183
+ key === "$ref" && typeof inner === "string" ? inner.replace("#/components/schemas/", "#/$defs/") : repoint(inner)
184
+ ]));
185
+ };
186
+ return {
187
+ ...repoint(schema),
188
+ $defs: repoint(document.components?.schemas ?? {})
189
+ };
190
+ }
191
+ function headerProblems(status, described, response, names) {
192
+ const declared = Object.keys(described.headers ?? {}).map((name) => name.toLowerCase());
193
+ return names.filter((name) => response.headers.has(name) && !declared.includes(name.toLowerCase())).map((name) => `the header "${name}", which its ${status} does not declare`);
194
+ }
195
+ function isRecord(value) {
196
+ return value !== null && typeof value === "object" && !Array.isArray(value);
197
+ }
198
+ export {
199
+ assertDescribed
200
+ };
201
+
202
+ //# debugId=608BF03DC34E084D64756E2164756E21
203
+ //# sourceMappingURL=testing.js.map