@kubb/plugin-fetch 5.0.0-beta.73
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.
- package/README.md +70 -0
- package/dist/index.cjs +1260 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.js +1231 -0
- package/dist/index.js.map +1 -0
- package/dist/rolldown-runtime-C0LytTxp.js +8 -0
- package/package.json +82 -0
- package/src/generators/clientGenerator.tsx +90 -0
- package/src/index.ts +3 -0
- package/src/plugin.ts +95 -0
- package/src/templates.ts +8 -0
- package/src/types.ts +19 -0
- package/templates/fetch.ts +578 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["ast","File","Function","ast","File","File","pluginTsName","pluginZodName","ast","jsxRenderer","path","File","macroSimplifyUnion","jsxRenderer","ast","pluginTsName","pluginZodName","path","File","pluginTsName","pluginZodName","path"],"sources":["../../../internals/client/src/builders/parser.ts","../../../internals/client/src/builders/security.ts","../../../internals/utils/src/casing.ts","../../../internals/utils/src/fs.ts","../../../internals/utils/src/reserved.ts","../../../internals/utils/src/url.ts","../../../internals/shared/src/params.ts","../../../internals/shared/src/operation.ts","../../../internals/shared/src/group.ts","../../../internals/client/src/builders/generics.ts","../../../internals/client/src/builders/returnStatement.ts","../../../internals/client/src/builders/signature.ts","../../../internals/client/src/builders/validator.ts","../../../internals/client/src/components/Operation.tsx","../../../internals/client/src/builders/sdkMethod.ts","../../../internals/client/src/components/SdkClient.tsx","../../../internals/client/src/components/SdkFacade.tsx","../../../internals/client/src/generators/sdkGenerator.tsx","../../../internals/client/src/macros.ts","../../../internals/client/src/resolver.ts","../src/generators/clientGenerator.tsx","../src/templates.ts","../src/plugin.ts"],"sourcesContent":["import type { ast } from '@kubb/core'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport type { ParserOptions } from '../types.ts'\n\n/**\n * Returns `true` when any direction of the parser uses zod (used for dependency checks).\n */\nexport function isParserEnabled(parser: ParserOptions | undefined): boolean {\n if (!parser) return false\n if (parser === 'zod') return true\n return Boolean(parser.request || parser.response)\n}\n\n/**\n * Returns `'zod'` when request body parsing is enabled, `null` otherwise. The string shorthand\n * `'zod'` validates the response only, so it does not enable request parsing.\n */\nexport function resolveRequestParser(parser: ParserOptions | undefined): 'zod' | null {\n if (!parser || parser === 'zod') return null\n return parser.request ?? null\n}\n\n/**\n * Returns `'zod'` when query-parameters parsing is enabled, `null` otherwise. Only the object form\n * `{ request: 'zod' }` enables it.\n */\nexport function resolveQueryParamsParser(parser: ParserOptions | undefined): 'zod' | null {\n if (!parser || parser === 'zod') return null\n return parser.request ?? null\n}\n\n/**\n * Returns `'zod'` when response parsing is enabled, `null` otherwise. The string shorthand `'zod'`\n * maps to response parsing.\n */\nexport function resolveResponseParser(parser: ParserOptions | undefined): 'zod' | null {\n if (!parser) return null\n if (parser === 'zod') return 'zod'\n return parser.response ?? null\n}\n\n/**\n * The zod validation a generated client applies to a success response body.\n */\nexport type ZodResponseParse = {\n /**\n * The success-only response schema name that the generated code calls `.parse(data)` on.\n */\n expression: string\n /**\n * Schema names the generated file imports from the zod plugin output.\n */\n importNames: Array<string>\n}\n\n/**\n * Resolves the zod expression a generated client validates a success response with. Only success\n * (2xx) bodies reach the parse under the throw-on-error contract, so the success-only\n * `<operation>ResponseSchema` is used; error bodies are never zod-parsed.\n */\nexport function buildZodResponseParse(node: ast.OperationNode, zodResolver: ResolverZod): ZodResponseParse | null {\n const name = zodResolver.resolveResponseName?.(node)\n return name ? { expression: name, importNames: [name] } : null\n}\n","/**\n * A resolved security scheme as emitted on each generated call's `security` array. The runtime calls\n * the configured `auth` resolver with this object and places the returned token: `http` bearer/basic\n * on `Authorization`, `apiKey` under `name` in the header/query/cookie, and `oauth2`/`openIdConnect`\n * as a bearer token.\n */\nexport type Auth = {\n type: 'http' | 'apiKey' | 'oauth2' | 'openIdConnect'\n scheme?: 'bearer' | 'basic'\n name?: string\n in?: 'header' | 'query' | 'cookie'\n}\n\n/**\n * A single OpenAPI security requirement read from the spec: scheme name to the scopes it needs.\n */\ntype SecurityRequirement = Record<string, Array<string>>\n\n/**\n * The slice of an OpenAPI document the security derivation reads: the global `security`, the\n * per-operation `security` under `paths`, and the `securitySchemes` map under `components`. Typed\n * locally so this package stays independent of the OpenAPI adapter.\n */\nexport type SecurityDocument = {\n security?: Array<SecurityRequirement>\n components?: {\n securitySchemes?: Record<string, OasSecurityScheme | { $ref: string } | undefined>\n }\n paths?: Record<string, Record<string, { security?: Array<SecurityRequirement> } | undefined> | undefined>\n}\n\ntype OasSecurityScheme = { type: 'http'; scheme?: string } | { type: 'apiKey'; name?: string; in?: string } | { type: 'oauth2' } | { type: 'openIdConnect' }\n\nfunction serializeAuth(auth: Auth): string {\n const parts = [`type: '${auth.type}'`]\n if (auth.scheme) parts.push(`scheme: '${auth.scheme}'`)\n if (auth.name) parts.push(`name: '${auth.name}'`)\n if (auth.in) parts.push(`in: '${auth.in}'`)\n return `{ ${parts.join(', ')} }`\n}\n\n/**\n * Maps an OpenAPI security scheme to the inline `Auth` object, or `null` when the runtime cannot\n * place it (an unresolved `$ref`, or an `apiKey` without a name or outside `header` / `query` /\n * `cookie`). `http` schemes other than `basic` are treated as bearer.\n */\nexport function resolveSecurityScheme(scheme: OasSecurityScheme | { $ref: string } | undefined): Auth | null {\n if (!scheme || '$ref' in scheme) return null\n if (scheme.type === 'apiKey') {\n if (!scheme.name || (scheme.in !== 'header' && scheme.in !== 'query' && scheme.in !== 'cookie')) return null\n return { type: 'apiKey', name: scheme.name, in: scheme.in }\n }\n if (scheme.type === 'http') return { type: 'http', scheme: scheme.scheme?.toLowerCase() === 'basic' ? 'basic' : 'bearer' }\n if (scheme.type === 'oauth2') return { type: 'oauth2' }\n if (scheme.type === 'openIdConnect') return { type: 'openIdConnect' }\n return null\n}\n\n/**\n * Derives the per-operation security metadata from the OpenAPI document. The operation's own\n * `security` overrides the global `security` (an explicit empty array disables auth), and every\n * referenced scheme is resolved from `components.securitySchemes` into a flat, de-duplicated list of\n * `Auth` objects the runtime walks in order.\n *\n * @example\n * `getOperationSecurity({ document, method: 'POST', path: '/pet' })`\n * `// [{ type: 'http', scheme: 'bearer' }]`\n */\nexport function getOperationSecurity({\n document,\n method,\n path,\n}: {\n document: SecurityDocument | null | undefined\n method: string\n path: string\n}): Array<Auth> | undefined {\n if (!document) return undefined\n\n const operation = document.paths?.[path]?.[method.toLowerCase()]\n const requirements = operation?.security ?? document.security\n if (!requirements?.length) return undefined\n\n const definitions = document.components?.securitySchemes ?? {}\n const security: Array<Auth> = []\n const seen = new Set<string>()\n for (const requirement of requirements) {\n for (const schemeName of Object.keys(requirement)) {\n if (seen.has(schemeName)) continue\n seen.add(schemeName)\n const auth = resolveSecurityScheme(definitions[schemeName])\n if (auth) security.push(auth)\n }\n }\n\n return security.length ? security : undefined\n}\n\n/**\n * Serializes the per-operation security into the literal emitted on each generated call's `security`\n * field. The runtime `resolveAuth` helper walks it, calling the configured `auth` resolver per entry.\n *\n * @example\n * `buildSecurityMetadata({ security: [{ type: 'http', scheme: 'bearer' }] }) // \"[{ type: 'http', scheme: 'bearer' }]\"`\n */\nexport function buildSecurityMetadata({ security }: { security?: Array<Auth> }): string | null {\n if (!security?.length) return null\n return `[${security.map(serializeAuth).join(', ')}]`\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example From camelCase\n * `snakeCase('helloWorld') // 'hello_world'`\n *\n * @example From mixed separators\n * `snakeCase('Hello-World') // 'hello_world'`\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example From camelCase\n * `screamingSnakeCase('helloWorld') // 'HELLO_WORLD'`\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { posix } from 'node:path'\nimport { camelCase } from './casing.ts'\n\nfunction toSlash(p: string): string {\n if (p.startsWith('\\\\\\\\?\\\\')) return p\n return p.replaceAll('\\\\', '/')\n}\n\n/**\n * Returns the relative path from `rootDir` to `filePath`, always using forward slashes\n * and prefixed with `./` when not already traversing upward.\n *\n * @example\n * ```ts\n * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'\n * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'\n * ```\n */\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = posix.relative(toSlash(rootDir), toSlash(filePath))\n\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Builds a nested file path from a dotted name. Splits on dots that precede a letter\n * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases\n * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.\n *\n * Empty segments are dropped before joining. They arise when the name starts with a dot\n * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to\n * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an\n * absolute path, letting generated files escape the configured output directory.\n *\n * @example Nested path from a dotted name\n * `toFilePath('pet.petId') // 'pet/petId'`\n *\n * @example PascalCase the final segment\n * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`\n *\n * @example Suffix applied to the final segment only\n * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`\n */\nexport function toFilePath(name: string, caseLast: (part: string) => string = camelCase): string {\n const parts = name.split(/\\.(?=[a-zA-Z])/)\n return parts\n .map((part, i) => (i === parts.length - 1 ? caseLast(part) : camelCase(part)))\n .filter(Boolean)\n .join('/')\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 '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 /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(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","import { camelCase } from './casing.ts'\nimport { isValidVarName } from './reserved.ts'\n\nexport type URLObject = {\n /**\n * The resolved URL string (Express-style or template literal, depending on context).\n */\n url: string\n /**\n * Extracted path parameters as a key-value map, or `null` when the path has none.\n */\n params: Record<string, string> | null\n}\n\n/**\n * Supported identifier casing strategies for path parameters.\n */\nexport type PathCasing = 'camelcase'\n\ntype TemplateOptions = {\n /**\n * Literal text prepended inside the template literal, e.g. a base URL.\n */\n prefix?: string | null\n /**\n * Transform applied to each extracted parameter name before interpolation.\n */\n replacer?: (pathParam: string) => string\n /**\n * Casing strategy applied to path parameter names.\n */\n casing?: PathCasing\n}\n\ntype ObjectOptions = {\n /**\n * Controls whether the `url` is rendered as an Express path or a template literal.\n * @default 'path'\n */\n type?: 'path' | 'template'\n /**\n * Transform applied to each extracted parameter name.\n */\n replacer?: (pathParam: string) => string\n /**\n * When `true`, the result is serialized to a string expression instead of a plain object.\n */\n stringify?: boolean\n /**\n * Casing strategy applied to path parameter names.\n */\n casing?: PathCasing\n}\n\nfunction transformParam(raw: string, casing?: PathCasing): string {\n const param = isValidVarName(raw) ? raw : camelCase(raw)\n return casing === 'camelcase' ? camelCase(param) : param\n}\n\nfunction toParamsObject(\n path: string,\n { replacer, casing }: { replacer?: (pathParam: string) => string; casing?: PathCasing } = {},\n): Record<string, string> | null {\n const params: Record<string, string> = {}\n\n for (const match of path.matchAll(/\\{([^}]+)\\}/g)) {\n const param = transformParam(match[1]!, casing)\n const key = replacer ? replacer(param) : param\n params[key] = key\n }\n\n return Object.keys(params).length > 0 ? params : null\n}\n\n/**\n * Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.\n */\nexport class Url {\n /**\n * Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.\n *\n * @example\n * Url.canParse('https://petstore.swagger.io/v2') // true\n * Url.canParse('/pet/{petId}') // false\n */\n static canParse(url: string, base?: string | URL): boolean {\n return URL.canParse(url, base)\n }\n\n /**\n * Converts an OpenAPI/Swagger path to Express-style colon syntax.\n *\n * @example\n * Url.toPath('/pet/{petId}') // '/pet/:petId'\n */\n static toPath(path: string): string {\n return path.replace(/\\{([^}]+)\\}/g, ':$1')\n }\n\n /**\n * Converts an OpenAPI/Swagger path to a TypeScript template literal string.\n * `prefix` is prepended inside the literal, `replacer` transforms each parameter name,\n * and `casing` controls parameter identifier casing.\n *\n * @example\n * Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'\n *\n * @example\n * Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'\n */\n static toTemplateString(path: string, { prefix, replacer, casing }: TemplateOptions = {}): string {\n const parts = path.split(/\\{([^}]+)\\}/)\n const result = parts\n .map((part, i) => {\n if (i % 2 === 0) return part\n const param = transformParam(part, casing)\n return `\\${${replacer ? replacer(param) : param}}`\n })\n .join('')\n\n return `\\`${prefix ?? ''}${result}\\``\n }\n\n /**\n * Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the\n * grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter\n * names are camelCased to match the generated `path` type, and `prefix` is prepended inside the\n * literal. Shared by the client and cypress generators that pass a grouped `path` object.\n *\n * @example\n * Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'\n */\n static toGroupedTemplateString(path: string, { prefix }: { prefix?: string | null } = {}): string {\n return Url.toTemplateString(path, { prefix, casing: 'camelcase', replacer: (name) => `path.${name}` })\n }\n\n /**\n * Returns the path and its extracted params as a structured `URLObject`, or as a stringified\n * expression when `stringify` is set.\n *\n * @example\n * Url.toObject('/pet/{petId}')\n * // { url: '/pet/:petId', params: { petId: 'petId' } }\n */\n static toObject(path: string, { type = 'path', replacer, stringify, casing }: ObjectOptions = {}): URLObject | string {\n const object: URLObject = {\n url: type === 'path' ? Url.toPath(path) : Url.toTemplateString(path, { replacer, casing }),\n params: toParamsObject(path, { replacer, casing }),\n }\n\n if (stringify) {\n if (type === 'template') {\n return JSON.stringify(object).replaceAll(\"'\", '').replaceAll(`\"`, '')\n }\n\n if (object.params) {\n return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll(\"'\", '').replaceAll(`\"`, '')} }`\n }\n\n return `{ url: '${object.url}' }`\n }\n\n return object\n }\n}\n","import { camelCase } from '@internals/utils'\nimport type { ParameterNode } from '@kubb/ast'\n\nconst caseParamsCache = new WeakMap<Array<ParameterNode>, Array<ParameterNode>>()\n\n/**\n * Applies camelCase to parameter names and returns a new array without mutating the input.\n *\n * Run it before handing parameters to schema builders so output property keys get the right casing\n * while `OperationNode.parameters` stays intact for other consumers. When `casing` is unset, the\n * original array is returned unchanged. Results are cached per input array.\n */\nexport function caseParams(params: Array<ParameterNode>, casing: 'camelcase' | undefined): Array<ParameterNode> {\n if (!casing) return params\n\n const cached = caseParamsCache.get(params)\n if (cached) return cached\n\n const result = params.map((param) => ({ ...param, name: camelCase(param.name) }))\n caseParamsCache.set(params, result)\n return result\n}\n\nexport function buildParamsMapping<TParam extends { name: string }>(\n originalParams: ReadonlyArray<TParam>,\n mappedParams: ReadonlyArray<TParam>,\n): Record<string, string> | null {\n const mapping: Record<string, string> = {}\n let hasChanged = false\n\n originalParams.forEach((param, i) => {\n const mappedName = mappedParams[i]?.name ?? param.name\n mapping[param.name] = mappedName\n\n if (param.name !== mappedName) {\n hasChanged = true\n }\n })\n\n return hasChanged ? mapping : null\n}\n\nexport function buildTransformedParamsMapping<TParam extends { name: string }>(\n params: ReadonlyArray<TParam>,\n transformName: (name: string) => string,\n): Record<string, string> | null {\n if (!params.length) {\n return null\n }\n\n return buildParamsMapping(\n params,\n params.map((param) => ({ ...param, name: transformName(param.name) })),\n )\n}\n","import { Url } from '@internals/utils'\nimport { ast, type ResolverFileParams } from '@kubb/core'\nimport { caseParams } from './params.ts'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.resolveFile`: 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.resolveFile(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\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n resolveDataName(node: ast.OperationNode): string\n}\n\nexport type ResponseStatusNameResolver = {\n resolveResponseStatusName(node: ast.OperationNode, statusCode: ast.StatusCode): string\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n resolveResponseName(node: ast.OperationNode): string\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n resolvePathParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n resolveQueryParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n resolveHeaderParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n\n/**\n * Resolver interface for building operation parameters.\n *\n * `ResolverTs` from `@kubb/plugin-ts` satisfies this interface and can be passed directly.\n */\nexport type OperationParamsResolver = {\n /**\n * Resolves the type name for an individual parameter.\n *\n * @example Individual path parameter name\n * `resolver.resolveParamName(node, param) // → 'DeletePetPathPetId'`\n */\n resolveParamName(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the request body type name.\n *\n * @example Request body type name\n * `resolver.resolveDataName(node) // → 'CreatePetData'`\n */\n resolveDataName(node: ast.OperationNode): string\n /**\n * Resolves the grouped path parameters type name.\n * When the return value equals `resolveParamName`, no indexed access is emitted.\n *\n * @example Grouped path params type name\n * `resolver.resolvePathParamsName(node, param) // → 'DeletePetPathParams'`\n */\n resolvePathParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped query parameters type name.\n * When the return value equals `resolveParamName`, an inline struct type is emitted instead.\n *\n * @example Grouped query params type name\n * `resolver.resolveQueryParamsName(node, param) // → 'FindPetsByStatusQueryParams'`\n */\n resolveQueryParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped header parameters type name.\n * When the return value equals `resolveParamName`, an inline struct type is emitted instead.\n *\n * @example Grouped header params type name\n * `resolver.resolveHeaderParamsName(node, param) // → 'DeletePetHeaderParams'`\n */\n resolveHeaderParamsName(node: ast.OperationNode, param: ast.ParameterNode): string\n}\n\nexport type OperationCommentLink = 'pathTemplate' | 'urlPath' | false | ((node: ast.OperationNode) => string | undefined)\n\nexport type BuildOperationCommentsOptions = {\n link?: OperationCommentLink\n linkPosition?: 'beforeDeprecated' | 'afterDeprecated'\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<ast.ParameterNode['in'], Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n paramsCasing?: 'camelcase' | 'original'\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `PathParams`/`QueryParams`/`HeaderParams` type names. Set to `false`\n * for clients that reference the grouped `RequestConfig` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\nfunction getOperationLink(node: ast.OperationNode, link: OperationCommentLink): string | null {\n if (!link) {\n return null\n }\n\n if (typeof link === 'function') {\n return link(node) ?? null\n }\n\n if (link === 'urlPath') {\n return node.path ? `{@link ${Url.toPath(node.path)}}` : null\n }\n\n return node.path ? `{@link ${node.path.replaceAll('{', ':').replaceAll('}', '')}}` : null\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? []\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 type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n\n/**\n * Derives the default `responseType` for an operation from its primary success response.\n *\n * Returns a value only when that response declares a single non-JSON content type — a binary type\n * (`application/octet-stream`, `application/pdf`, `image/*`, `audio/*`, `video/*`) maps to `'blob'`\n * and other `text/*` maps to `'text'`. Otherwise `undefined`, leaving the runtime client's\n * `Content-Type` auto-detection in charge.\n */\nexport function getResponseType(node: ast.OperationNode): ResponseType | undefined {\n const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? []\n if (contentTypes.length !== 1) return undefined\n\n const baseType = contentTypes[0]!.split(';')[0]!.trim().toLowerCase()\n if (baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json') return undefined\n if (baseType.startsWith('text/')) return 'text'\n if (baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)) return 'blob'\n return undefined\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 * 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\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n const { isMultipleContentTypes, contentTypeUnion } = getContentTypeInfo(node)\n // The request groups come from the grouped params, so `config` drops the data-shape keys to stay\n // assignable to `Options`, which omits them from `RequestConfig`.\n const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n const contentTypeProp = isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` : null\n\n return contentTypeProp ? `${configType} & { ${contentTypeProp} }` : configType\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a\n * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a\n * content type for.\n */\nexport function buildClientOptionType(): string {\n return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n}\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: 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 } = 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 }\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 isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body,\n }\n}\n\nexport type RequestConfigNameResolver = RequestConfigResolver & {\n resolveRequestConfigName(node: ast.OperationNode): string\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers }` parameter for a generated client\n * function, typed from the operation's `RequestConfig` (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: RequestConfigNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = (['path', 'query', 'body', 'headers'] as const).filter((key) => groups[key])\n\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${resolver.resolveRequestConfigName(node)}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { link = 'pathTemplate', linkPosition = 'afterDeprecated', splitLines = false } = options\n const linkComment = getOperationLink(node, link)\n const comments =\n linkPosition === 'beforeDeprecated'\n ? [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, linkComment, node.deprecated && '@deprecated']\n : [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, node.deprecated && '@deprecated', linkComment]\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\nexport function getOperationParameters(node: ast.OperationNode, options: { paramsCasing?: 'camelcase' | 'original' } = {}): OperationParameterGroups {\n const params = caseParams(node.parameters, options.paramsCasing === 'original' ? undefined : 'camelcase')\n\n return {\n path: params.filter((param) => param.in === 'path'),\n query: params.filter((param) => param.in === 'query'),\n header: params.filter((param) => param.in === 'header'),\n cookie: params.filter((param) => param.in === 'cookie'),\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\n .filter((response) => isErrorStatusCode(response.statusCode))\n .map((response) => resolver.resolveResponseStatusName(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses\n .filter((response) => isSuccessStatusCode(response.statusCode))\n .map((response) => resolver.resolveResponseStatusName(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode))\n}\n\nconst typeNamesByResolver = new WeakMap<OperationTypeNameResolver, Map<string, string[]>>()\n\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const cacheKey = `${node.operationId}\\0${options.paramsCasing ?? ''}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n let byResolver = typeNamesByResolver.get(resolver)\n if (byResolver) {\n const cached = byResolver.get(cacheKey)\n if (cached) return cached\n } else {\n byResolver = new Map()\n typeNamesByResolver.set(resolver, byResolver)\n }\n\n const { path, query, header } = getOperationParameters(node, { paramsCasing: options.paramsCasing })\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.resolvePathParamsName(node, param)),\n ...query.map((param) => resolver.resolveQueryParamsName(node, param)),\n ...header.map((param) => resolver.resolveHeaderParamsName(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n const result = names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n byResolver.set(cacheKey, result)\n return result\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.resolveResponseName(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.resolveResponseName(node) : resolver.resolveResponseStatusName(node, response.statusCode)])\n }\n\n return types\n}\n\nexport function findSuccessStatusCode(responses: Array<{ statusCode: ast.StatusCode | number | string }>): ast.StatusCode | null {\n for (const response of responses) {\n if (isSuccessStatusCode(response.statusCode)) {\n return response.statusCode as ast.StatusCode\n }\n }\n\n return null\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\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 type { ast } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\n\n/**\n * Builds the `RequestResult` generic arguments for one operation: the plugin-ts per-status responses\n * record plus the per-call `ThrowOnError` flag. `SuccessOf` / `ErrorOf` split the record inside the\n * runtime, so this only names the record and threads `ThrowOnError`.\n *\n * @example\n * `buildRequestResultGenerics({ node, tsResolver }) // 'AddPetResponses, ThrowOnError'`\n */\nexport function buildRequestResultGenerics({ node, tsResolver }: { node: ast.OperationNode; tsResolver: ResolverTs }): string {\n return `${tsResolver.resolveResponsesName(node)}, ThrowOnError`\n}\n","import type { ast } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { buildRequestResultGenerics } from './generics.ts'\n\n/**\n * Builds the return statement of a generated operation function. The runtime call already resolves\n * to `{ data, error, request, response }`; the generated code forwards that result and casts it to\n * the operation's `RequestResult`, which carries the `throwOnError` discrimination.\n *\n * @example\n * `return request({ method: 'POST', url: '/pet', ...config }) as Promise<RequestResult<AddPetResponses, ThrowOnError>>`\n */\nexport function buildReturnStatement({ node, tsResolver, callConfig }: { node: ast.OperationNode; tsResolver: ResolverTs; callConfig: string }): string {\n return `return request(${callConfig}) as Promise<RequestResult<${buildRequestResultGenerics({ node, tsResolver })}>>`\n}\n","import type { ast } from '@kubb/core'\nimport { createFunctionParameter, createFunctionParameters, functionPrinter, type ResolverTs } from '@kubb/plugin-ts'\nimport { buildRequestResultGenerics } from './generics.ts'\n\nconst declarationPrinter = functionPrinter({ mode: 'declaration' })\n\n/**\n * The pieces of a generated operation function's grouped-options signature.\n */\nexport type GroupedOptionsSignature = {\n /**\n * Name of the per-operation grouped data type, the plugin-ts `<Name>RequestConfig` used directly\n * as the function input.\n */\n dataTypeName: string\n /**\n * The single function parameter: `options: Options<<Name>RequestConfig, ThrowOnError>`.\n */\n paramsSignature: string\n /**\n * The function return type: `Promise<RequestResult<<Name>Responses, ThrowOnError>>`.\n */\n returnType: string\n /**\n * The function generics. One per-call `ThrowOnError` flag, defaulting to `true`.\n */\n generics: Array<string>\n /**\n * The plugin-ts type names the generated file imports (type-only).\n */\n importedTypeNames: Array<string>\n}\n\n/**\n * Builds the grouped-options signature for one operation: a single `options` object whose `TData`\n * is the plugin-ts `<Name>RequestConfig` (carrying a literal `url`), and a `RequestResult` return type\n * keyed to the plugin-ts per-status responses record. There are no positional arguments.\n *\n * The generated file imports `<Name>RequestConfig` and `<Name>Responses` and uses them directly, so no\n * per-operation input type has to be emitted.\n */\nexport function buildGroupedOptionsSignature({ node, tsResolver }: { node: ast.OperationNode; tsResolver: ResolverTs }): GroupedOptionsSignature {\n const requestConfigName = tsResolver.resolveRequestConfigName(node)\n const responsesName = tsResolver.resolveResponsesName(node)\n const resultGenerics = buildRequestResultGenerics({ node, tsResolver })\n\n const paramsSignature =\n declarationPrinter.print(\n createFunctionParameters({\n params: [createFunctionParameter({ name: 'options', type: `Options<${requestConfigName}, ThrowOnError>` })],\n }),\n ) ?? ''\n\n return {\n dataTypeName: requestConfigName,\n paramsSignature,\n returnType: `Promise<RequestResult<${resultGenerics}>>`,\n generics: ['ThrowOnError extends boolean = true'],\n importedTypeNames: [requestConfigName, responsesName],\n }\n}\n","import type { ast } from '@kubb/core'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport type { ParserOptions } from '../types.ts'\nimport { buildZodResponseParse, resolveRequestParser, resolveResponseParser } from './parser.ts'\n\n/**\n * The per-call parser expressions a generated function wires into its request config. Both run\n * through the runtime's `parser.request` / `parser.response` hooks rather than inline parse calls,\n * and the response parser only ever sees success (2xx) bodies.\n */\nexport type ParserHooks = {\n /**\n * Expression for the `parser.request` hook, or `null` when request parsing is off.\n */\n request: string | null\n /**\n * Expression for the `parser.response` hook, or `null` when response parsing is off.\n */\n response: string | null\n /**\n * Zod schema names the generated file imports from the zod plugin output.\n */\n importedZodNames: Array<string>\n}\n\n/**\n * Builds the parser-hook expressions for one operation. Request parsing runs before the send;\n * response parsing runs on the success body only. Returns `null` expressions when the matching\n * parser direction is disabled or the schema is absent.\n */\nexport function buildParserHooks({\n node,\n parser,\n zodResolver,\n}: {\n node: ast.OperationNode\n parser: ParserOptions | undefined\n zodResolver: ResolverZod | null | undefined\n}): ParserHooks {\n const importedZodNames: Array<string> = []\n\n const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const zodRequestName = zodResolver && resolveRequestParser(parser) === 'zod' && hasRequestBody ? zodResolver.resolveDataName?.(node) : null\n const request = zodRequestName ? `(data: unknown) => ${zodRequestName}.parse(data)` : null\n if (zodRequestName) importedZodNames.push(zodRequestName)\n\n const responseParse = zodResolver && resolveResponseParser(parser) === 'zod' ? buildZodResponseParse(node, zodResolver) : null\n const response = responseParse ? `(data: unknown) => ${responseParse.expression}.parse(data)` : null\n if (responseParse) importedZodNames.push(...responseParse.importNames)\n\n return { request, response, importedZodNames }\n}\n","import { buildOperationComments } from '@internals/shared'\nimport { ast } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx/types'\nimport { buildReturnStatement } from '../builders/returnStatement.ts'\nimport { type Auth, buildSecurityMetadata } from '../builders/security.ts'\nimport { buildGroupedOptionsSignature } from '../builders/signature.ts'\nimport { buildParserHooks } from '../builders/validator.ts'\nimport type { ParserOptions } from '../types.ts'\n\ntype Props = {\n /**\n * The generated function name.\n */\n name: string\n /**\n * The operation being generated.\n */\n node: ast.OperationNode\n /**\n * Resolver for the plugin-ts type names the signature references.\n */\n tsResolver: ResolverTs\n /**\n * Resolver for the zod schema names the validators reference, when `parser` is on.\n */\n zodResolver?: ResolverZod | null\n /**\n * The active parser option, driving the validator-hook wiring.\n */\n parser?: ParserOptions\n /**\n * Per-operation security, resolved from the spec into inline `Auth` objects and serialized onto the\n * call config's `security` field for the runtime `auth` resolver to consume.\n */\n security?: Array<Auth>\n isExportable?: boolean\n isIndexable?: boolean\n}\n\n/**\n * Renders one client operation: the grouped `<Name>Request` type and the function that forwards a\n * single `options` object to the resolved client and returns the `RequestResult`. The type, signature,\n * and call config are built with the AST factory, and only the jsx-renderer emits the source.\n */\nexport function Operation({ name, node, tsResolver, zodResolver, parser, security, isExportable = true, isIndexable = true }: Props): KubbReactNode {\n if (!ast.isHttpOperationNode(node)) return null\n\n const signature = buildGroupedOptionsSignature({ node, tsResolver })\n const parsers = buildParserHooks({ node, parser, zodResolver })\n const securityLiteral = buildSecurityMetadata({ security })\n\n const parserEntries = [parsers.request ? `request: ${parsers.request}` : null, parsers.response ? `response: ${parsers.response}` : null].filter(Boolean)\n const parserLiteral = parserEntries.length ? `parser: { ${parserEntries.join(', ')} }` : null\n\n const callConfig = `{ ${[\n `method: '${node.method.toUpperCase()}'`,\n `url: '${node.path}'`,\n securityLiteral ? `security: ${securityLiteral}` : null,\n parserLiteral,\n '...config',\n ]\n .filter(Boolean)\n .join(', ')} }`\n\n return (\n <File.Source name={name} isExportable={isExportable} isIndexable={isIndexable}>\n <Function\n name={name}\n export={isExportable}\n generics={signature.generics}\n params={signature.paramsSignature}\n returnType={signature.returnType}\n JSDoc={{ comments: buildOperationComments(node, { link: 'urlPath', linkPosition: 'beforeDeprecated', splitLines: true }) }}\n >\n {'const { client: request = client, ...config } = options'}\n <br />\n {buildReturnStatement({ node, tsResolver, callConfig })}\n </Function>\n </File.Source>\n )\n}\n","import { buildOperationComments } from '@internals/shared'\nimport type { HttpOperationNode } from '@kubb/ast'\nimport { buildJSDoc } from '@kubb/ast/utils'\nimport { ast } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport type { ParserOptions } from '../types.ts'\nimport { buildReturnStatement } from './returnStatement.ts'\nimport { type Auth, buildSecurityMetadata } from './security.ts'\nimport { buildGroupedOptionsSignature } from './signature.ts'\nimport { buildParserHooks } from './validator.ts'\n\n/**\n * Builds the call config literal forwarded to the contract client, mirroring the shared `Operation`\n * component: `{ method, url, security?, parser?, ...config }`. The `...config` spread carries every\n * per-call field (including `throwOnError`), so the method stays a thin wrapper over the contract.\n */\nfunction buildCallConfig({\n node,\n parser,\n zodResolver,\n security,\n}: {\n node: HttpOperationNode\n parser: ParserOptions | undefined\n zodResolver?: ResolverZod | null\n security?: Array<Auth>\n}): string {\n const parsers = buildParserHooks({ node, parser, zodResolver })\n const parserEntries = [parsers.request ? `request: ${parsers.request}` : null, parsers.response ? `response: ${parsers.response}` : null].filter(Boolean)\n const parserLiteral = parserEntries.length ? `parser: { ${parserEntries.join(', ')} }` : null\n const securityLiteral = buildSecurityMetadata({ security })\n\n return `{ ${[\n `method: '${node.method.toUpperCase()}'`,\n `url: '${node.path}'`,\n securityLiteral ? `security: ${securityLiteral}` : null,\n parserLiteral,\n '...config',\n ]\n .filter(Boolean)\n .join(', ')} }`\n}\n\n/**\n * Builds a single instance method for a generated SDK class. The body forwards the single grouped\n * `options` object to the instance's own client (`this.client`, built once in the constructor) and\n * returns the `RequestResult`. A per-call `options.client` still overrides the instance client, so\n * one operation can be routed to a different environment without a new instance.\n */\nexport function buildSdkMethod({\n node,\n name,\n tsResolver,\n zodResolver,\n parser,\n security,\n}: {\n node: ast.OperationNode\n name: string\n tsResolver: ResolverTs\n zodResolver?: ResolverZod | null\n parser: ParserOptions | undefined\n security?: Array<Auth>\n}): string {\n if (!ast.isHttpOperationNode(node)) return ''\n\n const signature = buildGroupedOptionsSignature({ node, tsResolver })\n const callConfig = buildCallConfig({ node, parser, zodResolver, security })\n const returnStatement = buildReturnStatement({ node, tsResolver, callConfig })\n const generics = signature.generics.length ? `<${signature.generics.join(', ')}>` : ''\n const jsdoc = buildJSDoc(buildOperationComments(node, { link: 'urlPath', linkPosition: 'beforeDeprecated', splitLines: true }))\n\n const methodBody = ['const { client: request = this.client, ...config } = options', '', returnStatement].map((line) => (line ? ` ${line}` : '')).join('\\n')\n\n return `${jsdoc} public ${name}${generics}(${signature.paramsSignature}): ${signature.returnType} {\\n${methodBody}\\n }`\n}\n","import type { ast } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport { File } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx/types'\nimport { buildSdkMethod } from '../builders/sdkMethod.ts'\nimport type { Auth } from '../builders/security.ts'\nimport type { ParserOptions } from '../types.ts'\n\ntype OperationData = {\n node: ast.OperationNode\n name: string\n tsResolver: ResolverTs\n zodResolver?: ResolverZod | null\n security?: Array<Auth>\n}\n\ntype Props = {\n name: string\n isExportable?: boolean\n isIndexable?: boolean\n operations: Array<OperationData>\n parser: ParserOptions | undefined\n children?: KubbReactNode\n}\n\n/**\n * Renders one instance class per tag with one method per operation. The constructor takes a client\n * config object and builds its own client through `createClient`, so each environment is a separate\n * instance: `const api = new PetClient({ baseURL }); api.getPetById(...)`. A per-call `client` option\n * still overrides the instance client for a one-off call.\n */\nexport function SdkClient({ name, isExportable = true, isIndexable = true, operations, parser, children }: Props): KubbReactNode {\n const methods = operations.map(({ node, name: methodName, tsResolver, zodResolver, security }) =>\n buildSdkMethod({\n node,\n name: methodName,\n tsResolver,\n zodResolver,\n parser,\n security,\n }),\n )\n\n const constructor = [\n ' private readonly client: ClientInstance',\n '',\n ' constructor(config: ClientConfig = {}) {',\n ' this.client = createClient(config)',\n ' }',\n ].join('\\n')\n\n const classCode = `export class ${name} {\\n${constructor}\\n\\n${methods.join('\\n\\n')}\\n}`\n\n return (\n <File.Source name={name} isExportable={isExportable} isIndexable={isIndexable}>\n {classCode}\n {children}\n </File.Source>\n )\n}\n","import { File } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx/types'\n\ntype Member = {\n className: string\n propName: string\n}\n\ntype Props = {\n name: string\n isExportable?: boolean\n isIndexable?: boolean\n members: Array<Member>\n children?: KubbReactNode\n}\n\n/**\n * Renders a composed root SDK class that instantiates every tag client from one shared config, so\n * `new PetStore({ baseURL }).petClient.getPetById(...)` reaches an operation through a single entry\n * point bound to one environment. The per-tag clients are read-only fields built in the constructor.\n */\nexport function SdkFacade({ name, isExportable = true, isIndexable = true, members, children }: Props): KubbReactNode {\n const fields = members.map((member) => ` readonly ${member.propName}: ${member.className}`)\n const assignments = members.map((member) => ` this.${member.propName} = new ${member.className}(config)`)\n const body = [...fields, '', ' constructor(config: ClientConfig = {}) {', ...assignments, ' }'].join('\\n')\n\n const classCode = `export class ${name} {\\n${body}\\n}`\n\n return (\n <File.Source name={name} isExportable={isExportable} isIndexable={isIndexable}>\n {classCode}\n {children}\n </File.Source>\n )\n}\n","import path from 'node:path'\nimport { getOperationParameters, operationFileEntry } from '@internals/shared'\nimport { camelCase } from '@internals/utils'\nimport { ast, defineGenerator } from '@kubb/core'\nimport type { Generator, PluginFactoryOptions } from '@kubb/core'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport type { ResolverZod } from '@kubb/plugin-zod'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from '@kubb/renderer-jsx'\nimport { isParserEnabled, resolveQueryParamsParser, resolveRequestParser, resolveResponseParser } from '../builders/parser.ts'\nimport { type Auth, getOperationSecurity, type SecurityDocument } from '../builders/security.ts'\nimport { SdkClient } from '../components/SdkClient.tsx'\nimport { SdkFacade } from '../components/SdkFacade.tsx'\nimport type { Options, ParserOptions, ResolvedOptions, ResolverClient } from '../types.ts'\n\n/**\n * The shape any client plugin (plugin-fetch, plugin-axios) must satisfy to reuse the shared SDK\n * generator. Pins the option, resolved-option, and resolver shapes while leaving the plugin name\n * free.\n */\ntype ContractClientFactory = PluginFactoryOptions<string, Options, ResolvedOptions, ResolverClient>\n\ntype GeneratorContext = Parameters<NonNullable<Generator<ContractClientFactory>['operations']>>[1]\n\ntype OperationData = {\n node: ast.OperationNode\n name: string\n tsResolver: ResolverTs\n zodResolver: ResolverZod | null\n typeFile: ast.FileNode\n zodFile: ast.FileNode | null\n security?: Array<Auth>\n}\n\ntype Controller = {\n name: string\n tag: string | undefined\n file: ast.FileNode\n operations: Array<OperationData>\n}\n\nfunction resolveTypeImportNames(node: ast.OperationNode, tsResolver: ResolverTs): Array<string> {\n return [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)]\n}\n\nfunction resolveZodImportNames(node: ast.OperationNode, zodResolver: ResolverZod, parser: ParserOptions): Array<string> {\n const { query: queryParams } = getOperationParameters(node, { paramsCasing: 'original' })\n const names: Array<string | null | undefined> = [\n resolveResponseParser(parser) === 'zod' ? zodResolver.resolveResponseName?.(node) : null,\n resolveRequestParser(parser) === 'zod' && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null,\n resolveQueryParamsParser(parser) === 'zod' && queryParams.length > 0 ? zodResolver.resolveQueryParamsName?.(node, queryParams[0]!) : null,\n ]\n return names.filter((n): n is string => Boolean(n))\n}\n\n/**\n * Groups operations into one controller per tag. Operations without a tag fall back to a single\n * `Client`/`ApiClient` controller, matching the resolver's default naming.\n */\nfunction buildControllers(nodes: ReadonlyArray<ast.OperationNode>, ctx: GeneratorContext): Array<Controller> {\n const { driver, resolver, root } = ctx\n const { output, group, parser } = ctx.options\n\n const pluginTs = driver.getPlugin(pluginTsName)!\n const tsResolver = driver.getResolver(pluginTsName)\n const tsPluginOptions = pluginTs.options\n const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null\n const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null\n const document = ctx.adapter.document as SecurityDocument | null | undefined\n\n function buildOperationData(node: ast.OperationNode): OperationData {\n const typeFile = tsResolver.resolveFile(operationFileEntry(node, node.operationId), {\n root,\n output: tsPluginOptions?.output ?? output,\n group: tsPluginOptions?.group,\n })\n const zodFile =\n zodResolver && pluginZod?.options\n ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {\n root,\n output: pluginZod.options?.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n : null\n\n const security = ast.isHttpOperationNode(node) ? getOperationSecurity({ document, method: node.method, path: node.path }) : undefined\n\n return { node, name: resolver.resolveName(node.operationId), tsResolver, zodResolver, typeFile, zodFile, security }\n }\n\n return nodes.reduce((acc, operationNode) => {\n if (!ast.isHttpOperationNode(operationNode)) return acc\n const tag = operationNode.tags[0]\n const name = tag ? (group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag)) : resolver.resolveClassName('ApiClient')\n const file = resolver.resolveFile({ name, extname: '.ts', tag }, { root, output, group: group ?? undefined })\n const operationData = buildOperationData(operationNode)\n const previous = acc.find((item) => item.file.path === file.path)\n\n if (previous) {\n previous.operations.push(operationData)\n } else {\n acc.push({ name, tag, file, operations: [operationData] })\n }\n\n return acc\n }, [] as Array<Controller>)\n}\n\nfunction collectImportsByFile(ops: Array<OperationData>, pick: (op: OperationData) => { file: ast.FileNode | null; names: Array<string> }) {\n const namesByPath = new Map<string, Set<string>>()\n const filesByPath = new Map<string, ast.FileNode>()\n\n ops.forEach((op) => {\n const { file, names } = pick(op)\n if (!file || names.length === 0) return\n if (!namesByPath.has(file.path)) namesByPath.set(file.path, new Set())\n const set = namesByPath.get(file.path)!\n names.forEach((n) => set.add(n))\n filesByPath.set(file.path, file)\n })\n\n return { namesByPath, filesByPath }\n}\n\n/**\n * Builds the class-based SDK generator for a client plugin (`@kubb/plugin-fetch`,\n * `@kubb/plugin-axios`). Only registered when `sdk` is set; otherwise the plugin keeps its\n * standalone per-operation functions.\n *\n * Every tag client is an instance class whose constructor takes a client config and builds its own\n * client, so each environment is a separate instance. With `sdk.mode: 'tag'` (the default) it\n * emits one class per tag and, when `sdk.name` is set, a composed root that instantiates every tag\n * client. With `sdk.mode: 'flat'` it emits one class named by `sdk.name`, with every operation as a\n * direct method.\n */\nexport function createSdkGenerator<TFactory extends ContractClientFactory>(): Generator<TFactory> {\n return defineGenerator<TFactory>({\n name: 'sdk',\n renderer: jsxRenderer,\n operations(nodes, ctx) {\n const { config, resolver, root } = ctx\n const { output, group, parser, sdk } = ctx.options\n\n const pluginTs = ctx.driver.getPlugin(pluginTsName)\n if (!pluginTs || !sdk) return null\n\n const controllers = buildControllers(nodes, ctx)\n const clientPath = path.resolve(root, '.kubb/client.ts')\n\n const banner = (file: ast.FileNode) => resolver.resolveBanner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })\n const footer = (file: ast.FileNode) => resolver.resolveFooter(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })\n\n const renderClassFile = (className: string, file: ast.FileNode, ops: Array<OperationData>) => {\n const { namesByPath: typeNamesByPath, filesByPath: typeFilesByPath } = collectImportsByFile(ops, (op) => ({\n file: op.typeFile,\n names: resolveTypeImportNames(op.node, op.tsResolver),\n }))\n const { namesByPath: zodNamesByPath, filesByPath: zodFilesByPath } = isParserEnabled(parser)\n ? collectImportsByFile(ops, (op) => ({ file: op.zodFile, names: op.zodResolver ? resolveZodImportNames(op.node, op.zodResolver, parser) : [] }))\n : { namesByPath: new Map<string, Set<string>>(), filesByPath: new Map<string, ast.FileNode>() }\n\n return (\n <File key={file.path} baseName={file.baseName} path={file.path} meta={file.meta} banner={banner(file)} footer={footer(file)}>\n <File.Import name={['createClient']} root={file.path} path={clientPath} />\n <File.Import name={['ClientConfig', 'ClientInstance', 'Options', 'RequestResult']} root={file.path} path={clientPath} isTypeOnly />\n\n {parser === 'zod' && ops.some((op) => op.node.requestBody?.content?.[0]?.schema != null) && <File.Import name={['z']} path=\"zod\" isTypeOnly />}\n\n {Array.from(typeNamesByPath.entries()).map(([filePath, set]) => (\n <File.Import key={filePath} name={Array.from(set)} root={file.path} path={typeFilesByPath.get(filePath)!.path} isTypeOnly />\n ))}\n\n {isParserEnabled(parser) &&\n Array.from(zodNamesByPath.entries()).map(([filePath, set]) => (\n <File.Import key={filePath} name={Array.from(set)} root={file.path} path={zodFilesByPath.get(filePath)!.path} />\n ))}\n\n <SdkClient name={className} operations={ops} parser={parser} />\n </File>\n )\n }\n\n // `flat` collapses every operation into one class named by `sdk.name`, so callers reach\n // an operation as `new PetStore(config).getPetById(...)` without a per-tag sub-client.\n if (sdk.mode === 'flat') {\n const flatName = resolver.resolveClassName(sdk.name ?? 'sdk')\n const flatFile = resolver.resolveFile({ name: sdk.name ?? 'sdk', extname: '.ts' }, { root, output, group: group ?? undefined })\n const allOps = controllers.flatMap((controller) => controller.operations)\n\n return renderClassFile(flatName, flatFile, allOps)\n }\n\n const classFiles = controllers.map(({ name, file, operations: ops }) => renderClassFile(name, file, ops))\n\n if (!sdk.name) return <>{classFiles}</>\n\n const sdkFile = resolver.resolveFile({ name: sdk.name, extname: '.ts' }, { root, output, group: group ?? undefined })\n const facadeName = resolver.resolveClassName(sdk.name)\n const members = controllers.map(({ name, tag }) => ({ className: name, propName: resolver.resolveClientPropertyName(tag ?? name) }))\n\n return (\n <>\n {classFiles}\n <File key={sdkFile.path} baseName={sdkFile.baseName} path={sdkFile.path} meta={sdkFile.meta} banner={banner(sdkFile)} footer={footer(sdkFile)}>\n <File.Import name={['ClientConfig']} root={sdkFile.path} path={clientPath} isTypeOnly />\n {controllers.map(({ name, file }) => (\n <File.Import key={name} name={[name]} root={sdkFile.path} path={file.path} />\n ))}\n <SdkFacade name={facadeName} members={members} />\n </File>\n </>\n )\n },\n })\n}\n","import type { ast } from '@kubb/core'\nimport { macroSimplifyUnion } from '@kubb/ast/macros'\n\n/**\n * Macros the client plugins apply by default, ahead of any user macros. `macroSimplifyUnion`\n * drops union members a broader scalar already covers, keeping the generated response and error\n * unions tidy. A plugin wires them with `ctx.setMacros([...defaultMacros, ...userMacros])`.\n */\nexport const defaultMacros: ReadonlyArray<ast.Macro> = [macroSimplifyUnion]\n","import { camelCase, ensureValidVarName, pascalCase, toFilePath } from '@internals/utils'\nimport { defineResolver } from '@kubb/core'\nimport type { PluginContractClient } from './types.ts'\n\n/**\n * Default resolver shared by the client plugins. Functions and files use camelCase; classes and\n * tag groups use PascalCase.\n *\n * @example\n * ```ts\n * resolverClient.resolveName('show pet by id') // 'showPetById'\n * resolverClient.resolveGroupName('pet') // 'PetClient'\n * ```\n */\nexport const resolverClient = defineResolver<PluginContractClient>(() => ({\n name: 'default',\n pluginName: 'plugin-contract-client',\n default(name, type) {\n if (type === 'file') return toFilePath(name)\n return ensureValidVarName(camelCase(name))\n },\n resolveName(name) {\n return this.default(name, 'function')\n },\n resolvePathName(name, type) {\n return this.default(name, type)\n },\n resolveClassName(name) {\n return ensureValidVarName(pascalCase(name))\n },\n resolveGroupName(name) {\n return ensureValidVarName(pascalCase(`${name} Client`))\n },\n resolveClientPropertyName(name) {\n return ensureValidVarName(camelCase(name))\n },\n}))\n","import path from 'node:path'\nimport { getOperationSecurity, Operation, resolveRequestParser, resolveResponseParser, type SecurityDocument } from '@internals/client'\nimport { operationFileEntry } from '@internals/shared'\nimport { ast, defineGenerator } from '@kubb/core'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from '@kubb/renderer-jsx'\nimport type { PluginFetch } from '../types.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-fetch`. Emits one async function per OpenAPI\n * operation using the shared `Operation` component: a grouped `<Name>Request` type and a function that\n * forwards a single `options` object to the bundled `client` and returns the `RequestResult`.\n */\nexport const clientGenerator = defineGenerator<PluginFetch>({\n name: 'fetch',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n\n const { config, driver, resolver, root } = ctx\n const { output, parser, group } = ctx.options\n\n const pluginTs = driver.getPlugin(pluginTsName)\n if (!pluginTs) return null\n\n const tsResolver = driver.getResolver(pluginTsName)\n\n const parserEnabled = resolveResponseParser(parser) === 'zod' || resolveRequestParser(parser) === 'zod'\n const pluginZod = parserEnabled ? driver.getPlugin(pluginZodName) : null\n const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null\n\n const hasRequestBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const importedTypeNames = [tsResolver.resolveRequestConfigName(node), tsResolver.resolveResponsesName(node)]\n\n const importedZodNames = zodResolver\n ? [\n resolveResponseParser(parser) === 'zod' ? zodResolver.resolveResponseName?.(node) : null,\n resolveRequestParser(parser) === 'zod' && hasRequestBody ? zodResolver.resolveDataName?.(node) : null,\n ].filter((name): name is string => Boolean(name))\n : []\n\n const meta = {\n name: resolver.resolveName(node.operationId),\n file: resolver.resolveFile(operationFileEntry(node, node.operationId), { root, output, group: group ?? undefined }),\n fileTs: tsResolver.resolveFile(operationFileEntry(node, node.operationId), {\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group ?? undefined,\n }),\n fileZod:\n zodResolver && pluginZod?.options\n ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {\n root,\n output: pluginZod.options.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n : null,\n } as const\n\n const security = getOperationSecurity({\n document: ctx.adapter.document as SecurityDocument | null | undefined,\n method: node.method,\n path: node.path,\n })\n\n const clientPath = path.resolve(root, '.kubb/client.ts')\n\n return (\n <File\n baseName={meta.file.baseName}\n path={meta.file.path}\n meta={meta.file.meta}\n banner={resolver.resolveBanner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n footer={resolver.resolveFooter(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n >\n <File.Import name={['client']} root={meta.file.path} path={clientPath} />\n <File.Import name={['Options', 'RequestResult']} root={meta.file.path} path={clientPath} isTypeOnly />\n\n {meta.fileTs && importedTypeNames.length > 0 && (\n <File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />\n )}\n\n {meta.fileZod && importedZodNames.length > 0 && <File.Import name={importedZodNames} root={meta.file.path} path={meta.fileZod.path} />}\n\n <Operation name={meta.name} node={node} tsResolver={tsResolver} zodResolver={zodResolver} parser={parser} security={security} />\n </File>\n )\n },\n})\n","import { fileURLToPath } from 'node:url'\n\n/**\n * Absolute path to the fetch client runtime template, resolved relative to this package's own\n * location so it stays correct no matter which package imports it. Pass it to a file node's `copy`\n * field to emit the runtime into the generated `.kubb/client.ts` verbatim.\n */\nexport const fetchClientTemplatePath = fileURLToPath(new URL('../templates/fetch.ts', import.meta.url))\n","import path from 'node:path'\nimport { createSdkGenerator, defaultMacros, isParserEnabled, resolverClient } from '@internals/client'\nimport { createGroupConfig } from '@internals/shared'\nimport { definePlugin } from '@kubb/core'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { clientGenerator } from './generators/clientGenerator.tsx'\nimport { fetchClientTemplatePath } from './templates.ts'\nimport type { PluginFetch, ResolvedOptions } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-fetch`. Used for driver lookups and cross-plugin\n * dependency references.\n */\nexport const pluginFetchName = 'plugin-fetch' satisfies PluginFetch['name']\n\n/**\n * Generates a type-safe HTTP client pinned to the Fetch API. Each operation becomes one async\n * function that takes a single grouped `options` object and returns the shared `RequestResult`\n * contract. The runtime is always bundled into `.kubb/client.ts`, so generated code never imports\n * from `@kubb/plugin-fetch` and the only runtime dependency is the global `fetch`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginFetch } from '@kubb/plugin-fetch'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginFetch({ output: { path: './clients' } }),\n * ],\n * })\n * ```\n */\nexport const pluginFetch = definePlugin<PluginFetch>((options) => {\n const {\n output = { path: 'clients', barrel: { type: 'named' } },\n exclude = [],\n include,\n override = [],\n baseURL,\n parser = false,\n group,\n sdk,\n resolver: userResolver,\n } = options\n\n const resolved: ResolvedOptions = {\n output,\n exclude,\n include,\n override,\n group: createGroupConfig(group),\n baseURL,\n parser,\n sdk: sdk ? { mode: sdk.mode ?? 'tag', name: sdk.name } : undefined,\n resolver: userResolver ? { ...resolverClient, ...userResolver } : resolverClient,\n }\n\n // `sdk` swaps the per-operation functions for the class-based SDK; left unset, the standalone\n // functions (which query plugins consume) stay.\n const selectedGenerators = resolved.sdk ? [createSdkGenerator<PluginFetch>()] : [clientGenerator]\n\n return {\n name: pluginFetchName,\n options,\n dependencies: [pluginTsName, isParserEnabled(resolved.parser) ? pluginZodName : null].filter((dependency): dependency is string => Boolean(dependency)),\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n ctx.setOptions(resolved)\n ctx.setResolver(resolved.resolver)\n ctx.setMacros([...defaultMacros, ...(options.macros ?? [])])\n\n for (const gen of selectedGenerators) {\n ctx.addGenerator(gen)\n }\n\n const root = path.resolve(ctx.config.root, ctx.config.output.path)\n\n ctx.injectFile({\n baseName: 'client.ts',\n path: path.resolve(root, '.kubb/client.ts'),\n copy: fetchClientTemplatePath,\n footer: baseURL ? `client.setConfig({ baseURL: ${JSON.stringify(baseURL)} })` : undefined,\n })\n },\n },\n }\n})\n\nexport default pluginFetch\n"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
+
import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
|
|
3
|
+
//#region ../../internals/client/src/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validator applied to request and response bodies using schemas from `@kubb/plugin-zod`.
|
|
6
|
+
* - `false`: no validation.
|
|
7
|
+
* - `'zod'`: validates success (2xx) response bodies only.
|
|
8
|
+
* - `{ request?: 'zod'; response?: 'zod' }`: opt in per direction. `request` validates the request
|
|
9
|
+
* body and query parameters before the call; `response` validates the success response body.
|
|
10
|
+
*/
|
|
11
|
+
type ParserOptions = false | 'zod' | {
|
|
12
|
+
request?: 'zod';
|
|
13
|
+
response?: 'zod';
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* How the class-based SDK groups operations.
|
|
17
|
+
* - `'tag'`: one class per tag, optionally composed into a root client.
|
|
18
|
+
* - `'flat'`: one class with every operation as a direct method.
|
|
19
|
+
*/
|
|
20
|
+
type Mode = 'tag' | 'flat';
|
|
21
|
+
/**
|
|
22
|
+
* The resolver shared by the client plugins. Functions and files use camelCase; URL helpers get
|
|
23
|
+
* a `get<Operation>Url` name.
|
|
24
|
+
*/
|
|
25
|
+
type ResolverClient = Resolver & {
|
|
26
|
+
/**
|
|
27
|
+
* Resolves the function name for a raw operation name.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* `resolver.resolveName('show pet by id') // -> 'showPetById'`
|
|
31
|
+
*/
|
|
32
|
+
resolveName(this: ResolverClient, name: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Resolves the output file name for a generated client module.
|
|
35
|
+
*/
|
|
36
|
+
resolvePathName(this: ResolverClient, name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the generated class name for class-based clients.
|
|
39
|
+
*/
|
|
40
|
+
resolveClassName(this: ResolverClient, name: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the generated class name for a tag-based client group. The default appends a
|
|
43
|
+
* `Client` suffix (tag `pet` becomes `PetClient`) so the class never collides with the schema
|
|
44
|
+
* model of the same name in the barrel.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* `resolver.resolveGroupName('pet') // -> 'PetClient'`
|
|
48
|
+
*/
|
|
49
|
+
resolveGroupName(this: ResolverClient, name: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Resolves the property name a tag client is exposed under on the composed root SDK
|
|
52
|
+
* (`new PetStore(config).pet`).
|
|
53
|
+
*/
|
|
54
|
+
resolveClientPropertyName(this: ResolverClient, name: string): string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The shared options surface for the client plugins. Deliberately small: there is one
|
|
58
|
+
* response contract and one grouped options object. Each plugin extends this with its own
|
|
59
|
+
* `transport` field.
|
|
60
|
+
*/
|
|
61
|
+
type Options = OutputOptions & {
|
|
62
|
+
/**
|
|
63
|
+
* Skip operations matching at least one entry in the list.
|
|
64
|
+
*/
|
|
65
|
+
exclude?: Array<Exclude>;
|
|
66
|
+
/**
|
|
67
|
+
* Restrict generation to operations matching at least one entry in the list.
|
|
68
|
+
*/
|
|
69
|
+
include?: Array<Include>;
|
|
70
|
+
/**
|
|
71
|
+
* Apply a different options object to operations matching a pattern.
|
|
72
|
+
*/
|
|
73
|
+
override?: Array<Override<ResolvedOptions>>;
|
|
74
|
+
/**
|
|
75
|
+
* Base URL prepended to every request. When omitted, falls back to the adapter's server URL.
|
|
76
|
+
*/
|
|
77
|
+
baseURL?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Validate request and response bodies with schemas from `@kubb/plugin-zod`.
|
|
80
|
+
*
|
|
81
|
+
* @default false
|
|
82
|
+
*/
|
|
83
|
+
parser?: ParserOptions;
|
|
84
|
+
/**
|
|
85
|
+
* Generates a class-based SDK instead of the standalone functions. Each tag client is an instance
|
|
86
|
+
* class whose constructor takes a client config and builds its own client, so every environment is
|
|
87
|
+
* a separate instance. Leave `sdk` unset to keep the standalone per-operation functions (the
|
|
88
|
+
* default), which is also what query plugins consume.
|
|
89
|
+
*
|
|
90
|
+
* @example Instance class per tag
|
|
91
|
+
* ```ts
|
|
92
|
+
* pluginFetch({ sdk: {} })
|
|
93
|
+
* // const api = new PetClient({ baseURL: 'https://api.example.com' })
|
|
94
|
+
* // await api.getPetById({ path: { petId: 1 } })
|
|
95
|
+
* ```
|
|
96
|
+
* @example Composed root that instantiates every tag client from one config
|
|
97
|
+
* ```ts
|
|
98
|
+
* pluginFetch({ sdk: { name: 'petStore' } })
|
|
99
|
+
* // class PetStore {
|
|
100
|
+
* // readonly pet: PetClient
|
|
101
|
+
* // readonly store: StoreClient
|
|
102
|
+
* // constructor(config = {}) { ... }
|
|
103
|
+
* // }
|
|
104
|
+
* // const api = new PetStore({ baseURL })
|
|
105
|
+
* // await api.pet.getPetById({ path: { petId: 1 } })
|
|
106
|
+
* ```
|
|
107
|
+
* @example Flat class with every operation as a direct method
|
|
108
|
+
* ```ts
|
|
109
|
+
* pluginFetch({ sdk: { name: 'petStore', mode: 'flat' } })
|
|
110
|
+
* // const api = new PetStore({ baseURL })
|
|
111
|
+
* // await api.getPetById({ path: { petId: 1 } })
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
sdk?: {
|
|
115
|
+
/**
|
|
116
|
+
* How the SDK groups operations.
|
|
117
|
+
* - `'tag'`: one class per tag. With `name`, a composed root instantiates every tag client.
|
|
118
|
+
* - `'flat'`: one class named by `name`, with every operation as a direct method.
|
|
119
|
+
*
|
|
120
|
+
* @default 'tag'
|
|
121
|
+
*/
|
|
122
|
+
mode?: Mode;
|
|
123
|
+
/**
|
|
124
|
+
* Name of the generated entry point, also the file name. With `mode: 'tag'` it emits a
|
|
125
|
+
* composed root class that instantiates every tag client from one shared config. With
|
|
126
|
+
* `mode: 'flat'` it names the single class.
|
|
127
|
+
*/
|
|
128
|
+
name?: string;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Override how names and file paths are built. Methods you omit fall back to the default resolver.
|
|
132
|
+
*/
|
|
133
|
+
resolver?: Partial<ResolverClient> & ThisType<ResolverClient>;
|
|
134
|
+
/**
|
|
135
|
+
* Macros applied to each operation node before code is printed.
|
|
136
|
+
*/
|
|
137
|
+
macros?: Array<ast.Macro>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* The resolved options after defaults are applied.
|
|
141
|
+
*/
|
|
142
|
+
type ResolvedOptions = {
|
|
143
|
+
output: Output;
|
|
144
|
+
exclude: Array<Exclude>;
|
|
145
|
+
include: Array<Include> | undefined;
|
|
146
|
+
override: Array<Override<ResolvedOptions>>;
|
|
147
|
+
group: Group | null;
|
|
148
|
+
baseURL: Options['baseURL'];
|
|
149
|
+
parser: NonNullable<Options['parser']>;
|
|
150
|
+
sdk: {
|
|
151
|
+
mode: Mode;
|
|
152
|
+
name: string | undefined;
|
|
153
|
+
} | undefined;
|
|
154
|
+
resolver: ResolverClient;
|
|
155
|
+
};
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/types.d.ts
|
|
158
|
+
/**
|
|
159
|
+
* The plugin factory type for `@kubb/plugin-fetch`. Shares the options surface, resolver, and
|
|
160
|
+
* resolved-options shape with the other client plugins; only the plugin name and transport
|
|
161
|
+
* differ.
|
|
162
|
+
*/
|
|
163
|
+
type PluginFetch = PluginFactoryOptions<'plugin-fetch', Options, ResolvedOptions, ResolverClient>;
|
|
164
|
+
declare global {
|
|
165
|
+
namespace Kubb {
|
|
166
|
+
interface PluginRegistry {
|
|
167
|
+
'plugin-fetch': PluginFetch;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/generators/clientGenerator.d.ts
|
|
173
|
+
/**
|
|
174
|
+
* Built-in operation generator for `@kubb/plugin-fetch`. Emits one async function per OpenAPI
|
|
175
|
+
* operation using the shared `Operation` component: a grouped `<Name>Request` type and a function that
|
|
176
|
+
* forwards a single `options` object to the bundled `client` and returns the `RequestResult`.
|
|
177
|
+
*/
|
|
178
|
+
declare const clientGenerator: import("@kubb/core").Generator<PluginFetch, unknown>;
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/plugin.d.ts
|
|
181
|
+
/**
|
|
182
|
+
* Canonical plugin name for `@kubb/plugin-fetch`. Used for driver lookups and cross-plugin
|
|
183
|
+
* dependency references.
|
|
184
|
+
*/
|
|
185
|
+
declare const pluginFetchName = "plugin-fetch";
|
|
186
|
+
/**
|
|
187
|
+
* Generates a type-safe HTTP client pinned to the Fetch API. Each operation becomes one async
|
|
188
|
+
* function that takes a single grouped `options` object and returns the shared `RequestResult`
|
|
189
|
+
* contract. The runtime is always bundled into `.kubb/client.ts`, so generated code never imports
|
|
190
|
+
* from `@kubb/plugin-fetch` and the only runtime dependency is the global `fetch`.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* import { defineConfig } from 'kubb'
|
|
195
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
196
|
+
* import { pluginFetch } from '@kubb/plugin-fetch'
|
|
197
|
+
*
|
|
198
|
+
* export default defineConfig({
|
|
199
|
+
* input: { path: './petStore.yaml' },
|
|
200
|
+
* output: { path: './src/gen' },
|
|
201
|
+
* plugins: [
|
|
202
|
+
* pluginTs(),
|
|
203
|
+
* pluginFetch({ output: { path: './clients' } }),
|
|
204
|
+
* ],
|
|
205
|
+
* })
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
declare const pluginFetch: (options?: Options | undefined) => import("@kubb/core").Plugin<PluginFetch>;
|
|
209
|
+
//#endregion
|
|
210
|
+
export { type Options, type PluginFetch, type ResolvedOptions, type ResolverClient, clientGenerator, pluginFetch as default, pluginFetch, pluginFetchName };
|
|
211
|
+
//# sourceMappingURL=index.d.ts.map
|