import { URLPath } from '@kubb/core/utils' import { useOperation, useOperationManager } from '@kubb/plugin-oas/hooks' import { getComments, getPathParams } from '@kubb/plugin-oas/utils' import { File, Function, Parser, useApp } from '@kubb/react' import { pluginTsName } from '@kubb/swagger-ts' import { isOptional } from '@kubb/oas' import type { HttpMethod } from '@kubb/oas' import type { KubbNode, Params } from '@kubb/react' import type { ComponentProps, ComponentType } from 'react' import type { FileMeta, PluginClient } from '../types.ts' type TemplateProps = { /** * Name of the function */ name: string /** * Parameters/options/props that need to be used */ params: Params /** * Generics that needs to be added for TypeScript */ generics?: string /** * ReturnType(see async for adding Promise type) */ returnType?: string /** * Options for JSdocs */ JSDoc?: { comments: string[] } client: { baseURL: string | undefined generics: string | string[] method: HttpMethod path: URLPath dataReturnType: PluginClient['options']['dataReturnType'] withQueryParams: boolean withData: boolean withHeaders: boolean contentType: string } } function Template({ name, generics, returnType, params, JSDoc, client }: TemplateProps): KubbNode { const isFormData = client.contentType === 'multipart/form-data' const headers = [ client.contentType !== 'application/json' ? `'Content-Type': '${client.contentType}'` : undefined, client.withHeaders ? '...headers' : undefined, ] .filter(Boolean) .join(', ') const clientParams: Params = { data: { mode: 'object', children: { method: { type: 'string', value: JSON.stringify(client.method), }, url: { type: 'string', value: client.path.template, }, baseURL: client.baseURL ? { type: 'string', value: JSON.stringify(client.baseURL), } : undefined, params: client.withQueryParams ? { type: 'any', } : undefined, data: client.withData ? { type: 'any', value: isFormData ? 'formData' : undefined, } : undefined, headers: headers.length ? { type: 'any', value: headers.length ? `{ ${headers}, ...options.headers }` : undefined, } : undefined, options: { type: 'any', mode: 'inlineSpread', }, }, }, } const formData = isFormData ? ` const formData = new FormData() if(data) { Object.keys(data).forEach((key) => { const value = data[key]; if (typeof key === "string" && (typeof value === "string" || value instanceof Blob)) { formData.append(key, value); } }) } ` : undefined return ( {formData || ''} } /> {client.dataReturnType === 'data' ? 'res.data' : 'res'} ) } type RootTemplateProps = { children?: React.ReactNode } function RootTemplate({ children }: RootTemplateProps) { const { plugin: { options: { client: { importPath }, extName, }, }, } = useApp() const { getSchemas, getFile } = useOperationManager() const operation = useOperation() const file = getFile(operation) const fileType = getFile(operation, { pluginKey: [pluginTsName] }) const schemas = getSchemas(operation, { pluginKey: [pluginTsName], type: 'type' }) return ( baseName={file.baseName} path={file.path} meta={file.meta}> {children} ) } const defaultTemplates = { default: Template, root: RootTemplate } as const type Templates = Partial type ClientProps = { baseURL: string | undefined /** * This will make it possible to override the default behaviour. */ Template?: ComponentType> } export function Client({ baseURL, Template = defaultTemplates.default }: ClientProps): KubbNode { const { plugin: { options: { client, dataReturnType, pathParamsType }, }, } = useApp() const { getSchemas, getName } = useOperationManager() const operation = useOperation() const contentType = operation.getContentType() const name = getName(operation, { type: 'function' }) const schemas = getSchemas(operation, { pluginKey: [pluginTsName], type: 'type' }) return (