@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 +163 -306
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +163 -306
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
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
|
-
//
|
|
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
|
-
*
|
|
37
|
-
*
|
|
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
|
-
*
|
|
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
|
|
43
|
-
|
|
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.
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
335
|
-
|
|
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
|
|
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) =>
|
|
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 } =
|
|
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(
|
|
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 } =
|
|
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
|
|
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
|
|
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 } =
|
|
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 = [
|
|
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(
|
|
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 =
|
|
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
|
|
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 =
|
|
1313
|
-
let resolved = (content?.find((item) =>
|
|
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 } =
|
|
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 (
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
2431
|
+
group: group ?? null,
|
|
2575
2432
|
exclude,
|
|
2576
2433
|
include,
|
|
2577
2434
|
override,
|