@kubb/plugin-fetch 5.0.0-beta.79 → 5.0.0-beta.81

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/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactory
7
7
  * - `'zod'`: validates the success (2xx) response body, and the error body when a non-2xx call does
8
8
  * not throw (`throwOnError: false`).
9
9
  * - `{ request?: 'zod'; response?: 'zod' }`: opt in per direction. `request` validates the request
10
- * body and query parameters before the call; `response` validates the success response body and,
10
+ * body before the call; `response` validates the success response body and,
11
11
  * on the non-throw path, the error body.
12
12
  */
13
13
  type ValidatorOptions = false | 'zod' | {
@@ -75,6 +75,8 @@ type Options = OutputOptions & {
75
75
  override?: Array<Override<ResolvedOptions>>;
76
76
  /**
77
77
  * Base URL prepended to every request. When omitted, falls back to the adapter's server URL.
78
+ * Values containing a `${...}` interpolation are emitted as template literals in the generated
79
+ * client config, which keeps runtime environment reads dynamic.
78
80
  */
79
81
  baseURL?: string;
80
82
  /**
package/dist/index.js CHANGED
@@ -430,6 +430,37 @@ function getResponseType(node) {
430
430
  if (baseType.startsWith("text/")) return "text";
431
431
  if (baseType === "application/octet-stream" || baseType === "application/pdf" || /^(image|audio|video)\//.test(baseType)) return "blob";
432
432
  }
433
+ /**
434
+ * Which of the grouped request options an operation carries.
435
+ */
436
+ function getRequestGroups(node) {
437
+ const { path, query, header } = getOperationParameters(node);
438
+ return {
439
+ path: path.length > 0,
440
+ query: query.length > 0,
441
+ body: Boolean(node.requestBody?.content?.[0]?.schema),
442
+ headers: header.length > 0
443
+ };
444
+ }
445
+ /**
446
+ * Resolves which grouped request options an operation carries together with whether each group
447
+ * holds a required member. The grouped parameter stays optional only when nothing inside it is
448
+ * required, matching the generated `RequestConfig` type.
449
+ */
450
+ function getRequestGroupOptionality(node) {
451
+ const groups = getRequestGroups(node);
452
+ const { path, query, header } = getOperationParameters(node);
453
+ const hasRequiredPath = path.some((param) => param.required);
454
+ const hasRequiredQuery = query.some((param) => param.required);
455
+ const hasRequiredHeader = header.some((param) => param.required);
456
+ return {
457
+ groups,
458
+ hasRequiredPath,
459
+ hasRequiredQuery,
460
+ hasRequiredHeader,
461
+ isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body
462
+ };
463
+ }
433
464
  function buildOperationComments(node, options = {}) {
434
465
  const { link = "pathTemplate", linkPosition = "afterDeprecated", splitLines = false } = options;
435
466
  const linkComment = getOperationLink(node, link);
@@ -679,11 +710,13 @@ function buildGroupedOptionsSignature({ node, tsResolver }) {
679
710
  node,
680
711
  tsResolver
681
712
  });
713
+ const { isOptional } = getRequestGroupOptionality(node);
682
714
  return {
683
715
  dataTypeName: requestConfigName,
684
716
  paramsSignature: declarationPrinter.print(createFunctionParameters({ params: [createFunctionParameter({
685
717
  name: "options",
686
- type: `Options<${requestConfigName}, ThrowOnError>`
718
+ type: `Options<${requestConfigName}, ThrowOnError>`,
719
+ ...isOptional ? { default: "{}" } : {}
687
720
  })] })) ?? "",
688
721
  returnType: `Promise<RequestResult<${resultGenerics}>>`,
689
722
  generics: ["ThrowOnError extends boolean = true"],
@@ -1420,6 +1453,7 @@ const pluginFetch = definePlugin((options) => {
1420
1453
  ctx.setMacros([...defaultMacros, ...options.macros ?? []]);
1421
1454
  ctx.addGenerator(...selectedGenerators);
1422
1455
  const root = path.resolve(ctx.config.root, ctx.config.output.path);
1456
+ const baseURLExpression = baseURL ? baseURL.includes("${") ? `\`${baseURL.replaceAll("`", "\\`")}\`` : JSON.stringify(baseURL) : void 0;
1423
1457
  ctx.injectFile({
1424
1458
  baseName: "serializers.ts",
1425
1459
  path: path.resolve(root, ".kubb/serializers.ts"),
@@ -1429,7 +1463,7 @@ const pluginFetch = definePlugin((options) => {
1429
1463
  baseName: "client.ts",
1430
1464
  path: path.resolve(root, ".kubb/client.ts"),
1431
1465
  copy: fetchClientTemplatePath,
1432
- footer: baseURL ? `client.setConfig({ baseURL: ${JSON.stringify(baseURL)} })` : void 0
1466
+ footer: baseURLExpression ? `client.setConfig({ baseURL: ${baseURLExpression} })` : void 0
1433
1467
  });
1434
1468
  ctx.injectFile({
1435
1469
  baseName: "standardSchema.ts",