@kubb/plugin-msw 6.2.0-canary.20261111T122007 → 6.2.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["ast","camelCase","defineGenerator","camelCase","ast","ast","Url","File","Function","File","Function","defineGenerator","jsxRenderer","ast","pluginFakerName","pluginTsName","enumTypeName","File","createResolver","camelCase","defineExtension","pluginTsName","pluginFakerName","Resolver"],"sources":["../../../internals/shared/src/operation.ts","../../../internals/shared/src/resolver.ts","../../../internals/shared/src/group.ts","../kubb-extension.json","../package.json","../src/generators/handlersGenerator.ts","../src/utils.ts","../src/components/Mock.tsx","../src/components/Response.tsx","../src/generators/mswGenerator.tsx","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["import { ast, type Group, type Memo, type Output, type Resolver, type ResolverFileParams } from '@kubb/kit'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves the file a schema-emitting plugin (`plugin-ts`, `plugin-zod`, `plugin-faker`) writes\n * `node` to, cached in `ctx.memo` under the resolver's plugin name and the\n * operation. The plugin itself and every plugin that imports from it call this, so they all get\n * the same path.\n *\n * When that path matches the file of a component schema in `ctx.driver.inputNode`, ignoring case, the file name\n * gets an `Operation` suffix: operation `point` goes to `PointOperation.ts` next to schema `Point.ts`.\n * Otherwise the two merge into one file, or overwrite each other on a case-insensitive file system.\n * Only the file name changes. The declarations keep their names.\n *\n * @example Resolve `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveOperationFile({ ctx, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveOperationFile(options: {\n ctx: { memo: Memo; driver: { inputNode?: { schemas: ReadonlyArray<ast.SchemaNode> } | null } }\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { ctx, node, resolver, root, output } = options\n const { memo } = ctx\n const location = { root, output, group: options.group ?? undefined }\n\n return memo(`${resolver.pluginName}:operationFile:${node.operationId}`, () => {\n const schemaPaths = memo(\n `${resolver.pluginName}:schemaFilePaths`,\n () =>\n new Set(\n (ctx.driver.inputNode?.schemas ?? []).flatMap((schema) =>\n schema.name ? [resolver.file({ name: schema.name, extname: '.ts', ...location }).path.toLowerCase()] : [],\n ),\n ),\n )\n let file = resolver.file({ ...operationFileEntry(node, node.operationId), ...location })\n\n for (let name = `${node.operationId}Operation`; schemaPaths.has(file.path.toLowerCase()); name += 'Operation') {\n const next = resolver.file({ ...operationFileEntry(node, name), ...location })\n // A single-file output holds every declaration on purpose, so a new name changes nothing.\n if (next.path === file.path) break\n file = next\n }\n\n return file\n })\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n cookies(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\nexport type BuildOperationCommentsOptions = {\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<Exclude<ast.ParameterNode['in'], 'querystring'>, Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\n/**\n * The operation's method and path as plain text, such as `` `GET /pet/{petId}` ``. A path is not a valid `{@link}` target.\n */\nfunction getOperationRequestLine(node: ast.OperationNode): string | null {\n return ast.isHttpOperationNode(node) && node.path ? `\\`${node.method.toUpperCase()} ${node.path}\\`` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\ntype ResponseType = 'blob' | 'text' | 'stream'\n\nfunction baseContentType(contentType: string): string {\n return contentType.split(';')[0]!.trim().toLowerCase()\n}\n\ntype ResponseContentEntry = { contentType: string; schema?: ast.SchemaNode | null; stream?: ast.ContentNode['stream'] }\n\n/**\n * Whether a content entry is a sequence of JSON values the adapter marks as a stream, such as `application/jsonl`,\n * `application/x-ndjson`, `application/json-seq`, or any media type with an OpenAPI 3.2 `itemSchema`.\n */\nfunction isJsonLines(entry: ResponseContentEntry): boolean {\n const baseType = baseContentType(entry.contentType)\n // `multipart/mixed` is a stream of parts, not of JSON values.\n return Boolean(entry.stream) && baseType !== 'text/event-stream' && !baseType.startsWith('multipart/')\n}\n\n/**\n * How an operation streams its primary success response item by item, when that response declares one content type:\n * - `'event'` for `text/event-stream` whose `itemSchema` types the whole event with its own `event` and `data`\n * - `'data'` for `text/event-stream` typed by its payload only\n * - `'line'` for JSON Lines, one parsed JSON value per line\n *\n * Returns `null` for any other response, and for a response that also declares another content type, which stays a normal\n * call with its query hooks.\n */\nexport function getEventStream(node: ast.OperationNode): 'event' | 'data' | 'line' | null {\n const content = getPrimarySuccessResponse(node)?.content ?? []\n if (content.length !== 1) return null\n const entry = content[0]!\n if (baseContentType(entry.contentType) === 'text/event-stream') return entry.stream?.shape ?? 'data'\n return isJsonLines(entry) ? 'line' : null\n}\n\n/**\n * Whether an operation streams its primary success response, as Server-Sent Events or JSON Lines. The client generator uses\n * this to return a typed stream of items instead of a one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getEventStream(node) !== null\n}\n\n/**\n * Whether the primary success response offers `text/event-stream`, alone or next to other content types. The client asks\n * for the stream by default and ships the `sse.ts` runtime, so a mixed response can be read as events too.\n */\nexport function hasEventStreamContent(node: ast.OperationNode): boolean {\n const entries = getPrimarySuccessResponse(node)?.content ?? []\n // Next to another type, a stream without a schema gets no typed variant, so it keeps the plain call.\n return entries.some((entry) => baseContentType(entry.contentType) === 'text/event-stream' && (entries.length === 1 || Boolean(entry.schema)))\n}\n\nconst formContentTypes = new Set(['multipart/form-data', 'application/x-www-form-urlencoded'])\n\n/**\n * Whether the request body offers `multipart/form-data` or `application/x-www-form-urlencoded`, so the client registers the\n * form media types.\n */\nexport function hasFormBody(node: ast.OperationNode): boolean {\n return (node.requestBody?.content ?? []).some((entry) => formContentTypes.has(baseContentType(entry.contentType)))\n}\n\nfunction isJsonContentType(baseType: string): boolean {\n return baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json'\n}\n\n/**\n * Parser for one response content entry.\n *\n * JSON stays unset so the runtime detects it. `text/event-stream` and JSON Lines are streams. A binary schema\n * (`format: binary` / `contentMediaType`) is a blob even when the media type is not a well-known\n * binary type. Other `text/*` is text, and `application/octet-stream`, `application/pdf`,\n * `image/*`, `audio/*`, and `video/*` are blobs.\n */\nfunction responseTypeForContent(entry: ResponseContentEntry): ResponseType | undefined {\n const baseType = baseContentType(entry.contentType)\n if (!baseType) return undefined\n if (baseType === 'text/event-stream' || isJsonLines(entry)) return 'stream'\n if (isJsonContentType(baseType)) return undefined\n if (entry.schema?.type === 'blob') return 'blob'\n if (baseType.startsWith('text/')) return 'text'\n if (isBinaryContentType(baseType)) return 'blob'\n return undefined\n}\n\nfunction isBinaryContentType(baseType: string): boolean {\n return baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Returns the entry with the schema of the value the client returns: `string` for a body read as text, such as `Pet` on\n * `application/xml`, and `blob` for `image/*`, `audio/*`, `video/*`, PDF, and octet-stream. A binary schema elsewhere is a `Blob`\n * only through `parseAs: 'blob'`, which needs every entry in `entries` binary. JSON, vendor (`application/vnd.*`), stream,\n * schemaless, and wildcard entries keep their schema. `entries` is the response's full list of content types.\n */\nexport function toResponseContent<T extends ContentVariantInput & ResponseContentEntry>(entry: T, entries: ReadonlyArray<ResponseContentEntry> = [entry]): T {\n const { contentType, schema } = entry\n if (!schema || entry.stream) return entry\n\n const baseType = baseContentType(contentType)\n const resolved = ast.resolveRef(schema)\n if (isBinaryContentType(baseType)) {\n return resolved.type === 'blob' ? entry : { ...entry, schema: ast.factory.createSchema({ type: 'blob' }), keysToOmit: null }\n }\n const isPlainMediaType = Boolean(baseType) && !isJsonContentType(baseType) && !baseType.includes('*')\n if (resolved.type === 'blob') {\n // shortcut: an error response never gets `parseAs`, so a lone binary schema there reads as text too but stays `Blob`.\n const readsAsText = isPlainMediaType && !entries.every((item) => item.schema?.type === 'blob')\n return readsAsText ? { ...entry, schema: ast.factory.createSchema({ type: 'string' }), keysToOmit: null } : entry\n }\n if (resolved.primitive === 'string') return entry\n\n const responseType = responseTypeForContent(entry)\n // A response without a body, such as a 405, has no schema to read. Only `text/*` is always text.\n if (responseType !== 'text' && (resolved.type === 'unknown' || resolved.type === 'any' || resolved.type === 'void')) return entry\n const isVendorJson = /^[^/]+\\/vnd\\./.test(baseType) && !/(xml|yaml|yml|csv)$/.test(baseType)\n const isText = responseType === 'text' || (!responseType && isPlainMediaType && !isVendorJson)\n\n return isText ? { ...entry, schema: ast.factory.createSchema({ type: 'string' }), keysToOmit: null } : entry\n}\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...): `RequestConfig` minus what the\n * hook fills in, which is every request group and `throwOnError`. Unlike {@link buildRequestConfigType},\n * it never narrows `contentType`: query hooks wrap GET operations, which carry no request body to select\n * a content type for.\n */\nexport function buildClientOptionType(options: { omit?: Array<string> } = {}): string {\n const keys = [...requestGroupOrder, 'url', ...(options.omit ?? []), 'throwOnError']\n return `Partial<Omit<RequestConfig, ${keys.map((key) => `'${key}'`).join(' | ')}>>`\n}\n\n/**\n * The `client?:` option type of a mutation hook. When the operation has a request content type choice,\n * the mutation variables carry `contentType`, so the config leaves it out. Otherwise the ambiguous side is\n * narrowed to the operation's media types; a single-type side has nothing to pick, so it stays baked in the\n * generated call.\n */\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n if (hasRequestContentTypeChoice(node)) {\n return buildClientOptionType({ omit: ['contentType'] })\n }\n\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n const base = buildClientOptionType()\n return members.length ? `${base} & { contentType?: { ${members.join('; ')} } }` : base\n}\n\n/** The grouped request options, in the order generated signatures and calls list them. */\nexport const requestGroupOrder = ['path', 'query', 'body', 'headers', 'cookies'] as const\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n cookies: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header, cookie } = getOperationParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(node.requestBody?.content?.[0]?.schema),\n headers: header.length > 0,\n cookies: cookie.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = getOperationParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n // `cookies` never makes the parameter required: a browser sends its cookies itself and cannot set a `Cookie` header.\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !(groups.body && node.requestBody?.required === true),\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers, cookies }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups; names: Array<keyof RequestGroups> } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = requestGroupOrder.filter((key) => groups[key])\n\n // These callers never carry the `contentType` that several media types require.\n const optionsType = hasRequestContentTypeChoice(node)\n ? `Pick<${resolver.response.options(node)}, ${names.map((name) => `'${name}'`).join(' | ')}>`\n : resolver.response.options(node)\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${optionsType}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n names,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { splitLines = false } = options\n // The request line leads: free text after a block tag would belong to that tag.\n const comments = [\n getOperationRequestLine(node),\n node.description && `@description ${node.description}`,\n node.summary && `@summary ${node.summary}`,\n node.deprecated && '@deprecated',\n ]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\nconst operationParameterGroupsByNode = new WeakMap<ast.OperationNode, OperationParameterGroups>()\n\n/**\n * An OpenAPI 3.2 `querystring` parameter is the whole query string, so a form-encoded object becomes one query parameter\n * per property, typed and serialized like any other.\n * Another content type, such as JSON, stays one parameter named after it, and the runtime sends its value as the whole query string.\n */\nfunction spreadQuerystring(param: ast.ParameterNode): Array<ast.ParameterNode> {\n const schema = param.schema.type === 'ref' ? param.schema.schema : param.schema\n const formEncoded = !param.contentType || param.contentType.split(';')[0]!.trim().toLowerCase() === 'application/x-www-form-urlencoded'\n if (schema?.type !== 'object' || !formEncoded) return [param]\n return schema.properties.map((property) =>\n ast.factory.createParameter({ name: property.name, in: 'query', schema: property.schema, required: param.required && property.required }),\n )\n}\n\n/**\n * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each\n * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance\n * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the\n * same parameters once per plugin.\n */\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n const cached = operationParameterGroupsByNode.get(node)\n if (cached) return cached\n\n // A malformed spec can declare the same name twice within one location. Both would resolve to the\n // same output property, so emitting both would yield an object type with a duplicate member,\n // which TypeScript rejects. Keep the first.\n const dedupe = (params: Array<ast.ParameterNode>) => {\n const seen = new Set<string>()\n return params.filter((param) => {\n if (seen.has(param.name)) return false\n seen.add(param.name)\n return true\n })\n }\n const group = (location: ast.ParameterNode['in']) => dedupe(node.parameters.filter((param) => param.in === location))\n\n const groups: OperationParameterGroups = {\n path: group('path'),\n query: dedupe([...group('query'), ...group('querystring').flatMap(spreadQuerystring)]),\n header: group('header'),\n cookie: group('cookie'),\n }\n\n operationParameterGroupsByNode.set(node, groups)\n return groups\n}\n\n/**\n * Whether the operation declares more than one request media type with a schema, so a caller must pick one on `contentType`.\n */\nexport function hasRequestContentTypeChoice(node: ast.OperationNode): boolean {\n return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1\n}\n\n/**\n * Casts a call argument to the client's parameter type; a `'plain'` client is non-generic.\n */\nexport function castToClientOptions(callArg: string, clientName: string, returnType: 'full' | 'data' | 'plain' = 'full'): string {\n return `${callArg} as Parameters<typeof ${clientName}${returnType === 'plain' ? '' : '<true>'}>[0]`\n}\n\n/**\n * Builds the combined `{ body, path, query, headers, cookies }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. `cookies` appears only on an operation\n * with a cookie parameter, and stays optional because a browser sends its cookies itself. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same shape from the same inputs.\n * `primitive: 'object'` is a no-op for the TS printer and tells the Zod printer to emit `z.object(…)` rather\n * than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver, { pairContentTypes = false } = {}): ast.SchemaNode {\n const { path, query, header, cookie } = getOperationParameters(node)\n const hasBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n { name: 'cookies', params: cookie, resolve: resolver.param.cookies },\n ] as const\n\n const createOptions = (body: ast.SchemaNode, extra: Array<ast.PropertyNode> = []) =>\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({ name: 'body', required: hasBody && node.requestBody?.required === true, schema: body }),\n ...groups\n .filter(({ name, params }) => name !== 'cookies' || params.length > 0)\n .map(({ name, params, resolve }) => {\n const required = name !== 'cookies' && params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ...extra,\n ],\n })\n\n const variants =\n pairContentTypes && hasRequestContentTypeChoice(node) ? resolveContentTypeVariants(node.requestBody?.content ?? [], resolver.response.body(node)) : []\n if (variants.length < 2) {\n return createOptions(hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever())\n }\n\n // The first media type is the runtime default, so only the others must pass `contentType`. A bare string sets the\n // request content type at runtime, so it is accepted next to the `{ request }` form.\n return ast.factory.createSchema({\n type: 'union',\n members: variants.map((variant, index) => {\n const contentType = ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] })\n\n return createOptions(ast.factory.createSchema({ type: 'ref', name: variant.name }), [\n ast.factory.createProperty({\n name: 'contentType',\n required: index > 0,\n schema: ast.factory.createSchema({\n type: 'union',\n members: [\n contentType,\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [ast.factory.createProperty({ name: 'request', required: true, schema: contentType })],\n }),\n ],\n }),\n }),\n ])\n }),\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use.\n */\nfunction buildResponseRecordEntry(node: ast.OperationNode, res: ast.ResponseNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n // The runtime reports the bare media type, without parameters such as `charset` or `profile`.\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [baseContentType(variant.contentType)] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema: ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n */\nexport function buildResponses(node: ast.OperationNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver),\n }),\n ),\n })\n}\n\nexport function getStatusCodeNumber(statusCode: ast.StatusCode | number | string): number | null {\n const code = Number(statusCode)\n\n return Number.isNaN(code) ? null : code\n}\n\nexport function isSuccessStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 200 && code < 300\n}\n\nexport function isErrorStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 400\n}\n\nexport function getSuccessResponses<TResponse extends ResponseLike>(responses: ReadonlyArray<TResponse>): Array<TResponse> {\n return responses.filter((response) => isSuccessStatusCode(response.statusCode))\n}\n\nexport function getOperationSuccessResponses(node: ast.OperationNode): Array<ast.ResponseNode> {\n return getSuccessResponses(node.responses)\n}\n\nexport function getPrimarySuccessResponse(node: ast.OperationNode): ast.ResponseNode | null {\n return getOperationSuccessResponses(node)[0] ?? null\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\n/**\n * Lists the type names an operation's types file declares, computed once per resolver and `options` so every\n * dependent reads the same list.\n */\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver & Pick<Resolver, 'memo'>,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const key = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n return resolver.memo(`operationTypeNames:${key}`, () => {\n const { path, query, header, cookie } = getOperationParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ...cookie.map((param) => resolver.param.cookies(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n return names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n })\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = getStatusCodeNumber(response.statusCode)\n if (code === null) {\n continue\n }\n\n types.push([code, isSuccessStatusCode(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n","import { ensureValidVarName, toFilePath } from '@internals/utils'\nimport { ast, camelCase } from '@kubb/kit'\nimport type { GeneratorContext, Resolver, ResolverFile } from '@kubb/kit'\n\n/**\n * The shared top-level `name` of the operation plugins, computed once per operation name and build.\n */\nexport function resolveOperationName(this: Resolver, name: string): string {\n return this.memo(`operation:${name}`, () => ensureValidVarName(camelCase(name)))\n}\n\n/**\n * Builds the allocation key for a declaration an operation owns. `scope` names which declaration\n * it is, so two of them never share an allocation even when a custom resolver gives both the same\n * name. Leave `scope` empty for the operation's own declaration.\n *\n * The key starts from the operation's input `pointer`, which macros keep, so a plugin whose macro\n * rewrites the method or path still resolves another plugin's names for the same operation.\n *\n * @example\n * ```ts\n * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })\n * ```\n */\nexport function operationKey(node: ast.OperationNode, ...scope: Array<string | number>): Array<string | undefined> {\n const source = node.pointer ? [node.pointer] : [node.method, node.path]\n return ['operation', ...source, ...scope.map(String)]\n}\n\n/**\n * The `param` namespace shared by the schema-producing plugins (ts, zod, faker):\n * per-parameter names plus the grouped `Path`/`Query`/`Headers`/`Cookies` names, all routed\n * through the plugin's top-level `name` casing.\n */\nexport type OperationParamResolver = {\n name(this: Resolver, node: ast.OperationNode, param: ast.ParameterNode): string\n path(this: Resolver, node: ast.OperationNode): string\n query(this: Resolver, node: ast.OperationNode): string\n headers(this: Resolver, node: ast.OperationNode): string\n cookies(this: Resolver, node: ast.OperationNode): string\n}\n\n/**\n * The `response` namespace shared by the schema-producing plugins: per-status,\n * body, and combined response names, all routed through the plugin's top-level\n * `name` casing.\n */\nexport type OperationResponseResolver = {\n status(this: Resolver, node: ast.OperationNode, statusCode: ast.StatusCode): string\n body(this: Resolver, node: ast.OperationNode): string\n responses(this: Resolver, node: ast.OperationNode): string\n response(this: Resolver, node: ast.OperationNode): string\n}\n\n/**\n * Builds the shared `param` namespace. Spread the result into `createResolver`\n * and override individual methods next to it when a plugin deviates.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ param: createOperationParamResolver(), ... })\n * ```\n */\nexport function createOperationParamResolver(): OperationParamResolver {\n return {\n name(node, param) {\n const name = this.name(`${node.operationId} ${param.in} ${param.name}`)\n return this.resolveName({ key: operationKey(node, 'param', 'name', param.in, param.name), name })\n },\n path(node) {\n const name = this.name(`${node.operationId} Path`)\n return this.resolveName({ key: operationKey(node, 'param', 'path'), name })\n },\n query(node) {\n const name = this.name(`${node.operationId} Query`)\n return this.resolveName({ key: operationKey(node, 'param', 'query'), name })\n },\n headers(node) {\n const name = this.name(`${node.operationId} Headers`)\n return this.resolveName({ key: operationKey(node, 'param', 'headers'), name })\n },\n cookies(node) {\n const name = this.name(`${node.operationId} Cookies`)\n return this.resolveName({ key: operationKey(node, 'param', 'cookies'), name })\n },\n }\n}\n\n/**\n * Builds the shared `response` namespace. Spread the result into\n * `createResolver` and add plugin-specific methods (`options`, `error`) next\n * to it.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ response: { ...createOperationResponseResolver(), options(node) {...} }, ... })\n * ```\n */\nexport function createOperationResponseResolver(): OperationResponseResolver {\n return {\n status(node, statusCode) {\n const name = this.name(`${node.operationId} Status ${statusCode}`)\n return this.resolveName({ key: operationKey(node, 'response', 'status', statusCode), name })\n },\n body(node) {\n const name = this.name(`${node.operationId} Body`)\n return this.resolveName({ key: operationKey(node, 'response', 'body'), name })\n },\n responses(node) {\n const name = this.name(`${node.operationId} Responses`)\n return this.resolveName({ key: operationKey(node, 'response', 'responses'), name })\n },\n response(node) {\n const name = this.name(`${node.operationId} Response`)\n return this.resolveName({ key: operationKey(node, 'response', 'response'), name })\n },\n }\n}\n\n/**\n * Builds a resolver `file` override whose base name runs every path segment\n * through `toFilePath`, casing the final segment with `caseLast`.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ file: createCasedFile(pascalCase), ... })\n * ```\n */\nexport function createCasedFile(caseLast: (part: string) => string): ResolverFile {\n return {\n baseName({ name, extname }) {\n return this.memo(`file:${name}\\0${extname}`, (): ast.FileNode['baseName'] => `${toFilePath(name, caseLast)}${extname}`)\n },\n }\n}\n\ntype SchemaIndexContext = Pick<GeneratorContext, 'memo' | 'driver'>\n\n/**\n * Names of the schemas in a circular reference chain, computed once per build.\n */\nexport function getCircularNames(ctx: SchemaIndexContext): ReadonlySet<string> {\n return ctx.memo('circularNames:set', () => ast.findCircularSchemas(ctx.driver.inputNode?.schemas ?? []))\n}\n\n/**\n * Names of the schemas whose type is `enum`, computed once per build.\n */\nexport function getEnumNames(ctx: SchemaIndexContext): ReadonlySet<string> {\n return ctx.memo(\n 'enumNames:set',\n () => new Set((ctx.driver.inputNode?.schemas ?? []).flatMap((schema) => (schema.type === 'enum' && schema.name ? [schema.name] : []))),\n )\n}\n\ndeclare global {\n namespace Kubb {\n interface MemoRegistry {\n operation: string\n file: ast.FileNode['baseName']\n operationTypeNames: Array<string>\n }\n }\n}\n","import { camelCase, type Group } from '@kubb/kit'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","","","import { ast, camelCase, defineGenerator } from '@kubb/kit'\nimport type { PluginMsw } from '../types'\n\n/**\n * Aggregate generator enabled by `pluginMsw({ handlers: true })`. Emits a\n * `handlers.ts` file that re-exports every generated handler in operation\n * order, ready to spread into `setupServer(...handlers)` or\n * `setupWorker(...handlers)`.\n */\nexport const handlersGenerator = defineGenerator<PluginMsw>({\n name: 'plugin-msw',\n operations(nodes, ctx) {\n const { resolver, config, root } = ctx\n const { output, group } = ctx.options\n\n const handlersName = resolver.handler.listName()\n const createHandlersName = resolver.resolveName({ key: ['handlers', 'create'], name: camelCase(handlersName, { prefix: 'create' }) })\n const file = resolver.file({ name: handlersName, extname: '.ts', root, output, group: group ?? undefined })\n\n const handlerNames = nodes.map((node) => resolver.handler.name(node))\n\n const imports = nodes.map((node, index) => {\n const operationName = handlerNames[index]!\n const operationFile = resolver.file({\n name: resolver.name(node.operationId),\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n return ast.factory.createImport({ name: [operationName], root: file.path, path: operationFile.path })\n })\n\n const handlers = handlerNames.map((name) => `${name}(undefined, options)`)\n\n return [\n ast.factory.createFile({\n baseName: file.baseName,\n path: file.path,\n meta: file.meta,\n banner: resolver.default.banner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),\n footer: resolver.default.footer(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),\n imports,\n sources: [\n ast.factory.createSource({\n name: createHandlersName,\n isIndexable: true,\n isExportable: true,\n nodes: [\n ast.factory.createText(`export function ${createHandlersName}(options?: { baseURL?: string }) {\n return [${handlers.join(', ')}] as const\n}`),\n ],\n }),\n ast.factory.createSource({\n name: handlersName,\n isIndexable: true,\n isExportable: true,\n nodes: [ast.factory.createText(`export const ${handlersName} = ${createHandlersName}()`)],\n }),\n ],\n }),\n ]\n },\n})\n","import { toResponseContent } from '@internals/shared'\nimport { ast } from '@kubb/kit'\n\n/**\n * Returns the base URL as source code. A `${...}` value stays a template literal.\n */\nexport function resolveDefaultBaseURL(baseURL: string | null | undefined): string {\n if (!baseURL) {\n return \"''\"\n }\n if (baseURL.includes('${')) {\n return `\\`${baseURL.replaceAll('`', '\\\\`')}\\``\n }\n return JSON.stringify(baseURL)\n}\n\n/**\n * Gets the content type from a response, defaulting to 'application/json' if a schema exists.\n */\nexport function getContentType(response: ast.ResponseNode | null | undefined): string | null {\n if (!hasResponseSchema(response)) {\n return null\n }\n\n return getResponseContentType(response) ?? 'application/json'\n}\n\n/**\n * Determines if a response has a usable body schema.\n */\nexport function hasResponseSchema(response: ast.ResponseNode | null | undefined): boolean {\n const schema = response?.content?.find((entry) => entry.schema)?.schema\n return !!schema && schema.type !== 'void' && schema.type !== 'any' && schema.type !== 'unknown'\n}\n\n/**\n * Picks the content type used for the mocked response header. When a response declares multiple\n * content types, JSON is preferred (the faker mock body is JSON), otherwise the first declared type.\n */\nfunction getResponseContentType(response: ast.ResponseNode | null | undefined): string | null {\n const contents = response?.content ?? []\n const value = (contents.find((entry) => isJson(entry.contentType)) ?? contents[0])?.contentType\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction isJson(contentType: string | undefined): boolean {\n const baseType = contentType?.split(';')[0]?.trim().toLowerCase()\n return baseType === 'application/json' || Boolean(baseType?.endsWith('+json'))\n}\n\n/**\n * The first content type of a response that the client reads as text, such as `application/xml`, or `null` when none is.\n */\nfunction getTextContentType(response: ast.ResponseNode | null | undefined): string | null {\n const entry = (response?.content ?? []).find((entry) => {\n const schema = toResponseContent(entry, response?.content).schema\n return !isJson(entry.contentType) && schema && ast.resolveRef(schema).primitive === 'string'\n })\n return entry?.contentType ?? null\n}\n\n/**\n * The statements that return a mocked `Response` for `body`. A string body for a response the client reads as text goes\n * out as raw text with that content type, so an XML mock is not sent as a quoted JSON string. Any other body is JSON.\n */\nexport function responseReturn(body: string, status: number, response: ast.ResponseNode | null | undefined): string {\n const contentType = getContentType(response)\n const textContentType = hasResponseSchema(response) ? getTextContentType(response) : null\n if (!textContentType) return `return ${responseLiteral(`JSON.stringify(${body})`, status, contentType)}`\n\n // A plain variable such as `data` is checked as it is, an expression such as `data ?? createPet(data)` is read once.\n const name = /^\\w+$/.test(body) ? body : 'body'\n return `${name === body ? '' : `const body = ${body}\\n `}if (typeof ${name} === 'string') return ${responseLiteral(name, status, textContentType)}\n\n return ${responseLiteral(`JSON.stringify(${name})`, status, contentType)}`\n}\n\n/**\n * Converts an HTTP method to its lowercase MSW equivalent (e.g., 'POST' → 'post'). MSW has no\n * `http.query`, so a QUERY operation maps to `http.all` and its handler checks the method itself.\n */\nexport function getMswMethod(node: ast.HttpOperationNode): string {\n return node.method === 'QUERY' ? 'all' : node.method.toLowerCase()\n}\n\n/**\n * The `headers` entry of a mocked `Response` init, or an empty string when there is no content type.\n */\nfunction headersBlock(contentType: string | null): string {\n return contentType ? `\\n headers: {\\n 'Content-Type': '${contentType}'\\n },` : ''\n}\n\n/**\n * The `new HttpResponse<string>(...)` expression a mocked handler returns.\n */\nexport function responseLiteral(body: string, status: number, contentType: string | null): string {\n return `new HttpResponse<string>(${body}, {\n status: ${status},${headersBlock(contentType)}\n })`\n}\n","import { getPrimarySuccessResponse } from '@internals/shared'\nimport type { ast } from '@kubb/kit'\nimport { Url } from '@kubb/kit'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx'\nimport { getMswMethod, hasResponseSchema, resolveDefaultBaseURL, responseReturn } from '../utils.ts'\n\ntype Props = {\n name: string\n typeName: string\n requestTypeName?: string | null\n fakerName?: string\n baseURL: string | null | undefined\n node: ast.HttpOperationNode\n}\n\nexport function Mock({ baseURL = '', name, fakerName, typeName, requestTypeName, node }: Props): KubbReactNode {\n const method = getMswMethod(node)\n // `http.all` matches every method on the path, so the QUERY handler lets the others pass through.\n const methodGuard = node.method === 'QUERY' ? `if (info.request.method !== 'QUERY') return\\n\\n ` : ''\n const successResponse = getPrimarySuccessResponse(node)\n const statusCode = successResponse ? Number(successResponse.statusCode) : 200\n const url = Url.toPath(node.path)\n\n const responseHasSchema = hasResponseSchema(successResponse)\n const dataType = responseHasSchema ? typeName : 'string | number | boolean | null | object'\n const paramType = fakerName ? typeName : dataType\n const requestBodyType = requestTypeName ? `${requestTypeName} extends DefaultBodyType ? ${requestTypeName} : DefaultBodyType` : null\n\n const callbackType = requestBodyType\n ? `HttpResponseResolver<Record<string, string>, ${requestBodyType}>`\n : `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`\n\n const params = `data?: ${paramType} | ${callbackType}, options?: { baseURL?: string }`\n\n const httpCall = requestBodyType ? `http.${method}<Record<string, string>, ${requestBodyType}>` : `http.${method}`\n\n // Escape colons that do not start a param, such as the second one in `/pet/:petId:search`.\n const urlLiteral = `\\`\\${options?.baseURL ?? ${resolveDefaultBaseURL(baseURL)}}${url.replace(/([^/]):/g, '$1\\\\\\\\:')}\\``\n const responseBody = fakerName ? `data ?? ${fakerName}(data)` : 'data'\n\n return (\n <File.Source name={name} isIndexable isExportable>\n <Function name={name} export params={params}>\n {`return ${httpCall}(${urlLiteral}, function handler(info) {\n ${methodGuard}if(typeof data === 'function') return data(info)\n\n ${responseReturn(responseBody, statusCode, successResponse)}\n })`}\n </Function>\n </File.Source>\n )\n}\n","import type { ast } from '@kubb/kit'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx'\nimport { hasResponseSchema, responseReturn } from '../utils.ts'\n\ntype Props = {\n typeName: string\n name: string\n response: ast.ResponseNode\n}\n\nexport function Response({ name, typeName, response }: Props): KubbReactNode {\n const statusCode = Number(response.statusCode)\n\n const params = `data${hasResponseSchema(response) ? '' : '?'}: ${typeName}`\n\n const responseName = `${name}Response${statusCode}`\n\n return (\n <File.Source name={responseName} isIndexable isExportable>\n <Function name={responseName} export params={params}>\n {`\n ${responseReturn('data', statusCode, response)}`}\n </Function>\n </File.Source>\n )\n}\n","import { getEnumNames, getOperationSuccessResponses, resolveOperationFile, resolveResponseTypes } from '@internals/shared'\nimport { ast, defineGenerator } from '@kubb/kit'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { enumTypeName, pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from '@kubb/renderer-jsx'\nimport { Mock } from '../components/Mock.tsx'\nimport { Response } from '../components/Response.tsx'\nimport type { PluginMsw } from '../types'\nimport { hasResponseSchema } from '../utils.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-msw`. Emits one MSW handler\n * per OpenAPI operation. With `parser: 'faker'` the handler returns a value\n * from `@kubb/plugin-faker`; with `parser: 'data'` it returns a typed empty\n * payload for tests to fill in.\n */\nexport const mswGenerator = defineGenerator<PluginMsw>({\n name: 'msw',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n const { driver, resolver, config, root } = ctx\n const { output, parser, baseURL, group } = ctx.options\n\n const fileName = resolver.name(node.operationId)\n const mock = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: fileName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n }\n\n const fakerPlugin = parser === 'faker' ? ctx.requirePlugin(pluginFakerName) : null\n const fakerResolver = fakerPlugin ? driver.getResolver(pluginFakerName) : null\n const faker =\n fakerPlugin && fakerResolver\n ? {\n name: fakerResolver.response.response(node),\n file: resolveOperationFile({\n ctx,\n node,\n resolver: fakerResolver,\n root,\n output: fakerPlugin.options?.output ?? output,\n group: fakerPlugin.options?.group ?? undefined,\n }),\n }\n : null\n\n const pluginTs = ctx.requirePlugin(pluginTsName)\n const tsResolver = driver.getResolver(pluginTsName)\n\n const type = {\n file: resolveOperationFile({\n ctx,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n responseName: tsResolver.response.response(node),\n }\n\n const successResponses = getOperationSuccessResponses(node)\n const referencedNames = node.responses.flatMap((response) =>\n (response.content ?? []).flatMap((entry) => (entry.schema ? ast.collectImportedRefNames(entry.schema) : [])),\n )\n const enumOptions = pluginTs.options?.enum\n const enumNames = getEnumNames(ctx)\n const hasResponseNameCollision = referencedNames.some((name) => {\n return enumTypeName({ resolver: tsResolver, name, enumOptions, isEnum: enumNames.has(name) }) === type.responseName\n })\n const types = resolveResponseTypes(node, tsResolver).map(([code, typeName]) => {\n const successResponse = successResponses.find((response) => response.statusCode === String(code))\n return [code, hasResponseNameCollision && successResponse ? tsResolver.response.status(node, successResponse.statusCode) : typeName] as const\n })\n const responseTypeNames = types.map(([, typeName]) => typeName).filter((name) => !hasResponseNameCollision || name !== type.responseName)\n const mockResponseName =\n hasResponseNameCollision && successResponses[0] ? tsResolver.response.status(node, successResponses[0].statusCode) : type.responseName\n const hasSuccessSchema = successResponses.some((response) => hasResponseSchema(response))\n\n const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.response.body(node) : null\n\n return (\n <File\n baseName={mock.file.baseName}\n path={mock.file.path}\n meta={mock.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: mock.file.path, baseName: mock.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: mock.file.path, baseName: mock.file.baseName } })}\n >\n <File.Import name={['http', 'HttpResponse']} path=\"msw/http\" />\n <File.Import name={['HttpResponseResolver']} isTypeOnly path=\"msw/http\" />\n {requestName && <File.Import name={['DefaultBodyType']} isTypeOnly path=\"msw\" />}\n <File.Import\n name={Array.from(new Set([...(hasResponseNameCollision ? [] : [type.responseName]), ...responseTypeNames, ...(requestName ? [requestName] : [])]))}\n path={type.file.path}\n root={mock.file.path}\n isTypeOnly\n />\n {faker && hasSuccessSchema && <File.Import name={[faker.name]} root={mock.file.path} path={faker.file.path} />}\n\n {types\n .filter(([code]) => code !== 'default')\n .map(([code, typeName]) => {\n const response = node.responses.find((item) => item.statusCode === String(code))\n if (!response) return null\n return <Response key={typeName} typeName={typeName} response={response} name={mock.name} />\n })}\n\n <Mock\n name={mock.name}\n typeName={mockResponseName}\n requestTypeName={requestName}\n fakerName={faker && hasSuccessSchema ? faker.name : undefined}\n node={node}\n baseURL={baseURL}\n />\n </File>\n )\n },\n})\n","import { operationKey } from '@internals/shared'\nimport { camelCase, createResolver } from '@kubb/kit'\nimport type { PluginMsw } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-msw`. Decides the names and file\n * paths for every generated MSW handler. Function names get a `Handler`\n * suffix; the aggregate export is always `handlers`.\n *\n * The top-level `name` applies the `handler` suffix, and `file` falls back to the built-in\n * `toFilePath` casing. Operation-specific naming is grouped under the `handler` namespace.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMsw } from '@kubb/plugin-msw'\n *\n * resolverMsw.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMsw = createResolver<PluginMsw>({\n pluginName: 'plugin-msw',\n name(name) {\n return this.memo(`name:${name}`, () => camelCase(name, { suffix: 'handler' }))\n },\n handler: {\n name(node) {\n const name = this.name(node.operationId)\n return this.resolveName({ key: operationKey(node, 'handler', 'name'), name })\n },\n listName() {\n return this.resolveName({ key: ['handlers', 'list'], name: 'handlers' })\n },\n },\n})\n","import { createGroupConfig } from '@internals/shared'\nimport { addGenerator, defineExtension, Resolver, setMacros, setResolver } from '@kubb/kit'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { handlersGenerator } from './generators/handlersGenerator.ts'\nimport { mswGenerator } from './generators/mswGenerator.tsx'\nimport { resolverMsw } from './resolvers/resolverMsw.ts'\nimport type { PluginMsw, ResolverMsw } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-msw`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']\n\n/**\n * Generates MSW request handlers from an OpenAPI spec. Drop them into your\n * test setup or service worker to mock the API end-to-end. Request path,\n * method, status, and response body all stay in sync with the spec. Combine\n * with `@kubb/plugin-faker` (via `parser: 'faker'`) to seed handlers with\n * realistic data.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginMsw } from '@kubb/plugin-msw'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginMsw({\n * output: { path: './handlers' },\n * handlers: true,\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMsw = defineExtension<PluginMsw>({\n kind: 'plugin',\n meta: { name: pluginMswName, version, compatibility },\n dependencies: (options) => ({ [pluginTsName]: {}, ...(options.parser === 'faker' ? { [pluginFakerName]: {} } : {}) }),\n setup(options) {\n const {\n output = { path: 'handlers', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n handlers = false,\n parser = 'data',\n baseURL,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const resolver = userResolver ? Resolver.merge<ResolverMsw>(resolverMsw, userResolver) : resolverMsw\n\n setResolver(resolver)\n if (userMacros?.length) {\n setMacros(userMacros)\n }\n\n addGenerator(mswGenerator)\n if (handlers) {\n addGenerator(handlersGenerator)\n }\n\n return {\n output,\n parser,\n baseURL,\n group: createGroupConfig(group),\n exclude,\n include,\n override,\n handlers,\n }\n },\n})\n\nexport default pluginMsw\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["defineGenerator","casing","ast","text","ast","ast","text","text","ast","Url","File","Function","File","Function","ast","defineGenerator","jsxRenderer","ast","pluginFakerName","pluginTsName","enumTypeName","File","createResolver","casing","defineExtension","pluginTsName","pluginFakerName","Resolver"],"sources":["../kubb-extension.json","../package.json","../src/generators/handlersGenerator.ts","../../../internals/utils/src/reserved.ts","../../../internals/utils/src/codegen.ts","../../../internals/shared/src/operation.ts","../../../internals/shared/src/resolver.ts","../src/utils.ts","../src/components/Mock.tsx","../src/components/Response.tsx","../src/generators/mswGenerator.tsx","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["","","import { ast, casing, defineGenerator } from '@kubb/kit'\nimport type { PluginMsw } from '../types'\n\n/**\n * Aggregate generator enabled by `pluginMsw({ handlers: true })`. Emits a\n * `handlers.ts` file that re-exports every generated handler in operation\n * order, ready to spread into `setupServer(...handlers)` or\n * `setupWorker(...handlers)`.\n */\nexport const handlersGenerator = defineGenerator<PluginMsw>({\n name: 'plugin-msw',\n operations(nodes, ctx) {\n const { resolver, config, root } = ctx\n const { output, group } = ctx.options\n\n const handlersName = resolver.handler.listName()\n const createHandlersName = resolver.resolveName({ key: ['handlers', 'create'], name: casing.camel(handlersName, { prefix: 'create' }) })\n const file = resolver.file({ name: handlersName, extname: '.ts', root, output, group: group ?? undefined })\n\n const handlerNames = nodes.map((node) => resolver.handler.name(node))\n\n const imports = nodes.map((node, index) => {\n const operationName = handlerNames[index]!\n const operationFile = resolver.file({\n name: resolver.name(node.operationId),\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n return ast.factory.createImport({ name: [operationName], root: file.path, path: operationFile.path })\n })\n\n const handlers = handlerNames.map((name) => `${name}(undefined, options)`)\n\n return [\n ast.factory.createFile({\n baseName: file.baseName,\n path: file.path,\n meta: file.meta,\n banner: resolver.default.banner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),\n footer: resolver.default.footer(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),\n imports,\n sources: [\n ast.factory.createSource({\n name: createHandlersName,\n isIndexable: true,\n isExportable: true,\n nodes: [\n ast.factory.createText(`export function ${createHandlersName}(options?: { baseURL?: string }) {\n return [${handlers.join(', ')}] as const\n}`),\n ],\n }),\n ast.factory.createSource({\n name: handlersName,\n isIndexable: true,\n isExportable: true,\n nodes: [ast.factory.createText(`export const ${handlersName} = ${createHandlersName}()`)],\n }),\n ],\n }),\n ]\n },\n})\n","/**\n * JavaScript and Java reserved words.\n * @link https://github.com/jonschlinkert/reserved/blob/master/index.js\n */\nconst reservedWords = new Set([\n 'abstract',\n 'arguments',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n 'Array',\n 'Date',\n 'hasOwnProperty',\n 'Infinity',\n 'isFinite',\n 'isNaN',\n 'isPrototypeOf',\n 'length',\n 'Math',\n 'name',\n 'NaN',\n 'Number',\n 'Object',\n 'prototype',\n 'String',\n 'toString',\n 'undefined',\n 'valueOf',\n] as const)\n\n/**\n * Returns `true` when `name` is a syntactically valid JavaScript variable name.\n *\n * @example\n * ```ts\n * isValidVarName('status') // true\n * isValidVarName('class') // false (reserved word)\n * isValidVarName('42foo') // false (starts with digit)\n * ```\n */\nexport function isValidVarName(name: string): boolean {\n if (!name || reservedWords.has(name as 'valueOf')) {\n return false\n }\n return isIdentifier(name)\n}\n\n/**\n * Returns `name` when it's a syntactically valid JavaScript variable name,\n * otherwise prefixes it with `_` so the result is a valid identifier.\n *\n * Useful for sanitizing OpenAPI schema names or operation IDs that start with\n * a digit (e.g. `409`, `504AccountCancel`) before using them as exported\n * variable, type, or function names.\n *\n * @example\n * ```ts\n * ensureValidVarName('409') // '_409'\n * ensureValidVarName('504AccountCancel') // '_504AccountCancel'\n * ensureValidVarName('Pet') // 'Pet'\n * ensureValidVarName('class') // '_class'\n * ```\n */\nexport function ensureValidVarName(name: string): string {\n if (!name || isValidVarName(name)) {\n return name\n }\n return `_${name}`\n}\n\n/**\n * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.\n *\n * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys\n * even though they are not valid variable names, so use this (not {@link isValidVarName}) when\n * deciding whether an object key needs quoting.\n *\n * @example\n * ```ts\n * isIdentifier('name') // true\n * isIdentifier('x-total')// false\n * ```\n */\nexport function isIdentifier(name: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)\n}\n","import { text } from '@kubb/kit'\nimport { isIdentifier } from './reserved.ts'\n\n/**\n * Builds a JSDoc comment block from an array of lines. Returns `fallback` when there are no\n * comments.\n *\n * @example\n * ```ts\n * buildJSDoc(['@type string', '@example hello'])\n * // '/**\\n * @type string\\n * @example hello\\n *\\/\\n '\n * ```\n */\nexport function buildJSDoc(\n comments: Array<string>,\n options: {\n /**\n * String used to indent each comment line.\n * @default ' * '\n */\n indent?: string\n /**\n * String appended after the closing tag.\n * @default '\\n '\n */\n suffix?: string\n /**\n * Returned as-is when `comments` is empty.\n * @default ' '\n */\n fallback?: string\n } = {},\n): string {\n const { indent = ' * ', suffix = '\\n ', fallback = ' ' } = options\n\n if (comments.length === 0) return fallback\n\n return `/**\\n${comments.map((c) => `${indent}${c}`).join('\\n')}\\n */${suffix}`\n}\n\n/**\n * Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one\n * level and closing the brace at column zero. Entries that are themselves multi-line objects indent\n * cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.\n *\n * @example\n * ```ts\n * buildObject(['id: z.number()', 'name: z.string()'])\n * // '{\\n id: z.number(),\\n name: z.string(),\\n}'\n * ```\n */\nexport function buildObject(entries: Array<string>): string {\n if (entries.length === 0) return '{}'\n const body = entries.map((entry) => `${text.indent({ text: entry })},`).join('\\n')\n\n return `{\\n${body}\\n}`\n}\n\n/**\n * Assembles a bracketed list (array by default) from already-rendered `items`. Keeps everything on\n * one line when no item spans multiple lines, and otherwise puts each item on its own line, indented\n * one level with a trailing comma and the closing bracket at column zero. Used for member lists such\n * as `z.union([…])` and `z.array([…])`.\n *\n * @example\n * ```ts\n * buildList(['z.string()', 'z.number()'])\n * // '[z.string(), z.number()]'\n * ```\n */\nexport function buildList(items: Array<string>, brackets: [open: string, close: string] = ['[', ']']): string {\n const [open, close] = brackets\n if (items.length === 0) return `${open}${close}`\n if (!items.some((item) => item.includes('\\n'))) return `${open}${items.join(', ')}${close}`\n const body = items.map((item) => `${text.indent({ text: item })},`).join('\\n')\n\n return `${open}\\n${body}\\n${close}`\n}\n\n/**\n * Emits a lazy getter for a circular-ref property position, `get name() { return body }`. The key\n * is quoted only when it is not a valid identifier. Used by the string printers to defer evaluation\n * of a recursive schema until first access.\n *\n * @example\n * ```ts\n * lazyGetter({ name: 'parent', body: 'z.lazy(() => Pet)' })\n * // \"get parent() { return z.lazy(() => Pet) }\"\n * ```\n */\nexport function lazyGetter({ name, body }: { name: string; body: string }): string {\n return `get ${objectKey(name)}() { return ${body} }`\n}\n\n/**\n * An object key, quoted only when it is not identifier-shaped. Reserved words such as `class` stay bare.\n *\n * @example\n * ```ts\n * objectKey('x-total') // \"'x-total'\"\n * ```\n */\nexport function objectKey(name: string): string {\n return isIdentifier(name) ? name : text.quote(name)\n}\n\n/**\n * A JSON value as a JavaScript literal, with single-quoted strings and identifier keys left unquoted.\n *\n * @example\n * ```ts\n * toLiteral({ id: 1, 'x-tag': ['a'] }) // \"{ id: 1, 'x-tag': ['a'] }\"\n * ```\n */\nexport function toLiteral(value: unknown): string {\n if (typeof value === 'string') return text.quote(value)\n if (Array.isArray(value)) return `[${value.map(toLiteral).join(', ')}]`\n if (value && typeof value === 'object') {\n return `{ ${Object.entries(value)\n .map(([key, item]) => `${objectKey(key)}: ${toLiteral(item)}`)\n .join(', ')} }`\n }\n return String(value)\n}\n","import { jsDocEscape } from '@internals/utils'\nimport { ast, type Group, type Memo, type Output, type Resolver, type ResolverFileParams } from '@kubb/kit'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves the file a schema-emitting plugin (`plugin-ts`, `plugin-zod`, `plugin-faker`) writes\n * `node` to, cached in `ctx.memo` under the resolver's plugin name and the\n * operation. The plugin itself and every plugin that imports from it call this, so they all get\n * the same path.\n *\n * When that path matches the file of a component schema in `ctx.driver.inputNode`, ignoring case, the file name\n * gets an `Operation` suffix: operation `point` goes to `PointOperation.ts` next to schema `Point.ts`.\n * Otherwise the two merge into one file, or overwrite each other on a case-insensitive file system.\n * Only the file name changes. The declarations keep their names.\n *\n * @example Resolve `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveOperationFile({ ctx, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveOperationFile(options: {\n ctx: { memo: Memo; driver: { inputNode?: { schemas: ReadonlyArray<ast.SchemaNode> } | null } }\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { ctx, node, resolver, root, output } = options\n const { memo } = ctx\n const location = { root, output, group: options.group ?? undefined }\n\n return memo(`${resolver.pluginName}:operationFile:${node.operationId}`, () => {\n const schemaPaths = memo(\n `${resolver.pluginName}:schemaFilePaths`,\n () =>\n new Set(\n (ctx.driver.inputNode?.schemas ?? []).flatMap((schema) =>\n schema.name ? [resolver.file({ name: schema.name, extname: '.ts', ...location }).path.toLowerCase()] : [],\n ),\n ),\n )\n let file = resolver.file({ ...operationFileEntry(node, node.operationId), ...location })\n\n for (let name = `${node.operationId}Operation`; schemaPaths.has(file.path.toLowerCase()); name += 'Operation') {\n const next = resolver.file({ ...operationFileEntry(node, name), ...location })\n // A single-file output holds every declaration on purpose, so a new name changes nothing.\n if (next.path === file.path) break\n file = next\n }\n\n return file\n })\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n cookies(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\nexport type BuildOperationCommentsOptions = {\n splitLines?: boolean\n}\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\n/**\n * The operation's method and path as plain text, such as `` `GET /pet/{petId}` ``. A path is not a valid `{@link}` target.\n */\nfunction getOperationRequestLine(node: ast.OperationNode): string | null {\n return ast.http.isOperation(node) && node.path ? `\\`${node.method.toUpperCase()} ${node.path}\\`` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(ast.http.responses.findPrimary(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\ntype ResponseType = 'blob' | 'text' | 'stream'\n\ntype ResponseContentEntry = { contentType: string; schema?: ast.SchemaNode | null; stream?: ast.ContentNode['stream'] }\n\n/**\n * How an operation streams its primary success response item by item, when that response declares one content type:\n * - `'event'` for `text/event-stream` whose `itemSchema` types the whole event with its own `event` and `data`\n * - `'data'` for `text/event-stream` typed by its payload only\n * - `'line'` for JSON Lines, one parsed JSON value per line\n *\n * Returns `null` for any other response, and for a response that also declares another content type, which stays a normal\n * call with its query hooks.\n */\nexport function getEventStream(node: ast.OperationNode): 'event' | 'data' | 'line' | null {\n const content = ast.http.responses.findPrimary(node)?.content ?? []\n if (content.length !== 1) return null\n const entry = content[0]!\n const framing = getStreamFraming(entry)\n if (framing === 'events') return entry.stream?.shape ?? 'data'\n return framing === 'lines' ? 'line' : null\n}\n\n/**\n * How a content entry is framed as a stream: `'events'` for Server-Sent Events, `'lines'` for JSON Lines.\n */\nexport function getStreamFraming(entry: Pick<ast.ContentNode, 'contentType' | 'stream'>): 'events' | 'lines' | undefined {\n if (ast.mediaType.getBase(entry) === 'text/event-stream') return 'events'\n // `multipart/mixed` with an `itemSchema` also has `stream`, but it is a stream of parts, not of JSON values.\n return entry.stream && ast.mediaType.isStream(entry) ? 'lines' : undefined\n}\n\n/**\n * Whether an operation streams its primary success response, as Server-Sent Events or JSON Lines. The client generator uses\n * this to return a typed stream of items instead of a one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getEventStream(node) !== null\n}\n\n// A stream without a schema is a `blob` with a string primitive, so it keeps the JSON-parse default.\nfunction isTextSchema(schema: ast.SchemaNode | null | undefined): boolean {\n if (!schema) return false\n const resolved = ast.ref.getSchema(schema)\n return resolved.type !== 'blob' && resolved.primitive === 'string'\n}\n\n/**\n * Whether an operation streams Server-Sent Events whose `data` the document types as a string, so the client keeps each\n * `data` as text instead of JSON-parsing it. With an event-shaped `itemSchema` where only some events type `data` as a\n * string, it returns the names of those events, or `false` when one of them has no fixed name.\n */\nexport function hasTextEventData(node: ast.OperationNode): boolean | Array<string> {\n const shape = getEventStream(node)\n const entry = ast.http.responses.findPrimary(node)?.content?.[0]\n if (!entry || (shape !== 'data' && shape !== 'event')) return false\n if (shape === 'data') return isTextSchema(entry.stream?.schema ?? entry.schema)\n\n const item = entry.stream?.schema ? ast.ref.getSchema(entry.stream.schema) : undefined\n if (!item) return false\n const events = item.type === 'union' ? (ast.schema.narrow(item, 'union')?.members ?? []) : [item]\n // A discriminator makes each event an intersection of its `$ref` and the pinned `event`, so every part is read.\n const propertySchemas = (event: ast.SchemaNode, propertyName: string) => ast.schema.findProperties({ node: event, propertyName }).map(({ schema }) => schema)\n const textEvents = events.filter((event) => {\n const dataSchemas = propertySchemas(event, 'data')\n return dataSchemas.length > 0 && dataSchemas.every(isTextSchema)\n })\n if (textEvents.length === events.length) return events.length > 0\n\n const eventNames = textEvents.map((event) => propertySchemas(event, 'event').flatMap((schema) => ast.schema.getLiterals(ast.ref.getSchema(schema))))\n return eventNames.length > 0 && eventNames.every((values) => values.length > 0) && [...new Set(eventNames.flat().map(String))]\n}\n\n/**\n * Whether the primary success response offers `text/event-stream`, alone or next to other content types. The client asks\n * for the stream by default and ships the `sse.ts` runtime, so a mixed response can be read as events too.\n */\nexport function hasEventStreamContent(node: ast.OperationNode): boolean {\n const entries = ast.http.responses.findPrimary(node)?.content ?? []\n // Next to another type, a stream without a schema gets no typed variant, so it keeps the plain call.\n return entries.some((entry) => getStreamFraming(entry) === 'events' && (entries.length === 1 || Boolean(entry.schema)))\n}\n\n/**\n * Whether a success response offers a stream media type next to other content types. The client returns that variant's\n * body as a `ReadableStream`, so the stream runtime is registered and a hook's data type includes the stream.\n */\nexport function hasStreamVariant(node: ast.OperationNode): boolean {\n return ast.http.responses.filterSuccess(node).some((response) => {\n const variants = (response.content ?? []).filter((entry) => entry.schema)\n return variants.length > 1 && variants.some((entry) => ast.mediaType.isStream(entry))\n })\n}\n\nconst formContentTypes = ['multipart/form-data', 'application/x-www-form-urlencoded'] as const\n\n/**\n * The form media types the operation's request body offers, `multipart/form-data` and `application/x-www-form-urlencoded`,\n * which the client needs a handler for.\n */\nexport function getFormContentTypes(node: ast.OperationNode): Array<(typeof formContentTypes)[number]> {\n const request = new Set((node.requestBody?.content ?? []).map((entry) => ast.mediaType.getBase(entry)))\n return formContentTypes.filter((contentType) => request.has(contentType))\n}\n\n/**\n * Parser for one response content entry.\n *\n * JSON stays unset so the runtime detects it. `text/event-stream` and JSON Lines are streams. A binary schema\n * (`format: binary` / `contentMediaType`) is a blob even when the media type is not a well-known\n * binary type. Other `text/*` is text, and `application/octet-stream`, `application/pdf`,\n * `image/*`, `audio/*`, and `video/*` are blobs.\n */\nfunction responseTypeForContent(entry: ResponseContentEntry): ResponseType | undefined {\n const baseType = ast.mediaType.getBase(entry)\n if (!baseType) return undefined\n if (getStreamFraming(entry)) return 'stream'\n if (ast.mediaType.isJson(baseType)) return undefined\n if (entry.schema?.type === 'blob') return 'blob'\n if (baseType.startsWith('text/')) return 'text'\n if (isBinaryContentType(baseType)) return 'blob'\n return undefined\n}\n\nfunction isBinaryContentType(baseType: string): boolean {\n return baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n // Keeps the original case, unlike ast.mediaType.getBase, so generated names stay stable.\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Returns the entry with the schema of the value the client returns: `string` for a body read as text, such as `Pet` on\n * `application/xml`, and `blob` for `image/*`, `audio/*`, `video/*`, PDF, and octet-stream. A binary schema elsewhere is a `Blob`\n * only through `parseAs: 'blob'`, which needs every entry in `entries` binary. JSON, vendor (`application/vnd.*`), stream,\n * schemaless, and wildcard entries keep their schema. `entries` is the response's full list of content types.\n */\nexport function toResponseContent<T extends ContentVariantInput & ResponseContentEntry>(entry: T, entries: ReadonlyArray<ResponseContentEntry> = [entry]): T {\n const { contentType, schema } = entry\n if (!schema || entry.stream) return entry\n\n const baseType = ast.mediaType.getBase(contentType)\n const resolved = ast.ref.getSchema(schema)\n if (isBinaryContentType(baseType)) {\n return resolved.type === 'blob' ? entry : { ...entry, schema: ast.factory.createSchema({ type: 'blob' }), keysToOmit: null }\n }\n const isPlainMediaType = Boolean(baseType) && !ast.mediaType.isJson(baseType) && !baseType.includes('*')\n if (resolved.type === 'blob') {\n // shortcut: an error response never gets `parseAs`, so a lone binary schema there reads as text too but stays `Blob`.\n const readsAsText = isPlainMediaType && !entries.every((item) => item.schema?.type === 'blob')\n return readsAsText ? { ...entry, schema: ast.factory.createSchema({ type: 'string' }), keysToOmit: null } : entry\n }\n if (resolved.primitive === 'string') return entry\n\n const responseType = responseTypeForContent(entry)\n // A response without a body, such as a 405, has no schema to read. Only `text/*` is always text.\n if (responseType !== 'text' && (resolved.type === 'unknown' || resolved.type === 'any' || resolved.type === 'void')) return entry\n const isVendorJson = /^[^/]+\\/vnd\\./.test(baseType) && !/(xml|yaml|yml|csv)$/.test(baseType)\n const isText = responseType === 'text' || (!responseType && isPlainMediaType && !isVendorJson)\n\n return isText ? { ...entry, schema: ast.factory.createSchema({ type: 'string' }), keysToOmit: null } : entry\n}\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...): `RequestConfig` minus what the\n * hook fills in, which is every request group and `throwOnError`. Unlike {@link buildRequestConfigType},\n * it never narrows `contentType`: query hooks wrap GET operations, which carry no request body to select\n * a content type for.\n */\nexport function buildClientOptionType(options: { omit?: Array<string> } = {}): string {\n const keys = [...requestGroupOrder, 'url', ...(options.omit ?? []), 'throwOnError']\n return `Partial<Omit<RequestConfig, ${keys.map((key) => `'${key}'`).join(' | ')}>>`\n}\n\n/**\n * The `client?:` option type of a mutation hook. When the operation has a request content type choice,\n * the mutation variables carry `contentType`, so the config leaves it out. Otherwise the ambiguous side is\n * narrowed to the operation's media types; a single-type side has nothing to pick, so it stays baked in the\n * generated call.\n */\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n if (hasRequestContentTypeChoice(node)) {\n return buildClientOptionType({ omit: ['contentType'] })\n }\n\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n const base = buildClientOptionType()\n return members.length ? `${base} & { contentType?: { ${members.join('; ')} } }` : base\n}\n\n/** The grouped request options, in the order generated signatures and calls list them. */\nexport const requestGroupOrder = ['path', 'query', 'body', 'headers', 'cookies'] as const\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n cookies: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header, cookie } = ast.http.groupParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(ast.http.requestBody.getSchema(node)),\n headers: header.length > 0,\n cookies: cookie.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = ast.http.groupParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n // `cookies` never makes the parameter required: a browser sends its cookies itself and cannot set a `Cookie` header.\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !(groups.body && node.requestBody?.required === true),\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers, cookies }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups; names: Array<keyof RequestGroups> } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = requestGroupOrder.filter((key) => groups[key])\n\n // These callers never carry the `contentType` that several media types require.\n const optionsType = hasRequestContentTypeChoice(node)\n ? `Pick<${resolver.response.options(node)}, ${names.map((name) => `'${name}'`).join(' | ')}>`\n : resolver.response.options(node)\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${optionsType}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n names,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { splitLines = false } = options\n // The request line leads: free text after a block tag would belong to that tag.\n const comments = [\n getOperationRequestLine(node),\n node.description && `@description ${node.description}`,\n node.summary && `@summary ${node.summary}`,\n node.deprecated && '@deprecated',\n node.externalDocs && `@see ${jsDocEscape([node.externalDocs.url, node.externalDocs.description].filter(Boolean).join(' '))}`,\n ]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\n/**\n * Whether the operation declares more than one request media type with a schema, so a caller must pick one on `contentType`.\n */\nexport function hasRequestContentTypeChoice(node: ast.OperationNode): boolean {\n return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1\n}\n\n/**\n * Casts a call argument to the client's parameter type; a `'plain'` client is non-generic.\n */\nexport function castToClientOptions(callArg: string, clientName: string, returnType: 'full' | 'data' | 'plain' = 'full'): string {\n return `${callArg} as Parameters<typeof ${clientName}${returnType === 'plain' ? '' : '<true>'}>[0]`\n}\n\n/**\n * Builds the combined `{ body, path, query, headers, cookies }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. `cookies` appears only on an operation\n * with a cookie parameter, and stays optional because a browser sends its cookies itself. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same shape from the same inputs.\n * `primitive: 'object'` is a no-op for the TS printer and tells the Zod printer to emit `z.object(…)` rather\n * than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver, { pairContentTypes = false } = {}): ast.SchemaNode {\n const { path, query, header, cookie } = ast.http.groupParameters(node)\n const hasBody = Boolean(ast.http.requestBody.getSchema(node))\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n { name: 'cookies', params: cookie, resolve: resolver.param.cookies },\n ] as const\n\n const createOptions = (body: ast.SchemaNode, extra: Array<ast.PropertyNode> = []) =>\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({ name: 'body', required: hasBody && node.requestBody?.required === true, schema: body }),\n ...groups\n .filter(({ name, params }) => name !== 'cookies' || params.length > 0)\n .map(({ name, params, resolve }) => {\n const required = name !== 'cookies' && params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ...extra,\n ],\n })\n\n const variants =\n pairContentTypes && hasRequestContentTypeChoice(node) ? resolveContentTypeVariants(node.requestBody?.content ?? [], resolver.response.body(node)) : []\n if (variants.length < 2) {\n return createOptions(hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever())\n }\n\n // The first media type is the runtime default, so only the others must pass `contentType`. A bare string sets the\n // request content type at runtime, so it is accepted next to the `{ request }` form.\n return ast.factory.createSchema({\n type: 'union',\n members: variants.map((variant, index) => {\n const contentType = ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] })\n\n return createOptions(ast.factory.createSchema({ type: 'ref', name: variant.name }), [\n ast.factory.createProperty({\n name: 'contentType',\n required: index > 0,\n schema: ast.factory.createSchema({\n type: 'union',\n members: [\n contentType,\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [ast.factory.createProperty({ name: 'request', required: true, schema: contentType })],\n }),\n ],\n }),\n }),\n ])\n }),\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use. With `streamData`, the stream variant of a 2xx status holds that schema, since the\n * client returns its body unread.\n */\nfunction buildResponseRecordEntry(\n node: ast.OperationNode,\n res: ast.ResponseNode,\n resolver: ResponseStatusNameResolver,\n streamData: ast.SchemaNode | undefined,\n): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n // The runtime reports the bare media type, without parameters such as `charset` or `profile`.\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [ast.mediaType.getBase(variant)] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema:\n streamData && ast.http.status.isSuccess(res) && ast.mediaType.isStream(variant)\n ? streamData\n : ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n *\n * `streamData` is the type of a stream variant's `data`, such as a `ReadableStream<Uint8Array>` reference.\n */\nexport function buildResponses(\n node: ast.OperationNode,\n resolver: ResponseStatusNameResolver,\n { streamData }: { streamData?: ast.SchemaNode } = {},\n): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver, streamData),\n }),\n ),\n })\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return ast.http.responses.filterError(node).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return ast.http.responses.filterSuccess(node).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\n/**\n * Lists the type names an operation's types file declares, computed once per resolver and `options` so every\n * dependent reads the same list.\n */\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver & Pick<Resolver, 'memo'>,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const key = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n return resolver.memo(`operationTypeNames:${key}`, () => {\n const { path, query, header, cookie } = ast.http.groupParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ...cookie.map((param) => resolver.param.cookies(node, param)),\n ]\n const bodyAndResponseNames = [ast.http.requestBody.getSchema(node) ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n return names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n })\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = Number(response.statusCode)\n if (Number.isNaN(code)) {\n continue\n }\n\n types.push([code, ast.http.status.isSuccess(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n","import { ensureValidVarName, toFilePath } from '@internals/utils'\nimport { ast, casing } from '@kubb/kit'\nimport type { GeneratorContext, Resolver, ResolverFile } from '@kubb/kit'\n\n/**\n * The shared top-level `name` of the operation plugins, computed once per operation name and build.\n */\nexport function resolveOperationName(this: Resolver, name: string): string {\n return this.memo(`operation:${name}`, () => ensureValidVarName(casing.camel(name)))\n}\n\n/**\n * Builds the allocation key for a declaration an operation owns. `scope` names which declaration\n * it is, so two of them never share an allocation even when a custom resolver gives both the same\n * name. Leave `scope` empty for the operation's own declaration.\n *\n * The key starts from the operation's input `pointer`, which macros keep, so a plugin whose macro\n * rewrites the method or path still resolves another plugin's names for the same operation.\n *\n * @example\n * ```ts\n * resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })\n * ```\n */\nexport function operationKey(node: ast.OperationNode, ...scope: Array<string | number>): Array<string | undefined> {\n const source = node.pointer ? [node.pointer] : [node.method, node.path]\n return ['operation', ...source, ...scope.map(String)]\n}\n\n/**\n * The `param` namespace shared by the schema-producing plugins (ts, zod, faker):\n * per-parameter names plus the grouped `Path`/`Query`/`Headers`/`Cookies` names, all routed\n * through the plugin's top-level `name` casing.\n */\nexport type OperationParamResolver = {\n name(this: Resolver, node: ast.OperationNode, param: ast.ParameterNode): string\n path(this: Resolver, node: ast.OperationNode): string\n query(this: Resolver, node: ast.OperationNode): string\n headers(this: Resolver, node: ast.OperationNode): string\n cookies(this: Resolver, node: ast.OperationNode): string\n}\n\n/**\n * The `response` namespace shared by the schema-producing plugins: per-status,\n * body, and combined response names, all routed through the plugin's top-level\n * `name` casing.\n */\nexport type OperationResponseResolver = {\n status(this: Resolver, node: ast.OperationNode, statusCode: ast.StatusCode): string\n /**\n * Name of the headers a response declares, such as `ListPetsStatus200Headers`.\n */\n headers(this: Resolver, node: ast.OperationNode, statusCode: ast.StatusCode): string\n body(this: Resolver, node: ast.OperationNode): string\n responses(this: Resolver, node: ast.OperationNode): string\n response(this: Resolver, node: ast.OperationNode): string\n}\n\n/**\n * Builds the shared `param` namespace. Spread the result into `createResolver`\n * and override individual methods next to it when a plugin deviates.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ param: createOperationParamResolver(), ... })\n * ```\n */\nexport function createOperationParamResolver(): OperationParamResolver {\n return {\n name(node, param) {\n const name = this.name(`${node.operationId} ${param.in} ${param.name}`)\n return this.resolveName({ key: operationKey(node, 'param', 'name', param.in, param.name), name })\n },\n path(node) {\n const name = this.name(`${node.operationId} Path`)\n return this.resolveName({ key: operationKey(node, 'param', 'path'), name })\n },\n query(node) {\n const name = this.name(`${node.operationId} Query`)\n return this.resolveName({ key: operationKey(node, 'param', 'query'), name })\n },\n headers(node) {\n const name = this.name(`${node.operationId} Headers`)\n return this.resolveName({ key: operationKey(node, 'param', 'headers'), name })\n },\n cookies(node) {\n const name = this.name(`${node.operationId} Cookies`)\n return this.resolveName({ key: operationKey(node, 'param', 'cookies'), name })\n },\n }\n}\n\n/**\n * Builds the shared `response` namespace. Spread the result into\n * `createResolver` and add plugin-specific methods (`options`, `error`) next\n * to it.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ response: { ...createOperationResponseResolver(), options(node) {...} }, ... })\n * ```\n */\nexport function createOperationResponseResolver(): OperationResponseResolver {\n return {\n status(node, statusCode) {\n const name = this.name(`${node.operationId} Status ${statusCode}`)\n return this.resolveName({ key: operationKey(node, 'response', 'status', statusCode), name })\n },\n headers(node, statusCode) {\n const name = this.name(`${node.operationId} Status ${statusCode} Headers`)\n return this.resolveName({ key: operationKey(node, 'response', 'headers', statusCode), name })\n },\n body(node) {\n const name = this.name(`${node.operationId} Body`)\n return this.resolveName({ key: operationKey(node, 'response', 'body'), name })\n },\n responses(node) {\n const name = this.name(`${node.operationId} Responses`)\n return this.resolveName({ key: operationKey(node, 'response', 'responses'), name })\n },\n response(node) {\n const name = this.name(`${node.operationId} Response`)\n return this.resolveName({ key: operationKey(node, 'response', 'response'), name })\n },\n }\n}\n\n/**\n * Builds a resolver `file` override whose base name runs every path segment\n * through `toFilePath`, casing the final segment with `caseLast`.\n *\n * @example\n * ```ts\n * createResolver<PluginTs>({ file: createCasedFile(pascalCase), ... })\n * ```\n */\nexport function createCasedFile(caseLast: (part: string) => string): ResolverFile {\n return {\n baseName({ name, extname }) {\n return this.memo(`file:${name}\\0${extname}`, (): ast.FileNode['baseName'] => `${toFilePath(name, caseLast)}${extname}`)\n },\n }\n}\n\ntype SchemaIndexContext = Pick<GeneratorContext, 'memo' | 'driver'>\n\n/**\n * Names of the schemas in a circular reference chain, computed once per build.\n */\nexport function getCircularNames(ctx: SchemaIndexContext): ReadonlySet<string> {\n return ctx.memo('circularNames:set', () => ast.graph.getCircularNames(ctx.driver.inputNode?.schemas ?? []))\n}\n\n/**\n * Names of the schemas whose type is `enum`, computed once per build.\n */\nexport function getEnumNames(ctx: SchemaIndexContext): ReadonlySet<string> {\n return ctx.memo(\n 'enumNames:set',\n () => new Set((ctx.driver.inputNode?.schemas ?? []).flatMap((schema) => (schema.type === 'enum' && schema.name ? [schema.name] : []))),\n )\n}\n\ndeclare global {\n namespace Kubb {\n interface MemoRegistry {\n operation: string\n file: ast.FileNode['baseName']\n operationTypeNames: Array<string>\n }\n }\n}\n","import { isValidVarName, toLiteral } from '@internals/utils'\nimport { toResponseContent } from '@internals/shared'\n\nimport { ast, text } from '@kubb/kit'\n\n// Headers use the `simple` style, so an array or object is sent comma-separated.\nfunction toSimpleStyle(value: unknown): string {\n if (Array.isArray(value)) return value.join(',')\n if (typeof value === 'object' && value !== null) return Object.entries(value).flat().join(',')\n return String(value)\n}\n\n/**\n * The declared headers a mock sends, each with its example's `serializedValue` or `value`, else its schema's `default` or first example.\n */\nexport function getMockHeaders(response: ast.ResponseNode | null | undefined): Array<[name: string, value: string]> {\n return (response?.headers ?? []).flatMap((header): Array<[string, string]> => {\n // OpenAPI ignores a `Content-Type` response header, and the mock already sends one.\n if (header.name.toLowerCase() === 'content-type') return []\n const example = header.examples?.find((entry) => entry.serializedValue !== undefined || entry.value !== undefined)\n const headerValue = example?.serializedValue ?? example?.value ?? header.schema.default ?? header.schema.examples?.[0]\n if (headerValue === undefined || headerValue === null) return []\n const headerText = toSimpleStyle(headerValue)\n // `Headers` throws on a line break or a character above U+00FF, so such an example is left out.\n return /^[\\t\\x20-\\x7E\\x80-\\xFF]*$/.test(headerText) ? [[header.name, headerText]] : []\n })\n}\n\n/**\n * Returns the base URL as source code. A `${...}` value stays a template literal.\n */\nexport function resolveDefaultBaseURL(baseURL: string | null | undefined): string {\n if (!baseURL) {\n return \"''\"\n }\n if (baseURL.includes('${')) {\n return `\\`${baseURL.replaceAll('`', '\\\\`')}\\``\n }\n return JSON.stringify(baseURL)\n}\n\n/**\n * Gets the content type from a response, defaulting to 'application/json' if a schema exists.\n */\nexport function getContentType(response: ast.ResponseNode | null | undefined): string | null {\n if (!hasResponseSchema(response)) {\n return null\n }\n\n return getResponseContentType(response) ?? 'application/json'\n}\n\n/**\n * Determines if a response has a usable body schema.\n */\nexport function hasResponseSchema(response: ast.ResponseNode | null | undefined): boolean {\n const schema = response?.content?.find((entry) => entry.schema)?.schema\n return !!schema && schema.type !== 'void' && schema.type !== 'any' && schema.type !== 'unknown'\n}\n\n/**\n * Picks the content type used for the mocked response header. When a response declares multiple\n * content types, JSON is preferred (the faker mock body is JSON), otherwise the first declared type.\n */\nfunction getResponseContentType(response: ast.ResponseNode | null | undefined): string | null {\n const contentType = getResponseEntry(response)?.contentType\n return typeof contentType === 'string' && contentType.length > 0 ? contentType : null\n}\n\nfunction getResponseEntry(response: ast.ResponseNode | null | undefined): ast.ContentNode | undefined {\n const contents = response?.content ?? []\n return contents.find((entry) => ast.mediaType.isJson(entry)) ?? contents[0]\n}\n\n/**\n * The first content type of a response that the client reads as text, such as `application/xml`, or `null` when none is.\n */\nfunction getTextContentType(response: ast.ResponseNode | null | undefined): string | null {\n const entry = (response?.content ?? []).find((entry) => {\n const schema = toResponseContent(entry, response?.content).schema\n return !ast.mediaType.isJson(entry) && schema && ast.ref.getSchema(schema).primitive === 'string'\n })\n return entry?.contentType ?? null\n}\n\n// The client's `jsonReplacer`: a `bigint` goes out as a JSON number, and throws past the safe-integer range instead of losing precision.\nconst bigintReplacer = `(_key, value) => {\n if (typeof value !== 'bigint') return value\n if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) throw new TypeError(\\`Cannot serialize \\${value}n as JSON without losing precision.\\`)\n return Number(value)\n }`\n\n/** The `JSON.stringify` call for `body`, with a replacer when the response holds an `int64`, which `JSON.stringify` throws on. */\nfunction stringify(body: string, response: ast.ResponseNode | null | undefined): string {\n const hasBigint = (response?.content ?? []).some(\n (entry) => entry.schema && ast.schema.find(entry.schema, { predicate: (schema) => schema.type === 'bigint', followRefs: true }) !== undefined,\n )\n return hasBigint ? `JSON.stringify(${body}, ${bigintReplacer})` : `JSON.stringify(${body})`\n}\n\n/**\n * The statements that return a mocked `Response` for `body`. A string body for a response the client reads as text goes\n * out as raw text with that content type, so an XML mock is not sent as a quoted JSON string. Any other body is JSON.\n */\nexport function responseReturn(body: string, status: number, response: ast.ResponseNode | null | undefined): string {\n const contentType = getContentType(response)\n const headers = getMockHeaders(response)\n // A plain variable such as `data` is checked as it is, an expression such as `data ?? createPet()` is read once.\n const name = isValidVarName(body) ? body : 'body'\n const prelude = name === body ? '' : `const body = ${body}\\n `\n\n // shortcut: one event per mock, upgrade when a mock needs to send several events.\n if (contentType && ast.mediaType.getBase(contentType) === 'text/event-stream') {\n const entry = getResponseEntry(response)\n // Without a body, a spec example already serialized as SSE text goes out as it is.\n const serialized = entry?.examples?.find((example) => example.serializedValue !== undefined)?.serializedValue\n const fallback = serialized === undefined ? \"''\" : toLiteral(serialized)\n if (entry?.stream?.shape !== 'event') {\n return `${prelude}return ${responseLiteral(`${name} === undefined ? ${fallback} : \\`\\${${eventDataLines(name, response)}}\\\\n\\\\n\\``, status, contentType, headers)}`\n }\n // The item is the whole event, so its fields become SSE lines and the client parses it back to the same object.\n return `${prelude}const event = ${name} as { event?: unknown; id?: unknown; retry?: unknown; data?: unknown } | undefined\n const lines = [\n ...(['event', 'id', 'retry'] as const).filter((field) => event?.[field] !== undefined).map((field) => \\`\\${field}: \\${event?.[field]}\\`),\n // A client dispatches an event only once it has a \\`data\\` line, so an event without data still sends an empty one.\n event?.data === undefined ? 'data:' : ${eventDataLines('event.data', response)},\n ]\n\n return ${responseLiteral(`event === undefined ? ${fallback} : \\`\\${lines.join('\\\\n')}\\\\n\\\\n\\``, status, contentType, headers)}`\n }\n\n const textContentType = hasResponseSchema(response) ? getTextContentType(response) : null\n if (!textContentType) return `return ${responseLiteral(stringify(body, response), status, contentType, headers)}`\n\n return `${prelude}if (typeof ${name} === 'string') return ${responseLiteral(name, status, textContentType, headers)}\n\n return ${responseLiteral(stringify(name, response), status, contentType, headers)}`\n}\n\n/**\n * The `data:` lines of one Server-Sent Event. A string goes out as it is, since a client keeps string `data` as text.\n */\nfunction eventDataLines(body: string, response: ast.ResponseNode | null | undefined): string {\n return `(typeof ${body} === 'string' ? ${body} : ${stringify(body, response)}).split('\\\\n').map((line) => \\`data: \\${line}\\`).join('\\\\n')`\n}\n\n/**\n * The spec example of the response entry the mock sends, as source code, or `null` when that entry has none.\n */\nexport function getExampleBody(response: ast.ResponseNode | null | undefined): string | null {\n const entry = getResponseEntry(response)\n const example = entry?.examples?.find((item) => item.value !== undefined || item.serializedValue !== undefined)\n if (!entry || !example) return null\n if (example.value !== undefined) return toLiteral(example.value)\n // `responseReturn` sends raw text only for a text response. For a binary one the example would go out JSON-encoded.\n // A serialized SSE example is already events, which `responseReturn` sends as is when the body is `undefined`.\n if (!ast.mediaType.isJson(entry)) {\n const isTextBody = ast.mediaType.getBase(entry) !== 'text/event-stream' && getTextContentType(response) === entry.contentType\n return isTextBody ? toLiteral(example.serializedValue) : null\n }\n // `responseReturn` encodes a JSON body itself, so a serialized JSON example is parsed first.\n try {\n return toLiteral(JSON.parse(example.serializedValue!))\n } catch {\n return null\n }\n}\n\nconst mswMethods = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n\n/**\n * Converts an HTTP method to its lowercase MSW equivalent (e.g., 'POST' → 'post'). MSW has no `http.query`, `http.trace` or\n * handler for a custom `additionalOperations` method, so such an operation maps to `http.all` and its handler checks the\n * method itself.\n */\nexport function getMswMethod(node: ast.HttpOperationNode): string {\n return mswMethods.has(node.method) ? node.method.toLowerCase() : 'all'\n}\n\n/**\n * The `headers` entry of a mocked `Response` init, or an empty string when there is no header to send.\n */\nfunction headersBlock(contentType: string | null, headers: Array<[string, string]>): string {\n const entries = [\n ...(contentType ? [`'Content-Type': ${text.quote(contentType)}`] : []),\n ...headers.map(([name, value]) => `${text.quote(name)}: ${text.quote(value)}`),\n ]\n return entries.length ? `\\n headers: {\\n ${entries.join(',\\n ')}\\n },` : ''\n}\n\n/**\n * The `new HttpResponse<string>(...)` expression a mocked handler returns.\n */\nexport function responseLiteral(body: string, status: number, contentType: string | null, headers: Array<[string, string]>): string {\n return `new HttpResponse<string>(${body}, {\n status: ${status},${headersBlock(contentType, headers)}\n })`\n}\n","import { ast, text } from '@kubb/kit'\nimport { Url } from '@kubb/kit'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx'\nimport { getExampleBody, getMswMethod, hasResponseSchema, resolveDefaultBaseURL, responseReturn } from '../utils.ts'\n\ntype Props = {\n name: string\n typeName: string\n requestTypeName?: string | null\n fakerName?: string\n /**\n * The `...Response<status>` helper of the response this handler mocks, when its `data` has the handler's type.\n */\n responseName?: string\n baseURL: string | null | undefined\n node: ast.HttpOperationNode\n}\n\nexport function Mock({ baseURL = '', name, fakerName, responseName, typeName, requestTypeName, node }: Props): KubbReactNode {\n const method = getMswMethod(node)\n // `http.all` matches every method on the path, so a handler for a method MSW has no helper for lets the others pass through.\n const methodGuard = method === 'all' ? `if (info.request.method !== ${text.quote(node.method)}) return\\n\\n ` : ''\n const successResponse = ast.http.responses.findPrimary(node)\n const statusCode = successResponse ? ast.http.status.toCode(successResponse) : 200\n const url = Url.toPath(node.path)\n\n const responseHasSchema = hasResponseSchema(successResponse)\n const dataType = responseHasSchema ? typeName : 'string | number | boolean | null | object'\n const paramType = fakerName ? typeName : dataType\n const requestBodyType = requestTypeName ? `${requestTypeName} extends DefaultBodyType ? ${requestTypeName} : DefaultBodyType` : null\n\n const callbackType = requestBodyType\n ? `HttpResponseResolver<Record<string, string>, ${requestBodyType}>`\n : `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`\n\n const params = `data?: ${paramType} | ${callbackType}, options?: { baseURL?: string }`\n\n const httpCall = requestBodyType ? `http.${method}<Record<string, string>, ${requestBodyType}>` : `http.${method}`\n\n // Escape colons that do not start a param, such as the second one in `/pet/:petId:search`.\n const urlLiteral = `\\`\\${options?.baseURL ?? ${resolveDefaultBaseURL(baseURL)}}${url.replace(/([^/]):/g, '$1\\\\\\\\:')}\\``\n // Without Faker, the spec's own response example is the default body. An explicit `null` stays a `null` body.\n const example = fakerName ? null : getExampleBody(successResponse)\n const exampleBody = example ? `data === undefined ? ${example} : data` : 'data'\n const responseBody = fakerName ? `data ?? ${fakerName}()` : exampleBody\n // A spec example is not checked against the response type, so it is not passed to the typed helper.\n const responseStatements = responseName && !example ? `return ${responseName}(${responseBody})` : responseReturn(responseBody, statusCode, successResponse)\n\n return (\n <File.Source name={name} isIndexable isExportable>\n <Function name={name} export params={params}>\n {`return ${httpCall}(${urlLiteral}, function handler(info) {\n ${methodGuard}if(typeof data === 'function') return data(info)\n\n ${responseStatements}\n })`}\n </Function>\n </File.Source>\n )\n}\n","import { ast } from '@kubb/kit'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx'\nimport { responseReturn } from '../utils.ts'\n\ntype Props = {\n typeName: string\n name: string\n response: ast.ResponseNode\n}\n\nexport function Response({ name, typeName, response }: Props): KubbReactNode {\n // Optional, since a handler passes on the `data` it got, which may be left out.\n const params = `data?: ${typeName}`\n\n const responseName = `${name}Response${response.statusCode}`\n\n return (\n <File.Source name={responseName} isIndexable isExportable>\n <Function name={responseName} export params={params}>\n {`\n ${responseReturn('data', ast.http.status.toCode(response), response)}`}\n </Function>\n </File.Source>\n )\n}\n","import { getEnumNames, resolveOperationFile } from '@internals/shared'\nimport { ast, defineGenerator } from '@kubb/kit'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { enumTypeName, pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from '@kubb/renderer-jsx'\nimport { Mock } from '../components/Mock.tsx'\nimport { Response } from '../components/Response.tsx'\nimport type { PluginMsw } from '../types'\nimport { hasResponseSchema } from '../utils.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-msw`. Emits one MSW handler\n * per OpenAPI operation. With `parser: 'faker'` the handler returns a value\n * from `@kubb/plugin-faker`; with `parser: 'data'` it returns a typed empty\n * payload for tests to fill in.\n */\nexport const mswGenerator = defineGenerator<PluginMsw>({\n name: 'msw',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.http.isOperation(node)) return null\n const { driver, resolver, config, root } = ctx\n const { output, parser, baseURL, group } = ctx.options\n\n const fileName = resolver.name(node.operationId)\n const mock = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: fileName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n }\n\n const fakerPlugin = parser === 'faker' ? ctx.requirePlugin(pluginFakerName) : null\n const fakerResolver = fakerPlugin ? driver.getResolver(pluginFakerName) : null\n const faker =\n fakerPlugin && fakerResolver\n ? {\n name: fakerResolver.response.response(node),\n file: resolveOperationFile({\n ctx,\n node,\n resolver: fakerResolver,\n root,\n output: fakerPlugin.options?.output ?? output,\n group: fakerPlugin.options?.group ?? undefined,\n }),\n }\n : null\n\n const pluginTs = ctx.requirePlugin(pluginTsName)\n const tsResolver = driver.getResolver(pluginTsName)\n\n const type = {\n file: resolveOperationFile({\n ctx,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n responseName: tsResolver.response.response(node),\n }\n\n const successResponses = ast.http.responses.filterSuccess(node)\n const referencedNames = ast.http.responses.getImportedNames(node.responses)\n const enumOptions = pluginTs.options?.enum\n const enumNames = getEnumNames(ctx)\n const hasResponseNameCollision = referencedNames.some((name) => {\n return enumTypeName({ resolver: tsResolver, name, enumOptions, isEnum: enumNames.has(name) }) === type.responseName\n })\n // One helper per documented status, a range such as `4xx` included. `default` has no status to mock,\n // and the Fetch `Response` constructor rejects a `1xx` status.\n const types = node.responses\n .filter((response) => response.statusCode !== 'default' && ast.http.status.getClass(response) !== 1)\n .map((response) => {\n const isResponseType = ast.http.status.isSuccess(response) && !hasResponseNameCollision\n return [response, isResponseType ? type.responseName : tsResolver.response.status(node, response.statusCode)] as const\n })\n const responseTypeNames = types.map(([, typeName]) => typeName)\n const mockResponseName =\n hasResponseNameCollision && successResponses[0] ? tsResolver.response.status(node, successResponses[0].statusCode) : type.responseName\n const hasSuccessSchema = successResponses.some((response) => hasResponseSchema(response))\n // The handler calls the helper of the response it mocks when that helper takes the handler's own data type.\n const primaryResponse = ast.http.responses.findPrimary(node)\n const responseHelperName =\n primaryResponse &&\n hasResponseSchema(primaryResponse) &&\n types.some(([response, typeName]) => response.statusCode === primaryResponse.statusCode && typeName === mockResponseName)\n ? `${mock.name}Response${primaryResponse.statusCode}`\n : undefined\n\n const requestName = ast.http.requestBody.getSchema(node) ? tsResolver.response.body(node) : null\n\n return (\n <File\n baseName={mock.file.baseName}\n path={mock.file.path}\n meta={mock.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: mock.file.path, baseName: mock.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: mock.file.path, baseName: mock.file.baseName } })}\n >\n <File.Import name={['http', 'HttpResponse']} path=\"msw/http\" />\n <File.Import name={['HttpResponseResolver']} isTypeOnly path=\"msw/http\" />\n {requestName && <File.Import name={['DefaultBodyType']} isTypeOnly path=\"msw\" />}\n <File.Import\n name={Array.from(new Set([...(hasResponseNameCollision ? [] : [type.responseName]), ...responseTypeNames, ...(requestName ? [requestName] : [])]))}\n path={type.file.path}\n root={mock.file.path}\n isTypeOnly\n />\n {faker && hasSuccessSchema && <File.Import name={[faker.name]} root={mock.file.path} path={faker.file.path} />}\n\n {types.map(([response, typeName]) => (\n <Response key={response.statusCode} typeName={typeName} response={response} name={mock.name} />\n ))}\n\n <Mock\n name={mock.name}\n typeName={mockResponseName}\n requestTypeName={requestName}\n fakerName={faker && hasSuccessSchema ? faker.name : undefined}\n responseName={responseHelperName}\n node={node}\n baseURL={baseURL}\n />\n </File>\n )\n },\n})\n","import { operationKey } from '@internals/shared'\nimport { casing, createResolver } from '@kubb/kit'\nimport type { PluginMsw } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-msw`. Decides the names and file\n * paths for every generated MSW handler. Function names get a `Handler`\n * suffix; the aggregate export is always `handlers`.\n *\n * The top-level `name` applies the `handler` suffix, and `file` falls back to the built-in\n * `toFilePath` casing. Operation-specific naming is grouped under the `handler` namespace.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMsw } from '@kubb/plugin-msw'\n *\n * resolverMsw.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMsw = createResolver<PluginMsw>({\n pluginName: 'plugin-msw',\n name(name) {\n return this.memo(`name:${name}`, () => casing.camel(name, { suffix: 'handler' }))\n },\n handler: {\n name(node) {\n const name = this.name(node.operationId)\n return this.resolveName({ key: operationKey(node, 'handler', 'name'), name })\n },\n listName() {\n return this.resolveName({ key: ['handlers', 'list'], name: 'handlers' })\n },\n },\n})\n","import { addGenerator, defineExtension, Resolver, setMacros, setResolver } from '@kubb/kit'\nimport { compatibility } from '../kubb-extension.json'\nimport { version } from '../package.json'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { handlersGenerator } from './generators/handlersGenerator.ts'\nimport { mswGenerator } from './generators/mswGenerator.tsx'\nimport { resolverMsw } from './resolvers/resolverMsw.ts'\nimport type { PluginMsw, ResolverMsw } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-msw`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']\n\n/**\n * Generates MSW request handlers from an OpenAPI spec. Drop them into your\n * test setup or service worker to mock the API end-to-end. Request path,\n * method, status, and response body all stay in sync with the spec. Combine\n * with `@kubb/plugin-faker` (via `parser: 'faker'`) to seed handlers with\n * realistic data.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginMsw } from '@kubb/plugin-msw'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginMsw({\n * output: { path: './handlers' },\n * handlers: true,\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMsw = defineExtension<PluginMsw>({\n kind: 'plugin',\n meta: { name: pluginMswName, version, compatibility },\n dependencies: (options) => ({ [pluginTsName]: {}, ...(options.parser === 'faker' ? { [pluginFakerName]: {} } : {}) }),\n setup(options) {\n const {\n output = { path: 'handlers', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n handlers = false,\n parser = 'data',\n baseURL,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const resolver = userResolver ? Resolver.merge<ResolverMsw>(resolverMsw, userResolver) : resolverMsw\n\n setResolver(resolver)\n if (userMacros?.length) {\n setMacros(userMacros)\n }\n\n addGenerator(mswGenerator)\n if (handlers) {\n addGenerator(handlersGenerator)\n }\n\n return {\n output,\n parser,\n baseURL,\n group: group ?? null,\n exclude,\n include,\n override,\n handlers,\n }\n },\n})\n\nexport default pluginMsw\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -131,5 +131,4 @@ export declare const pluginMsw: import("@kubb/kit").PluginFactory<PluginMsw>;
131
131
  * ```
132
132
  */
133
133
  export declare const resolverMsw: ResolverMsw;
134
- export { type PluginMsw, type ResolverMsw, pluginMsw as default };
135
- //# sourceMappingURL=index.d.cts.map
134
+ export { type PluginMsw, type ResolverMsw, pluginMsw as default };
package/dist/index.d.ts CHANGED
@@ -131,5 +131,4 @@ export declare const pluginMsw: import("@kubb/kit").PluginFactory<PluginMsw>;
131
131
  * ```
132
132
  */
133
133
  export declare const resolverMsw: ResolverMsw;
134
- export { type PluginMsw, type ResolverMsw, pluginMsw as default };
135
- //# sourceMappingURL=index.d.ts.map
134
+ export { type PluginMsw, type ResolverMsw, pluginMsw as default };