@applitools/req
Advanced tools
Comparing version 1.5.4 to 1.6.0
# Changelog | ||
## [1.6.0](https://github.com/applitools/eyes.sdk.javascript1/compare/js/req@1.5.4...js/req@1.6.0) (2023-09-04) | ||
### Features | ||
* add support for fallback in `req` ([#1899](https://github.com/applitools/eyes.sdk.javascript1/issues/1899)) ([d69c4b5](https://github.com/applitools/eyes.sdk.javascript1/commit/d69c4b5830370c471dfc25b6e2caddca8b458df9)) | ||
* update testcafe ([#1884](https://github.com/applitools/eyes.sdk.javascript1/issues/1884)) ([104f1b6](https://github.com/applitools/eyes.sdk.javascript1/commit/104f1b6cc0d4f107ba46404383de2fa11fe99dcf)) | ||
### Dependencies | ||
* @applitools/utils bumped to 1.6.0 | ||
#### Features | ||
* add support for fallback in `req` ([#1899](https://github.com/applitools/eyes.sdk.javascript1/issues/1899)) ([d69c4b5](https://github.com/applitools/eyes.sdk.javascript1/commit/d69c4b5830370c471dfc25b6e2caddca8b458df9)) | ||
## [1.5.4](https://github.com/applitools/eyes.sdk.javascript1/compare/js/req@1.5.3...js/req@1.5.4) (2023-08-30) | ||
@@ -4,0 +20,0 @@ |
@@ -8,3 +8,3 @@ import { parse as urlToHttpOptions } from 'url'; // should be replaced with `urlToHttpOptions` after supporting node >=16 | ||
import * as utils from '@applitools/utils'; | ||
export function makeAgent({ proxy, useDnsCache, }) { | ||
export function makeAgent({ proxy, useDnsCache, keepAliveOptions, }) { | ||
return function agent(url) { | ||
@@ -31,9 +31,9 @@ var _a, _b; | ||
else if (url.protocol === 'https:') { | ||
return new HttpsAgent({ rejectUnauthorized: false, lookup }); | ||
return new HttpsAgent({ rejectUnauthorized: false, lookup, ...keepAliveOptions }); | ||
} | ||
else if (url.protocol === 'http:') { | ||
// @ts-expect-error due to a wrong type definition for node 12, already fixed in newer versions | ||
return new HttpAgent({ lookup }); | ||
return new HttpAgent({ lookup, ...keepAliveOptions }); | ||
} | ||
}; | ||
} |
@@ -38,4 +38,11 @@ import { AbortController } from 'abort-controller'; | ||
async function req(input, options) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; | ||
const fetch = (_a = options.fetch) !== null && _a !== void 0 ? _a : globalFetch; | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p; | ||
const url = new URL(String((_a = input.url) !== null && _a !== void 0 ? _a : input), options.baseUrl); | ||
const fetch = (_b = options.fetch) !== null && _b !== void 0 ? _b : globalFetch; | ||
let optionsFallbacks = []; | ||
if (options.fallbacks) | ||
optionsFallbacks = utils.types.isArray(options.fallbacks) ? options.fallbacks : [options.fallbacks]; | ||
const fb = optionsFallbacks.find(fallback => { var _a; return (_a = fallback.cache) === null || _a === void 0 ? void 0 : _a.get(url.origin); }); | ||
if (fb === null || fb === void 0 ? void 0 : fb.updateOptions) | ||
options = await fb.updateOptions({ options }); | ||
const requestController = new AbortController(); | ||
@@ -56,3 +63,2 @@ const requestTimer = options.requestTimeout | ||
} | ||
const url = new URL(String((_b = input.url) !== null && _b !== void 0 ? _b : input), options.baseUrl); | ||
if (options.query) { | ||
@@ -78,3 +84,7 @@ Object.entries(options.query).forEach(([key, value]) => { | ||
highWaterMark: 1024 * 1024 * 100 + 1, | ||
agent: makeAgent({ proxy: options.proxy, useDnsCache: options.useDnsCache }), | ||
agent: makeAgent({ | ||
proxy: options.proxy, | ||
useDnsCache: options.useDnsCache, | ||
keepAliveOptions: options.keepAliveOptions, | ||
}), | ||
signal: requestController.signal, | ||
@@ -85,4 +95,19 @@ }); | ||
let response = await fetch(request); | ||
// if the request has a fallback try it | ||
if (!response.ok && optionsFallbacks.length > 0) { | ||
const fallbackStrategy = optionsFallbacks[0]; | ||
const shouldFallback = await fallbackStrategy.shouldFallbackCondition({ request, response }); | ||
const fallbackOptions = shouldFallback && | ||
(await ((_g = fallbackStrategy === null || fallbackStrategy === void 0 ? void 0 : fallbackStrategy.updateOptions) === null || _g === void 0 ? void 0 : _g.call(fallbackStrategy, { | ||
options: { ...options, fallbacks: optionsFallbacks.slice(1) }, | ||
}))); | ||
if (fallbackOptions) { | ||
const fallbackStrategyResponse = await req(request, fallbackOptions); | ||
(_h = fallbackStrategy.cache) !== null && _h !== void 0 ? _h : (fallbackStrategy.cache = new Map()); | ||
fallbackStrategy.cache.set(new URL(request.url).origin, fallbackStrategyResponse.ok); | ||
return fallbackStrategyResponse; | ||
} | ||
} | ||
// if the request has to be retried due to status code | ||
const retry = await ((_g = options.retry) === null || _g === void 0 ? void 0 : _g.reduce(async (prev, retry) => { | ||
const retry = await ((_j = options.retry) === null || _j === void 0 ? void 0 : _j.reduce(async (prev, retry) => { | ||
var _a, _b; | ||
@@ -96,3 +121,3 @@ const result = await prev; | ||
if (retry) { | ||
(_h = retry.attempt) !== null && _h !== void 0 ? _h : (retry.attempt = 0); | ||
(_k = retry.attempt) !== null && _k !== void 0 ? _k : (retry.attempt = 0); | ||
const delay = response.headers.has('Retry-After') | ||
@@ -102,3 +127,3 @@ ? Number(response.headers.get('Retry-After')) * 1000 | ||
? retry.timeout[Math.min(retry.attempt, retry.timeout.length - 1)] | ||
: (_j = retry.timeout) !== null && _j !== void 0 ? _j : 0; | ||
: (_l = retry.timeout) !== null && _l !== void 0 ? _l : 0; | ||
await utils.general.sleep(delay); | ||
@@ -120,3 +145,3 @@ retry.attempt += 1; | ||
// if the request has to be retried due to network error | ||
const retry = await ((_k = options.retry) === null || _k === void 0 ? void 0 : _k.reduce((prev, retry) => { | ||
const retry = await ((_m = options.retry) === null || _m === void 0 ? void 0 : _m.reduce((prev, retry) => { | ||
return prev.then(async (result) => { | ||
@@ -131,6 +156,6 @@ var _a, _b; | ||
if (retry) { | ||
(_l = retry.attempt) !== null && _l !== void 0 ? _l : (retry.attempt = 0); | ||
(_o = retry.attempt) !== null && _o !== void 0 ? _o : (retry.attempt = 0); | ||
const delay = utils.types.isArray(retry.timeout) | ||
? retry.timeout[Math.min(retry.attempt, retry.timeout.length)] | ||
: (_m = retry.timeout) !== null && _m !== void 0 ? _m : 0; | ||
: (_p = retry.timeout) !== null && _p !== void 0 ? _p : 0; | ||
await utils.general.sleep(delay); | ||
@@ -169,2 +194,6 @@ retry.attempt = retry.attempt + 1; | ||
], | ||
fallbacks: [ | ||
...(baseOptions.fallbacks ? [].concat(baseOptions.fallbacks) : []), | ||
...((options === null || options === void 0 ? void 0 : options.fallbacks) ? [].concat(options.fallbacks) : []), | ||
], | ||
}), baseOptions); | ||
@@ -171,0 +200,0 @@ return ((_a = mergedOptions.hooks) !== null && _a !== void 0 ? _a : []).reduce((options, hooks) => { var _a, _b; return (_b = (_a = hooks.afterOptionsMerged) === null || _a === void 0 ? void 0 : _a.call(hooks, { options })) !== null && _b !== void 0 ? _b : options; }, mergedOptions); |
{ | ||
"name": "@applitools/req", | ||
"version": "1.5.4", | ||
"version": "1.6.0", | ||
"description": "Applitools fetch-based request library", | ||
@@ -57,3 +57,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@applitools/utils": "1.5.2", | ||
"@applitools/utils": "1.6.0", | ||
"abort-controller": "3.0.0", | ||
@@ -65,3 +65,3 @@ "http-proxy-agent": "5.0.0", | ||
"devDependencies": { | ||
"@applitools/api-extractor": "^1.2.21", | ||
"@applitools/api-extractor": "^1.2.22", | ||
"@applitools/test-server": "^1.2.2", | ||
@@ -74,3 +74,3 @@ "@types/node": "^12.20.55", | ||
"engines": { | ||
"node": ">=12.13.0" | ||
"node": ">=16.13.0" | ||
}, | ||
@@ -77,0 +77,0 @@ "publishConfig": { |
@@ -101,2 +101,4 @@ export type Stop = typeof stop; | ||
fetch?: undefined | Fetch; | ||
fallbacks?: undefined | Fallback<this> | Array<Fallback<this>>; | ||
keepAliveOptions?: undefined | KeepAliveOptions; | ||
} | ||
@@ -116,5 +118,14 @@ export interface Retry { | ||
} | ||
export interface KeepAliveOptions { | ||
keepAlive: boolean; | ||
keepAliveMsecs?: undefined | number; | ||
} | ||
export interface Fallback<TOptions extends Options = Options> { | ||
shouldFallbackCondition: (options: { response: Response; request: Request; }) => boolean | PromiseLike<boolean>; | ||
updateOptions?: undefined | ((options: { options: TOptions; }) => TOptions | PromiseLike<TOptions>); | ||
cache?: undefined | Map<string, boolean>; | ||
} | ||
export interface Hooks<TOptions extends Options = Options> { | ||
afterOptionsMerged?(options: { options: TOptions; }): void | TOptions; | ||
beforeRequest?(options: { request: Request; options?: undefined | TOptions; }): void | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; }) | Promise<void | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; })>; | ||
beforeRequest?(options: { request: Request; options?: undefined | TOptions; }): void | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; }) | PromiseLike<void | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; })>; | ||
beforeRetry?(options: { | ||
@@ -127,5 +138,5 @@ request: Request; | ||
options?: undefined | TOptions; | ||
}): void | Stop | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; }) | Promise<void | Stop | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; })>; | ||
afterResponse?(options: { request: Request; response: Response; options?: undefined | TOptions; }): void | Response | (ResponseInit & { response?: undefined | Response; body?: undefined | null | BodyInit; }) | Promise<void | Response | (ResponseInit & { response?: undefined | Response; body?: undefined | null | BodyInit; })>; | ||
afterError?(options: { request: Request; error: Error; options?: undefined | TOptions; }): void | Error | Promise<void | Error>; | ||
}): void | Stop | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; }) | PromiseLike<void | Stop | Request | (RequestInit & { request: Request; }) | (RequestInit & { url: string | URL; request?: undefined | Request; })>; | ||
afterResponse?(options: { request: Request; response: Response; options?: undefined | TOptions; }): void | Response | (ResponseInit & { response?: undefined | Response; body?: undefined | null | BodyInit; }) | PromiseLike<void | Response | (ResponseInit & { response?: undefined | Response; body?: undefined | null | BodyInit; })>; | ||
afterError?(options: { request: Request; error: Error; options?: undefined | TOptions; }): void | Error | PromiseLike<void | Error>; | ||
} | ||
@@ -132,0 +143,0 @@ export type AbortSignal = { readonly aborted: boolean; onabort: null | ((event: any) => void); addEventListener: (type: "abort", listener: () => void) => void; removeEventListener: (type: "abort", listener: () => void) => void; }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
424914
10061
+ Added@applitools/utils@1.6.0(transitive)
- Removed@applitools/utils@1.5.2(transitive)
Updated@applitools/utils@1.6.0