@zimic/fetch 0.2.1 → 0.2.2
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 +113 -109
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/client/FetchClient.ts +2 -4
- package/src/client/types/public.ts +113 -115
- package/src/client/types/requests.ts +6 -0
- package/src/index.ts +1 -0
package/dist/index.d.ts
CHANGED
|
@@ -176,6 +176,12 @@ type FetchRequestObject = Pick<FetchRequest.Loose, 'url' | 'path' | 'method' | '
|
|
|
176
176
|
*/
|
|
177
177
|
body?: string | null;
|
|
178
178
|
};
|
|
179
|
+
/**
|
|
180
|
+
* A {@link FetchResponse `FetchResponse`} instance with a specific status code.
|
|
181
|
+
*
|
|
182
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponse `FetchResponse` API reference}
|
|
183
|
+
* @see {@link https://developer.mozilla.org/docs/Web/API/Response}
|
|
184
|
+
*/
|
|
179
185
|
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>> {
|
|
180
186
|
/** The request that originated the response. */
|
|
181
187
|
request: FetchRequest<Schema, Method, Path>;
|
|
@@ -508,116 +514,9 @@ type FetchInput<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schem
|
|
|
508
514
|
* @see {@link https://developer.mozilla.org/docs/Web/API/RequestInit}
|
|
509
515
|
* @see {@link https://developer.mozilla.org/docs/Web/API/Response}
|
|
510
516
|
*/
|
|
511
|
-
interface Fetch<Schema extends HttpSchema> extends
|
|
517
|
+
interface Fetch<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
|
|
512
518
|
<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>>;
|
|
513
519
|
<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>>;
|
|
514
|
-
}
|
|
515
|
-
declare namespace Fetch {
|
|
516
|
-
/** A loosely-typed version of {@link Fetch `fetch`}. This can be useful to make requests with fewer type constraints, */
|
|
517
|
-
type Loose = (input: string | URL | FetchRequest.Loose, init?: FetchRequestInit.Loose) => Promise<FetchResponse.Loose>;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* The options to create a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
521
|
-
*
|
|
522
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}
|
|
523
|
-
*/
|
|
524
|
-
interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
|
|
525
|
-
/**
|
|
526
|
-
* A listener function that is called for each request. It can modify the requests before they are sent.
|
|
527
|
-
*
|
|
528
|
-
* @example
|
|
529
|
-
* import { createFetch } from '@zimic/fetch';
|
|
530
|
-
* import { type HttpSchema } from '@zimic/http';
|
|
531
|
-
*
|
|
532
|
-
* interface User {
|
|
533
|
-
* id: string;
|
|
534
|
-
* username: string;
|
|
535
|
-
* }
|
|
536
|
-
*
|
|
537
|
-
* type Schema = HttpSchema<{
|
|
538
|
-
* '/users': {
|
|
539
|
-
* GET: {
|
|
540
|
-
* request: {
|
|
541
|
-
* searchParams: { page?: number; limit?: number };
|
|
542
|
-
* };
|
|
543
|
-
* response: {
|
|
544
|
-
* 200: { body: User[] };
|
|
545
|
-
* };
|
|
546
|
-
* };
|
|
547
|
-
* };
|
|
548
|
-
* }>;
|
|
549
|
-
*
|
|
550
|
-
* const fetch = createFetch<Schema>({
|
|
551
|
-
* baseURL: 'http://localhost:80',
|
|
552
|
-
*
|
|
553
|
-
* onRequest(request) {
|
|
554
|
-
* if (this.isRequest(request, 'GET', '/users')) {
|
|
555
|
-
* const url = new URL(request.url);
|
|
556
|
-
* url.searchParams.append('limit', '10');
|
|
557
|
-
*
|
|
558
|
-
* const updatedRequest = new Request(url, request);
|
|
559
|
-
* return updatedRequest;
|
|
560
|
-
* }
|
|
561
|
-
*
|
|
562
|
-
* return request;
|
|
563
|
-
* },
|
|
564
|
-
* });
|
|
565
|
-
*
|
|
566
|
-
* @param request The original request.
|
|
567
|
-
* @returns The request to be sent. It can be the original request or a modified version of it.
|
|
568
|
-
* @this {Fetch<Schema>} The fetch instance that is sending the request.
|
|
569
|
-
*/
|
|
570
|
-
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
|
|
571
|
-
/**
|
|
572
|
-
* A listener function that is called after each response is received. It can modify the responses before they are
|
|
573
|
-
* returned to the fetch caller.
|
|
574
|
-
*
|
|
575
|
-
* @example
|
|
576
|
-
* import { type HttpSchema } from '@zimic/http';
|
|
577
|
-
* import { createFetch } from '@zimic/fetch';
|
|
578
|
-
*
|
|
579
|
-
* interface User {
|
|
580
|
-
* id: string;
|
|
581
|
-
* username: string;
|
|
582
|
-
* }
|
|
583
|
-
*
|
|
584
|
-
* type Schema = HttpSchema<{
|
|
585
|
-
* '/users': {
|
|
586
|
-
* GET: {
|
|
587
|
-
* response: {
|
|
588
|
-
* 200: {
|
|
589
|
-
* headers: { 'content-encoding'?: string };
|
|
590
|
-
* body: User[];
|
|
591
|
-
* };
|
|
592
|
-
* };
|
|
593
|
-
* };
|
|
594
|
-
* };
|
|
595
|
-
* }>;
|
|
596
|
-
*
|
|
597
|
-
* const fetch = createFetch<Schema>({
|
|
598
|
-
* baseURL: 'http://localhost:80',
|
|
599
|
-
*
|
|
600
|
-
* onResponse(response) {
|
|
601
|
-
* if (this.isResponse(response, 'GET', '/users')) {
|
|
602
|
-
* console.log(response.headers.get('content-encoding'));
|
|
603
|
-
* }
|
|
604
|
-
* return response;
|
|
605
|
-
* },
|
|
606
|
-
* });
|
|
607
|
-
*
|
|
608
|
-
* @param response The original response.
|
|
609
|
-
* @returns The response to be returned.
|
|
610
|
-
* @this {Fetch<Schema>} The fetch instance that received the response.
|
|
611
|
-
*/
|
|
612
|
-
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* The default options for each request sent by the fetch instance.
|
|
616
|
-
*
|
|
617
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchdefaults `fetch.defaults` API reference}
|
|
618
|
-
*/
|
|
619
|
-
type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
|
|
620
|
-
interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
|
|
621
520
|
/**
|
|
622
521
|
* The default options for each request sent by the fetch instance. The available options are the same as the
|
|
623
522
|
* {@link https://developer.mozilla.org/docs/Web/API/RequestInit `RequestInit`} options, plus `baseURL`.
|
|
@@ -974,6 +873,111 @@ interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schem
|
|
|
974
873
|
*/
|
|
975
874
|
isResponseError: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(error: unknown, method: Method, path: Path) => error is FetchResponseError<Schema, Method, Path>;
|
|
976
875
|
}
|
|
876
|
+
declare namespace Fetch {
|
|
877
|
+
/** A loosely-typed version of {@link Fetch `fetch`}. This can be useful to make requests with fewer type constraints, */
|
|
878
|
+
type Loose = (input: string | URL | FetchRequest.Loose, init?: FetchRequestInit.Loose) => Promise<FetchResponse.Loose>;
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* The options to create a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
882
|
+
*
|
|
883
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}
|
|
884
|
+
*/
|
|
885
|
+
interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
|
|
886
|
+
/**
|
|
887
|
+
* A listener function that is called for each request. It can modify the requests before they are sent.
|
|
888
|
+
*
|
|
889
|
+
* @example
|
|
890
|
+
* import { createFetch } from '@zimic/fetch';
|
|
891
|
+
* import { type HttpSchema } from '@zimic/http';
|
|
892
|
+
*
|
|
893
|
+
* interface User {
|
|
894
|
+
* id: string;
|
|
895
|
+
* username: string;
|
|
896
|
+
* }
|
|
897
|
+
*
|
|
898
|
+
* type Schema = HttpSchema<{
|
|
899
|
+
* '/users': {
|
|
900
|
+
* GET: {
|
|
901
|
+
* request: {
|
|
902
|
+
* searchParams: { page?: number; limit?: number };
|
|
903
|
+
* };
|
|
904
|
+
* response: {
|
|
905
|
+
* 200: { body: User[] };
|
|
906
|
+
* };
|
|
907
|
+
* };
|
|
908
|
+
* };
|
|
909
|
+
* }>;
|
|
910
|
+
*
|
|
911
|
+
* const fetch = createFetch<Schema>({
|
|
912
|
+
* baseURL: 'http://localhost:80',
|
|
913
|
+
*
|
|
914
|
+
* onRequest(request) {
|
|
915
|
+
* if (this.isRequest(request, 'GET', '/users')) {
|
|
916
|
+
* const url = new URL(request.url);
|
|
917
|
+
* url.searchParams.append('limit', '10');
|
|
918
|
+
*
|
|
919
|
+
* const updatedRequest = new Request(url, request);
|
|
920
|
+
* return updatedRequest;
|
|
921
|
+
* }
|
|
922
|
+
*
|
|
923
|
+
* return request;
|
|
924
|
+
* },
|
|
925
|
+
* });
|
|
926
|
+
*
|
|
927
|
+
* @param request The original request.
|
|
928
|
+
* @returns The request to be sent. It can be the original request or a modified version of it.
|
|
929
|
+
* @this {Fetch<Schema>} The fetch instance that is sending the request.
|
|
930
|
+
*/
|
|
931
|
+
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
|
|
932
|
+
/**
|
|
933
|
+
* A listener function that is called after each response is received. It can modify the responses before they are
|
|
934
|
+
* returned to the fetch caller.
|
|
935
|
+
*
|
|
936
|
+
* @example
|
|
937
|
+
* import { type HttpSchema } from '@zimic/http';
|
|
938
|
+
* import { createFetch } from '@zimic/fetch';
|
|
939
|
+
*
|
|
940
|
+
* interface User {
|
|
941
|
+
* id: string;
|
|
942
|
+
* username: string;
|
|
943
|
+
* }
|
|
944
|
+
*
|
|
945
|
+
* type Schema = HttpSchema<{
|
|
946
|
+
* '/users': {
|
|
947
|
+
* GET: {
|
|
948
|
+
* response: {
|
|
949
|
+
* 200: {
|
|
950
|
+
* headers: { 'content-encoding'?: string };
|
|
951
|
+
* body: User[];
|
|
952
|
+
* };
|
|
953
|
+
* };
|
|
954
|
+
* };
|
|
955
|
+
* };
|
|
956
|
+
* }>;
|
|
957
|
+
*
|
|
958
|
+
* const fetch = createFetch<Schema>({
|
|
959
|
+
* baseURL: 'http://localhost:80',
|
|
960
|
+
*
|
|
961
|
+
* onResponse(response) {
|
|
962
|
+
* if (this.isResponse(response, 'GET', '/users')) {
|
|
963
|
+
* console.log(response.headers.get('content-encoding'));
|
|
964
|
+
* }
|
|
965
|
+
* return response;
|
|
966
|
+
* },
|
|
967
|
+
* });
|
|
968
|
+
*
|
|
969
|
+
* @param response The original response.
|
|
970
|
+
* @returns The response to be returned.
|
|
971
|
+
* @this {Fetch<Schema>} The fetch instance that received the response.
|
|
972
|
+
*/
|
|
973
|
+
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* The default options for each request sent by the fetch instance.
|
|
977
|
+
*
|
|
978
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchdefaults `fetch.defaults` API reference}
|
|
979
|
+
*/
|
|
980
|
+
type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
|
|
977
981
|
/**
|
|
978
982
|
* Infers the schema of a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
979
983
|
*
|
|
@@ -1058,4 +1062,4 @@ type InferFetchSchema<FetchInstance> = FetchInstance extends Fetch<infer Schema>
|
|
|
1058
1062
|
*/
|
|
1059
1063
|
declare function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema>;
|
|
1060
1064
|
|
|
1061
|
-
export { Fetch, type FetchDefaults, type FetchInput, type FetchOptions, FetchRequest, type FetchRequestConstructor, FetchRequestInit, type FetchRequestObject, FetchResponse, FetchResponseError, type FetchResponseErrorObject, FetchResponseErrorObjectOptions, type FetchResponseObject, type InferFetchSchema, type JSONStringified, createFetch };
|
|
1065
|
+
export { Fetch, type FetchDefaults, type FetchInput, type FetchOptions, FetchRequest, type FetchRequestConstructor, FetchRequestInit, type FetchRequestObject, FetchResponse, FetchResponseError, type FetchResponseErrorObject, FetchResponseErrorObjectOptions, type FetchResponseObject, type FetchResponsePerStatusCode, type InferFetchSchema, type JSONStringified, createFetch };
|
package/dist/index.js
CHANGED
|
@@ -78,11 +78,11 @@ var FetchResponseError = class extends Error {
|
|
|
78
78
|
};
|
|
79
79
|
var FetchResponseError_default = FetchResponseError;
|
|
80
80
|
|
|
81
|
-
// ../zimic-utils/dist/chunk-
|
|
81
|
+
// ../zimic-utils/dist/chunk-6IEM75FG.mjs
|
|
82
82
|
var __defProp2 = Object.defineProperty;
|
|
83
83
|
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
|
|
84
84
|
|
|
85
|
-
// ../zimic-utils/dist/chunk-
|
|
85
|
+
// ../zimic-utils/dist/chunk-PFX6YIKR.mjs
|
|
86
86
|
var URL_PATH_PARAM_REGEX = /\/:([^/]+)/g;
|
|
87
87
|
function createRegExpFromURL(url) {
|
|
88
88
|
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
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":["HttpHeaders","__defProp","__name","Request","HttpSearchParams"],"mappings":"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","file":"index.js","sourcesContent":["import { HttpHeaders, HttpHeadersSchema, HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchRequestObject, FetchResponse, FetchResponseObject } from '../types/requests';\n\n/**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObjectOptions {\n /**\n * Whether to include the body of the request in the plain object.\n *\n * @default false\n */\n includeRequestBody?: boolean;\n\n /**\n * Whether to include the body of the response in the plain object.\n *\n * @default false\n */\n includeResponseBody?: boolean;\n}\n\nexport namespace FetchResponseErrorObjectOptions {\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, including the body of\n * the request and/or response.\n */\n export type WithBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody: true } | { includeResponseBody: true });\n\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, excluding the body of\n * the request and/or response.\n */\n export type WithoutBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody?: false } | { includeResponseBody?: false });\n}\n\n/**\n * A plain object representation of a {@link FetchResponseError `FetchResponseError`}, compatible with JSON. It is useful\n * for serialization, debugging, and logging purposes.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObject {\n name: string;\n message: string;\n request: FetchRequestObject;\n response: FetchResponseObject;\n}\n\n/**\n * An error representing a response with a failure status code (4XX or 5XX).\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users/:userId': {\n * GET: {\n * response: {\n * 200: { body: User };\n * 404: { body: { message: string } };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * console.log(response.status); // 404\n *\n * console.log(response.error); // FetchResponseError<Schema, 'GET', '/users'>\n * console.log(response.error.request); // FetchRequest<Schema, 'GET', '/users'>\n * console.log(response.error.response); // FetchResponse<Schema, 'GET', '/users'>\n *\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerror `FetchResponseError` API reference}\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 /**\n * Converts this error into a plain object. This method is useful for serialization, debugging, and logging purposes.\n *\n * @example\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @param options Options for converting this error into a plain object. By default, the body of the request and\n * response will not be included.\n * @returns A plain object representing this error. If `options.includeRequestBody` or `options.includeResponseBody`\n * is `true`, the body of the request and response will be included, respectively, and the return is a `Promise`.\n * Otherwise, the return is the plain object itself without the bodies.\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\n toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;\n toObject(options: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject {\n const includeRequestBody = options?.includeRequestBody ?? false;\n const includeResponseBody = options?.includeResponseBody ?? false;\n\n const partialObject = {\n name: this.name,\n message: this.message,\n } satisfies Partial<FetchResponseErrorObject>;\n\n if (!includeRequestBody && !includeResponseBody) {\n const request = this.convertRequestToObject({ includeBody: false });\n const response = this.convertResponseToObject({ includeBody: false });\n return { ...partialObject, request, response };\n }\n\n return Promise.all([\n this.convertRequestToObject({ includeBody: includeRequestBody }),\n this.convertResponseToObject({ includeBody: includeResponseBody }),\n ]).then(([request, response]) => ({ ...partialObject, request, response }));\n }\n\n private convertRequestToObject(options: { includeBody: true }): Promise<FetchRequestObject>;\n private convertRequestToObject(options: { includeBody: false }): FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject {\n const requestObject: FetchRequestObject = {\n url: this.request.url,\n path: this.request.path,\n method: this.request.method,\n headers: HttpHeaders.prototype.toObject.call(this.request.headers) as HttpHeadersSchema,\n cache: this.request.cache,\n destination: this.request.destination,\n credentials: this.request.credentials,\n integrity: this.request.integrity,\n keepalive: this.request.keepalive,\n mode: this.request.mode,\n redirect: this.request.redirect,\n referrer: this.request.referrer,\n referrerPolicy: this.request.referrerPolicy,\n };\n\n if (!options.includeBody) {\n return requestObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.request.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n requestObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return requestObject;\n });\n }\n\n private convertResponseToObject(options: { includeBody: true }): Promise<FetchResponseObject>;\n private convertResponseToObject(options: { includeBody: false }): FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject {\n const responseObject: FetchResponseObject = {\n url: this.response.url,\n type: this.response.type,\n status: this.response.status,\n statusText: this.response.statusText,\n ok: this.response.ok,\n headers: HttpHeaders.prototype.toObject.call(this.response.headers) as HttpHeadersSchema,\n redirected: this.response.redirected,\n };\n\n if (!options.includeBody) {\n return responseObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.response.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n responseObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return responseObject;\n });\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 { FetchInput, FetchOptions, Fetch, FetchClient as PublicFetchClient, FetchDefaults } 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 Fetch.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\n // Optimize type checking by narrowing the type of headers\n const headersFromRequest = new HttpHeaders(input.headers as 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\n/**\n * Creates a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance} typed with an HTTP\n * schema, closely compatible with the {@link https://developer.mozilla.org/docs/Web/API/Fetch_API native Fetch API}. All\n * requests and responses are typed by default with the schema, including methods, paths, status codes, parameters, and\n * bodies.\n *\n * Requests sent by the fetch instance have their URL automatically prefixed with the base URL of the instance.\n * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch.defaults Default options} are also applied to the\n * requests, if provided.\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users': {\n * POST: {\n * request: {\n * headers: { 'content-type': 'application/json' };\n * body: { username: string };\n * };\n * response: {\n * 201: { body: User };\n * };\n * };\n *\n * GET: {\n * request: {\n * searchParams: {\n * query?: string;\n * page?: number;\n * limit?: number;\n * };\n * };\n * response: {\n * 200: { body: User[] };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch `fetch` API reference}\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-6IEM75FG.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":["HttpHeaders","__defProp","__name","Request","HttpSearchParams"],"mappings":"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","file":"index.js","sourcesContent":["import { HttpHeaders, HttpHeadersSchema, HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchRequestObject, FetchResponse, FetchResponseObject } from '../types/requests';\n\n/**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObjectOptions {\n /**\n * Whether to include the body of the request in the plain object.\n *\n * @default false\n */\n includeRequestBody?: boolean;\n\n /**\n * Whether to include the body of the response in the plain object.\n *\n * @default false\n */\n includeResponseBody?: boolean;\n}\n\nexport namespace FetchResponseErrorObjectOptions {\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, including the body of\n * the request and/or response.\n */\n export type WithBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody: true } | { includeResponseBody: true });\n\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, excluding the body of\n * the request and/or response.\n */\n export type WithoutBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody?: false } | { includeResponseBody?: false });\n}\n\n/**\n * A plain object representation of a {@link FetchResponseError `FetchResponseError`}, compatible with JSON. It is useful\n * for serialization, debugging, and logging purposes.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObject {\n name: string;\n message: string;\n request: FetchRequestObject;\n response: FetchResponseObject;\n}\n\n/**\n * An error representing a response with a failure status code (4XX or 5XX).\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users/:userId': {\n * GET: {\n * response: {\n * 200: { body: User };\n * 404: { body: { message: string } };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * console.log(response.status); // 404\n *\n * console.log(response.error); // FetchResponseError<Schema, 'GET', '/users'>\n * console.log(response.error.request); // FetchRequest<Schema, 'GET', '/users'>\n * console.log(response.error.response); // FetchResponse<Schema, 'GET', '/users'>\n *\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerror `FetchResponseError` API reference}\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 /**\n * Converts this error into a plain object. This method is useful for serialization, debugging, and logging purposes.\n *\n * @example\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @param options Options for converting this error into a plain object. By default, the body of the request and\n * response will not be included.\n * @returns A plain object representing this error. If `options.includeRequestBody` or `options.includeResponseBody`\n * is `true`, the body of the request and response will be included, respectively, and the return is a `Promise`.\n * Otherwise, the return is the plain object itself without the bodies.\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\n toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;\n toObject(options: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject {\n const includeRequestBody = options?.includeRequestBody ?? false;\n const includeResponseBody = options?.includeResponseBody ?? false;\n\n const partialObject = {\n name: this.name,\n message: this.message,\n } satisfies Partial<FetchResponseErrorObject>;\n\n if (!includeRequestBody && !includeResponseBody) {\n const request = this.convertRequestToObject({ includeBody: false });\n const response = this.convertResponseToObject({ includeBody: false });\n return { ...partialObject, request, response };\n }\n\n return Promise.all([\n this.convertRequestToObject({ includeBody: includeRequestBody }),\n this.convertResponseToObject({ includeBody: includeResponseBody }),\n ]).then(([request, response]) => ({ ...partialObject, request, response }));\n }\n\n private convertRequestToObject(options: { includeBody: true }): Promise<FetchRequestObject>;\n private convertRequestToObject(options: { includeBody: false }): FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject {\n const requestObject: FetchRequestObject = {\n url: this.request.url,\n path: this.request.path,\n method: this.request.method,\n headers: HttpHeaders.prototype.toObject.call(this.request.headers) as HttpHeadersSchema,\n cache: this.request.cache,\n destination: this.request.destination,\n credentials: this.request.credentials,\n integrity: this.request.integrity,\n keepalive: this.request.keepalive,\n mode: this.request.mode,\n redirect: this.request.redirect,\n referrer: this.request.referrer,\n referrerPolicy: this.request.referrerPolicy,\n };\n\n if (!options.includeBody) {\n return requestObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.request.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n requestObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return requestObject;\n });\n }\n\n private convertResponseToObject(options: { includeBody: true }): Promise<FetchResponseObject>;\n private convertResponseToObject(options: { includeBody: false }): FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject {\n const responseObject: FetchResponseObject = {\n url: this.response.url,\n type: this.response.type,\n status: this.response.status,\n statusText: this.response.statusText,\n ok: this.response.ok,\n headers: HttpHeaders.prototype.toObject.call(this.response.headers) as HttpHeadersSchema,\n redirected: this.response.redirected,\n };\n\n if (!options.includeBody) {\n return responseObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.response.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n responseObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return responseObject;\n });\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 __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\nvar __require = /* @__PURE__ */ ((x) => typeof require !== \"undefined\" ? require : typeof Proxy !== \"undefined\" ? new Proxy(x, {\n get: (a, b) => (typeof require !== \"undefined\" ? require : a)[b]\n}) : x)(function(x) {\n if (typeof require !== \"undefined\") return require.apply(this, arguments);\n throw Error('Dynamic require of \"' + x + '\" is not supported');\n});\nvar __commonJS = (cb, mod) => function __require2() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\n\nexport { __commonJS, __name, __require, __toESM };\n//# sourceMappingURL=chunk-6IEM75FG.mjs.map\n//# sourceMappingURL=chunk-6IEM75FG.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 { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> implements Omit<Fetch<Schema>, 'defaults' | 'loose' | 'Request'> {\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 Fetch.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\n // Optimize type checking by narrowing the type of headers\n const headersFromRequest = new HttpHeaders(input.headers as 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\n/**\n * Creates a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance} typed with an HTTP\n * schema, closely compatible with the {@link https://developer.mozilla.org/docs/Web/API/Fetch_API native Fetch API}. All\n * requests and responses are typed by default with the schema, including methods, paths, status codes, parameters, and\n * bodies.\n *\n * Requests sent by the fetch instance have their URL automatically prefixed with the base URL of the instance.\n * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch.defaults Default options} are also applied to the\n * requests, if provided.\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users': {\n * POST: {\n * request: {\n * headers: { 'content-type': 'application/json' };\n * body: { username: string };\n * };\n * response: {\n * 201: { body: User };\n * };\n * };\n *\n * GET: {\n * request: {\n * searchParams: {\n * query?: string;\n * page?: number;\n * limit?: number;\n * };\n * };\n * response: {\n * 200: { body: User[] };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch `fetch` API reference}\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
|
@@ -76,11 +76,11 @@ var FetchResponseError = class extends Error {
|
|
|
76
76
|
};
|
|
77
77
|
var FetchResponseError_default = FetchResponseError;
|
|
78
78
|
|
|
79
|
-
// ../zimic-utils/dist/chunk-
|
|
79
|
+
// ../zimic-utils/dist/chunk-6IEM75FG.mjs
|
|
80
80
|
var __defProp2 = Object.defineProperty;
|
|
81
81
|
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
|
|
82
82
|
|
|
83
|
-
// ../zimic-utils/dist/chunk-
|
|
83
|
+
// ../zimic-utils/dist/chunk-PFX6YIKR.mjs
|
|
84
84
|
var URL_PATH_PARAM_REGEX = /\/:([^/]+)/g;
|
|
85
85
|
function createRegExpFromURL(url) {
|
|
86
86
|
URL_PATH_PARAM_REGEX.lastIndex = 0;
|
package/dist/index.mjs.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","HttpHeaders"],"mappings":"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","file":"index.mjs","sourcesContent":["import { HttpHeaders, HttpHeadersSchema, HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchRequestObject, FetchResponse, FetchResponseObject } from '../types/requests';\n\n/**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObjectOptions {\n /**\n * Whether to include the body of the request in the plain object.\n *\n * @default false\n */\n includeRequestBody?: boolean;\n\n /**\n * Whether to include the body of the response in the plain object.\n *\n * @default false\n */\n includeResponseBody?: boolean;\n}\n\nexport namespace FetchResponseErrorObjectOptions {\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, including the body of\n * the request and/or response.\n */\n export type WithBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody: true } | { includeResponseBody: true });\n\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, excluding the body of\n * the request and/or response.\n */\n export type WithoutBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody?: false } | { includeResponseBody?: false });\n}\n\n/**\n * A plain object representation of a {@link FetchResponseError `FetchResponseError`}, compatible with JSON. It is useful\n * for serialization, debugging, and logging purposes.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObject {\n name: string;\n message: string;\n request: FetchRequestObject;\n response: FetchResponseObject;\n}\n\n/**\n * An error representing a response with a failure status code (4XX or 5XX).\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users/:userId': {\n * GET: {\n * response: {\n * 200: { body: User };\n * 404: { body: { message: string } };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * console.log(response.status); // 404\n *\n * console.log(response.error); // FetchResponseError<Schema, 'GET', '/users'>\n * console.log(response.error.request); // FetchRequest<Schema, 'GET', '/users'>\n * console.log(response.error.response); // FetchResponse<Schema, 'GET', '/users'>\n *\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerror `FetchResponseError` API reference}\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 /**\n * Converts this error into a plain object. This method is useful for serialization, debugging, and logging purposes.\n *\n * @example\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @param options Options for converting this error into a plain object. By default, the body of the request and\n * response will not be included.\n * @returns A plain object representing this error. If `options.includeRequestBody` or `options.includeResponseBody`\n * is `true`, the body of the request and response will be included, respectively, and the return is a `Promise`.\n * Otherwise, the return is the plain object itself without the bodies.\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\n toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;\n toObject(options: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject {\n const includeRequestBody = options?.includeRequestBody ?? false;\n const includeResponseBody = options?.includeResponseBody ?? false;\n\n const partialObject = {\n name: this.name,\n message: this.message,\n } satisfies Partial<FetchResponseErrorObject>;\n\n if (!includeRequestBody && !includeResponseBody) {\n const request = this.convertRequestToObject({ includeBody: false });\n const response = this.convertResponseToObject({ includeBody: false });\n return { ...partialObject, request, response };\n }\n\n return Promise.all([\n this.convertRequestToObject({ includeBody: includeRequestBody }),\n this.convertResponseToObject({ includeBody: includeResponseBody }),\n ]).then(([request, response]) => ({ ...partialObject, request, response }));\n }\n\n private convertRequestToObject(options: { includeBody: true }): Promise<FetchRequestObject>;\n private convertRequestToObject(options: { includeBody: false }): FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject {\n const requestObject: FetchRequestObject = {\n url: this.request.url,\n path: this.request.path,\n method: this.request.method,\n headers: HttpHeaders.prototype.toObject.call(this.request.headers) as HttpHeadersSchema,\n cache: this.request.cache,\n destination: this.request.destination,\n credentials: this.request.credentials,\n integrity: this.request.integrity,\n keepalive: this.request.keepalive,\n mode: this.request.mode,\n redirect: this.request.redirect,\n referrer: this.request.referrer,\n referrerPolicy: this.request.referrerPolicy,\n };\n\n if (!options.includeBody) {\n return requestObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.request.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n requestObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return requestObject;\n });\n }\n\n private convertResponseToObject(options: { includeBody: true }): Promise<FetchResponseObject>;\n private convertResponseToObject(options: { includeBody: false }): FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject {\n const responseObject: FetchResponseObject = {\n url: this.response.url,\n type: this.response.type,\n status: this.response.status,\n statusText: this.response.statusText,\n ok: this.response.ok,\n headers: HttpHeaders.prototype.toObject.call(this.response.headers) as HttpHeadersSchema,\n redirected: this.response.redirected,\n };\n\n if (!options.includeBody) {\n return responseObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.response.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n responseObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return responseObject;\n });\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 { FetchInput, FetchOptions, Fetch, FetchClient as PublicFetchClient, FetchDefaults } 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 Fetch.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\n // Optimize type checking by narrowing the type of headers\n const headersFromRequest = new HttpHeaders(input.headers as 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\n/**\n * Creates a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance} typed with an HTTP\n * schema, closely compatible with the {@link https://developer.mozilla.org/docs/Web/API/Fetch_API native Fetch API}. All\n * requests and responses are typed by default with the schema, including methods, paths, status codes, parameters, and\n * bodies.\n *\n * Requests sent by the fetch instance have their URL automatically prefixed with the base URL of the instance.\n * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch.defaults Default options} are also applied to the\n * requests, if provided.\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users': {\n * POST: {\n * request: {\n * headers: { 'content-type': 'application/json' };\n * body: { username: string };\n * };\n * response: {\n * 201: { body: User };\n * };\n * };\n *\n * GET: {\n * request: {\n * searchParams: {\n * query?: string;\n * page?: number;\n * limit?: number;\n * };\n * };\n * response: {\n * 200: { body: User[] };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch `fetch` API reference}\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/errors/FetchResponseError.ts","../../zimic-utils/dist/chunk-6IEM75FG.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"],"mappings":"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","file":"index.mjs","sourcesContent":["import { HttpHeaders, HttpHeadersSchema, HttpSchema, HttpSchemaMethod, HttpSchemaPath } from '@zimic/http';\n\nimport { FetchRequest, FetchRequestObject, FetchResponse, FetchResponseObject } from '../types/requests';\n\n/**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObjectOptions {\n /**\n * Whether to include the body of the request in the plain object.\n *\n * @default false\n */\n includeRequestBody?: boolean;\n\n /**\n * Whether to include the body of the response in the plain object.\n *\n * @default false\n */\n includeResponseBody?: boolean;\n}\n\nexport namespace FetchResponseErrorObjectOptions {\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, including the body of\n * the request and/or response.\n */\n export type WithBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody: true } | { includeResponseBody: true });\n\n /**\n * Options for converting a {@link FetchResponseError `FetchResponseError`} into a plain object, excluding the body of\n * the request and/or response.\n */\n export type WithoutBody = FetchResponseErrorObjectOptions &\n ({ includeRequestBody?: false } | { includeResponseBody?: false });\n}\n\n/**\n * A plain object representation of a {@link FetchResponseError `FetchResponseError`}, compatible with JSON. It is useful\n * for serialization, debugging, and logging purposes.\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\nexport interface FetchResponseErrorObject {\n name: string;\n message: string;\n request: FetchRequestObject;\n response: FetchResponseObject;\n}\n\n/**\n * An error representing a response with a failure status code (4XX or 5XX).\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users/:userId': {\n * GET: {\n * response: {\n * 200: { body: User };\n * 404: { body: { message: string } };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * console.log(response.status); // 404\n *\n * console.log(response.error); // FetchResponseError<Schema, 'GET', '/users'>\n * console.log(response.error.request); // FetchRequest<Schema, 'GET', '/users'>\n * console.log(response.error.response); // FetchResponse<Schema, 'GET', '/users'>\n *\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerror `FetchResponseError` API reference}\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 /**\n * Converts this error into a plain object. This method is useful for serialization, debugging, and logging purposes.\n *\n * @example\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * const response = await fetch(`/users/${userId}`, {\n * method: 'GET',\n * });\n *\n * if (!response.ok) {\n * const plainError = response.error.toObject();\n * console.log(JSON.stringify(plainError));\n * // {\"name\":\"FetchResponseError\",\"message\":\"...\",\"request\":{...},\"response\":{...}}\n * }\n *\n * @param options Options for converting this error into a plain object. By default, the body of the request and\n * response will not be included.\n * @returns A plain object representing this error. If `options.includeRequestBody` or `options.includeResponseBody`\n * is `true`, the body of the request and response will be included, respectively, and the return is a `Promise`.\n * Otherwise, the return is the plain object itself without the bodies.\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponseerrortoobject `FetchResponseError#toObject` API reference}\n */\n toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;\n toObject(options: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject;\n toObject(options?: FetchResponseErrorObjectOptions): Promise<FetchResponseErrorObject> | FetchResponseErrorObject {\n const includeRequestBody = options?.includeRequestBody ?? false;\n const includeResponseBody = options?.includeResponseBody ?? false;\n\n const partialObject = {\n name: this.name,\n message: this.message,\n } satisfies Partial<FetchResponseErrorObject>;\n\n if (!includeRequestBody && !includeResponseBody) {\n const request = this.convertRequestToObject({ includeBody: false });\n const response = this.convertResponseToObject({ includeBody: false });\n return { ...partialObject, request, response };\n }\n\n return Promise.all([\n this.convertRequestToObject({ includeBody: includeRequestBody }),\n this.convertResponseToObject({ includeBody: includeResponseBody }),\n ]).then(([request, response]) => ({ ...partialObject, request, response }));\n }\n\n private convertRequestToObject(options: { includeBody: true }): Promise<FetchRequestObject>;\n private convertRequestToObject(options: { includeBody: false }): FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject;\n private convertRequestToObject(options: { includeBody: boolean }): Promise<FetchRequestObject> | FetchRequestObject {\n const requestObject: FetchRequestObject = {\n url: this.request.url,\n path: this.request.path,\n method: this.request.method,\n headers: HttpHeaders.prototype.toObject.call(this.request.headers) as HttpHeadersSchema,\n cache: this.request.cache,\n destination: this.request.destination,\n credentials: this.request.credentials,\n integrity: this.request.integrity,\n keepalive: this.request.keepalive,\n mode: this.request.mode,\n redirect: this.request.redirect,\n referrer: this.request.referrer,\n referrerPolicy: this.request.referrerPolicy,\n };\n\n if (!options.includeBody) {\n return requestObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.request.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n requestObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return requestObject;\n });\n }\n\n private convertResponseToObject(options: { includeBody: true }): Promise<FetchResponseObject>;\n private convertResponseToObject(options: { includeBody: false }): FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject;\n private convertResponseToObject(options: {\n includeBody: boolean;\n }): Promise<FetchResponseObject> | FetchResponseObject {\n const responseObject: FetchResponseObject = {\n url: this.response.url,\n type: this.response.type,\n status: this.response.status,\n statusText: this.response.statusText,\n ok: this.response.ok,\n headers: HttpHeaders.prototype.toObject.call(this.response.headers) as HttpHeadersSchema,\n redirected: this.response.redirected,\n };\n\n if (!options.includeBody) {\n return responseObject;\n }\n\n // Optimize type checking by narrowing the type of the body\n const bodyAsTextPromise = this.response.text() as Promise<string>;\n\n return bodyAsTextPromise.then((bodyAsText) => {\n responseObject.body = bodyAsText.length > 0 ? bodyAsText : null;\n return responseObject;\n });\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 __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\nvar __require = /* @__PURE__ */ ((x) => typeof require !== \"undefined\" ? require : typeof Proxy !== \"undefined\" ? new Proxy(x, {\n get: (a, b) => (typeof require !== \"undefined\" ? require : a)[b]\n}) : x)(function(x) {\n if (typeof require !== \"undefined\") return require.apply(this, arguments);\n throw Error('Dynamic require of \"' + x + '\" is not supported');\n});\nvar __commonJS = (cb, mod) => function __require2() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\n\nexport { __commonJS, __name, __require, __toESM };\n//# sourceMappingURL=chunk-6IEM75FG.mjs.map\n//# sourceMappingURL=chunk-6IEM75FG.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 { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';\nimport { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';\n\nclass FetchClient<Schema extends HttpSchema> implements Omit<Fetch<Schema>, 'defaults' | 'loose' | 'Request'> {\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 Fetch.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\n // Optimize type checking by narrowing the type of headers\n const headersFromRequest = new HttpHeaders(input.headers as 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\n/**\n * Creates a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance} typed with an HTTP\n * schema, closely compatible with the {@link https://developer.mozilla.org/docs/Web/API/Fetch_API native Fetch API}. All\n * requests and responses are typed by default with the schema, including methods, paths, status codes, parameters, and\n * bodies.\n *\n * Requests sent by the fetch instance have their URL automatically prefixed with the base URL of the instance.\n * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch.defaults Default options} are also applied to the\n * requests, if provided.\n *\n * @example\n * import { type HttpSchema } from '@zimic/http';\n * import { createFetch } from '@zimic/fetch';\n *\n * interface User {\n * id: string;\n * username: string;\n * }\n *\n * type Schema = HttpSchema<{\n * '/users': {\n * POST: {\n * request: {\n * headers: { 'content-type': 'application/json' };\n * body: { username: string };\n * };\n * response: {\n * 201: { body: User };\n * };\n * };\n *\n * GET: {\n * request: {\n * searchParams: {\n * query?: string;\n * page?: number;\n * limit?: number;\n * };\n * };\n * response: {\n * 200: { body: User[] };\n * };\n * };\n * };\n * }>;\n *\n * const fetch = createFetch<Schema>({\n * baseURL: 'http://localhost:3000',\n * });\n *\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}\n * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch `fetch` API reference}\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.2.
|
|
16
|
+
"version": "0.2.2",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "https://github.com/zimicjs/zimic.git",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"./package.json": "./package.json"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@types/node": "^22.14.
|
|
60
|
+
"@types/node": "^22.14.1",
|
|
61
61
|
"@vitest/browser": "^3.1.1",
|
|
62
62
|
"@vitest/coverage-istanbul": "^3.1.1",
|
|
63
63
|
"dotenv-cli": "^8.0.0",
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"typescript": "^5.8.3",
|
|
68
68
|
"vitest": "^3.1.1",
|
|
69
69
|
"@zimic/eslint-config-node": "0.0.0",
|
|
70
|
-
"@zimic/interceptor": "0.17.
|
|
70
|
+
"@zimic/interceptor": "0.17.1",
|
|
71
71
|
"@zimic/lint-staged-config": "0.0.0",
|
|
72
|
-
"@zimic/
|
|
73
|
-
"@zimic/
|
|
72
|
+
"@zimic/utils": "0.0.0",
|
|
73
|
+
"@zimic/tsconfig": "0.0.0"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"
|
|
77
|
-
"
|
|
76
|
+
"typescript": ">=4.8.0",
|
|
77
|
+
"@zimic/http": "^0.3.0 || 0.3.1"
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
80
|
"dev": "tsup --watch",
|
|
@@ -11,12 +11,10 @@ import excludeURLParams from '@zimic/utils/url/excludeURLParams';
|
|
|
11
11
|
import joinURL from '@zimic/utils/url/joinURL';
|
|
12
12
|
|
|
13
13
|
import FetchResponseError from './errors/FetchResponseError';
|
|
14
|
-
import { FetchInput, FetchOptions, Fetch,
|
|
14
|
+
import { FetchInput, FetchOptions, Fetch, FetchDefaults } from './types/public';
|
|
15
15
|
import { FetchRequestConstructor, FetchRequestInit, FetchRequest, FetchResponse } from './types/requests';
|
|
16
16
|
|
|
17
|
-
class FetchClient<Schema extends HttpSchema>
|
|
18
|
-
implements Omit<PublicFetchClient<Schema>, 'defaults' | 'loose' | 'Request'>
|
|
19
|
-
{
|
|
17
|
+
class FetchClient<Schema extends HttpSchema> implements Omit<Fetch<Schema>, 'defaults' | 'loose' | 'Request'> {
|
|
20
18
|
fetch: Fetch<Schema>;
|
|
21
19
|
|
|
22
20
|
constructor({ onRequest, onResponse, ...defaults }: FetchOptions<Schema>) {
|
|
@@ -81,7 +81,7 @@ export type FetchInput<
|
|
|
81
81
|
* @see {@link https://developer.mozilla.org/docs/Web/API/RequestInit}
|
|
82
82
|
* @see {@link https://developer.mozilla.org/docs/Web/API/Response}
|
|
83
83
|
*/
|
|
84
|
-
export interface Fetch<Schema extends HttpSchema> extends
|
|
84
|
+
export interface Fetch<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
|
|
85
85
|
<
|
|
86
86
|
Method extends HttpSchemaMethod<Schema>,
|
|
87
87
|
Path extends HttpSchemaPath.NonLiteral<Schema, Method>,
|
|
@@ -99,121 +99,7 @@ export interface Fetch<Schema extends HttpSchema> extends FetchClient<Schema> {
|
|
|
99
99
|
input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>,
|
|
100
100
|
init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>,
|
|
101
101
|
): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, false, Redirect>>;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export namespace Fetch {
|
|
105
|
-
/** A loosely-typed version of {@link Fetch `fetch`}. This can be useful to make requests with fewer type constraints, */
|
|
106
|
-
export type Loose = (
|
|
107
|
-
input: string | URL | FetchRequest.Loose,
|
|
108
|
-
init?: FetchRequestInit.Loose,
|
|
109
|
-
) => Promise<FetchResponse.Loose>;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* The options to create a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
114
|
-
*
|
|
115
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}
|
|
116
|
-
*/
|
|
117
|
-
export interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
|
|
118
|
-
/**
|
|
119
|
-
* A listener function that is called for each request. It can modify the requests before they are sent.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* import { createFetch } from '@zimic/fetch';
|
|
123
|
-
* import { type HttpSchema } from '@zimic/http';
|
|
124
|
-
*
|
|
125
|
-
* interface User {
|
|
126
|
-
* id: string;
|
|
127
|
-
* username: string;
|
|
128
|
-
* }
|
|
129
|
-
*
|
|
130
|
-
* type Schema = HttpSchema<{
|
|
131
|
-
* '/users': {
|
|
132
|
-
* GET: {
|
|
133
|
-
* request: {
|
|
134
|
-
* searchParams: { page?: number; limit?: number };
|
|
135
|
-
* };
|
|
136
|
-
* response: {
|
|
137
|
-
* 200: { body: User[] };
|
|
138
|
-
* };
|
|
139
|
-
* };
|
|
140
|
-
* };
|
|
141
|
-
* }>;
|
|
142
|
-
*
|
|
143
|
-
* const fetch = createFetch<Schema>({
|
|
144
|
-
* baseURL: 'http://localhost:80',
|
|
145
|
-
*
|
|
146
|
-
* onRequest(request) {
|
|
147
|
-
* if (this.isRequest(request, 'GET', '/users')) {
|
|
148
|
-
* const url = new URL(request.url);
|
|
149
|
-
* url.searchParams.append('limit', '10');
|
|
150
|
-
*
|
|
151
|
-
* const updatedRequest = new Request(url, request);
|
|
152
|
-
* return updatedRequest;
|
|
153
|
-
* }
|
|
154
|
-
*
|
|
155
|
-
* return request;
|
|
156
|
-
* },
|
|
157
|
-
* });
|
|
158
|
-
*
|
|
159
|
-
* @param request The original request.
|
|
160
|
-
* @returns The request to be sent. It can be the original request or a modified version of it.
|
|
161
|
-
* @this {Fetch<Schema>} The fetch instance that is sending the request.
|
|
162
|
-
*/
|
|
163
|
-
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* A listener function that is called after each response is received. It can modify the responses before they are
|
|
167
|
-
* returned to the fetch caller.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* import { type HttpSchema } from '@zimic/http';
|
|
171
|
-
* import { createFetch } from '@zimic/fetch';
|
|
172
|
-
*
|
|
173
|
-
* interface User {
|
|
174
|
-
* id: string;
|
|
175
|
-
* username: string;
|
|
176
|
-
* }
|
|
177
|
-
*
|
|
178
|
-
* type Schema = HttpSchema<{
|
|
179
|
-
* '/users': {
|
|
180
|
-
* GET: {
|
|
181
|
-
* response: {
|
|
182
|
-
* 200: {
|
|
183
|
-
* headers: { 'content-encoding'?: string };
|
|
184
|
-
* body: User[];
|
|
185
|
-
* };
|
|
186
|
-
* };
|
|
187
|
-
* };
|
|
188
|
-
* };
|
|
189
|
-
* }>;
|
|
190
|
-
*
|
|
191
|
-
* const fetch = createFetch<Schema>({
|
|
192
|
-
* baseURL: 'http://localhost:80',
|
|
193
|
-
*
|
|
194
|
-
* onResponse(response) {
|
|
195
|
-
* if (this.isResponse(response, 'GET', '/users')) {
|
|
196
|
-
* console.log(response.headers.get('content-encoding'));
|
|
197
|
-
* }
|
|
198
|
-
* return response;
|
|
199
|
-
* },
|
|
200
|
-
* });
|
|
201
|
-
*
|
|
202
|
-
* @param response The original response.
|
|
203
|
-
* @returns The response to be returned.
|
|
204
|
-
* @this {Fetch<Schema>} The fetch instance that received the response.
|
|
205
|
-
*/
|
|
206
|
-
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* The default options for each request sent by the fetch instance.
|
|
211
|
-
*
|
|
212
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchdefaults `fetch.defaults` API reference}
|
|
213
|
-
*/
|
|
214
|
-
export type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
|
|
215
102
|
|
|
216
|
-
export interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'> {
|
|
217
103
|
/**
|
|
218
104
|
* The default options for each request sent by the fetch instance. The available options are the same as the
|
|
219
105
|
* {@link https://developer.mozilla.org/docs/Web/API/RequestInit `RequestInit`} options, plus `baseURL`.
|
|
@@ -588,6 +474,118 @@ export interface FetchClient<Schema extends HttpSchema> extends Pick<FetchOption
|
|
|
588
474
|
) => error is FetchResponseError<Schema, Method, Path>;
|
|
589
475
|
}
|
|
590
476
|
|
|
477
|
+
export namespace Fetch {
|
|
478
|
+
/** A loosely-typed version of {@link Fetch `fetch`}. This can be useful to make requests with fewer type constraints, */
|
|
479
|
+
export type Loose = (
|
|
480
|
+
input: string | URL | FetchRequest.Loose,
|
|
481
|
+
init?: FetchRequestInit.Loose,
|
|
482
|
+
) => Promise<FetchResponse.Loose>;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* The options to create a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
487
|
+
*
|
|
488
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#createfetch `createFetch(options)` API reference}
|
|
489
|
+
*/
|
|
490
|
+
export interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults, 'method'> {
|
|
491
|
+
/**
|
|
492
|
+
* A listener function that is called for each request. It can modify the requests before they are sent.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* import { createFetch } from '@zimic/fetch';
|
|
496
|
+
* import { type HttpSchema } from '@zimic/http';
|
|
497
|
+
*
|
|
498
|
+
* interface User {
|
|
499
|
+
* id: string;
|
|
500
|
+
* username: string;
|
|
501
|
+
* }
|
|
502
|
+
*
|
|
503
|
+
* type Schema = HttpSchema<{
|
|
504
|
+
* '/users': {
|
|
505
|
+
* GET: {
|
|
506
|
+
* request: {
|
|
507
|
+
* searchParams: { page?: number; limit?: number };
|
|
508
|
+
* };
|
|
509
|
+
* response: {
|
|
510
|
+
* 200: { body: User[] };
|
|
511
|
+
* };
|
|
512
|
+
* };
|
|
513
|
+
* };
|
|
514
|
+
* }>;
|
|
515
|
+
*
|
|
516
|
+
* const fetch = createFetch<Schema>({
|
|
517
|
+
* baseURL: 'http://localhost:80',
|
|
518
|
+
*
|
|
519
|
+
* onRequest(request) {
|
|
520
|
+
* if (this.isRequest(request, 'GET', '/users')) {
|
|
521
|
+
* const url = new URL(request.url);
|
|
522
|
+
* url.searchParams.append('limit', '10');
|
|
523
|
+
*
|
|
524
|
+
* const updatedRequest = new Request(url, request);
|
|
525
|
+
* return updatedRequest;
|
|
526
|
+
* }
|
|
527
|
+
*
|
|
528
|
+
* return request;
|
|
529
|
+
* },
|
|
530
|
+
* });
|
|
531
|
+
*
|
|
532
|
+
* @param request The original request.
|
|
533
|
+
* @returns The request to be sent. It can be the original request or a modified version of it.
|
|
534
|
+
* @this {Fetch<Schema>} The fetch instance that is sending the request.
|
|
535
|
+
*/
|
|
536
|
+
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* A listener function that is called after each response is received. It can modify the responses before they are
|
|
540
|
+
* returned to the fetch caller.
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* import { type HttpSchema } from '@zimic/http';
|
|
544
|
+
* import { createFetch } from '@zimic/fetch';
|
|
545
|
+
*
|
|
546
|
+
* interface User {
|
|
547
|
+
* id: string;
|
|
548
|
+
* username: string;
|
|
549
|
+
* }
|
|
550
|
+
*
|
|
551
|
+
* type Schema = HttpSchema<{
|
|
552
|
+
* '/users': {
|
|
553
|
+
* GET: {
|
|
554
|
+
* response: {
|
|
555
|
+
* 200: {
|
|
556
|
+
* headers: { 'content-encoding'?: string };
|
|
557
|
+
* body: User[];
|
|
558
|
+
* };
|
|
559
|
+
* };
|
|
560
|
+
* };
|
|
561
|
+
* };
|
|
562
|
+
* }>;
|
|
563
|
+
*
|
|
564
|
+
* const fetch = createFetch<Schema>({
|
|
565
|
+
* baseURL: 'http://localhost:80',
|
|
566
|
+
*
|
|
567
|
+
* onResponse(response) {
|
|
568
|
+
* if (this.isResponse(response, 'GET', '/users')) {
|
|
569
|
+
* console.log(response.headers.get('content-encoding'));
|
|
570
|
+
* }
|
|
571
|
+
* return response;
|
|
572
|
+
* },
|
|
573
|
+
* });
|
|
574
|
+
*
|
|
575
|
+
* @param response The original response.
|
|
576
|
+
* @returns The response to be returned.
|
|
577
|
+
* @this {Fetch<Schema>} The fetch instance that received the response.
|
|
578
|
+
*/
|
|
579
|
+
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* The default options for each request sent by the fetch instance.
|
|
584
|
+
*
|
|
585
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchdefaults `fetch.defaults` API reference}
|
|
586
|
+
*/
|
|
587
|
+
export type FetchDefaults = RequiredByKey<FetchRequestInit.Defaults, 'headers' | 'searchParams'>;
|
|
588
|
+
|
|
591
589
|
/**
|
|
592
590
|
* Infers the schema of a {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetch fetch instance}.
|
|
593
591
|
*
|
|
@@ -245,6 +245,12 @@ export type FetchRequestObject = Pick<
|
|
|
245
245
|
body?: string | null;
|
|
246
246
|
};
|
|
247
247
|
|
|
248
|
+
/**
|
|
249
|
+
* A {@link FetchResponse `FetchResponse`} instance with a specific status code.
|
|
250
|
+
*
|
|
251
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐fetch#fetchresponse `FetchResponse` API reference}
|
|
252
|
+
* @see {@link https://developer.mozilla.org/docs/Web/API/Response}
|
|
253
|
+
*/
|
|
248
254
|
export interface FetchResponsePerStatusCode<
|
|
249
255
|
Schema extends HttpSchema,
|
|
250
256
|
Method extends HttpSchemaMethod<Schema>,
|