@internetarchive/fetch-handler 1.1.0-webdev-7731.9 → 1.1.0-webdev-7731.11
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 +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/fetch-handler-interface.d.ts +7 -26
- package/dist/src/fetch-handler-interface.js.map +1 -1
- package/dist/src/fetch-handler.d.ts +24 -40
- package/dist/src/fetch-handler.js +26 -25
- package/dist/src/fetch-handler.js.map +1 -1
- package/dist/src/fetch-options.d.ts +13 -0
- package/dist/src/fetch-options.js.map +1 -1
- package/dist/src/fetch-retry/fetch-retrier.js +1 -1
- package/dist/src/fetch-retry/fetch-retrier.js.map +1 -1
- package/dist/test/fetch-handler.test.js +21 -2
- package/dist/test/fetch-handler.test.js.map +1 -1
- package/index.ts +6 -2
- package/package.json +1 -1
- package/src/fetch-handler-interface.ts +7 -35
- package/src/fetch-handler.ts +53 -63
- package/src/fetch-options.ts +14 -0
- package/src/fetch-retry/fetch-retrier.ts +3 -4
- package/test/fetch-handler.test.ts +27 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
1
|
+
export { FetchHandler, IaFetchHandler, type FetchHandlerConstructorOptions, } from './src/fetch-handler';
|
|
2
2
|
export type { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
-
export type { FetchOptions } from './src/fetch-options';
|
|
3
|
+
export type { ApiFetchOptions, FetchOptions } from './src/fetch-options';
|
|
4
4
|
export type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';
|
|
5
5
|
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
6
6
|
export { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { FetchHandler, IaFetchHandler } from './src/fetch-handler';
|
|
1
|
+
export { FetchHandler, IaFetchHandler, } from './src/fetch-handler';
|
|
2
2
|
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
|
3
3
|
export { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';
|
|
4
4
|
export { NoRetryConfiguration } from './src/fetch-retry/configuration/no-retry-configuration';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6DAA6D,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,wDAAwD,CAAC;AAE9F,OAAO,EACL,YAAY,GAEb,MAAM,iCAAiC,CAAC","sourcesContent":["export {\n FetchHandler,\n IaFetchHandler,\n type FetchHandlerConstructorOptions,\n} from './src/fetch-handler';\nexport type { FetchHandlerInterface } from './src/fetch-handler-interface';\nexport type { ApiFetchOptions, FetchOptions } from './src/fetch-options';\nexport type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';\n\nexport { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';\nexport { DefaultRetryConfiguration } from './src/fetch-retry/configuration/default-retry-configuration';\nexport { NoRetryConfiguration } from './src/fetch-retry/configuration/no-retry-configuration';\nexport type { RetryConfiguring } from './src/fetch-retry/configuration/retry-configuring';\nexport {\n FetchRetrier,\n FetchRetrierInterface,\n} from './src/fetch-retry/fetch-retrier';\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FetchOptions } from './fetch-options';
|
|
2
|
-
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
1
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
3
2
|
export interface FetchHandlerInterface {
|
|
4
3
|
/**
|
|
5
4
|
* Generic fetch function that handles retries and common IA parameters like `reCache=1`
|
|
@@ -12,15 +11,9 @@ export interface FetchHandlerInterface {
|
|
|
12
11
|
* A helper function to fetch a response from an API and get a JSON object
|
|
13
12
|
*
|
|
14
13
|
* @param path string
|
|
15
|
-
* @param options?:
|
|
14
|
+
* @param options?: ApiFetchOptions
|
|
16
15
|
*/
|
|
17
|
-
fetchApiResponse<T>(url: string, options?:
|
|
18
|
-
includeCredentials?: boolean;
|
|
19
|
-
method?: string;
|
|
20
|
-
body?: BodyInit;
|
|
21
|
-
headers?: HeadersInit;
|
|
22
|
-
retryConfig?: RetryConfiguring;
|
|
23
|
-
}): Promise<T>;
|
|
16
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
24
17
|
/**
|
|
25
18
|
* A helper function to fetch a response from the IA API and get a JSON object
|
|
26
19
|
*
|
|
@@ -30,27 +23,15 @@ export interface FetchHandlerInterface {
|
|
|
30
23
|
* ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`
|
|
31
24
|
*
|
|
32
25
|
* @param path - Path to API endpoint
|
|
33
|
-
* @param options -
|
|
26
|
+
* @param options - ApiFetchOptions
|
|
34
27
|
*/
|
|
35
|
-
fetchApiPathResponse<T>(path: string, options?:
|
|
36
|
-
includeCredentials?: boolean;
|
|
37
|
-
method?: string;
|
|
38
|
-
body?: BodyInit;
|
|
39
|
-
headers?: HeadersInit;
|
|
40
|
-
retryConfig?: RetryConfiguring;
|
|
41
|
-
}): Promise<T>;
|
|
28
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
42
29
|
/**
|
|
43
30
|
* Fetch a response from the IA API by path
|
|
44
31
|
*
|
|
45
32
|
* @deprecated Use `fetchApiPathResponse` instead.
|
|
46
33
|
* @param path - Path to API endpoint
|
|
47
|
-
* @param options -
|
|
34
|
+
* @param options - ApiFetchOptions
|
|
48
35
|
*/
|
|
49
|
-
fetchIAApiResponse<T>(path: string, options?:
|
|
50
|
-
includeCredentials?: boolean;
|
|
51
|
-
method?: string;
|
|
52
|
-
body?: BodyInit;
|
|
53
|
-
headers?: HeadersInit;
|
|
54
|
-
retryConfig?: RetryConfiguring;
|
|
55
|
-
}): Promise<T>;
|
|
36
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
56
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler-interface.js","sourceRoot":"","sources":["../../src/fetch-handler-interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { FetchOptions } from './fetch-options';\
|
|
1
|
+
{"version":3,"file":"fetch-handler-interface.js","sourceRoot":"","sources":["../../src/fetch-handler-interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { ApiFetchOptions, FetchOptions } from './fetch-options';\n\nexport interface FetchHandlerInterface {\n /**\n * Generic fetch function that handles retries and common IA parameters like `reCache=1`\n *\n * @param input RequestInfo\n * @param options RequestInit | FetchOptions\n */\n fetch(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response>;\n\n /**\n * A helper function to fetch a response from an API and get a JSON object\n *\n * @param path string\n * @param options?: ApiFetchOptions\n */\n fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;\n\n /**\n * A helper function to fetch a response from the IA API and get a JSON object\n *\n * This allows you to just pass the path to the API and get the response instead\n * of the full URL. If you need a full URL, use `fetchApiResponse` instead.\n *\n * ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`\n *\n * @param path - Path to API endpoint\n * @param options - ApiFetchOptions\n */\n fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;\n\n /**\n * Fetch a response from the IA API by path\n *\n * @deprecated Use `fetchApiPathResponse` instead.\n * @param path - Path to API endpoint\n * @param options - ApiFetchOptions\n */\n fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;\n}\n"]}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { FetchRetrierInterface } from './fetch-retry/fetch-retrier';
|
|
2
2
|
import type { FetchHandlerInterface } from './fetch-handler-interface';
|
|
3
|
-
import type { FetchOptions } from './fetch-options';
|
|
4
|
-
|
|
3
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
4
|
+
export type FetchHandlerConstructorOptions = {
|
|
5
|
+
/** @deprecated Use `apiBaseUrl` instead. */
|
|
6
|
+
iaApiBaseUrl?: string;
|
|
7
|
+
apiBaseUrl?: string;
|
|
8
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
9
|
+
searchParams?: string;
|
|
10
|
+
};
|
|
5
11
|
/**
|
|
6
12
|
* The FetchHandler adds some common helpers:
|
|
7
13
|
* - retry the request if it fails
|
|
@@ -12,49 +18,21 @@ export declare class FetchHandler implements FetchHandlerInterface {
|
|
|
12
18
|
private apiBaseUrl;
|
|
13
19
|
private fetchRetrier;
|
|
14
20
|
private searchParams?;
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
* @param options {
|
|
18
|
-
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
19
|
-
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
20
|
-
* fetchRetrier - FetchRetrier to use instead of the default
|
|
21
|
-
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
22
|
-
*/
|
|
23
|
-
constructor(options?: {
|
|
24
|
-
iaApiBaseUrl?: string;
|
|
25
|
-
apiBaseUrl?: string;
|
|
26
|
-
fetchRetrier?: FetchRetrierInterface;
|
|
27
|
-
searchParams?: string;
|
|
28
|
-
});
|
|
21
|
+
constructor(options?: FetchHandlerConstructorOptions);
|
|
29
22
|
/** @inheritdoc */
|
|
30
|
-
|
|
31
|
-
includeCredentials?: boolean;
|
|
32
|
-
method?: string;
|
|
33
|
-
body?: BodyInit;
|
|
34
|
-
headers?: HeadersInit;
|
|
35
|
-
retryConfig?: RetryConfiguring;
|
|
36
|
-
}): Promise<T>;
|
|
23
|
+
fetch(request: RequestInfo, options?: RequestInit | FetchOptions): Promise<Response>;
|
|
37
24
|
/** @inheritdoc */
|
|
38
|
-
|
|
39
|
-
includeCredentials?: boolean;
|
|
40
|
-
method?: string;
|
|
41
|
-
body?: BodyInit;
|
|
42
|
-
headers?: HeadersInit;
|
|
43
|
-
retryConfig?: RetryConfiguring;
|
|
44
|
-
}): Promise<T>;
|
|
25
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
45
26
|
/** @inheritdoc */
|
|
46
|
-
|
|
47
|
-
includeCredentials?: boolean;
|
|
48
|
-
method?: string;
|
|
49
|
-
body?: BodyInit;
|
|
50
|
-
headers?: HeadersInit;
|
|
51
|
-
retryConfig?: RetryConfiguring;
|
|
52
|
-
}): Promise<T>;
|
|
27
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
53
28
|
/** @inheritdoc */
|
|
54
|
-
|
|
29
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
55
30
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
31
|
+
* Construct a new URL with the given search params added
|
|
32
|
+
*
|
|
33
|
+
* @param urlString - Original URL string
|
|
34
|
+
* @param params - Params to add
|
|
35
|
+
* @returns New URL string with params added
|
|
58
36
|
*/
|
|
59
37
|
private addSearchParams;
|
|
60
38
|
}
|
|
@@ -64,4 +42,10 @@ export declare class FetchHandler implements FetchHandlerInterface {
|
|
|
64
42
|
* @deprecated Use `FetchHandler` instead.
|
|
65
43
|
*/
|
|
66
44
|
export declare class IaFetchHandler extends FetchHandler {
|
|
45
|
+
constructor(options?: {
|
|
46
|
+
iaApiBaseUrl?: string;
|
|
47
|
+
apiBaseUrl?: string;
|
|
48
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
49
|
+
searchParams?: string;
|
|
50
|
+
});
|
|
67
51
|
}
|
|
@@ -6,14 +6,6 @@ import { FetchRetrier, } from './fetch-retry/fetch-retrier';
|
|
|
6
6
|
* - add convenience method for fetching/decoding an API response by just the path
|
|
7
7
|
*/
|
|
8
8
|
export class FetchHandler {
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param options {
|
|
12
|
-
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
13
|
-
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
14
|
-
* fetchRetrier - FetchRetrier to use instead of the default
|
|
15
|
-
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
16
|
-
*/
|
|
17
9
|
constructor(options) {
|
|
18
10
|
this.apiBaseUrl = '';
|
|
19
11
|
this.fetchRetrier = new FetchRetrier();
|
|
@@ -33,13 +25,14 @@ export class FetchHandler {
|
|
|
33
25
|
}
|
|
34
26
|
}
|
|
35
27
|
/** @inheritdoc */
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
async fetch(request, options) {
|
|
29
|
+
let finalRequest = request;
|
|
30
|
+
const urlParams = new URLSearchParams(this.searchParams);
|
|
31
|
+
if (urlParams.get('reCache') === '1') {
|
|
32
|
+
const urlString = typeof request === 'string' ? request : request.url;
|
|
33
|
+
finalRequest = this.addSearchParams(urlString, { reCache: '1' });
|
|
34
|
+
}
|
|
35
|
+
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
43
36
|
}
|
|
44
37
|
/** @inheritdoc */
|
|
45
38
|
async fetchApiResponse(url, options) {
|
|
@@ -60,18 +53,20 @@ export class FetchHandler {
|
|
|
60
53
|
return json;
|
|
61
54
|
}
|
|
62
55
|
/** @inheritdoc */
|
|
63
|
-
async
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
56
|
+
async fetchApiPathResponse(path, options) {
|
|
57
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
58
|
+
return this.fetchApiResponse(url, options);
|
|
59
|
+
}
|
|
60
|
+
/** @inheritdoc */
|
|
61
|
+
async fetchIAApiResponse(path, options) {
|
|
62
|
+
return this.fetchApiPathResponse(path, options);
|
|
71
63
|
}
|
|
72
64
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
65
|
+
* Construct a new URL with the given search params added
|
|
66
|
+
*
|
|
67
|
+
* @param urlString - Original URL string
|
|
68
|
+
* @param params - Params to add
|
|
69
|
+
* @returns New URL string with params added
|
|
75
70
|
*/
|
|
76
71
|
addSearchParams(urlString, params) {
|
|
77
72
|
const url = new URL(urlString, window.location.href);
|
|
@@ -87,5 +82,11 @@ export class FetchHandler {
|
|
|
87
82
|
* @deprecated Use `FetchHandler` instead.
|
|
88
83
|
*/
|
|
89
84
|
export class IaFetchHandler extends FetchHandler {
|
|
85
|
+
constructor(options) {
|
|
86
|
+
var _a;
|
|
87
|
+
const superOptions = { ...options };
|
|
88
|
+
superOptions.iaApiBaseUrl = (_a = options === null || options === void 0 ? void 0 : options.iaApiBaseUrl) !== null && _a !== void 0 ? _a : 'https://archive.org';
|
|
89
|
+
super(superOptions);
|
|
90
|
+
}
|
|
90
91
|
}
|
|
91
92
|
//# sourceMappingURL=fetch-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.js","sourceRoot":"","sources":["../../src/fetch-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAEb,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-handler.js","sourceRoot":"","sources":["../../src/fetch-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n FetchRetrier,\n FetchRetrierInterface,\n} from './fetch-retry/fetch-retrier';\nimport type { FetchHandlerInterface } from './fetch-handler-interface';\nimport type { ApiFetchOptions, FetchOptions } from './fetch-options';\n\nexport type FetchHandlerConstructorOptions = {\n /** @deprecated Use `apiBaseUrl` instead. */\n iaApiBaseUrl?: string;\n apiBaseUrl?: string;\n fetchRetrier?: FetchRetrierInterface;\n searchParams?: string;\n};\n\n/**\n * The FetchHandler adds some common helpers:\n * - retry the request if it fails\n * - add `reCache=1` to the request if it's in the current url so the backend sees it\n * - add convenience method for fetching/decoding an API response by just the path\n */\nexport class FetchHandler implements FetchHandlerInterface {\n private apiBaseUrl: string = '';\n\n private fetchRetrier: FetchRetrierInterface = new FetchRetrier();\n\n private searchParams?: string;\n\n constructor(options?: FetchHandlerConstructorOptions) {\n if (options?.apiBaseUrl) {\n this.apiBaseUrl = options.apiBaseUrl;\n } else if (options?.iaApiBaseUrl) {\n this.apiBaseUrl = options.iaApiBaseUrl;\n }\n if (options?.fetchRetrier) this.fetchRetrier = options.fetchRetrier;\n if (options?.searchParams) {\n this.searchParams = options.searchParams;\n } else {\n this.searchParams = window.location.search;\n }\n }\n\n /** @inheritdoc */\n async fetch(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response> {\n let finalRequest = request;\n const urlParams = new URLSearchParams(this.searchParams);\n if (urlParams.get('reCache') === '1') {\n const urlString = typeof request === 'string' ? request : request.url;\n finalRequest = this.addSearchParams(urlString, { reCache: '1' });\n }\n return this.fetchRetrier.fetchRetry(finalRequest, options);\n }\n\n /** @inheritdoc */\n async fetchApiResponse<T>(\n url: string,\n options?: ApiFetchOptions,\n ): Promise<T> {\n const requestInit: RequestInit = {};\n if (options?.includeCredentials) requestInit.credentials = 'include';\n if (options?.method) requestInit.method = options.method;\n if (options?.body) requestInit.body = options.body;\n if (options?.headers) requestInit.headers = options.headers;\n const response = await this.fetch(url, {\n requestInit: requestInit,\n retryConfig: options?.retryConfig,\n });\n const json = await response.json();\n return json as T;\n }\n\n /** @inheritdoc */\n async fetchApiPathResponse<T>(\n path: string,\n options?: ApiFetchOptions,\n ): Promise<T> {\n const url = `${this.apiBaseUrl}${path}`;\n return this.fetchApiResponse(url, options);\n }\n\n /** @inheritdoc */\n async fetchIAApiResponse<T>(\n path: string,\n options?: ApiFetchOptions,\n ): Promise<T> {\n return this.fetchApiPathResponse(path, options);\n }\n\n /**\n * Construct a new URL with the given search params added\n *\n * @param urlString - Original URL string\n * @param params - Params to add\n * @returns New URL string with params added\n */\n private addSearchParams(\n urlString: string,\n params: Record<string, string>,\n ): string {\n const url = new URL(urlString, window.location.href);\n\n for (const [key, value] of Object.entries(params)) {\n url.searchParams.set(key, value);\n }\n\n return url.href;\n }\n}\n\n/**\n * Backwards compatibility class\n *\n * @deprecated Use `FetchHandler` instead.\n */\nexport class IaFetchHandler extends FetchHandler {\n constructor(options?: {\n iaApiBaseUrl?: string;\n apiBaseUrl?: string;\n fetchRetrier?: FetchRetrierInterface;\n searchParams?: string;\n }) {\n const superOptions = { ...options };\n superOptions.iaApiBaseUrl = options?.iaApiBaseUrl ?? 'https://archive.org';\n super(superOptions);\n }\n}\n"]}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
2
|
+
/**
|
|
3
|
+
* Base fetch options for FetchHandler
|
|
4
|
+
*/
|
|
2
5
|
export type FetchOptions = {
|
|
3
6
|
requestInit?: RequestInit;
|
|
4
7
|
retryConfig?: RetryConfiguring;
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* A convenience type for FetchHandler methods with common API fetch options.
|
|
11
|
+
*/
|
|
12
|
+
export type ApiFetchOptions = {
|
|
13
|
+
includeCredentials?: boolean;
|
|
14
|
+
method?: string;
|
|
15
|
+
body?: BodyInit;
|
|
16
|
+
headers?: HeadersInit;
|
|
17
|
+
retryConfig?: RetryConfiguring;
|
|
18
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-options.js","sourceRoot":"","sources":["../../src/fetch-options.ts"],"names":[],"mappings":"","sourcesContent":["import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\nexport type FetchOptions = {\n requestInit?: RequestInit;\n retryConfig?: RetryConfiguring;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"fetch-options.js","sourceRoot":"","sources":["../../src/fetch-options.ts"],"names":[],"mappings":"","sourcesContent":["import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';\n\n/**\n * Base fetch options for FetchHandler\n */\nexport type FetchOptions = {\n requestInit?: RequestInit;\n retryConfig?: RetryConfiguring;\n};\n\n/**\n * A convenience type for FetchHandler methods with common API fetch options.\n */\nexport type ApiFetchOptions = {\n includeCredentials?: boolean;\n method?: string;\n body?: BodyInit;\n headers?: HeadersInit;\n retryConfig?: RetryConfiguring;\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promisedSleep } from '../utils/promised-sleep';
|
|
2
|
-
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
3
2
|
import { FetchRetryConfig } from './configuration/configurations';
|
|
3
|
+
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
4
4
|
/** @inheritdoc */
|
|
5
5
|
export class FetchRetrier {
|
|
6
6
|
constructor(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-retrier.js","sourceRoot":"","sources":["../../../src/fetch-retry/fetch-retrier.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-retrier.js","sourceRoot":"","sources":["../../../src/fetch-retry/fetch-retrier.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnalyticsHandlerInterface } from '@internetarchive/analytics-manager';\nimport { type FetchOptions } from '../fetch-options';\nimport { promisedSleep } from '../utils/promised-sleep';\nimport { FetchRetryConfig } from './configuration/configurations';\nimport type { RetryConfiguring } from './configuration/retry-configuring';\nimport { legacyArgsAsFetchOptions } from './legacy-args';\n\n/**\n * A class that retries a fetch request.\n */\nexport interface FetchRetrierInterface {\n /**\n * Execute a fetch with retry.\n *\n * @param request RequestInfo\n * @param options Optional RequestInit | FetchOptions\n * @returns Promise<Response>\n */\n fetchRetry(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response>;\n}\n\n/** @inheritdoc */\nexport class FetchRetrier implements FetchRetrierInterface {\n private analyticsHandler?: AnalyticsHandlerInterface;\n\n private retryConfig: RetryConfiguring = FetchRetryConfig.default;\n\n constructor(options?: {\n analyticsHandler?: AnalyticsHandlerInterface;\n retryConfig?: RetryConfiguring;\n }) {\n if (options?.analyticsHandler)\n this.analyticsHandler = options.analyticsHandler;\n if (options?.retryConfig) this.retryConfig = options.retryConfig;\n }\n\n /** @inheritdoc */\n public async fetchRetry(\n request: RequestInfo,\n options?: RequestInit | FetchOptions,\n ): Promise<Response> {\n const fetchOptions = legacyArgsAsFetchOptions(options);\n return await this.doFetchRetry(request, 0, fetchOptions);\n }\n\n private async doFetchRetry(\n request: RequestInfo,\n retryNumber: number,\n options?: FetchOptions,\n ): Promise<Response> {\n const urlString = typeof request === 'string' ? request : request.url;\n\n try {\n const response = await fetch(request, options?.requestInit);\n if (response.ok) return response;\n\n if (response.status >= 400 && response.status < 600) {\n this.log4xx5xxResponse(response);\n }\n\n const retryConfig = options?.retryConfig ?? this.retryConfig;\n const shouldRetry = retryConfig.shouldRetry(response, retryNumber);\n if (shouldRetry) {\n const retryDelay = retryConfig.retryDelay(retryNumber, response);\n if (retryDelay !== null) {\n await promisedSleep(retryDelay);\n this.logRetryEvent(\n urlString,\n retryNumber,\n response.statusText,\n response.status,\n );\n return this.doFetchRetry(request, retryNumber + 1, options);\n }\n }\n this.logFailureEvent(urlString, response.status);\n return response;\n } catch (error) {\n // if a content blocker is detected, log it and don't retry\n if (this.isContentBlockerError(error)) {\n this.logContentBlockingEvent(urlString, error);\n throw error;\n }\n\n const retryConfig = options?.retryConfig ?? this.retryConfig;\n const shouldRetry = retryConfig.shouldRetry(null, retryNumber);\n if (shouldRetry) {\n const retryDelay = retryConfig.retryDelay(retryNumber);\n if (retryDelay !== null) {\n await promisedSleep(retryDelay);\n this.logRetryEvent(urlString, retryNumber, error, error);\n return this.doFetchRetry(request, retryNumber + 1, options);\n }\n }\n this.logFailureEvent(urlString, error);\n throw error;\n }\n }\n\n private isContentBlockerError(error: unknown): boolean {\n // all of the content blocker errors are `TypeError`\n if (!(error instanceof TypeError)) return false;\n const message = error.message.toLowerCase();\n return message.includes('content blocker');\n }\n\n private readonly eventCategory = 'offshootFetchRetry';\n\n private logRetryEvent(\n urlString: string,\n retryNumber: number,\n status: unknown,\n code: unknown,\n ) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'retryingFetch',\n label: `retryNumber: ${retryNumber}, code: ${code}, status: ${status}, url: ${urlString}`,\n });\n }\n\n private logFailureEvent(urlString: string, error: unknown) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'fetchFailed',\n label: `error: ${error}, url: ${urlString}`,\n });\n }\n\n private log4xx5xxResponse(response: Response) {\n const status = response.status;\n\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: `status${status}Response`,\n label: `url: ${response.url}`,\n });\n }\n\n private logContentBlockingEvent(urlString: string, error: unknown) {\n this.analyticsHandler?.sendEvent({\n category: this.eventCategory,\n action: 'contentBlockerDetectedNotRetrying',\n label: `error: ${error}, url: ${urlString}`,\n });\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { FetchHandler } from '../src/fetch-handler';
|
|
2
|
+
import { FetchHandler, IaFetchHandler } from '../src/fetch-handler';
|
|
3
3
|
import { MockFetchRetrier } from './mocks/mock-fetch-retrier';
|
|
4
4
|
import { NoRetryConfiguration } from '../src/fetch-retry/configuration/no-retry-configuration';
|
|
5
5
|
describe('Fetch Handler', () => {
|
|
@@ -125,7 +125,26 @@ describe('Fetch Handler', () => {
|
|
|
125
125
|
it('is an alias for fetchApiPathResponse', async () => {
|
|
126
126
|
const endpoint = '/foo/service/endpoint.php';
|
|
127
127
|
const fetchRetrier = new MockFetchRetrier();
|
|
128
|
-
const fetchHandler = new
|
|
128
|
+
const fetchHandler = new IaFetchHandler({
|
|
129
|
+
iaApiBaseUrl: 'www.example.com',
|
|
130
|
+
fetchRetrier: fetchRetrier,
|
|
131
|
+
});
|
|
132
|
+
await fetchHandler.fetchIAApiResponse(endpoint);
|
|
133
|
+
expect(fetchRetrier.requestInfo).to.equal('www.example.com/foo/service/endpoint.php');
|
|
134
|
+
});
|
|
135
|
+
it('defaults the baseUrl to https://archive.org', async () => {
|
|
136
|
+
const endpoint = '/foo/service/endpoint.php';
|
|
137
|
+
const fetchRetrier = new MockFetchRetrier();
|
|
138
|
+
const fetchHandler = new IaFetchHandler({
|
|
139
|
+
fetchRetrier: fetchRetrier,
|
|
140
|
+
});
|
|
141
|
+
await fetchHandler.fetchIAApiResponse(endpoint);
|
|
142
|
+
expect(fetchRetrier.requestInfo).to.equal('https://archive.org/foo/service/endpoint.php');
|
|
143
|
+
});
|
|
144
|
+
it('passes iaApiBaseUrl if provided', async () => {
|
|
145
|
+
const endpoint = '/foo/service/endpoint.php';
|
|
146
|
+
const fetchRetrier = new MockFetchRetrier();
|
|
147
|
+
const fetchHandler = new IaFetchHandler({
|
|
129
148
|
iaApiBaseUrl: 'www.example.com',
|
|
130
149
|
fetchRetrier: fetchRetrier,
|
|
131
150
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.test.js","sourceRoot":"","sources":["../../test/fetch-handler.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yDAAyD,CAAC;AAE/F,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;YACxC,uDAAuD;YACvD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY,EAAE,qBAAqB;aACpC,CAAC,CAAC;YACH,uDAAuD;YACvD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,UAAU,EAAE,yBAAyB;aACtC,CAAC,CAAC;YACH,uDAAuD;YACvD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY,EAAE,qBAAqB;gBACnC,UAAU,EAAE,yBAAyB;aACtC,CAAC,CAAC;YACH,uDAAuD;YACvD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY,EAAE,YAAY;gBAC1B,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YACzD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CACvC,wCAAwC,CACzC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY;gBACZ,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,8BAA8B,CAAC,CAAC;YACxD,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CACvC,wCAAwC,CACzC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY;gBACZ,YAAY,EAAE,UAAU;aACzB,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YACzD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,QAAQ,GAAG,2BAA2B,CAAC;YAC7C,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,UAAU,EAAE,iBAAiB;gBAC7B,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CACvC,0CAA0C,CAC3C,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,QAAQ,GAAG,2BAA2B,CAAC;YAC7C,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YAClD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,QAAQ,GAAG,2BAA2B,CAAC;YAC7C,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,UAAU,EAAE,iBAAiB;gBAC7B,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE;gBAC5C,kBAAkB,EAAE,IAAI;aACzB,CAAC,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAChD,MAAM,YAAY,CAAC,gBAAgB,CAAC,yBAAyB,EAAE;gBAC7D,MAAM,EAAE,MAAM;gBACd,IAAI;gBACJ,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAC/D,CAAC,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBACtC,MAAM,EAAE,MAAM;gBACd,IAAI;gBACJ,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAC/D,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,WAAW,GAAG,IAAI,oBAAoB,EAAE,CAAC;YAC/C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YACxD,MAAM,YAAY,CAAC,gBAAgB,CAAC,yBAAyB,EAAE;gBAC7D,WAAW;aACZ,CAAC,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,QAAQ,GAAG,2BAA2B,CAAC;YAC7C,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;gBACpC,YAAY,EAAE,iBAAiB;gBAC/B,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CACvC,0CAA0C,CAC3C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { FetchHandler } from '../src/fetch-handler';\nimport { MockFetchRetrier } from './mocks/mock-fetch-retrier';\nimport { NoRetryConfiguration } from '../src/fetch-retry/configuration/no-retry-configuration';\n\ndescribe('Fetch Handler', () => {\n describe('constructor', () => {\n it('has no default apiBaseUrl', () => {\n const fetchHandler = new FetchHandler();\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('');\n });\n\n it('sets iaApiBaseUrl if provided', () => {\n const fetchHandler = new FetchHandler({\n iaApiBaseUrl: 'https://example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://example.org');\n });\n\n it('sets apiBaseUrl if provided', () => {\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'https://api.example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://api.example.org');\n });\n\n it('uses apiBaseUrl over iaApiBaseUrl if both provided', () => {\n const fetchHandler = new FetchHandler({\n iaApiBaseUrl: 'https://example.org',\n apiBaseUrl: 'https://api.example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://api.example.org');\n });\n });\n\n describe('fetch', () => {\n it('adds reCache=1 if it is in the current url', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier: fetchRetrier,\n searchParams: '?reCache=1',\n });\n await fetchHandler.fetch('https://foo.org/api/v1/snoot');\n expect(fetchRetrier.requestInfo).to.equal(\n 'https://foo.org/api/v1/snoot?reCache=1',\n );\n });\n\n it('appends reCache=1 when request is a Request object', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier,\n searchParams: '?reCache=1',\n });\n const req = new Request('https://foo.org/api/v1/snoot');\n await fetchHandler.fetch(req);\n expect(fetchRetrier.requestInfo).to.equal(\n 'https://foo.org/api/v1/snoot?reCache=1',\n );\n });\n\n it('does not append reCache when not present', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier,\n searchParams: '?foo=bar',\n });\n await fetchHandler.fetch('https://foo.org/api/v1/snoot');\n expect(fetchRetrier.requestInfo).to.equal('https://foo.org/api/v1/snoot');\n });\n });\n\n describe('fetchApiPathResponse', () => {\n it('prepends the IA basehost to the url when making a request', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiPathResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'www.example.com/foo/service/endpoint.php',\n );\n });\n\n it('defaults to no apiBaseUrl', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiPathResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal('/foo/service/endpoint.php');\n });\n });\n\n describe('fetchApiResponse', () => {\n it('adds credentials: include if requested', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiResponse(endpoint, {\n includeCredentials: true,\n });\n expect(fetchRetrier.init).to.deep.equal({ credentials: 'include' });\n });\n\n it('passes method, body, and headers to RequestInit', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({ fetchRetrier });\n const body = JSON.stringify({ hello: 'world' });\n await fetchHandler.fetchApiResponse('https://example.org/api', {\n method: 'POST',\n body,\n headers: { 'x-test': '1', 'content-type': 'application/json' },\n });\n expect(fetchRetrier.init).to.deep.equal({\n method: 'POST',\n body,\n headers: { 'x-test': '1', 'content-type': 'application/json' },\n });\n });\n\n it('passes retryConfig through to retrier', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const retryConfig = new NoRetryConfiguration();\n const fetchHandler = new FetchHandler({ fetchRetrier });\n await fetchHandler.fetchApiResponse('https://example.org/api', {\n retryConfig,\n });\n expect(fetchRetrier.retryConfig).to.equal(retryConfig);\n });\n });\n\n describe('fetchIAApiResponse', () => {\n it('is an alias for fetchApiPathResponse', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n iaApiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchIAApiResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'www.example.com/foo/service/endpoint.php',\n );\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"fetch-handler.test.js","sourceRoot":"","sources":["../../test/fetch-handler.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { FetchHandler, IaFetchHandler } from '../src/fetch-handler';\nimport { MockFetchRetrier } from './mocks/mock-fetch-retrier';\nimport { NoRetryConfiguration } from '../src/fetch-retry/configuration/no-retry-configuration';\n\ndescribe('Fetch Handler', () => {\n describe('constructor', () => {\n it('has no default apiBaseUrl', () => {\n const fetchHandler = new FetchHandler();\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('');\n });\n\n it('sets iaApiBaseUrl if provided', () => {\n const fetchHandler = new FetchHandler({\n iaApiBaseUrl: 'https://example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://example.org');\n });\n\n it('sets apiBaseUrl if provided', () => {\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'https://api.example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://api.example.org');\n });\n\n it('uses apiBaseUrl over iaApiBaseUrl if both provided', () => {\n const fetchHandler = new FetchHandler({\n iaApiBaseUrl: 'https://example.org',\n apiBaseUrl: 'https://api.example.org',\n });\n // @ts-expect-error Accessing private property for test\n expect(fetchHandler.apiBaseUrl).to.equal('https://api.example.org');\n });\n });\n\n describe('fetch', () => {\n it('adds reCache=1 if it is in the current url', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier: fetchRetrier,\n searchParams: '?reCache=1',\n });\n await fetchHandler.fetch('https://foo.org/api/v1/snoot');\n expect(fetchRetrier.requestInfo).to.equal(\n 'https://foo.org/api/v1/snoot?reCache=1',\n );\n });\n\n it('appends reCache=1 when request is a Request object', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier,\n searchParams: '?reCache=1',\n });\n const req = new Request('https://foo.org/api/v1/snoot');\n await fetchHandler.fetch(req);\n expect(fetchRetrier.requestInfo).to.equal(\n 'https://foo.org/api/v1/snoot?reCache=1',\n );\n });\n\n it('does not append reCache when not present', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier,\n searchParams: '?foo=bar',\n });\n await fetchHandler.fetch('https://foo.org/api/v1/snoot');\n expect(fetchRetrier.requestInfo).to.equal('https://foo.org/api/v1/snoot');\n });\n });\n\n describe('fetchApiPathResponse', () => {\n it('prepends the IA basehost to the url when making a request', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiPathResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'www.example.com/foo/service/endpoint.php',\n );\n });\n\n it('defaults to no apiBaseUrl', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiPathResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal('/foo/service/endpoint.php');\n });\n });\n\n describe('fetchApiResponse', () => {\n it('adds credentials: include if requested', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({\n apiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchApiResponse(endpoint, {\n includeCredentials: true,\n });\n expect(fetchRetrier.init).to.deep.equal({ credentials: 'include' });\n });\n\n it('passes method, body, and headers to RequestInit', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new FetchHandler({ fetchRetrier });\n const body = JSON.stringify({ hello: 'world' });\n await fetchHandler.fetchApiResponse('https://example.org/api', {\n method: 'POST',\n body,\n headers: { 'x-test': '1', 'content-type': 'application/json' },\n });\n expect(fetchRetrier.init).to.deep.equal({\n method: 'POST',\n body,\n headers: { 'x-test': '1', 'content-type': 'application/json' },\n });\n });\n\n it('passes retryConfig through to retrier', async () => {\n const fetchRetrier = new MockFetchRetrier();\n const retryConfig = new NoRetryConfiguration();\n const fetchHandler = new FetchHandler({ fetchRetrier });\n await fetchHandler.fetchApiResponse('https://example.org/api', {\n retryConfig,\n });\n expect(fetchRetrier.retryConfig).to.equal(retryConfig);\n });\n });\n\n describe('fetchIAApiResponse', () => {\n it('is an alias for fetchApiPathResponse', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new IaFetchHandler({\n iaApiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchIAApiResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'www.example.com/foo/service/endpoint.php',\n );\n });\n\n it('defaults the baseUrl to https://archive.org', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new IaFetchHandler({\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchIAApiResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'https://archive.org/foo/service/endpoint.php',\n );\n });\n\n it('passes iaApiBaseUrl if provided', async () => {\n const endpoint = '/foo/service/endpoint.php';\n const fetchRetrier = new MockFetchRetrier();\n const fetchHandler = new IaFetchHandler({\n iaApiBaseUrl: 'www.example.com',\n fetchRetrier: fetchRetrier,\n });\n await fetchHandler.fetchIAApiResponse(endpoint);\n expect(fetchRetrier.requestInfo).to.equal(\n 'www.example.com/foo/service/endpoint.php',\n );\n });\n });\n});\n"]}
|
package/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
FetchHandler,
|
|
3
|
+
IaFetchHandler,
|
|
4
|
+
type FetchHandlerConstructorOptions,
|
|
5
|
+
} from './src/fetch-handler';
|
|
2
6
|
export type { FetchHandlerInterface } from './src/fetch-handler-interface';
|
|
3
|
-
export type { FetchOptions } from './src/fetch-options';
|
|
7
|
+
export type { ApiFetchOptions, FetchOptions } from './src/fetch-options';
|
|
4
8
|
export type { Milliseconds } from './src/fetch-retry/configuration/milliseconds';
|
|
5
9
|
|
|
6
10
|
export { FetchRetryConfig } from './src/fetch-retry/configuration/configurations';
|
package/package.json
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FetchOptions } from './fetch-options';
|
|
2
|
-
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
1
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
3
2
|
|
|
4
3
|
export interface FetchHandlerInterface {
|
|
5
4
|
/**
|
|
@@ -17,18 +16,9 @@ export interface FetchHandlerInterface {
|
|
|
17
16
|
* A helper function to fetch a response from an API and get a JSON object
|
|
18
17
|
*
|
|
19
18
|
* @param path string
|
|
20
|
-
* @param options?:
|
|
19
|
+
* @param options?: ApiFetchOptions
|
|
21
20
|
*/
|
|
22
|
-
fetchApiResponse<T>(
|
|
23
|
-
url: string,
|
|
24
|
-
options?: {
|
|
25
|
-
includeCredentials?: boolean;
|
|
26
|
-
method?: string;
|
|
27
|
-
body?: BodyInit;
|
|
28
|
-
headers?: HeadersInit;
|
|
29
|
-
retryConfig?: RetryConfiguring;
|
|
30
|
-
},
|
|
31
|
-
): Promise<T>;
|
|
21
|
+
fetchApiResponse<T>(url: string, options?: ApiFetchOptions): Promise<T>;
|
|
32
22
|
|
|
33
23
|
/**
|
|
34
24
|
* A helper function to fetch a response from the IA API and get a JSON object
|
|
@@ -39,34 +29,16 @@ export interface FetchHandlerInterface {
|
|
|
39
29
|
* ie `fetchApiPathResponse('/items/123')` will fetch from `${apiBaseUrl}/items/123`
|
|
40
30
|
*
|
|
41
31
|
* @param path - Path to API endpoint
|
|
42
|
-
* @param options -
|
|
32
|
+
* @param options - ApiFetchOptions
|
|
43
33
|
*/
|
|
44
|
-
fetchApiPathResponse<T>(
|
|
45
|
-
path: string,
|
|
46
|
-
options?: {
|
|
47
|
-
includeCredentials?: boolean;
|
|
48
|
-
method?: string;
|
|
49
|
-
body?: BodyInit;
|
|
50
|
-
headers?: HeadersInit;
|
|
51
|
-
retryConfig?: RetryConfiguring;
|
|
52
|
-
},
|
|
53
|
-
): Promise<T>;
|
|
34
|
+
fetchApiPathResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
54
35
|
|
|
55
36
|
/**
|
|
56
37
|
* Fetch a response from the IA API by path
|
|
57
38
|
*
|
|
58
39
|
* @deprecated Use `fetchApiPathResponse` instead.
|
|
59
40
|
* @param path - Path to API endpoint
|
|
60
|
-
* @param options -
|
|
41
|
+
* @param options - ApiFetchOptions
|
|
61
42
|
*/
|
|
62
|
-
fetchIAApiResponse<T>(
|
|
63
|
-
path: string,
|
|
64
|
-
options?: {
|
|
65
|
-
includeCredentials?: boolean;
|
|
66
|
-
method?: string;
|
|
67
|
-
body?: BodyInit;
|
|
68
|
-
headers?: HeadersInit;
|
|
69
|
-
retryConfig?: RetryConfiguring;
|
|
70
|
-
},
|
|
71
|
-
): Promise<T>;
|
|
43
|
+
fetchIAApiResponse<T>(path: string, options?: ApiFetchOptions): Promise<T>;
|
|
72
44
|
}
|
package/src/fetch-handler.ts
CHANGED
|
@@ -3,8 +3,15 @@ import {
|
|
|
3
3
|
FetchRetrierInterface,
|
|
4
4
|
} from './fetch-retry/fetch-retrier';
|
|
5
5
|
import type { FetchHandlerInterface } from './fetch-handler-interface';
|
|
6
|
-
import type { FetchOptions } from './fetch-options';
|
|
7
|
-
|
|
6
|
+
import type { ApiFetchOptions, FetchOptions } from './fetch-options';
|
|
7
|
+
|
|
8
|
+
export type FetchHandlerConstructorOptions = {
|
|
9
|
+
/** @deprecated Use `apiBaseUrl` instead. */
|
|
10
|
+
iaApiBaseUrl?: string;
|
|
11
|
+
apiBaseUrl?: string;
|
|
12
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
13
|
+
searchParams?: string;
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* The FetchHandler adds some common helpers:
|
|
@@ -19,20 +26,7 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
19
26
|
|
|
20
27
|
private searchParams?: string;
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
* @param options {
|
|
25
|
-
* iaApiBaseUrl - deprecated Use `apiBaseUrl` instead.
|
|
26
|
-
* apiBaseUrl - The base URL for API requests for `fetchApiPathResponse`
|
|
27
|
-
* fetchRetrier - FetchRetrier to use instead of the default
|
|
28
|
-
* searchParams - Search params to check for `reCache=1` (defaults to current window location)
|
|
29
|
-
*/
|
|
30
|
-
constructor(options?: {
|
|
31
|
-
iaApiBaseUrl?: string;
|
|
32
|
-
apiBaseUrl?: string;
|
|
33
|
-
fetchRetrier?: FetchRetrierInterface;
|
|
34
|
-
searchParams?: string;
|
|
35
|
-
}) {
|
|
29
|
+
constructor(options?: FetchHandlerConstructorOptions) {
|
|
36
30
|
if (options?.apiBaseUrl) {
|
|
37
31
|
this.apiBaseUrl = options.apiBaseUrl;
|
|
38
32
|
} else if (options?.iaApiBaseUrl) {
|
|
@@ -47,44 +41,23 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
/** @inheritdoc */
|
|
50
|
-
async
|
|
51
|
-
|
|
52
|
-
options?:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return this.fetchApiResponse(url, options);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** @inheritdoc */
|
|
65
|
-
async fetchIAApiResponse<T>(
|
|
66
|
-
path: string,
|
|
67
|
-
options?: {
|
|
68
|
-
includeCredentials?: boolean;
|
|
69
|
-
method?: string;
|
|
70
|
-
body?: BodyInit;
|
|
71
|
-
headers?: HeadersInit;
|
|
72
|
-
retryConfig?: RetryConfiguring;
|
|
73
|
-
},
|
|
74
|
-
): Promise<T> {
|
|
75
|
-
return this.fetchApiPathResponse(path, options);
|
|
44
|
+
async fetch(
|
|
45
|
+
request: RequestInfo,
|
|
46
|
+
options?: RequestInit | FetchOptions,
|
|
47
|
+
): Promise<Response> {
|
|
48
|
+
let finalRequest = request;
|
|
49
|
+
const urlParams = new URLSearchParams(this.searchParams);
|
|
50
|
+
if (urlParams.get('reCache') === '1') {
|
|
51
|
+
const urlString = typeof request === 'string' ? request : request.url;
|
|
52
|
+
finalRequest = this.addSearchParams(urlString, { reCache: '1' });
|
|
53
|
+
}
|
|
54
|
+
return this.fetchRetrier.fetchRetry(finalRequest, options);
|
|
76
55
|
}
|
|
77
56
|
|
|
78
57
|
/** @inheritdoc */
|
|
79
58
|
async fetchApiResponse<T>(
|
|
80
59
|
url: string,
|
|
81
|
-
options?:
|
|
82
|
-
includeCredentials?: boolean;
|
|
83
|
-
method?: string;
|
|
84
|
-
body?: BodyInit;
|
|
85
|
-
headers?: HeadersInit;
|
|
86
|
-
retryConfig?: RetryConfiguring;
|
|
87
|
-
},
|
|
60
|
+
options?: ApiFetchOptions,
|
|
88
61
|
): Promise<T> {
|
|
89
62
|
const requestInit: RequestInit = {};
|
|
90
63
|
if (options?.includeCredentials) requestInit.credentials = 'include';
|
|
@@ -100,22 +73,28 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
100
73
|
}
|
|
101
74
|
|
|
102
75
|
/** @inheritdoc */
|
|
103
|
-
async
|
|
104
|
-
|
|
105
|
-
options?:
|
|
106
|
-
): Promise<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
76
|
+
async fetchApiPathResponse<T>(
|
|
77
|
+
path: string,
|
|
78
|
+
options?: ApiFetchOptions,
|
|
79
|
+
): Promise<T> {
|
|
80
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
81
|
+
return this.fetchApiResponse(url, options);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @inheritdoc */
|
|
85
|
+
async fetchIAApiResponse<T>(
|
|
86
|
+
path: string,
|
|
87
|
+
options?: ApiFetchOptions,
|
|
88
|
+
): Promise<T> {
|
|
89
|
+
return this.fetchApiPathResponse(path, options);
|
|
114
90
|
}
|
|
115
91
|
|
|
116
92
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
93
|
+
* Construct a new URL with the given search params added
|
|
94
|
+
*
|
|
95
|
+
* @param urlString - Original URL string
|
|
96
|
+
* @param params - Params to add
|
|
97
|
+
* @returns New URL string with params added
|
|
119
98
|
*/
|
|
120
99
|
private addSearchParams(
|
|
121
100
|
urlString: string,
|
|
@@ -136,4 +115,15 @@ export class FetchHandler implements FetchHandlerInterface {
|
|
|
136
115
|
*
|
|
137
116
|
* @deprecated Use `FetchHandler` instead.
|
|
138
117
|
*/
|
|
139
|
-
export class IaFetchHandler extends FetchHandler {
|
|
118
|
+
export class IaFetchHandler extends FetchHandler {
|
|
119
|
+
constructor(options?: {
|
|
120
|
+
iaApiBaseUrl?: string;
|
|
121
|
+
apiBaseUrl?: string;
|
|
122
|
+
fetchRetrier?: FetchRetrierInterface;
|
|
123
|
+
searchParams?: string;
|
|
124
|
+
}) {
|
|
125
|
+
const superOptions = { ...options };
|
|
126
|
+
superOptions.iaApiBaseUrl = options?.iaApiBaseUrl ?? 'https://archive.org';
|
|
127
|
+
super(superOptions);
|
|
128
|
+
}
|
|
129
|
+
}
|
package/src/fetch-options.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { RetryConfiguring } from './fetch-retry/configuration/retry-configuring';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Base fetch options for FetchHandler
|
|
5
|
+
*/
|
|
3
6
|
export type FetchOptions = {
|
|
4
7
|
requestInit?: RequestInit;
|
|
5
8
|
retryConfig?: RetryConfiguring;
|
|
6
9
|
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A convenience type for FetchHandler methods with common API fetch options.
|
|
13
|
+
*/
|
|
14
|
+
export type ApiFetchOptions = {
|
|
15
|
+
includeCredentials?: boolean;
|
|
16
|
+
method?: string;
|
|
17
|
+
body?: BodyInit;
|
|
18
|
+
headers?: HeadersInit;
|
|
19
|
+
retryConfig?: RetryConfiguring;
|
|
20
|
+
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { AnalyticsHandlerInterface } from '@internetarchive/analytics-manager';
|
|
2
|
-
import { promisedSleep } from '../utils/promised-sleep';
|
|
3
2
|
import { type FetchOptions } from '../fetch-options';
|
|
4
|
-
import {
|
|
5
|
-
import { DefaultRetryConfiguration } from './configuration/default-retry-configuration';
|
|
6
|
-
import type { RetryConfiguring } from './configuration/retry-configuring';
|
|
3
|
+
import { promisedSleep } from '../utils/promised-sleep';
|
|
7
4
|
import { FetchRetryConfig } from './configuration/configurations';
|
|
5
|
+
import type { RetryConfiguring } from './configuration/retry-configuring';
|
|
6
|
+
import { legacyArgsAsFetchOptions } from './legacy-args';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* A class that retries a fetch request.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { FetchHandler } from '../src/fetch-handler';
|
|
2
|
+
import { FetchHandler, IaFetchHandler } from '../src/fetch-handler';
|
|
3
3
|
import { MockFetchRetrier } from './mocks/mock-fetch-retrier';
|
|
4
4
|
import { NoRetryConfiguration } from '../src/fetch-retry/configuration/no-retry-configuration';
|
|
5
5
|
|
|
@@ -144,7 +144,32 @@ describe('Fetch Handler', () => {
|
|
|
144
144
|
it('is an alias for fetchApiPathResponse', async () => {
|
|
145
145
|
const endpoint = '/foo/service/endpoint.php';
|
|
146
146
|
const fetchRetrier = new MockFetchRetrier();
|
|
147
|
-
const fetchHandler = new
|
|
147
|
+
const fetchHandler = new IaFetchHandler({
|
|
148
|
+
iaApiBaseUrl: 'www.example.com',
|
|
149
|
+
fetchRetrier: fetchRetrier,
|
|
150
|
+
});
|
|
151
|
+
await fetchHandler.fetchIAApiResponse(endpoint);
|
|
152
|
+
expect(fetchRetrier.requestInfo).to.equal(
|
|
153
|
+
'www.example.com/foo/service/endpoint.php',
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('defaults the baseUrl to https://archive.org', async () => {
|
|
158
|
+
const endpoint = '/foo/service/endpoint.php';
|
|
159
|
+
const fetchRetrier = new MockFetchRetrier();
|
|
160
|
+
const fetchHandler = new IaFetchHandler({
|
|
161
|
+
fetchRetrier: fetchRetrier,
|
|
162
|
+
});
|
|
163
|
+
await fetchHandler.fetchIAApiResponse(endpoint);
|
|
164
|
+
expect(fetchRetrier.requestInfo).to.equal(
|
|
165
|
+
'https://archive.org/foo/service/endpoint.php',
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('passes iaApiBaseUrl if provided', async () => {
|
|
170
|
+
const endpoint = '/foo/service/endpoint.php';
|
|
171
|
+
const fetchRetrier = new MockFetchRetrier();
|
|
172
|
+
const fetchHandler = new IaFetchHandler({
|
|
148
173
|
iaApiBaseUrl: 'www.example.com',
|
|
149
174
|
fetchRetrier: fetchRetrier,
|
|
150
175
|
});
|