@kubb/plugin-fetch 5.5.0-canary.20260924T110844 → 5.5.0
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 +58 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js +58 -24
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/plugin.ts +5 -2
- package/templates/fetch.ts +29 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-fetch",
|
|
3
|
-
"version": "5.5.0
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Generate a slim, type-safe HTTP client with Kubb based on the native Fetch api.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api-client",
|
|
@@ -65,17 +65,17 @@
|
|
|
65
65
|
"registry": "https://registry.npmjs.org/"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@kubb/plugin-ts": "^5.
|
|
69
|
-
"@kubb/plugin-zod": "^5.
|
|
68
|
+
"@kubb/plugin-ts": "^5.0.2",
|
|
69
|
+
"@kubb/plugin-zod": "^5.2.1"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@internals/client": "0.
|
|
73
|
-
"@internals/shared": "0.
|
|
74
|
-
"kubb": "^5.3.
|
|
72
|
+
"@internals/client": "0.0.0",
|
|
73
|
+
"@internals/shared": "0.0.0",
|
|
74
|
+
"kubb": "^5.3.14",
|
|
75
75
|
"typescript": "^6.0.3"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"kubb": "^5.3.
|
|
78
|
+
"kubb": "^5.3.14"
|
|
79
79
|
},
|
|
80
80
|
"engines": {
|
|
81
81
|
"node": ">=22"
|
package/src/plugin.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import { createSdkGenerator, defaultMacros, resolverClient } from '@internals/client'
|
|
2
|
+
import { createSdkGenerator, defaultMacros, resolverClient, runtimeTemplate } from '@internals/client'
|
|
3
3
|
import { createGroupConfig } from '@internals/shared'
|
|
4
4
|
import { definePlugin, Resolver } from 'kubb/kit'
|
|
5
5
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
@@ -43,6 +43,7 @@ export const pluginFetch = definePlugin<PluginFetch>((options) => {
|
|
|
43
43
|
include,
|
|
44
44
|
override = [],
|
|
45
45
|
baseURL,
|
|
46
|
+
throwOnErrorDefault = true,
|
|
46
47
|
validator = false,
|
|
47
48
|
returnType = 'full',
|
|
48
49
|
group,
|
|
@@ -57,6 +58,7 @@ export const pluginFetch = definePlugin<PluginFetch>((options) => {
|
|
|
57
58
|
override,
|
|
58
59
|
group: createGroupConfig(group),
|
|
59
60
|
baseURL,
|
|
61
|
+
throwOnErrorDefault,
|
|
60
62
|
validator,
|
|
61
63
|
returnType,
|
|
62
64
|
sdk: sdk ? { mode: sdk.mode ?? 'tag', name: sdk.name } : undefined,
|
|
@@ -93,7 +95,8 @@ export const pluginFetch = definePlugin<PluginFetch>((options) => {
|
|
|
93
95
|
ctx.injectFile({
|
|
94
96
|
baseName: 'client.ts',
|
|
95
97
|
path: path.resolve(root, '.kubb/client.ts'),
|
|
96
|
-
|
|
98
|
+
// Keep sources empty so the barrel exports the whole runtime module.
|
|
99
|
+
banner: runtimeTemplate(fetchClientTemplatePath, ctx.config),
|
|
97
100
|
footer: baseURLExpression ? `client.setConfig({ baseURL: ${baseURLExpression} })` : undefined,
|
|
98
101
|
})
|
|
99
102
|
|
package/templates/fetch.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { applyHeaderStyles, defaultBodySerializer, defaultPathSerializer, defaultQuerySerializer, isDefaultJsonBody, serializeCookies } from './serializers'
|
|
2
|
-
import type { HeadersInit, PathParamStyle, PathSerializer, RequestBody, Serializers, Styles } from './serializers'
|
|
3
|
-
import { ParseError, type StandardSchemaValidator, validateStandardSchema } from './standardSchema'
|
|
1
|
+
import { applyHeaderStyles, defaultBodySerializer, defaultPathSerializer, defaultQuerySerializer, isDefaultJsonBody, serializeCookies } from './serializers.ts'
|
|
2
|
+
import type { HeadersInit, PathParamStyle, PathSerializer, RequestBody, Serializers, Styles } from './serializers.ts'
|
|
3
|
+
import { ParseError, type StandardSchemaValidator, validateStandardSchema } from './standardSchema.ts'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* HTTP status codes treated as a success, everything else is an error.
|
|
@@ -109,21 +109,16 @@ export function withUnwrap<T extends { data: unknown; error: unknown }>(promise:
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
* The shape a generated operation returns
|
|
113
|
-
*
|
|
114
|
-
* `RequestResult` when a call sets `throwOnError: false` and still needs `error` to discriminate a
|
|
115
|
-
* failed response.
|
|
112
|
+
* The shape a generated operation returns with `returnType: 'data'`: the success body when
|
|
113
|
+
* `throwOnError` is true, or the full `RequestResult` when it is false.
|
|
116
114
|
*/
|
|
117
115
|
export type UnwrappedResult<TResponses, ThrowOnError extends boolean = true, TRequest = Request, TResponse = Response> = ThrowOnError extends true
|
|
118
116
|
? RequestResult<TResponses, true, TRequest, TResponse>['data']
|
|
119
117
|
: RequestResult<TResponses, ThrowOnError, TRequest, TResponse>
|
|
120
118
|
|
|
121
119
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* a call that sets `throwOnError: false`, since that path still needs `error` to discriminate a
|
|
125
|
-
* failed response. Backs `returnType: 'data'`, mirroring how `toEventStream` centralizes the
|
|
126
|
-
* post-processing for `text/event-stream` operations.
|
|
120
|
+
* Returns the success body when `throwOnError` is true, or the full result when it is false.
|
|
121
|
+
* Backs generated operations with `returnType: 'data'`.
|
|
127
122
|
*/
|
|
128
123
|
export function unwrapResult<T extends { data: unknown; error: unknown }>(promise: Promise<T>, throwOnError: boolean | undefined): Promise<T | T['data']> {
|
|
129
124
|
return promise.then((result) => ((throwOnError ?? true) ? result.data : result))
|
|
@@ -317,25 +312,25 @@ export type CallResult<TRequest = Request, TResponse = Response> = {
|
|
|
317
312
|
response: TResponse
|
|
318
313
|
}
|
|
319
314
|
|
|
320
|
-
export type InterceptorFn<T> = (value: T) => T | Promise<T>
|
|
315
|
+
export type InterceptorFn<T, TContext = never> = (value: T, context?: TContext) => T | Promise<T>
|
|
321
316
|
|
|
322
317
|
/**
|
|
323
318
|
* A single interceptor channel with a transport-agnostic `use` / `eject` / `update` API.
|
|
324
319
|
*/
|
|
325
|
-
export type InterceptorStack<T> = {
|
|
326
|
-
use: (fn: InterceptorFn<T>) => number
|
|
320
|
+
export type InterceptorStack<T, TContext = never> = {
|
|
321
|
+
use: (fn: InterceptorFn<T, TContext>) => number
|
|
327
322
|
eject: (id: number) => void
|
|
328
|
-
update: (id: number, fn: InterceptorFn<T>) => void
|
|
329
|
-
run: (value: T) => Promise<T>
|
|
323
|
+
update: (id: number, fn: InterceptorFn<T, TContext>) => void
|
|
324
|
+
run: (value: T, context?: TContext) => Promise<T>
|
|
330
325
|
}
|
|
331
326
|
|
|
332
327
|
/**
|
|
333
328
|
* The three interceptor channels every client instance exposes.
|
|
334
329
|
*/
|
|
335
330
|
export type Interceptors<TRequest = Request, TResponse = Response> = {
|
|
336
|
-
request: InterceptorStack<ResolvedRequest
|
|
337
|
-
response: InterceptorStack<TransportResult<unknown, TRequest, TResponse>>
|
|
338
|
-
error: InterceptorStack<ResponseError<unknown, TRequest, TResponse>>
|
|
331
|
+
request: InterceptorStack<ResolvedRequest, RequestConfig<unknown, TRequest, TResponse>>
|
|
332
|
+
response: InterceptorStack<TransportResult<unknown, TRequest, TResponse>, RequestConfig<unknown, TRequest, TResponse>>
|
|
333
|
+
error: InterceptorStack<ResponseError<unknown, TRequest, TResponse>, RequestConfig<unknown, TRequest, TResponse>>
|
|
339
334
|
}
|
|
340
335
|
|
|
341
336
|
/**
|
|
@@ -426,8 +421,8 @@ function serializeUrl({
|
|
|
426
421
|
/**
|
|
427
422
|
* Creates a transport-agnostic interceptor channel that runs interceptors in registration order.
|
|
428
423
|
*/
|
|
429
|
-
export function createInterceptorStack<T>(): InterceptorStack<T> {
|
|
430
|
-
let entries: Array<{ id: number; fn: InterceptorFn<T> }> = []
|
|
424
|
+
export function createInterceptorStack<T, TContext = never>(): InterceptorStack<T, TContext> {
|
|
425
|
+
let entries: Array<{ id: number; fn: InterceptorFn<T, TContext> }> = []
|
|
431
426
|
let counter = 0
|
|
432
427
|
return {
|
|
433
428
|
use(fn) {
|
|
@@ -442,10 +437,10 @@ export function createInterceptorStack<T>(): InterceptorStack<T> {
|
|
|
442
437
|
const entry = entries.find((item) => item.id === id)
|
|
443
438
|
if (entry) entry.fn = fn
|
|
444
439
|
},
|
|
445
|
-
async run(value) {
|
|
440
|
+
async run(value, context) {
|
|
446
441
|
let result = value
|
|
447
442
|
for (const entry of entries) {
|
|
448
|
-
result = await entry.fn(result)
|
|
443
|
+
result = await entry.fn(result, context)
|
|
449
444
|
}
|
|
450
445
|
return result
|
|
451
446
|
},
|
|
@@ -640,6 +635,7 @@ async function settleResult<TRequest, TResponse>({
|
|
|
640
635
|
validator,
|
|
641
636
|
onValidationError,
|
|
642
637
|
errorInterceptors,
|
|
638
|
+
requestConfig,
|
|
643
639
|
}: {
|
|
644
640
|
result: TransportResult<unknown, TRequest, TResponse>
|
|
645
641
|
request: ResolvedRequest
|
|
@@ -647,7 +643,8 @@ async function settleResult<TRequest, TResponse>({
|
|
|
647
643
|
throwOnError: boolean
|
|
648
644
|
validator: { response?: Validator; error?: Validator } | undefined
|
|
649
645
|
onValidationError: ValidationErrorHandler | undefined
|
|
650
|
-
errorInterceptors: InterceptorStack<ResponseError<unknown, TRequest, TResponse>>
|
|
646
|
+
errorInterceptors: InterceptorStack<ResponseError<unknown, TRequest, TResponse>, RequestConfig<unknown, TRequest, TResponse>>
|
|
647
|
+
requestConfig: RequestConfig<unknown, TRequest, TResponse>
|
|
651
648
|
}): Promise<CallResult<TRequest, TResponse>> {
|
|
652
649
|
const isSuccess = result.status >= 200 && result.status < 300
|
|
653
650
|
const contentType = result.contentType ?? getResponseContentType(result.headers)
|
|
@@ -684,7 +681,7 @@ async function settleResult<TRequest, TResponse>({
|
|
|
684
681
|
request: result.request,
|
|
685
682
|
response: result.response,
|
|
686
683
|
})
|
|
687
|
-
await errorInterceptors.run(responseError)
|
|
684
|
+
await errorInterceptors.run(responseError, requestConfig)
|
|
688
685
|
throw responseError
|
|
689
686
|
}
|
|
690
687
|
return { status: result.status, data: undefined, error, contentType, request: result.request, response: result.response }
|
|
@@ -700,17 +697,17 @@ export function createClientCore<TRequest = Request, TResponse = Response>(
|
|
|
700
697
|
let config: ClientConfig<TRequest, TResponse> = { ...initialConfig }
|
|
701
698
|
|
|
702
699
|
const interceptors: Interceptors<TRequest, TResponse> = {
|
|
703
|
-
request: createInterceptorStack<ResolvedRequest
|
|
704
|
-
response: createInterceptorStack<TransportResult<unknown, TRequest, TResponse>>(),
|
|
705
|
-
error: createInterceptorStack<ResponseError<unknown, TRequest, TResponse>>(),
|
|
700
|
+
request: createInterceptorStack<ResolvedRequest, RequestConfig<unknown, TRequest, TResponse>>(),
|
|
701
|
+
response: createInterceptorStack<TransportResult<unknown, TRequest, TResponse>, RequestConfig<unknown, TRequest, TResponse>>(),
|
|
702
|
+
error: createInterceptorStack<ResponseError<unknown, TRequest, TResponse>, RequestConfig<unknown, TRequest, TResponse>>(),
|
|
706
703
|
}
|
|
707
704
|
|
|
708
705
|
const client = (async <TBody = unknown>(requestConfig: RequestConfig<TBody, TRequest, TResponse>): Promise<CallResult<TRequest, TResponse>> => {
|
|
709
706
|
const transport = requestConfig.transport ?? config.transport ?? defaultTransport
|
|
710
707
|
const { request, codecs } = await resolveRequest({ config, requestConfig })
|
|
711
708
|
|
|
712
|
-
const resolvedRequest = await interceptors.request.run(request)
|
|
713
|
-
const result = await interceptors.response.run(await transport(resolvedRequest))
|
|
709
|
+
const resolvedRequest = await interceptors.request.run(request, requestConfig)
|
|
710
|
+
const result = await interceptors.response.run(await transport(resolvedRequest), requestConfig)
|
|
714
711
|
|
|
715
712
|
return settleResult({
|
|
716
713
|
result,
|
|
@@ -720,6 +717,7 @@ export function createClientCore<TRequest = Request, TResponse = Response>(
|
|
|
720
717
|
validator: requestConfig.validator,
|
|
721
718
|
onValidationError: requestConfig.onValidationError ?? config.onValidationError,
|
|
722
719
|
errorInterceptors: interceptors.error,
|
|
720
|
+
requestConfig,
|
|
723
721
|
})
|
|
724
722
|
}) as ClientInstance<TRequest, TResponse>
|
|
725
723
|
|