@kubb/plugin-react-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.cjs +74 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +74 -32
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
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
|
|
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
|
-
|
|
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
|
-
|
|
151
|
+
validator: NonNullable<Options$1['validator']>;
|
|
152
152
|
sdk: {
|
|
153
153
|
mode: Mode;
|
|
154
154
|
name: string | undefined;
|
|
@@ -470,7 +470,7 @@ type Options = OutputOptions & {
|
|
|
470
470
|
* - `'client'` — no validation. Trusts the API.
|
|
471
471
|
* - `'zod'` — pipes responses through schemas from `@kubb/plugin-zod`.
|
|
472
472
|
*/
|
|
473
|
-
|
|
473
|
+
validator?: Options$1['validator'];
|
|
474
474
|
/**
|
|
475
475
|
* Override how hook names and file paths are built. Methods you omit fall
|
|
476
476
|
* back to the default `resolverReactQuery`.
|
|
@@ -499,7 +499,7 @@ type ResolvedOptions = {
|
|
|
499
499
|
* The resolved contract client the generators import and call.
|
|
500
500
|
*/
|
|
501
501
|
client: ResolvedClient;
|
|
502
|
-
|
|
502
|
+
validator: NonNullable<Options['validator']>;
|
|
503
503
|
/**
|
|
504
504
|
* Only used for infinite
|
|
505
505
|
*/
|
package/dist/index.js
CHANGED
|
@@ -64,7 +64,7 @@ function toFilePath(name, caseLast = camelCase) {
|
|
|
64
64
|
* JavaScript and Java reserved words.
|
|
65
65
|
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
66
66
|
*/
|
|
67
|
-
const reservedWords = new Set([
|
|
67
|
+
const reservedWords = /* @__PURE__ */ new Set([
|
|
68
68
|
"abstract",
|
|
69
69
|
"arguments",
|
|
70
70
|
"boolean",
|
|
@@ -293,6 +293,23 @@ function caseParams(params, casing) {
|
|
|
293
293
|
caseParamsCache.set(params, result);
|
|
294
294
|
return result;
|
|
295
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Drops parameters that collapse to the same property identity once camelCased, keeping the first.
|
|
298
|
+
*
|
|
299
|
+
* Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
|
|
300
|
+
* `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
|
|
301
|
+
* an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
|
|
302
|
+
* identity so the resulting group is collision-free regardless of the names each caller carries.
|
|
303
|
+
*/
|
|
304
|
+
function dedupeByCasedName(params) {
|
|
305
|
+
const seen = /* @__PURE__ */ new Set();
|
|
306
|
+
return params.filter((param) => {
|
|
307
|
+
const key = camelCase(param.name);
|
|
308
|
+
if (seen.has(key)) return false;
|
|
309
|
+
seen.add(key);
|
|
310
|
+
return true;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
296
313
|
//#endregion
|
|
297
314
|
//#region ../../internals/shared/src/operation.ts
|
|
298
315
|
/**
|
|
@@ -331,11 +348,27 @@ function getContentTypeInfo(node) {
|
|
|
331
348
|
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
332
349
|
};
|
|
333
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* The request-body counterpart for the primary success response: the content types it documents and
|
|
353
|
+
* whether several are present, so the client can let a caller pick which one to accept.
|
|
354
|
+
*/
|
|
355
|
+
function getResponseContentTypeInfo(node) {
|
|
356
|
+
const contentTypes = getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [];
|
|
357
|
+
const isMultipleContentTypes = contentTypes.length > 1;
|
|
358
|
+
return {
|
|
359
|
+
contentTypes,
|
|
360
|
+
isMultipleContentTypes,
|
|
361
|
+
contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(" | ") : "",
|
|
362
|
+
defaultContentType: contentTypes[0] ?? "application/json",
|
|
363
|
+
hasFormData: contentTypes.some((ct) => ct === "multipart/form-data")
|
|
364
|
+
};
|
|
365
|
+
}
|
|
334
366
|
function buildRequestConfigType(node) {
|
|
335
|
-
const
|
|
367
|
+
const request = getContentTypeInfo(node);
|
|
368
|
+
const response = getResponseContentTypeInfo(node);
|
|
336
369
|
const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`;
|
|
337
|
-
const
|
|
338
|
-
return
|
|
370
|
+
const members = [request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null, response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null].filter(Boolean);
|
|
371
|
+
return members.length ? `${configType} & { contentType?: { ${members.join("; ")} } }` : configType;
|
|
339
372
|
}
|
|
340
373
|
/**
|
|
341
374
|
* Builds the `client?:` option type shared by the generated query hooks (`useQuery`,
|
|
@@ -397,10 +430,10 @@ function buildOperationComments(node, options = {}) {
|
|
|
397
430
|
function getOperationParameters(node, options = {}) {
|
|
398
431
|
const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
|
|
399
432
|
return {
|
|
400
|
-
path: params.filter((param) => param.in === "path"),
|
|
401
|
-
query: params.filter((param) => param.in === "query"),
|
|
402
|
-
header: params.filter((param) => param.in === "header"),
|
|
403
|
-
cookie: params.filter((param) => param.in === "cookie")
|
|
433
|
+
path: dedupeByCasedName(params.filter((param) => param.in === "path")),
|
|
434
|
+
query: dedupeByCasedName(params.filter((param) => param.in === "query")),
|
|
435
|
+
header: dedupeByCasedName(params.filter((param) => param.in === "header")),
|
|
436
|
+
cookie: dedupeByCasedName(params.filter((param) => param.in === "cookie"))
|
|
404
437
|
};
|
|
405
438
|
}
|
|
406
439
|
function getStatusCodeNumber(statusCode) {
|
|
@@ -415,6 +448,15 @@ function isErrorStatusCode(statusCode) {
|
|
|
415
448
|
const code = getStatusCodeNumber(statusCode);
|
|
416
449
|
return code !== null && code >= 400;
|
|
417
450
|
}
|
|
451
|
+
function getSuccessResponses(responses) {
|
|
452
|
+
return responses.filter((response) => isSuccessStatusCode(response.statusCode));
|
|
453
|
+
}
|
|
454
|
+
function getOperationSuccessResponses(node) {
|
|
455
|
+
return getSuccessResponses(node.responses);
|
|
456
|
+
}
|
|
457
|
+
function getPrimarySuccessResponse(node) {
|
|
458
|
+
return getOperationSuccessResponses(node)[0] ?? null;
|
|
459
|
+
}
|
|
418
460
|
function resolveErrorNames(node, resolver) {
|
|
419
461
|
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
420
462
|
}
|
|
@@ -488,14 +530,14 @@ function createGroupConfig(group) {
|
|
|
488
530
|
};
|
|
489
531
|
}
|
|
490
532
|
//#endregion
|
|
491
|
-
//#region ../../internals/client/src/builders/
|
|
533
|
+
//#region ../../internals/client/src/builders/validatorOptions.ts
|
|
492
534
|
/**
|
|
493
|
-
* Returns `true` when any direction of the
|
|
535
|
+
* Returns `true` when any direction of the validator uses zod (used for dependency checks).
|
|
494
536
|
*/
|
|
495
|
-
function
|
|
496
|
-
if (!
|
|
497
|
-
if (
|
|
498
|
-
return Boolean(
|
|
537
|
+
function isValidatorEnabled(validator) {
|
|
538
|
+
if (!validator) return false;
|
|
539
|
+
if (validator === "zod") return true;
|
|
540
|
+
return Boolean(validator.request || validator.response);
|
|
499
541
|
}
|
|
500
542
|
//#endregion
|
|
501
543
|
//#region ../../internals/client/src/resolveClient.ts
|
|
@@ -1743,7 +1785,7 @@ const infiniteQueryGenerator = defineGenerator({
|
|
|
1743
1785
|
operation(node, ctx) {
|
|
1744
1786
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
1745
1787
|
const { config, driver, resolver, root } = ctx;
|
|
1746
|
-
const { output, query, mutation, infinite,
|
|
1788
|
+
const { output, query, mutation, infinite, validator, client, group, customOptions } = ctx.options;
|
|
1747
1789
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1748
1790
|
if (!pluginTs) return null;
|
|
1749
1791
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
@@ -1793,14 +1835,14 @@ const infiniteQueryGenerator = defineGenerator({
|
|
|
1793
1835
|
includeParams: false
|
|
1794
1836
|
})
|
|
1795
1837
|
].filter((name) => Boolean(name));
|
|
1796
|
-
const pluginZod =
|
|
1838
|
+
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
1797
1839
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1798
1840
|
const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
1799
1841
|
root,
|
|
1800
1842
|
output: pluginZod?.options?.output ?? output,
|
|
1801
1843
|
group: pluginZod?.options?.group ?? void 0
|
|
1802
1844
|
}) : null;
|
|
1803
|
-
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver,
|
|
1845
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
|
|
1804
1846
|
const calledClientName = contractOp.name;
|
|
1805
1847
|
return /* @__PURE__ */ jsxs(File, {
|
|
1806
1848
|
baseName: meta.file.baseName,
|
|
@@ -1919,7 +1961,7 @@ const mutationGenerator = defineGenerator({
|
|
|
1919
1961
|
operation(node, ctx) {
|
|
1920
1962
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
1921
1963
|
const { config, driver, resolver, root } = ctx;
|
|
1922
|
-
const { output, query, mutation,
|
|
1964
|
+
const { output, query, mutation, validator, client, group, customOptions } = ctx.options;
|
|
1923
1965
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
1924
1966
|
if (!pluginTs) return null;
|
|
1925
1967
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
@@ -1955,14 +1997,14 @@ const mutationGenerator = defineGenerator({
|
|
|
1955
1997
|
order: "body-response-first",
|
|
1956
1998
|
includeParams: false
|
|
1957
1999
|
})].filter((name) => Boolean(name));
|
|
1958
|
-
const pluginZod =
|
|
2000
|
+
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
1959
2001
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
1960
2002
|
const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
1961
2003
|
root,
|
|
1962
2004
|
output: pluginZod?.options?.output ?? output,
|
|
1963
2005
|
group: pluginZod?.options?.group ?? void 0
|
|
1964
2006
|
}) : null;
|
|
1965
|
-
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver,
|
|
2007
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
|
|
1966
2008
|
const calledClientName = contractOp.name;
|
|
1967
2009
|
return /* @__PURE__ */ jsxs(File, {
|
|
1968
2010
|
baseName: meta.file.baseName,
|
|
@@ -2068,7 +2110,7 @@ const queryGenerator = defineGenerator({
|
|
|
2068
2110
|
operation(node, ctx) {
|
|
2069
2111
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
2070
2112
|
const { config, driver, resolver, root } = ctx;
|
|
2071
|
-
const { output, query, mutation,
|
|
2113
|
+
const { output, query, mutation, validator, client, group, customOptions } = ctx.options;
|
|
2072
2114
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
2073
2115
|
if (!pluginTs) return null;
|
|
2074
2116
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
@@ -2106,14 +2148,14 @@ const queryGenerator = defineGenerator({
|
|
|
2106
2148
|
order: "body-response-first",
|
|
2107
2149
|
includeParams: false
|
|
2108
2150
|
})].filter((name) => Boolean(name));
|
|
2109
|
-
const pluginZod =
|
|
2151
|
+
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
2110
2152
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
2111
2153
|
const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
2112
2154
|
root,
|
|
2113
2155
|
output: pluginZod?.options?.output ?? output,
|
|
2114
2156
|
group: pluginZod?.options?.group ?? void 0
|
|
2115
2157
|
}) : null;
|
|
2116
|
-
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver,
|
|
2158
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
|
|
2117
2159
|
const calledClientName = contractOp.name;
|
|
2118
2160
|
return /* @__PURE__ */ jsxs(File, {
|
|
2119
2161
|
baseName: meta.file.baseName,
|
|
@@ -2223,7 +2265,7 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
|
|
|
2223
2265
|
operation(node, ctx) {
|
|
2224
2266
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
2225
2267
|
const { config, driver, resolver, root } = ctx;
|
|
2226
|
-
const { output, query, mutation, infinite, suspense,
|
|
2268
|
+
const { output, query, mutation, infinite, suspense, validator, client, group, customOptions } = ctx.options;
|
|
2227
2269
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
2228
2270
|
if (!pluginTs) return null;
|
|
2229
2271
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
@@ -2273,14 +2315,14 @@ const suspenseInfiniteQueryGenerator = defineGenerator({
|
|
|
2273
2315
|
includeParams: false
|
|
2274
2316
|
})
|
|
2275
2317
|
].filter((name) => Boolean(name));
|
|
2276
|
-
const pluginZod =
|
|
2318
|
+
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
2277
2319
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
2278
2320
|
const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
2279
2321
|
root,
|
|
2280
2322
|
output: pluginZod?.options?.output ?? output,
|
|
2281
2323
|
group: pluginZod?.options?.group ?? void 0
|
|
2282
2324
|
}) : null;
|
|
2283
|
-
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver,
|
|
2325
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
|
|
2284
2326
|
const calledClientName = contractOp.name;
|
|
2285
2327
|
return /* @__PURE__ */ jsxs(File, {
|
|
2286
2328
|
baseName: meta.file.baseName,
|
|
@@ -2400,7 +2442,7 @@ const suspenseQueryGenerator = defineGenerator({
|
|
|
2400
2442
|
operation(node, ctx) {
|
|
2401
2443
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
2402
2444
|
const { config, driver, resolver, root } = ctx;
|
|
2403
|
-
const { output, query, mutation, suspense,
|
|
2445
|
+
const { output, query, mutation, suspense, validator, client, group, customOptions } = ctx.options;
|
|
2404
2446
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
2405
2447
|
if (!pluginTs) return null;
|
|
2406
2448
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
@@ -2438,14 +2480,14 @@ const suspenseQueryGenerator = defineGenerator({
|
|
|
2438
2480
|
order: "body-response-first",
|
|
2439
2481
|
includeParams: false
|
|
2440
2482
|
})].filter((name) => Boolean(name));
|
|
2441
|
-
const pluginZod =
|
|
2483
|
+
const pluginZod = isValidatorEnabled(validator) ? driver.getPlugin(pluginZodName) : null;
|
|
2442
2484
|
const zodResolver = pluginZod ? driver.getResolver(pluginZodName) : null;
|
|
2443
2485
|
const fileZod = zodResolver ? zodResolver.resolveFile(operationFileEntry(node, node.operationId), {
|
|
2444
2486
|
root,
|
|
2445
2487
|
output: pluginZod?.options?.output ?? output,
|
|
2446
2488
|
group: pluginZod?.options?.group ?? void 0
|
|
2447
2489
|
}) : null;
|
|
2448
|
-
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver,
|
|
2490
|
+
const zodSchemaNames = resolveZodSchemaNames(node, zodResolver, validator);
|
|
2449
2491
|
const calledClientName = contractOp.name;
|
|
2450
2492
|
return /* @__PURE__ */ jsxs(File, {
|
|
2451
2493
|
baseName: meta.file.baseName,
|
|
@@ -2692,7 +2734,7 @@ const pluginReactQuery = definePlugin((options) => {
|
|
|
2692
2734
|
const { output = {
|
|
2693
2735
|
path: "hooks",
|
|
2694
2736
|
barrel: { type: "named" }
|
|
2695
|
-
}, group, exclude = [], include, override = [],
|
|
2737
|
+
}, group, exclude = [], include, override = [], validator = false, suspense = {}, infinite = false, mutation = {}, query = {}, mutationKey = mutationKeyTransformer, queryKey = queryKeyTransformer, customOptions, client, resolver: userResolver, macros: userMacros } = options;
|
|
2696
2738
|
const selectedGenerators = [
|
|
2697
2739
|
queryGenerator,
|
|
2698
2740
|
suspenseQueryGenerator,
|
|
@@ -2706,7 +2748,7 @@ const pluginReactQuery = definePlugin((options) => {
|
|
|
2706
2748
|
return {
|
|
2707
2749
|
name: pluginReactQueryName,
|
|
2708
2750
|
options,
|
|
2709
|
-
dependencies: [pluginTsName,
|
|
2751
|
+
dependencies: [pluginTsName, isValidatorEnabled(validator) ? pluginZodName : void 0].filter((dependency) => Boolean(dependency)),
|
|
2710
2752
|
hooks: { "kubb:plugin:setup"(ctx) {
|
|
2711
2753
|
const resolver = userResolver ? {
|
|
2712
2754
|
...resolverReactQuery,
|
|
@@ -2754,7 +2796,7 @@ const pluginReactQuery = definePlugin((options) => {
|
|
|
2754
2796
|
name: "useCustomHookOptions",
|
|
2755
2797
|
...customOptions
|
|
2756
2798
|
} : null,
|
|
2757
|
-
|
|
2799
|
+
validator,
|
|
2758
2800
|
group: groupConfig,
|
|
2759
2801
|
exclude,
|
|
2760
2802
|
include,
|