@kubb/plugin-client 5.0.0-beta.25 → 5.0.0-beta.28

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.
@@ -21,12 +21,27 @@ const mergeConfig = (...configs) => {
21
21
  ...merged,
22
22
  ...config,
23
23
  headers: {
24
- ...merged.headers,
25
- ...config.headers
24
+ ...Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers,
25
+ ...Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers
26
26
  }
27
27
  };
28
28
  }, {});
29
29
  };
30
+ /**
31
+ * Serializes header values into the string form axios ultimately puts on the wire.
32
+ * Objects (including arrays) are JSON-stringified so spec-defined object headers like `X-Filter`
33
+ * are sent in their canonical JSON-string form rather than `[object Object]`.
34
+ */
35
+ function serializeHeaders(headers) {
36
+ if (!headers) return {};
37
+ const entries = Array.isArray(headers) ? headers : Object.entries(headers);
38
+ const result = {};
39
+ for (const [key, value] of entries) {
40
+ if (value === void 0 || value === null) continue;
41
+ result[key] = typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value);
42
+ }
43
+ return result;
44
+ }
30
45
  const axiosInstance = axios.default.create(getConfig());
31
46
  const client = async (config, _request) => {
32
47
  const { contentType, headers, ...axiosConfig } = mergeConfig(getConfig(), config);
@@ -34,7 +49,7 @@ const client = async (config, _request) => {
34
49
  ...axiosConfig,
35
50
  headers: {
36
51
  ...contentType && contentType !== "multipart/form-data" ? { "Content-Type": contentType } : {},
37
- ...headers
52
+ ...serializeHeaders(headers)
38
53
  }
39
54
  }).catch((e) => {
40
55
  throw e;
@@ -1 +1 @@
1
- {"version":3,"file":"axios.cjs","names":[],"sources":["../../src/clients/axios.ts"],"sourcesContent":["import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'\nimport axios from 'axios'\n\ndeclare const AXIOS_BASE: string\ndeclare const AXIOS_HEADERS: string\n\n/**\n * Subset of AxiosRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n validateStatus?: (status: number) => boolean\n headers?: AxiosRequestConfig['headers']\n paramsSerializer?: AxiosRequestConfig['paramsSerializer']\n contentType?: string\n}\n\n/**\n * Subset of AxiosResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: AxiosResponse['headers']\n}\n\nexport type ResponseErrorConfig<TError = unknown> = AxiosError<TError>\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nlet _config: Partial<RequestConfig> = {\n baseURL: typeof AXIOS_BASE !== 'undefined' ? AXIOS_BASE : undefined,\n headers: typeof AXIOS_HEADERS !== 'undefined' ? JSON.parse(AXIOS_HEADERS) : undefined,\n}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: RequestConfig) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...merged.headers,\n ...config.headers,\n },\n }\n }, {})\n}\n\nexport const axiosInstance = axios.create(getConfig())\n\nexport const client = async <TResponseData, TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const requestConfig = mergeConfig(getConfig(), config)\n const { contentType, headers, ...axiosConfig } = requestConfig\n return axiosInstance\n .request<TResponseData, ResponseConfig<TResponseData>>({\n ...axiosConfig,\n headers: {\n ...(contentType && contentType !== 'multipart/form-data' ? { 'Content-Type': contentType } : {}),\n ...headers,\n },\n })\n .catch((e: AxiosError<TError>) => {\n throw e\n })\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;;;;;;AAwCA,IAAI,UAAkC;CACpC,SAAS,OAAO,eAAe,cAAc,aAAa,KAAA;CAC1D,SAAS,OAAO,kBAAkB,cAAc,KAAK,MAAM,cAAc,GAAG,KAAA;CAC7E;AAED,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAA0B;CAClD,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAG,OAAO;IACV,GAAG,OAAO;IACX;GACF;IACA,EAAE,CAAC;;AAGR,MAAa,gBAAgB,MAAA,QAAM,OAAO,WAAW,CAAC;AAEtD,MAAa,SAAS,OACpB,QACA,aAC2C;CAE3C,MAAM,EAAE,aAAa,SAAS,GAAG,gBADX,YAAY,WAAW,EAAE,OACe;CAC9D,OAAO,cACJ,QAAsD;EACrD,GAAG;EACH,SAAS;GACP,GAAI,eAAe,gBAAgB,wBAAwB,EAAE,gBAAgB,aAAa,GAAG,EAAE;GAC/F,GAAG;GACJ;EACF,CAAC,CACD,OAAO,MAA0B;EAChC,MAAM;GACN;;AAGN,OAAO,YAAY;AACnB,OAAO,YAAY"}
1
+ {"version":3,"file":"axios.cjs","names":[],"sources":["../../src/clients/axios.ts"],"sourcesContent":["import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'\nimport axios from 'axios'\n\ndeclare const AXIOS_BASE: string\ndeclare const AXIOS_HEADERS: string\n\n/**\n * Header values may be objects (e.g. JSON-encoded headers like `X-Filter` in the Linode API).\n * Non-string values are JSON-serialized before the request is sent.\n */\nexport type HeaderValue = string | number | boolean | null | undefined | object\nexport type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>\n\n/**\n * Subset of AxiosRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n validateStatus?: (status: number) => boolean\n headers?: HeadersInit\n paramsSerializer?: AxiosRequestConfig['paramsSerializer']\n contentType?: string\n}\n\n/**\n * Subset of AxiosResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: AxiosResponse['headers']\n}\n\nexport type ResponseErrorConfig<TError = unknown> = AxiosError<TError>\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nlet _config: Partial<RequestConfig> = {\n baseURL: typeof AXIOS_BASE !== 'undefined' ? AXIOS_BASE : undefined,\n headers: typeof AXIOS_HEADERS !== 'undefined' ? JSON.parse(AXIOS_HEADERS) : undefined,\n}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: RequestConfig) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\n/**\n * Serializes header values into the string form axios ultimately puts on the wire.\n * Objects (including arrays) are JSON-stringified so spec-defined object headers like `X-Filter`\n * are sent in their canonical JSON-string form rather than `[object Object]`.\n */\nfunction serializeHeaders(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {}\n const entries = Array.isArray(headers) ? headers : Object.entries(headers)\n const result: Record<string, string> = {}\n for (const [key, value] of entries) {\n if (value === undefined || value === null) continue\n result[key] = typeof value === 'string' ? value : typeof value === 'object' ? JSON.stringify(value) : String(value)\n }\n return result\n}\n\nexport const axiosInstance = axios.create(getConfig() as AxiosRequestConfig)\n\nexport const client = async <TResponseData, TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const requestConfig = mergeConfig(getConfig(), config)\n const { contentType, headers, ...axiosConfig } = requestConfig\n return axiosInstance\n .request<TResponseData, ResponseConfig<TResponseData>>({\n ...axiosConfig,\n headers: {\n ...(contentType && contentType !== 'multipart/form-data' ? { 'Content-Type': contentType } : {}),\n ...serializeHeaders(headers),\n },\n })\n .catch((e: AxiosError<TError>) => {\n throw e\n })\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;;;;;;AA+CA,IAAI,UAAkC;CACpC,SAAS,OAAO,eAAe,cAAc,aAAa,KAAA;CAC1D,SAAS,OAAO,kBAAkB,cAAc,KAAK,MAAM,cAAc,GAAG,KAAA;CAC7E;AAED,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAA0B;CAClD,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;;;;;;AAQR,SAAS,iBAAiB,SAA0D;CAClF,IAAI,CAAC,SAAS,OAAO,EAAE;CACvB,MAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG,UAAU,OAAO,QAAQ,QAAQ;CAC1E,MAAM,SAAiC,EAAE;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS;EAClC,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;EAC3C,OAAO,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,UAAU,WAAW,KAAK,UAAU,MAAM,GAAG,OAAO,MAAM;;CAErH,OAAO;;AAGT,MAAa,gBAAgB,MAAA,QAAM,OAAO,WAAW,CAAuB;AAE5E,MAAa,SAAS,OACpB,QACA,aAC2C;CAE3C,MAAM,EAAE,aAAa,SAAS,GAAG,gBADX,YAAY,WAAW,EAAE,OACe;CAC9D,OAAO,cACJ,QAAsD;EACrD,GAAG;EACH,SAAS;GACP,GAAI,eAAe,gBAAgB,wBAAwB,EAAE,gBAAgB,aAAa,GAAG,EAAE;GAC/F,GAAG,iBAAiB,QAAQ;GAC7B;EACF,CAAC,CACD,OAAO,MAA0B;EAChC,MAAM;GACN;;AAGN,OAAO,YAAY;AACnB,OAAO,YAAY"}
@@ -3,6 +3,12 @@ import * as _$axios from "axios";
3
3
  import { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
4
4
 
5
5
  //#region src/clients/axios.d.ts
6
+ /**
7
+ * Header values may be objects (e.g. JSON-encoded headers like `X-Filter` in the Linode API).
8
+ * Non-string values are JSON-serialized before the request is sent.
9
+ */
10
+ type HeaderValue = string | number | boolean | null | undefined | object;
11
+ type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>;
6
12
  /**
7
13
  * Subset of AxiosRequestConfig
8
14
  */
@@ -15,7 +21,7 @@ type RequestConfig<TData = unknown> = {
15
21
  responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';
16
22
  signal?: AbortSignal;
17
23
  validateStatus?: (status: number) => boolean;
18
- headers?: AxiosRequestConfig['headers'];
24
+ headers?: HeadersInit;
19
25
  paramsSerializer?: AxiosRequestConfig['paramsSerializer'];
20
26
  contentType?: string;
21
27
  };
@@ -40,5 +46,5 @@ declare const client: {
40
46
  setConfig: (config: RequestConfig) => Partial<RequestConfig<unknown>>;
41
47
  };
42
48
  //#endregion
43
- export { Client, RequestConfig, ResponseConfig, ResponseErrorConfig, axiosInstance, client, client as default, getConfig, mergeConfig, setConfig };
49
+ export { Client, HeaderValue, HeadersInit, RequestConfig, ResponseConfig, ResponseErrorConfig, axiosInstance, client, client as default, getConfig, mergeConfig, setConfig };
44
50
  //# sourceMappingURL=axios.d.ts.map
@@ -16,12 +16,27 @@ const mergeConfig = (...configs) => {
16
16
  ...merged,
17
17
  ...config,
18
18
  headers: {
19
- ...merged.headers,
20
- ...config.headers
19
+ ...Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers,
20
+ ...Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers
21
21
  }
22
22
  };
23
23
  }, {});
24
24
  };
25
+ /**
26
+ * Serializes header values into the string form axios ultimately puts on the wire.
27
+ * Objects (including arrays) are JSON-stringified so spec-defined object headers like `X-Filter`
28
+ * are sent in their canonical JSON-string form rather than `[object Object]`.
29
+ */
30
+ function serializeHeaders(headers) {
31
+ if (!headers) return {};
32
+ const entries = Array.isArray(headers) ? headers : Object.entries(headers);
33
+ const result = {};
34
+ for (const [key, value] of entries) {
35
+ if (value === void 0 || value === null) continue;
36
+ result[key] = typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value);
37
+ }
38
+ return result;
39
+ }
25
40
  const axiosInstance = axios.create(getConfig());
26
41
  const client = async (config, _request) => {
27
42
  const { contentType, headers, ...axiosConfig } = mergeConfig(getConfig(), config);
@@ -29,7 +44,7 @@ const client = async (config, _request) => {
29
44
  ...axiosConfig,
30
45
  headers: {
31
46
  ...contentType && contentType !== "multipart/form-data" ? { "Content-Type": contentType } : {},
32
- ...headers
47
+ ...serializeHeaders(headers)
33
48
  }
34
49
  }).catch((e) => {
35
50
  throw e;
@@ -1 +1 @@
1
- {"version":3,"file":"axios.js","names":[],"sources":["../../src/clients/axios.ts"],"sourcesContent":["import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'\nimport axios from 'axios'\n\ndeclare const AXIOS_BASE: string\ndeclare const AXIOS_HEADERS: string\n\n/**\n * Subset of AxiosRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n validateStatus?: (status: number) => boolean\n headers?: AxiosRequestConfig['headers']\n paramsSerializer?: AxiosRequestConfig['paramsSerializer']\n contentType?: string\n}\n\n/**\n * Subset of AxiosResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: AxiosResponse['headers']\n}\n\nexport type ResponseErrorConfig<TError = unknown> = AxiosError<TError>\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nlet _config: Partial<RequestConfig> = {\n baseURL: typeof AXIOS_BASE !== 'undefined' ? AXIOS_BASE : undefined,\n headers: typeof AXIOS_HEADERS !== 'undefined' ? JSON.parse(AXIOS_HEADERS) : undefined,\n}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: RequestConfig) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...merged.headers,\n ...config.headers,\n },\n }\n }, {})\n}\n\nexport const axiosInstance = axios.create(getConfig())\n\nexport const client = async <TResponseData, TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const requestConfig = mergeConfig(getConfig(), config)\n const { contentType, headers, ...axiosConfig } = requestConfig\n return axiosInstance\n .request<TResponseData, ResponseConfig<TResponseData>>({\n ...axiosConfig,\n headers: {\n ...(contentType && contentType !== 'multipart/form-data' ? { 'Content-Type': contentType } : {}),\n ...headers,\n },\n })\n .catch((e: AxiosError<TError>) => {\n throw e\n })\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;AAwCA,IAAI,UAAkC;CACpC,SAAS,OAAO,eAAe,cAAc,aAAa,KAAA;CAC1D,SAAS,OAAO,kBAAkB,cAAc,KAAK,MAAM,cAAc,GAAG,KAAA;CAC7E;AAED,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAA0B;CAClD,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAG,OAAO;IACV,GAAG,OAAO;IACX;GACF;IACA,EAAE,CAAC;;AAGR,MAAa,gBAAgB,MAAM,OAAO,WAAW,CAAC;AAEtD,MAAa,SAAS,OACpB,QACA,aAC2C;CAE3C,MAAM,EAAE,aAAa,SAAS,GAAG,gBADX,YAAY,WAAW,EAAE,OACe;CAC9D,OAAO,cACJ,QAAsD;EACrD,GAAG;EACH,SAAS;GACP,GAAI,eAAe,gBAAgB,wBAAwB,EAAE,gBAAgB,aAAa,GAAG,EAAE;GAC/F,GAAG;GACJ;EACF,CAAC,CACD,OAAO,MAA0B;EAChC,MAAM;GACN;;AAGN,OAAO,YAAY;AACnB,OAAO,YAAY"}
1
+ {"version":3,"file":"axios.js","names":[],"sources":["../../src/clients/axios.ts"],"sourcesContent":["import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'\nimport axios from 'axios'\n\ndeclare const AXIOS_BASE: string\ndeclare const AXIOS_HEADERS: string\n\n/**\n * Header values may be objects (e.g. JSON-encoded headers like `X-Filter` in the Linode API).\n * Non-string values are JSON-serialized before the request is sent.\n */\nexport type HeaderValue = string | number | boolean | null | undefined | object\nexport type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>\n\n/**\n * Subset of AxiosRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n validateStatus?: (status: number) => boolean\n headers?: HeadersInit\n paramsSerializer?: AxiosRequestConfig['paramsSerializer']\n contentType?: string\n}\n\n/**\n * Subset of AxiosResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: AxiosResponse['headers']\n}\n\nexport type ResponseErrorConfig<TError = unknown> = AxiosError<TError>\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nlet _config: Partial<RequestConfig> = {\n baseURL: typeof AXIOS_BASE !== 'undefined' ? AXIOS_BASE : undefined,\n headers: typeof AXIOS_HEADERS !== 'undefined' ? JSON.parse(AXIOS_HEADERS) : undefined,\n}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: RequestConfig) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\n/**\n * Serializes header values into the string form axios ultimately puts on the wire.\n * Objects (including arrays) are JSON-stringified so spec-defined object headers like `X-Filter`\n * are sent in their canonical JSON-string form rather than `[object Object]`.\n */\nfunction serializeHeaders(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {}\n const entries = Array.isArray(headers) ? headers : Object.entries(headers)\n const result: Record<string, string> = {}\n for (const [key, value] of entries) {\n if (value === undefined || value === null) continue\n result[key] = typeof value === 'string' ? value : typeof value === 'object' ? JSON.stringify(value) : String(value)\n }\n return result\n}\n\nexport const axiosInstance = axios.create(getConfig() as AxiosRequestConfig)\n\nexport const client = async <TResponseData, TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const requestConfig = mergeConfig(getConfig(), config)\n const { contentType, headers, ...axiosConfig } = requestConfig\n return axiosInstance\n .request<TResponseData, ResponseConfig<TResponseData>>({\n ...axiosConfig,\n headers: {\n ...(contentType && contentType !== 'multipart/form-data' ? { 'Content-Type': contentType } : {}),\n ...serializeHeaders(headers),\n },\n })\n .catch((e: AxiosError<TError>) => {\n throw e\n })\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;AA+CA,IAAI,UAAkC;CACpC,SAAS,OAAO,eAAe,cAAc,aAAa,KAAA;CAC1D,SAAS,OAAO,kBAAkB,cAAc,KAAK,MAAM,cAAc,GAAG,KAAA;CAC7E;AAED,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAA0B;CAClD,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;;;;;;AAQR,SAAS,iBAAiB,SAA0D;CAClF,IAAI,CAAC,SAAS,OAAO,EAAE;CACvB,MAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG,UAAU,OAAO,QAAQ,QAAQ;CAC1E,MAAM,SAAiC,EAAE;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS;EAClC,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;EAC3C,OAAO,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,UAAU,WAAW,KAAK,UAAU,MAAM,GAAG,OAAO,MAAM;;CAErH,OAAO;;AAGT,MAAa,gBAAgB,MAAM,OAAO,WAAW,CAAuB;AAE5E,MAAa,SAAS,OACpB,QACA,aAC2C;CAE3C,MAAM,EAAE,aAAa,SAAS,GAAG,gBADX,YAAY,WAAW,EAAE,OACe;CAC9D,OAAO,cACJ,QAAsD;EACrD,GAAG;EACH,SAAS;GACP,GAAI,eAAe,gBAAgB,wBAAwB,EAAE,gBAAgB,aAAa,GAAG,EAAE;GAC/F,GAAG,iBAAiB,QAAQ;GAC7B;EACF,CAAC,CACD,OAAO,MAA0B;EAChC,MAAM;GACN;;AAGN,OAAO,YAAY;AACnB,OAAO,YAAY"}
@@ -22,6 +22,21 @@ const mergeConfig = (...configs) => {
22
22
  };
23
23
  }, {});
24
24
  };
25
+ /**
26
+ * Serializes header values into the string form `fetch` expects.
27
+ * Objects (including arrays) are JSON-stringified so spec-defined object
28
+ * headers like `X-Filter` are sent in their canonical JSON-string form.
29
+ */
30
+ function serializeHeaders(headers) {
31
+ if (!headers) return {};
32
+ const entries = Array.isArray(headers) ? headers : Object.entries(headers);
33
+ const result = {};
34
+ for (const [key, value] of entries) {
35
+ if (value === void 0 || value === null) continue;
36
+ result[key] = typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value);
37
+ }
38
+ return result;
39
+ }
25
40
  const client = async (paramsConfig, _request) => {
26
41
  const normalizedParams = new URLSearchParams();
27
42
  const config = mergeConfig(getConfig(), paramsConfig);
@@ -30,14 +45,14 @@ const client = async (paramsConfig, _request) => {
30
45
  });
31
46
  let targetUrl = [config.baseURL, config.url].filter(Boolean).join("");
32
47
  if (config.params) targetUrl += `?${normalizedParams}`;
33
- const response = await fetch(targetUrl, {
48
+ const response = await globalThis.fetch(targetUrl, {
34
49
  credentials: config.credentials || "same-origin",
35
50
  method: config.method?.toUpperCase(),
36
51
  body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),
37
52
  signal: config.signal,
38
53
  headers: {
39
54
  ...config.contentType && config.contentType !== "multipart/form-data" ? { "Content-Type": config.contentType } : {},
40
- ...Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers
55
+ ...serializeHeaders(config.headers)
41
56
  }
42
57
  });
43
58
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.cjs","names":[],"sources":["../../src/clients/fetch.ts"],"sourcesContent":["/**\n * RequestCredentials\n */\nexport type RequestCredentials = 'omit' | 'same-origin' | 'include'\n\n/**\n * Subset of FetchRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n headers?: Array<[string, string]> | Record<string, string>\n credentials?: RequestCredentials\n contentType?: string\n}\n\n/**\n * Subset of FetchResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: Headers\n}\n\nlet _config: Partial<RequestConfig> = {}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: Partial<RequestConfig>) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\nexport type ResponseErrorConfig<TError = unknown> = TError\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nexport const client = async <TResponseData, _TError = unknown, RequestData = unknown>(\n paramsConfig: RequestConfig<RequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const normalizedParams = new URLSearchParams()\n\n const config = mergeConfig(getConfig(), paramsConfig)\n\n Object.entries(config.params || {}).forEach(([key, value]) => {\n if (value !== undefined) {\n normalizedParams.append(key, value === null ? 'null' : value.toString())\n }\n })\n\n let targetUrl = [config.baseURL, config.url].filter(Boolean).join('')\n\n if (config.params) {\n targetUrl += `?${normalizedParams}`\n }\n\n const response = await fetch(targetUrl, {\n credentials: config.credentials || 'same-origin',\n method: config.method?.toUpperCase(),\n body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),\n signal: config.signal,\n headers: {\n ...(config.contentType && config.contentType !== 'multipart/form-data' ? { 'Content-Type': config.contentType } : {}),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n })\n\n const data = [204, 205, 304].includes(response.status) || !response.body ? {} : await response.json()\n\n return {\n data: data as TResponseData,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers as Headers,\n }\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;;;;AA+BA,IAAI,UAAkC,EAAE;AAExC,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAAmC;CAC3D,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;AAUR,MAAa,SAAS,OACpB,cACA,aAC2C;CAC3C,MAAM,mBAAmB,IAAI,iBAAiB;CAE9C,MAAM,SAAS,YAAY,WAAW,EAAE,aAAa;CAErD,OAAO,QAAQ,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EAC5D,IAAI,UAAU,KAAA,GACZ,iBAAiB,OAAO,KAAK,UAAU,OAAO,SAAS,MAAM,UAAU,CAAC;GAE1E;CAEF,IAAI,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG;CAErE,IAAI,OAAO,QACT,aAAa,IAAI;CAGnB,MAAM,WAAW,MAAM,MAAM,WAAW;EACtC,aAAa,OAAO,eAAe;EACnC,QAAQ,OAAO,QAAQ,aAAa;EACpC,MAAM,OAAO,gBAAgB,WAAW,OAAO,OAAO,KAAK,UAAU,OAAO,KAAK;EACjF,QAAQ,OAAO;EACf,SAAS;GACP,GAAI,OAAO,eAAe,OAAO,gBAAgB,wBAAwB,EAAE,gBAAgB,OAAO,aAAa,GAAG,EAAE;GACpH,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;GACjF;EACF,CAAC;CAIF,OAAO;EACL,MAHW;GAAC;GAAK;GAAK;GAAI,CAAC,SAAS,SAAS,OAAO,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,MAAM,SAAS,MAAM;EAInG,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,SAAS,SAAS;EACnB;;AAGH,OAAO,YAAY;AACnB,OAAO,YAAY"}
1
+ {"version":3,"file":"fetch.cjs","names":[],"sources":["../../src/clients/fetch.ts"],"sourcesContent":["/**\n * RequestCredentials\n */\nexport type RequestCredentials = 'omit' | 'same-origin' | 'include'\n\n/**\n * Header values may be objects (e.g. JSON-encoded filter headers like `X-Filter`).\n * Non-string values are JSON-serialized before the request is sent.\n */\nexport type HeaderValue = string | number | boolean | null | undefined | object\nexport type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>\n\n/**\n * Subset of FetchRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n headers?: HeadersInit\n credentials?: RequestCredentials\n contentType?: string\n}\n\n/**\n * Subset of FetchResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: Headers\n}\n\nlet _config: Partial<RequestConfig> = {}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: Partial<RequestConfig>) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\n/**\n * Serializes header values into the string form `fetch` expects.\n * Objects (including arrays) are JSON-stringified so spec-defined object\n * headers like `X-Filter` are sent in their canonical JSON-string form.\n */\nfunction serializeHeaders(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {}\n const entries = Array.isArray(headers) ? headers : Object.entries(headers)\n const result: Record<string, string> = {}\n for (const [key, value] of entries) {\n if (value === undefined || value === null) continue\n result[key] = typeof value === 'string' ? value : typeof value === 'object' ? JSON.stringify(value) : String(value)\n }\n return result\n}\n\nexport type ResponseErrorConfig<TError = unknown> = TError\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nexport const client = async <TResponseData, _TError = unknown, RequestData = unknown>(\n paramsConfig: RequestConfig<RequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const normalizedParams = new URLSearchParams()\n\n const config = mergeConfig(getConfig(), paramsConfig)\n\n Object.entries(config.params || {}).forEach(([key, value]) => {\n if (value !== undefined) {\n normalizedParams.append(key, value === null ? 'null' : value.toString())\n }\n })\n\n let targetUrl = [config.baseURL, config.url].filter(Boolean).join('')\n\n if (config.params) {\n targetUrl += `?${normalizedParams}`\n }\n\n const response = await globalThis.fetch(targetUrl, {\n credentials: config.credentials || 'same-origin',\n method: config.method?.toUpperCase(),\n body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),\n signal: config.signal,\n headers: {\n ...(config.contentType && config.contentType !== 'multipart/form-data' ? { 'Content-Type': config.contentType } : {}),\n ...serializeHeaders(config.headers),\n },\n })\n\n const data = [204, 205, 304].includes(response.status) || !response.body ? {} : await response.json()\n\n return {\n data: data as TResponseData,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers as Headers,\n }\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;;;;;AAsCA,IAAI,UAAkC,EAAE;AAExC,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAAmC;CAC3D,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;;;;;;AAQR,SAAS,iBAAiB,SAA0D;CAClF,IAAI,CAAC,SAAS,OAAO,EAAE;CACvB,MAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG,UAAU,OAAO,QAAQ,QAAQ;CAC1E,MAAM,SAAiC,EAAE;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS;EAClC,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;EAC3C,OAAO,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,UAAU,WAAW,KAAK,UAAU,MAAM,GAAG,OAAO,MAAM;;CAErH,OAAO;;AAUT,MAAa,SAAS,OACpB,cACA,aAC2C;CAC3C,MAAM,mBAAmB,IAAI,iBAAiB;CAE9C,MAAM,SAAS,YAAY,WAAW,EAAE,aAAa;CAErD,OAAO,QAAQ,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EAC5D,IAAI,UAAU,KAAA,GACZ,iBAAiB,OAAO,KAAK,UAAU,OAAO,SAAS,MAAM,UAAU,CAAC;GAE1E;CAEF,IAAI,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG;CAErE,IAAI,OAAO,QACT,aAAa,IAAI;CAGnB,MAAM,WAAW,MAAM,WAAW,MAAM,WAAW;EACjD,aAAa,OAAO,eAAe;EACnC,QAAQ,OAAO,QAAQ,aAAa;EACpC,MAAM,OAAO,gBAAgB,WAAW,OAAO,OAAO,KAAK,UAAU,OAAO,KAAK;EACjF,QAAQ,OAAO;EACf,SAAS;GACP,GAAI,OAAO,eAAe,OAAO,gBAAgB,wBAAwB,EAAE,gBAAgB,OAAO,aAAa,GAAG,EAAE;GACpH,GAAG,iBAAiB,OAAO,QAAQ;GACpC;EACF,CAAC;CAIF,OAAO;EACL,MAHW;GAAC;GAAK;GAAK;GAAI,CAAC,SAAS,SAAS,OAAO,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,MAAM,SAAS,MAAM;EAInG,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,SAAS,SAAS;EACnB;;AAGH,OAAO,YAAY;AACnB,OAAO,YAAY"}
@@ -5,6 +5,12 @@ import { t as __name } from "../chunk--u3MIqq1.js";
5
5
  * RequestCredentials
6
6
  */
7
7
  type RequestCredentials = 'omit' | 'same-origin' | 'include';
8
+ /**
9
+ * Header values may be objects (e.g. JSON-encoded filter headers like `X-Filter`).
10
+ * Non-string values are JSON-serialized before the request is sent.
11
+ */
12
+ type HeaderValue = string | number | boolean | null | undefined | object;
13
+ type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>;
8
14
  /**
9
15
  * Subset of FetchRequestConfig
10
16
  */
@@ -16,7 +22,7 @@ type RequestConfig<TData = unknown> = {
16
22
  data?: TData | FormData;
17
23
  responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';
18
24
  signal?: AbortSignal;
19
- headers?: Array<[string, string]> | Record<string, string>;
25
+ headers?: HeadersInit;
20
26
  credentials?: RequestCredentials;
21
27
  contentType?: string;
22
28
  };
@@ -40,5 +46,5 @@ declare const client: {
40
46
  setConfig: (config: Partial<RequestConfig>) => Partial<RequestConfig<unknown>>;
41
47
  };
42
48
  //#endregion
43
- export { Client, RequestConfig, RequestCredentials, ResponseConfig, ResponseErrorConfig, client, client as default, getConfig, mergeConfig, setConfig };
49
+ export { Client, HeaderValue, HeadersInit, RequestConfig, RequestCredentials, ResponseConfig, ResponseErrorConfig, client, client as default, getConfig, mergeConfig, setConfig };
44
50
  //# sourceMappingURL=fetch.d.ts.map
@@ -18,6 +18,21 @@ const mergeConfig = (...configs) => {
18
18
  };
19
19
  }, {});
20
20
  };
21
+ /**
22
+ * Serializes header values into the string form `fetch` expects.
23
+ * Objects (including arrays) are JSON-stringified so spec-defined object
24
+ * headers like `X-Filter` are sent in their canonical JSON-string form.
25
+ */
26
+ function serializeHeaders(headers) {
27
+ if (!headers) return {};
28
+ const entries = Array.isArray(headers) ? headers : Object.entries(headers);
29
+ const result = {};
30
+ for (const [key, value] of entries) {
31
+ if (value === void 0 || value === null) continue;
32
+ result[key] = typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value);
33
+ }
34
+ return result;
35
+ }
21
36
  const client = async (paramsConfig, _request) => {
22
37
  const normalizedParams = new URLSearchParams();
23
38
  const config = mergeConfig(getConfig(), paramsConfig);
@@ -26,14 +41,14 @@ const client = async (paramsConfig, _request) => {
26
41
  });
27
42
  let targetUrl = [config.baseURL, config.url].filter(Boolean).join("");
28
43
  if (config.params) targetUrl += `?${normalizedParams}`;
29
- const response = await fetch(targetUrl, {
44
+ const response = await globalThis.fetch(targetUrl, {
30
45
  credentials: config.credentials || "same-origin",
31
46
  method: config.method?.toUpperCase(),
32
47
  body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),
33
48
  signal: config.signal,
34
49
  headers: {
35
50
  ...config.contentType && config.contentType !== "multipart/form-data" ? { "Content-Type": config.contentType } : {},
36
- ...Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers
51
+ ...serializeHeaders(config.headers)
37
52
  }
38
53
  });
39
54
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","names":[],"sources":["../../src/clients/fetch.ts"],"sourcesContent":["/**\n * RequestCredentials\n */\nexport type RequestCredentials = 'omit' | 'same-origin' | 'include'\n\n/**\n * Subset of FetchRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n headers?: Array<[string, string]> | Record<string, string>\n credentials?: RequestCredentials\n contentType?: string\n}\n\n/**\n * Subset of FetchResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: Headers\n}\n\nlet _config: Partial<RequestConfig> = {}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: Partial<RequestConfig>) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\nexport type ResponseErrorConfig<TError = unknown> = TError\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nexport const client = async <TResponseData, _TError = unknown, RequestData = unknown>(\n paramsConfig: RequestConfig<RequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const normalizedParams = new URLSearchParams()\n\n const config = mergeConfig(getConfig(), paramsConfig)\n\n Object.entries(config.params || {}).forEach(([key, value]) => {\n if (value !== undefined) {\n normalizedParams.append(key, value === null ? 'null' : value.toString())\n }\n })\n\n let targetUrl = [config.baseURL, config.url].filter(Boolean).join('')\n\n if (config.params) {\n targetUrl += `?${normalizedParams}`\n }\n\n const response = await fetch(targetUrl, {\n credentials: config.credentials || 'same-origin',\n method: config.method?.toUpperCase(),\n body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),\n signal: config.signal,\n headers: {\n ...(config.contentType && config.contentType !== 'multipart/form-data' ? { 'Content-Type': config.contentType } : {}),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n })\n\n const data = [204, 205, 304].includes(response.status) || !response.body ? {} : await response.json()\n\n return {\n data: data as TResponseData,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers as Headers,\n }\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;AA+BA,IAAI,UAAkC,EAAE;AAExC,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAAmC;CAC3D,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;AAUR,MAAa,SAAS,OACpB,cACA,aAC2C;CAC3C,MAAM,mBAAmB,IAAI,iBAAiB;CAE9C,MAAM,SAAS,YAAY,WAAW,EAAE,aAAa;CAErD,OAAO,QAAQ,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EAC5D,IAAI,UAAU,KAAA,GACZ,iBAAiB,OAAO,KAAK,UAAU,OAAO,SAAS,MAAM,UAAU,CAAC;GAE1E;CAEF,IAAI,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG;CAErE,IAAI,OAAO,QACT,aAAa,IAAI;CAGnB,MAAM,WAAW,MAAM,MAAM,WAAW;EACtC,aAAa,OAAO,eAAe;EACnC,QAAQ,OAAO,QAAQ,aAAa;EACpC,MAAM,OAAO,gBAAgB,WAAW,OAAO,OAAO,KAAK,UAAU,OAAO,KAAK;EACjF,QAAQ,OAAO;EACf,SAAS;GACP,GAAI,OAAO,eAAe,OAAO,gBAAgB,wBAAwB,EAAE,gBAAgB,OAAO,aAAa,GAAG,EAAE;GACpH,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;GACjF;EACF,CAAC;CAIF,OAAO;EACL,MAHW;GAAC;GAAK;GAAK;GAAI,CAAC,SAAS,SAAS,OAAO,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,MAAM,SAAS,MAAM;EAInG,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,SAAS,SAAS;EACnB;;AAGH,OAAO,YAAY;AACnB,OAAO,YAAY"}
1
+ {"version":3,"file":"fetch.js","names":[],"sources":["../../src/clients/fetch.ts"],"sourcesContent":["/**\n * RequestCredentials\n */\nexport type RequestCredentials = 'omit' | 'same-origin' | 'include'\n\n/**\n * Header values may be objects (e.g. JSON-encoded filter headers like `X-Filter`).\n * Non-string values are JSON-serialized before the request is sent.\n */\nexport type HeaderValue = string | number | boolean | null | undefined | object\nexport type HeadersInit = Array<[string, HeaderValue]> | Record<string, HeaderValue>\n\n/**\n * Subset of FetchRequestConfig\n */\nexport type RequestConfig<TData = unknown> = {\n baseURL?: string\n url?: string\n method?: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD'\n params?: unknown\n data?: TData | FormData\n responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n signal?: AbortSignal\n headers?: HeadersInit\n credentials?: RequestCredentials\n contentType?: string\n}\n\n/**\n * Subset of FetchResponse\n */\nexport type ResponseConfig<TData = unknown> = {\n data: TData\n status: number\n statusText: string\n headers: Headers\n}\n\nlet _config: Partial<RequestConfig> = {}\n\nexport const getConfig = () => _config\n\nexport const setConfig = (config: Partial<RequestConfig>) => {\n _config = config\n return getConfig()\n}\n\nexport const mergeConfig = <T extends RequestConfig>(...configs: Array<Partial<T>>): Partial<T> => {\n return configs.reduce<Partial<T>>((merged, config) => {\n return {\n ...merged,\n ...config,\n headers: {\n ...(Array.isArray(merged.headers) ? Object.fromEntries(merged.headers) : merged.headers),\n ...(Array.isArray(config.headers) ? Object.fromEntries(config.headers) : config.headers),\n },\n }\n }, {})\n}\n\n/**\n * Serializes header values into the string form `fetch` expects.\n * Objects (including arrays) are JSON-stringified so spec-defined object\n * headers like `X-Filter` are sent in their canonical JSON-string form.\n */\nfunction serializeHeaders(headers: HeadersInit | undefined): Record<string, string> {\n if (!headers) return {}\n const entries = Array.isArray(headers) ? headers : Object.entries(headers)\n const result: Record<string, string> = {}\n for (const [key, value] of entries) {\n if (value === undefined || value === null) continue\n result[key] = typeof value === 'string' ? value : typeof value === 'object' ? JSON.stringify(value) : String(value)\n }\n return result\n}\n\nexport type ResponseErrorConfig<TError = unknown> = TError\n\nexport type Client = <TResponseData, _TError = unknown, TRequestData = unknown>(\n config: RequestConfig<TRequestData>,\n request?: unknown,\n) => Promise<ResponseConfig<TResponseData>>\n\nexport const client = async <TResponseData, _TError = unknown, RequestData = unknown>(\n paramsConfig: RequestConfig<RequestData>,\n _request?: unknown,\n): Promise<ResponseConfig<TResponseData>> => {\n const normalizedParams = new URLSearchParams()\n\n const config = mergeConfig(getConfig(), paramsConfig)\n\n Object.entries(config.params || {}).forEach(([key, value]) => {\n if (value !== undefined) {\n normalizedParams.append(key, value === null ? 'null' : value.toString())\n }\n })\n\n let targetUrl = [config.baseURL, config.url].filter(Boolean).join('')\n\n if (config.params) {\n targetUrl += `?${normalizedParams}`\n }\n\n const response = await globalThis.fetch(targetUrl, {\n credentials: config.credentials || 'same-origin',\n method: config.method?.toUpperCase(),\n body: config.data instanceof FormData ? config.data : JSON.stringify(config.data),\n signal: config.signal,\n headers: {\n ...(config.contentType && config.contentType !== 'multipart/form-data' ? { 'Content-Type': config.contentType } : {}),\n ...serializeHeaders(config.headers),\n },\n })\n\n const data = [204, 205, 304].includes(response.status) || !response.body ? {} : await response.json()\n\n return {\n data: data as TResponseData,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers as Headers,\n }\n}\n\nclient.getConfig = getConfig\nclient.setConfig = setConfig\n\nexport default client\n"],"mappings":";;AAsCA,IAAI,UAAkC,EAAE;AAExC,MAAa,kBAAkB;AAE/B,MAAa,aAAa,WAAmC;CAC3D,UAAU;CACV,OAAO,WAAW;;AAGpB,MAAa,eAAwC,GAAG,YAA2C;CACjG,OAAO,QAAQ,QAAoB,QAAQ,WAAW;EACpD,OAAO;GACL,GAAG;GACH,GAAG;GACH,SAAS;IACP,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IAChF,GAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG,OAAO,YAAY,OAAO,QAAQ,GAAG,OAAO;IACjF;GACF;IACA,EAAE,CAAC;;;;;;;AAQR,SAAS,iBAAiB,SAA0D;CAClF,IAAI,CAAC,SAAS,OAAO,EAAE;CACvB,MAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG,UAAU,OAAO,QAAQ,QAAQ;CAC1E,MAAM,SAAiC,EAAE;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS;EAClC,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;EAC3C,OAAO,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,UAAU,WAAW,KAAK,UAAU,MAAM,GAAG,OAAO,MAAM;;CAErH,OAAO;;AAUT,MAAa,SAAS,OACpB,cACA,aAC2C;CAC3C,MAAM,mBAAmB,IAAI,iBAAiB;CAE9C,MAAM,SAAS,YAAY,WAAW,EAAE,aAAa;CAErD,OAAO,QAAQ,OAAO,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EAC5D,IAAI,UAAU,KAAA,GACZ,iBAAiB,OAAO,KAAK,UAAU,OAAO,SAAS,MAAM,UAAU,CAAC;GAE1E;CAEF,IAAI,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,CAAC,OAAO,QAAQ,CAAC,KAAK,GAAG;CAErE,IAAI,OAAO,QACT,aAAa,IAAI;CAGnB,MAAM,WAAW,MAAM,WAAW,MAAM,WAAW;EACjD,aAAa,OAAO,eAAe;EACnC,QAAQ,OAAO,QAAQ,aAAa;EACpC,MAAM,OAAO,gBAAgB,WAAW,OAAO,OAAO,KAAK,UAAU,OAAO,KAAK;EACjF,QAAQ,OAAO;EACf,SAAS;GACP,GAAI,OAAO,eAAe,OAAO,gBAAgB,wBAAwB,EAAE,gBAAgB,OAAO,aAAa,GAAG,EAAE;GACpH,GAAG,iBAAiB,OAAO,QAAQ;GACpC;EACF,CAAC;CAIF,OAAO;EACL,MAHW;GAAC;GAAK;GAAK;GAAI,CAAC,SAAS,SAAS,OAAO,IAAI,CAAC,SAAS,OAAO,EAAE,GAAG,MAAM,SAAS,MAAM;EAInG,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,SAAS,SAAS;EACnB;;AAGH,OAAO,YAAY;AACnB,OAAO,YAAY"}
package/dist/index.cjs CHANGED
@@ -191,6 +191,26 @@ function isValidVarName(name) {
191
191
  if (!name || reservedWords.has(name)) return false;
192
192
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
193
193
  }
194
+ /**
195
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
196
+ * otherwise prefixes it with `_` so the result is a valid identifier.
197
+ *
198
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
199
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
200
+ * variable, type, or function names.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * ensureValidVarName('409') // '_409'
205
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
206
+ * ensureValidVarName('Pet') // 'Pet'
207
+ * ensureValidVarName('class') // '_class'
208
+ * ```
209
+ */
210
+ function ensureValidVarName(name) {
211
+ if (!name || isValidVarName(name)) return name;
212
+ return `_${name}`;
213
+ }
194
214
  //#endregion
195
215
  //#region ../../internals/utils/src/urlPath.ts
196
216
  /**
@@ -392,6 +412,10 @@ function getStatusCodeNumber(statusCode) {
392
412
  const code = Number(statusCode);
393
413
  return Number.isNaN(code) ? null : code;
394
414
  }
415
+ function isSuccessStatusCode(statusCode) {
416
+ const code = getStatusCodeNumber(statusCode);
417
+ return code !== null && code >= 200 && code < 300;
418
+ }
395
419
  function isErrorStatusCode(statusCode) {
396
420
  const code = getStatusCodeNumber(statusCode);
397
421
  return code !== null && code >= 400;
@@ -399,6 +423,9 @@ function isErrorStatusCode(statusCode) {
399
423
  function resolveErrorNames(node, resolver) {
400
424
  return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
401
425
  }
426
+ function resolveSuccessNames(node, resolver) {
427
+ return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
428
+ }
402
429
  function resolveStatusCodeNames(node, resolver) {
403
430
  return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
404
431
  }
@@ -588,7 +615,8 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
588
615
  const queryParamsMapping = paramsCasing ? buildParamsMapping(originalQueryParams, casedQueryParams) : null;
589
616
  const headerParamsMapping = paramsCasing ? buildParamsMapping(originalHeaderParams, casedHeaderParams) : null;
590
617
  const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
591
- const responseName = tsResolver.resolveResponseName(node);
618
+ const successNames = resolveSuccessNames(node, tsResolver);
619
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
592
620
  const queryParamsName = originalQueryParams.length > 0 ? tsResolver.resolveQueryParamsName(node, originalQueryParams[0]) : null;
593
621
  const headerParamsName = originalHeaderParams.length > 0 ? tsResolver.resolveHeaderParamsName(node, originalHeaderParams[0]) : null;
594
622
  const zodResponseName = zodResolver && parser === "zod" ? zodResolver.resolveResponseName?.(node) : null;
@@ -654,7 +682,7 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
654
682
  }) },
655
683
  returnType,
656
684
  children: [
657
- isConfigurable ? `const { client: request = fetch, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = config` : "",
685
+ isConfigurable ? `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = config` : "",
658
686
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
659
687
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
660
688
  pathParamsMapping && Object.entries(pathParamsMapping).filter(([originalName, camelCaseName]) => isValidVarName(originalName) && originalName !== camelCaseName).map(([originalName, camelCaseName]) => `const ${originalName} = ${camelCaseName}`).join("\n"),
@@ -673,7 +701,7 @@ function Client({ name, isExportable = true, isIndexable = true, returnType, bas
673
701
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
674
702
  (isFormData || isMultipleContentTypes && hasFormData) && requestName && "const formData = buildFormData(requestData)",
675
703
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
676
- isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await fetch<${generics.join(", ")}>(${clientParams.toCall()})`,
704
+ isConfigurable ? `const res = await request<${generics.join(", ")}>(${clientParams.toCall()})` : `const res = await client<${generics.join(", ")}>(${clientParams.toCall()})`,
677
705
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)("br", {}),
678
706
  childrenElement
679
707
  ]
@@ -694,7 +722,8 @@ function buildHeaders(contentType, hasHeaderParams) {
694
722
  * Includes response type, error type, and optional request type.
695
723
  */
696
724
  function buildGenerics(node, tsResolver) {
697
- const responseName = tsResolver.resolveResponseName(node);
725
+ const successNames = resolveSuccessNames(node, tsResolver);
726
+ const responseName = successNames.length > 0 ? successNames.join(" | ") : tsResolver.resolveResponseName(node);
698
727
  const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
699
728
  const errorNames = node.responses.filter((r) => Number.parseInt(r.statusCode, 10) >= 400).map((r) => tsResolver.resolveResponseStatusName(node, r.statusCode));
700
729
  return [
@@ -801,7 +830,7 @@ function generateMethod$1({ node, name, tsResolver, zodResolver, baseURL, dataRe
801
830
  zodResolver
802
831
  });
803
832
  return `${jsdoc}async ${name}(${paramsSignature}) {\n${[
804
- `const { client: request = fetch, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
833
+ `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
805
834
  "",
806
835
  requestDataLine,
807
836
  formDataLine,
@@ -1008,16 +1037,24 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
1008
1037
  meta: file.meta,
1009
1038
  banner: resolver.resolveBanner(ctx.meta, {
1010
1039
  output,
1011
- config
1040
+ config,
1041
+ file: {
1042
+ path: file.path,
1043
+ baseName: file.baseName
1044
+ }
1012
1045
  }),
1013
1046
  footer: resolver.resolveFooter(ctx.meta, {
1014
1047
  output,
1015
- config
1048
+ config,
1049
+ file: {
1050
+ path: file.path,
1051
+ baseName: file.baseName
1052
+ }
1016
1053
  }),
1017
1054
  children: [
1018
1055
  importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1019
1056
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1020
- name: "fetch",
1057
+ name: "client",
1021
1058
  path: importPath
1022
1059
  }),
1023
1060
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
@@ -1035,7 +1072,7 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
1035
1072
  })
1036
1073
  ] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1037
1074
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1038
- name: ["fetch"],
1075
+ name: ["client"],
1039
1076
  root: file.path,
1040
1077
  path: node_path.default.resolve(root, ".kubb/client.ts")
1041
1078
  }),
@@ -1111,11 +1148,19 @@ const classClientGenerator = (0, _kubb_core.defineGenerator)({
1111
1148
  meta: sdkFile.meta,
1112
1149
  banner: resolver.resolveBanner(ctx.meta, {
1113
1150
  output,
1114
- config
1151
+ config,
1152
+ file: {
1153
+ path: sdkFile.path,
1154
+ baseName: sdkFile.baseName
1155
+ }
1115
1156
  }),
1116
1157
  footer: resolver.resolveFooter(ctx.meta, {
1117
1158
  output,
1118
- config
1159
+ config,
1160
+ file: {
1161
+ path: sdkFile.path,
1162
+ baseName: sdkFile.baseName
1163
+ }
1119
1164
  }),
1120
1165
  children: [
1121
1166
  importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
@@ -1208,15 +1253,23 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
1208
1253
  meta: meta.file.meta,
1209
1254
  banner: resolver.resolveBanner(ctx.meta, {
1210
1255
  output,
1211
- config
1256
+ config,
1257
+ file: {
1258
+ path: meta.file.path,
1259
+ baseName: meta.file.baseName
1260
+ }
1212
1261
  }),
1213
1262
  footer: resolver.resolveFooter(ctx.meta, {
1214
1263
  output,
1215
- config
1264
+ config,
1265
+ file: {
1266
+ path: meta.file.path,
1267
+ baseName: meta.file.baseName
1268
+ }
1216
1269
  }),
1217
1270
  children: [
1218
1271
  importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1219
- name: "fetch",
1272
+ name: "client",
1220
1273
  path: importPath
1221
1274
  }), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1222
1275
  name: [
@@ -1227,7 +1280,7 @@ const clientGenerator = (0, _kubb_core.defineGenerator)({
1227
1280
  path: importPath,
1228
1281
  isTypeOnly: true
1229
1282
  })] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1230
- name: ["fetch"],
1283
+ name: ["client"],
1231
1284
  root: meta.file.path,
1232
1285
  path: node_path.default.resolve(root, ".kubb/client.ts")
1233
1286
  }), /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
@@ -1342,11 +1395,21 @@ const groupedClientGenerator = (0, _kubb_core.defineGenerator)({
1342
1395
  meta: file.meta,
1343
1396
  banner: resolver.resolveBanner(ctx.meta, {
1344
1397
  output,
1345
- config
1398
+ config,
1399
+ file: {
1400
+ path: file.path,
1401
+ baseName: file.baseName,
1402
+ isAggregation: true
1403
+ }
1346
1404
  }),
1347
1405
  footer: resolver.resolveFooter(ctx.meta, {
1348
1406
  output,
1349
- config
1407
+ config,
1408
+ file: {
1409
+ path: file.path,
1410
+ baseName: file.baseName,
1411
+ isAggregation: true
1412
+ }
1350
1413
  }),
1351
1414
  children: [clients.map((client) => /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1352
1415
  name: [client.name],
@@ -1416,11 +1479,19 @@ const operationsGenerator = (0, _kubb_core.defineGenerator)({
1416
1479
  meta: file.meta,
1417
1480
  banner: resolver.resolveBanner(ctx.meta, {
1418
1481
  output,
1419
- config
1482
+ config,
1483
+ file: {
1484
+ path: file.path,
1485
+ baseName: file.baseName
1486
+ }
1420
1487
  }),
1421
1488
  footer: resolver.resolveFooter(ctx.meta, {
1422
1489
  output,
1423
- config
1490
+ config,
1491
+ file: {
1492
+ path: file.path,
1493
+ baseName: file.baseName
1494
+ }
1424
1495
  }),
1425
1496
  children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Operations, {
1426
1497
  name,
@@ -1477,7 +1548,7 @@ function generateMethod({ node, name, tsResolver, zodResolver, baseURL, dataRetu
1477
1548
  zodResolver
1478
1549
  });
1479
1550
  return `${jsdoc} static async ${name}(${paramsSignature}) {\n${[
1480
- `const { client: request = fetch, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
1551
+ `const { client: request = client, ${isMultipleContentTypes ? `contentType = ${JSON.stringify(contentType)}, ` : ""}...requestConfig } = mergeConfig(this.#config, config)`,
1481
1552
  "",
1482
1553
  requestDataLine,
1483
1554
  formDataLine,
@@ -1655,16 +1726,24 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
1655
1726
  meta: file.meta,
1656
1727
  banner: resolver.resolveBanner(ctx.meta, {
1657
1728
  output,
1658
- config
1729
+ config,
1730
+ file: {
1731
+ path: file.path,
1732
+ baseName: file.baseName
1733
+ }
1659
1734
  }),
1660
1735
  footer: resolver.resolveFooter(ctx.meta, {
1661
1736
  output,
1662
- config
1737
+ config,
1738
+ file: {
1739
+ path: file.path,
1740
+ baseName: file.baseName
1741
+ }
1663
1742
  }),
1664
1743
  children: [
1665
1744
  importPath ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1666
1745
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1667
- name: "fetch",
1746
+ name: "client",
1668
1747
  path: importPath
1669
1748
  }),
1670
1749
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
@@ -1682,7 +1761,7 @@ const staticClassClientGenerator = (0, _kubb_core.defineGenerator)({
1682
1761
  })
1683
1762
  ] }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx_jsx_runtime.Fragment, { children: [
1684
1763
  /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
1685
- name: ["fetch"],
1764
+ name: ["client"],
1686
1765
  root: file.path,
1687
1766
  path: node_path.default.resolve(root, ".kubb/client.ts")
1688
1767
  }),
@@ -1765,7 +1844,8 @@ const resolverClient = (0, _kubb_core.defineResolver)(() => ({
1765
1844
  name: "default",
1766
1845
  pluginName: "plugin-client",
1767
1846
  default(name, type) {
1768
- return camelCase(name, { isFile: type === "file" });
1847
+ const resolved = camelCase(name, { isFile: type === "file" });
1848
+ return type === "file" ? resolved : ensureValidVarName(resolved);
1769
1849
  },
1770
1850
  resolveName(name) {
1771
1851
  return this.default(name, "function");
@@ -1774,13 +1854,13 @@ const resolverClient = (0, _kubb_core.defineResolver)(() => ({
1774
1854
  return this.default(name, type);
1775
1855
  },
1776
1856
  resolveClassName(name) {
1777
- return pascalCase(name);
1857
+ return ensureValidVarName(pascalCase(name));
1778
1858
  },
1779
1859
  resolveGroupName(name) {
1780
- return pascalCase(name);
1860
+ return ensureValidVarName(pascalCase(name));
1781
1861
  },
1782
1862
  resolveClientPropertyName(name) {
1783
- return camelCase(name);
1863
+ return ensureValidVarName(camelCase(name));
1784
1864
  },
1785
1865
  resolveUrlName(node) {
1786
1866
  const name = this.resolveName(node.operationId);