@kubb/plugin-client 5.0.0-beta.3 → 5.0.0-beta.30
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 +24 -4
- package/dist/clients/axios.cjs +25 -3
- package/dist/clients/axios.cjs.map +1 -1
- package/dist/clients/axios.d.ts +9 -2
- package/dist/clients/axios.js +25 -3
- package/dist/clients/axios.js.map +1 -1
- package/dist/clients/fetch.cjs +20 -2
- package/dist/clients/fetch.cjs.map +1 -1
- package/dist/clients/fetch.d.ts +9 -2
- package/dist/clients/fetch.js +20 -2
- package/dist/clients/fetch.js.map +1 -1
- package/dist/index.cjs +524 -301
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +150 -84
- package/dist/index.js +525 -302
- package/dist/index.js.map +1 -1
- package/dist/templates/clients/axios.source.cjs +1 -1
- package/dist/templates/clients/axios.source.js +1 -1
- package/dist/templates/clients/fetch.source.cjs +1 -1
- package/dist/templates/clients/fetch.source.js +1 -1
- package/extension.yaml +1293 -0
- package/package.json +11 -17
- package/src/clients/axios.ts +41 -7
- package/src/clients/fetch.ts +30 -3
- package/src/components/ClassClient.tsx +17 -19
- package/src/components/Client.tsx +68 -51
- package/src/components/StaticClassClient.tsx +17 -19
- package/src/components/Url.tsx +7 -9
- package/src/components/WrapperClient.tsx +9 -5
- package/src/functionParams.ts +8 -8
- package/src/generators/classClientGenerator.tsx +40 -38
- package/src/generators/clientGenerator.tsx +32 -35
- package/src/generators/groupedClientGenerator.tsx +14 -8
- package/src/generators/operationsGenerator.tsx +12 -6
- package/src/generators/staticClassClientGenerator.tsx +34 -32
- package/src/plugin.ts +24 -11
- package/src/resolvers/resolverClient.ts +31 -8
- package/src/types.ts +90 -53
- package/src/utils.ts +30 -53
- package/templates/clients/axios.ts +0 -73
- package/templates/clients/fetch.ts +0 -96
- package/templates/config.ts +0 -43
package/dist/index.cjs
CHANGED
|
@@ -191,6 +191,26 @@ function isValidVarName(name) {
|
|
|
191
191
|
if (!name || reservedWords.has(name)) return false;
|
|
192
192
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
193
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
196
|
+
* otherwise prefixes it with `_` so the result is a valid identifier.
|
|
197
|
+
*
|
|
198
|
+
* Useful for sanitizing OpenAPI schema names or operation IDs that start with
|
|
199
|
+
* a digit (e.g. `409`, `504AccountCancel`) before using them as exported
|
|
200
|
+
* variable, type, or function names.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* ensureValidVarName('409') // '_409'
|
|
205
|
+
* ensureValidVarName('504AccountCancel') // '_504AccountCancel'
|
|
206
|
+
* ensureValidVarName('Pet') // 'Pet'
|
|
207
|
+
* ensureValidVarName('class') // '_class'
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
function ensureValidVarName(name) {
|
|
211
|
+
if (!name || isValidVarName(name)) return name;
|
|
212
|
+
return `_${name}`;
|
|
213
|
+
}
|
|
194
214
|
//#endregion
|
|
195
215
|
//#region ../../internals/utils/src/urlPath.ts
|
|
196
216
|
/**
|
|
@@ -257,16 +277,16 @@ var URLPath = class {
|
|
|
257
277
|
get object() {
|
|
258
278
|
return this.toObject();
|
|
259
279
|
}
|
|
260
|
-
/** Returns a map of path parameter names, or `
|
|
280
|
+
/** Returns a map of path parameter names, or `null` when the path has no parameters.
|
|
261
281
|
*
|
|
262
282
|
* @example
|
|
263
283
|
* ```ts
|
|
264
284
|
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
265
|
-
* new URLPath('/pet').params //
|
|
285
|
+
* new URLPath('/pet').params // null
|
|
266
286
|
* ```
|
|
267
287
|
*/
|
|
268
288
|
get params() {
|
|
269
|
-
return this.
|
|
289
|
+
return this.toParamsObject();
|
|
270
290
|
}
|
|
271
291
|
#transformParam(raw) {
|
|
272
292
|
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
@@ -284,7 +304,7 @@ var URLPath = class {
|
|
|
284
304
|
toObject({ type = "path", replacer, stringify } = {}) {
|
|
285
305
|
const object = {
|
|
286
306
|
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
287
|
-
params: this.
|
|
307
|
+
params: this.toParamsObject()
|
|
288
308
|
};
|
|
289
309
|
if (stringify) {
|
|
290
310
|
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
@@ -300,12 +320,13 @@ var URLPath = class {
|
|
|
300
320
|
* @example
|
|
301
321
|
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
302
322
|
*/
|
|
303
|
-
toTemplateString({ prefix
|
|
304
|
-
|
|
323
|
+
toTemplateString({ prefix, replacer } = {}) {
|
|
324
|
+
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
305
325
|
if (i % 2 === 0) return part;
|
|
306
326
|
const param = this.#transformParam(part);
|
|
307
327
|
return `\${${replacer ? replacer(param) : param}}`;
|
|
308
|
-
}).join("")
|
|
328
|
+
}).join("");
|
|
329
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
309
330
|
}
|
|
310
331
|
/**
|
|
311
332
|
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
@@ -314,17 +335,17 @@ var URLPath = class {
|
|
|
314
335
|
*
|
|
315
336
|
* @example
|
|
316
337
|
* ```ts
|
|
317
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').
|
|
338
|
+
* new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
|
|
318
339
|
* // { petId: 'petId', tagId: 'tagId' }
|
|
319
340
|
* ```
|
|
320
341
|
*/
|
|
321
|
-
|
|
342
|
+
toParamsObject(replacer) {
|
|
322
343
|
const params = {};
|
|
323
344
|
this.#eachParam((_raw, param) => {
|
|
324
345
|
const key = replacer ? replacer(param) : param;
|
|
325
346
|
params[key] = key;
|
|
326
347
|
});
|
|
327
|
-
return Object.keys(params).length > 0 ? params :
|
|
348
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
328
349
|
}
|
|
329
350
|
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
330
351
|
*
|
|
@@ -338,6 +359,121 @@ var URLPath = class {
|
|
|
338
359
|
}
|
|
339
360
|
};
|
|
340
361
|
//#endregion
|
|
362
|
+
//#region ../../internals/shared/src/operation.ts
|
|
363
|
+
function getOperationLink(node, link) {
|
|
364
|
+
if (!link) return null;
|
|
365
|
+
if (typeof link === "function") return link(node) ?? null;
|
|
366
|
+
if (link === "urlPath") return node.path ? `{@link ${new URLPath(node.path).URL}}` : null;
|
|
367
|
+
return `{@link ${node.path.replaceAll("{", ":").replaceAll("}", "")}}`;
|
|
368
|
+
}
|
|
369
|
+
function getContentTypeInfo(node) {
|
|
370
|
+
const contentTypes = node.requestBody?.content?.map((e) => e.contentType) ?? [];
|
|
371
|
+
const isMultipleContentTypes = contentTypes.length > 1;
|
|
372
|
+
return {
|
|
373
|
+
contentTypes,
|
|
374
|
+
isMultipleContentTypes,
|
|
375
|
+
contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
|
|
376
|
+
defaultContentType: contentTypes[0] ?? "application/json",
|
|
377
|
+
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function buildRequestConfigType(node, resolver) {
|
|
381
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null;
|
|
382
|
+
const { isMultipleContentTypes, contentTypeUnion } = getContentTypeInfo(node);
|
|
383
|
+
return `${requestName ? `Partial<RequestConfig<${requestName}>>` : "Partial<RequestConfig>"} & { ${["client?: Client", isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` : null].filter(Boolean).join("; ")} }`;
|
|
384
|
+
}
|
|
385
|
+
function buildOperationComments(node, options = {}) {
|
|
386
|
+
const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
|
|
387
|
+
const linkComment = getOperationLink(node, link);
|
|
388
|
+
const filteredComments = (linkPosition === "beforeDeprecated" ? [
|
|
389
|
+
node.description && `@description ${node.description}`,
|
|
390
|
+
node.summary && `@summary ${node.summary}`,
|
|
391
|
+
linkComment,
|
|
392
|
+
node.deprecated && "@deprecated"
|
|
393
|
+
] : [
|
|
394
|
+
node.description && `@description ${node.description}`,
|
|
395
|
+
node.summary && `@summary ${node.summary}`,
|
|
396
|
+
node.deprecated && "@deprecated",
|
|
397
|
+
linkComment
|
|
398
|
+
]).filter((comment) => Boolean(comment));
|
|
399
|
+
if (!splitLines) return filteredComments;
|
|
400
|
+
return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
|
|
401
|
+
}
|
|
402
|
+
function getOperationParameters(node, options = {}) {
|
|
403
|
+
const params = _kubb_core.ast.caseParams(node.parameters, options.paramsCasing);
|
|
404
|
+
return {
|
|
405
|
+
path: params.filter((param) => param.in === "path"),
|
|
406
|
+
query: params.filter((param) => param.in === "query"),
|
|
407
|
+
header: params.filter((param) => param.in === "header"),
|
|
408
|
+
cookie: params.filter((param) => param.in === "cookie")
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
function getStatusCodeNumber(statusCode) {
|
|
412
|
+
const code = Number(statusCode);
|
|
413
|
+
return Number.isNaN(code) ? null : code;
|
|
414
|
+
}
|
|
415
|
+
function isSuccessStatusCode(statusCode) {
|
|
416
|
+
const code = getStatusCodeNumber(statusCode);
|
|
417
|
+
return code !== null && code >= 200 && code < 300;
|
|
418
|
+
}
|
|
419
|
+
function isErrorStatusCode(statusCode) {
|
|
420
|
+
const code = getStatusCodeNumber(statusCode);
|
|
421
|
+
return code !== null && code >= 400;
|
|
422
|
+
}
|
|
423
|
+
function resolveErrorNames(node, resolver) {
|
|
424
|
+
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
425
|
+
}
|
|
426
|
+
function resolveSuccessNames(node, resolver) {
|
|
427
|
+
return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
428
|
+
}
|
|
429
|
+
function resolveStatusCodeNames(node, resolver) {
|
|
430
|
+
return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
431
|
+
}
|
|
432
|
+
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
433
|
+
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
434
|
+
const cacheKey = `${node.operationId}\0${options.paramsCasing ?? ""}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${(options.exclude ?? []).join(",")}`;
|
|
435
|
+
let byResolver = typeNamesByResolver.get(resolver);
|
|
436
|
+
if (byResolver) {
|
|
437
|
+
const cached = byResolver.get(cacheKey);
|
|
438
|
+
if (cached) return cached;
|
|
439
|
+
} else {
|
|
440
|
+
byResolver = /* @__PURE__ */ new Map();
|
|
441
|
+
typeNamesByResolver.set(resolver, byResolver);
|
|
442
|
+
}
|
|
443
|
+
const { path, query, header } = getOperationParameters(node, { paramsCasing: options.paramsCasing });
|
|
444
|
+
const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
|
|
445
|
+
const exclude = new Set(options.exclude ?? []);
|
|
446
|
+
const paramNames = [
|
|
447
|
+
...path.map((param) => resolver.resolvePathParamsName(node, param)),
|
|
448
|
+
...query.map((param) => resolver.resolveQueryParamsName(node, param)),
|
|
449
|
+
...header.map((param) => resolver.resolveHeaderParamsName(node, param))
|
|
450
|
+
];
|
|
451
|
+
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)];
|
|
452
|
+
const result = (options.order === "body-response-first" ? [
|
|
453
|
+
...bodyAndResponseNames,
|
|
454
|
+
...paramNames,
|
|
455
|
+
...responseStatusNames
|
|
456
|
+
] : [
|
|
457
|
+
...paramNames,
|
|
458
|
+
...bodyAndResponseNames,
|
|
459
|
+
...responseStatusNames
|
|
460
|
+
]).filter((name) => Boolean(name) && !exclude.has(name));
|
|
461
|
+
byResolver.set(cacheKey, result);
|
|
462
|
+
return result;
|
|
463
|
+
}
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region ../../internals/shared/src/params.ts
|
|
466
|
+
function buildParamsMapping(originalParams, mappedParams) {
|
|
467
|
+
const mapping = {};
|
|
468
|
+
let hasChanged = false;
|
|
469
|
+
originalParams.forEach((param, i) => {
|
|
470
|
+
const mappedName = mappedParams[i]?.name ?? param.name;
|
|
471
|
+
mapping[param.name] = mappedName;
|
|
472
|
+
if (param.name !== mappedName) hasChanged = true;
|
|
473
|
+
});
|
|
474
|
+
return hasChanged ? mapping : null;
|
|
475
|
+
}
|
|
476
|
+
//#endregion
|
|
341
477
|
//#region src/functionParams.ts
|
|
342
478
|
const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
343
479
|
const callPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "call" });
|
|
@@ -348,18 +484,18 @@ function createType(type) {
|
|
|
348
484
|
return type ? _kubb_core.ast.createParamsType({
|
|
349
485
|
variant: "reference",
|
|
350
486
|
name: type
|
|
351
|
-
}) :
|
|
487
|
+
}) : null;
|
|
352
488
|
}
|
|
353
489
|
function createDeclarationLeaf(name, spec) {
|
|
354
490
|
if (spec.default !== void 0) return _kubb_core.ast.createFunctionParameter({
|
|
355
491
|
name,
|
|
356
|
-
type: createType(spec.type),
|
|
492
|
+
type: createType(spec.type) ?? void 0,
|
|
357
493
|
default: spec.default,
|
|
358
494
|
rest: spec.mode === "inlineSpread"
|
|
359
495
|
});
|
|
360
496
|
return _kubb_core.ast.createFunctionParameter({
|
|
361
497
|
name,
|
|
362
|
-
type: createType(spec.type),
|
|
498
|
+
type: createType(spec.type) ?? void 0,
|
|
363
499
|
optional: !!spec.optional,
|
|
364
500
|
rest: spec.mode === "inlineSpread"
|
|
365
501
|
});
|
|
@@ -368,14 +504,14 @@ function createDeclarationParam(name, spec) {
|
|
|
368
504
|
if (isGroup(spec)) return _kubb_core.ast.createParameterGroup({
|
|
369
505
|
inline: spec.mode === "inlineSpread",
|
|
370
506
|
default: spec.default,
|
|
371
|
-
properties: Object.entries(spec.children).filter(([, child]) => child
|
|
507
|
+
properties: Object.entries(spec.children).filter(([, child]) => child != null).map(([childName, child]) => createDeclarationLeaf(childName, child))
|
|
372
508
|
});
|
|
373
509
|
return createDeclarationLeaf(name, spec);
|
|
374
510
|
}
|
|
375
511
|
function createCallParam(name, spec) {
|
|
376
512
|
if (isGroup(spec)) return _kubb_core.ast.createParameterGroup({
|
|
377
513
|
inline: spec.mode === "inlineSpread",
|
|
378
|
-
properties: Object.entries(spec.children).filter(([, child]) => child
|
|
514
|
+
properties: Object.entries(spec.children).filter(([, child]) => child != null).map(([childName, child]) => _kubb_core.ast.createFunctionParameter({
|
|
379
515
|
name: child?.mode === "inlineSpread" ? spec.mode === "inlineSpread" ? child.value ?? childName : `...${child.value ?? childName}` : child?.value ? `${childName}: ${child.value}` : childName,
|
|
380
516
|
rest: spec.mode === "inlineSpread" && child?.mode === "inlineSpread"
|
|
381
517
|
}))
|
|
@@ -390,7 +526,7 @@ function createCallParam(name, spec) {
|
|
|
390
526
|
* Returns utilities to output constructor signatures (`toConstructor()`) or call expressions (`toCall()`).
|
|
391
527
|
*/
|
|
392
528
|
function createFunctionParams(params) {
|
|
393
|
-
const entries = Object.entries(params).filter(([, spec]) => spec
|
|
529
|
+
const entries = Object.entries(params).filter(([, spec]) => spec != null);
|
|
394
530
|
return {
|
|
395
531
|
toConstructor() {
|
|
396
532
|
return declarationPrinter$4.print(_kubb_core.ast.createFunctionParameters({ params: entries.map(([name, spec]) => createDeclarationParam(name, spec)) })) ?? "";
|
|
@@ -401,106 +537,9 @@ function createFunctionParams(params) {
|
|
|
401
537
|
};
|
|
402
538
|
}
|
|
403
539
|
//#endregion
|
|
404
|
-
//#region src/utils.ts
|
|
405
|
-
/**
|
|
406
|
-
* Extracts documentation comments from an operation node.
|
|
407
|
-
* Includes description, summary, link, and deprecation information.
|
|
408
|
-
*/
|
|
409
|
-
function getComments(node) {
|
|
410
|
-
return [
|
|
411
|
-
node.description && `@description ${node.description}`,
|
|
412
|
-
node.summary && `@summary ${node.summary}`,
|
|
413
|
-
node.path && `{@link ${new URLPath(node.path).URL}}`,
|
|
414
|
-
node.deprecated && "@deprecated"
|
|
415
|
-
].filter((x) => Boolean(x)).flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((x) => Boolean(x));
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Builds a mapping of original parameter names to their transformed (cased) names.
|
|
419
|
-
* Returns undefined if no names have changed.
|
|
420
|
-
*/
|
|
421
|
-
function buildParamsMapping(originalParams, casedParams) {
|
|
422
|
-
const mapping = {};
|
|
423
|
-
let hasChanged = false;
|
|
424
|
-
originalParams.forEach((param, i) => {
|
|
425
|
-
const casedName = casedParams[i]?.name ?? param.name;
|
|
426
|
-
mapping[param.name] = casedName;
|
|
427
|
-
if (param.name !== casedName) hasChanged = true;
|
|
428
|
-
});
|
|
429
|
-
return hasChanged ? mapping : void 0;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Builds HTTP headers array for a client request.
|
|
433
|
-
* Includes Content-Type (if not default) and spreads header parameters if present.
|
|
434
|
-
*/
|
|
435
|
-
function buildHeaders(contentType, hasHeaderParams) {
|
|
436
|
-
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : void 0, hasHeaderParams ? "...headers" : void 0].filter(Boolean);
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Builds TypeScript generic parameters for a client method.
|
|
440
|
-
* Includes response type, error type, and optional request type.
|
|
441
|
-
*/
|
|
442
|
-
function buildGenerics(node, tsResolver) {
|
|
443
|
-
const responseName = tsResolver.resolveResponseName(node);
|
|
444
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0;
|
|
445
|
-
const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
446
|
-
return [
|
|
447
|
-
responseName,
|
|
448
|
-
`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
|
|
449
|
-
requestName || "unknown"
|
|
450
|
-
].filter(Boolean);
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Builds the parameters object for a class-based client method.
|
|
454
|
-
* Includes URL, method, base URL, headers, and request/response data.
|
|
455
|
-
*/
|
|
456
|
-
function buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, headers }) {
|
|
457
|
-
const queryParamsName = node.parameters.filter((p) => p.in === "query").length > 0 ? tsResolver.resolveQueryParamsName(node, node.parameters.filter((p) => p.in === "query")[0]) : void 0;
|
|
458
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0;
|
|
459
|
-
return createFunctionParams({ config: {
|
|
460
|
-
mode: "object",
|
|
461
|
-
children: {
|
|
462
|
-
requestConfig: { mode: "inlineSpread" },
|
|
463
|
-
method: { value: JSON.stringify(node.method.toUpperCase()) },
|
|
464
|
-
url: { value: path.template },
|
|
465
|
-
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : void 0,
|
|
466
|
-
params: queryParamsName ? {} : void 0,
|
|
467
|
-
data: requestName ? { value: isFormData ? "formData as FormData" : "requestData" } : void 0,
|
|
468
|
-
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : void 0
|
|
469
|
-
}
|
|
470
|
-
} });
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Builds the request data parsing line for client methods.
|
|
474
|
-
* Applies Zod validation if configured, otherwise uses data directly.
|
|
475
|
-
*/
|
|
476
|
-
function buildRequestDataLine({ parser, node, zodResolver }) {
|
|
477
|
-
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0;
|
|
478
|
-
if (parser === "zod" && zodRequestName) return `const requestData = ${zodRequestName}.parse(data)`;
|
|
479
|
-
if (node.requestBody?.content?.[0]?.schema) return "const requestData = data";
|
|
480
|
-
return "";
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Builds the form data conversion line for file upload requests.
|
|
484
|
-
* Returns empty string if not applicable.
|
|
485
|
-
*/
|
|
486
|
-
function buildFormDataLine(isFormData, hasRequest) {
|
|
487
|
-
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Builds the return statement for a client method.
|
|
491
|
-
* Applies Zod validation to response data if configured, otherwise returns raw response.
|
|
492
|
-
*/
|
|
493
|
-
function buildReturnStatement({ dataReturnType, parser, node, zodResolver }) {
|
|
494
|
-
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : void 0;
|
|
495
|
-
if (dataReturnType === "full" && parser === "zod" && zodResponseName) return `return {...res, data: ${zodResponseName}.parse(res.data)}`;
|
|
496
|
-
if (dataReturnType === "data" && parser === "zod" && zodResponseName) return `return ${zodResponseName}.parse(res.data)`;
|
|
497
|
-
if (dataReturnType === "full" && parser === "client") return "return res";
|
|
498
|
-
return "return res.data";
|
|
499
|
-
}
|
|
500
|
-
//#endregion
|
|
501
540
|
//#region src/components/Url.tsx
|
|
502
541
|
const declarationPrinter$3 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
503
|
-
function
|
|
542
|
+
function buildUrlParamsNode({ paramsType, paramsCasing, pathParamsType, node, tsResolver }) {
|
|
504
543
|
const urlNode = {
|
|
505
544
|
...node,
|
|
506
545
|
parameters: node.parameters.filter((p) => p.in === "path"),
|
|
@@ -513,10 +552,9 @@ function getParams$1({ paramsType, paramsCasing, pathParamsType, node, tsResolve
|
|
|
513
552
|
resolver: tsResolver
|
|
514
553
|
});
|
|
515
554
|
}
|
|
516
|
-
require_chunk.__name(getParams$1, "getParams");
|
|
517
555
|
function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsType, paramsCasing, pathParamsType, node, tsResolver }) {
|
|
518
556
|
const path = new URLPath(node.path);
|
|
519
|
-
const paramsNode =
|
|
557
|
+
const paramsNode = buildUrlParamsNode({
|
|
520
558
|
paramsType,
|
|
521
559
|
paramsCasing,
|
|
522
560
|
pathParamsType,
|
|
@@ -524,9 +562,9 @@ function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsTyp
|
|
|
524
562
|
tsResolver
|
|
525
563
|
});
|
|
526
564
|
const paramsSignature = declarationPrinter$3.print(paramsNode) ?? "";
|
|
527
|
-
const originalPathParams = node
|
|
528
|
-
const casedPathParams =
|
|
529
|
-
const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) :
|
|
565
|
+
const { path: originalPathParams } = getOperationParameters(node);
|
|
566
|
+
const { path: casedPathParams } = getOperationParameters(node, { paramsCasing });
|
|
567
|
+
const pathParamsMapping = paramsCasing ? buildParamsMapping(originalPathParams, casedPathParams) : null;
|
|
530
568
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
531
569
|
name,
|
|
532
570
|
isExportable,
|
|
@@ -548,56 +586,51 @@ function Url({ name, isExportable = true, isIndexable = true, baseURL, paramsTyp
|
|
|
548
586
|
})
|
|
549
587
|
});
|
|
550
588
|
}
|
|
551
|
-
Url.getParams = getParams$1;
|
|
552
589
|
//#endregion
|
|
553
590
|
//#region src/components/Client.tsx
|
|
554
591
|
const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
555
|
-
function
|
|
556
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0;
|
|
592
|
+
function buildClientParamsNode({ paramsType, paramsCasing, pathParamsType, node, tsResolver, isConfigurable }) {
|
|
557
593
|
return _kubb_core.ast.createOperationParams(node, {
|
|
558
594
|
paramsType,
|
|
559
595
|
pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
|
|
560
596
|
paramsCasing,
|
|
561
597
|
resolver: tsResolver,
|
|
562
|
-
extraParams: isConfigurable ? [_kubb_core.ast.createFunctionParameter({
|
|
598
|
+
extraParams: [...isConfigurable ? [_kubb_core.ast.createFunctionParameter({
|
|
563
599
|
name: "config",
|
|
564
600
|
type: _kubb_core.ast.createParamsType({
|
|
565
601
|
variant: "reference",
|
|
566
|
-
name:
|
|
602
|
+
name: buildRequestConfigType(node, tsResolver)
|
|
567
603
|
}),
|
|
568
604
|
default: "{}"
|
|
569
|
-
})] : []
|
|
605
|
+
})] : []]
|
|
570
606
|
});
|
|
571
607
|
}
|
|
572
608
|
function Client({ name, isExportable = true, isIndexable = true, returnType, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType, node, tsResolver, zodResolver, urlName, children, isConfigurable = true }) {
|
|
573
609
|
const path = new URLPath(node.path);
|
|
574
|
-
const contentType = node
|
|
575
|
-
const isFormData = contentType === "multipart/form-data";
|
|
576
|
-
const originalPathParams
|
|
577
|
-
const casedPathParams =
|
|
578
|
-
const
|
|
579
|
-
const
|
|
580
|
-
const
|
|
581
|
-
const
|
|
582
|
-
const
|
|
583
|
-
const
|
|
584
|
-
const
|
|
585
|
-
const
|
|
586
|
-
const
|
|
587
|
-
const
|
|
588
|
-
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) : void 0;
|
|
589
|
-
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : void 0;
|
|
590
|
-
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0;
|
|
610
|
+
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
611
|
+
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
612
|
+
const { path: originalPathParams, query: originalQueryParams, header: originalHeaderParams } = getOperationParameters(node);
|
|
613
|
+
const { path: casedPathParams, query: casedQueryParams, header: casedHeaderParams } = getOperationParameters(node, { paramsCasing });
|
|
614
|
+
const pathParamsMapping = paramsCasing && !urlName ? buildParamsMapping(originalPathParams, casedPathParams) : null;
|
|
615
|
+
const queryParamsMapping = paramsCasing ? buildParamsMapping(originalQueryParams, casedQueryParams) : null;
|
|
616
|
+
const headerParamsMapping = paramsCasing ? buildParamsMapping(originalHeaderParams, casedHeaderParams) : null;
|
|
617
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
618
|
+
const successNames = resolveSuccessNames(node, tsResolver);
|
|
619
|
+
const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
|
|
620
|
+
const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]) : null;
|
|
621
|
+
const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) : null;
|
|
622
|
+
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
623
|
+
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
591
624
|
const errorNames = node.responses.filter((r) => {
|
|
592
625
|
return Number.parseInt(r.statusCode, 10) >= 400;
|
|
593
626
|
}).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
594
|
-
const headers = [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` :
|
|
627
|
+
const headers = [!isMultipleContentTypes && contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, headerParamsName ? headerParamsMapping ? "...mappedHeaders" : "...headers" : null].filter(Boolean);
|
|
595
628
|
const generics = [
|
|
596
629
|
responseName,
|
|
597
630
|
`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
|
|
598
631
|
requestName || "unknown"
|
|
599
632
|
].filter(Boolean);
|
|
600
|
-
const paramsNode =
|
|
633
|
+
const paramsNode = buildClientParamsNode({
|
|
601
634
|
paramsType,
|
|
602
635
|
paramsCasing,
|
|
603
636
|
pathParamsType,
|
|
@@ -606,7 +639,7 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
606
639
|
isConfigurable
|
|
607
640
|
});
|
|
608
641
|
const paramsSignature = declarationPrinter$2.print(paramsNode) ?? "";
|
|
609
|
-
const urlParamsNode =
|
|
642
|
+
const urlParamsNode = buildUrlParamsNode({
|
|
610
643
|
paramsType,
|
|
611
644
|
paramsCasing,
|
|
612
645
|
pathParamsType,
|
|
@@ -619,11 +652,12 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
619
652
|
children: {
|
|
620
653
|
method: { value: JSON.stringify(node.method.toUpperCase()) },
|
|
621
654
|
url: { value: urlName ? `${urlName}(${urlParamsCall}).url.toString()` : path.template },
|
|
622
|
-
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } :
|
|
623
|
-
params: queryParamsName ? queryParamsMapping ? { value: "mappedParams" } : {} :
|
|
624
|
-
data: requestName ? { value: isFormData ? "formData as FormData" : "requestData" } :
|
|
625
|
-
|
|
626
|
-
|
|
655
|
+
baseURL: baseURL && !urlName ? { value: `\`${baseURL}\`` } : null,
|
|
656
|
+
params: queryParamsName ? queryParamsMapping ? { value: "mappedParams" } : {} : null,
|
|
657
|
+
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
658
|
+
contentType: isConfigurable && isMultipleContentTypes ? {} : null,
|
|
659
|
+
requestConfig: isConfigurable ? { mode: "inlineSpread" } : null,
|
|
660
|
+
headers: headers.length ? { value: isConfigurable ? `{ ${headers.join(", ")}, ...requestConfig.headers }` : `{ ${headers.join(", ")} }` } : null
|
|
627
661
|
}
|
|
628
662
|
} });
|
|
629
663
|
const childrenElement = children ? children : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
@@ -641,10 +675,14 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
641
675
|
async: true,
|
|
642
676
|
export: isExportable,
|
|
643
677
|
params: paramsSignature,
|
|
644
|
-
JSDoc: { comments:
|
|
678
|
+
JSDoc: { comments: buildOperationComments(node, {
|
|
679
|
+
link: "urlPath",
|
|
680
|
+
linkPosition: "beforeDeprecated",
|
|
681
|
+
splitLines: true
|
|
682
|
+
}) },
|
|
645
683
|
returnType,
|
|
646
684
|
children: [
|
|
647
|
-
isConfigurable ?
|
|
685
|
+
isConfigurable ? `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = config` : "",
|
|
648
686
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
649
687
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
650
688
|
pathParamsMapping && Object.entries(pathParamsMapping).filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
|
|
@@ -661,26 +699,101 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
|
|
|
661
699
|
] }),
|
|
662
700
|
parser === "zod" && zodRequestName ? `const requestData = ${zodRequestName}.parse(data)` : requestName && "const requestData = data",
|
|
663
701
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
664
|
-
isFormData && requestName && "const formData = buildFormData(requestData)",
|
|
702
|
+
(isFormData || isMultipleContentTypes && hasFormData) && requestName && "const formData = buildFormData(requestData)",
|
|
665
703
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
666
|
-
isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await
|
|
704
|
+
isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await client<${generics.join(", ")}>(${clientParams.toCall()})`,
|
|
667
705
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
|
|
668
706
|
childrenElement
|
|
669
707
|
]
|
|
670
708
|
})
|
|
671
709
|
})] });
|
|
672
710
|
}
|
|
673
|
-
|
|
711
|
+
//#endregion
|
|
712
|
+
//#region src/utils.ts
|
|
713
|
+
/**
|
|
714
|
+
* Builds HTTP headers array for a client request.
|
|
715
|
+
* Includes Content-Type (if not default) and spreads header parameters if present.
|
|
716
|
+
*/
|
|
717
|
+
function buildHeaders(contentType, hasHeaderParams) {
|
|
718
|
+
return [contentType !== "application/json" && contentType !== "multipart/form-data" ? `'Content-Type': '${contentType}'` : null, hasHeaderParams ? "...headers" : null].filter(Boolean);
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Builds TypeScript generic parameters for a client method.
|
|
722
|
+
* Includes response type, error type, and optional request type.
|
|
723
|
+
*/
|
|
724
|
+
function buildGenerics(node, tsResolver) {
|
|
725
|
+
const successNames = resolveSuccessNames(node, tsResolver);
|
|
726
|
+
const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
|
|
727
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
728
|
+
const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
|
|
729
|
+
return [
|
|
730
|
+
responseName,
|
|
731
|
+
`ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`,
|
|
732
|
+
requestName || "unknown"
|
|
733
|
+
].filter(Boolean);
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Builds the parameters object for a class-based client method.
|
|
737
|
+
* Includes URL, method, base URL, headers, and request/response data.
|
|
738
|
+
*/
|
|
739
|
+
function buildClassClientParams({ node, path, baseURL, tsResolver, isFormData, isMultipleContentTypes, hasFormData, headers }) {
|
|
740
|
+
const { query: queryParams } = getOperationParameters(node);
|
|
741
|
+
const queryParamsName = queryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, queryParams[0]) : null;
|
|
742
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
|
|
743
|
+
return createFunctionParams({ config: {
|
|
744
|
+
mode: "object",
|
|
745
|
+
children: {
|
|
746
|
+
requestConfig: { mode: "inlineSpread" },
|
|
747
|
+
method: { value: JSON.stringify(node.method.toUpperCase()) },
|
|
748
|
+
url: { value: path.template },
|
|
749
|
+
baseURL: baseURL ? { value: JSON.stringify(baseURL) } : null,
|
|
750
|
+
params: queryParamsName ? {} : null,
|
|
751
|
+
data: requestName ? { value: isMultipleContentTypes && hasFormData ? "contentType === 'multipart/form-data' ? formData as FormData : requestData" : isFormData ? "formData as FormData" : "requestData" } : null,
|
|
752
|
+
contentType: isMultipleContentTypes ? {} : null,
|
|
753
|
+
headers: headers.length ? { value: `{ ${headers.join(", ")}, ...requestConfig.headers }` } : null
|
|
754
|
+
}
|
|
755
|
+
} });
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Builds the request data parsing line for client methods.
|
|
759
|
+
* Applies Zod validation if configured, otherwise uses data directly.
|
|
760
|
+
*/
|
|
761
|
+
function buildRequestDataLine({ parser, node, zodResolver }) {
|
|
762
|
+
const zodRequestName = zodResolver && parser === "zod" && node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null;
|
|
763
|
+
if (parser === "zod" && zodRequestName) return `const requestData = ${zodRequestName}.parse(data)`;
|
|
764
|
+
if (node.requestBody?.content?.[0]?.schema) return "const requestData = data";
|
|
765
|
+
return "";
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Builds the form data conversion line for file upload requests.
|
|
769
|
+
* Returns empty string if not applicable.
|
|
770
|
+
*/
|
|
771
|
+
function buildFormDataLine(isFormData, hasRequest) {
|
|
772
|
+
return isFormData && hasRequest ? "const formData = buildFormData(requestData)" : "";
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Builds the return statement for a client method.
|
|
776
|
+
* Applies Zod validation to response data if configured, otherwise returns raw response.
|
|
777
|
+
*/
|
|
778
|
+
function buildReturnStatement({ dataReturnType, parser, node, zodResolver }) {
|
|
779
|
+
const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
|
|
780
|
+
if (dataReturnType === "full" && parser === "zod" && zodResponseName) return `return {...res, data: ${zodResponseName}.parse(res.data)}`;
|
|
781
|
+
if (dataReturnType === "data" && parser === "zod" && zodResponseName) return `return ${zodResponseName}.parse(res.data)`;
|
|
782
|
+
if (dataReturnType === "full" && parser === "client") return "return res";
|
|
783
|
+
return "return res.data";
|
|
784
|
+
}
|
|
674
785
|
//#endregion
|
|
675
786
|
//#region src/components/ClassClient.tsx
|
|
676
787
|
const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
677
788
|
function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
|
|
678
789
|
const path = new URLPath(node.path, { casing: paramsCasing });
|
|
679
|
-
const contentType = node
|
|
680
|
-
const isFormData = contentType === "multipart/form-data";
|
|
681
|
-
const
|
|
790
|
+
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
791
|
+
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
792
|
+
const { header: headerParams } = getOperationParameters(node);
|
|
793
|
+
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
794
|
+
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
682
795
|
const generics = buildGenerics(node, tsResolver);
|
|
683
|
-
const paramsNode =
|
|
796
|
+
const paramsNode = buildClientParamsNode({
|
|
684
797
|
paramsType,
|
|
685
798
|
paramsCasing,
|
|
686
799
|
pathParamsType,
|
|
@@ -695,15 +808,21 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
|
|
|
695
808
|
baseURL,
|
|
696
809
|
tsResolver,
|
|
697
810
|
isFormData,
|
|
811
|
+
isMultipleContentTypes,
|
|
812
|
+
hasFormData,
|
|
698
813
|
headers
|
|
699
814
|
});
|
|
700
|
-
const jsdoc = buildJSDoc(
|
|
815
|
+
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
816
|
+
link: "urlPath",
|
|
817
|
+
linkPosition: "beforeDeprecated",
|
|
818
|
+
splitLines: true
|
|
819
|
+
}));
|
|
701
820
|
const requestDataLine = buildRequestDataLine({
|
|
702
821
|
parser,
|
|
703
822
|
node,
|
|
704
823
|
zodResolver
|
|
705
824
|
});
|
|
706
|
-
const formDataLine = buildFormDataLine(isFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
825
|
+
const formDataLine = buildFormDataLine(isFormData || isMultipleContentTypes && hasFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
707
826
|
const returnStatement = buildReturnStatement({
|
|
708
827
|
dataReturnType,
|
|
709
828
|
parser,
|
|
@@ -711,7 +830,7 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
|
|
|
711
830
|
zodResolver
|
|
712
831
|
});
|
|
713
832
|
return `${jsdoc}async ${name}(${paramsSignature}) {\n${[
|
|
714
|
-
|
|
833
|
+
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
|
|
715
834
|
"",
|
|
716
835
|
requestDataLine,
|
|
717
836
|
formDataLine,
|
|
@@ -748,15 +867,14 @@ ${operations.map(({ node, name: methodName, tsResolver, zodResolver }) => genera
|
|
|
748
867
|
children: [classCode, children]
|
|
749
868
|
});
|
|
750
869
|
}
|
|
751
|
-
ClassClient.getParams = Client.getParams;
|
|
752
870
|
//#endregion
|
|
753
871
|
//#region src/components/WrapperClient.tsx
|
|
754
|
-
function WrapperClient({ name,
|
|
872
|
+
function WrapperClient({ name, controllers, isExportable = true, isIndexable = true }) {
|
|
755
873
|
const classCode = `export class ${name} {
|
|
756
|
-
${
|
|
874
|
+
${controllers.map(({ className, propertyName }) => ` readonly ${propertyName}: ${className}`).join("\n")}
|
|
757
875
|
|
|
758
876
|
constructor(config: Partial<RequestConfig> & { client?: Client } = {}) {
|
|
759
|
-
${
|
|
877
|
+
${controllers.map(({ className, propertyName }) => ` this.${propertyName} = new ${className}(config)`).join("\n")}
|
|
760
878
|
}
|
|
761
879
|
}`;
|
|
762
880
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
|
|
@@ -769,33 +887,31 @@ ${classNames.map((className) => ` this.${camelCase(className)} = new ${classN
|
|
|
769
887
|
//#endregion
|
|
770
888
|
//#region src/generators/classClientGenerator.tsx
|
|
771
889
|
function resolveTypeImportNames$1(node, tsResolver) {
|
|
772
|
-
return
|
|
773
|
-
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
|
|
774
|
-
tsResolver.resolveResponseName(node),
|
|
775
|
-
...node.parameters.filter((p) => p.in === "path").map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
776
|
-
...node.parameters.filter((p) => p.in === "query").map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
777
|
-
...node.parameters.filter((p) => p.in === "header").map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
778
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
|
|
779
|
-
].filter((n) => Boolean(n));
|
|
890
|
+
return resolveOperationTypeNames(node, tsResolver, { order: "body-response-first" });
|
|
780
891
|
}
|
|
781
892
|
require_chunk.__name(resolveTypeImportNames$1, "resolveTypeImportNames");
|
|
782
893
|
function resolveZodImportNames$1(node, zodResolver) {
|
|
783
|
-
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
894
|
+
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((n) => Boolean(n));
|
|
784
895
|
}
|
|
785
896
|
require_chunk.__name(resolveZodImportNames$1, "resolveZodImportNames");
|
|
897
|
+
/**
|
|
898
|
+
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
899
|
+
* `clientType: 'class'`. Emits one class per tag, with one instance method
|
|
900
|
+
* per operation and a shared constructor for request configuration.
|
|
901
|
+
*/
|
|
786
902
|
const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
787
903
|
name: "classClient",
|
|
788
|
-
renderer: _kubb_renderer_jsx.
|
|
904
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
789
905
|
operations(nodes, ctx) {
|
|
790
|
-
const {
|
|
906
|
+
const { config, driver, resolver, root } = ctx;
|
|
791
907
|
const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, sdk } = ctx.options;
|
|
792
|
-
const baseURL = ctx.options.baseURL ??
|
|
908
|
+
const baseURL = ctx.options.baseURL ?? ctx.meta.baseURL;
|
|
793
909
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
794
910
|
if (!pluginTs) return null;
|
|
795
911
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
796
912
|
const tsPluginOptions = pluginTs.options;
|
|
797
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) :
|
|
798
|
-
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) :
|
|
913
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
|
|
914
|
+
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
799
915
|
function buildOperationData(node) {
|
|
800
916
|
const typeFile = tsResolver.resolveFile({
|
|
801
917
|
name: node.operationId,
|
|
@@ -815,8 +931,8 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
815
931
|
}, {
|
|
816
932
|
root,
|
|
817
933
|
output: pluginZod.options?.output ?? output,
|
|
818
|
-
group: pluginZod.options?.group
|
|
819
|
-
}) :
|
|
934
|
+
group: pluginZod.options?.group ?? void 0
|
|
935
|
+
}) : null;
|
|
820
936
|
return {
|
|
821
937
|
node,
|
|
822
938
|
name: resolver.resolveName(node.operationId),
|
|
@@ -828,26 +944,29 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
828
944
|
}
|
|
829
945
|
const controllers = nodes.reduce((acc, operationNode) => {
|
|
830
946
|
const tag = operationNode.tags[0];
|
|
831
|
-
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ??
|
|
947
|
+
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveGroupName("Client");
|
|
832
948
|
if (!tag && !group) {
|
|
833
|
-
const name = "ApiClient";
|
|
949
|
+
const name = resolver.resolveClassName("ApiClient");
|
|
834
950
|
const file = resolver.resolveFile({
|
|
835
951
|
name,
|
|
836
952
|
extname: ".ts"
|
|
837
953
|
}, {
|
|
838
954
|
root,
|
|
839
955
|
output,
|
|
840
|
-
group
|
|
956
|
+
group: group ?? void 0
|
|
841
957
|
});
|
|
842
958
|
const operationData = buildOperationData(operationNode);
|
|
843
959
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
844
960
|
if (previous) previous.operations.push(operationData);
|
|
845
961
|
else acc.push({
|
|
846
962
|
name,
|
|
963
|
+
propertyName: resolver.resolveClientPropertyName(name),
|
|
847
964
|
file,
|
|
848
965
|
operations: [operationData]
|
|
849
966
|
});
|
|
850
|
-
|
|
967
|
+
return acc;
|
|
968
|
+
}
|
|
969
|
+
if (tag) {
|
|
851
970
|
const name = groupName;
|
|
852
971
|
const file = resolver.resolveFile({
|
|
853
972
|
name,
|
|
@@ -856,13 +975,14 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
856
975
|
}, {
|
|
857
976
|
root,
|
|
858
977
|
output,
|
|
859
|
-
group
|
|
978
|
+
group: group ?? void 0
|
|
860
979
|
});
|
|
861
980
|
const operationData = buildOperationData(operationNode);
|
|
862
981
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
863
982
|
if (previous) previous.operations.push(operationData);
|
|
864
983
|
else acc.push({
|
|
865
984
|
name,
|
|
985
|
+
propertyName: resolver.resolveClientPropertyName(name),
|
|
866
986
|
file,
|
|
867
987
|
operations: [operationData]
|
|
868
988
|
});
|
|
@@ -910,23 +1030,31 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
910
1030
|
zodImportsByFile: /* @__PURE__ */ new Map(),
|
|
911
1031
|
zodFilesByPath: /* @__PURE__ */ new Map()
|
|
912
1032
|
};
|
|
913
|
-
const hasFormData = ops.some((op) => op.node.requestBody?.content?.
|
|
1033
|
+
const hasFormData = ops.some((op) => op.node.requestBody?.content?.some((e) => e.contentType === "multipart/form-data") ?? false);
|
|
914
1034
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
915
1035
|
baseName: file.baseName,
|
|
916
1036
|
path: file.path,
|
|
917
1037
|
meta: file.meta,
|
|
918
|
-
banner: resolver.resolveBanner(
|
|
1038
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
919
1039
|
output,
|
|
920
|
-
config
|
|
1040
|
+
config,
|
|
1041
|
+
file: {
|
|
1042
|
+
path: file.path,
|
|
1043
|
+
baseName: file.baseName
|
|
1044
|
+
}
|
|
921
1045
|
}),
|
|
922
|
-
footer: resolver.resolveFooter(
|
|
1046
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
923
1047
|
output,
|
|
924
|
-
config
|
|
1048
|
+
config,
|
|
1049
|
+
file: {
|
|
1050
|
+
path: file.path,
|
|
1051
|
+
baseName: file.baseName
|
|
1052
|
+
}
|
|
925
1053
|
}),
|
|
926
1054
|
children: [
|
|
927
1055
|
importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
928
1056
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
929
|
-
name: "
|
|
1057
|
+
name: "client",
|
|
930
1058
|
path: importPath
|
|
931
1059
|
}),
|
|
932
1060
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -944,7 +1072,7 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
944
1072
|
})
|
|
945
1073
|
] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
946
1074
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
947
|
-
name: ["
|
|
1075
|
+
name: ["client"],
|
|
948
1076
|
root: file.path,
|
|
949
1077
|
path: node_path.default.resolve(root, ".kubb/client.ts")
|
|
950
1078
|
}),
|
|
@@ -1012,19 +1140,27 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1012
1140
|
}, {
|
|
1013
1141
|
root,
|
|
1014
1142
|
output,
|
|
1015
|
-
group
|
|
1143
|
+
group: group ?? void 0
|
|
1016
1144
|
});
|
|
1017
1145
|
files.push(/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
1018
1146
|
baseName: sdkFile.baseName,
|
|
1019
1147
|
path: sdkFile.path,
|
|
1020
1148
|
meta: sdkFile.meta,
|
|
1021
|
-
banner: resolver.resolveBanner(
|
|
1149
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1022
1150
|
output,
|
|
1023
|
-
config
|
|
1151
|
+
config,
|
|
1152
|
+
file: {
|
|
1153
|
+
path: sdkFile.path,
|
|
1154
|
+
baseName: sdkFile.baseName
|
|
1155
|
+
}
|
|
1024
1156
|
}),
|
|
1025
|
-
footer: resolver.resolveFooter(
|
|
1157
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1026
1158
|
output,
|
|
1027
|
-
config
|
|
1159
|
+
config,
|
|
1160
|
+
file: {
|
|
1161
|
+
path: sdkFile.path,
|
|
1162
|
+
baseName: sdkFile.baseName
|
|
1163
|
+
}
|
|
1028
1164
|
}),
|
|
1029
1165
|
children: [
|
|
1030
1166
|
importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -1044,7 +1180,10 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1044
1180
|
}, name)),
|
|
1045
1181
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(WrapperClient, {
|
|
1046
1182
|
name: sdk.className,
|
|
1047
|
-
|
|
1183
|
+
controllers: controllers.map(({ name, propertyName }) => ({
|
|
1184
|
+
className: name,
|
|
1185
|
+
propertyName
|
|
1186
|
+
}))
|
|
1048
1187
|
})
|
|
1049
1188
|
]
|
|
1050
1189
|
}, sdkFile.path));
|
|
@@ -1054,34 +1193,28 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1054
1193
|
});
|
|
1055
1194
|
//#endregion
|
|
1056
1195
|
//#region src/generators/clientGenerator.tsx
|
|
1196
|
+
/**
|
|
1197
|
+
* Built-in operation generator for `@kubb/plugin-client`. Emits one async
|
|
1198
|
+
* function per OpenAPI operation, plus the matching URL helper. Used when
|
|
1199
|
+
* `clientType: 'function'` (the default).
|
|
1200
|
+
*/
|
|
1057
1201
|
const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
1058
1202
|
name: "client",
|
|
1059
|
-
renderer: _kubb_renderer_jsx.
|
|
1203
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
1060
1204
|
operation(node, ctx) {
|
|
1061
|
-
const {
|
|
1205
|
+
const { config, driver, resolver, root } = ctx;
|
|
1062
1206
|
const { output, urlType, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath, group } = ctx.options;
|
|
1063
|
-
const baseURL = ctx.options.baseURL ??
|
|
1207
|
+
const baseURL = ctx.options.baseURL ?? ctx.meta.baseURL;
|
|
1064
1208
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1065
1209
|
if (!pluginTs) return null;
|
|
1066
1210
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1067
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) :
|
|
1068
|
-
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) :
|
|
1069
|
-
const
|
|
1070
|
-
const
|
|
1071
|
-
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
1072
|
-
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
1073
|
-
const importedTypeNames = [
|
|
1074
|
-
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
1075
|
-
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
1076
|
-
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
1077
|
-
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
|
|
1078
|
-
tsResolver.resolveResponseName(node),
|
|
1079
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
|
|
1080
|
-
].filter(Boolean);
|
|
1081
|
-
const importedZodNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : void 0].filter(Boolean) : [];
|
|
1211
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
|
|
1212
|
+
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
1213
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing });
|
|
1214
|
+
const importedZodNames = zodResolver && parser === "zod" ? [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((name) => Boolean(name)) : [];
|
|
1082
1215
|
const meta = {
|
|
1083
1216
|
name: resolver.resolveName(node.operationId),
|
|
1084
|
-
urlName:
|
|
1217
|
+
urlName: resolver.resolveUrlName(node),
|
|
1085
1218
|
file: resolver.resolveFile({
|
|
1086
1219
|
name: node.operationId,
|
|
1087
1220
|
extname: ".ts",
|
|
@@ -1090,7 +1223,7 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1090
1223
|
}, {
|
|
1091
1224
|
root,
|
|
1092
1225
|
output,
|
|
1093
|
-
group
|
|
1226
|
+
group: group ?? void 0
|
|
1094
1227
|
}),
|
|
1095
1228
|
fileTs: tsResolver.resolveFile({
|
|
1096
1229
|
name: node.operationId,
|
|
@@ -1100,7 +1233,7 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1100
1233
|
}, {
|
|
1101
1234
|
root,
|
|
1102
1235
|
output: pluginTs.options?.output ?? output,
|
|
1103
|
-
group: pluginTs.options?.group
|
|
1236
|
+
group: pluginTs.options?.group ?? void 0
|
|
1104
1237
|
}),
|
|
1105
1238
|
fileZod: zodResolver && pluginZod?.options ? zodResolver.resolveFile({
|
|
1106
1239
|
name: node.operationId,
|
|
@@ -1110,25 +1243,33 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1110
1243
|
}, {
|
|
1111
1244
|
root,
|
|
1112
1245
|
output: pluginZod.options.output ?? output,
|
|
1113
|
-
group: pluginZod.options?.group
|
|
1114
|
-
}) :
|
|
1246
|
+
group: pluginZod.options?.group ?? void 0
|
|
1247
|
+
}) : null
|
|
1115
1248
|
};
|
|
1116
|
-
const
|
|
1249
|
+
const hasFormData = node.requestBody?.content?.some((e) => e.contentType === "multipart/form-data") ?? false;
|
|
1117
1250
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
1118
1251
|
baseName: meta.file.baseName,
|
|
1119
1252
|
path: meta.file.path,
|
|
1120
1253
|
meta: meta.file.meta,
|
|
1121
|
-
banner: resolver.resolveBanner(
|
|
1254
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1122
1255
|
output,
|
|
1123
|
-
config
|
|
1256
|
+
config,
|
|
1257
|
+
file: {
|
|
1258
|
+
path: meta.file.path,
|
|
1259
|
+
baseName: meta.file.baseName
|
|
1260
|
+
}
|
|
1124
1261
|
}),
|
|
1125
|
-
footer: resolver.resolveFooter(
|
|
1262
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1126
1263
|
output,
|
|
1127
|
-
config
|
|
1264
|
+
config,
|
|
1265
|
+
file: {
|
|
1266
|
+
path: meta.file.path,
|
|
1267
|
+
baseName: meta.file.baseName
|
|
1268
|
+
}
|
|
1128
1269
|
}),
|
|
1129
1270
|
children: [
|
|
1130
1271
|
importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1131
|
-
name: "
|
|
1272
|
+
name: "client",
|
|
1132
1273
|
path: importPath
|
|
1133
1274
|
}), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1134
1275
|
name: [
|
|
@@ -1139,7 +1280,7 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1139
1280
|
path: importPath,
|
|
1140
1281
|
isTypeOnly: true
|
|
1141
1282
|
})] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1142
|
-
name: ["
|
|
1283
|
+
name: ["client"],
|
|
1143
1284
|
root: meta.file.path,
|
|
1144
1285
|
path: node_path.default.resolve(root, ".kubb/client.ts")
|
|
1145
1286
|
}), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -1152,7 +1293,7 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1152
1293
|
path: node_path.default.resolve(root, ".kubb/client.ts"),
|
|
1153
1294
|
isTypeOnly: true
|
|
1154
1295
|
})] }),
|
|
1155
|
-
|
|
1296
|
+
hasFormData && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1156
1297
|
name: ["buildFormData"],
|
|
1157
1298
|
root: meta.file.path,
|
|
1158
1299
|
path: node_path.default.resolve(root, ".kubb/config.ts")
|
|
@@ -1198,16 +1339,22 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1198
1339
|
});
|
|
1199
1340
|
//#endregion
|
|
1200
1341
|
//#region src/generators/groupedClientGenerator.tsx
|
|
1342
|
+
/**
|
|
1343
|
+
* Emits one aggregate file per tag/group when `group` is configured. Each
|
|
1344
|
+
* file re-exports every client function for that group, so callers can
|
|
1345
|
+
* `import { petController } from './gen/clients'` instead of importing
|
|
1346
|
+
* each operation individually.
|
|
1347
|
+
*/
|
|
1201
1348
|
const groupedClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
1202
1349
|
name: "groupedClient",
|
|
1203
|
-
renderer: _kubb_renderer_jsx.
|
|
1350
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
1204
1351
|
operations(nodes, ctx) {
|
|
1205
|
-
const { config, resolver,
|
|
1352
|
+
const { config, resolver, root } = ctx;
|
|
1206
1353
|
const { output, group } = ctx.options;
|
|
1207
1354
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: nodes.reduce((acc, operationNode) => {
|
|
1208
1355
|
if (group?.type === "tag") {
|
|
1209
1356
|
const tag = operationNode.tags[0];
|
|
1210
|
-
const name = tag ? group?.name?.({ group: camelCase(tag) }) :
|
|
1357
|
+
const name = tag ? group?.name?.({ group: camelCase(tag) }) : null;
|
|
1211
1358
|
if (!tag || !name) return acc;
|
|
1212
1359
|
const file = resolver.resolveFile({
|
|
1213
1360
|
name,
|
|
@@ -1216,7 +1363,7 @@ const groupedClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1216
1363
|
}, {
|
|
1217
1364
|
root,
|
|
1218
1365
|
output,
|
|
1219
|
-
group
|
|
1366
|
+
group: group ?? void 0
|
|
1220
1367
|
});
|
|
1221
1368
|
const clientFile = resolver.resolveFile({
|
|
1222
1369
|
name: operationNode.operationId,
|
|
@@ -1226,7 +1373,7 @@ const groupedClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1226
1373
|
}, {
|
|
1227
1374
|
root,
|
|
1228
1375
|
output,
|
|
1229
|
-
group
|
|
1376
|
+
group: group ?? void 0
|
|
1230
1377
|
});
|
|
1231
1378
|
const client = {
|
|
1232
1379
|
name: resolver.resolveName(operationNode.operationId),
|
|
@@ -1246,13 +1393,23 @@ const groupedClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1246
1393
|
baseName: file.baseName,
|
|
1247
1394
|
path: file.path,
|
|
1248
1395
|
meta: file.meta,
|
|
1249
|
-
banner: resolver.resolveBanner(
|
|
1396
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1250
1397
|
output,
|
|
1251
|
-
config
|
|
1398
|
+
config,
|
|
1399
|
+
file: {
|
|
1400
|
+
path: file.path,
|
|
1401
|
+
baseName: file.baseName,
|
|
1402
|
+
isAggregation: true
|
|
1403
|
+
}
|
|
1252
1404
|
}),
|
|
1253
|
-
footer: resolver.resolveFooter(
|
|
1405
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1254
1406
|
output,
|
|
1255
|
-
config
|
|
1407
|
+
config,
|
|
1408
|
+
file: {
|
|
1409
|
+
path: file.path,
|
|
1410
|
+
baseName: file.baseName,
|
|
1411
|
+
isAggregation: true
|
|
1412
|
+
}
|
|
1256
1413
|
}),
|
|
1257
1414
|
children: [clients.map((client) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1258
1415
|
name: [client.name],
|
|
@@ -1295,11 +1452,17 @@ function Operations({ name, nodes }) {
|
|
|
1295
1452
|
}
|
|
1296
1453
|
//#endregion
|
|
1297
1454
|
//#region src/generators/operationsGenerator.tsx
|
|
1455
|
+
/**
|
|
1456
|
+
* Generates an `operations.ts` file that re-exports every operation grouped
|
|
1457
|
+
* by HTTP method. Enabled when `pluginClient({ operations: true })`. Useful
|
|
1458
|
+
* for building meta-tooling on top of the generated client (route
|
|
1459
|
+
* registries, API explorers).
|
|
1460
|
+
*/
|
|
1298
1461
|
const operationsGenerator = (0, _kubb_core.defineGenerator)({
|
|
1299
1462
|
name: "client",
|
|
1300
|
-
renderer: _kubb_renderer_jsx.
|
|
1463
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
1301
1464
|
operations(nodes, ctx) {
|
|
1302
|
-
const { config, resolver,
|
|
1465
|
+
const { config, resolver, root } = ctx;
|
|
1303
1466
|
const { output, group } = ctx.options;
|
|
1304
1467
|
const name = "operations";
|
|
1305
1468
|
const file = resolver.resolveFile({
|
|
@@ -1308,19 +1471,27 @@ const operationsGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1308
1471
|
}, {
|
|
1309
1472
|
root,
|
|
1310
1473
|
output,
|
|
1311
|
-
group
|
|
1474
|
+
group: group ?? void 0
|
|
1312
1475
|
});
|
|
1313
1476
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File, {
|
|
1314
1477
|
baseName: file.baseName,
|
|
1315
1478
|
path: file.path,
|
|
1316
1479
|
meta: file.meta,
|
|
1317
|
-
banner: resolver.resolveBanner(
|
|
1480
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1318
1481
|
output,
|
|
1319
|
-
config
|
|
1482
|
+
config,
|
|
1483
|
+
file: {
|
|
1484
|
+
path: file.path,
|
|
1485
|
+
baseName: file.baseName
|
|
1486
|
+
}
|
|
1320
1487
|
}),
|
|
1321
|
-
footer: resolver.resolveFooter(
|
|
1488
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1322
1489
|
output,
|
|
1323
|
-
config
|
|
1490
|
+
config,
|
|
1491
|
+
file: {
|
|
1492
|
+
path: file.path,
|
|
1493
|
+
baseName: file.baseName
|
|
1494
|
+
}
|
|
1324
1495
|
}),
|
|
1325
1496
|
children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Operations, {
|
|
1326
1497
|
name,
|
|
@@ -1334,11 +1505,13 @@ const operationsGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1334
1505
|
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
1335
1506
|
function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataReturnType, parser, paramsType, paramsCasing, pathParamsType }) {
|
|
1336
1507
|
const path = new URLPath(node.path, { casing: paramsCasing });
|
|
1337
|
-
const contentType = node
|
|
1338
|
-
const isFormData = contentType === "multipart/form-data";
|
|
1339
|
-
const
|
|
1508
|
+
const { defaultContentType: contentType, isMultipleContentTypes, hasFormData } = getContentTypeInfo(node);
|
|
1509
|
+
const isFormData = !isMultipleContentTypes && contentType === "multipart/form-data";
|
|
1510
|
+
const { header: headerParams } = getOperationParameters(node);
|
|
1511
|
+
const headerParamsName = headerParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, headerParams[0]) : null;
|
|
1512
|
+
const headers = isMultipleContentTypes ? headerParamsName ? ["...headers"] : [] : buildHeaders(contentType, !!headerParamsName);
|
|
1340
1513
|
const generics = buildGenerics(node, tsResolver);
|
|
1341
|
-
const paramsNode =
|
|
1514
|
+
const paramsNode = buildClientParamsNode({
|
|
1342
1515
|
paramsType,
|
|
1343
1516
|
paramsCasing,
|
|
1344
1517
|
pathParamsType,
|
|
@@ -1353,15 +1526,21 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
|
|
|
1353
1526
|
baseURL,
|
|
1354
1527
|
tsResolver,
|
|
1355
1528
|
isFormData,
|
|
1529
|
+
isMultipleContentTypes,
|
|
1530
|
+
hasFormData,
|
|
1356
1531
|
headers
|
|
1357
1532
|
});
|
|
1358
|
-
const jsdoc = buildJSDoc(
|
|
1533
|
+
const jsdoc = buildJSDoc(buildOperationComments(node, {
|
|
1534
|
+
link: "urlPath",
|
|
1535
|
+
linkPosition: "beforeDeprecated",
|
|
1536
|
+
splitLines: true
|
|
1537
|
+
}));
|
|
1359
1538
|
const requestDataLine = buildRequestDataLine({
|
|
1360
1539
|
parser,
|
|
1361
1540
|
node,
|
|
1362
1541
|
zodResolver
|
|
1363
1542
|
});
|
|
1364
|
-
const formDataLine = buildFormDataLine(isFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
1543
|
+
const formDataLine = buildFormDataLine(isFormData || isMultipleContentTypes && hasFormData, !!node.requestBody?.content?.[0]?.schema);
|
|
1365
1544
|
const returnStatement = buildReturnStatement({
|
|
1366
1545
|
dataReturnType,
|
|
1367
1546
|
parser,
|
|
@@ -1369,7 +1548,7 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
|
|
|
1369
1548
|
zodResolver
|
|
1370
1549
|
});
|
|
1371
1550
|
return `${jsdoc} static async ${name}(${paramsSignature}) {\n${[
|
|
1372
|
-
|
|
1551
|
+
`const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
|
|
1373
1552
|
"",
|
|
1374
1553
|
requestDataLine,
|
|
1375
1554
|
formDataLine,
|
|
@@ -1397,35 +1576,33 @@ function StaticClassClient({ name, isExportable = true, isIndexable = true, oper
|
|
|
1397
1576
|
children: [classCode, children]
|
|
1398
1577
|
});
|
|
1399
1578
|
}
|
|
1400
|
-
StaticClassClient.getParams = Client.getParams;
|
|
1401
1579
|
//#endregion
|
|
1402
1580
|
//#region src/generators/staticClassClientGenerator.tsx
|
|
1403
1581
|
function resolveTypeImportNames(node, tsResolver) {
|
|
1404
|
-
return
|
|
1405
|
-
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
|
|
1406
|
-
tsResolver.resolveResponseName(node),
|
|
1407
|
-
...node.parameters.filter((p) => p.in === "path").map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
1408
|
-
...node.parameters.filter((p) => p.in === "query").map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
1409
|
-
...node.parameters.filter((p) => p.in === "header").map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
1410
|
-
...node.responses.map((res) => tsResolver.resolveResponseStatusName(node, res.statusCode))
|
|
1411
|
-
].filter((n) => Boolean(n));
|
|
1582
|
+
return resolveOperationTypeNames(node, tsResolver, { order: "body-response-first" });
|
|
1412
1583
|
}
|
|
1413
1584
|
function resolveZodImportNames(node, zodResolver) {
|
|
1414
|
-
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) :
|
|
1585
|
+
return [zodResolver.resolveResponseName?.(node), node.requestBody?.content?.[0]?.schema ? zodResolver.resolveDataName?.(node) : null].filter((n) => Boolean(n));
|
|
1415
1586
|
}
|
|
1587
|
+
/**
|
|
1588
|
+
* Built-in `operations` generator for `@kubb/plugin-client` when
|
|
1589
|
+
* `clientType: 'staticClass'`. Emits one class per tag, with a static method
|
|
1590
|
+
* per operation so callers can use `Pet.getPetById(...)` without
|
|
1591
|
+
* instantiating the class.
|
|
1592
|
+
*/
|
|
1416
1593
|
const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
1417
1594
|
name: "staticClassClient",
|
|
1418
|
-
renderer: _kubb_renderer_jsx.
|
|
1595
|
+
renderer: _kubb_renderer_jsx.jsxRendererSync,
|
|
1419
1596
|
operations(nodes, ctx) {
|
|
1420
|
-
const {
|
|
1597
|
+
const { config, driver, resolver, root } = ctx;
|
|
1421
1598
|
const { output, group, dataReturnType, paramsCasing, paramsType, pathParamsType, parser, importPath } = ctx.options;
|
|
1422
|
-
const baseURL = ctx.options.baseURL ??
|
|
1599
|
+
const baseURL = ctx.options.baseURL ?? ctx.meta.baseURL;
|
|
1423
1600
|
const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
|
|
1424
1601
|
if (!pluginTs) return null;
|
|
1425
1602
|
const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1426
1603
|
const tsPluginOptions = pluginTs.options;
|
|
1427
|
-
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) :
|
|
1428
|
-
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) :
|
|
1604
|
+
const pluginZod = parser === "zod" ? driver.getPlugin(_kubb_plugin_zod.pluginZodName) : null;
|
|
1605
|
+
const zodResolver = pluginZod ? driver.getResolver(_kubb_plugin_zod.pluginZodName) : null;
|
|
1429
1606
|
function buildOperationData(node) {
|
|
1430
1607
|
const typeFile = tsResolver.resolveFile({
|
|
1431
1608
|
name: node.operationId,
|
|
@@ -1445,8 +1622,8 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1445
1622
|
}, {
|
|
1446
1623
|
root,
|
|
1447
1624
|
output: pluginZod.options?.output ?? output,
|
|
1448
|
-
group: pluginZod.options?.group
|
|
1449
|
-
}) :
|
|
1625
|
+
group: pluginZod.options?.group ?? void 0
|
|
1626
|
+
}) : null;
|
|
1450
1627
|
return {
|
|
1451
1628
|
node,
|
|
1452
1629
|
name: resolver.resolveName(node.operationId),
|
|
@@ -1458,16 +1635,16 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1458
1635
|
}
|
|
1459
1636
|
const controllers = nodes.reduce((acc, operationNode) => {
|
|
1460
1637
|
const tag = operationNode.tags[0];
|
|
1461
|
-
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ??
|
|
1638
|
+
const groupName = tag ? group?.name?.({ group: camelCase(tag) }) ?? resolver.resolveGroupName(tag) : resolver.resolveGroupName("Client");
|
|
1462
1639
|
if (!tag && !group) {
|
|
1463
|
-
const name = "ApiClient";
|
|
1640
|
+
const name = resolver.resolveClassName("ApiClient");
|
|
1464
1641
|
const file = resolver.resolveFile({
|
|
1465
1642
|
name,
|
|
1466
1643
|
extname: ".ts"
|
|
1467
1644
|
}, {
|
|
1468
1645
|
root,
|
|
1469
1646
|
output,
|
|
1470
|
-
group
|
|
1647
|
+
group: group ?? void 0
|
|
1471
1648
|
});
|
|
1472
1649
|
const operationData = buildOperationData(operationNode);
|
|
1473
1650
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -1477,7 +1654,9 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1477
1654
|
file,
|
|
1478
1655
|
operations: [operationData]
|
|
1479
1656
|
});
|
|
1480
|
-
|
|
1657
|
+
return acc;
|
|
1658
|
+
}
|
|
1659
|
+
if (tag) {
|
|
1481
1660
|
const name = groupName;
|
|
1482
1661
|
const file = resolver.resolveFile({
|
|
1483
1662
|
name,
|
|
@@ -1486,7 +1665,7 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1486
1665
|
}, {
|
|
1487
1666
|
root,
|
|
1488
1667
|
output,
|
|
1489
|
-
group
|
|
1668
|
+
group: group ?? void 0
|
|
1490
1669
|
});
|
|
1491
1670
|
const operationData = buildOperationData(operationNode);
|
|
1492
1671
|
const previous = acc.find((item) => item.file.path === file.path);
|
|
@@ -1540,23 +1719,31 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1540
1719
|
zodImportsByFile: /* @__PURE__ */ new Map(),
|
|
1541
1720
|
zodFilesByPath: /* @__PURE__ */ new Map()
|
|
1542
1721
|
};
|
|
1543
|
-
const hasFormData = ops.some((op) => op.node.requestBody?.content?.
|
|
1722
|
+
const hasFormData = ops.some((op) => op.node.requestBody?.content?.some((e) => e.contentType === "multipart/form-data") ?? false);
|
|
1544
1723
|
return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
|
|
1545
1724
|
baseName: file.baseName,
|
|
1546
1725
|
path: file.path,
|
|
1547
1726
|
meta: file.meta,
|
|
1548
|
-
banner: resolver.resolveBanner(
|
|
1727
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
1549
1728
|
output,
|
|
1550
|
-
config
|
|
1729
|
+
config,
|
|
1730
|
+
file: {
|
|
1731
|
+
path: file.path,
|
|
1732
|
+
baseName: file.baseName
|
|
1733
|
+
}
|
|
1551
1734
|
}),
|
|
1552
|
-
footer: resolver.resolveFooter(
|
|
1735
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
1553
1736
|
output,
|
|
1554
|
-
config
|
|
1737
|
+
config,
|
|
1738
|
+
file: {
|
|
1739
|
+
path: file.path,
|
|
1740
|
+
baseName: file.baseName
|
|
1741
|
+
}
|
|
1555
1742
|
}),
|
|
1556
1743
|
children: [
|
|
1557
1744
|
importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
1558
1745
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1559
|
-
name: "
|
|
1746
|
+
name: "client",
|
|
1560
1747
|
path: importPath
|
|
1561
1748
|
}),
|
|
1562
1749
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
@@ -1574,7 +1761,7 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1574
1761
|
})
|
|
1575
1762
|
] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
|
|
1576
1763
|
/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
|
|
1577
|
-
name: ["
|
|
1764
|
+
name: ["client"],
|
|
1578
1765
|
root: file.path,
|
|
1579
1766
|
path: node_path.default.resolve(root, ".kubb/client.ts")
|
|
1580
1767
|
}),
|
|
@@ -1640,39 +1827,75 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
|
|
|
1640
1827
|
//#endregion
|
|
1641
1828
|
//#region src/resolvers/resolverClient.ts
|
|
1642
1829
|
/**
|
|
1643
|
-
*
|
|
1830
|
+
* Default resolver used by `@kubb/plugin-client`. Decides the names and file
|
|
1831
|
+
* paths for every generated client function or class. Functions and files use
|
|
1832
|
+
* camelCase; classes and tag groups use PascalCase.
|
|
1644
1833
|
*
|
|
1645
|
-
*
|
|
1834
|
+
* @example Resolve client function and class names
|
|
1835
|
+
* ```ts
|
|
1836
|
+
* import { resolverClient } from '@kubb/plugin-client'
|
|
1646
1837
|
*
|
|
1647
|
-
*
|
|
1648
|
-
*
|
|
1838
|
+
* resolverClient.default('list pets', 'function') // 'listPets'
|
|
1839
|
+
* resolverClient.resolveClassName('pet') // 'Pet'
|
|
1840
|
+
* resolverClient.resolveUrlName(operationNode) // 'getShowPetByIdUrl'
|
|
1841
|
+
* ```
|
|
1649
1842
|
*/
|
|
1650
|
-
const resolverClient = (0, _kubb_core.defineResolver)((
|
|
1843
|
+
const resolverClient = (0, _kubb_core.defineResolver)(() => ({
|
|
1651
1844
|
name: "default",
|
|
1652
1845
|
pluginName: "plugin-client",
|
|
1653
1846
|
default(name, type) {
|
|
1654
|
-
|
|
1847
|
+
const resolved = camelCase(name, { isFile: type === "file" });
|
|
1848
|
+
return type === "file" ? resolved : ensureValidVarName(resolved);
|
|
1655
1849
|
},
|
|
1656
1850
|
resolveName(name) {
|
|
1657
|
-
return
|
|
1851
|
+
return this.default(name, "function");
|
|
1852
|
+
},
|
|
1853
|
+
resolvePathName(name, type) {
|
|
1854
|
+
return this.default(name, type);
|
|
1855
|
+
},
|
|
1856
|
+
resolveClassName(name) {
|
|
1857
|
+
return ensureValidVarName(pascalCase(name));
|
|
1858
|
+
},
|
|
1859
|
+
resolveGroupName(name) {
|
|
1860
|
+
return ensureValidVarName(pascalCase(name));
|
|
1861
|
+
},
|
|
1862
|
+
resolveClientPropertyName(name) {
|
|
1863
|
+
return ensureValidVarName(camelCase(name));
|
|
1864
|
+
},
|
|
1865
|
+
resolveUrlName(node) {
|
|
1866
|
+
const name = this.resolveName(node.operationId);
|
|
1867
|
+
return `get${name.charAt(0).toUpperCase()}${name.slice(1)}Url`;
|
|
1658
1868
|
}
|
|
1659
1869
|
}));
|
|
1660
1870
|
//#endregion
|
|
1661
1871
|
//#region src/plugin.ts
|
|
1662
1872
|
/**
|
|
1663
|
-
* Canonical plugin name for `@kubb/plugin-client
|
|
1873
|
+
* Canonical plugin name for `@kubb/plugin-client`. Used for driver lookups and
|
|
1874
|
+
* cross-plugin dependency references.
|
|
1664
1875
|
*/
|
|
1665
1876
|
const pluginClientName = "plugin-client";
|
|
1666
1877
|
/**
|
|
1667
|
-
* Generates
|
|
1668
|
-
*
|
|
1669
|
-
*
|
|
1878
|
+
* Generates one HTTP client function per OpenAPI operation. Each function has
|
|
1879
|
+
* typed path params, query params, body, and response, so callers use the API
|
|
1880
|
+
* like any other typed function. Ships with `axios` and `fetch` runtimes; bring
|
|
1881
|
+
* your own by setting `importPath`.
|
|
1670
1882
|
*
|
|
1671
|
-
* @example
|
|
1883
|
+
* @example
|
|
1672
1884
|
* ```ts
|
|
1673
|
-
* import
|
|
1885
|
+
* import { defineConfig } from 'kubb'
|
|
1886
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1887
|
+
* import { pluginClient } from '@kubb/plugin-client'
|
|
1888
|
+
*
|
|
1674
1889
|
* export default defineConfig({
|
|
1675
|
-
*
|
|
1890
|
+
* input: { path: './petStore.yaml' },
|
|
1891
|
+
* output: { path: './src/gen' },
|
|
1892
|
+
* plugins: [
|
|
1893
|
+
* pluginTs(),
|
|
1894
|
+
* pluginClient({
|
|
1895
|
+
* output: { path: './clients' },
|
|
1896
|
+
* client: 'fetch',
|
|
1897
|
+
* }),
|
|
1898
|
+
* ],
|
|
1676
1899
|
* })
|
|
1677
1900
|
* ```
|
|
1678
1901
|
*/
|
|
@@ -1684,8 +1907,8 @@ const pluginClient = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1684
1907
|
const resolvedImportPath = importPath ?? (!bundle ? `@kubb/plugin-client/clients/${client}` : void 0);
|
|
1685
1908
|
const selectedGenerators = options.generators ?? [
|
|
1686
1909
|
clientType === "staticClass" ? staticClassClientGenerator : clientType === "class" ? classClientGenerator : clientGenerator,
|
|
1687
|
-
group && clientType === "function" ? groupedClientGenerator :
|
|
1688
|
-
operations ? operationsGenerator :
|
|
1910
|
+
group && clientType === "function" ? groupedClientGenerator : null,
|
|
1911
|
+
operations ? operationsGenerator : null
|
|
1689
1912
|
].filter((x) => Boolean(x));
|
|
1690
1913
|
const groupConfig = group ? {
|
|
1691
1914
|
...group,
|
|
@@ -1693,11 +1916,11 @@ const pluginClient = (0, _kubb_core.definePlugin)((options) => {
|
|
|
1693
1916
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
1694
1917
|
return `${camelCase(ctx.group)}Controller`;
|
|
1695
1918
|
}
|
|
1696
|
-
} :
|
|
1919
|
+
} : null;
|
|
1697
1920
|
return {
|
|
1698
1921
|
name: pluginClientName,
|
|
1699
1922
|
options,
|
|
1700
|
-
dependencies: [_kubb_plugin_ts.pluginTsName, parser === "zod" ? _kubb_plugin_zod.pluginZodName :
|
|
1923
|
+
dependencies: [_kubb_plugin_ts.pluginTsName, parser === "zod" ? _kubb_plugin_zod.pluginZodName : null].filter((dependency) => Boolean(dependency)),
|
|
1701
1924
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
1702
1925
|
const resolver = userResolver ? {
|
|
1703
1926
|
...resolverClient,
|