@empathyco/x-adapter 8.0.0-alpha.2 → 8.0.0-alpha.3
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/cjs/http-clients/beacon.http-client.js +3 -2
- package/dist/cjs/http-clients/beacon.http-client.js.map +1 -1
- package/dist/cjs/http-clients/fetch.http-client.js +28 -9
- package/dist/cjs/http-clients/fetch.http-client.js.map +1 -1
- package/dist/cjs/http-clients/types.js.map +1 -1
- package/dist/cjs/http-clients/utils.js +1 -2
- package/dist/cjs/http-clients/utils.js.map +1 -1
- package/dist/esm/http-clients/beacon.http-client.js +3 -2
- package/dist/esm/http-clients/beacon.http-client.js.map +1 -1
- package/dist/esm/http-clients/fetch.http-client.js +27 -8
- package/dist/esm/http-clients/fetch.http-client.js.map +1 -1
- package/dist/esm/http-clients/types.js.map +1 -1
- package/dist/esm/http-clients/utils.js +2 -3
- package/dist/esm/http-clients/utils.js.map +1 -1
- package/dist/types/http-clients/types.d.ts +4 -0
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.beaconHttpClient = void 0;
|
|
4
|
+
const x_utils_1 = require("@empathyco/x-utils");
|
|
4
5
|
const utils_1 = require("./utils");
|
|
5
6
|
/**
|
|
6
7
|
* Flag determining if the user has an ad-blocker installed.
|
|
@@ -18,8 +19,8 @@ let hasAdBlocker = undefined;
|
|
|
18
19
|
*
|
|
19
20
|
* @public
|
|
20
21
|
*/
|
|
21
|
-
const beaconHttpClient = async (endpoint, { parameters, properties } = {}) => {
|
|
22
|
-
const url = (0, utils_1.buildUrl)(endpoint, parameters);
|
|
22
|
+
const beaconHttpClient = async (endpoint, { parameters = {}, properties } = {}) => {
|
|
23
|
+
const url = (0, utils_1.buildUrl)(endpoint, (0, x_utils_1.flatObject)(parameters));
|
|
23
24
|
if (hasAdBlocker === undefined) {
|
|
24
25
|
try {
|
|
25
26
|
const response = await detectAdBlocker();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beacon.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/beacon.http-client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"beacon.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/beacon.http-client.ts"],"names":[],"mappings":";;;AAAA,gDAAgD;AAEhD,mCAAmC;AAEnC;;GAEG;AACH,IAAI,YAAY,GAAwB,SAAS,CAAC;AAElD;;;;;;;;;;;GAWG;AACI,MAAM,gBAAgB,GAAe,KAAK,EAC/C,QAAQ,EACR,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EACpC,EAAE;IACF,MAAM,GAAG,GAAG,IAAA,gBAAQ,EAAC,QAAQ,EAAE,IAAA,oBAAU,EAAC,UAAU,CAAC,CAAC,CAAC;IAEvD,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,IAAI;YACF,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;YACzC,8FAA8F;YAC9F,8FAA8F;YAC9F,4FAA4F;YAC5F,kDAAkD;YAClD,YAAY,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;SAC7B;QAAC,OAAO,MAAM,EAAE;YACf,kDAAkD;YAClD,YAAY,GAAG,IAAI,CAAC;SACrB;KACF;IAED,IAAI,YAAY,EAAE;QAChB,OAAO,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;KAC/B;SAAM;QACL,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAE1B,OAAO,OAAO,CAAC,OAAO,CAAM,EAAE,CAAC,CAAC;KACjC;AACH,CAAC,CAAC;AA3BW,QAAA,gBAAgB,oBA2B3B;AAEF;;;;;;;GAOG;AACH,SAAS,eAAe;IACtB,OAAO,KAAK,CAAC,6CAA6C,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl } from './utils';\n\n/**\n * Flag determining if the user has an ad-blocker installed.\n */\nlet hasAdBlocker: boolean | undefined = undefined;\n\n/**\n * The `beaconHttpClient()` function is a http client implementation using the WebAPI\n * `navigator.sendBeacon`.\n *\n * @remarks As a `navigation.sendBeacon` request might be cancelled by an ad-blocker, the function\n * firstly checks if an ad-blocker is installed. In case it is, the `fetch` API is used as fallback.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @public\n */\nexport const beaconHttpClient: HttpClient = async (\n endpoint,\n { parameters = {}, properties } = {}\n) => {\n const url = buildUrl(endpoint, flatObject(parameters));\n\n if (hasAdBlocker === undefined) {\n try {\n const response = await detectAdBlocker();\n // The Promise returned from fetch() won't reject on HTTP error status even if the response is\n // an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it\n // will only reject on network failure or if anything prevented the request from completing.\n // eslint-disable-next-line require-atomic-updates\n hasAdBlocker = !response.ok;\n } catch (_error) {\n // eslint-disable-next-line require-atomic-updates\n hasAdBlocker = true;\n }\n }\n\n if (hasAdBlocker) {\n return fetch(url, properties);\n } else {\n navigator.sendBeacon(url);\n\n return Promise.resolve<any>({});\n }\n};\n\n/**\n * The `detectAdBlocker()` function checks if the user has an ad-blocker installed.\n *\n * @returns A Promise object. If the `response` is `ok`, no ad-blocker is installed. Otherwise, an\n * ad-blocker is active.\n *\n * @internal\n */\nfunction detectAdBlocker(): Promise<Response> {\n return fetch('https://google.com/pagead/js/adsbygoogle.js', {\n method: 'HEAD',\n mode: 'no-cors'\n });\n}\n"]}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchHttpClient = void 0;
|
|
4
|
+
const x_utils_1 = require("@empathyco/x-utils");
|
|
4
5
|
const utils_1 = require("./utils");
|
|
5
|
-
/**
|
|
6
|
-
* Dictionary with the request id as key and an `AbortController` as value.
|
|
7
|
-
*/
|
|
8
|
-
const requestAbortControllers = {};
|
|
9
6
|
/**
|
|
10
7
|
* The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.
|
|
11
8
|
*
|
|
@@ -16,12 +13,34 @@ const requestAbortControllers = {};
|
|
|
16
13
|
*
|
|
17
14
|
* @public
|
|
18
15
|
*/
|
|
19
|
-
const fetchHttpClient = (endpoint, { id = endpoint, parameters, properties } = {}) => {
|
|
16
|
+
const fetchHttpClient = (endpoint, { id = endpoint, parameters = {}, properties, sendParamsInBody = false } = {}) => {
|
|
17
|
+
const signal = abortAndGetNewAbortSignal(id);
|
|
18
|
+
const flatParameters = (0, x_utils_1.flatObject)(parameters);
|
|
19
|
+
const url = sendParamsInBody ? endpoint : (0, utils_1.buildUrl)(endpoint, flatParameters);
|
|
20
|
+
const bodyParameters = sendParamsInBody ? { body: JSON.stringify(flatParameters) } : {};
|
|
21
|
+
return fetch(url, {
|
|
22
|
+
...properties,
|
|
23
|
+
...bodyParameters,
|
|
24
|
+
signal
|
|
25
|
+
}).then(utils_1.toJson);
|
|
26
|
+
};
|
|
27
|
+
exports.fetchHttpClient = fetchHttpClient;
|
|
28
|
+
/**
|
|
29
|
+
* Dictionary with the request id as key and an `AbortController` as value.
|
|
30
|
+
*/
|
|
31
|
+
const requestAbortControllers = {};
|
|
32
|
+
/**
|
|
33
|
+
* Function that cancels previous request with the same `id` and returns a new `AbortSignal` for
|
|
34
|
+
* the new request.
|
|
35
|
+
*
|
|
36
|
+
* @param id - The identifier of the request to cancel and create a new `AbortSignal`.
|
|
37
|
+
*
|
|
38
|
+
* @returns The new `AbortSignal`.
|
|
39
|
+
*/
|
|
40
|
+
function abortAndGetNewAbortSignal(id) {
|
|
20
41
|
var _a;
|
|
21
|
-
const url = (0, utils_1.buildUrl)(endpoint, parameters);
|
|
22
42
|
(_a = requestAbortControllers[id]) === null || _a === void 0 ? void 0 : _a.abort();
|
|
23
43
|
requestAbortControllers[id] = new AbortController();
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
exports.fetchHttpClient = fetchHttpClient;
|
|
44
|
+
return requestAbortControllers[id].signal;
|
|
45
|
+
}
|
|
27
46
|
//# sourceMappingURL=fetch.http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":";;;AAAA,gDAA4D;AAE5D,mCAA2C;AAE3C;;;;;;;;;GASG;AACI,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAC7E,EAAE;IACF,MAAM,MAAM,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAA,oBAAU,EAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,gBAAQ,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,MAAM;KACP,CAAC,CAAC,IAAI,CAAC,cAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAdW,QAAA,eAAe,mBAc1B;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = abortAndGetNewAbortSignal(id);\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(flatParameters) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/http-clients/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Dictionary } from '@empathyco/x-utils';\n\n/**\n * Makes a request to a backend API using the given parameters.\n *\n * @param endpoint - The endpoint to use.\n * @param options - Additional options to make the request with.\n * @returns A promise wrapped object containing the response.\n * @public\n */\nexport type HttpClient = <Response = unknown>(\n endpoint: string,\n options?: Omit<RequestOptions, 'endpoint'>\n) => Promise<Readonly<Response>>;\n\n/**\n * A record of options to make the request with.\n *\n * @public\n */\nexport interface RequestOptions {\n /**\n * A unique identifier for this request. Can be used to abort requests with same id.\n */\n id?: string;\n /**\n * A list of parameters to send to the API.\n */\n parameters?: Dictionary<unknown>;\n /**\n * The RequestInit object to create the request with.\n */\n properties?: RequestInit;\n /**\n * The base endpoint that the request should use.\n */\n endpoint?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/http-clients/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Dictionary } from '@empathyco/x-utils';\n\n/**\n * Makes a request to a backend API using the given parameters.\n *\n * @param endpoint - The endpoint to use.\n * @param options - Additional options to make the request with.\n * @returns A promise wrapped object containing the response.\n * @public\n */\nexport type HttpClient = <Response = unknown>(\n endpoint: string,\n options?: Omit<RequestOptions, 'endpoint'>\n) => Promise<Readonly<Response>>;\n\n/**\n * A record of options to make the request with.\n *\n * @public\n */\nexport interface RequestOptions {\n /**\n * A unique identifier for this request. Can be used to abort requests with same id.\n */\n id?: string;\n /**\n * A flag to send parameters in the body if true or in the url QueryString if false.\n */\n sendParamsInBody?: boolean;\n /**\n * A list of parameters to send to the API.\n */\n parameters?: Dictionary<unknown>;\n /**\n * The RequestInit object to create the request with.\n */\n properties?: RequestInit;\n /**\n * The base endpoint that the request should use.\n */\n endpoint?: string;\n}\n"]}
|
|
@@ -34,8 +34,7 @@ exports.toJson = toJson;
|
|
|
34
34
|
*/
|
|
35
35
|
function buildUrl(endpoint, params = {}) {
|
|
36
36
|
const url = new URL(endpoint);
|
|
37
|
-
|
|
38
|
-
(0, x_utils_1.forEach)(flattenedParams, (key, value) => (Array.isArray(value) ? value : [value]).forEach(arrayItemValue => url.searchParams.append(key, String(arrayItemValue))));
|
|
37
|
+
(0, x_utils_1.forEach)(params, (key, value) => (Array.isArray(value) ? value : [value]).forEach(arrayItemValue => url.searchParams.append(key, String(arrayItemValue))));
|
|
39
38
|
return url.href;
|
|
40
39
|
}
|
|
41
40
|
exports.buildUrl = buildUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/http-clients/utils.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/http-clients/utils.ts"],"names":[],"mappings":";;;AAAA,gDAAyD;AACzD,0DAAsD;AAEtD;;;;;;;;;GASG;AACH,SAAgB,MAAM,CAAC,QAAkB;IACvC,IAAI,QAAQ,CAAC,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;KACxB;SAAM;QACL,MAAM,IAAI,4BAAY,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;KACpD;AACH,CAAC;AAND,wBAMC;AAED;;;;;;;;;GASG;AACH,SAAgB,QAAQ,CAAC,QAAgB,EAAE,SAA8B,EAAE;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAA,iBAAO,EAAC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAChE,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CACrD,CACF,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AARD,4BAQC","sourcesContent":["import { Dictionary, forEach } from '@empathyco/x-utils';\nimport { RequestError } from './errors/request-error';\n\n/**\n * Formats a response object to JSON.\n *\n * @remarks If the `response.ok` is falsy, a `RequestError` object is thrown.\n *\n * @param response - The response to convert to JSON format.\n * @returns - The resultant promise of formatting the response to JSON.\n *\n * @public\n */\nexport function toJson(response: Response): Promise<any> {\n if (response.ok) {\n return response.json();\n } else {\n throw new RequestError('Request failed', response);\n }\n}\n\n/**\n * Builds a URL object based on the passed endpoint and the request parameters.\n *\n * @param endpoint - The endpoint.\n * @param params - The request parameters.\n *\n * @returns The `href` property of the newly built `URL` object.\n *\n * @public\n */\nexport function buildUrl(endpoint: string, params: Dictionary<unknown> = {}): URL['href'] {\n const url = new URL(endpoint);\n forEach(params, (key, value) =>\n (Array.isArray(value) ? value : [value]).forEach(arrayItemValue =>\n url.searchParams.append(key, String(arrayItemValue))\n )\n );\n return url.href;\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { flatObject } from '@empathyco/x-utils';
|
|
1
2
|
import { buildUrl } from './utils';
|
|
2
3
|
/**
|
|
3
4
|
* Flag determining if the user has an ad-blocker installed.
|
|
@@ -15,8 +16,8 @@ let hasAdBlocker = undefined;
|
|
|
15
16
|
*
|
|
16
17
|
* @public
|
|
17
18
|
*/
|
|
18
|
-
export const beaconHttpClient = async (endpoint, { parameters, properties } = {}) => {
|
|
19
|
-
const url = buildUrl(endpoint, parameters);
|
|
19
|
+
export const beaconHttpClient = async (endpoint, { parameters = {}, properties } = {}) => {
|
|
20
|
+
const url = buildUrl(endpoint, flatObject(parameters));
|
|
20
21
|
if (hasAdBlocker === undefined) {
|
|
21
22
|
try {
|
|
22
23
|
const response = await detectAdBlocker();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beacon.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/beacon.http-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"beacon.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/beacon.http-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC;;GAEG;AACH,IAAI,YAAY,GAAwB,SAAS,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAe,KAAK,EAC/C,QAAQ,EACR,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,EACpC,EAAE;IACF,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAEvD,IAAI,YAAY,KAAK,SAAS,EAAE;QAC9B,IAAI;YACF,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;YACzC,8FAA8F;YAC9F,8FAA8F;YAC9F,4FAA4F;YAC5F,kDAAkD;YAClD,YAAY,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;SAC7B;QAAC,OAAO,MAAM,EAAE;YACf,kDAAkD;YAClD,YAAY,GAAG,IAAI,CAAC;SACrB;KACF;IAED,IAAI,YAAY,EAAE;QAChB,OAAO,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;KAC/B;SAAM;QACL,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAE1B,OAAO,OAAO,CAAC,OAAO,CAAM,EAAE,CAAC,CAAC;KACjC;AACH,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,SAAS,eAAe;IACtB,OAAO,KAAK,CAAC,6CAA6C,EAAE;QAC1D,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl } from './utils';\n\n/**\n * Flag determining if the user has an ad-blocker installed.\n */\nlet hasAdBlocker: boolean | undefined = undefined;\n\n/**\n * The `beaconHttpClient()` function is a http client implementation using the WebAPI\n * `navigator.sendBeacon`.\n *\n * @remarks As a `navigation.sendBeacon` request might be cancelled by an ad-blocker, the function\n * firstly checks if an ad-blocker is installed. In case it is, the `fetch` API is used as fallback.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @public\n */\nexport const beaconHttpClient: HttpClient = async (\n endpoint,\n { parameters = {}, properties } = {}\n) => {\n const url = buildUrl(endpoint, flatObject(parameters));\n\n if (hasAdBlocker === undefined) {\n try {\n const response = await detectAdBlocker();\n // The Promise returned from fetch() won't reject on HTTP error status even if the response is\n // an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it\n // will only reject on network failure or if anything prevented the request from completing.\n // eslint-disable-next-line require-atomic-updates\n hasAdBlocker = !response.ok;\n } catch (_error) {\n // eslint-disable-next-line require-atomic-updates\n hasAdBlocker = true;\n }\n }\n\n if (hasAdBlocker) {\n return fetch(url, properties);\n } else {\n navigator.sendBeacon(url);\n\n return Promise.resolve<any>({});\n }\n};\n\n/**\n * The `detectAdBlocker()` function checks if the user has an ad-blocker installed.\n *\n * @returns A Promise object. If the `response` is `ok`, no ad-blocker is installed. Otherwise, an\n * ad-blocker is active.\n *\n * @internal\n */\nfunction detectAdBlocker(): Promise<Response> {\n return fetch('https://google.com/pagead/js/adsbygoogle.js', {\n method: 'HEAD',\n mode: 'no-cors'\n });\n}\n"]}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
import { flatObject } from '@empathyco/x-utils';
|
|
1
2
|
import { buildUrl, toJson } from './utils';
|
|
2
|
-
/**
|
|
3
|
-
* Dictionary with the request id as key and an `AbortController` as value.
|
|
4
|
-
*/
|
|
5
|
-
const requestAbortControllers = {};
|
|
6
3
|
/**
|
|
7
4
|
* The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.
|
|
8
5
|
*
|
|
@@ -13,11 +10,33 @@ const requestAbortControllers = {};
|
|
|
13
10
|
*
|
|
14
11
|
* @public
|
|
15
12
|
*/
|
|
16
|
-
export const fetchHttpClient = (endpoint, { id = endpoint, parameters, properties } = {}) => {
|
|
13
|
+
export const fetchHttpClient = (endpoint, { id = endpoint, parameters = {}, properties, sendParamsInBody = false } = {}) => {
|
|
14
|
+
const signal = abortAndGetNewAbortSignal(id);
|
|
15
|
+
const flatParameters = flatObject(parameters);
|
|
16
|
+
const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);
|
|
17
|
+
const bodyParameters = sendParamsInBody ? { body: JSON.stringify(flatParameters) } : {};
|
|
18
|
+
return fetch(url, {
|
|
19
|
+
...properties,
|
|
20
|
+
...bodyParameters,
|
|
21
|
+
signal
|
|
22
|
+
}).then(toJson);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Dictionary with the request id as key and an `AbortController` as value.
|
|
26
|
+
*/
|
|
27
|
+
const requestAbortControllers = {};
|
|
28
|
+
/**
|
|
29
|
+
* Function that cancels previous request with the same `id` and returns a new `AbortSignal` for
|
|
30
|
+
* the new request.
|
|
31
|
+
*
|
|
32
|
+
* @param id - The identifier of the request to cancel and create a new `AbortSignal`.
|
|
33
|
+
*
|
|
34
|
+
* @returns The new `AbortSignal`.
|
|
35
|
+
*/
|
|
36
|
+
function abortAndGetNewAbortSignal(id) {
|
|
17
37
|
var _a;
|
|
18
|
-
const url = buildUrl(endpoint, parameters);
|
|
19
38
|
(_a = requestAbortControllers[id]) === null || _a === void 0 ? void 0 : _a.abort();
|
|
20
39
|
requestAbortControllers[id] = new AbortController();
|
|
21
|
-
return
|
|
22
|
-
}
|
|
40
|
+
return requestAbortControllers[id].signal;
|
|
41
|
+
}
|
|
23
42
|
//# sourceMappingURL=fetch.http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAC7E,EAAE;IACF,MAAM,MAAM,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAExF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,MAAM;KACP,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = abortAndGetNewAbortSignal(id);\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(flatParameters) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/http-clients/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Dictionary } from '@empathyco/x-utils';\n\n/**\n * Makes a request to a backend API using the given parameters.\n *\n * @param endpoint - The endpoint to use.\n * @param options - Additional options to make the request with.\n * @returns A promise wrapped object containing the response.\n * @public\n */\nexport type HttpClient = <Response = unknown>(\n endpoint: string,\n options?: Omit<RequestOptions, 'endpoint'>\n) => Promise<Readonly<Response>>;\n\n/**\n * A record of options to make the request with.\n *\n * @public\n */\nexport interface RequestOptions {\n /**\n * A unique identifier for this request. Can be used to abort requests with same id.\n */\n id?: string;\n /**\n * A list of parameters to send to the API.\n */\n parameters?: Dictionary<unknown>;\n /**\n * The RequestInit object to create the request with.\n */\n properties?: RequestInit;\n /**\n * The base endpoint that the request should use.\n */\n endpoint?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/http-clients/types.ts"],"names":[],"mappings":"","sourcesContent":["import { Dictionary } from '@empathyco/x-utils';\n\n/**\n * Makes a request to a backend API using the given parameters.\n *\n * @param endpoint - The endpoint to use.\n * @param options - Additional options to make the request with.\n * @returns A promise wrapped object containing the response.\n * @public\n */\nexport type HttpClient = <Response = unknown>(\n endpoint: string,\n options?: Omit<RequestOptions, 'endpoint'>\n) => Promise<Readonly<Response>>;\n\n/**\n * A record of options to make the request with.\n *\n * @public\n */\nexport interface RequestOptions {\n /**\n * A unique identifier for this request. Can be used to abort requests with same id.\n */\n id?: string;\n /**\n * A flag to send parameters in the body if true or in the url QueryString if false.\n */\n sendParamsInBody?: boolean;\n /**\n * A list of parameters to send to the API.\n */\n parameters?: Dictionary<unknown>;\n /**\n * The RequestInit object to create the request with.\n */\n properties?: RequestInit;\n /**\n * The base endpoint that the request should use.\n */\n endpoint?: string;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { forEach } from '@empathyco/x-utils';
|
|
2
2
|
import { RequestError } from './errors/request-error';
|
|
3
3
|
/**
|
|
4
4
|
* Formats a response object to JSON.
|
|
@@ -30,8 +30,7 @@ export function toJson(response) {
|
|
|
30
30
|
*/
|
|
31
31
|
export function buildUrl(endpoint, params = {}) {
|
|
32
32
|
const url = new URL(endpoint);
|
|
33
|
-
|
|
34
|
-
forEach(flattenedParams, (key, value) => (Array.isArray(value) ? value : [value]).forEach(arrayItemValue => url.searchParams.append(key, String(arrayItemValue))));
|
|
33
|
+
forEach(params, (key, value) => (Array.isArray(value) ? value : [value]).forEach(arrayItemValue => url.searchParams.append(key, String(arrayItemValue))));
|
|
35
34
|
return url.href;
|
|
36
35
|
}
|
|
37
36
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/http-clients/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/http-clients/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,QAAkB;IACvC,IAAI,QAAQ,CAAC,EAAE,EAAE;QACf,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;KACxB;SAAM;QACL,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;KACpD;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,SAA8B,EAAE;IACzE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAChE,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CACrD,CACF,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC","sourcesContent":["import { Dictionary, forEach } from '@empathyco/x-utils';\nimport { RequestError } from './errors/request-error';\n\n/**\n * Formats a response object to JSON.\n *\n * @remarks If the `response.ok` is falsy, a `RequestError` object is thrown.\n *\n * @param response - The response to convert to JSON format.\n * @returns - The resultant promise of formatting the response to JSON.\n *\n * @public\n */\nexport function toJson(response: Response): Promise<any> {\n if (response.ok) {\n return response.json();\n } else {\n throw new RequestError('Request failed', response);\n }\n}\n\n/**\n * Builds a URL object based on the passed endpoint and the request parameters.\n *\n * @param endpoint - The endpoint.\n * @param params - The request parameters.\n *\n * @returns The `href` property of the newly built `URL` object.\n *\n * @public\n */\nexport function buildUrl(endpoint: string, params: Dictionary<unknown> = {}): URL['href'] {\n const url = new URL(endpoint);\n forEach(params, (key, value) =>\n (Array.isArray(value) ? value : [value]).forEach(arrayItemValue =>\n url.searchParams.append(key, String(arrayItemValue))\n )\n );\n return url.href;\n}\n"]}
|
|
@@ -18,6 +18,10 @@ export interface RequestOptions {
|
|
|
18
18
|
* A unique identifier for this request. Can be used to abort requests with same id.
|
|
19
19
|
*/
|
|
20
20
|
id?: string;
|
|
21
|
+
/**
|
|
22
|
+
* A flag to send parameters in the body if true or in the url QueryString if false.
|
|
23
|
+
*/
|
|
24
|
+
sendParamsInBody?: boolean;
|
|
21
25
|
/**
|
|
22
26
|
* A list of parameters to send to the API.
|
|
23
27
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empathyco/x-adapter",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.3",
|
|
4
4
|
"description": "A utils library to create a client for any API",
|
|
5
5
|
"author": "Empathy Systems Corporation S.L.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"publishConfig": {
|
|
49
49
|
"access": "public"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "a94853e17793bab55cecf8dc9cd6ffedd1ac8812"
|
|
52
52
|
}
|