@kubb/plugin-react-query 5.7.0-canary.20261025T201031 → 5.8.0-canary.20261025T213931

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.cjs CHANGED
@@ -193,6 +193,22 @@ function getOperationParameters(node) {
193
193
  operationParameterGroupsByNode.set(node, groups);
194
194
  return groups;
195
195
  }
196
+ /**
197
+ * Builds the combined `{ body, path, query, headers }` options object schema for an operation,
198
+ * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s
199
+ * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same
200
+ * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod
201
+ * printer to emit `z.object(…)` rather than a record.
202
+ */
203
+ function hasRequestContentTypeChoice(node) {
204
+ return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
205
+ }
206
+ /**
207
+ * Casts a call argument to the client's parameter type; a `'plain'` client is non-generic.
208
+ */
209
+ function castToClientOptions(callArg, clientName, returnType = "full") {
210
+ return `${callArg} as Parameters<typeof ${clientName}${returnType === "plain" ? "" : "<true>"}>[0]`;
211
+ }
196
212
  function getStatusCodeNumber(statusCode) {
197
213
  const code = Number(statusCode);
198
214
  return Number.isNaN(code) ? null : code;
@@ -304,6 +320,146 @@ function capitalize(text) {
304
320
  return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
305
321
  }
306
322
  //#endregion
323
+ //#region ../../internals/utils/src/reserved.ts
324
+ /**
325
+ * JavaScript and Java reserved words.
326
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
327
+ */
328
+ const reservedWords = /* @__PURE__ */ new Set([
329
+ "abstract",
330
+ "arguments",
331
+ "await",
332
+ "boolean",
333
+ "break",
334
+ "byte",
335
+ "case",
336
+ "catch",
337
+ "char",
338
+ "class",
339
+ "const",
340
+ "continue",
341
+ "debugger",
342
+ "default",
343
+ "delete",
344
+ "do",
345
+ "double",
346
+ "else",
347
+ "enum",
348
+ "eval",
349
+ "export",
350
+ "extends",
351
+ "false",
352
+ "final",
353
+ "finally",
354
+ "float",
355
+ "for",
356
+ "function",
357
+ "goto",
358
+ "if",
359
+ "implements",
360
+ "import",
361
+ "in",
362
+ "instanceof",
363
+ "int",
364
+ "interface",
365
+ "let",
366
+ "long",
367
+ "native",
368
+ "new",
369
+ "null",
370
+ "package",
371
+ "private",
372
+ "protected",
373
+ "public",
374
+ "return",
375
+ "short",
376
+ "static",
377
+ "super",
378
+ "switch",
379
+ "synchronized",
380
+ "this",
381
+ "throw",
382
+ "throws",
383
+ "transient",
384
+ "true",
385
+ "try",
386
+ "typeof",
387
+ "var",
388
+ "void",
389
+ "volatile",
390
+ "while",
391
+ "with",
392
+ "yield",
393
+ "Array",
394
+ "Date",
395
+ "hasOwnProperty",
396
+ "Infinity",
397
+ "isFinite",
398
+ "isNaN",
399
+ "isPrototypeOf",
400
+ "length",
401
+ "Math",
402
+ "name",
403
+ "NaN",
404
+ "Number",
405
+ "Object",
406
+ "prototype",
407
+ "String",
408
+ "toString",
409
+ "undefined",
410
+ "valueOf"
411
+ ]);
412
+ /**
413
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
414
+ *
415
+ * @example
416
+ * ```ts
417
+ * isValidVarName('status') // true
418
+ * isValidVarName('class') // false (reserved word)
419
+ * isValidVarName('42foo') // false (starts with digit)
420
+ * ```
421
+ */
422
+ function isValidVarName(name) {
423
+ if (!name || reservedWords.has(name)) return false;
424
+ return isIdentifier(name);
425
+ }
426
+ /**
427
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
428
+ * otherwise prefixes it with `_` so the result is a valid identifier.
429
+ *
430
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
431
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
432
+ * variable, type, or function names.
433
+ *
434
+ * @example
435
+ * ```ts
436
+ * ensureValidVarName('409') // '_409'
437
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
438
+ * ensureValidVarName('Pet') // 'Pet'
439
+ * ensureValidVarName('class') // '_class'
440
+ * ```
441
+ */
442
+ function ensureValidVarName(name) {
443
+ if (!name || isValidVarName(name)) return name;
444
+ return `_${name}`;
445
+ }
446
+ /**
447
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
448
+ *
449
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
450
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
451
+ * deciding whether an object key needs quoting.
452
+ *
453
+ * @example
454
+ * ```ts
455
+ * isIdentifier('name') // true
456
+ * isIdentifier('x-total')// false
457
+ * ```
458
+ */
459
+ function isIdentifier(name) {
460
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
461
+ }
462
+ //#endregion
307
463
  //#region ../../internals/utils/src/strings.ts
308
464
  /**
309
465
  * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
@@ -321,6 +477,11 @@ function getNestedAccessor(param, accessor) {
321
477
  return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
322
478
  }
323
479
  //#endregion
480
+ //#region ../../internals/shared/src/resolver.ts
481
+ function resolveOperationName(name) {
482
+ return ensureValidVarName(camelCase(name));
483
+ }
484
+ //#endregion
324
485
  //#region ../../internals/shared/src/group.ts
325
486
  /**
326
487
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
@@ -359,7 +520,7 @@ var compatibility = {
359
520
  };
360
521
  //#endregion
361
522
  //#region package.json
362
- var version = "5.7.0-canary.20261025T201031";
523
+ var version = "5.8.0-canary.20261025T213931";
363
524
  //#endregion
364
525
  //#region ../../internals/client/src/resolveOperationTypes.ts
365
526
  /**
@@ -715,7 +876,7 @@ function maybeValueOrGetter(type) {
715
876
  * `MaybeRefOrGetter` per group.
716
877
  */
717
878
  function buildGroupedRequestParam(node, options) {
718
- const { resolver, keys = requestGroupOrder, memberTypeWrapper } = options;
879
+ const { resolver, keys = requestGroupOrder, memberTypeWrapper, withContentType = false } = options;
719
880
  const { groups, hasRequiredPath, hasRequiredQuery, hasRequiredHeader } = getRequestGroupOptionality(node);
720
881
  const names = keys.filter((key) => groups[key]);
721
882
  if (names.length === 0) return null;
@@ -727,6 +888,11 @@ function buildGroupedRequestParam(node, options) {
727
888
  };
728
889
  const isOptional = names.every((name) => !requiredByGroup[name]);
729
890
  const optionsName = resolver.response.options(node);
891
+ if (withContentType && hasRequestContentTypeChoice(node)) return (0, _kubb_plugin_ts.createFunctionParameter)({
892
+ name: "variables",
893
+ type: optionsName,
894
+ optional: false
895
+ });
730
896
  const omittedKeys = requestGroupOrder.filter((key) => !keys.includes(key));
731
897
  const optionsType = omittedKeys.length > 0 ? `Omit<${optionsName}, ${omittedKeys.map((key) => `'${key}'`).join(" | ")}>` : optionsName;
732
898
  if (memberTypeWrapper) {
@@ -784,14 +950,17 @@ function buildQueryOptionsParams(node, options) {
784
950
  * ```
785
951
  */
786
952
  function buildClientCall(node, options) {
787
- const { clientName, signal = false, unwrapName } = options;
953
+ const { clientName, signal = false, unwrapName, withContentType = false, returnType = "full" } = options;
788
954
  const { groups } = getRequestGroupOptionality(node);
789
- return `${clientName}({ ${[
955
+ const names = requestGroupOrder.filter((key) => groups[key]);
956
+ const args = [
790
957
  "...config",
791
- ...requestGroupOrder.filter((key) => groups[key]).map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
958
+ ...withContentType && hasRequestContentTypeChoice(node) ? ["...variables"] : names.map((name) => unwrapName ? `${name}: ${unwrapName(name)}` : name),
792
959
  signal ? "signal: config.signal ?? signal" : null,
793
960
  "throwOnError: true"
794
- ].filter((part) => part !== null).join(", ")} })`;
961
+ ].filter((part) => part !== null);
962
+ if (withContentType && hasRequestContentTypeChoice(node)) return `${clientName}(${castToClientOptions(`{ ${args.join(", ")} }`, clientName, returnType)})`;
963
+ return `${clientName}({ ${args.join(", ")} })`;
795
964
  }
796
965
  /**
797
966
  * Builds the query/mutation body that resolves a `buildClientCall` expression down to the bare
@@ -1870,14 +2039,19 @@ function MutationOptions({ name, clientName, node, tsResolver, mutationKeyName,
1870
2039
  const { TData, TError } = buildResponseTypes(node, tsResolver);
1871
2040
  const configParamsNode = buildMutationConfigParamsNode(node);
1872
2041
  const paramsSignature = declarationPrinter$1.print(configParamsNode) ?? "";
1873
- const groupedParam = buildGroupedRequestParam(node, { resolver: tsResolver });
2042
+ const groupedParam = buildGroupedRequestParam(node, {
2043
+ resolver: tsResolver,
2044
+ withContentType: true
2045
+ });
1874
2046
  const hasMutationParams = groupedParam !== null;
1875
2047
  const groupedParamsNode = (0, _kubb_plugin_ts.createFunctionParameters)({ params: groupedParam ? [groupedParam] : [] });
1876
2048
  const TRequest = hasMutationParams ? tsResolver.response.options(node) : "undefined";
1877
2049
  const argBindingStr = hasMutationParams ? callPrinter$1.print(groupedParamsNode) ?? "" : "_";
1878
2050
  const mutationFnBody = buildCallResultBody(buildClientCall(node, {
1879
2051
  clientName,
1880
- signal: false
2052
+ signal: false,
2053
+ withContentType: true,
2054
+ returnType
1881
2055
  }), { returnType });
1882
2056
  return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
1883
2057
  name,
@@ -2098,7 +2272,7 @@ const suspenseQueryGenerator = createQueryGenerator({
2098
2272
  * `useFooSuspense`, `useFooInfinite`, ...) and its companion helpers
2099
2273
  * (`fooQueryKey`, `fooQueryOptions`).
2100
2274
  *
2101
- * Functions and files use the built-in camelCase casing; hooks get the `use`
2275
+ * Functions use safe camelCase identifiers; hooks get the `use`
2102
2276
  * prefix; suspense and infinite variants are suffixed with `Suspense`/`Infinite`.
2103
2277
  *
2104
2278
  * @example Resolve hook and helper names
@@ -2113,6 +2287,7 @@ const suspenseQueryGenerator = createQueryGenerator({
2113
2287
  */
2114
2288
  const resolverReactQuery = (0, kubb_kit.createResolver)({
2115
2289
  pluginName: "plugin-react-query",
2290
+ name: resolveOperationName,
2116
2291
  query: createQueryResolver(),
2117
2292
  suspenseQuery: createQueryResolver("Suspense"),
2118
2293
  infiniteQuery: createQueryResolver("Infinite"),