@kubb/plugin-vue-query 5.0.0-beta.77 → 5.0.0-beta.79

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
@@ -10,7 +10,7 @@ import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactory
10
10
  * body and query parameters before the call; `response` validates the success response body and,
11
11
  * on the non-throw path, the error body.
12
12
  */
13
- type ParserOptions = false | 'zod' | {
13
+ type ValidatorOptions = false | 'zod' | {
14
14
  request?: 'zod';
15
15
  response?: 'zod';
16
16
  };
@@ -82,7 +82,7 @@ type Options$1 = OutputOptions & {
82
82
  *
83
83
  * @default false
84
84
  */
85
- parser?: ParserOptions;
85
+ validator?: ValidatorOptions;
86
86
  /**
87
87
  * Generates a class-based SDK instead of the standalone functions. Each tag client is an instance
88
88
  * class whose constructor takes a client config and builds its own client, so every environment is
@@ -148,7 +148,7 @@ type ResolvedOptions$1 = {
148
148
  override: Array<Override<ResolvedOptions$1>>;
149
149
  group: Group | null;
150
150
  baseURL: Options$1['baseURL'];
151
- parser: NonNullable<Options$1['parser']>;
151
+ validator: NonNullable<Options$1['validator']>;
152
152
  sdk: {
153
153
  mode: Mode;
154
154
  name: string | undefined;
@@ -382,7 +382,7 @@ type Options = OutputOptions & {
382
382
  * - `'client'` — no validation.
383
383
  * - `'zod'` — pipes responses through schemas from `@kubb/plugin-zod`.
384
384
  */
385
- parser?: Options$1['parser'];
385
+ validator?: Options$1['validator'];
386
386
  /**
387
387
  * Override how composable names and file paths are built.
388
388
  */
@@ -410,7 +410,7 @@ type ResolvedOptions = {
410
410
  * The resolved contract client the generators import and call.
411
411
  */
412
412
  client: ResolvedClient;
413
- parser: NonNullable<Options['parser']>;
413
+ validator: NonNullable<Options['validator']>;
414
414
  /**
415
415
  * Only used for infinite
416
416
  */
package/dist/index.js CHANGED
@@ -63,7 +63,7 @@ function toFilePath(name, caseLast = camelCase) {
63
63
  * JavaScript and Java reserved words.
64
64
  * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
65
65
  */
66
- const reservedWords = new Set([
66
+ const reservedWords = /* @__PURE__ */ new Set([
67
67
  "abstract",
68
68
  "arguments",
69
69
  "boolean",
@@ -292,6 +292,23 @@ function caseParams(params, casing) {
292
292
  caseParamsCache.set(params, result);
293
293
  return result;
294
294
  }
295
+ /**
296
+ * Drops parameters that collapse to the same property identity once camelCased, keeping the first.
297
+ *
298
+ * Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
299
+ * `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
300
+ * an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
301
+ * identity so the resulting group is collision-free regardless of the names each caller carries.
302
+ */
303
+ function dedupeByCasedName(params) {
304
+ const seen = /* @__PURE__ */ new Set();
305
+ return params.filter((param) => {
306
+ const key = camelCase(param.name);
307
+ if (seen.has(key)) return false;
308
+ seen.add(key);
309
+ return true;
310
+ });
311
+ }
295
312
  //#endregion
296
313
  //#region ../../internals/shared/src/operation.ts
297
314
  /**
@@ -330,11 +347,27 @@ function getContentTypeInfo(node) {
330
347
  hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
331
348
  };
332
349
  }
350
+ /**
351
+ * The request-body counterpart for the primary success response: the content types it documents and
352
+ * whether several are present, so the client can let a caller pick which one to accept.
353
+ */
354
+ function getResponseContentTypeInfo(node) {
355
+ const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
356
+ const isMultipleContentTypes = contentTypes.length > 1;
357
+ return {
358
+ contentTypes,
359
+ isMultipleContentTypes,
360
+ contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
361
+ defaultContentType: contentTypes[0] ?? "application/json",
362
+ hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
363
+ };
364
+ }
333
365
  function buildRequestConfigType(node) {
334
- const { isMultipleContentTypes, contentTypeUnion } = getContentTypeInfo(node);
366
+ const request = getContentTypeInfo(node);
367
+ const response = getResponseContentTypeInfo(node);
335
368
  const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
336
- const contentTypeProp = isMultipleContentTypes ? `contentType?: ${contentTypeUnion}` : null;
337
- return contentTypeProp ? `${configType} & { ${contentTypeProp} }` : configType;
369
+ const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
370
+ return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
338
371
  }
339
372
  /**
340
373
  * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
@@ -396,10 +429,10 @@ function buildOperationComments(node, options = {}) {
396
429
  function getOperationParameters(node, options = {}) {
397
430
  const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
398
431
  return {
399
- path: params.filter((param) => param.in === "path"),
400
- query: params.filter((param) => param.in === "query"),
401
- header: params.filter((param) => param.in === "header"),
402
- cookie: params.filter((param) => param.in === "cookie")
432
+ path: dedupeByCasedName(params.filter((param) => param.in === "path")),
433
+ query: dedupeByCasedName(params.filter((param) => param.in === "query")),
434
+ header: dedupeByCasedName(params.filter((param) => param.in === "header")),
435
+ cookie: dedupeByCasedName(params.filter((param) => param.in === "cookie"))
403
436
  };
404
437
  }
405
438
  function getStatusCodeNumber(statusCode) {
@@ -414,6 +447,15 @@ function isErrorStatusCode(statusCode) {
414
447
  const code = getStatusCodeNumber(statusCode);
415
448
  return code !== null && code >= 400;
416
449
  }
450
+ function getSuccessResponses(responses) {
451
+ return responses.filter((response) => isSuccessStatusCode(response.statusCode));
452
+ }
453
+ function getOperationSuccessResponses(node) {
454
+ return getSuccessResponses(node.responses);
455
+ }
456
+ function getPrimarySuccessResponse(node) {
457
+ return getOperationSuccessResponses(node)[0] ?? null;
458
+ }
417
459
  function resolveErrorNames(node, resolver) {
418
460
  return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
419
461
  }
@@ -487,14 +529,14 @@ function createGroupConfig(group) {
487
529
  };
488
530
  }
489
531
  //#endregion
490
- //#region ../../internals/client/src/builders/parser.ts
532
+ //#region ../../internals/client/src/builders/validatorOptions.ts
491
533
  /**
492
- * Returns `true` when any direction of the parser uses zod (used for dependency checks).
534
+ * Returns `true` when any direction of the validator uses zod (used for dependency checks).
493
535
  */
494
- function isParserEnabled(parser) {
495
- if (!parser) return false;
496
- if (parser === "zod") return true;
497
- return Boolean(parser.request || parser.response);
536
+ function isValidatorEnabled(validator) {
537
+ if (!validator) return false;
538
+ if (validator === "zod") return true;
539
+ return Boolean(validator.request || validator.response);
498
540
  }
499
541
  //#endregion
500
542
  //#region ../../internals/client/src/resolveClient.ts
@@ -1199,7 +1241,7 @@ const infiniteQueryGenerator = defineGenerator({
1199
1241
  operation(node, ctx) {
1200
1242
  if (!ast.isHttpOperationNode(node)) return null;
1201
1243
  const { config, driver, resolver, root } = ctx;
1202
- const { output, query, mutation, infinite, parser, client, group } = ctx.options;
1244
+ const { output, query, mutation, infinite, validator, client, group } = ctx.options;
1203
1245
  const pluginTs = driver.getPlugin(pluginTsName);
1204
1246
  if (!pluginTs) return null;
1205
1247
  const tsResolver = driver.getResolver(pluginTsName);
@@ -1249,14 +1291,14 @@ const infiniteQueryGenerator = defineGenerator({
1249
1291
  includeParams: false
1250
1292
  })
1251
1293
  ].filter((name) => Boolean(name));
1252
- const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
1294
+ const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
1253
1295
  const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
1254
1296
  const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1255
1297
  root,
1256
1298
  output: pluginZod?.options?.output ?? output,
1257
1299
  group: pluginZod?.options?.group ?? void 0
1258
1300
  }) : null;
1259
- const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
1301
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
1260
1302
  const calledClientName = contractOp.name;
1261
1303
  return /* @__PURE__ */ jsxs(File, {
1262
1304
  baseName: meta.file.baseName,
@@ -1379,7 +1421,7 @@ const mutationGenerator = defineGenerator({
1379
1421
  operation(node, ctx) {
1380
1422
  if (!ast.isHttpOperationNode(node)) return null;
1381
1423
  const { config, driver, resolver, root } = ctx;
1382
- const { output, query, mutation, parser, client, group } = ctx.options;
1424
+ const { output, query, mutation, validator, client, group } = ctx.options;
1383
1425
  const pluginTs = driver.getPlugin(pluginTsName);
1384
1426
  if (!pluginTs) return null;
1385
1427
  const tsResolver = driver.getResolver(pluginTsName);
@@ -1414,14 +1456,14 @@ const mutationGenerator = defineGenerator({
1414
1456
  order: "body-response-first",
1415
1457
  includeParams: false
1416
1458
  })].filter((name) => Boolean(name));
1417
- const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
1459
+ const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
1418
1460
  const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
1419
1461
  const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1420
1462
  root,
1421
1463
  output: pluginZod?.options?.output ?? output,
1422
1464
  group: pluginZod?.options?.group ?? void 0
1423
1465
  }) : null;
1424
- const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
1466
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
1425
1467
  const calledClientName = contractOp.name;
1426
1468
  const groups = getRequestGroups(node);
1427
1469
  const hasRequestGroups = groups.path || groups.query || groups.body || groups.headers;
@@ -1518,7 +1560,7 @@ const queryGenerator = defineGenerator({
1518
1560
  operation(node, ctx) {
1519
1561
  if (!ast.isHttpOperationNode(node)) return null;
1520
1562
  const { config, driver, resolver, root } = ctx;
1521
- const { output, query, mutation, parser, client, group } = ctx.options;
1563
+ const { output, query, mutation, validator, client, group } = ctx.options;
1522
1564
  const pluginTs = driver.getPlugin(pluginTsName);
1523
1565
  if (!pluginTs) return null;
1524
1566
  const tsResolver = driver.getResolver(pluginTsName);
@@ -1556,14 +1598,14 @@ const queryGenerator = defineGenerator({
1556
1598
  order: "body-response-first",
1557
1599
  includeParams: false
1558
1600
  })].filter((name) => Boolean(name));
1559
- const pluginZod = isParserEnabled(parser) ? driver.getPlugin(pluginZodName) : null;
1601
+ const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
1560
1602
  const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
1561
1603
  const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
1562
1604
  root,
1563
1605
  output: pluginZod?.options?.output ?? output,
1564
1606
  group: pluginZod?.options?.group ?? void 0
1565
1607
  }) : null;
1566
- const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, parser);
1608
+ const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
1567
1609
  const calledClientName = contractOp.name;
1568
1610
  return /* @__PURE__ */ jsxs(File, {
1569
1611
  baseName: meta.file.baseName,
@@ -1771,7 +1813,7 @@ const pluginVueQuery = definePlugin((options) => {
1771
1813
  const { output = {
1772
1814
  path: "hooks",
1773
1815
  barrel: { type: "named" }
1774
- }, group, exclude = [], include, override = [], parser = false, infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, client, resolver: userResolver, macros: userMacros } = options;
1816
+ }, group, exclude = [], include, override = [], validator = false, infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, client, resolver: userResolver, macros: userMacros } = options;
1775
1817
  const selectedGenerators = [
1776
1818
  queryGenerator,
1777
1819
  infiniteQueryGenerator,
@@ -1781,7 +1823,7 @@ const pluginVueQuery = definePlugin((options) => {
1781
1823
  return {
1782
1824
  name: pluginVueQueryName,
1783
1825
  options,
1784
- dependencies: [pluginTsName, isParserEnabled(parser) ? pluginZodName : void 0].filter((dependency) => Boolean(dependency)),
1826
+ dependencies: [pluginTsName, isValidatorEnabled(validator) ? pluginZodName : void 0].filter((dependency) => Boolean(dependency)),
1785
1827
  hooks: { "kubb:plugin:setup"(ctx) {
1786
1828
  const resolver = userResolver ? {
1787
1829
  ...resolverVueQuery,
@@ -1824,7 +1866,7 @@ const pluginVueQuery = definePlugin((options) => {
1824
1866
  previousParam: null,
1825
1867
  ...infinite
1826
1868
  } : false,
1827
- parser,
1869
+ validator,
1828
1870
  group: groupConfig,
1829
1871
  exclude,
1830
1872
  include,