@zimic/fetch 0.1.0-canary.2 → 0.1.0-canary.20
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/README.md +3 -7
- package/dist/index.d.ts +61 -44
- package/dist/index.js +77 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +78 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -11
- package/src/client/FetchClient.ts +113 -66
- package/src/client/errors/FetchResponseError.ts +6 -6
- package/src/client/factory.ts +3 -5
- package/src/client/types/public.ts +42 -50
- package/src/client/types/requests.ts +89 -49
- package/src/index.ts +5 -9
- package/src/types/requests.ts +1 -2
- package/src/utils/environment.ts +3 -0
- package/src/utils/files.ts +4 -19
- package/src/types/strings.d.ts +0 -9
- package/src/types/utils.ts +0 -11
- package/src/utils/imports.ts +0 -14
- package/src/utils/urls.ts +0 -43
package/README.md
CHANGED
|
@@ -44,8 +44,8 @@ Zimic provides a flexible and type-safe way to mock HTTP requests.
|
|
|
44
44
|
- :zap: **Statically-typed mocks**: Declare the
|
|
45
45
|
[schema](https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http‐schemas) of your HTTP endpoints and create
|
|
46
46
|
fully typed mocks. If you have an [OpenAPI v3](https://swagger.io/specification) schema, use
|
|
47
|
-
[`zimic typegen`](https://github.com/zimicjs/zimic/wiki/cli‐zimic‐typegen) to automatically generate types and
|
|
48
|
-
your mocks in sync with your API.
|
|
47
|
+
[`zimic-http typegen`](https://github.com/zimicjs/zimic/wiki/cli‐zimic‐typegen) to automatically generate types and
|
|
48
|
+
keep your mocks in sync with your API.
|
|
49
49
|
- :link: **Network-level intercepts**: Internally, Zimic combines [MSW](https://github.com/mswjs/msw) and
|
|
50
50
|
[interceptor servers](https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server) to act on real HTTP requests. From you
|
|
51
51
|
application's point of view, the mocked responses are indistinguishable from the real ones.
|
|
@@ -56,7 +56,7 @@ Zimic provides a flexible and type-safe way to mock HTTP requests.
|
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
58
|
import { type HttpSchema } from '@zimic/http';
|
|
59
|
-
import { httpInterceptor } from 'zimic/interceptor/http';
|
|
59
|
+
import { httpInterceptor } from '@zimic/interceptor/http';
|
|
60
60
|
|
|
61
61
|
// 1. Declare your types:
|
|
62
62
|
interface User {
|
|
@@ -212,10 +212,6 @@ test('example', async () => {
|
|
|
212
212
|
> - Breaking changes, if any, will be delivered in the next **_minor_** version.
|
|
213
213
|
> - Breaking changes, if any, will be documented in the [version release](https://github.com/zimicjs/zimic/releases),
|
|
214
214
|
> along with a migration guide detailing the introduced changes and suggesting steps to migrate.
|
|
215
|
-
>
|
|
216
|
-
> From v0.8 onwards, we expect Zimic's public API to become more stable. If you'd like to share any feedback, please
|
|
217
|
-
> feel free to [open an issue](https://github.com/zimicjs/zimic/issues) or
|
|
218
|
-
> [create a discussion](https://github.com/zimicjs/zimic/discussions/new/choose)!
|
|
219
215
|
|
|
220
216
|
## Examples
|
|
221
217
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import { HttpSchema, HttpSchemaPath,
|
|
2
|
-
|
|
3
|
-
type Default<Type, IfEmpty = never> = [undefined | void] extends [Type] ? IfEmpty : Exclude<Type, undefined | void>;
|
|
4
|
-
type DefaultNoExclude<Type, IfEmpty = never> = [undefined | void] extends Type ? IfEmpty : Type;
|
|
5
|
-
type IfNever<Type, Yes, No = Type> = [Type] extends [never] ? Yes : No;
|
|
6
|
-
type PossiblePromise<Type> = Type | PromiseLike<Type>;
|
|
7
|
-
type ReplaceBy<Type, Source, Target> = Type extends Source ? Target : Type;
|
|
1
|
+
import { HttpSchema, HttpSchemaMethod, HttpSchemaPath, HttpRequestSchema, HttpHeaders, HttpSearchParams, JSONValue, HttpMethod, HttpHeadersSchema, HttpSearchParamsSchema, HttpMethodSchema, HttpStatusCode, HttpResponseSchemaStatusCode, HttpResponse, HttpResponseBodySchema, HttpResponseHeadersSchema, HttpRequest, HttpRequestHeadersSchema, AllowAnyStringInPathParams, LiteralHttpSchemaPathFromNonLiteral } from '@zimic/http';
|
|
8
2
|
|
|
9
3
|
declare const value: unique symbol;
|
|
10
4
|
type JSONStringified<Value> = string & {
|
|
@@ -16,49 +10,68 @@ declare global {
|
|
|
16
10
|
}
|
|
17
11
|
}
|
|
18
12
|
|
|
13
|
+
type Default<Type, IfEmpty = never> = [undefined | void] extends [Type] ? IfEmpty : Exclude<Type, undefined | void>;
|
|
14
|
+
type DefaultNoExclude<Type, IfEmpty = never> = [undefined | void] extends Type ? IfEmpty : Type;
|
|
15
|
+
type IfNever<Type, Yes, No = Type> = [Type] extends [never] ? Yes : No;
|
|
16
|
+
type PossiblePromise<Type> = Type | PromiseLike<Type>;
|
|
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>>;
|
|
19
|
+
|
|
20
|
+
type FetchRequestInitHeaders<RequestSchema extends HttpRequestSchema> = RequestSchema['headers'] | HttpHeaders<Default<RequestSchema['headers']>>;
|
|
19
21
|
type FetchRequestInitWithHeaders<RequestSchema extends HttpRequestSchema> = [RequestSchema['headers']] extends [never] ? {
|
|
20
22
|
headers?: undefined;
|
|
21
23
|
} : undefined extends RequestSchema['headers'] ? {
|
|
22
|
-
headers?:
|
|
24
|
+
headers?: FetchRequestInitHeaders<RequestSchema>;
|
|
23
25
|
} : {
|
|
24
|
-
headers:
|
|
26
|
+
headers: FetchRequestInitHeaders<RequestSchema>;
|
|
25
27
|
};
|
|
28
|
+
type FetchRequestInitSearchParams<RequestSchema extends HttpRequestSchema> = RequestSchema['searchParams'] | HttpSearchParams<Default<RequestSchema['searchParams']>>;
|
|
26
29
|
type FetchRequestInitWithSearchParams<RequestSchema extends HttpRequestSchema> = [
|
|
27
30
|
RequestSchema['searchParams']
|
|
28
31
|
] extends [never] ? {
|
|
29
32
|
searchParams?: undefined;
|
|
30
33
|
} : undefined extends RequestSchema['searchParams'] ? {
|
|
31
|
-
searchParams?:
|
|
34
|
+
searchParams?: FetchRequestInitSearchParams<RequestSchema>;
|
|
32
35
|
} : {
|
|
33
|
-
searchParams:
|
|
36
|
+
searchParams: FetchRequestInitSearchParams<RequestSchema>;
|
|
34
37
|
};
|
|
35
38
|
type FetchRequestInitWithBody<RequestSchema extends HttpRequestSchema> = [RequestSchema['body']] extends [never] ? {
|
|
36
39
|
body?: null;
|
|
37
|
-
} : undefined extends RequestSchema['body'] ? {
|
|
40
|
+
} : RequestSchema['body'] extends string ? undefined extends RequestSchema['body'] ? {
|
|
38
41
|
body?: ReplaceBy<RequestSchema['body'], undefined, null>;
|
|
39
|
-
} :
|
|
42
|
+
} : {
|
|
40
43
|
body: RequestSchema['body'];
|
|
41
|
-
} : RequestSchema['body'] extends JSONValue ? {
|
|
44
|
+
} : RequestSchema['body'] extends JSONValue ? undefined extends RequestSchema['body'] ? {
|
|
45
|
+
body?: JSONStringified<ReplaceBy<RequestSchema['body'], undefined, null>>;
|
|
46
|
+
} : {
|
|
42
47
|
body: JSONStringified<RequestSchema['body']>;
|
|
48
|
+
} : undefined extends RequestSchema['body'] ? {
|
|
49
|
+
body?: ReplaceBy<RequestSchema['body'], undefined, null>;
|
|
43
50
|
} : {
|
|
44
51
|
body: RequestSchema['body'];
|
|
45
52
|
};
|
|
46
53
|
type FetchRequestInitPerPath<RequestSchema extends HttpRequestSchema> = FetchRequestInitWithHeaders<RequestSchema> & FetchRequestInitWithSearchParams<RequestSchema> & FetchRequestInitWithBody<RequestSchema>;
|
|
47
|
-
type FetchRequestInit<Schema extends HttpSchema, Path extends HttpSchemaPath<Schema, Method>,
|
|
48
|
-
baseURL?: string;
|
|
54
|
+
type FetchRequestInit<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath<Schema, Method>, Redirect extends RequestRedirect = 'follow'> = Omit<RequestInit, 'method' | 'headers' | 'body'> & {
|
|
49
55
|
method: Method;
|
|
56
|
+
baseURL?: string;
|
|
57
|
+
redirect?: Redirect;
|
|
50
58
|
} & (Path extends Path ? FetchRequestInitPerPath<Default<Default<Schema[Path][Method]>['request']>> : never);
|
|
51
59
|
declare namespace FetchRequestInit {
|
|
52
|
-
|
|
60
|
+
/** The default options for each request sent by a fetch instance. */
|
|
61
|
+
interface Defaults extends Omit<RequestInit, 'headers'> {
|
|
53
62
|
baseURL: string;
|
|
54
63
|
method?: HttpMethod;
|
|
55
|
-
|
|
64
|
+
headers?: HttpHeadersSchema;
|
|
65
|
+
searchParams?: HttpSearchParamsSchema;
|
|
56
66
|
}
|
|
67
|
+
type Loose = Partial<Defaults>;
|
|
57
68
|
}
|
|
58
69
|
type AllFetchResponseStatusCode<MethodSchema extends HttpMethodSchema> = HttpResponseSchemaStatusCode<Default<MethodSchema['response']>>;
|
|
59
|
-
type
|
|
70
|
+
type FilterFetchResponseStatusCodeByError<StatusCode extends HttpStatusCode, ErrorOnly extends boolean> = ErrorOnly extends true ? Extract<StatusCode, HttpStatusCode.ClientError | HttpStatusCode.ServerError> : StatusCode;
|
|
71
|
+
type FilterFetchResponseStatusCodeByRedirect<StatusCode extends HttpStatusCode, Redirect extends RequestRedirect> = Redirect extends 'error' ? FilterFetchResponseStatusCodeByRedirect<StatusCode, 'follow'> : Redirect extends 'follow' ? Exclude<StatusCode, Exclude<HttpStatusCode.Redirection, 304>> : StatusCode;
|
|
72
|
+
type FetchResponseStatusCode<MethodSchema extends HttpMethodSchema, ErrorOnly extends boolean, Redirect extends RequestRedirect> = FilterFetchResponseStatusCodeByRedirect<FilterFetchResponseStatusCodeByError<AllFetchResponseStatusCode<MethodSchema>, ErrorOnly>, Redirect>;
|
|
60
73
|
type HttpRequestBodySchema<MethodSchema extends HttpMethodSchema> = ReplaceBy<ReplaceBy<IfNever<DefaultNoExclude<Default<MethodSchema['request']>['body']>, null>, undefined, null>, ArrayBuffer, Blob>;
|
|
61
|
-
interface FetchRequest<
|
|
74
|
+
interface FetchRequest<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>> extends HttpRequest<HttpRequestBodySchema<Default<Schema[Path][Method]>>, HttpRequestHeadersSchema<Default<Schema[Path][Method]>>> {
|
|
62
75
|
path: AllowAnyStringInPathParams<Path>;
|
|
63
76
|
method: Method;
|
|
64
77
|
}
|
|
@@ -69,11 +82,11 @@ declare namespace FetchRequest {
|
|
|
69
82
|
clone: () => Loose;
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
|
-
interface FetchResponsePerStatusCode<
|
|
73
|
-
request: FetchRequest<
|
|
74
|
-
error: StatusCode extends HttpStatusCode.ClientError | HttpStatusCode.ServerError ? FetchResponseError<
|
|
85
|
+
interface FetchResponsePerStatusCode<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>, StatusCode extends HttpStatusCode = HttpStatusCode> extends HttpResponse<HttpResponseBodySchema<Default<Schema[Path][Method]>, StatusCode>, StatusCode, HttpResponseHeadersSchema<Default<Schema[Path][Method]>, StatusCode>> {
|
|
86
|
+
request: FetchRequest<Schema, Method, Path>;
|
|
87
|
+
error: StatusCode extends HttpStatusCode.ClientError | HttpStatusCode.ServerError ? FetchResponseError<Schema, Method, Path> : null;
|
|
75
88
|
}
|
|
76
|
-
type FetchResponse<
|
|
89
|
+
type FetchResponse<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>, ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>> = StatusCode extends StatusCode ? FetchResponsePerStatusCode<Schema, Method, Path, StatusCode> : never;
|
|
77
90
|
declare namespace FetchResponse {
|
|
78
91
|
interface Loose extends Response {
|
|
79
92
|
request: FetchRequest.Loose;
|
|
@@ -81,36 +94,40 @@ declare namespace FetchResponse {
|
|
|
81
94
|
clone: () => Loose;
|
|
82
95
|
}
|
|
83
96
|
}
|
|
84
|
-
type FetchRequestConstructor<Schema extends HttpSchema> = new <Path extends HttpSchemaPath.NonLiteral<Schema, Method
|
|
97
|
+
type FetchRequestConstructor<Schema extends HttpSchema> = new <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>>(input: FetchInput<Schema, Method, Path>, init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>) => FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
85
98
|
|
|
86
|
-
declare class FetchResponseError<
|
|
87
|
-
request: FetchRequest<
|
|
88
|
-
response: FetchResponse<
|
|
89
|
-
constructor(request: FetchRequest<
|
|
90
|
-
get cause(): FetchResponse<
|
|
99
|
+
declare class FetchResponseError<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>> extends Error {
|
|
100
|
+
request: FetchRequest<Schema, Method, Path>;
|
|
101
|
+
response: FetchResponse<Schema, Method, Path, true, 'manual'>;
|
|
102
|
+
constructor(request: FetchRequest<Schema, Method, Path>, response: FetchResponse<Schema, Method, Path, true, 'manual'>);
|
|
103
|
+
get cause(): FetchResponse<Schema, Method, Path, true, "manual">;
|
|
91
104
|
}
|
|
92
105
|
type AnyFetchRequestError = FetchResponseError<any, any, any>;
|
|
93
106
|
|
|
94
|
-
type FetchInput<Schema extends HttpSchema, Path extends HttpSchemaPath.NonLiteral<Schema, Method
|
|
107
|
+
type FetchInput<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>> = Path | URL | FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
95
108
|
interface FetchFunction<Schema extends HttpSchema> {
|
|
96
|
-
<Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
97
|
-
<Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
109
|
+
<Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: Path | URL, init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, false, Redirect>>;
|
|
110
|
+
<Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>, init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, false, Redirect>>;
|
|
111
|
+
}
|
|
112
|
+
declare namespace FetchFunction {
|
|
113
|
+
type Loose = (input: string | URL | FetchRequest.Loose, init?: FetchRequestInit.Loose) => Promise<FetchResponse.Loose>;
|
|
98
114
|
}
|
|
99
115
|
interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
|
|
100
|
-
onRequest?: (request: FetchRequest.Loose
|
|
101
|
-
onResponse?: (response: FetchResponse.Loose
|
|
116
|
+
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
|
|
117
|
+
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
|
|
102
118
|
}
|
|
103
|
-
|
|
104
|
-
|
|
119
|
+
type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
|
|
120
|
+
interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
|
|
121
|
+
defaults: FetchDefaults;
|
|
122
|
+
loose: FetchFunction.Loose;
|
|
105
123
|
Request: FetchRequestConstructor<Schema>;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
isResponse: <Path extends HttpSchemaPath<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(response: unknown, path: Path, method: Method) => response is FetchResponse<Path, Method, Default<Schema[Path][Method]>>;
|
|
110
|
-
isResponseError: <Path extends HttpSchemaPath<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(error: unknown, path: Path, method: Method) => error is FetchResponseError<Path, Method, Default<Schema[Path][Method]>>;
|
|
124
|
+
isRequest: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(request: unknown, method: Method, path: Path) => request is FetchRequest<Schema, Method, Path>;
|
|
125
|
+
isResponse: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(response: unknown, method: Method, path: Path) => response is FetchResponse<Schema, Method, Path>;
|
|
126
|
+
isResponseError: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(error: unknown, method: Method, path: Path) => error is FetchResponseError<Schema, Method, Path>;
|
|
111
127
|
}
|
|
112
128
|
type Fetch<Schema extends HttpSchema> = FetchFunction<Schema> & FetchClient<Schema>;
|
|
129
|
+
type InferFetchSchema<FetchInstance> = FetchInstance extends Fetch<infer Schema> ? Schema : never;
|
|
113
130
|
|
|
114
|
-
declare function createFetch<Schema extends HttpSchema>(options: FetchOptions<
|
|
131
|
+
declare function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema>;
|
|
115
132
|
|
|
116
|
-
export { type Fetch, type
|
|
133
|
+
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
|
@@ -22,26 +22,34 @@ var FetchResponseError = class extends Error {
|
|
|
22
22
|
};
|
|
23
23
|
var FetchResponseError_default = FetchResponseError;
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
|
|
25
|
+
// ../zimic-utils/dist/chunk-PAWJFY3S.mjs
|
|
26
|
+
var __defProp2 = Object.defineProperty;
|
|
27
|
+
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
|
|
28
|
+
|
|
29
|
+
// ../zimic-utils/dist/chunk-RIVHLEFF.mjs
|
|
30
|
+
var URL_PATH_PARAM_REGEX = /\/:([^/]+)/g;
|
|
31
|
+
function createRegExpFromURL(url) {
|
|
32
|
+
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
|
33
|
+
const urlWithReplacedPathParams = encodeURI(url).replace(/([.()*?+$\\])/g, "\\$1").replace(URL_PATH_PARAM_REGEX, "/(?<$1>[^/]+)").replace(/^(\/)|(\/)$/g, "");
|
|
34
|
+
return new RegExp(`^(?:/)?${urlWithReplacedPathParams}(?:/)?$`);
|
|
35
|
+
}
|
|
36
|
+
__name(createRegExpFromURL, "createRegExpFromURL");
|
|
37
|
+
__name2(createRegExpFromURL, "createRegExpFromURL");
|
|
38
|
+
var createRegExpFromURL_default = createRegExpFromURL;
|
|
39
|
+
|
|
40
|
+
// ../zimic-utils/dist/url/excludeURLParams.mjs
|
|
41
|
+
function excludeURLParams(url) {
|
|
27
42
|
url.hash = "";
|
|
28
43
|
url.search = "";
|
|
29
44
|
url.username = "";
|
|
30
45
|
url.password = "";
|
|
31
46
|
return url;
|
|
32
47
|
}
|
|
33
|
-
__name(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
__name(prepareURLForRegex, "prepareURLForRegex");
|
|
39
|
-
var URL_PATH_PARAM_REGEX = /\/:([^/]+)/g;
|
|
40
|
-
function createRegexFromURL(url) {
|
|
41
|
-
const urlWithReplacedPathParams = prepareURLForRegex(url).replace(URL_PATH_PARAM_REGEX, "/(?<$1>[^/]+)").replace(/(\/+)$/, "(?:/+)?");
|
|
42
|
-
return new RegExp(`^${urlWithReplacedPathParams}$`);
|
|
43
|
-
}
|
|
44
|
-
__name(createRegexFromURL, "createRegexFromURL");
|
|
48
|
+
__name(excludeURLParams, "excludeURLParams");
|
|
49
|
+
__name2(excludeURLParams, "excludeURLParams");
|
|
50
|
+
var excludeURLParams_default = excludeURLParams;
|
|
51
|
+
|
|
52
|
+
// ../zimic-utils/dist/url/joinURL.mjs
|
|
45
53
|
function joinURL(...parts) {
|
|
46
54
|
return parts.map((part, index) => {
|
|
47
55
|
const isFirstPart = index === 0;
|
|
@@ -57,6 +65,8 @@ function joinURL(...parts) {
|
|
|
57
65
|
}).filter((part) => part.length > 0).join("/");
|
|
58
66
|
}
|
|
59
67
|
__name(joinURL, "joinURL");
|
|
68
|
+
__name2(joinURL, "joinURL");
|
|
69
|
+
var joinURL_default = joinURL;
|
|
60
70
|
|
|
61
71
|
// src/client/FetchClient.ts
|
|
62
72
|
var FetchClient = class {
|
|
@@ -66,8 +76,13 @@ var FetchClient = class {
|
|
|
66
76
|
fetch;
|
|
67
77
|
constructor({ onRequest, onResponse, ...defaults }) {
|
|
68
78
|
this.fetch = this.createFetchFunction();
|
|
69
|
-
this.fetch.defaults =
|
|
70
|
-
|
|
79
|
+
this.fetch.defaults = {
|
|
80
|
+
...defaults,
|
|
81
|
+
headers: defaults.headers ?? {},
|
|
82
|
+
searchParams: defaults.searchParams ?? {}
|
|
83
|
+
};
|
|
84
|
+
this.fetch.loose = this.fetch;
|
|
85
|
+
this.fetch.Request = this.createRequestClass(this.fetch.defaults);
|
|
71
86
|
this.fetch.onRequest = onRequest;
|
|
72
87
|
this.fetch.onResponse = onResponse;
|
|
73
88
|
}
|
|
@@ -90,8 +105,7 @@ var FetchClient = class {
|
|
|
90
105
|
if (this.fetch.onRequest) {
|
|
91
106
|
const requestAfterInterceptor = await this.fetch.onRequest(
|
|
92
107
|
// Optimize type checking by narrowing the type of request
|
|
93
|
-
request
|
|
94
|
-
this.fetch
|
|
108
|
+
request
|
|
95
109
|
);
|
|
96
110
|
if (requestAfterInterceptor !== request) {
|
|
97
111
|
const isFetchRequest = requestAfterInterceptor instanceof this.fetch.Request;
|
|
@@ -105,8 +119,7 @@ var FetchClient = class {
|
|
|
105
119
|
if (this.fetch.onResponse) {
|
|
106
120
|
const responseAfterInterceptor = await this.fetch.onResponse(
|
|
107
121
|
// Optimize type checking by narrowing the type of response
|
|
108
|
-
response
|
|
109
|
-
this.fetch
|
|
122
|
+
response
|
|
110
123
|
);
|
|
111
124
|
const isFetchResponse = responseAfterInterceptor instanceof Response && "request" in responseAfterInterceptor && responseAfterInterceptor.request instanceof this.fetch.Request;
|
|
112
125
|
response = isFetchResponse ? responseAfterInterceptor : this.defineFetchResponseProperties(fetchRequest, responseAfterInterceptor);
|
|
@@ -121,10 +134,17 @@ var FetchClient = class {
|
|
|
121
134
|
enumerable: true,
|
|
122
135
|
configurable: false
|
|
123
136
|
});
|
|
124
|
-
|
|
137
|
+
let responseError;
|
|
125
138
|
Object.defineProperty(fetchResponse, "error", {
|
|
126
|
-
|
|
127
|
-
|
|
139
|
+
get() {
|
|
140
|
+
if (responseError === void 0) {
|
|
141
|
+
responseError = fetchResponse.ok ? null : new FetchResponseError_default(
|
|
142
|
+
fetchRequest,
|
|
143
|
+
fetchResponse
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return responseError;
|
|
147
|
+
},
|
|
128
148
|
enumerable: true,
|
|
129
149
|
configurable: false
|
|
130
150
|
});
|
|
@@ -136,24 +156,39 @@ var FetchClient = class {
|
|
|
136
156
|
__name(this, "Request");
|
|
137
157
|
}
|
|
138
158
|
path;
|
|
139
|
-
constructor(input,
|
|
140
|
-
const
|
|
159
|
+
constructor(input, init) {
|
|
160
|
+
const initWithDefaults = { ...defaults, ...init };
|
|
161
|
+
const headersFromDefaults = new http.HttpHeaders(defaults.headers);
|
|
162
|
+
const headersFromInit = new http.HttpHeaders(init.headers);
|
|
141
163
|
let url;
|
|
164
|
+
const baseURL = new URL(initWithDefaults.baseURL);
|
|
142
165
|
if (input instanceof globalThis.Request) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
166
|
+
const request = input;
|
|
167
|
+
const headersFromRequest = new http.HttpHeaders(input.headers);
|
|
168
|
+
initWithDefaults.headers = {
|
|
169
|
+
...headersFromDefaults.toObject(),
|
|
170
|
+
...headersFromRequest.toObject(),
|
|
171
|
+
...headersFromInit.toObject()
|
|
172
|
+
};
|
|
173
|
+
super(request, initWithDefaults);
|
|
148
174
|
url = new URL(input.url);
|
|
149
175
|
} else {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
176
|
+
initWithDefaults.headers = {
|
|
177
|
+
...headersFromDefaults.toObject(),
|
|
178
|
+
...headersFromInit.toObject()
|
|
179
|
+
};
|
|
180
|
+
url = input instanceof URL ? new URL(input) : new URL(joinURL_default(baseURL, input));
|
|
181
|
+
const searchParamsFromDefaults = new http.HttpSearchParams(defaults.searchParams);
|
|
182
|
+
const searchParamsFromInit = new http.HttpSearchParams(initWithDefaults.searchParams);
|
|
183
|
+
initWithDefaults.searchParams = {
|
|
184
|
+
...searchParamsFromDefaults.toObject(),
|
|
185
|
+
...searchParamsFromInit.toObject()
|
|
186
|
+
};
|
|
187
|
+
url.search = new http.HttpSearchParams(initWithDefaults.searchParams).toString();
|
|
188
|
+
super(url, initWithDefaults);
|
|
155
189
|
}
|
|
156
|
-
|
|
190
|
+
const baseURLWithoutTrailingSlash = baseURL.toString().replace(/\/$/, "");
|
|
191
|
+
this.path = excludeURLParams_default(url).toString().replace(baseURLWithoutTrailingSlash, "");
|
|
157
192
|
}
|
|
158
193
|
clone() {
|
|
159
194
|
const rawClone = super.clone();
|
|
@@ -165,14 +200,14 @@ var FetchClient = class {
|
|
|
165
200
|
}
|
|
166
201
|
return Request2;
|
|
167
202
|
}
|
|
168
|
-
isRequest(request,
|
|
169
|
-
return request instanceof Request && request.method === method && "path" in request && typeof request.path === "string" &&
|
|
203
|
+
isRequest(request, method, path) {
|
|
204
|
+
return request instanceof Request && request.method === method && "path" in request && typeof request.path === "string" && createRegExpFromURL_default(path).test(request.path);
|
|
170
205
|
}
|
|
171
|
-
isResponse(response,
|
|
172
|
-
return response instanceof Response && "request" in response && "error" in response &&
|
|
206
|
+
isResponse(response, method, path) {
|
|
207
|
+
return response instanceof Response && "request" in response && this.isRequest(response.request, method, path) && "error" in response && (response.error === null || response.error instanceof FetchResponseError_default);
|
|
173
208
|
}
|
|
174
|
-
isResponseError(error,
|
|
175
|
-
return error instanceof FetchResponseError_default && error.request
|
|
209
|
+
isResponseError(error, method, path) {
|
|
210
|
+
return error instanceof FetchResponseError_default && this.isRequest(error.request, method, path) && this.isResponse(error.response, method, path);
|
|
176
211
|
}
|
|
177
212
|
};
|
|
178
213
|
var FetchClient_default = FetchClient;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../src/utils/urls.ts","../src/client/FetchClient.ts","../src/client/factory.ts"],"names":["Request","HttpSearchParams"],"mappings":"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","file":"index.js","sourcesContent":["import { HttpMethod, HttpMethodSchema } from '@zimic/http';\n\nimport { FetchRequest, FetchResponse } from '../types/requests';\n\nclass FetchResponseError<\n Path extends string = string,\n Method extends HttpMethod = HttpMethod,\n MethodSchema extends HttpMethodSchema = HttpMethodSchema,\n> extends Error {\n constructor(\n public request: FetchRequest<Path, Method, MethodSchema>,\n public response: FetchResponse<Path, Method, MethodSchema, 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","export function excludeNonPathParams(url: URL) {\n url.hash = '';\n url.search = '';\n url.username = '';\n url.password = '';\n return url;\n}\n\nfunction prepareURLForRegex(url: string) {\n const encodedURL = encodeURI(url);\n return encodedURL.replace(/([.()*?+$\\\\])/g, '\\\\$1');\n}\n\nconst URL_PATH_PARAM_REGEX = /\\/:([^/]+)/g;\n\nexport function createRegexFromURL(url: string) {\n const urlWithReplacedPathParams = prepareURLForRegex(url)\n .replace(URL_PATH_PARAM_REGEX, '/(?<$1>[^/]+)')\n .replace(/(\\/+)$/, '(?:/+)?');\n\n return new RegExp(`^${urlWithReplacedPathParams}$`);\n}\n\nexport function joinURL(...parts: (string | URL)[]) {\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","import {\n HttpSchemaPath,\n HttpSchemaMethod,\n HttpSearchParams,\n LiteralHttpSchemaPathFromNonLiteral,\n HttpSchema,\n} from '@zimic/http';\n\nimport { Default } from '@/types/utils';\nimport { createRegexFromURL, excludeNonPathParams, joinURL } from '@/utils/urls';\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 Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n Method extends HttpSchemaMethod<Schema>,\n >(\n input: FetchInput<Schema, Path, Method>,\n init: FetchRequestInit<Schema, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Method>,\n ) => {\n const request = await this.createFetchRequest<Path, Method>(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 LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>,\n Method\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 Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n Method extends HttpSchemaMethod<Schema>,\n >(\n input: FetchInput<Schema, Path, Method>,\n init: FetchRequestInit<Schema, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Method>,\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, Path, Method>, init);\n }\n }\n\n return request;\n }\n\n private async createFetchResponse<\n Path extends HttpSchemaPath<Schema, Method>,\n Method extends HttpSchemaMethod<Schema>,\n >(fetchRequest: FetchRequest<Path, Method, Default<Schema[Path][Method]>>, rawResponse: Response) {\n let response = this.defineFetchResponseProperties<Path, Method>(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<Path, Method>(fetchRequest, responseAfterInterceptor);\n }\n\n return response;\n }\n\n private defineFetchResponseProperties<\n Path extends HttpSchemaPath<Schema, Method>,\n Method extends HttpSchemaMethod<Schema>,\n >(fetchRequest: FetchRequest<Path, Method, Default<Schema[Path][Method]>>, response: Response) {\n const fetchResponse = response as FetchResponse<Path, Method, Default<Schema[Path][Method]>>;\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 const responseError = (\n fetchResponse.ok ? null : new FetchResponseError(fetchRequest, fetchResponse)\n ) satisfies FetchResponse.Loose['error'];\n\n Object.defineProperty(fetchResponse, 'error', {\n value: responseError,\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n return fetchResponse;\n }\n\n private createRequestClass(defaults: FetchRequestInit.Defaults) {\n class Request<\n Path extends HttpSchemaPath.NonLiteral<Schema, Method>,\n Method extends HttpSchemaMethod<Schema>,\n > extends globalThis.Request {\n path: LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n\n constructor(\n input: FetchInput<Schema, Path, Method>,\n rawInit: FetchRequestInit<Schema, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Method>,\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 = excludeNonPathParams(url)\n .toString()\n .replace(init.baseURL, '') as LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>;\n }\n\n clone(): Request<Path, Method> {\n const rawClone = super.clone();\n\n return new Request<Path, Method>(\n rawClone as unknown as FetchInput<Schema, Path, Method>,\n rawClone as unknown as FetchRequestInit<\n Schema,\n LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>,\n Method\n >,\n );\n }\n }\n\n return Request as FetchRequestConstructor<Schema>;\n }\n\n isRequest<Path extends HttpSchemaPath<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n request: unknown,\n path: Path,\n method: Method,\n ): request is FetchRequest<Path, Method, Default<Schema[Path][Method]>> {\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<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n response: unknown,\n path: Path,\n method: Method,\n ): response is FetchResponse<Path, Method, Default<Schema[Path][Method]>> {\n return (\n response instanceof Response &&\n 'request' in response &&\n 'error' in response &&\n this.isRequest(response.request, path, method)\n );\n }\n\n isResponseError<Path extends HttpSchemaPath<Schema, Method>, Method extends HttpSchemaMethod<Schema>>(\n error: unknown,\n path: Path,\n method: Method,\n ): error is FetchResponseError<Path, Method, Default<Schema[Path][Method]>> {\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>(\n options: FetchOptions<HttpSchema<Schema>>,\n): PublicFetch<HttpSchema<Schema>> {\n const { fetch } = new FetchClient<HttpSchema<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, 'manual'>,\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(/^(\\/)|(\\/)$/g, '');\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 {\n FetchInput,\n FetchOptions,\n Fetch,\n FetchClient as PublicFetchClient,\n FetchDefaults,\n FetchFunction,\n} from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema>\n implements Omit<PublicFetchClient<Schema>, 'defaults' | 'loose' | 'Request'>\n{\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.fetch.loose = this.fetch as Fetch<any> as FetchFunction.Loose;\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\n ? null\n : new FetchResponseError(\n fetchRequest,\n fetchResponse as FetchResponse<Schema, Method, Path, true, 'manual'>,\n );\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 const baseURL = new URL(initWithDefaults.baseURL);\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(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 const baseURLWithoutTrailingSlash = baseURL.toString().replace(/\\/$/, '');\n\n this.path = excludeURLParams(url)\n .toString()\n .replace(baseURLWithoutTrailingSlash, '') 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 this.isRequest(response.request, method, path) &&\n 'error' in response &&\n (response.error === null || response.error instanceof FetchResponseError)\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 this.isRequest(error.request, method, path) &&\n this.isResponse(error.response, method, 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"]}
|