@zimic/fetch 0.1.0-canary.14 → 0.1.0-canary.16

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpSchema, HttpSchemaMethod, HttpSchemaPath, HttpMethod, HttpSearchParams, HttpRequest, HttpRequestHeadersSchema, AllowAnyStringInPathParams, LiteralHttpSchemaPathFromNonLiteral, HttpRequestSchema, HttpMethodSchema, HttpStatusCode, HttpResponse, HttpResponseBodySchema, HttpResponseHeadersSchema, JSONValue, HttpResponseSchemaStatusCode, HttpHeaders } from '@zimic/http';
1
+ import { HttpSchema, HttpSchemaMethod, HttpSchemaPath, HttpMethod, HttpHeadersSchema, HttpSearchParamsSchema, HttpRequest, HttpRequestHeadersSchema, AllowAnyStringInPathParams, LiteralHttpSchemaPathFromNonLiteral, HttpRequestSchema, HttpMethodSchema, HttpStatusCode, HttpResponse, HttpResponseBodySchema, HttpResponseHeadersSchema, JSONValue, HttpResponseSchemaStatusCode, HttpHeaders, HttpSearchParams } from '@zimic/http';
2
2
 
3
3
  declare const value: unique symbol;
4
4
  type JSONStringified<Value> = string & {
@@ -15,6 +15,7 @@ type DefaultNoExclude<Type, IfEmpty = never> = [undefined | void] extends Type ?
15
15
  type IfNever<Type, Yes, No = Type> = [Type] extends [never] ? Yes : No;
16
16
  type PossiblePromise<Type> = Type | PromiseLike<Type>;
17
17
  type ReplaceBy<Type, Source, Target> = Type extends Source ? Target : Type;
18
+ type RequiredByKey<Type, Key extends keyof Type> = Omit<Type, Key> & Required<Pick<Type, Key>>;
18
19
 
19
20
  type FetchRequestInitHeaders<RequestSchema extends HttpRequestSchema> = RequestSchema['headers'] | HttpHeaders<Default<RequestSchema['headers']>>;
20
21
  type FetchRequestInitWithHeaders<RequestSchema extends HttpRequestSchema> = [RequestSchema['headers']] extends [never] ? {
@@ -55,10 +56,12 @@ type FetchRequestInit<Schema extends HttpSchema, Method extends HttpSchemaMethod
55
56
  method: Method;
56
57
  } & (Path extends Path ? FetchRequestInitPerPath<Default<Default<Schema[Path][Method]>['request']>> : never);
57
58
  declare namespace FetchRequestInit {
58
- interface Defaults extends RequestInit {
59
+ /** The default options for each request sent by a fetch instance. */
60
+ interface Defaults extends Omit<RequestInit, 'headers'> {
59
61
  baseURL: string;
60
62
  method?: HttpMethod;
61
- searchParams?: HttpSearchParams;
63
+ headers?: HttpHeadersSchema;
64
+ searchParams?: HttpSearchParamsSchema;
62
65
  }
63
66
  }
64
67
  type AllFetchResponseStatusCode<MethodSchema extends HttpMethodSchema> = HttpResponseSchemaStatusCode<Default<MethodSchema['response']>>;
@@ -103,14 +106,13 @@ interface FetchFunction<Schema extends HttpSchema> {
103
106
  <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>>(input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>, init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>>;
104
107
  }
105
108
  interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
106
- onRequest?: (request: FetchRequest.Loose, fetch: Fetch<Schema>) => PossiblePromise<Request>;
107
- onResponse?: (response: FetchResponse.Loose, fetch: Fetch<Schema>) => PossiblePromise<Response>;
109
+ onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
110
+ onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
108
111
  }
109
- interface FetchClient<Schema extends HttpSchema> {
110
- defaults: FetchRequestInit.Defaults;
112
+ type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
113
+ interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
114
+ defaults: FetchDefaults;
111
115
  Request: FetchRequestConstructor<Schema>;
112
- onRequest?: FetchOptions<Schema>['onRequest'];
113
- onResponse?: FetchOptions<Schema>['onResponse'];
114
116
  isRequest: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(request: unknown, method: Method, path: Path) => request is FetchRequest<Schema, Method, Path>;
115
117
  isResponse: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(response: unknown, method: Method, path: Path) => response is FetchResponse<Schema, Method, Path>;
116
118
  isResponseError: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(error: unknown, method: Method, path: Path) => error is FetchResponseError<Schema, Method, Path>;
@@ -120,4 +122,4 @@ type InferFetchSchema<FetchInstance> = FetchInstance extends Fetch<infer Schema>
120
122
 
121
123
  declare function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema>;
122
124
 
123
- export { type Fetch, type FetchInput, type FetchOptions, FetchRequest, type FetchRequestConstructor, FetchRequestInit, FetchResponse, FetchResponseError, type InferFetchSchema, type JSONStringified, createFetch };
125
+ export { type Fetch, type FetchDefaults, type FetchInput, type FetchOptions, FetchRequest, type FetchRequestConstructor, FetchRequestInit, FetchResponse, FetchResponseError, type InferFetchSchema, type JSONStringified, createFetch };
package/dist/index.js CHANGED
@@ -76,8 +76,12 @@ var FetchClient = class {
76
76
  fetch;
77
77
  constructor({ onRequest, onResponse, ...defaults }) {
78
78
  this.fetch = this.createFetchFunction();
79
- this.fetch.defaults = defaults;
80
- this.fetch.Request = this.createRequestClass(defaults);
79
+ this.fetch.defaults = {
80
+ ...defaults,
81
+ headers: defaults.headers ?? {},
82
+ searchParams: defaults.searchParams ?? {}
83
+ };
84
+ this.fetch.Request = this.createRequestClass(this.fetch.defaults);
81
85
  this.fetch.onRequest = onRequest;
82
86
  this.fetch.onResponse = onResponse;
83
87
  }
@@ -100,8 +104,7 @@ var FetchClient = class {
100
104
  if (this.fetch.onRequest) {
101
105
  const requestAfterInterceptor = await this.fetch.onRequest(
102
106
  // Optimize type checking by narrowing the type of request
103
- request,
104
- this.fetch
107
+ request
105
108
  );
106
109
  if (requestAfterInterceptor !== request) {
107
110
  const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;
@@ -115,8 +118,7 @@ var FetchClient = class {
115
118
  if (this.fetch.onResponse) {
116
119
  const responseAfterInterceptor = await this.fetch.onResponse(
117
120
  // Optimize type checking by narrowing the type of response
118
- response,
119
- this.fetch
121
+ response
120
122
  );
121
123
  const isFetchResponse = responseAfterInterceptor instanceof Response && "request" in responseAfterInterceptor && responseAfterInterceptor.request instanceof this.fetch.Request;
122
124
  response = isFetchResponse ? responseAfterInterceptor : this.defineFetchResponseProperties(fetchRequest, responseAfterInterceptor);
@@ -150,24 +152,37 @@ var FetchClient = class {
150
152
  __name(this, "Request");
151
153
  }
152
154
  path;
153
- constructor(input, rawInit) {
154
- const init = { ...defaults, ...rawInit };
155
+ constructor(input, init) {
156
+ const initWithDefaults = { ...defaults, ...init };
157
+ const headersFromDefaults = new http.HttpHeaders(defaults.headers);
158
+ const headersFromInit = new http.HttpHeaders(init.headers);
155
159
  let url;
156
160
  if (input instanceof globalThis.Request) {
157
- super(
158
- // Optimize type checking by narrowing the type of input
159
- input,
160
- init
161
- );
161
+ const request = input;
162
+ const headersFromRequest = new http.HttpHeaders(input.headers);
163
+ initWithDefaults.headers = {
164
+ ...headersFromDefaults.toObject(),
165
+ ...headersFromRequest.toObject(),
166
+ ...headersFromInit.toObject()
167
+ };
168
+ super(request, initWithDefaults);
162
169
  url = new URL(input.url);
163
170
  } else {
164
- url = input instanceof URL ? new URL(input) : new URL(joinURL_default(init.baseURL, input));
165
- if (init.searchParams) {
166
- url.search = new http.HttpSearchParams(init.searchParams).toString();
167
- }
168
- super(url, init);
171
+ initWithDefaults.headers = {
172
+ ...headersFromDefaults.toObject(),
173
+ ...headersFromInit.toObject()
174
+ };
175
+ url = input instanceof URL ? new URL(input) : new URL(joinURL_default(initWithDefaults.baseURL, input));
176
+ const searchParamsFromDefaults = new http.HttpSearchParams(defaults.searchParams);
177
+ const searchParamsFromInit = new http.HttpSearchParams(initWithDefaults.searchParams);
178
+ initWithDefaults.searchParams = {
179
+ ...searchParamsFromDefaults.toObject(),
180
+ ...searchParamsFromInit.toObject()
181
+ };
182
+ url.search = new http.HttpSearchParams(initWithDefaults.searchParams).toString();
183
+ super(url, initWithDefaults);
169
184
  }
170
- this.path = excludeURLParams_default(url).toString().replace(init.baseURL, "");
185
+ this.path = excludeURLParams_default(url).toString().replace(initWithDefaults.baseURL, "");
171
186
  }
172
187
  clone() {
173
188
  const rawClone = super.clone();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-PAWJFY3S.mjs","../../zimic-utils/src/url/createRegExpFromURL.ts","../../zimic-utils/src/url/excludeURLParams.ts","../../zimic-utils/src/url/joinURL.ts","../src/client/FetchClient.ts","../src/client/factory.ts"],"names":["__defProp","__name","Request","HttpSearchParams"],"mappings":"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","file":"index.js","sourcesContent":["import { HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchResponse } from '../types/requests';\n\nclass FetchResponseError<\n Schema extends HttpSchema,\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n> extends Error {\n constructor(\n public request: FetchRequest<Schema, Method, Path>,\n public response: FetchResponse<Schema, Method, Path, true>,\n ) {\n super(`${request.method} ${request.url} failed with status ${response.status}: ${response.statusText}`);\n this.name = 'FetchResponseError';\n }\n\n get cause() {\n return this.response;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFetchRequestError = FetchResponseError<any, any, any>;\n\nexport default FetchResponseError;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\nexport { __name };\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map","export const URL_PATH_PARAM_REGEX = /\\/:([^/]+)/g;\n\nfunction createRegExpFromURL(url: string) {\n URL_PATH_PARAM_REGEX.lastIndex = 0;\n\n const urlWithReplacedPathParams = encodeURI(url)\n .replace(/([.()*?+$\\\\])/g, '\\\\$1')\n .replace(URL_PATH_PARAM_REGEX, '/(?<$1>[^/]+)')\n .replace(/(\\/+)$/, '(?:/+)?');\n\n return new RegExp(`^${urlWithReplacedPathParams}$`);\n}\n\nexport default createRegExpFromURL;\n","function excludeURLParams(url: URL) {\n url.hash = '';\n url.search = '';\n url.username = '';\n url.password = '';\n return url;\n}\n\nexport default excludeURLParams;\n","function joinURL(...parts: (URL | string)[]) {\n return parts\n .map((part, index) => {\n const isFirstPart = index === 0;\n const isLastPart = index === parts.length - 1;\n\n let partAsString = part.toString();\n\n if (!isFirstPart) {\n partAsString = partAsString.replace(/^\\//, '');\n }\n if (!isLastPart) {\n partAsString = partAsString.replace(/\\/$/, '');\n }\n\n return partAsString;\n })\n .filter((part) => part.length > 0)\n .join('/');\n}\n\nexport default joinURL;\n","import {\n HttpSchemaPath,\n HttpSchemaMethod,\n HttpSearchParams,\n LiteralHttpSchemaPathFromNonLiteral,\n HttpSchema,\n} from '@zimic/http';\nimport createRegexFromURL from '@zimic/utils/url/createRegExpFromURL';\nimport excludeURLParams from '@zimic/utils/url/excludeURLParams';\nimport joinURL from '@zimic/utils/url/joinURL';\n\nimport FetchResponseError from './errors/FetchResponseError';\nimport { FetchInput, FetchOptions, Fetch } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> {\n fetch: Fetch<Schema>;\n\n constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {\n this.fetch = this.createFetchFunction();\n this.fetch.defaults = defaults;\n this.fetch.Request = this.createRequestClass(defaults);\n this.fetch.onRequest = onRequest;\n this.fetch.onResponse = onResponse;\n }\n\n private createFetchFunction() {\n const fetch = async <\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) => {\n const request = await this.createFetchRequest<Method, Path>(input, init);\n const requestClone = request.clone();\n\n const rawResponse = await globalThis.fetch(\n // Optimize type checking by narrowing the type of request\n requestClone as Request,\n );\n const response = await this.createFetchResponse<\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >(request, rawResponse);\n\n return response;\n };\n\n Object.setPrototypeOf(fetch, this);\n\n return fetch as Fetch<Schema>;\n }\n\n private async createFetchRequest<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n let request = input instanceof Request ? input : new this.fetch.Request(input, init);\n\n if (this.fetch.onRequest) {\n const requestAfterInterceptor = await this.fetch.onRequest(\n // Optimize type checking by narrowing the type of request\n request as FetchRequest.Loose,\n this.fetch,\n );\n\n if (requestAfterInterceptor !== request) {\n const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;\n\n request = isFetchRequest\n ? (requestAfterInterceptor as Request as typeof request)\n : new this.fetch.Request(requestAfterInterceptor as FetchInput<Schema, Method, Path>, init);\n }\n }\n\n return request;\n }\n\n private async createFetchResponse<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, rawResponse: Response) {\n let response = this.defineFetchResponseProperties<Method, Path>(fetchRequest, rawResponse);\n\n if (this.fetch.onResponse) {\n const responseAfterInterceptor = await this.fetch.onResponse(\n // Optimize type checking by narrowing the type of response\n response as FetchResponse.Loose,\n this.fetch,\n );\n\n const isFetchResponse =\n responseAfterInterceptor instanceof Response &&\n 'request' in responseAfterInterceptor &&\n responseAfterInterceptor.request instanceof this.fetch.Request;\n\n response = isFetchResponse\n ? (responseAfterInterceptor as typeof response)\n : this.defineFetchResponseProperties<Method, Path>(fetchRequest, responseAfterInterceptor);\n }\n\n return response;\n }\n\n private defineFetchResponseProperties<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, response: Response) {\n const fetchResponse = response as FetchResponse<Schema, Method, Path>;\n\n Object.defineProperty(fetchResponse, 'request', {\n value: fetchRequest satisfies FetchResponse.Loose['request'],\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n let responseError: FetchResponse.Loose['error'] | undefined;\n\n Object.defineProperty(fetchResponse, 'error', {\n get() {\n if (responseError === undefined) {\n responseError = fetchResponse.ok ? null : new FetchResponseError(fetchRequest, fetchResponse);\n }\n return responseError;\n },\n enumerable: true,\n configurable: false,\n });\n\n return fetchResponse;\n }\n\n private createRequestClass(defaults: FetchRequestInit.Defaults) {\n class Request<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n > extends globalThis.Request {\n path: LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n\n constructor(\n input: FetchInput<Schema, Method, Path>,\n rawInit: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n const init = { ...defaults, ...rawInit };\n\n let url: URL;\n\n if (input instanceof globalThis.Request) {\n super(\n // Optimize type checking by narrowing the type of input\n input as globalThis.Request,\n init,\n );\n\n url = new URL(input.url);\n } else {\n url = input instanceof URL ? new URL(input) : new URL(joinURL(init.baseURL, input));\n\n if (init.searchParams) {\n url.search = new HttpSearchParams(init.searchParams).toString();\n }\n\n super(url, init);\n }\n\n this.path = excludeURLParams(url).toString().replace(init.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<\n Schema,\n Method,\n Path\n >;\n }\n\n clone(): Request<Method, Path> {\n const rawClone = super.clone();\n\n return new Request<Method, Path>(\n rawClone as unknown as FetchInput<Schema, Method, Path>,\n rawClone as unknown as FetchRequestInit<\n Schema,\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >,\n );\n }\n }\n\n return Request as FetchRequestConstructor<Schema>;\n }\n\n isRequest<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n request: unknown,\n method: Method,\n path: Path,\n ): request is FetchRequest<Schema, Method, Path> {\n return (\n request instanceof Request &&\n request.method === method &&\n 'path' in request &&\n typeof request.path === 'string' &&\n createRegexFromURL(path).test(request.path)\n );\n }\n\n isResponse<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n response: unknown,\n method: Method,\n path: Path,\n ): response is FetchResponse<Schema, Method, Path> {\n return (\n response instanceof Response &&\n 'request' in response &&\n 'error' in response &&\n this.isRequest(response.request, method, path)\n );\n }\n\n isResponseError<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n error: unknown,\n method: Method,\n path: Path,\n ): error is FetchResponseError<Schema, Method, Path> {\n return (\n error instanceof FetchResponseError &&\n error.request.method === method &&\n typeof error.request.path === 'string' &&\n createRegexFromURL(path).test(error.request.path)\n );\n }\n}\n\nexport default FetchClient;\n","import { HttpSchema } from '@zimic/http';\n\nimport FetchClient from './FetchClient';\nimport { FetchOptions, Fetch as PublicFetch } from './types/public';\n\nfunction createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): PublicFetch<Schema> {\n const { fetch } = new FetchClient<Schema>(options);\n return fetch;\n}\n\nexport default createFetch;\n"]}
1
+ {"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-PAWJFY3S.mjs","../../zimic-utils/src/url/createRegExpFromURL.ts","../../zimic-utils/src/url/excludeURLParams.ts","../../zimic-utils/src/url/joinURL.ts","../src/client/FetchClient.ts","../src/client/factory.ts"],"names":["__defProp","__name","Request","HttpHeaders","HttpSearchParams"],"mappings":"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","file":"index.js","sourcesContent":["import { HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchResponse } from '../types/requests';\n\nclass FetchResponseError<\n Schema extends HttpSchema,\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n> extends Error {\n constructor(\n public request: FetchRequest<Schema, Method, Path>,\n public response: FetchResponse<Schema, Method, Path, true>,\n ) {\n super(`${request.method} ${request.url} failed with status ${response.status}: ${response.statusText}`);\n this.name = 'FetchResponseError';\n }\n\n get cause() {\n return this.response;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFetchRequestError = FetchResponseError<any, any, any>;\n\nexport default FetchResponseError;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\nexport { __name };\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map","export const URL_PATH_PARAM_REGEX = /\\/:([^/]+)/g;\n\nfunction createRegExpFromURL(url: string) {\n URL_PATH_PARAM_REGEX.lastIndex = 0;\n\n const urlWithReplacedPathParams = encodeURI(url)\n .replace(/([.()*?+$\\\\])/g, '\\\\$1')\n .replace(URL_PATH_PARAM_REGEX, '/(?<$1>[^/]+)')\n .replace(/(\\/+)$/, '(?:/+)?');\n\n return new RegExp(`^${urlWithReplacedPathParams}$`);\n}\n\nexport default createRegExpFromURL;\n","function excludeURLParams(url: URL) {\n url.hash = '';\n url.search = '';\n url.username = '';\n url.password = '';\n return url;\n}\n\nexport default excludeURLParams;\n","function joinURL(...parts: (URL | string)[]) {\n return parts\n .map((part, index) => {\n const isFirstPart = index === 0;\n const isLastPart = index === parts.length - 1;\n\n let partAsString = part.toString();\n\n if (!isFirstPart) {\n partAsString = partAsString.replace(/^\\//, '');\n }\n if (!isLastPart) {\n partAsString = partAsString.replace(/\\/$/, '');\n }\n\n return partAsString;\n })\n .filter((part) => part.length > 0)\n .join('/');\n}\n\nexport default joinURL;\n","import {\n HttpSchemaPath,\n HttpSchemaMethod,\n HttpSearchParams,\n LiteralHttpSchemaPathFromNonLiteral,\n HttpSchema,\n HttpHeaders,\n} from '@zimic/http';\nimport createRegexFromURL from '@zimic/utils/url/createRegExpFromURL';\nimport excludeURLParams from '@zimic/utils/url/excludeURLParams';\nimport joinURL from '@zimic/utils/url/joinURL';\n\nimport FetchResponseError from './errors/FetchResponseError';\nimport { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> {\n fetch: Fetch<Schema>;\n\n constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {\n this.fetch = this.createFetchFunction();\n\n this.fetch.defaults = {\n ...defaults,\n headers: defaults.headers ?? {},\n searchParams: defaults.searchParams ?? {},\n };\n\n this.fetch.Request = this.createRequestClass(this.fetch.defaults);\n this.fetch.onRequest = onRequest;\n this.fetch.onResponse = onResponse;\n }\n\n private createFetchFunction() {\n const fetch = async <\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) => {\n const request = await this.createFetchRequest<Method, Path>(input, init);\n const requestClone = request.clone();\n\n const rawResponse = await globalThis.fetch(\n // Optimize type checking by narrowing the type of request\n requestClone as Request,\n );\n const response = await this.createFetchResponse<\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >(request, rawResponse);\n\n return response;\n };\n\n Object.setPrototypeOf(fetch, this);\n\n return fetch as Fetch<Schema>;\n }\n\n private async createFetchRequest<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n let request = input instanceof Request ? input : new this.fetch.Request(input, init);\n\n if (this.fetch.onRequest) {\n const requestAfterInterceptor = await this.fetch.onRequest(\n // Optimize type checking by narrowing the type of request\n request as FetchRequest.Loose,\n );\n\n if (requestAfterInterceptor !== request) {\n const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;\n\n request = isFetchRequest\n ? (requestAfterInterceptor as Request as typeof request)\n : new this.fetch.Request(requestAfterInterceptor as FetchInput<Schema, Method, Path>, init);\n }\n }\n\n return request;\n }\n\n private async createFetchResponse<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, rawResponse: Response) {\n let response = this.defineFetchResponseProperties<Method, Path>(fetchRequest, rawResponse);\n\n if (this.fetch.onResponse) {\n const responseAfterInterceptor = await this.fetch.onResponse(\n // Optimize type checking by narrowing the type of response\n response as FetchResponse.Loose,\n );\n\n const isFetchResponse =\n responseAfterInterceptor instanceof Response &&\n 'request' in responseAfterInterceptor &&\n responseAfterInterceptor.request instanceof this.fetch.Request;\n\n response = isFetchResponse\n ? (responseAfterInterceptor as typeof response)\n : this.defineFetchResponseProperties<Method, Path>(fetchRequest, responseAfterInterceptor);\n }\n\n return response;\n }\n\n private defineFetchResponseProperties<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, response: Response) {\n const fetchResponse = response as FetchResponse<Schema, Method, Path>;\n\n Object.defineProperty(fetchResponse, 'request', {\n value: fetchRequest satisfies FetchResponse.Loose['request'],\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n let responseError: FetchResponse.Loose['error'] | undefined;\n\n Object.defineProperty(fetchResponse, 'error', {\n get() {\n if (responseError === undefined) {\n responseError = fetchResponse.ok ? null : new FetchResponseError(fetchRequest, fetchResponse);\n }\n return responseError;\n },\n enumerable: true,\n configurable: false,\n });\n\n return fetchResponse;\n }\n\n private createRequestClass(defaults: FetchDefaults) {\n class Request<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n > extends globalThis.Request {\n path: LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n\n constructor(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n const initWithDefaults = { ...defaults, ...init };\n\n const headersFromDefaults = new HttpHeaders(defaults.headers);\n const headersFromInit = new HttpHeaders((init satisfies RequestInit as RequestInit).headers);\n\n let url: URL;\n\n if (input instanceof globalThis.Request) {\n // Optimize type checking by narrowing the type of input\n const request = input as globalThis.Request;\n const headersFromRequest = new HttpHeaders(input.headers);\n\n initWithDefaults.headers = {\n ...headersFromDefaults.toObject(),\n ...headersFromRequest.toObject(),\n ...headersFromInit.toObject(),\n };\n\n super(request, initWithDefaults);\n\n url = new URL(input.url);\n } else {\n initWithDefaults.headers = {\n ...headersFromDefaults.toObject(),\n ...headersFromInit.toObject(),\n };\n\n url = input instanceof URL ? new URL(input) : new URL(joinURL(initWithDefaults.baseURL, input));\n\n const searchParamsFromDefaults = new HttpSearchParams(defaults.searchParams);\n const searchParamsFromInit = new HttpSearchParams(initWithDefaults.searchParams);\n\n initWithDefaults.searchParams = {\n ...searchParamsFromDefaults.toObject(),\n ...searchParamsFromInit.toObject(),\n };\n\n url.search = new HttpSearchParams(initWithDefaults.searchParams).toString();\n\n super(url, initWithDefaults);\n }\n\n this.path = excludeURLParams(url)\n .toString()\n .replace(initWithDefaults.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n }\n\n clone(): Request<Method, Path> {\n const rawClone = super.clone();\n\n return new Request<Method, Path>(\n rawClone as unknown as FetchInput<Schema, Method, Path>,\n rawClone as unknown as FetchRequestInit<\n Schema,\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >,\n );\n }\n }\n\n return Request as FetchRequestConstructor<Schema>;\n }\n\n isRequest<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n request: unknown,\n method: Method,\n path: Path,\n ): request is FetchRequest<Schema, Method, Path> {\n return (\n request instanceof Request &&\n request.method === method &&\n 'path' in request &&\n typeof request.path === 'string' &&\n createRegexFromURL(path).test(request.path)\n );\n }\n\n isResponse<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n response: unknown,\n method: Method,\n path: Path,\n ): response is FetchResponse<Schema, Method, Path> {\n return (\n response instanceof Response &&\n 'request' in response &&\n 'error' in response &&\n this.isRequest(response.request, method, path)\n );\n }\n\n isResponseError<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n error: unknown,\n method: Method,\n path: Path,\n ): error is FetchResponseError<Schema, Method, Path> {\n return (\n error instanceof FetchResponseError &&\n error.request.method === method &&\n typeof error.request.path === 'string' &&\n createRegexFromURL(path).test(error.request.path)\n );\n }\n}\n\nexport default FetchClient;\n","import { HttpSchema } from '@zimic/http';\n\nimport FetchClient from './FetchClient';\nimport { FetchOptions, Fetch } from './types/public';\n\nfunction createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema> {\n const { fetch } = new FetchClient<Schema>(options);\n return fetch;\n}\n\nexport default createFetch;\n"]}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { HttpSearchParams } from '@zimic/http';
1
+ import { HttpHeaders, HttpSearchParams } from '@zimic/http';
2
2
 
3
3
  var __defProp = Object.defineProperty;
4
4
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -74,8 +74,12 @@ var FetchClient = class {
74
74
  fetch;
75
75
  constructor({ onRequest, onResponse, ...defaults }) {
76
76
  this.fetch = this.createFetchFunction();
77
- this.fetch.defaults = defaults;
78
- this.fetch.Request = this.createRequestClass(defaults);
77
+ this.fetch.defaults = {
78
+ ...defaults,
79
+ headers: defaults.headers ?? {},
80
+ searchParams: defaults.searchParams ?? {}
81
+ };
82
+ this.fetch.Request = this.createRequestClass(this.fetch.defaults);
79
83
  this.fetch.onRequest = onRequest;
80
84
  this.fetch.onResponse = onResponse;
81
85
  }
@@ -98,8 +102,7 @@ var FetchClient = class {
98
102
  if (this.fetch.onRequest) {
99
103
  const requestAfterInterceptor = await this.fetch.onRequest(
100
104
  // Optimize type checking by narrowing the type of request
101
- request,
102
- this.fetch
105
+ request
103
106
  );
104
107
  if (requestAfterInterceptor !== request) {
105
108
  const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;
@@ -113,8 +116,7 @@ var FetchClient = class {
113
116
  if (this.fetch.onResponse) {
114
117
  const responseAfterInterceptor = await this.fetch.onResponse(
115
118
  // Optimize type checking by narrowing the type of response
116
- response,
117
- this.fetch
119
+ response
118
120
  );
119
121
  const isFetchResponse = responseAfterInterceptor instanceof Response && "request" in responseAfterInterceptor && responseAfterInterceptor.request instanceof this.fetch.Request;
120
122
  response = isFetchResponse ? responseAfterInterceptor : this.defineFetchResponseProperties(fetchRequest, responseAfterInterceptor);
@@ -148,24 +150,37 @@ var FetchClient = class {
148
150
  __name(this, "Request");
149
151
  }
150
152
  path;
151
- constructor(input, rawInit) {
152
- const init = { ...defaults, ...rawInit };
153
+ constructor(input, init) {
154
+ const initWithDefaults = { ...defaults, ...init };
155
+ const headersFromDefaults = new HttpHeaders(defaults.headers);
156
+ const headersFromInit = new HttpHeaders(init.headers);
153
157
  let url;
154
158
  if (input instanceof globalThis.Request) {
155
- super(
156
- // Optimize type checking by narrowing the type of input
157
- input,
158
- init
159
- );
159
+ const request = input;
160
+ const headersFromRequest = new HttpHeaders(input.headers);
161
+ initWithDefaults.headers = {
162
+ ...headersFromDefaults.toObject(),
163
+ ...headersFromRequest.toObject(),
164
+ ...headersFromInit.toObject()
165
+ };
166
+ super(request, initWithDefaults);
160
167
  url = new URL(input.url);
161
168
  } else {
162
- url = input instanceof URL ? new URL(input) : new URL(joinURL_default(init.baseURL, input));
163
- if (init.searchParams) {
164
- url.search = new HttpSearchParams(init.searchParams).toString();
165
- }
166
- super(url, init);
169
+ initWithDefaults.headers = {
170
+ ...headersFromDefaults.toObject(),
171
+ ...headersFromInit.toObject()
172
+ };
173
+ url = input instanceof URL ? new URL(input) : new URL(joinURL_default(initWithDefaults.baseURL, input));
174
+ const searchParamsFromDefaults = new HttpSearchParams(defaults.searchParams);
175
+ const searchParamsFromInit = new HttpSearchParams(initWithDefaults.searchParams);
176
+ initWithDefaults.searchParams = {
177
+ ...searchParamsFromDefaults.toObject(),
178
+ ...searchParamsFromInit.toObject()
179
+ };
180
+ url.search = new HttpSearchParams(initWithDefaults.searchParams).toString();
181
+ super(url, initWithDefaults);
167
182
  }
168
- this.path = excludeURLParams_default(url).toString().replace(init.baseURL, "");
183
+ this.path = excludeURLParams_default(url).toString().replace(initWithDefaults.baseURL, "");
169
184
  }
170
185
  clone() {
171
186
  const rawClone = super.clone();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-PAWJFY3S.mjs","../../zimic-utils/src/url/createRegExpFromURL.ts","../../zimic-utils/src/url/excludeURLParams.ts","../../zimic-utils/src/url/joinURL.ts","../src/client/FetchClient.ts","../src/client/factory.ts"],"names":["__defProp","__name","Request"],"mappings":"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","file":"index.mjs","sourcesContent":["import { HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchResponse } from '../types/requests';\n\nclass FetchResponseError<\n Schema extends HttpSchema,\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n> extends Error {\n constructor(\n public request: FetchRequest<Schema, Method, Path>,\n public response: FetchResponse<Schema, Method, Path, true>,\n ) {\n super(`${request.method} ${request.url} failed with status ${response.status}: ${response.statusText}`);\n this.name = 'FetchResponseError';\n }\n\n get cause() {\n return this.response;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFetchRequestError = FetchResponseError<any, any, any>;\n\nexport default FetchResponseError;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\nexport { __name };\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map","export const URL_PATH_PARAM_REGEX = /\\/:([^/]+)/g;\n\nfunction createRegExpFromURL(url: string) {\n URL_PATH_PARAM_REGEX.lastIndex = 0;\n\n const urlWithReplacedPathParams = encodeURI(url)\n .replace(/([.()*?+$\\\\])/g, '\\\\$1')\n .replace(URL_PATH_PARAM_REGEX, '/(?<$1>[^/]+)')\n .replace(/(\\/+)$/, '(?:/+)?');\n\n return new RegExp(`^${urlWithReplacedPathParams}$`);\n}\n\nexport default createRegExpFromURL;\n","function excludeURLParams(url: URL) {\n url.hash = '';\n url.search = '';\n url.username = '';\n url.password = '';\n return url;\n}\n\nexport default excludeURLParams;\n","function joinURL(...parts: (URL | string)[]) {\n return parts\n .map((part, index) => {\n const isFirstPart = index === 0;\n const isLastPart = index === parts.length - 1;\n\n let partAsString = part.toString();\n\n if (!isFirstPart) {\n partAsString = partAsString.replace(/^\\//, '');\n }\n if (!isLastPart) {\n partAsString = partAsString.replace(/\\/$/, '');\n }\n\n return partAsString;\n })\n .filter((part) => part.length > 0)\n .join('/');\n}\n\nexport default joinURL;\n","import {\n HttpSchemaPath,\n HttpSchemaMethod,\n HttpSearchParams,\n LiteralHttpSchemaPathFromNonLiteral,\n HttpSchema,\n} from '@zimic/http';\nimport createRegexFromURL from '@zimic/utils/url/createRegExpFromURL';\nimport excludeURLParams from '@zimic/utils/url/excludeURLParams';\nimport joinURL from '@zimic/utils/url/joinURL';\n\nimport FetchResponseError from './errors/FetchResponseError';\nimport { FetchInput, FetchOptions, Fetch } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> {\n fetch: Fetch<Schema>;\n\n constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {\n this.fetch = this.createFetchFunction();\n this.fetch.defaults = defaults;\n this.fetch.Request = this.createRequestClass(defaults);\n this.fetch.onRequest = onRequest;\n this.fetch.onResponse = onResponse;\n }\n\n private createFetchFunction() {\n const fetch = async <\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) => {\n const request = await this.createFetchRequest<Method, Path>(input, init);\n const requestClone = request.clone();\n\n const rawResponse = await globalThis.fetch(\n // Optimize type checking by narrowing the type of request\n requestClone as Request,\n );\n const response = await this.createFetchResponse<\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >(request, rawResponse);\n\n return response;\n };\n\n Object.setPrototypeOf(fetch, this);\n\n return fetch as Fetch<Schema>;\n }\n\n private async createFetchRequest<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n let request = input instanceof Request ? input : new this.fetch.Request(input, init);\n\n if (this.fetch.onRequest) {\n const requestAfterInterceptor = await this.fetch.onRequest(\n // Optimize type checking by narrowing the type of request\n request as FetchRequest.Loose,\n this.fetch,\n );\n\n if (requestAfterInterceptor !== request) {\n const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;\n\n request = isFetchRequest\n ? (requestAfterInterceptor as Request as typeof request)\n : new this.fetch.Request(requestAfterInterceptor as FetchInput<Schema, Method, Path>, init);\n }\n }\n\n return request;\n }\n\n private async createFetchResponse<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, rawResponse: Response) {\n let response = this.defineFetchResponseProperties<Method, Path>(fetchRequest, rawResponse);\n\n if (this.fetch.onResponse) {\n const responseAfterInterceptor = await this.fetch.onResponse(\n // Optimize type checking by narrowing the type of response\n response as FetchResponse.Loose,\n this.fetch,\n );\n\n const isFetchResponse =\n responseAfterInterceptor instanceof Response &&\n 'request' in responseAfterInterceptor &&\n responseAfterInterceptor.request instanceof this.fetch.Request;\n\n response = isFetchResponse\n ? (responseAfterInterceptor as typeof response)\n : this.defineFetchResponseProperties<Method, Path>(fetchRequest, responseAfterInterceptor);\n }\n\n return response;\n }\n\n private defineFetchResponseProperties<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, response: Response) {\n const fetchResponse = response as FetchResponse<Schema, Method, Path>;\n\n Object.defineProperty(fetchResponse, 'request', {\n value: fetchRequest satisfies FetchResponse.Loose['request'],\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n let responseError: FetchResponse.Loose['error'] | undefined;\n\n Object.defineProperty(fetchResponse, 'error', {\n get() {\n if (responseError === undefined) {\n responseError = fetchResponse.ok ? null : new FetchResponseError(fetchRequest, fetchResponse);\n }\n return responseError;\n },\n enumerable: true,\n configurable: false,\n });\n\n return fetchResponse;\n }\n\n private createRequestClass(defaults: FetchRequestInit.Defaults) {\n class Request<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n > extends globalThis.Request {\n path: LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n\n constructor(\n input: FetchInput<Schema, Method, Path>,\n rawInit: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n const init = { ...defaults, ...rawInit };\n\n let url: URL;\n\n if (input instanceof globalThis.Request) {\n super(\n // Optimize type checking by narrowing the type of input\n input as globalThis.Request,\n init,\n );\n\n url = new URL(input.url);\n } else {\n url = input instanceof URL ? new URL(input) : new URL(joinURL(init.baseURL, input));\n\n if (init.searchParams) {\n url.search = new HttpSearchParams(init.searchParams).toString();\n }\n\n super(url, init);\n }\n\n this.path = excludeURLParams(url).toString().replace(init.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<\n Schema,\n Method,\n Path\n >;\n }\n\n clone(): Request<Method, Path> {\n const rawClone = super.clone();\n\n return new Request<Method, Path>(\n rawClone as unknown as FetchInput<Schema, Method, Path>,\n rawClone as unknown as FetchRequestInit<\n Schema,\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >,\n );\n }\n }\n\n return Request as FetchRequestConstructor<Schema>;\n }\n\n isRequest<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n request: unknown,\n method: Method,\n path: Path,\n ): request is FetchRequest<Schema, Method, Path> {\n return (\n request instanceof Request &&\n request.method === method &&\n 'path' in request &&\n typeof request.path === 'string' &&\n createRegexFromURL(path).test(request.path)\n );\n }\n\n isResponse<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n response: unknown,\n method: Method,\n path: Path,\n ): response is FetchResponse<Schema, Method, Path> {\n return (\n response instanceof Response &&\n 'request' in response &&\n 'error' in response &&\n this.isRequest(response.request, method, path)\n );\n }\n\n isResponseError<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n error: unknown,\n method: Method,\n path: Path,\n ): error is FetchResponseError<Schema, Method, Path> {\n return (\n error instanceof FetchResponseError &&\n error.request.method === method &&\n typeof error.request.path === 'string' &&\n createRegexFromURL(path).test(error.request.path)\n );\n }\n}\n\nexport default FetchClient;\n","import { HttpSchema } from '@zimic/http';\n\nimport FetchClient from './FetchClient';\nimport { FetchOptions, Fetch as PublicFetch } from './types/public';\n\nfunction createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): PublicFetch<Schema> {\n const { fetch } = new FetchClient<Schema>(options);\n return fetch;\n}\n\nexport default createFetch;\n"]}
1
+ {"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-PAWJFY3S.mjs","../../zimic-utils/src/url/createRegExpFromURL.ts","../../zimic-utils/src/url/excludeURLParams.ts","../../zimic-utils/src/url/joinURL.ts","../src/client/FetchClient.ts","../src/client/factory.ts"],"names":["__defProp","__name","Request"],"mappings":"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","file":"index.mjs","sourcesContent":["import { HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchResponse } from '../types/requests';\n\nclass FetchResponseError<\n Schema extends HttpSchema,\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n> extends Error {\n constructor(\n public request: FetchRequest<Schema, Method, Path>,\n public response: FetchResponse<Schema, Method, Path, true>,\n ) {\n super(`${request.method} ${request.url} failed with status ${response.status}: ${response.statusText}`);\n this.name = 'FetchResponseError';\n }\n\n get cause() {\n return this.response;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFetchRequestError = FetchResponseError<any, any, any>;\n\nexport default FetchResponseError;\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\nexport { __name };\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map\n//# sourceMappingURL=chunk-PAWJFY3S.mjs.map","export const URL_PATH_PARAM_REGEX = /\\/:([^/]+)/g;\n\nfunction createRegExpFromURL(url: string) {\n URL_PATH_PARAM_REGEX.lastIndex = 0;\n\n const urlWithReplacedPathParams = encodeURI(url)\n .replace(/([.()*?+$\\\\])/g, '\\\\$1')\n .replace(URL_PATH_PARAM_REGEX, '/(?<$1>[^/]+)')\n .replace(/(\\/+)$/, '(?:/+)?');\n\n return new RegExp(`^${urlWithReplacedPathParams}$`);\n}\n\nexport default createRegExpFromURL;\n","function excludeURLParams(url: URL) {\n url.hash = '';\n url.search = '';\n url.username = '';\n url.password = '';\n return url;\n}\n\nexport default excludeURLParams;\n","function joinURL(...parts: (URL | string)[]) {\n return parts\n .map((part, index) => {\n const isFirstPart = index === 0;\n const isLastPart = index === parts.length - 1;\n\n let partAsString = part.toString();\n\n if (!isFirstPart) {\n partAsString = partAsString.replace(/^\\//, '');\n }\n if (!isLastPart) {\n partAsString = partAsString.replace(/\\/$/, '');\n }\n\n return partAsString;\n })\n .filter((part) => part.length > 0)\n .join('/');\n}\n\nexport default joinURL;\n","import {\n HttpSchemaPath,\n HttpSchemaMethod,\n HttpSearchParams,\n LiteralHttpSchemaPathFromNonLiteral,\n HttpSchema,\n HttpHeaders,\n} from '@zimic/http';\nimport createRegexFromURL from '@zimic/utils/url/createRegExpFromURL';\nimport excludeURLParams from '@zimic/utils/url/excludeURLParams';\nimport joinURL from '@zimic/utils/url/joinURL';\n\nimport FetchResponseError from './errors/FetchResponseError';\nimport { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> {\n fetch: Fetch<Schema>;\n\n constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {\n this.fetch = this.createFetchFunction();\n\n this.fetch.defaults = {\n ...defaults,\n headers: defaults.headers ?? {},\n searchParams: defaults.searchParams ?? {},\n };\n\n this.fetch.Request = this.createRequestClass(this.fetch.defaults);\n this.fetch.onRequest = onRequest;\n this.fetch.onResponse = onResponse;\n }\n\n private createFetchFunction() {\n const fetch = async <\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) => {\n const request = await this.createFetchRequest<Method, Path>(input, init);\n const requestClone = request.clone();\n\n const rawResponse = await globalThis.fetch(\n // Optimize type checking by narrowing the type of request\n requestClone as Request,\n );\n const response = await this.createFetchResponse<\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >(request, rawResponse);\n\n return response;\n };\n\n Object.setPrototypeOf(fetch, this);\n\n return fetch as Fetch<Schema>;\n }\n\n private async createFetchRequest<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n >(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n let request = input instanceof Request ? input : new this.fetch.Request(input, init);\n\n if (this.fetch.onRequest) {\n const requestAfterInterceptor = await this.fetch.onRequest(\n // Optimize type checking by narrowing the type of request\n request as FetchRequest.Loose,\n );\n\n if (requestAfterInterceptor !== request) {\n const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;\n\n request = isFetchRequest\n ? (requestAfterInterceptor as Request as typeof request)\n : new this.fetch.Request(requestAfterInterceptor as FetchInput<Schema, Method, Path>, init);\n }\n }\n\n return request;\n }\n\n private async createFetchResponse<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, rawResponse: Response) {\n let response = this.defineFetchResponseProperties<Method, Path>(fetchRequest, rawResponse);\n\n if (this.fetch.onResponse) {\n const responseAfterInterceptor = await this.fetch.onResponse(\n // Optimize type checking by narrowing the type of response\n response as FetchResponse.Loose,\n );\n\n const isFetchResponse =\n responseAfterInterceptor instanceof Response &&\n 'request' in responseAfterInterceptor &&\n responseAfterInterceptor.request instanceof this.fetch.Request;\n\n response = isFetchResponse\n ? (responseAfterInterceptor as typeof response)\n : this.defineFetchResponseProperties<Method, Path>(fetchRequest, responseAfterInterceptor);\n }\n\n return response;\n }\n\n private defineFetchResponseProperties<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.Literal<Schema, Method>,\n >(fetchRequest: FetchRequest<Schema, Method, Path>, response: Response) {\n const fetchResponse = response as FetchResponse<Schema, Method, Path>;\n\n Object.defineProperty(fetchResponse, 'request', {\n value: fetchRequest satisfies FetchResponse.Loose['request'],\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n let responseError: FetchResponse.Loose['error'] | undefined;\n\n Object.defineProperty(fetchResponse, 'error', {\n get() {\n if (responseError === undefined) {\n responseError = fetchResponse.ok ? null : new FetchResponseError(fetchRequest, fetchResponse);\n }\n return responseError;\n },\n enumerable: true,\n configurable: false,\n });\n\n return fetchResponse;\n }\n\n private createRequestClass(defaults: FetchDefaults) {\n class Request<\n Method extends HttpSchemaMethod<Schema>,\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n > extends globalThis.Request {\n path: LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n\n constructor(\n input: FetchInput<Schema, Method, Path>,\n init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,\n ) {\n const initWithDefaults = { ...defaults, ...init };\n\n const headersFromDefaults = new HttpHeaders(defaults.headers);\n const headersFromInit = new HttpHeaders((init satisfies RequestInit as RequestInit).headers);\n\n let url: URL;\n\n if (input instanceof globalThis.Request) {\n // Optimize type checking by narrowing the type of input\n const request = input as globalThis.Request;\n const headersFromRequest = new HttpHeaders(input.headers);\n\n initWithDefaults.headers = {\n ...headersFromDefaults.toObject(),\n ...headersFromRequest.toObject(),\n ...headersFromInit.toObject(),\n };\n\n super(request, initWithDefaults);\n\n url = new URL(input.url);\n } else {\n initWithDefaults.headers = {\n ...headersFromDefaults.toObject(),\n ...headersFromInit.toObject(),\n };\n\n url = input instanceof URL ? new URL(input) : new URL(joinURL(initWithDefaults.baseURL, input));\n\n const searchParamsFromDefaults = new HttpSearchParams(defaults.searchParams);\n const searchParamsFromInit = new HttpSearchParams(initWithDefaults.searchParams);\n\n initWithDefaults.searchParams = {\n ...searchParamsFromDefaults.toObject(),\n ...searchParamsFromInit.toObject(),\n };\n\n url.search = new HttpSearchParams(initWithDefaults.searchParams).toString();\n\n super(url, initWithDefaults);\n }\n\n this.path = excludeURLParams(url)\n .toString()\n .replace(initWithDefaults.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n }\n\n clone(): Request<Method, Path> {\n const rawClone = super.clone();\n\n return new Request<Method, Path>(\n rawClone as unknown as FetchInput<Schema, Method, Path>,\n rawClone as unknown as FetchRequestInit<\n Schema,\n Method,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>\n >,\n );\n }\n }\n\n return Request as FetchRequestConstructor<Schema>;\n }\n\n isRequest<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n request: unknown,\n method: Method,\n path: Path,\n ): request is FetchRequest<Schema, Method, Path> {\n return (\n request instanceof Request &&\n request.method === method &&\n 'path' in request &&\n typeof request.path === 'string' &&\n createRegexFromURL(path).test(request.path)\n );\n }\n\n isResponse<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n response: unknown,\n method: Method,\n path: Path,\n ): response is FetchResponse<Schema, Method, Path> {\n return (\n response instanceof Response &&\n 'request' in response &&\n 'error' in response &&\n this.isRequest(response.request, method, path)\n );\n }\n\n isResponseError<Path extends HttpSchemaPath.Literal<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n error: unknown,\n method: Method,\n path: Path,\n ): error is FetchResponseError<Schema, Method, Path> {\n return (\n error instanceof FetchResponseError &&\n error.request.method === method &&\n typeof error.request.path === 'string' &&\n createRegexFromURL(path).test(error.request.path)\n );\n }\n}\n\nexport default FetchClient;\n","import { HttpSchema } from '@zimic/http';\n\nimport FetchClient from './FetchClient';\nimport { FetchOptions, Fetch } from './types/public';\n\nfunction createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema> {\n const { fetch } = new FetchClient<Schema>(options);\n return fetch;\n}\n\nexport default createFetch;\n"]}
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "api",
14
14
  "static"
15
15
  ],
16
- "version": "0.1.0-canary.14",
16
+ "version": "0.1.0-canary.16",
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "https://github.com/zimicjs/zimic.git",
@@ -65,11 +65,11 @@
65
65
  "tsup": "^8.3.6",
66
66
  "typescript": "^5.7.3",
67
67
  "vitest": "^3.0.6",
68
- "@zimic/eslint-config-node": "0.0.0",
69
- "@zimic/interceptor": "0.14.0-canary.23",
68
+ "@zimic/interceptor": "0.14.0-canary.24",
70
69
  "@zimic/lint-staged-config": "0.0.0",
71
- "@zimic/tsconfig": "0.0.0",
72
- "@zimic/utils": "0.0.0"
70
+ "@zimic/eslint-config-node": "0.0.0",
71
+ "@zimic/utils": "0.0.0",
72
+ "@zimic/tsconfig": "0.0.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@zimic/http": "^0.1.0 || ^0.1.0-canary.0",
@@ -4,13 +4,14 @@ import {
4
4
  HttpSearchParams,
5
5
  LiteralHttpSchemaPathFromNonLiteral,
6
6
  HttpSchema,
7
+ HttpHeaders,
7
8
  } from '@zimic/http';
8
9
  import createRegexFromURL from '@zimic/utils/url/createRegExpFromURL';
9
10
  import excludeURLParams from '@zimic/utils/url/excludeURLParams';
10
11
  import joinURL from '@zimic/utils/url/joinURL';
11
12
 
12
13
  import FetchResponseError from './errors/FetchResponseError';
13
- import { FetchInput, FetchOptions, Fetch } from './types/public';
14
+ import { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';
14
15
  import { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';
15
16
 
16
17
  class FetchClient<Schema extends HttpSchema> {
@@ -18,8 +19,14 @@ class FetchClient<Schema extends HttpSchema> {
18
19
 
19
20
  constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {
20
21
  this.fetch = this.createFetchFunction();
21
- this.fetch.defaults = defaults;
22
- this.fetch.Request = this.createRequestClass(defaults);
22
+
23
+ this.fetch.defaults = {
24
+ ...defaults,
25
+ headers: defaults.headers ?? {},
26
+ searchParams: defaults.searchParams ?? {},
27
+ };
28
+
29
+ this.fetch.Request = this.createRequestClass(this.fetch.defaults);
23
30
  this.fetch.onRequest = onRequest;
24
31
  this.fetch.onResponse = onResponse;
25
32
  }
@@ -65,7 +72,6 @@ class FetchClient<Schema extends HttpSchema> {
65
72
  const requestAfterInterceptor = await this.fetch.onRequest(
66
73
  // Optimize type checking by narrowing the type of request
67
74
  request as FetchRequest.Loose,
68
- this.fetch,
69
75
  );
70
76
 
71
77
  if (requestAfterInterceptor !== request) {
@@ -90,7 +96,6 @@ class FetchClient<Schema extends HttpSchema> {
90
96
  const responseAfterInterceptor = await this.fetch.onResponse(
91
97
  // Optimize type checking by narrowing the type of response
92
98
  response as FetchResponse.Loose,
93
- this.fetch,
94
99
  );
95
100
 
96
101
  const isFetchResponse =
@@ -135,7 +140,7 @@ class FetchClient<Schema extends HttpSchema> {
135
140
  return fetchResponse;
136
141
  }
137
142
 
138
- private createRequestClass(defaults: FetchRequestInit.Defaults) {
143
+ private createRequestClass(defaults: FetchDefaults) {
139
144
  class Request<
140
145
  Method extends HttpSchemaMethod<Schema>,
141
146
  Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
@@ -144,35 +149,53 @@ class FetchClient<Schema extends HttpSchema> {
144
149
 
145
150
  constructor(
146
151
  input: FetchInput<Schema, Method, Path>,
147
- rawInit: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,
152
+ init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,
148
153
  ) {
149
- const init = { ...defaults, ...rawInit };
154
+ const initWithDefaults = { ...defaults, ...init };
155
+
156
+ const headersFromDefaults = new HttpHeaders(defaults.headers);
157
+ const headersFromInit = new HttpHeaders((init satisfies RequestInit as RequestInit).headers);
150
158
 
151
159
  let url: URL;
152
160
 
153
161
  if (input instanceof globalThis.Request) {
154
- super(
155
- // Optimize type checking by narrowing the type of input
156
- input as globalThis.Request,
157
- init,
158
- );
162
+ // Optimize type checking by narrowing the type of input
163
+ const request = input as globalThis.Request;
164
+ const headersFromRequest = new HttpHeaders(input.headers);
165
+
166
+ initWithDefaults.headers = {
167
+ ...headersFromDefaults.toObject(),
168
+ ...headersFromRequest.toObject(),
169
+ ...headersFromInit.toObject(),
170
+ };
171
+
172
+ super(request, initWithDefaults);
159
173
 
160
174
  url = new URL(input.url);
161
175
  } else {
162
- url = input instanceof URL ? new URL(input) : new URL(joinURL(init.baseURL, input));
176
+ initWithDefaults.headers = {
177
+ ...headersFromDefaults.toObject(),
178
+ ...headersFromInit.toObject(),
179
+ };
180
+
181
+ url = input instanceof URL ? new URL(input) : new URL(joinURL(initWithDefaults.baseURL, input));
182
+
183
+ const searchParamsFromDefaults = new HttpSearchParams(defaults.searchParams);
184
+ const searchParamsFromInit = new HttpSearchParams(initWithDefaults.searchParams);
185
+
186
+ initWithDefaults.searchParams = {
187
+ ...searchParamsFromDefaults.toObject(),
188
+ ...searchParamsFromInit.toObject(),
189
+ };
163
190
 
164
- if (init.searchParams) {
165
- url.search = new HttpSearchParams(init.searchParams).toString();
166
- }
191
+ url.search = new HttpSearchParams(initWithDefaults.searchParams).toString();
167
192
 
168
- super(url, init);
193
+ super(url, initWithDefaults);
169
194
  }
170
195
 
171
- this.path = excludeURLParams(url).toString().replace(init.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<
172
- Schema,
173
- Method,
174
- Path
175
- >;
196
+ this.path = excludeURLParams(url)
197
+ .toString()
198
+ .replace(initWithDefaults.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;
176
199
  }
177
200
 
178
201
  clone(): Request<Method, Path> {
@@ -1,9 +1,9 @@
1
1
  import { HttpSchema } from '@zimic/http';
2
2
 
3
3
  import FetchClient from './FetchClient';
4
- import { FetchOptions, Fetch as PublicFetch } from './types/public';
4
+ import { FetchOptions, Fetch } from './types/public';
5
5
 
6
- function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): PublicFetch<Schema> {
6
+ function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema> {
7
7
  const { fetch } = new FetchClient<Schema>(options);
8
8
  return fetch;
9
9
  }
@@ -1,5 +1,5 @@
1
1
  import { HttpSchemaPath, HttpSchemaMethod, LiteralHttpSchemaPathFromNonLiteral, HttpSchema } from '@zimic/http';
2
- import { PossiblePromise } from '@zimic/utils/types';
2
+ import { PossiblePromise, RequiredByKey } from '@zimic/utils/types';
3
3
 
4
4
  import FetchResponseError from '../errors/FetchResponseError';
5
5
  import { FetchRequest, FetchRequestConstructor, FetchRequestInit, FetchResponse } from './requests';
@@ -23,17 +23,16 @@ interface FetchFunction<Schema extends HttpSchema> {
23
23
  }
24
24
 
25
25
  export interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
26
- onRequest?: (request: FetchRequest.Loose, fetch: Fetch<Schema>) => PossiblePromise<Request>;
27
- onResponse?: (response: FetchResponse.Loose, fetch: Fetch<Schema>) => PossiblePromise<Response>;
26
+ onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
27
+ onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
28
28
  }
29
29
 
30
- interface FetchClient<Schema extends HttpSchema> {
31
- defaults: FetchRequestInit.Defaults;
30
+ export type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
32
31
 
33
- Request: FetchRequestConstructor<Schema>;
32
+ interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
33
+ defaults: FetchDefaults;
34
34
 
35
- onRequest?: FetchOptions<Schema>['onRequest'];
36
- onResponse?: FetchOptions<Schema>['onResponse'];
35
+ Request: FetchRequestConstructor<Schema>;
37
36
 
38
37
  isRequest: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(
39
38
  request: unknown,
@@ -17,6 +17,8 @@ import {
17
17
  HttpResponseBodySchema,
18
18
  HttpResponseHeadersSchema,
19
19
  HttpRequestHeadersSchema,
20
+ HttpHeadersSchema,
21
+ HttpSearchParamsSchema,
20
22
  } from '@zimic/http';
21
23
  import { Default, DefaultNoExclude, IfNever, ReplaceBy } from '@zimic/utils/types';
22
24
 
@@ -73,10 +75,12 @@ export type FetchRequestInit<
73
75
  : never);
74
76
 
75
77
  export namespace FetchRequestInit {
76
- export interface Defaults extends RequestInit {
78
+ /** The default options for each request sent by a fetch instance. */
79
+ export interface Defaults extends Omit<RequestInit, 'headers'> {
77
80
  baseURL: string;
78
81
  method?: HttpMethod;
79
- searchParams?: HttpSearchParams;
82
+ headers?: HttpHeadersSchema;
83
+ searchParams?: HttpSearchParamsSchema;
80
84
  }
81
85
  }
82
86
 
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export type { JSONStringified } from './client/types/json';
2
2
 
3
- export type { Fetch, InferFetchSchema, FetchOptions, FetchInput } from './client/types/public';
3
+ export type { Fetch, InferFetchSchema, FetchOptions, FetchDefaults, FetchInput } from './client/types/public';
4
4
 
5
- export type { FetchRequestInit, FetchRequest, FetchRequestConstructor, FetchResponse } from './client/types/requests';
5
+ export type { FetchRequest, FetchRequestInit, FetchResponse, FetchRequestConstructor } from './client/types/requests';
6
6
 
7
7
  export { default as FetchResponseError } from './client/errors/FetchResponseError';
8
8