@kubb/plugin-client 6.1.0-canary.20261109T175349 → 6.1.0-canary.20261109T175913
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/{client-D0IfSe5q.d.ts → client-DaI8VaEz.d.ts} +2 -3
- package/dist/index.cjs +43 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -36
- package/dist/index.js.map +1 -1
- package/dist/templates/client.d.ts +1 -1
- package/dist/templates/core.d.ts +1 -1
- package/dist/templates/sse.d.ts +1 -1
- package/docs/guides/validate-requests-and-responses.md +7 -4
- package/package.json +5 -5
- package/templates/core.ts +9 -9
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { M as SuccessOf, m as DataShape, n as NativeRequest, r as NativeResponse, t as NativeOptions, w as RequestResult, x as Options } from "../client-
|
|
1
|
+
import { M as SuccessOf, m as DataShape, n as NativeRequest, r as NativeResponse, t as NativeOptions, w as RequestResult, x as Options } from "../client-DaI8VaEz.js";
|
|
2
2
|
export { type DataShape, NativeOptions, NativeRequest, NativeResponse, type Options, type RequestResult, type SuccessOf };
|
package/dist/templates/core.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as ValidateOption, o as ValidationErrorContext, s as ValidationErrorHandler } from "../standardSchema-B2AxHwZB.js";
|
|
2
|
-
import { $ as unwrapResult, A as ResultByStatus, B as UnwrappedResult, C as RequestCredentials, D as ResponseErrorConfig, E as ResponseError, F as SuccessVariant, G as getHeader, H as Validator, I as ToStatusNumber, J as parseJsonOrText, K as getResponseContentType, L as Transport, M as SuccessOf, N as SuccessResultUnion, O as ResponseType, P as SuccessStatusCode, Q as toRequestInit, R as TransportResult, S as RequestConfig, T as ResolvedRequest, U as createClientCore, V as UrlConfig, W as createInterceptorStack, X as resolveAuth, Y as readResponse, Z as resolveResponseType, _ as ErrorOf, a as AuthResolver, b as Interceptors, c as ClientConfig, d as ContentBodySerializer, et as withUnwrap, f as ContentType, g as EmptyErrorBody, h as Deserializer, i as Auth, j as ResultUnion, k as ResponseTypeMap, l as ClientInstance, m as DataShape, o as AuthToken, p as DataOf, q as isStreamed, s as CallResult, u as Codec, v as InterceptorFn, w as RequestResult, x as Options, y as InterceptorStack, z as Unwrappable } from "../client-
|
|
2
|
+
import { $ as unwrapResult, A as ResultByStatus, B as UnwrappedResult, C as RequestCredentials, D as ResponseErrorConfig, E as ResponseError, F as SuccessVariant, G as getHeader, H as Validator, I as ToStatusNumber, J as parseJsonOrText, K as getResponseContentType, L as Transport, M as SuccessOf, N as SuccessResultUnion, O as ResponseType, P as SuccessStatusCode, Q as toRequestInit, R as TransportResult, S as RequestConfig, T as ResolvedRequest, U as createClientCore, V as UrlConfig, W as createInterceptorStack, X as resolveAuth, Y as readResponse, Z as resolveResponseType, _ as ErrorOf, a as AuthResolver, b as Interceptors, c as ClientConfig, d as ContentBodySerializer, et as withUnwrap, f as ContentType, g as EmptyErrorBody, h as Deserializer, i as Auth, j as ResultUnion, k as ResponseTypeMap, l as ClientInstance, m as DataShape, o as AuthToken, p as DataOf, q as isStreamed, s as CallResult, u as Codec, v as InterceptorFn, w as RequestResult, x as Options, y as InterceptorStack, z as Unwrappable } from "../client-DaI8VaEz.js";
|
|
3
3
|
export { Auth, AuthResolver, AuthToken, CallResult, ClientConfig, ClientInstance, Codec, ContentBodySerializer, ContentType, DataOf, DataShape, Deserializer, EmptyErrorBody, ErrorOf, InterceptorFn, InterceptorStack, Interceptors, Options, RequestConfig, RequestCredentials, RequestResult, ResolvedRequest, ResponseError, ResponseErrorConfig, ResponseType, ResponseTypeMap, ResultByStatus, ResultUnion, SuccessOf, SuccessResultUnion, SuccessStatusCode, SuccessVariant, ToStatusNumber, Transport, TransportResult, Unwrappable, UnwrappedResult, UrlConfig, type ValidateOption, type ValidationErrorContext, type ValidationErrorHandler, Validator, createClientCore, createInterceptorStack, getHeader, getResponseContentType, isStreamed, parseJsonOrText, readResponse, resolveAuth, resolveResponseType, toRequestInit, unwrapResult, withUnwrap };
|
package/dist/templates/sse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as ValidateOption, i as StandardSchemaValidator, s as ValidationErrorHandler } from "../standardSchema-B2AxHwZB.js";
|
|
2
|
-
import { M as SuccessOf, m as DataShape, n as NativeRequest, r as NativeResponse, w as RequestResult, x as Options } from "../client-
|
|
2
|
+
import { M as SuccessOf, m as DataShape, n as NativeRequest, r as NativeResponse, w as RequestResult, x as Options } from "../client-DaI8VaEz.js";
|
|
3
3
|
/**
|
|
4
4
|
* One decoded Server-Sent Event. `data` is parsed as JSON when valid and kept as the raw string otherwise,
|
|
5
5
|
* `event` is `message` when the server sent no `event` field, and `id` is the last event ID the stream has set.
|
|
@@ -29,11 +29,13 @@ Each generated call now includes the schemas:
|
|
|
29
29
|
request({
|
|
30
30
|
method: 'POST',
|
|
31
31
|
url: '/pet',
|
|
32
|
-
validator: { response: addPetResponseSchema, error: addPetErrorSchema, errorStatus: [405] },
|
|
33
32
|
...config,
|
|
33
|
+
validator: { response: addPetResponseSchema, error: { 405: addPetStatus405Schema }, ...config.validator },
|
|
34
34
|
})
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
A `validator` passed on one call is merged per key, so `validator: { request }` adds a request schema and keeps the generated response schema. A per-call `error` replaces the generated error map as a whole.
|
|
38
|
+
|
|
37
39
|
Add a `validator` field to your `RequestConfig`, then run the schemas in `client`. Zod schemas follow [Standard Schema](https://standardschema.dev), so `~standard.validate` works with any compatible library:
|
|
38
40
|
|
|
39
41
|
```typescript [src/client.ts]
|
|
@@ -42,7 +44,7 @@ type Schema = { '~standard': { validate: (value: unknown) => Result | Promise<Re
|
|
|
42
44
|
|
|
43
45
|
export type RequestConfig = {
|
|
44
46
|
// ...
|
|
45
|
-
validator?: { request?: Schema; response?: Schema; error?: Schema
|
|
47
|
+
validator?: { request?: Schema; response?: Schema; error?: Schema | Record<string, Schema> }
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
// inside client(), after reading the body
|
|
@@ -53,7 +55,7 @@ const validatedBody = result && 'value' in result ? result.value : body
|
|
|
53
55
|
|
|
54
56
|
Return `validatedBody` as `data`, so a schema that transforms the value takes effect. Without a response schema, `validatedBody` is the original `body`.
|
|
55
57
|
|
|
56
|
-
`
|
|
58
|
+
`error` is keyed by status, such as `{ 404: schema, '5XX': schema, default: schema }`. Pick the exact status, then its range, then `default`, and skip validation when none matches.
|
|
57
59
|
|
|
58
60
|
Set `validator: { request: 'zod' }` or `{ response: 'zod' }` to pass one direction only. Without `pluginZod()` in the plugins list, generation stops with an error.
|
|
59
61
|
|
|
@@ -65,12 +67,13 @@ With `validator: { params: 'zod' }`, each call also passes the schemas for its p
|
|
|
65
67
|
request({
|
|
66
68
|
method: 'PUT',
|
|
67
69
|
url: '/events/{day}',
|
|
70
|
+
...config,
|
|
68
71
|
validator: {
|
|
69
72
|
path: putEventPathSchema,
|
|
70
73
|
query: putEventQuerySchema,
|
|
71
74
|
headers: toHeadersStandardSchema(putEventHeadersSchema, putEventHeadersSchema.shape),
|
|
75
|
+
...config.validator,
|
|
72
76
|
},
|
|
73
|
-
...config,
|
|
74
77
|
})
|
|
75
78
|
```
|
|
76
79
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-client",
|
|
3
|
-
"version": "6.1.0-canary.
|
|
3
|
+
"version": "6.1.0-canary.20261109T175913",
|
|
4
4
|
"description": "Generate typed API operations against your own client module.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api-client",
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@kubb/kit": "^5.16.1",
|
|
65
|
-
"@kubb/plugin-ts": "^5.5.0-canary.
|
|
66
|
-
"@kubb/plugin-zod": "^5.9.0-canary.
|
|
65
|
+
"@kubb/plugin-ts": "^5.5.0-canary.20261109T175913",
|
|
66
|
+
"@kubb/plugin-zod": "^5.9.0-canary.20261109T175913",
|
|
67
67
|
"@kubb/renderer-jsx": "^5.16.1"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@internals/client": "0.1.0-canary.
|
|
71
|
-
"@internals/shared": "0.1.0-canary.
|
|
70
|
+
"@internals/client": "0.1.0-canary.20261109T175913",
|
|
71
|
+
"@internals/shared": "0.1.0-canary.20261109T175913",
|
|
72
72
|
"typescript": "^7.0.2"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {},
|
package/templates/core.ts
CHANGED
|
@@ -226,7 +226,7 @@ export type RequestConfig<TBody = unknown, TRequest = NativeRequest, TResponse =
|
|
|
226
226
|
transport?: Transport<TRequest, TResponse>
|
|
227
227
|
serializer?: Serializers
|
|
228
228
|
codecs?: Record<string, Codec>
|
|
229
|
-
/** `
|
|
229
|
+
/** `error` takes one validator for every non-2xx body, or a map by status such as `{ 404: schema, '5XX': schema, default: schema }`. */
|
|
230
230
|
validator?: {
|
|
231
231
|
request?: Validator
|
|
232
232
|
path?: Validator
|
|
@@ -234,8 +234,7 @@ export type RequestConfig<TBody = unknown, TRequest = NativeRequest, TResponse =
|
|
|
234
234
|
headers?: Validator
|
|
235
235
|
cookies?: Validator
|
|
236
236
|
response?: Validator
|
|
237
|
-
error?: Validator
|
|
238
|
-
errorStatus?: Array<number | string>
|
|
237
|
+
error?: Validator | Record<string, Validator>
|
|
239
238
|
}
|
|
240
239
|
onValidationError?: ValidationErrorHandler
|
|
241
240
|
validate?: ValidateOption
|
|
@@ -627,9 +626,11 @@ export async function readResponse<TRequest, TResponse extends Response>(
|
|
|
627
626
|
}
|
|
628
627
|
}
|
|
629
628
|
|
|
630
|
-
/**
|
|
631
|
-
function
|
|
632
|
-
|
|
629
|
+
/** Picks the error validator for `status`: the exact status, then its range such as `5XX`, then `default`. */
|
|
630
|
+
function pickErrorValidator(error: Validator | Record<string, Validator> | undefined, status: number): Validator | undefined {
|
|
631
|
+
if (!error || '~standard' in error) return error as Validator | undefined
|
|
632
|
+
const range = Object.keys(error).find((key) => key.toUpperCase() === `${String(status)[0]}XX`)
|
|
633
|
+
return error[String(status)] ?? (range ? error[range] : undefined) ?? error.default
|
|
633
634
|
}
|
|
634
635
|
|
|
635
636
|
/**
|
|
@@ -828,10 +829,9 @@ export function createClientCore<TRequest = NativeRequest, TResponse = NativeRes
|
|
|
828
829
|
// A streamed success body is validated event by event in `toEventStream`, not as a whole. A JSON answer to a streamed call is a whole body.
|
|
829
830
|
const streaming = isSuccess && resolveResponseType(resolvedRequest.responseType, contentType) === 'stream' && isStreamed(decoded)
|
|
830
831
|
// An error body is validated only when the call returns it. A call that throws keeps its `ResponseError`.
|
|
831
|
-
const
|
|
832
|
-
const validatesBody = isValidationEnabled(validate, direction) && !streaming && declared && (isSuccess || !throwOnError)
|
|
832
|
+
const validatesBody = isValidationEnabled(validate, direction) && !streaming && (isSuccess || !throwOnError)
|
|
833
833
|
const data = await runValidator({
|
|
834
|
-
validator: validatesBody ? validator?.
|
|
834
|
+
validator: validatesBody ? (isSuccess ? validator?.response : pickErrorValidator(validator?.error, result.status)) : undefined,
|
|
835
835
|
value: decoded,
|
|
836
836
|
context: { direction, source: 'body', method: resolvedRequest.method, url: resolvedRequest.url, status: result.status },
|
|
837
837
|
onValidationError,
|