@kubb/plugin-react-query 5.11.0-canary.20261111T200928 → 5.11.0-canary.20261112T123121

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
@@ -23,24 +23,130 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  value: mod,
24
24
  enumerable: true
25
25
  }) : target, mod));
26
+ let _kubb_kit = require("@kubb/kit");
26
27
  let node_path = require("node:path");
27
28
  node_path = __toESM(node_path, 1);
28
- let _kubb_kit = require("@kubb/kit");
29
29
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
30
30
  let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
31
31
  let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
32
32
  let node_fs = require("node:fs");
33
33
  node_fs = __toESM(node_fs, 1);
34
- // ../../internals/utils/src/casing.ts
34
+ // kubb-extension.json
35
+ var compatibility = {
36
+ "kubb": ">=5.18.4",
37
+ "node": ">=22.22"
38
+ };
39
+ // package.json
40
+ var version = "5.11.0-canary.20261112T123121";
41
+ // ../../internals/client/src/resolveClient.ts
42
+ /**
43
+ * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
44
+ * operation, shared so the selection rules and diagnostics stay in one place.
45
+ *
46
+ * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
47
+ * contract client plugin (plugin-fetch, plugin-axios, or plugin-client) and never emits its own
48
+ * inline client:
49
+ *
50
+ * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
51
+ * imports and calls them.
52
+ * - `error` — no client plugin is registered, several are registered without a selector, the
53
+ * requested one is missing, or `client` is not a known selector.
54
+ *
55
+ * The `client` string selects explicitly (`'fetch'` / `'axios'` / `'client'`); when it is unset a
56
+ * lone registered contract client plugin is picked up automatically.
57
+ */
58
+ const pluginFetchName = "plugin-fetch";
59
+ const pluginAxiosName = "plugin-axios";
60
+ const pluginClientName = "plugin-client";
61
+ const selectorToPlugin = {
62
+ fetch: pluginFetchName,
63
+ axios: pluginAxiosName,
64
+ client: pluginClientName
65
+ };
66
+ const contractPlugins = [
67
+ pluginFetchName,
68
+ pluginAxiosName,
69
+ pluginClientName
70
+ ];
35
71
  /**
36
- * Uppercases only the first character of `text`, leaving the rest untouched.
37
- * Unlike `pascalCase` it never re-splits word boundaries or strips characters.
72
+ * Applies the `client` resolution rules. See the module comment for the strategy shape.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })
77
+ * // { kind: 'contract', pluginName: 'plugin-fetch' }
78
+ * ```
38
79
  *
39
80
  * @example
40
- * `capitalize('getPetById') // 'GetPetById'`
81
+ * ```ts
82
+ * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
83
+ * // { kind: 'error', code: 'KUBB_MISSING_DEPENDENCY', message: 'No client plugin is registered.', help: 'Add …' }
84
+ * ```
41
85
  */
42
- function capitalize(text) {
43
- return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
86
+ function resolveClient(options) {
87
+ const { client, pluginNames } = options;
88
+ const has = (name) => pluginNames.includes(name);
89
+ if (client === "fetch" || client === "axios" || client === "client") {
90
+ const pluginName = selectorToPlugin[client];
91
+ if (!has(pluginName)) return {
92
+ kind: "error",
93
+ code: _kubb_kit.Diagnostics.code.missingDependency,
94
+ message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`.`,
95
+ help: `Add \`@kubb/plugin-${client}\` to \`plugins\`, or drop \`client\` to use a different client plugin.`
96
+ };
97
+ return {
98
+ kind: "contract",
99
+ pluginName
100
+ };
101
+ }
102
+ if (client !== void 0) return {
103
+ kind: "error",
104
+ code: _kubb_kit.Diagnostics.code.invalidPluginOptions,
105
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'.`,
106
+ help: "Set `client` to one of those values, or drop it to use the registered client plugin."
107
+ };
108
+ const registered = contractPlugins.filter(has);
109
+ if (registered.length === 1) return {
110
+ kind: "contract",
111
+ pluginName: registered[0]
112
+ };
113
+ if (registered.length > 1) return {
114
+ kind: "error",
115
+ code: _kubb_kit.Diagnostics.code.invalidPluginOptions,
116
+ message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}) and \`client\` is not set.`,
117
+ help: "Set `client: 'fetch' | 'axios' | 'client'` to choose which client the hooks call, or register a single client plugin."
118
+ };
119
+ return {
120
+ kind: "error",
121
+ code: _kubb_kit.Diagnostics.code.missingDependency,
122
+ message: "No client plugin is registered.",
123
+ help: "Add `@kubb/plugin-fetch`, `@kubb/plugin-axios`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
124
+ };
125
+ }
126
+ /**
127
+ * Resolves the contract client during a consumer plugin's setup hook.
128
+ * It extracts the plugin names from the raw `plugins` config and applies {@link resolveClient}.
129
+ * On a misconfiguration it throws a config diagnostic tagged with `plugin`, so every consumer
130
+ * fails fast with the same message.
131
+ */
132
+ function resolveContractClient(options) {
133
+ const { plugin, client, plugins = [] } = options;
134
+ const resolved = resolveClient({
135
+ client,
136
+ pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
137
+ });
138
+ if (resolved.kind === "error") {
139
+ const { code, message, help } = resolved;
140
+ throw new _kubb_kit.Diagnostics.Error({
141
+ code,
142
+ severity: "error",
143
+ message,
144
+ help,
145
+ location: { kind: "config" },
146
+ plugin
147
+ });
148
+ }
149
+ return resolved;
44
150
  }
45
151
  // ../../internals/utils/src/reserved.ts
46
152
  /**
@@ -183,18 +289,6 @@ function isIdentifier(name) {
183
289
  }
184
290
  // ../../internals/utils/src/strings.ts
185
291
  /**
186
- * Escapes an `@` at the start of a line, so a multi-line description can't start a new JSDoc tag.
187
- * Editors render `\@` as `@` in hovers.
188
- *
189
- * @example
190
- * ```ts
191
- * jsDocEscape('intro\n@example value') // 'intro\n\\@example value'
192
- * ```
193
- */
194
- function jsDocEscape(input) {
195
- return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
196
- }
197
- /**
198
292
  * Renders a dotted path or string array as an optional-chaining accessor expression rooted at
199
293
  * `accessor`. Returns `null` for an empty path.
200
294
  *
@@ -209,6 +303,18 @@ function getNestedAccessor(param, accessor) {
209
303
  if (parts.length === 0 || parts.length === 1 && parts[0] === "") return null;
210
304
  return `${accessor}?.['${`${parts.join("']?.['")}']`}`;
211
305
  }
306
+ /**
307
+ * Escapes an `@` at the start of a line, so a multi-line description can't start a new JSDoc tag.
308
+ * Editors render `\@` as `@` in hovers.
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * jsDocEscape('intro\n@example value') // 'intro\n\\@example value'
313
+ * ```
314
+ */
315
+ function jsDocEscape(input) {
316
+ return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
317
+ }
212
318
  // ../../internals/shared/src/operation.ts
213
319
  /**
214
320
  * Builds the `ResolverFileParams` every operation generator passes to
@@ -278,7 +384,7 @@ function resolveOperationFile(options) {
278
384
  * The operation's method and path as plain text, such as `` `GET /pet/{petId}` ``. A path is not a valid `{@link}` target.
279
385
  */
280
386
  function getOperationRequestLine(node) {
281
- return _kubb_kit.ast.isHttpOperationNode(node) && node.path ? `\`${node.method.toUpperCase()} ${node.path}\`` : null;
387
+ return _kubb_kit.ast.http.isOperation(node) && node.path ? `\`${node.method.toUpperCase()} ${node.path}\`` : null;
282
388
  }
283
389
  /**
284
390
  * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
@@ -302,21 +408,7 @@ function getContentTypeInfo(node) {
302
408
  * whether several are present, so the client can let a caller pick which one to accept.
303
409
  */
304
410
  function getResponseContentTypeInfo(node) {
305
- return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? []);
306
- }
307
- /**
308
- * The media type without its parameters, in lower case: `Text/Plain; charset=utf-8` gives `text/plain`.
309
- */
310
- function baseContentType(contentType) {
311
- return contentType.split(";")[0].trim().toLowerCase();
312
- }
313
- /**
314
- * Whether a content entry is a sequence of JSON values the adapter marks as a stream, such as `application/jsonl`,
315
- * `application/x-ndjson` or `application/json-seq`.
316
- */
317
- function isJsonLines(entry) {
318
- const baseType = baseContentType(entry.contentType);
319
- return Boolean(entry.stream) && baseType !== "text/event-stream" && isStreamContentType(baseType);
411
+ return buildContentTypeInfo(_kubb_kit.ast.http.responses.findPrimary(node)?.content?.map((e) => e.contentType) ?? []);
320
412
  }
321
413
  /**
322
414
  * How an operation streams its primary success response item by item, when that response declares one content type:
@@ -328,11 +420,19 @@ function isJsonLines(entry) {
328
420
  * call with its query hooks.
329
421
  */
330
422
  function getEventStream(node) {
331
- const content = getPrimarySuccessResponse(node)?.content ?? [];
423
+ const content = _kubb_kit.ast.http.responses.findPrimary(node)?.content ?? [];
332
424
  if (content.length !== 1) return null;
333
425
  const entry = content[0];
334
- if (baseContentType(entry.contentType) === "text/event-stream") return entry.stream?.shape ?? "data";
335
- return isJsonLines(entry) ? "line" : null;
426
+ const framing = getStreamFraming(entry);
427
+ if (framing === "events") return entry.stream?.shape ?? "data";
428
+ return framing === "lines" ? "line" : null;
429
+ }
430
+ /**
431
+ * How a content entry is framed as a stream: `'events'` for Server-Sent Events, `'lines'` for JSON Lines.
432
+ */
433
+ function getStreamFraming(entry) {
434
+ if (_kubb_kit.ast.mediaType.getBase(entry) === "text/event-stream") return "events";
435
+ return entry.stream && _kubb_kit.ast.mediaType.isStream(entry) ? "lines" : void 0;
336
436
  }
337
437
  /**
338
438
  * Whether an operation streams its primary success response, as Server-Sent Events or JSON Lines. The client generator uses
@@ -341,23 +441,14 @@ function getEventStream(node) {
341
441
  function isEventStream(node) {
342
442
  return getEventStream(node) !== null;
343
443
  }
344
- const streamContentTypes = /* @__PURE__ */ new Set([
345
- "text/event-stream",
346
- "application/jsonl",
347
- "application/x-ndjson",
348
- "application/json-seq"
349
- ]);
350
- function isStreamContentType(baseType) {
351
- return streamContentTypes.has(baseType) || baseType.startsWith("application/") && baseType.endsWith("+json-seq");
352
- }
353
444
  /**
354
445
  * Whether a success response offers a stream media type next to other content types. The client returns that variant's
355
446
  * body as a `ReadableStream`, so the stream runtime is registered and a hook's data type includes the stream.
356
447
  */
357
448
  function hasStreamVariant(node) {
358
- return getSuccessResponses(node.responses).some((response) => {
449
+ return _kubb_kit.ast.http.responses.filterSuccess(node).some((response) => {
359
450
  const variants = (response.content ?? []).filter((entry) => entry.schema);
360
- return variants.length > 1 && variants.some((entry) => isStreamContentType(baseContentType(entry.contentType)));
451
+ return variants.length > 1 && variants.some((entry) => _kubb_kit.ast.mediaType.isStream(entry));
361
452
  });
362
453
  }
363
454
  /**
@@ -401,11 +492,11 @@ const requestGroupOrder = [
401
492
  * Which of the grouped request options an operation carries.
402
493
  */
403
494
  function getRequestGroups(node) {
404
- const { path, query, header, cookie } = getOperationParameters(node);
495
+ const { path, query, header, cookie } = _kubb_kit.ast.http.groupParameters(node);
405
496
  return {
406
497
  path: path.length > 0,
407
498
  query: query.length > 0,
408
- body: Boolean(node.requestBody?.content?.[0]?.schema),
499
+ body: Boolean(_kubb_kit.ast.http.requestBody.getSchema(node)),
409
500
  headers: header.length > 0,
410
501
  cookies: cookie.length > 0
411
502
  };
@@ -417,7 +508,7 @@ function getRequestGroups(node) {
417
508
  */
418
509
  function getRequestGroupOptionality(node) {
419
510
  const groups = getRequestGroups(node);
420
- const { path, query, header } = getOperationParameters(node);
511
+ const { path, query, header } = _kubb_kit.ast.http.groupParameters(node);
421
512
  const hasRequiredPath = path.some((param) => param.required);
422
513
  const hasRequiredQuery = query.some((param) => param.required);
423
514
  const hasRequiredHeader = header.some((param) => param.required);
@@ -441,106 +532,17 @@ function buildOperationComments(node, options = {}) {
441
532
  if (!splitLines) return filteredComments;
442
533
  return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
443
534
  }
444
- const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
445
- /**
446
- * An OpenAPI 3.2 `querystring` parameter is the whole query string, so a form-encoded object becomes one query parameter
447
- * per property, typed and serialized like any other, with the `style` and `explode` its `encoding` entry declares.
448
- * Another content type, such as JSON, stays one parameter named after it, and the runtime sends its value as the whole query string.
449
- */
450
- function spreadQuerystring(param) {
451
- const schema = param.schema.type === "ref" ? param.schema.schema : param.schema;
452
- const formEncoded = !param.contentType || baseContentType(param.contentType) === "application/x-www-form-urlencoded";
453
- if (schema?.type !== "object" || !formEncoded) return [param];
454
- return schema.properties.map((property) => {
455
- const { style, explode, allowReserved } = param.encoding?.[property.name] ?? {};
456
- return _kubb_kit.ast.factory.createParameter({
457
- name: property.name,
458
- in: "query",
459
- schema: property.schema,
460
- required: param.required && property.required,
461
- ...style !== void 0 && { style },
462
- ...explode !== void 0 && { explode },
463
- ...allowReserved !== void 0 && { allowReserved }
464
- });
465
- });
466
- }
467
- /**
468
- * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
469
- * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
470
- * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
471
- * same parameters once per plugin.
472
- */
473
- function getOperationParameters(node) {
474
- const cached = operationParameterGroupsByNode.get(node);
475
- if (cached) return cached;
476
- const dedupe = (params) => {
477
- const seen = /* @__PURE__ */ new Set();
478
- return params.filter((param) => {
479
- if (seen.has(param.name)) return false;
480
- seen.add(param.name);
481
- return true;
482
- });
483
- };
484
- const group = (location) => dedupe(node.parameters.filter((param) => param.in === location));
485
- const groups = {
486
- path: group("path"),
487
- query: dedupe([...group("query"), ...group("querystring").flatMap(spreadQuerystring)]),
488
- header: group("header"),
489
- cookie: group("cookie")
490
- };
491
- operationParameterGroupsByNode.set(node, groups);
492
- return groups;
493
- }
494
535
  /**
495
536
  * Whether the operation declares more than one request media type with a schema, so a caller must pick one on `contentType`.
496
537
  */
497
538
  function hasRequestContentTypeChoice(node) {
498
539
  return (node.requestBody?.content ?? []).filter((entry) => entry.schema).length > 1;
499
540
  }
500
- function getStatusCodeNumber(statusCode) {
501
- const code = Number(statusCode);
502
- return Number.isNaN(code) ? null : code;
503
- }
504
- const statusClassByRange = /* @__PURE__ */ new Map([
505
- ["1xx", 1],
506
- ["2xx", 2],
507
- ["3xx", 3],
508
- ["4xx", 4],
509
- ["5xx", 5]
510
- ]);
511
- /**
512
- * The class digit of a status code or range, such as `2` for `201` and `2xx`, or `null` for `default`.
513
- */
514
- function getStatusClass(statusCode) {
515
- const rangeClass = statusClassByRange.get(String(statusCode));
516
- if (rangeClass) return rangeClass;
517
- const code = getStatusCodeNumber(statusCode);
518
- return code === null ? null : Math.floor(code / 100);
519
- }
520
- function isSuccessStatusCode(statusCode) {
521
- return getStatusClass(statusCode) === 2;
522
- }
523
- function isErrorStatusCode(statusCode) {
524
- const statusClass = getStatusClass(statusCode);
525
- return statusClass !== null && statusClass >= 4;
526
- }
527
- function getSuccessResponses(responses) {
528
- return responses.filter((response) => isSuccessStatusCode(response.statusCode));
529
- }
530
- function getOperationSuccessResponses(node) {
531
- return getSuccessResponses(node.responses);
532
- }
533
- function getPrimarySuccessResponse(node) {
534
- const responses = getOperationSuccessResponses(node);
535
- const withBody = responses.filter((response) => response.content?.length);
536
- const candidates = withBody.length ? withBody : responses;
537
- return candidates.find((response) => getStatusCodeNumber(response.statusCode) !== null) ?? candidates[0] ?? null;
538
- }
539
541
  function resolveErrorNames(node, resolver) {
540
- return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
542
+ return _kubb_kit.ast.http.responses.filterError(node).map((response) => resolver.response.status(node, response.statusCode));
541
543
  }
542
544
  function resolveSuccessNames(node, resolver) {
543
- return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode));
545
+ return _kubb_kit.ast.http.responses.filterSuccess(node).map((response) => resolver.response.status(node, response.statusCode));
544
546
  }
545
547
  function resolveStatusCodeNames(node, resolver) {
546
548
  return node.responses.map((response) => resolver.response.status(node, response.statusCode));
@@ -552,7 +554,7 @@ function resolveStatusCodeNames(node, resolver) {
552
554
  function resolveOperationTypeNames(node, resolver, options = {}) {
553
555
  const key = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
554
556
  return resolver.memo(`operationTypeNames:${key}`, () => {
555
- const { path, query, header, cookie } = getOperationParameters(node);
557
+ const { path, query, header, cookie } = _kubb_kit.ast.http.groupParameters(node);
556
558
  const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
557
559
  const exclude = new Set(options.exclude ?? []);
558
560
  const paramNames = options.includeParams === false ? [] : [
@@ -561,7 +563,7 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
561
563
  ...header.map((param) => resolver.param.headers(node, param)),
562
564
  ...cookie.map((param) => resolver.param.cookies(node, param))
563
565
  ];
564
- const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)];
566
+ const bodyAndResponseNames = [_kubb_kit.ast.http.requestBody.getSchema(node) ? resolver.response.body(node) : null, resolver.response.response(node)];
565
567
  return (options.order === "body-response-first" ? [
566
568
  ...bodyAndResponseNames,
567
569
  ...paramNames,
@@ -578,7 +580,7 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
578
580
  * The shared top-level `name` of the operation plugins, computed once per operation name and build.
579
581
  */
580
582
  function resolveOperationName(name) {
581
- return this.memo(`operation:${name}`, () => ensureValidVarName((0, _kubb_kit.camelCase)(name)));
583
+ return this.memo(`operation:${name}`, () => ensureValidVarName(_kubb_kit.casing.camel(name)));
582
584
  }
583
585
  /**
584
586
  * Builds the allocation key for a declaration an operation owns. `scope` names which declaration
@@ -600,151 +602,6 @@ function operationKey(node, ...scope) {
600
602
  ...scope.map(String)
601
603
  ];
602
604
  }
603
- // ../../internals/shared/src/group.ts
604
- /**
605
- * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
606
- * shared default naming so every plugin groups output consistently:
607
- *
608
- * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
609
- * - `tag` groups get no name here, so Kubb names them itself: the camelCased tag (`pet store` → `petStore`), nested in
610
- * the folders of its OpenAPI 3.2 `parent` tags (`payment` with parent `store` → `store/payment`).
611
- *
612
- * A user-provided `group.name` always wins over the default namer, so callers stay in
613
- * control of their output folders. Returns `null` when grouping is disabled, matching the
614
- * per-plugin convention.
615
- *
616
- * @param group - The user-supplied group option, or `undefined` to disable grouping.
617
- *
618
- * @example
619
- * ```ts
620
- * createGroupConfig(group) // shared across every plugin
621
- * ```
622
- */
623
- function createGroupConfig(group) {
624
- if (!group) return null;
625
- if (group.name || group.type !== "path") return group;
626
- return {
627
- ...group,
628
- name: (ctx) => `${ctx.group.split("/")[1]}`
629
- };
630
- }
631
- // kubb-extension.json
632
- var compatibility = {
633
- "kubb": ">=5.18.4",
634
- "node": ">=22.22"
635
- };
636
- // package.json
637
- var version = "5.11.0-canary.20261111T200928";
638
- // ../../internals/client/src/resolveClient.ts
639
- /**
640
- * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
641
- * operation, shared so the selection rules and diagnostics stay in one place.
642
- *
643
- * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
644
- * contract client plugin (plugin-fetch, plugin-axios, or plugin-client) and never emits its own
645
- * inline client:
646
- *
647
- * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
648
- * imports and calls them.
649
- * - `error` — no client plugin is registered, several are registered without a selector, the
650
- * requested one is missing, or `client` is not a known selector.
651
- *
652
- * The `client` string selects explicitly (`'fetch'` / `'axios'` / `'client'`); when it is unset a
653
- * lone registered contract client plugin is picked up automatically.
654
- */
655
- const pluginFetchName = "plugin-fetch";
656
- const pluginAxiosName = "plugin-axios";
657
- const pluginClientName = "plugin-client";
658
- const selectorToPlugin = {
659
- fetch: pluginFetchName,
660
- axios: pluginAxiosName,
661
- client: pluginClientName
662
- };
663
- const contractPlugins = [
664
- pluginFetchName,
665
- pluginAxiosName,
666
- pluginClientName
667
- ];
668
- /**
669
- * Applies the `client` resolution rules. See the module comment for the strategy shape.
670
- *
671
- * @example
672
- * ```ts
673
- * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })
674
- * // { kind: 'contract', pluginName: 'plugin-fetch' }
675
- * ```
676
- *
677
- * @example
678
- * ```ts
679
- * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })
680
- * // { kind: 'error', code: 'KUBB_MISSING_DEPENDENCY', message: 'No client plugin is registered.', help: 'Add …' }
681
- * ```
682
- */
683
- function resolveClient(options) {
684
- const { client, pluginNames } = options;
685
- const has = (name) => pluginNames.includes(name);
686
- if (client === "fetch" || client === "axios" || client === "client") {
687
- const pluginName = selectorToPlugin[client];
688
- if (!has(pluginName)) return {
689
- kind: "error",
690
- code: _kubb_kit.Diagnostics.code.missingDependency,
691
- message: `\`client: '${client}'\` is set but \`@kubb/plugin-${client}\` is not registered in \`plugins\`.`,
692
- help: `Add \`@kubb/plugin-${client}\` to \`plugins\`, or drop \`client\` to use a different client plugin.`
693
- };
694
- return {
695
- kind: "contract",
696
- pluginName
697
- };
698
- }
699
- if (client !== void 0) return {
700
- kind: "error",
701
- code: _kubb_kit.Diagnostics.code.invalidPluginOptions,
702
- message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios', 'client'.`,
703
- help: "Set `client` to one of those values, or drop it to use the registered client plugin."
704
- };
705
- const registered = contractPlugins.filter(has);
706
- if (registered.length === 1) return {
707
- kind: "contract",
708
- pluginName: registered[0]
709
- };
710
- if (registered.length > 1) return {
711
- kind: "error",
712
- code: _kubb_kit.Diagnostics.code.invalidPluginOptions,
713
- message: `Multiple client plugins are registered (${registered.map((name) => `\`@kubb/${name}\``).join(", ")}) and \`client\` is not set.`,
714
- help: "Set `client: 'fetch' | 'axios' | 'client'` to choose which client the hooks call, or register a single client plugin."
715
- };
716
- return {
717
- kind: "error",
718
- code: _kubb_kit.Diagnostics.code.missingDependency,
719
- message: "No client plugin is registered.",
720
- help: "Add `@kubb/plugin-fetch`, `@kubb/plugin-axios`, or `@kubb/plugin-client` to `plugins` so the generated code has an HTTP client to call."
721
- };
722
- }
723
- /**
724
- * Resolves the contract client during a consumer plugin's setup hook.
725
- * It extracts the plugin names from the raw `plugins` config and applies {@link resolveClient}.
726
- * On a misconfiguration it throws a config diagnostic tagged with `plugin`, so every consumer
727
- * fails fast with the same message.
728
- */
729
- function resolveContractClient(options) {
730
- const { plugin, client, plugins = [] } = options;
731
- const resolved = resolveClient({
732
- client,
733
- pluginNames: plugins.map((plugin) => plugin.name).filter((name) => Boolean(name))
734
- });
735
- if (resolved.kind === "error") {
736
- const { code, message, help } = resolved;
737
- throw new _kubb_kit.Diagnostics.Error({
738
- code,
739
- severity: "error",
740
- message,
741
- help,
742
- location: { kind: "config" },
743
- plugin
744
- });
745
- }
746
- return resolved;
747
- }
748
605
  // ../../internals/client/src/resolveClientOperation.ts
749
606
  function isRelativeImport(importPath) {
750
607
  return importPath.startsWith(".");
@@ -1198,7 +1055,7 @@ function resolveFallbackPageParamType(initialPageParam) {
1198
1055
  * so callers can reuse it when rewriting the paginated request.
1199
1056
  */
1200
1057
  function resolvePageParamType(node, { resolver, initialPageParam, queryParam }) {
1201
- const firstQueryParam = getOperationParameters(node).query[0];
1058
+ const firstQueryParam = _kubb_kit.ast.http.groupParameters(node).query[0];
1202
1059
  const groupName = firstQueryParam ? resolver.param.query(node, firstQueryParam) : null;
1203
1060
  const queryParamsTypeName = groupName !== (firstQueryParam ? resolver.param.name(node, firstQueryParam) : null) ? groupName : null;
1204
1061
  const queryParamType = queryParam && queryParamsTypeName ? `${queryParamsTypeName}['${queryParam}']` : null;
@@ -1301,7 +1158,7 @@ function resolveInfiniteConfig(infinite) {
1301
1158
  */
1302
1159
  function matchesInfinite(node, infinite) {
1303
1160
  if (!infinite.queryParam) return false;
1304
- return getOperationParameters(node).query.some((param) => param.name.replace(/\?$/, "") === infinite.queryParam);
1161
+ return _kubb_kit.ast.http.groupParameters(node).query.some((param) => param.name.replace(/\?$/, "") === infinite.queryParam);
1305
1162
  }
1306
1163
  /**
1307
1164
  * Warning for an infinite hook that falls back to the built-in page params on a response that
@@ -1309,8 +1166,8 @@ function matchesInfinite(node, infinite) {
1309
1166
  */
1310
1167
  function getDefaultPageParamsWarning(node, infinite) {
1311
1168
  if (!(infinite.getNextPageParam == null && infinite.getPreviousPageParam == null && infinite.nextParam == null && infinite.previousParam == null && !infinite.cursorParam)) return null;
1312
- const content = getPrimarySuccessResponse(node)?.content;
1313
- let resolved = (content?.find((item) => item.contentType?.includes("json")) ?? content?.[0])?.schema;
1169
+ const content = _kubb_kit.ast.http.responses.findPrimary(node)?.content;
1170
+ let resolved = (content?.find((item) => _kubb_kit.ast.mediaType.isJson(item)) ?? content?.[0])?.schema;
1314
1171
  while (resolved?.type === "ref" || resolved?.type === "intersection" && resolved.members?.length === 1) resolved = resolved.type === "ref" ? resolved.schema : resolved.members?.[0];
1315
1172
  if (!resolved || resolved.type === "array") return null;
1316
1173
  return `${node.operationId}: the default infinite page params expect an array response and never end for this one. Set \`infinite.getNextPageParam\` (or \`nextParam\`) to read the next page from the response.`;
@@ -1555,7 +1412,7 @@ function MutationKey({ name, node, transformer, typeName }) {
1555
1412
  function createQueryResolver(variant = "") {
1556
1413
  return {
1557
1414
  name(node) {
1558
- const name = `use${capitalize(this.name(node.operationId))}${variant}`;
1415
+ const name = `use${_kubb_kit.casing.capitalize(this.name(node.operationId))}${variant}`;
1559
1416
  return this.resolveName({
1560
1417
  key: operationKey(node, "query", variant, "name"),
1561
1418
  name
@@ -1576,7 +1433,7 @@ function createQueryResolver(variant = "") {
1576
1433
  });
1577
1434
  },
1578
1435
  keyTypeName(node) {
1579
- const name = `${capitalize(this.name(node.operationId))}${variant}QueryKey`;
1436
+ const name = `${_kubb_kit.casing.capitalize(this.name(node.operationId))}${variant}QueryKey`;
1580
1437
  return this.resolveName({
1581
1438
  key: operationKey(node, "query", variant, "keyTypeName"),
1582
1439
  name
@@ -1597,7 +1454,7 @@ function createQueryResolver(variant = "") {
1597
1454
  function createMutationResolver() {
1598
1455
  return {
1599
1456
  name(node) {
1600
- const name = `use${capitalize(this.name(node.operationId))}`;
1457
+ const name = `use${_kubb_kit.casing.capitalize(this.name(node.operationId))}`;
1601
1458
  return this.resolveName({
1602
1459
  key: operationKey(node, "mutation", "name"),
1603
1460
  name
@@ -1626,14 +1483,14 @@ const declarationPrinter$4 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "decla
1626
1483
  */
1627
1484
  const queryKeyTransformer = ({ node, variant }) => {
1628
1485
  if (!node.path) return [];
1629
- const { path, query } = getOperationParameters(node);
1486
+ const { path, query } = _kubb_kit.ast.http.groupParameters(node);
1630
1487
  const isInfinite = variant === "infiniteQuery" || variant === "suspenseInfiniteQuery";
1631
1488
  const urlFields = [`url: '${_kubb_kit.Url.toPath(node.path)}'`];
1632
1489
  if (path.length > 0) urlFields.push("params: path");
1633
1490
  if (isInfinite) urlFields.push("infinite: true");
1634
1491
  const result = [`{ ${urlFields.join(", ")} }`];
1635
1492
  if (query.length > 0) result.push("...(query ? [query] : [])");
1636
- if (node.requestBody?.content?.[0]?.schema) result.push("...(body !== undefined ? [body] : [])");
1493
+ if (_kubb_kit.ast.http.requestBody.getSchema(node)) result.push("...(body !== undefined ? [body] : [])");
1637
1494
  return result;
1638
1495
  };
1639
1496
  function QueryKey({ name, node, tsResolver, typeName, transformer, variant = "query", memberTypeWrapper, exportType }) {
@@ -1797,7 +1654,7 @@ const hookOptionsGenerator = (0, _kubb_kit.defineGenerator)({
1797
1654
  const imports = [];
1798
1655
  const hookOptions = {};
1799
1656
  for (const node of nodes) {
1800
- if (!_kubb_kit.ast.isHttpOperationNode(node)) continue;
1657
+ if (!_kubb_kit.ast.http.isOperation(node)) continue;
1801
1658
  const opOverrides = resolveOperationOverrides(node, override);
1802
1659
  const nodeQuery = "query" in opOverrides ? opOverrides.query : query;
1803
1660
  const nodeMutation = "mutation" in opOverrides ? opOverrides.mutation : mutation;
@@ -2041,7 +1898,7 @@ function createQueryGenerator({ name, variant }) {
2041
1898
  renderer: _kubb_renderer_jsx.jsxRenderer,
2042
1899
  match(node, ctx) {
2043
1900
  const operationNode = node;
2044
- if (!_kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
1901
+ if (!_kubb_kit.ast.http.isOperation(operationNode)) return false;
2045
1902
  const { query, mutation, infinite: infiniteConfig, suspense: suspenseConfig, hooks } = ctx.options;
2046
1903
  const { isQuery, isMutation } = classifyOperation(operationNode, {
2047
1904
  query,
@@ -2056,7 +1913,7 @@ function createQueryGenerator({ name, variant }) {
2056
1913
  return !!infiniteOptions && matchesInfinite(operationNode, infiniteOptions);
2057
1914
  },
2058
1915
  operation(node, ctx) {
2059
- if (!_kubb_kit.ast.isHttpOperationNode(node)) return null;
1916
+ if (!_kubb_kit.ast.http.isOperation(node)) return null;
2060
1917
  const { driver, resolver, root } = ctx;
2061
1918
  const { output, query, infinite: infiniteConfig, client, group, customOptions, hooks } = ctx.options;
2062
1919
  const infiniteOptions = infinite && infiniteConfig && typeof infiniteConfig === "object" ? infiniteConfig : null;
@@ -2332,7 +2189,7 @@ const mutationGenerator = (0, _kubb_kit.defineGenerator)({
2332
2189
  renderer: _kubb_renderer_jsx.jsxRenderer,
2333
2190
  match(node, ctx) {
2334
2191
  const operationNode = node;
2335
- if (!_kubb_kit.ast.isHttpOperationNode(operationNode)) return false;
2192
+ if (!_kubb_kit.ast.http.isOperation(operationNode)) return false;
2336
2193
  const { query, mutation } = ctx.options;
2337
2194
  return classifyOperation(operationNode, {
2338
2195
  query,
@@ -2340,7 +2197,7 @@ const mutationGenerator = (0, _kubb_kit.defineGenerator)({
2340
2197
  }).isMutation;
2341
2198
  },
2342
2199
  operation(node, ctx) {
2343
- if (!_kubb_kit.ast.isHttpOperationNode(node)) return null;
2200
+ if (!_kubb_kit.ast.http.isOperation(node)) return null;
2344
2201
  const { driver, resolver, root } = ctx;
2345
2202
  const { output, mutation, client, group, customOptions, hooks } = ctx.options;
2346
2203
  const importPath = mutation ? mutation.importPath : "@tanstack/react-query";
@@ -2571,7 +2428,7 @@ const pluginReactQuery = (0, _kubb_kit.defineExtension)({
2571
2428
  ...customOptions
2572
2429
  } : null,
2573
2430
  hooks,
2574
- group: createGroupConfig(group),
2431
+ group: group ?? null,
2575
2432
  exclude,
2576
2433
  include,
2577
2434
  override,