@zimic/fetch 1.4.1 → 1.4.3-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +105 -40
- package/dist/index.js +313 -199
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +313 -201
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/client/FetchClient.ts +89 -173
- package/src/client/request/FetchRequest.ts +242 -0
- package/src/client/request/types.ts +143 -0
- package/src/client/response/FetchResponse.ts +225 -0
- package/src/client/response/error/FetchResponseError.ts +47 -0
- package/src/client/response/error/types.ts +29 -0
- package/src/client/response/types.ts +111 -0
- package/src/client/types/public.ts +38 -3
- package/src/client/utils/objects.ts +71 -0
- package/src/index.ts +19 -10
- package/src/client/errors/FetchResponseError.ts +0 -185
- package/src/client/types/requests.ts +0 -256
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HttpBody,
|
|
3
|
+
HttpHeadersSchema,
|
|
4
|
+
HttpHeadersSerialized,
|
|
5
|
+
HttpMethodSchema,
|
|
6
|
+
HttpResponseHeadersSchema,
|
|
7
|
+
HttpResponseSchema,
|
|
8
|
+
HttpResponseSchemaStatusCode,
|
|
9
|
+
HttpSchema,
|
|
10
|
+
HttpSchemaMethod,
|
|
11
|
+
HttpSchemaPath,
|
|
12
|
+
HttpStatusCode,
|
|
13
|
+
} from '@zimic/http';
|
|
14
|
+
import { Default } from '@zimic/utils/types';
|
|
15
|
+
|
|
16
|
+
import { FetchRequest } from '../request/FetchRequest';
|
|
17
|
+
import { FetchRequestBodySchema, FetchRequestInitWithHeaders } from '../request/types';
|
|
18
|
+
import { FetchResponse } from './FetchResponse';
|
|
19
|
+
|
|
20
|
+
export type AllFetchResponseStatusCode<MethodSchema extends HttpMethodSchema> = HttpResponseSchemaStatusCode<
|
|
21
|
+
Default<MethodSchema['response']>
|
|
22
|
+
>;
|
|
23
|
+
|
|
24
|
+
type FilterFetchResponseStatusCodeByError<
|
|
25
|
+
StatusCode extends HttpStatusCode,
|
|
26
|
+
ErrorOnly extends boolean,
|
|
27
|
+
> = ErrorOnly extends true ? Extract<StatusCode, HttpStatusCode.ClientError | HttpStatusCode.ServerError> : StatusCode;
|
|
28
|
+
|
|
29
|
+
type FilterFetchResponseStatusCodeByRedirect<
|
|
30
|
+
StatusCode extends HttpStatusCode,
|
|
31
|
+
Redirect extends RequestRedirect,
|
|
32
|
+
> = Redirect extends 'error'
|
|
33
|
+
? FilterFetchResponseStatusCodeByRedirect<StatusCode, 'follow'>
|
|
34
|
+
: Redirect extends 'follow'
|
|
35
|
+
? Exclude<StatusCode, Exclude<HttpStatusCode.Redirection, 304>>
|
|
36
|
+
: StatusCode;
|
|
37
|
+
|
|
38
|
+
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
|
|
39
|
+
export type FetchResponseStatusCode<
|
|
40
|
+
MethodSchema extends HttpMethodSchema,
|
|
41
|
+
ErrorOnly extends boolean,
|
|
42
|
+
Redirect extends RequestRedirect,
|
|
43
|
+
> = FilterFetchResponseStatusCodeByRedirect<
|
|
44
|
+
FilterFetchResponseStatusCodeByError<AllFetchResponseStatusCode<MethodSchema>, ErrorOnly>,
|
|
45
|
+
Redirect
|
|
46
|
+
>;
|
|
47
|
+
|
|
48
|
+
type FetchResponseInitWithHeaders<HeadersSchema extends HttpHeadersSchema | undefined> =
|
|
49
|
+
FetchRequestInitWithHeaders<HeadersSchema>;
|
|
50
|
+
|
|
51
|
+
export type FetchResponseBodySchema<ResponseSchema extends HttpResponseSchema> = FetchRequestBodySchema<ResponseSchema>;
|
|
52
|
+
|
|
53
|
+
type FetchResponseInitPerStatusCode<
|
|
54
|
+
MethodSchema extends HttpMethodSchema,
|
|
55
|
+
StatusCode extends AllFetchResponseStatusCode<MethodSchema>,
|
|
56
|
+
> = { status: StatusCode } & FetchResponseInitWithHeaders<HttpResponseHeadersSchema<MethodSchema, StatusCode>>;
|
|
57
|
+
|
|
58
|
+
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
|
|
59
|
+
export type FetchResponseInit<
|
|
60
|
+
Schema extends HttpSchema,
|
|
61
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
62
|
+
Path extends HttpSchemaPath<Schema, Method>,
|
|
63
|
+
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
|
|
64
|
+
ErrorOnly extends boolean = false,
|
|
65
|
+
Redirect extends RequestRedirect = 'follow',
|
|
66
|
+
StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> =
|
|
67
|
+
FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>,
|
|
68
|
+
> = Omit<ResponseInit, 'headers' | 'status'> &
|
|
69
|
+
(StatusCode extends StatusCode ? FetchResponseInitPerStatusCode<Default<Schema[Path][Method]>, StatusCode> : never);
|
|
70
|
+
|
|
71
|
+
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
|
|
72
|
+
export interface FetchResponseConstructor {
|
|
73
|
+
new <
|
|
74
|
+
Schema extends HttpSchema,
|
|
75
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
76
|
+
Path extends HttpSchemaPath.Literal<Schema, Method>,
|
|
77
|
+
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
|
|
78
|
+
ErrorOnly extends boolean = false,
|
|
79
|
+
Redirect extends RequestRedirect = 'follow',
|
|
80
|
+
StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> =
|
|
81
|
+
FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>,
|
|
82
|
+
>(
|
|
83
|
+
fetchRequest: FetchRequest<Schema, Method, Path>,
|
|
84
|
+
response?: Response,
|
|
85
|
+
): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
|
|
86
|
+
new <
|
|
87
|
+
Schema extends HttpSchema,
|
|
88
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
89
|
+
Path extends HttpSchemaPath.Literal<Schema, Method>,
|
|
90
|
+
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
|
|
91
|
+
ErrorOnly extends boolean = false,
|
|
92
|
+
Redirect extends RequestRedirect = 'follow',
|
|
93
|
+
StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> =
|
|
94
|
+
FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>,
|
|
95
|
+
>(
|
|
96
|
+
fetchRequest: FetchRequest<Schema, Method, Path>,
|
|
97
|
+
body?: FetchResponseBodySchema<Default<Default<Default<Schema[Path][Method]>['response']>[StatusCode]>>,
|
|
98
|
+
init?: FetchResponseInit<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>,
|
|
99
|
+
): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
|
|
100
|
+
|
|
101
|
+
[Symbol.hasInstance]: (instance: unknown) => boolean;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()`} */
|
|
105
|
+
export type FetchResponseObject = Pick<
|
|
106
|
+
FetchResponse.Loose,
|
|
107
|
+
'url' | 'type' | 'status' | 'statusText' | 'ok' | 'redirected'
|
|
108
|
+
> & {
|
|
109
|
+
headers: HttpHeadersSerialized<HttpHeadersSchema>;
|
|
110
|
+
body?: HttpBody | null;
|
|
111
|
+
};
|
|
@@ -1,14 +1,49 @@
|
|
|
1
1
|
import { HttpSchemaPath, HttpSchemaMethod, LiteralHttpSchemaPathFromNonLiteral, HttpSchema } from '@zimic/http';
|
|
2
2
|
import { PossiblePromise, RequiredByKey } from '@zimic/utils/types';
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import { FetchRequest } from '../request/FetchRequest';
|
|
5
|
+
import { FetchRequestInit } from '../request/types';
|
|
6
|
+
import FetchResponseError from '../response/error/FetchResponseError';
|
|
7
|
+
import { FetchResponse } from '../response/FetchResponse';
|
|
8
|
+
|
|
9
|
+
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchrequest `fetch.Request` API reference} */
|
|
10
|
+
export interface FetchRequestConstructor<Schema extends HttpSchema> {
|
|
11
|
+
new <
|
|
12
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
13
|
+
Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
14
|
+
Redirect extends RequestRedirect = 'follow',
|
|
15
|
+
>(
|
|
16
|
+
input: Path | URL,
|
|
17
|
+
init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>,
|
|
18
|
+
): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
19
|
+
|
|
20
|
+
new <
|
|
21
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
22
|
+
Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
23
|
+
Redirect extends RequestRedirect = 'follow',
|
|
24
|
+
>(
|
|
25
|
+
input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,
|
|
26
|
+
init?: Omit<
|
|
27
|
+
FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>,
|
|
28
|
+
'baseURL' | 'searchParams'
|
|
29
|
+
>,
|
|
30
|
+
): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
31
|
+
|
|
32
|
+
new <
|
|
33
|
+
Method extends HttpSchemaMethod<Schema>,
|
|
34
|
+
Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
35
|
+
Redirect extends RequestRedirect = 'follow',
|
|
36
|
+
>(
|
|
37
|
+
input: FetchInput<Schema, Method, Path>,
|
|
38
|
+
init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>,
|
|
39
|
+
): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
40
|
+
}
|
|
6
41
|
|
|
7
42
|
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
|
|
8
43
|
export type FetchInput<
|
|
9
44
|
Schema extends HttpSchema,
|
|
10
45
|
Method extends HttpSchemaMethod<Schema>,
|
|
11
|
-
Path extends HttpSchemaPath
|
|
46
|
+
Path extends HttpSchemaPath<Schema, Method>,
|
|
12
47
|
> = Path | URL | FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
|
|
13
48
|
|
|
14
49
|
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { parseHttpBody } from '@zimic/http';
|
|
2
|
+
import { PossiblePromise } from '@zimic/utils/types';
|
|
3
|
+
|
|
4
|
+
import { FetchRequestObject } from '../request/types';
|
|
5
|
+
import { FetchResponseObject } from '../response/types';
|
|
6
|
+
|
|
7
|
+
const BODY_METHOD = ['json', 'formData', 'text', 'arrayBuffer', 'blob', 'bytes'] satisfies (keyof Body)[];
|
|
8
|
+
type BodyMethod = (typeof BODY_METHOD)[number];
|
|
9
|
+
|
|
10
|
+
export function isBodyMethod(property: string | symbol, value: unknown): value is Body[BodyMethod] {
|
|
11
|
+
return BODY_METHOD.includes(property as BodyMethod) && typeof value === 'function';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getOrSetBoundBodyMethod(
|
|
15
|
+
resource: Request | Response,
|
|
16
|
+
property: string | symbol,
|
|
17
|
+
value: Body[BodyMethod],
|
|
18
|
+
) {
|
|
19
|
+
// We cache the bound function on the proxy instance to avoid re-binding it on every access.
|
|
20
|
+
const isValueAlreadyBound = Object.prototype.hasOwnProperty.call(resource, property);
|
|
21
|
+
|
|
22
|
+
if (isValueAlreadyBound) {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const boundValue = value.bind(resource) as unknown;
|
|
27
|
+
|
|
28
|
+
Object.defineProperty(resource, property, {
|
|
29
|
+
value: boundValue,
|
|
30
|
+
configurable: true,
|
|
31
|
+
enumerable: false,
|
|
32
|
+
writable: true,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return boundValue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function withIncludedBodyIfAvailable(
|
|
39
|
+
resource: Request,
|
|
40
|
+
resourceObject: FetchRequestObject,
|
|
41
|
+
): PossiblePromise<FetchRequestObject>;
|
|
42
|
+
export function withIncludedBodyIfAvailable(
|
|
43
|
+
resource: Response,
|
|
44
|
+
resourceObject: FetchResponseObject,
|
|
45
|
+
): PossiblePromise<FetchResponseObject>;
|
|
46
|
+
export function withIncludedBodyIfAvailable(
|
|
47
|
+
resource: Request | Response,
|
|
48
|
+
resourceObject: FetchRequestObject | FetchResponseObject,
|
|
49
|
+
): PossiblePromise<FetchRequestObject | FetchResponseObject> {
|
|
50
|
+
const resourceType = resource instanceof Request ? 'request' : 'response';
|
|
51
|
+
|
|
52
|
+
if (resource.bodyUsed) {
|
|
53
|
+
console.warn(
|
|
54
|
+
'[@zimic/fetch]',
|
|
55
|
+
`Could not include the ${resourceType} body because it is already used. ` +
|
|
56
|
+
'If you access the body before calling `toObject()`, consider reading it from a cloned ' +
|
|
57
|
+
`${resourceType}.\n\nLearn more: https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject`,
|
|
58
|
+
);
|
|
59
|
+
return resourceObject;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return parseHttpBody(resource.clone())
|
|
63
|
+
.then((body) => {
|
|
64
|
+
resourceObject.body = body;
|
|
65
|
+
return resourceObject;
|
|
66
|
+
})
|
|
67
|
+
.catch((error: unknown) => {
|
|
68
|
+
console.error('[@zimic/fetch]', `Failed to parse ${resourceType} body:`, error);
|
|
69
|
+
return resourceObject;
|
|
70
|
+
});
|
|
71
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
export type { JSONStringified } from '@zimic/utils/types';
|
|
2
2
|
|
|
3
|
-
export type { Fetch, InferFetchSchema, FetchOptions, FetchDefaults, FetchInput } from './client/types/public';
|
|
4
|
-
|
|
5
3
|
export type {
|
|
4
|
+
Fetch,
|
|
5
|
+
InferFetchSchema,
|
|
6
|
+
FetchOptions,
|
|
7
|
+
FetchDefaults,
|
|
8
|
+
FetchInput,
|
|
6
9
|
FetchRequestConstructor,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
} from './client/types/public';
|
|
11
|
+
|
|
12
|
+
export { FetchRequest } from './client/request/FetchRequest';
|
|
13
|
+
export type { FetchRequestInit, FetchRequestObject } from './client/request/types';
|
|
14
|
+
|
|
15
|
+
export { FetchResponse } from './client/response/FetchResponse';
|
|
16
|
+
export type { FetchResponsePerStatusCode } from './client/response/FetchResponse';
|
|
17
|
+
export type {
|
|
12
18
|
FetchResponseObject,
|
|
13
|
-
|
|
19
|
+
FetchResponseConstructor,
|
|
20
|
+
FetchResponseInit,
|
|
21
|
+
FetchResponseStatusCode,
|
|
22
|
+
} from './client/response/types';
|
|
14
23
|
|
|
15
|
-
export { default as FetchResponseError } from './client/
|
|
16
|
-
export type { FetchResponseErrorObject, FetchResponseErrorObjectOptions } from './client/
|
|
24
|
+
export { default as FetchResponseError } from './client/response/error/FetchResponseError';
|
|
25
|
+
export type { FetchResponseErrorObject, FetchResponseErrorObjectOptions } from './client/response/error/types';
|
|
17
26
|
|
|
18
27
|
export { default as createFetch } from './client/factory';
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HttpHeaders,
|
|
3
|
-
HttpHeadersSchema,
|
|
4
|
-
HttpSchema,
|
|
5
|
-
HttpSchemaMethod,
|
|
6
|
-
HttpSchemaPath,
|
|
7
|
-
parseHttpBody,
|
|
8
|
-
} from '@zimic/http';
|
|
9
|
-
import { PossiblePromise } from '@zimic/utils/types';
|
|
10
|
-
|
|
11
|
-
import { FetchRequest, FetchRequestObject, FetchResponse, FetchResponseObject } from '../types/requests';
|
|
12
|
-
|
|
13
|
-
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `fetchResponseError.toObject()` API reference} */
|
|
14
|
-
export interface FetchResponseErrorObjectOptions {
|
|
15
|
-
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `fetchResponseError.toObject()` API reference} */
|
|
16
|
-
includeRequestBody?: boolean;
|
|
17
|
-
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `fetchResponseError.toObject()` API reference} */
|
|
18
|
-
includeResponseBody?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export namespace FetchResponseErrorObjectOptions {
|
|
22
|
-
/**
|
|
23
|
-
* Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, including the body of
|
|
24
|
-
* the request and/or response.
|
|
25
|
-
*/
|
|
26
|
-
export type WithBody = FetchResponseErrorObjectOptions &
|
|
27
|
-
({ includeRequestBody: true } | { includeResponseBody: true });
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, excluding the body of
|
|
31
|
-
* the request and/or response.
|
|
32
|
-
*/
|
|
33
|
-
export type WithoutBody = FetchResponseErrorObjectOptions &
|
|
34
|
-
({ includeRequestBody?: false } | { includeResponseBody?: false });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A plain object representation of a {@link FetchResponseError `FetchResponseError`}, compatible with JSON. It is useful
|
|
39
|
-
* for serialization, debugging, and logging purposes.
|
|
40
|
-
*
|
|
41
|
-
* @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `fetchResponseError.toObject()` API reference}
|
|
42
|
-
*/
|
|
43
|
-
export interface FetchResponseErrorObject {
|
|
44
|
-
name: string;
|
|
45
|
-
message: string;
|
|
46
|
-
request: FetchRequestObject;
|
|
47
|
-
response: FetchResponseObject;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error `FetchResponseError` API reference} */
|
|
51
|
-
class FetchResponseError<
|
|
52
|
-
Schema extends HttpSchema,
|
|
53
|
-
Method extends HttpSchemaMethod<Schema>,
|
|
54
|
-
Path extends HttpSchemaPath.Literal<Schema, Method>,
|
|
55
|
-
> extends Error {
|
|
56
|
-
constructor(
|
|
57
|
-
public request: FetchRequest<Schema, Method, Path>,
|
|
58
|
-
public response: FetchResponse<Schema, Method, Path>,
|
|
59
|
-
) {
|
|
60
|
-
super(`${request.method} ${request.url} failed with status ${response.status}: ${response.statusText}`);
|
|
61
|
-
this.name = 'FetchResponseError';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `fetchResponseError.toObject()` API reference} */
|
|
65
|
-
toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;
|
|
66
|
-
toObject(options?: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;
|
|
67
|
-
toObject(options?: FetchResponseErrorObjectOptions): PossiblePromise<FetchResponseErrorObject>;
|
|
68
|
-
toObject({
|
|
69
|
-
includeRequestBody = false,
|
|
70
|
-
includeResponseBody = false,
|
|
71
|
-
}: FetchResponseErrorObjectOptions = {}): PossiblePromise<FetchResponseErrorObject> {
|
|
72
|
-
const partialObject = {
|
|
73
|
-
name: this.name,
|
|
74
|
-
message: this.message,
|
|
75
|
-
} satisfies Partial<FetchResponseErrorObject>;
|
|
76
|
-
|
|
77
|
-
if (!includeRequestBody && !includeResponseBody) {
|
|
78
|
-
return {
|
|
79
|
-
...partialObject,
|
|
80
|
-
request: this.requestToObject({ includeBody: false }),
|
|
81
|
-
response: this.responseToObject({ includeBody: false }),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return Promise.all([
|
|
86
|
-
Promise.resolve(this.requestToObject({ includeBody: includeRequestBody })),
|
|
87
|
-
Promise.resolve(this.responseToObject({ includeBody: includeResponseBody })),
|
|
88
|
-
]).then(([request, response]) => ({ ...partialObject, request, response }));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private requestToObject(options: { includeBody: true }): Promise<FetchRequestObject>;
|
|
92
|
-
private requestToObject(options: { includeBody: false }): FetchRequestObject;
|
|
93
|
-
private requestToObject(options: { includeBody: boolean }): PossiblePromise<FetchRequestObject>;
|
|
94
|
-
private requestToObject(options: { includeBody: boolean }): PossiblePromise<FetchRequestObject> {
|
|
95
|
-
const request = this.request;
|
|
96
|
-
|
|
97
|
-
const requestObject: FetchRequestObject = {
|
|
98
|
-
url: request.url,
|
|
99
|
-
path: request.path,
|
|
100
|
-
method: request.method,
|
|
101
|
-
headers: this.convertHeadersToObject(request),
|
|
102
|
-
cache: request.cache,
|
|
103
|
-
destination: request.destination,
|
|
104
|
-
credentials: request.credentials,
|
|
105
|
-
integrity: request.integrity,
|
|
106
|
-
keepalive: request.keepalive,
|
|
107
|
-
mode: request.mode,
|
|
108
|
-
redirect: request.redirect,
|
|
109
|
-
referrer: request.referrer,
|
|
110
|
-
referrerPolicy: request.referrerPolicy,
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
if (!options.includeBody) {
|
|
114
|
-
return requestObject;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return this.withIncludedBodyIfAvailable('request', requestObject);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private responseToObject(options: { includeBody: true }): Promise<FetchResponseObject>;
|
|
121
|
-
private responseToObject(options: { includeBody: false }): FetchResponseObject;
|
|
122
|
-
private responseToObject(options: { includeBody: boolean }): PossiblePromise<FetchResponseObject>;
|
|
123
|
-
private responseToObject(options: { includeBody: boolean }): PossiblePromise<FetchResponseObject> {
|
|
124
|
-
const response = this.response;
|
|
125
|
-
|
|
126
|
-
const responseObject: FetchResponseObject = {
|
|
127
|
-
url: response.url,
|
|
128
|
-
type: response.type,
|
|
129
|
-
status: response.status,
|
|
130
|
-
statusText: response.statusText,
|
|
131
|
-
ok: response.ok,
|
|
132
|
-
headers: this.convertHeadersToObject(response),
|
|
133
|
-
redirected: response.redirected,
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
if (!options.includeBody) {
|
|
137
|
-
return responseObject;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return this.withIncludedBodyIfAvailable('response', responseObject);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
private convertHeadersToObject(
|
|
144
|
-
resource: FetchRequest<Schema, Method, Path> | FetchResponse<Schema, Method, Path>,
|
|
145
|
-
): HttpHeadersSchema {
|
|
146
|
-
return HttpHeaders.prototype.toObject.call(resource.headers) as HttpHeadersSchema;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private withIncludedBodyIfAvailable(
|
|
150
|
-
resourceType: 'request',
|
|
151
|
-
resourceObject: FetchRequestObject,
|
|
152
|
-
): PossiblePromise<FetchRequestObject>;
|
|
153
|
-
private withIncludedBodyIfAvailable(
|
|
154
|
-
resourceType: 'response',
|
|
155
|
-
resourceObject: FetchResponseObject,
|
|
156
|
-
): PossiblePromise<FetchResponseObject>;
|
|
157
|
-
private withIncludedBodyIfAvailable(
|
|
158
|
-
resourceType: 'request' | 'response',
|
|
159
|
-
resourceObject: FetchRequestObject | FetchResponseObject,
|
|
160
|
-
): PossiblePromise<FetchRequestObject | FetchResponseObject> {
|
|
161
|
-
const resource = this[resourceType] as Request | Response;
|
|
162
|
-
|
|
163
|
-
if (resource.bodyUsed) {
|
|
164
|
-
console.warn(
|
|
165
|
-
'[@zimic/fetch]',
|
|
166
|
-
`Could not include the ${resourceType} body because it is already used. ` +
|
|
167
|
-
'If you access the body before calling `error.toObject()`, consider reading it from a cloned ' +
|
|
168
|
-
`${resourceType}.\n\nLearn more: https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject`,
|
|
169
|
-
);
|
|
170
|
-
return resourceObject;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return parseHttpBody(resource)
|
|
174
|
-
.then((body) => {
|
|
175
|
-
resourceObject.body = body;
|
|
176
|
-
return resourceObject;
|
|
177
|
-
})
|
|
178
|
-
.catch((error: unknown) => {
|
|
179
|
-
console.error('[@zimic/fetch]', `Failed to parse ${resourceType} body:`, error);
|
|
180
|
-
return resourceObject;
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export default FetchResponseError;
|