@kubb/plugin-client
Version:
API client generator plugin for Kubb, creating type-safe HTTP clients (Axios, Fetch) from OpenAPI specifications for making API requests.
460 lines (452 loc) • 19 kB
JavaScript
import { t as __name } from "./chunk-DKWOrOAv.js";
import { getComments, getParamsMapping, getPathParams } from "@kubb/plugin-oas/utils";
import { Const, File, Function, FunctionParams } from "@kubb/react-fabric";
import { URLPath, buildJSDoc } from "@kubb/core/utils";
import { getDefaultValue, isOptional } from "@kubb/oas";
import { Fragment, jsx, jsxs } from "@kubb/react-fabric/jsx-runtime";
//#region src/components/Url.tsx
function getParams$1({ paramsType, paramsCasing, pathParamsType, typeSchemas }) {
if (paramsType === "object") {
const pathParams = getPathParams(typeSchemas.pathParams, {
typed: true,
casing: paramsCasing
});
return FunctionParams.factory({ data: {
mode: "object",
children: { ...pathParams }
} });
}
return FunctionParams.factory({ pathParams: typeSchemas.pathParams?.name ? {
mode: pathParamsType === "object" ? "object" : "inlineSpread",
children: getPathParams(typeSchemas.pathParams, {
typed: true,
casing: paramsCasing
}),
default: getDefaultValue(typeSchemas.pathParams?.schema)
} : void 0 });
}
__name(getParams$1, "getParams");
function Url({ name, isExportable = true, isIndexable = true, typeSchemas, baseURL, paramsType, paramsCasing, pathParamsType, operation }) {
const path = new URLPath(operation.path);
const params = getParams$1({
paramsType,
paramsCasing,
pathParamsType,
typeSchemas
});
const pathParamsMapping = paramsCasing ? getParamsMapping(typeSchemas.pathParams, { casing: paramsCasing }) : void 0;
return /* @__PURE__ */ jsx(File.Source, {
name,
isExportable,
isIndexable,
children: /* @__PURE__ */ jsxs(Function, {
name,
export: isExportable,
params: params.toConstructor(),
children: [
pathParamsMapping && Object.entries(pathParamsMapping).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
pathParamsMapping && /* @__PURE__ */ jsx("br", {}),
/* @__PURE__ */ jsx(Const, {
name: "res",
children: `{ method: '${operation.method.toUpperCase()}', url: ${path.toTemplateString({ prefix: baseURL })} as const }`
}),
/* @__PURE__ */ jsx("br", {}),
"return res"
]
})
});
}
Url.getParams = getParams$1;
//#endregion
//#region src/components/Client.tsx
function getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas, isConfigurable }) {
if (paramsType === "object") {
const children = {
...getPathParams(typeSchemas.pathParams, {
typed: true,
casing: paramsCasing
}),
data: typeSchemas.request?.name ? {
type: typeSchemas.request?.name,
optional: isOptional(typeSchemas.request?.schema)
} : void 0,
params: typeSchemas.queryParams?.name ? {
type: typeSchemas.queryParams?.name,
optional: isOptional(typeSchemas.queryParams?.schema)
} : void 0,
headers: typeSchemas.headerParams?.name ? {
type: typeSchemas.headerParams?.name,
optional: isOptional(typeSchemas.headerParams?.schema)
} : void 0
};
const allChildrenAreOptional = Object.values(children).every((child) => !child || child.optional);
return FunctionParams.factory({
data: {
mode: "object",
children,
default: allChildrenAreOptional ? "{}" : void 0
},
config: isConfigurable ? {
type: typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }",
default: "{}"
} : void 0
});
}
return FunctionParams.factory({
pathParams: typeSchemas.pathParams?.name ? {
mode: pathParamsType === "object" ? "object" : "inlineSpread",
children: getPathParams(typeSchemas.pathParams, {
typed: true,
casing: paramsCasing
}),
default: getDefaultValue(typeSchemas.pathParams?.schema)
} : void 0,
data: typeSchemas.request?.name ? {
type: typeSchemas.request?.name,
optional: isOptional(typeSchemas.request?.schema)
} : void 0,
params: typeSchemas.queryParams?.name ? {
type: typeSchemas.queryParams?.name,
optional: isOptional(typeSchemas.queryParams?.schema)
} : void 0,
headers: typeSchemas.headerParams?.name ? {
type: typeSchemas.headerParams?.name,
optional: isOptional(typeSchemas.headerParams?.schema)
} : void 0,
config: isConfigurable ? {
type: typeSchemas.request?.name ? `Partial<RequestConfig<${typeSchemas.request?.name}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }",
default: "{}"
} : void 0
});
}
function Client({ name, isExportable = true, isIndexable = true, returnType, typeSchemas, baseURL, dataReturnType, parser, zodSchemas, paramsType, paramsCasing, pathParamsType, operation, urlName, children, isConfigurable = true }) {
const path = new URLPath(operation.path);
const contentType = operation.getContentType();
const isFormData = contentType === "multipart/form-data";
const pathParamsMapping = paramsCasing ? getParamsMapping(typeSchemas.pathParams, { casing: paramsCasing }) : void 0;
const queryParamsMapping = paramsCasing ? getParamsMapping(typeSchemas.queryParams, { casing: paramsCasing }) : void 0;
const headerParamsMapping = paramsCasing ? getParamsMapping(typeSchemas.headerParams, { casing: paramsCasing }) : void 0;
const headers = [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : void 0, typeSchemas.headerParams?.name ? headerParamsMapping ? "...mappedHeaders" : "...headers" : void 0].filter(Boolean);
const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(" | ") || "Error"}>`;
const generics = [
typeSchemas.response.name,
TError,
typeSchemas.request?.name || "unknown"
].filter(Boolean);
const params = getParams({
paramsType,
paramsCasing,
pathParamsType,
typeSchemas,
isConfigurable
});
const urlParams = Url.getParams({
paramsType,
paramsCasing,
pathParamsType,
typeSchemas
});
const clientParams = FunctionParams.factory({ config: {
mode: "object",
children: {
method: { value: JSON.stringify(operation.method.toUpperCase()) },
url: { value: urlName ? `${urlName}(${urlParams.toCall()}).url.toString()` : path.template },
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } : void 0,
params: typeSchemas.queryParams?.name ? queryParamsMapping ? { value: "mappedParams" } : {} : void 0,
data: typeSchemas.request?.name ? { value: isFormData ? "formData as FormData" : "requestData" } : void 0,
requestConfig: isConfigurable ? { mode: "inlineSpread" } : void 0,
headers: headers.length ? { value: isConfigurable ? `{ ${headers.join(", ")}, ...requestConfig.headers }` : `{ ${headers.join(", ")} }` } : void 0
}
} });
const childrenElement = children ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
dataReturnType === "full" && parser === "zod" && zodSchemas && `return {...res, data: ${zodSchemas.response.name}.parse(res.data)}`,
dataReturnType === "data" && parser === "zod" && zodSchemas && `return ${zodSchemas.response.name}.parse(res.data)`,
dataReturnType === "full" && parser === "client" && "return res",
dataReturnType === "data" && parser === "client" && "return res.data"
] });
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("br", {}), /* @__PURE__ */ jsx(File.Source, {
name,
isExportable,
isIndexable,
children: /* @__PURE__ */ jsxs(Function, {
name,
async: true,
export: isExportable,
params: params.toConstructor(),
JSDoc: { comments: getComments(operation) },
returnType,
children: [
isConfigurable ? "const { client: request = fetch, ...requestConfig } = config" : "",
/* @__PURE__ */ jsx("br", {}),
/* @__PURE__ */ jsx("br", {}),
pathParamsMapping && Object.entries(pathParamsMapping).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
pathParamsMapping && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("br", {}), /* @__PURE__ */ jsx("br", {})] }),
queryParamsMapping && typeSchemas.queryParams?.name && /* @__PURE__ */ jsxs(Fragment, { children: [
`const mappedParams = params ? { ${Object.entries(queryParamsMapping).map(([originalName, camelCaseName]) => `"${originalName}": params.${camelCaseName}`).join(", ")} } : undefined`,
/* @__PURE__ */ jsx("br", {}),
/* @__PURE__ */ jsx("br", {})
] }),
headerParamsMapping && typeSchemas.headerParams?.name && /* @__PURE__ */ jsxs(Fragment, { children: [
`const mappedHeaders = headers ? { ${Object.entries(headerParamsMapping).map(([originalName, camelCaseName]) => `"${originalName}": headers.${camelCaseName}`).join(", ")} } : undefined`,
/* @__PURE__ */ jsx("br", {}),
/* @__PURE__ */ jsx("br", {})
] }),
parser === "zod" && zodSchemas?.request?.name ? `const requestData = ${zodSchemas.request.name}.parse(data)` : typeSchemas?.request?.name && "const requestData = data",
/* @__PURE__ */ jsx("br", {}),
isFormData && typeSchemas?.request?.name && "const formData = buildFormData(requestData)",
/* @__PURE__ */ jsx("br", {}),
isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await fetch<${generics.join(", ")}>(${clientParams.toCall()})`,
/* @__PURE__ */ jsx("br", {}),
childrenElement
]
})
})] });
}
Client.getParams = getParams;
//#endregion
//#region src/components/ClassClient.tsx
function buildHeaders$1(contentType, hasHeaderParams) {
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : void 0, hasHeaderParams ? "...headers" : void 0].filter(Boolean);
}
__name(buildHeaders$1, "buildHeaders");
function buildGenerics$1(typeSchemas) {
const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(" | ") || "Error"}>`;
return [
typeSchemas.response.name,
TError,
typeSchemas.request?.name || "unknown"
].filter(Boolean);
}
__name(buildGenerics$1, "buildGenerics");
function buildClientParams$1({ operation, path, baseURL, typeSchemas, isFormData, headers }) {
return FunctionParams.factory({ config: {
mode: "object",
children: {
requestConfig: { mode: "inlineSpread" },
method: { value: JSON.stringify(operation.method.toUpperCase()) },
url: { value: path.template },
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : void 0,
params: typeSchemas.queryParams?.name ? {} : void 0,
data: typeSchemas.request?.name ? { value: isFormData ? "formData as FormData" : "requestData" } : void 0,
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : void 0
}
} });
}
__name(buildClientParams$1, "buildClientParams");
function buildRequestDataLine$1({ parser, zodSchemas, typeSchemas }) {
if (parser === "zod" && zodSchemas?.request?.name) return `const requestData = ${zodSchemas.request.name}.parse(data)`;
if (typeSchemas?.request?.name) return "const requestData = data";
return "";
}
__name(buildRequestDataLine$1, "buildRequestDataLine");
function buildFormDataLine$1(isFormData, hasRequest) {
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
}
__name(buildFormDataLine$1, "buildFormDataLine");
function buildReturnStatement$1({ dataReturnType, parser, zodSchemas }) {
if (dataReturnType === "full" && parser === "zod" && zodSchemas) return `return {...res, data: ${zodSchemas.response.name}.parse(res.data)}`;
if (dataReturnType === "data" && parser === "zod" && zodSchemas) return `return ${zodSchemas.response.name}.parse(res.data)`;
if (dataReturnType === "full" && parser === "client") return "return res";
return "return res.data";
}
__name(buildReturnStatement$1, "buildReturnStatement");
function generateMethod$1({ operation, name, typeSchemas, zodSchemas, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
const path = new URLPath(operation.path, { casing: paramsCasing });
const contentType = operation.getContentType();
const isFormData = contentType === "multipart/form-data";
const headers = buildHeaders$1(contentType, !!typeSchemas.headerParams?.name);
const generics = buildGenerics$1(typeSchemas);
const params = ClassClient.getParams({
paramsType,
paramsCasing,
pathParamsType,
typeSchemas,
isConfigurable: true
});
const clientParams = buildClientParams$1({
operation,
path,
baseURL,
typeSchemas,
isFormData,
headers
});
const jsdoc = buildJSDoc(getComments(operation));
const requestDataLine = buildRequestDataLine$1({
parser,
zodSchemas,
typeSchemas
});
const formDataLine = buildFormDataLine$1(isFormData, !!typeSchemas?.request?.name);
const returnStatement = buildReturnStatement$1({
dataReturnType,
parser,
zodSchemas
});
const methodBody = [
"const { client: request = fetch, ...requestConfig } = mergeConfig(this.#config, config)",
"",
requestDataLine,
formDataLine,
`const res = await request<${generics.join(", ")}>(${clientParams.toCall()})`,
returnStatement
].filter(Boolean).map((line) => ` ${line}`).join("\n");
return `${jsdoc}async ${name}(${params.toConstructor()}) {\n${methodBody}\n }`;
}
__name(generateMethod$1, "generateMethod");
function ClassClient({ name, isExportable = true, isIndexable = true, operations, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType, children }) {
const classCode = `export class ${name} {
#config: Partial<RequestConfig> & { client?: Client }
constructor(config: Partial<RequestConfig> & { client?: Client } = {}) {
this.#config = config
}
${operations.map(({ operation, name: methodName, typeSchemas, zodSchemas }) => generateMethod$1({
operation,
name: methodName,
typeSchemas,
zodSchemas,
baseURL,
dataReturnType,
parser,
paramsType,
paramsCasing,
pathParamsType
})).join("\n\n")}
}`;
return /* @__PURE__ */ jsxs(File.Source, {
name,
isExportable,
isIndexable,
children: [classCode, children]
});
}
ClassClient.getParams = Client.getParams;
//#endregion
//#region src/components/Operations.tsx
function Operations({ name, operations }) {
const operationsObject = {};
operations.forEach((operation) => {
operationsObject[operation.getOperationId()] = {
path: new URLPath(operation.path).URL,
method: operation.method
};
});
return /* @__PURE__ */ jsx(File.Source, {
name,
isExportable: true,
isIndexable: true,
children: /* @__PURE__ */ jsx(Const, {
name,
export: true,
children: JSON.stringify(operationsObject, void 0, 2)
})
});
}
//#endregion
//#region src/components/StaticClassClient.tsx
function buildHeaders(contentType, hasHeaderParams) {
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : void 0, hasHeaderParams ? "...headers" : void 0].filter(Boolean);
}
function buildGenerics(typeSchemas) {
const TError = `ResponseErrorConfig<${typeSchemas.errors?.map((item) => item.name).join(" | ") || "Error"}>`;
return [
typeSchemas.response.name,
TError,
typeSchemas.request?.name || "unknown"
].filter(Boolean);
}
function buildClientParams({ operation, path, baseURL, typeSchemas, isFormData, headers }) {
return FunctionParams.factory({ config: {
mode: "object",
children: {
requestConfig: { mode: "inlineSpread" },
method: { value: JSON.stringify(operation.method.toUpperCase()) },
url: { value: path.template },
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : void 0,
params: typeSchemas.queryParams?.name ? {} : void 0,
data: typeSchemas.request?.name ? { value: isFormData ? "formData as FormData" : "requestData" } : void 0,
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : void 0
}
} });
}
function buildRequestDataLine({ parser, zodSchemas, typeSchemas }) {
if (parser === "zod" && zodSchemas?.request?.name) return `const requestData = ${zodSchemas.request.name}.parse(data)`;
if (typeSchemas?.request?.name) return "const requestData = data";
return "";
}
function buildFormDataLine(isFormData, hasRequest) {
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
}
function buildReturnStatement({ dataReturnType, parser, zodSchemas }) {
if (dataReturnType === "full" && parser === "zod" && zodSchemas) return `return {...res, data: ${zodSchemas.response.name}.parse(res.data)}`;
if (dataReturnType === "data" && parser === "zod" && zodSchemas) return `return ${zodSchemas.response.name}.parse(res.data)`;
if (dataReturnType === "full" && parser === "client") return "return res";
return "return res.data";
}
function generateMethod({ operation, name, typeSchemas, zodSchemas, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
const path = new URLPath(operation.path, { casing: paramsCasing });
const contentType = operation.getContentType();
const isFormData = contentType === "multipart/form-data";
const headers = buildHeaders(contentType, !!typeSchemas.headerParams?.name);
const generics = buildGenerics(typeSchemas);
const params = Client.getParams({
paramsType,
paramsCasing,
pathParamsType,
typeSchemas,
isConfigurable: true
});
const clientParams = buildClientParams({
operation,
path,
baseURL,
typeSchemas,
isFormData,
headers
});
const jsdoc = buildJSDoc(getComments(operation));
const requestDataLine = buildRequestDataLine({
parser,
zodSchemas,
typeSchemas
});
const formDataLine = buildFormDataLine(isFormData, !!typeSchemas?.request?.name);
const returnStatement = buildReturnStatement({
dataReturnType,
parser,
zodSchemas
});
const methodBody = [
"const { client: request = fetch, ...requestConfig } = mergeConfig(this.#config, config)",
"",
requestDataLine,
formDataLine,
`const res = await request<${generics.join(", ")}>(${clientParams.toCall()})`,
returnStatement
].filter(Boolean).map((line) => ` ${line}`).join("\n");
return `${jsdoc} static async ${name}(${params.toConstructor()}) {\n${methodBody}\n }`;
}
function StaticClassClient({ name, isExportable = true, isIndexable = true, operations, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType, children }) {
const classCode = `export class ${name} {\n static #config: Partial<RequestConfig> & { client?: Client } = {}\n\n${operations.map(({ operation, name: methodName, typeSchemas, zodSchemas }) => generateMethod({
operation,
name: methodName,
typeSchemas,
zodSchemas,
baseURL,
dataReturnType,
parser,
paramsType,
paramsCasing,
pathParamsType
})).join("\n\n")}\n}`;
return /* @__PURE__ */ jsxs(File.Source, {
name,
isExportable,
isIndexable,
children: [classCode, children]
});
}
StaticClassClient.getParams = Client.getParams;
//#endregion
export { Url as a, Client as i, Operations as n, ClassClient as r, StaticClassClient as t };
//# sourceMappingURL=StaticClassClient-DGIMTS_f.js.map