@kubb/plugin-axios 5.0.0-beta.81 → 5.0.0-beta.85
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 +115 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +80 -18
- package/dist/index.js.map +1 -1
- package/package.json +6 -8
- package/src/generators/clientGenerator.tsx +2 -2
- package/src/plugin.ts +2 -2
- package/src/types.ts +1 -1
- package/templates/axios.ts +20 -10
- package/templates/serializers.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-axios",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.85",
|
|
4
4
|
"description": "Generate a slim, type-safe HTTP client with Kubb based on axios.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api-client",
|
|
@@ -49,22 +49,20 @@
|
|
|
49
49
|
"registry": "https://registry.npmjs.org/"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@kubb/
|
|
53
|
-
"@kubb/
|
|
54
|
-
"@kubb/renderer-jsx": "5.0.0-beta.80",
|
|
55
|
-
"@kubb/plugin-ts": "5.0.0-beta.81",
|
|
56
|
-
"@kubb/plugin-zod": "5.0.0-beta.81"
|
|
52
|
+
"@kubb/plugin-ts": "5.0.0-beta.84",
|
|
53
|
+
"@kubb/plugin-zod": "5.0.0-beta.84"
|
|
57
54
|
},
|
|
58
55
|
"devDependencies": {
|
|
59
56
|
"axios": "^1.18.1",
|
|
57
|
+
"kubb": "5.0.0-beta.84",
|
|
60
58
|
"typescript": "^6.0.3",
|
|
61
59
|
"@internals/client": "0.0.0",
|
|
62
60
|
"@internals/shared": "0.0.0",
|
|
63
61
|
"@internals/utils": "0.0.0"
|
|
64
62
|
},
|
|
65
63
|
"peerDependencies": {
|
|
66
|
-
"
|
|
67
|
-
"
|
|
64
|
+
"axios": "^1.7.2",
|
|
65
|
+
"kubb": "5.0.0-beta.84"
|
|
68
66
|
},
|
|
69
67
|
"peerDependenciesMeta": {
|
|
70
68
|
"axios": {
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
type SecurityDocument,
|
|
9
9
|
} from '@internals/client'
|
|
10
10
|
import { isEventStream, operationFileEntry } from '@internals/shared'
|
|
11
|
-
import { ast, defineGenerator } from '
|
|
11
|
+
import { ast, defineGenerator } from 'kubb/kit'
|
|
12
12
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
13
13
|
import { pluginZodName } from '@kubb/plugin-zod'
|
|
14
|
-
import { File, jsxRenderer } from '
|
|
14
|
+
import { File, jsxRenderer } from 'kubb/jsx'
|
|
15
15
|
import type { PluginAxios } from '../types.ts'
|
|
16
16
|
|
|
17
17
|
/**
|
package/src/plugin.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
import { createSdkGenerator, defaultMacros, isValidatorEnabled, resolverClient } from '@internals/client'
|
|
3
3
|
import { createGroupConfig } from '@internals/shared'
|
|
4
|
-
import { definePlugin } from '
|
|
4
|
+
import { definePlugin } from 'kubb/kit'
|
|
5
5
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
6
6
|
import { pluginZodName } from '@kubb/plugin-zod'
|
|
7
7
|
import { clientGenerator } from './generators/clientGenerator.tsx'
|
|
@@ -22,7 +22,7 @@ export const pluginAxiosName = 'plugin-axios' satisfies PluginAxios['name']
|
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
24
24
|
* ```ts
|
|
25
|
-
* import { defineConfig } from 'kubb'
|
|
25
|
+
* import { defineConfig } from 'kubb/config'
|
|
26
26
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
27
27
|
* import { pluginAxios } from '@kubb/plugin-axios'
|
|
28
28
|
*
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PluginFactoryOptions } from '
|
|
1
|
+
import type { PluginFactoryOptions } from 'kubb/kit'
|
|
2
2
|
import type { Options, ResolvedOptions, ResolverClient } from '@internals/client'
|
|
3
3
|
|
|
4
4
|
export type { Options, ResolvedOptions, ResolverClient } from '@internals/client'
|
package/templates/axios.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from 'axios'
|
|
2
2
|
import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
|
|
3
|
-
import { applyHeaderStyles, defaultBodySerializer, defaultPathSerializer, defaultQuerySerializer, serializeCookies } from './serializers'
|
|
3
|
+
import { applyHeaderStyles, defaultBodySerializer, defaultPathSerializer, defaultQuerySerializer, isDefaultJsonBody, serializeCookies } from './serializers'
|
|
4
4
|
import type { HeadersInit, PathParamStyle, PathSerializer, Serializers, Styles } from './serializers'
|
|
5
5
|
import { type StandardSchemaValidator, validateStandardSchema } from './standardSchema.ts'
|
|
6
6
|
|
|
@@ -291,6 +291,15 @@ function mergeHeaders(...sources: Array<HeadersInit | undefined>): Record<string
|
|
|
291
291
|
return Object.assign({}, ...sources.map(serializeHeaders))
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
function getHeader(headers: Record<string, string>, name: string): string | undefined {
|
|
295
|
+
const key = Object.keys(headers).find((k) => k.toLowerCase() === name.toLowerCase())
|
|
296
|
+
return key ? headers[key] : undefined
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function hasHeader(headers: Record<string, string>, name: string): boolean {
|
|
300
|
+
return Object.keys(headers).some((k) => k.toLowerCase() === name.toLowerCase())
|
|
301
|
+
}
|
|
302
|
+
|
|
294
303
|
/**
|
|
295
304
|
* Joins the URL parts, interpolates URL-encoded `{param}` segments, and appends the serialized query, backing `getUrl`.
|
|
296
305
|
*/
|
|
@@ -352,9 +361,6 @@ export async function resolveAuth(params: {
|
|
|
352
361
|
const { security, auth, headers, query } = params
|
|
353
362
|
if (!security?.length || auth === undefined) return
|
|
354
363
|
|
|
355
|
-
// An explicit caller-set header wins over the resolved token.
|
|
356
|
-
const hasHeader = (name: string) => Object.keys(headers).some((key) => key.toLowerCase() === name.toLowerCase())
|
|
357
|
-
|
|
358
364
|
for (const scheme of security) {
|
|
359
365
|
const token = typeof auth === 'function' ? await auth(scheme) : auth
|
|
360
366
|
if (token === undefined) continue
|
|
@@ -365,10 +371,10 @@ export async function resolveAuth(params: {
|
|
|
365
371
|
if (query[name] === undefined) query[name] = token
|
|
366
372
|
} else if (scheme.in === 'cookie') {
|
|
367
373
|
headers.Cookie = [headers.Cookie, `${name}=${token}`].filter(Boolean).join('; ')
|
|
368
|
-
} else if (!hasHeader(name)) {
|
|
374
|
+
} else if (!hasHeader(headers, name)) {
|
|
369
375
|
headers[name] = token
|
|
370
376
|
}
|
|
371
|
-
} else if (!hasHeader('Authorization')) {
|
|
377
|
+
} else if (!hasHeader(headers, 'Authorization')) {
|
|
372
378
|
headers.Authorization = scheme.scheme === 'basic' ? `Basic ${btoa(token)}` : `Bearer ${token}`
|
|
373
379
|
}
|
|
374
380
|
return
|
|
@@ -434,8 +440,8 @@ async function resolveRequest<TBody, TRequest, TResponse>({
|
|
|
434
440
|
|
|
435
441
|
const headers = mergeHeaders(config.headers, applyHeaderStyles(requestConfig.headers, requestConfig.styles?.header))
|
|
436
442
|
const { request: requestContentTypeOption, response: responseContentType } = resolveContentType(requestConfig.contentType)
|
|
437
|
-
const requestContentType = requestContentTypeOption ?? headers
|
|
438
|
-
if (responseContentType && headers
|
|
443
|
+
const requestContentType = requestContentTypeOption ?? getHeader(headers, 'content-type')
|
|
444
|
+
if (responseContentType && !hasHeader(headers, 'accept')) {
|
|
439
445
|
headers['Accept'] = responseContentType
|
|
440
446
|
}
|
|
441
447
|
|
|
@@ -456,15 +462,19 @@ async function resolveRequest<TBody, TRequest, TResponse>({
|
|
|
456
462
|
const validatedBody = await runValidator(requestConfig.validator?.request, requestConfig.body)
|
|
457
463
|
const requestContentTypeBase = baseContentType(requestContentType)
|
|
458
464
|
const contentCodec = requestContentTypeBase ? codecs[requestContentTypeBase] : undefined
|
|
465
|
+
const usesDefaultBodySerializer = !contentCodec?.serialize && bodySerializer === defaultBodySerializer
|
|
459
466
|
const body = contentCodec?.serialize
|
|
460
467
|
? contentCodec.serialize(validatedBody, requestContentType)
|
|
461
468
|
: bodySerializer({ body: validatedBody, contentType: requestContentType, encoding: requestConfig.styles?.body })
|
|
462
469
|
// A FormData body must keep its Content-Type unset so axios appends the multipart boundary.
|
|
463
470
|
if (body instanceof FormData) {
|
|
464
|
-
|
|
465
|
-
|
|
471
|
+
for (const key of Object.keys(headers)) {
|
|
472
|
+
if (key.toLowerCase() === 'content-type') delete headers[key]
|
|
473
|
+
}
|
|
466
474
|
} else if (requestContentTypeOption) {
|
|
467
475
|
headers['Content-Type'] = requestContentTypeOption
|
|
476
|
+
} else if (usesDefaultBodySerializer && isDefaultJsonBody(validatedBody) && !hasHeader(headers, 'content-type')) {
|
|
477
|
+
headers['Content-Type'] = 'application/json'
|
|
468
478
|
}
|
|
469
479
|
|
|
470
480
|
const pathParams = requestConfig.path ?? {}
|
package/templates/serializers.ts
CHANGED
|
@@ -122,6 +122,10 @@ function isFormBody(body: unknown): body is BodyInit {
|
|
|
122
122
|
)
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
export function isDefaultJsonBody(body: unknown): boolean {
|
|
126
|
+
return body !== undefined && body !== null && !isFormBody(body)
|
|
127
|
+
}
|
|
128
|
+
|
|
125
129
|
function appendFormDataValue({ formData, key, value, contentType }: { formData: FormData; key: string; value: unknown; contentType?: string }): void {
|
|
126
130
|
if (value === undefined || value === null) return
|
|
127
131
|
if (value instanceof Blob) formData.append(key, value)
|