@purespectrum1/purescore-client 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/lib/application/auto-init.d.ts +44 -0
- package/lib/application/auto-init.js +245 -0
- package/lib/application/device-identifier.d.ts +116 -0
- package/lib/application/device-identifier.js +169 -0
- package/lib/domain/models/crosscutting/device-intelligence.d.ts +11 -0
- package/lib/domain/models/crosscutting/device-intelligence.js +18 -0
- package/lib/domain/models/crosscutting/index.d.ts +1 -0
- package/lib/domain/models/crosscutting/index.js +17 -0
- package/lib/domain/protocols/cache/get-storage.d.ts +8 -0
- package/lib/domain/protocols/cache/get-storage.js +2 -0
- package/lib/domain/protocols/cache/index.d.ts +3 -0
- package/lib/domain/protocols/cache/index.js +19 -0
- package/lib/domain/protocols/cache/remove-storage.d.ts +6 -0
- package/lib/domain/protocols/cache/remove-storage.js +2 -0
- package/lib/domain/protocols/cache/set-storage.d.ts +7 -0
- package/lib/domain/protocols/cache/set-storage.js +2 -0
- package/lib/domain/protocols/http/http-client.d.ts +23 -0
- package/lib/domain/protocols/http/http-client.js +13 -0
- package/lib/domain/protocols/services/behavioural-biometrics/cursor-behavior.d.ts +63 -0
- package/lib/domain/protocols/services/behavioural-biometrics/cursor-behavior.js +2 -0
- package/lib/domain/protocols/services/behavioural-biometrics/index.d.ts +3 -0
- package/lib/domain/protocols/services/behavioural-biometrics/index.js +19 -0
- package/lib/domain/protocols/services/behavioural-biometrics/keystorke-metrics.d.ts +35 -0
- package/lib/domain/protocols/services/behavioural-biometrics/keystorke-metrics.js +2 -0
- package/lib/domain/protocols/services/behavioural-biometrics/touch-behavior.d.ts +88 -0
- package/lib/domain/protocols/services/behavioural-biometrics/touch-behavior.js +2 -0
- package/lib/domain/protocols/services/device-fingerprint/display.d.ts +22 -0
- package/lib/domain/protocols/services/device-fingerprint/display.js +2 -0
- package/lib/domain/protocols/services/device-fingerprint/index.d.ts +3 -0
- package/lib/domain/protocols/services/device-fingerprint/index.js +19 -0
- package/lib/domain/protocols/services/device-fingerprint/navigator.d.ts +63 -0
- package/lib/domain/protocols/services/device-fingerprint/navigator.js +2 -0
- package/lib/domain/protocols/services/device-fingerprint/utils.d.ts +40 -0
- package/lib/domain/protocols/services/device-fingerprint/utils.js +2 -0
- package/lib/domain/protocols/services/device-identifier.d.ts +96 -0
- package/lib/domain/protocols/services/device-identifier.js +2 -0
- package/lib/domain/protocols/services/device-intelligence.d.ts +5 -0
- package/lib/domain/protocols/services/device-intelligence.js +2 -0
- package/lib/domain/protocols/services/listeners.d.ts +9 -0
- package/lib/domain/protocols/services/listeners.js +2 -0
- package/lib/domain/protocols/services/single-script-injection/auto-init.d.ts +120 -0
- package/lib/domain/protocols/services/single-script-injection/auto-init.js +2 -0
- package/lib/domain/protocols/services/single-script-injection/index.d.ts +1 -0
- package/lib/domain/protocols/services/single-script-injection/index.js +17 -0
- package/lib/domain/services/behavioural-biometrics/collector.d.ts +94 -0
- package/lib/domain/services/behavioural-biometrics/collector.js +229 -0
- package/lib/domain/services/behavioural-biometrics/cursor-behavior.d.ts +87 -0
- package/lib/domain/services/behavioural-biometrics/cursor-behavior.js +369 -0
- package/lib/domain/services/behavioural-biometrics/index.d.ts +4 -0
- package/lib/domain/services/behavioural-biometrics/index.js +20 -0
- package/lib/domain/services/behavioural-biometrics/keystroke-metrics.d.ts +60 -0
- package/lib/domain/services/behavioural-biometrics/keystroke-metrics.js +213 -0
- package/lib/domain/services/behavioural-biometrics/touch-behavior.d.ts +125 -0
- package/lib/domain/services/behavioural-biometrics/touch-behavior.js +413 -0
- package/lib/domain/services/device-fingerprint/audio.d.ts +14 -0
- package/lib/domain/services/device-fingerprint/audio.js +109 -0
- package/lib/domain/services/device-fingerprint/canvas.d.ts +10 -0
- package/lib/domain/services/device-fingerprint/canvas.js +33 -0
- package/lib/domain/services/device-fingerprint/display.d.ts +49 -0
- package/lib/domain/services/device-fingerprint/display.js +88 -0
- package/lib/domain/services/device-fingerprint/hash.d.ts +14 -0
- package/lib/domain/services/device-fingerprint/hash.js +60 -0
- package/lib/domain/services/device-fingerprint/index.d.ts +8 -0
- package/lib/domain/services/device-fingerprint/index.js +24 -0
- package/lib/domain/services/device-fingerprint/navigator.d.ts +110 -0
- package/lib/domain/services/device-fingerprint/navigator.js +213 -0
- package/lib/domain/services/device-fingerprint/pointer-capability.d.ts +14 -0
- package/lib/domain/services/device-fingerprint/pointer-capability.js +42 -0
- package/lib/domain/services/device-fingerprint/storage.d.ts +44 -0
- package/lib/domain/services/device-fingerprint/storage.js +64 -0
- package/lib/domain/services/device-fingerprint/utils.d.ts +42 -0
- package/lib/domain/services/device-fingerprint/utils.js +95 -0
- package/lib/domain/services/device-intelligence.d.ts +10 -0
- package/lib/domain/services/device-intelligence.js +59 -0
- package/lib/domain/services/single-script-injection/checkpoint-scheduler.d.ts +37 -0
- package/lib/domain/services/single-script-injection/checkpoint-scheduler.js +94 -0
- package/lib/domain/services/single-script-injection/index.d.ts +3 -0
- package/lib/domain/services/single-script-injection/index.js +19 -0
- package/lib/domain/services/single-script-injection/response-delivery.d.ts +47 -0
- package/lib/domain/services/single-script-injection/response-delivery.js +115 -0
- package/lib/domain/services/single-script-injection/schedule-store.d.ts +69 -0
- package/lib/domain/services/single-script-injection/schedule-store.js +146 -0
- package/lib/domain/services/snapshot-store.d.ts +19 -0
- package/lib/domain/services/snapshot-store.js +36 -0
- package/lib/domain/services/spa-navigation.d.ts +15 -0
- package/lib/domain/services/spa-navigation.js +40 -0
- package/lib/index.d.ts +19 -0
- package/lib/index.js +27 -0
- package/lib/infra/cache/index.d.ts +3 -0
- package/lib/infra/cache/index.js +19 -0
- package/lib/infra/cache/local-storage-adapter.d.ts +8 -0
- package/lib/infra/cache/local-storage-adapter.js +14 -0
- package/lib/infra/cache/session-storage-adapter.d.ts +8 -0
- package/lib/infra/cache/session-storage-adapter.js +14 -0
- package/lib/infra/cache/web-storage-adapter.d.ts +13 -0
- package/lib/infra/cache/web-storage-adapter.js +33 -0
- package/lib/infra/http/axios-http-client.d.ts +4 -0
- package/lib/infra/http/axios-http-client.js +39 -0
- package/lib/validation/builder.d.ts +43 -0
- package/lib/validation/builder.js +85 -0
- package/lib/validation/composite.d.ts +13 -0
- package/lib/validation/composite.js +23 -0
- package/lib/validation/errors/index.d.ts +2 -0
- package/lib/validation/errors/index.js +18 -0
- package/lib/validation/errors/invalid-field-error.d.ts +7 -0
- package/lib/validation/errors/invalid-field-error.js +14 -0
- package/lib/validation/errors/required-field-error.d.ts +3 -0
- package/lib/validation/errors/required-field-error.js +10 -0
- package/lib/validation/index.d.ts +5 -0
- package/lib/validation/index.js +21 -0
- package/lib/validation/protocols/index.d.ts +1 -0
- package/lib/validation/protocols/index.js +17 -0
- package/lib/validation/protocols/validator.d.ts +11 -0
- package/lib/validation/protocols/validator.js +2 -0
- package/lib/validation/validators/behavioural-signal.d.ts +27 -0
- package/lib/validation/validators/behavioural-signal.js +56 -0
- package/lib/validation/validators/country-code.d.ts +14 -0
- package/lib/validation/validators/country-code.js +24 -0
- package/lib/validation/validators/global-function.d.ts +14 -0
- package/lib/validation/validators/global-function.js +29 -0
- package/lib/validation/validators/index.d.ts +9 -0
- package/lib/validation/validators/index.js +25 -0
- package/lib/validation/validators/interpolated-template.d.ts +14 -0
- package/lib/validation/validators/interpolated-template.js +28 -0
- package/lib/validation/validators/json-object.d.ts +14 -0
- package/lib/validation/validators/json-object.js +33 -0
- package/lib/validation/validators/language-code.d.ts +13 -0
- package/lib/validation/validators/language-code.js +23 -0
- package/lib/validation/validators/positive-number.d.ts +13 -0
- package/lib/validation/validators/positive-number.js +24 -0
- package/lib/validation/validators/required-string.d.ts +10 -0
- package/lib/validation/validators/required-string.js +19 -0
- package/lib/validation/validators/schedule-record.d.ts +26 -0
- package/lib/validation/validators/schedule-record.js +33 -0
- package/package.json +51 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare class Storage {
|
|
2
|
+
/**
|
|
3
|
+
* Returns an object with properties indicating the availability of different storage types.
|
|
4
|
+
*
|
|
5
|
+
* The returned object has the following properties:
|
|
6
|
+
* - `sessionStorage`: Whether session storage is available.
|
|
7
|
+
* - `localStorage`: Whether local storage is available.
|
|
8
|
+
* - `indexedDB`: Whether IndexedDB is available.
|
|
9
|
+
*
|
|
10
|
+
* @returns {object} An object with properties indicating the availability of different storage types.
|
|
11
|
+
* @example
|
|
12
|
+
* const storageProperties = getStorageProperties();
|
|
13
|
+
* console.log(storageProperties);
|
|
14
|
+
* // Output: { sessionStorage: true, localStorage: true, indexedDB: true }
|
|
15
|
+
*/
|
|
16
|
+
getStorageProperties(): {
|
|
17
|
+
sessionStorage: boolean;
|
|
18
|
+
localStorage: boolean;
|
|
19
|
+
indexedDB: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Checks if local storage is available.
|
|
23
|
+
*
|
|
24
|
+
* This function returns `true` if local storage is available, and `false` otherwise.
|
|
25
|
+
* Note that if a `SecurityError` is thrown when trying to access `window.localStorage`,
|
|
26
|
+
* it means that local storage exists, but is not accessible due to security restrictions.
|
|
27
|
+
* @returns {boolean} Whether local storage is available.
|
|
28
|
+
* @example
|
|
29
|
+
* const hasLocalStorage = hasLocalStorage(); // true if local storage is available, false otherwise
|
|
30
|
+
*/
|
|
31
|
+
private _hasLocalStorage;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if session storage is available.
|
|
34
|
+
*
|
|
35
|
+
* This function returns `true` if session storage is available, and `false` otherwise.
|
|
36
|
+
* Note that if a `SecurityError` is thrown when trying to access `window.sessionStorage`,
|
|
37
|
+
* it means that session storage exists, but is not accessible due to security restrictions.
|
|
38
|
+
*
|
|
39
|
+
* @returns {boolean} Whether session storage is available.
|
|
40
|
+
* @example
|
|
41
|
+
* const hasSessionStorage = hasSessionStorage(); // true if session storage is available, false otherwise
|
|
42
|
+
*/
|
|
43
|
+
private _hasSessionStorage;
|
|
44
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Storage = void 0;
|
|
4
|
+
class Storage {
|
|
5
|
+
/**
|
|
6
|
+
* Returns an object with properties indicating the availability of different storage types.
|
|
7
|
+
*
|
|
8
|
+
* The returned object has the following properties:
|
|
9
|
+
* - `sessionStorage`: Whether session storage is available.
|
|
10
|
+
* - `localStorage`: Whether local storage is available.
|
|
11
|
+
* - `indexedDB`: Whether IndexedDB is available.
|
|
12
|
+
*
|
|
13
|
+
* @returns {object} An object with properties indicating the availability of different storage types.
|
|
14
|
+
* @example
|
|
15
|
+
* const storageProperties = getStorageProperties();
|
|
16
|
+
* console.log(storageProperties);
|
|
17
|
+
* // Output: { sessionStorage: true, localStorage: true, indexedDB: true }
|
|
18
|
+
*/
|
|
19
|
+
getStorageProperties() {
|
|
20
|
+
return {
|
|
21
|
+
sessionStorage: this._hasSessionStorage(),
|
|
22
|
+
localStorage: this._hasLocalStorage(),
|
|
23
|
+
indexedDB: !!window.indexedDB,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Checks if local storage is available.
|
|
28
|
+
*
|
|
29
|
+
* This function returns `true` if local storage is available, and `false` otherwise.
|
|
30
|
+
* Note that if a `SecurityError` is thrown when trying to access `window.localStorage`,
|
|
31
|
+
* it means that local storage exists, but is not accessible due to security restrictions.
|
|
32
|
+
* @returns {boolean} Whether local storage is available.
|
|
33
|
+
* @example
|
|
34
|
+
* const hasLocalStorage = hasLocalStorage(); // true if local storage is available, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
_hasLocalStorage() {
|
|
37
|
+
try {
|
|
38
|
+
return !!window.localStorage;
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
return true; // SecurityError when referencing it means it exists
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Checks if session storage is available.
|
|
46
|
+
*
|
|
47
|
+
* This function returns `true` if session storage is available, and `false` otherwise.
|
|
48
|
+
* Note that if a `SecurityError` is thrown when trying to access `window.sessionStorage`,
|
|
49
|
+
* it means that session storage exists, but is not accessible due to security restrictions.
|
|
50
|
+
*
|
|
51
|
+
* @returns {boolean} Whether session storage is available.
|
|
52
|
+
* @example
|
|
53
|
+
* const hasSessionStorage = hasSessionStorage(); // true if session storage is available, false otherwise
|
|
54
|
+
*/
|
|
55
|
+
_hasSessionStorage() {
|
|
56
|
+
try {
|
|
57
|
+
return !!window.sessionStorage;
|
|
58
|
+
}
|
|
59
|
+
catch (_a) {
|
|
60
|
+
return true; // SecurityError when referencing it means it exists
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.Storage = Storage;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { NetworkTimes } from "../../protocols/services/device-fingerprint/utils";
|
|
2
|
+
export declare class Utils {
|
|
3
|
+
/**
|
|
4
|
+
* Gets the timezone offset of the current browser.
|
|
5
|
+
*
|
|
6
|
+
* @returns {number} The timezone offset in hours.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const timezoneOffset = getTimezoneOffset();
|
|
10
|
+
* console.log(timezoneOffset); // Output: -5 or 3
|
|
11
|
+
*/
|
|
12
|
+
getTimezoneOffset(): number;
|
|
13
|
+
/**
|
|
14
|
+
* Checks if touch events are supported in the current browser.
|
|
15
|
+
*
|
|
16
|
+
* @returns {boolean} True if touch events are supported, false otherwise.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const touchSupported = getTouchSupport();
|
|
20
|
+
* console.log(touchSupported); // Output: true or false
|
|
21
|
+
*/
|
|
22
|
+
getTouchSupport(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Gets network timing data for the current page load.
|
|
25
|
+
*
|
|
26
|
+
* @returns {NetworkTimes} An object containing network timing data.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const networkTimes = getNetworkTime();
|
|
30
|
+
* console.log(networkTimes);
|
|
31
|
+
* // Output:
|
|
32
|
+
* // {
|
|
33
|
+
* // networkTime: 1.234,
|
|
34
|
+
* // dnsLookupTime: 0.123,
|
|
35
|
+
* // tcpConnectionTime: 0.234,
|
|
36
|
+
* // serverResponseTime: 0.345,
|
|
37
|
+
* // pageDownloadTime: 0.456,
|
|
38
|
+
* // browserTime: 1.567
|
|
39
|
+
* // }
|
|
40
|
+
*/
|
|
41
|
+
getNetworkTime(): NetworkTimes;
|
|
42
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Utils = void 0;
|
|
4
|
+
class Utils {
|
|
5
|
+
/**
|
|
6
|
+
* Gets the timezone offset of the current browser.
|
|
7
|
+
*
|
|
8
|
+
* @returns {number} The timezone offset in hours.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const timezoneOffset = getTimezoneOffset();
|
|
12
|
+
* console.log(timezoneOffset); // Output: -5 or 3
|
|
13
|
+
*/
|
|
14
|
+
getTimezoneOffset() {
|
|
15
|
+
const dtDate = new Date();
|
|
16
|
+
return -dtDate.getTimezoneOffset() / 60;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Checks if touch events are supported in the current browser.
|
|
20
|
+
*
|
|
21
|
+
* @returns {boolean} True if touch events are supported, false otherwise.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const touchSupported = getTouchSupport();
|
|
25
|
+
* console.log(touchSupported); // Output: true or false
|
|
26
|
+
*/
|
|
27
|
+
getTouchSupport() {
|
|
28
|
+
try {
|
|
29
|
+
if (typeof navigator !== 'undefined' && typeof navigator.maxTouchPoints === 'number'
|
|
30
|
+
&& navigator.maxTouchPoints > 0) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (typeof window !== 'undefined' && 'ontouchstart' in window) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
|
37
|
+
&& window.matchMedia('(any-pointer: coarse)').matches) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return typeof document !== 'undefined' && !!document.createEvent('TouchEvent');
|
|
41
|
+
}
|
|
42
|
+
catch (_a) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Gets network timing data for the current page load.
|
|
48
|
+
*
|
|
49
|
+
* @returns {NetworkTimes} An object containing network timing data.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* const networkTimes = getNetworkTime();
|
|
53
|
+
* console.log(networkTimes);
|
|
54
|
+
* // Output:
|
|
55
|
+
* // {
|
|
56
|
+
* // networkTime: 1.234,
|
|
57
|
+
* // dnsLookupTime: 0.123,
|
|
58
|
+
* // tcpConnectionTime: 0.234,
|
|
59
|
+
* // serverResponseTime: 0.345,
|
|
60
|
+
* // pageDownloadTime: 0.456,
|
|
61
|
+
* // browserTime: 1.567
|
|
62
|
+
* // }
|
|
63
|
+
*/
|
|
64
|
+
getNetworkTime() {
|
|
65
|
+
try {
|
|
66
|
+
const navigationTiming = performance.getEntriesByType('navigation')[0];
|
|
67
|
+
const networkTime = navigationTiming.responseEnd - navigationTiming.fetchStart;
|
|
68
|
+
const dnsLookupTime = navigationTiming.domainLookupEnd - navigationTiming.domainLookupStart;
|
|
69
|
+
const tcpConnectionTime = navigationTiming.connectEnd - navigationTiming.connectStart;
|
|
70
|
+
const serverResponseTime = navigationTiming.responseStart - navigationTiming.requestStart;
|
|
71
|
+
const pageDownloadTime = navigationTiming.responseEnd - navigationTiming.responseStart;
|
|
72
|
+
const browserTime = navigationTiming.loadEventEnd - navigationTiming.fetchStart;
|
|
73
|
+
return {
|
|
74
|
+
networkTime: Number((networkTime / 1000).toFixed(3)),
|
|
75
|
+
dnsLookupTime: Number((dnsLookupTime / 1000).toFixed(3)),
|
|
76
|
+
tcpConnectionTime: Number((tcpConnectionTime / 1000).toFixed(3)),
|
|
77
|
+
serverResponseTime: Number((serverResponseTime / 1000).toFixed(3)),
|
|
78
|
+
pageDownloadTime: Number((pageDownloadTime / 1000).toFixed(3)),
|
|
79
|
+
browserTime: Number((browserTime / 1000).toFixed(3))
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.error("Failed to retrieve network timing data:", err);
|
|
84
|
+
return {
|
|
85
|
+
networkTime: 0,
|
|
86
|
+
dnsLookupTime: 0,
|
|
87
|
+
tcpConnectionTime: 0,
|
|
88
|
+
serverResponseTime: 0,
|
|
89
|
+
pageDownloadTime: 0,
|
|
90
|
+
browserTime: 0
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.Utils = Utils;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DeviceIdentifierConfig } from "../protocols/services/device-identifier";
|
|
2
|
+
import { HttpClient, HttpMethod } from "../protocols/http/http-client";
|
|
3
|
+
import { DeviceIntelligenceHTTPRequest } from "../protocols/services/device-intelligence";
|
|
4
|
+
export declare class DeviceIntelligenceService implements DeviceIntelligenceHTTPRequest {
|
|
5
|
+
private httpClient;
|
|
6
|
+
private baseUrl;
|
|
7
|
+
private token;
|
|
8
|
+
constructor(httpClient: HttpClient, baseUrl: string, token: string);
|
|
9
|
+
performRequest(patch: string, method: HttpMethod, config?: DeviceIdentifierConfig, data?: any): Promise<any>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DeviceIntelligenceService = void 0;
|
|
13
|
+
const crosscutting_1 = require("../models/crosscutting");
|
|
14
|
+
class DeviceIntelligenceService {
|
|
15
|
+
constructor(httpClient, baseUrl, token) {
|
|
16
|
+
this.httpClient = httpClient;
|
|
17
|
+
this.baseUrl = baseUrl || '';
|
|
18
|
+
this.token = token || '';
|
|
19
|
+
}
|
|
20
|
+
performRequest(patch_1, method_1) {
|
|
21
|
+
return __awaiter(this, arguments, void 0, function* (patch, method, config = {}, data) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
try {
|
|
24
|
+
const { token = '', env = 'staging' } = config;
|
|
25
|
+
const missingTransactionId = 'transactionId' in (data !== null && data !== void 0 ? data : {}) && !data.transactionId;
|
|
26
|
+
if (missingTransactionId || (!config.token && !this.token)) {
|
|
27
|
+
throw new Error('TransactionId or Authentication Token missing');
|
|
28
|
+
}
|
|
29
|
+
const isProductionEnv = env.toLowerCase() === 'production';
|
|
30
|
+
if (isProductionEnv) {
|
|
31
|
+
this.baseUrl = crosscutting_1.PURESCORE_INTELLIGENCE_BASE_URL.production;
|
|
32
|
+
}
|
|
33
|
+
const response = yield this.httpClient.request({
|
|
34
|
+
url: `${this.baseUrl}${patch}`,
|
|
35
|
+
method,
|
|
36
|
+
body: data,
|
|
37
|
+
headers: {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
Authorization: `Bearer ${token || this.token}`
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (!response.body) {
|
|
43
|
+
throw new Error(`Empty response with status: ${response.statusCode}`);
|
|
44
|
+
}
|
|
45
|
+
return { statusCode: response.statusCode, body: response.body };
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
const errorResponse = {
|
|
49
|
+
statusCode: (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status,
|
|
50
|
+
message: error.message,
|
|
51
|
+
body: (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.data,
|
|
52
|
+
};
|
|
53
|
+
console.error('Error performing Device Intelligence request:', errorResponse);
|
|
54
|
+
return errorResponse;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.DeviceIntelligenceService = DeviceIntelligenceService;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ScheduleRecord } from '../../protocols/services/single-script-injection/auto-init';
|
|
2
|
+
import { ScheduleStore } from './schedule-store';
|
|
3
|
+
/**
|
|
4
|
+
* How often the scheduler asks "is a checkpoint due yet?".
|
|
5
|
+
*
|
|
6
|
+
* Polling rather than a `setTimeout` per checkpoint because the schedule is
|
|
7
|
+
* shared state that another page load may have advanced: a timer armed on this
|
|
8
|
+
* page would not know that a checkpoint had already been delivered elsewhere.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TICK_MS = 5000;
|
|
11
|
+
type CheckpointHandler = (n: number, record: ScheduleRecord) => Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Drives the Device-Intelligence calls off the schedule record.
|
|
14
|
+
*
|
|
15
|
+
* Every tick it resolves the next outstanding checkpoint and fires it if its due
|
|
16
|
+
* time has passed; otherwise it keeps waiting. Once every checkpoint of the
|
|
17
|
+
* transaction has been delivered the scheduler stops itself, capping the
|
|
18
|
+
* transaction at `CHECKPOINT_COUNT`.
|
|
19
|
+
*/
|
|
20
|
+
export declare class CheckpointScheduler {
|
|
21
|
+
private readonly store;
|
|
22
|
+
private readonly onCheckpoint;
|
|
23
|
+
private timer;
|
|
24
|
+
private inFlight;
|
|
25
|
+
constructor(store: ScheduleStore, onCheckpoint: CheckpointHandler);
|
|
26
|
+
/**
|
|
27
|
+
* Resumes (or starts) the schedule and begins polling. The first tick runs
|
|
28
|
+
* immediately so a checkpoint already overdue is not delayed another `TICK_MS`.
|
|
29
|
+
*/
|
|
30
|
+
start(): ScheduleRecord;
|
|
31
|
+
stop(): void;
|
|
32
|
+
isRunning(): boolean;
|
|
33
|
+
/** Fires a tick without letting its promise escape as an unhandled rejection. */
|
|
34
|
+
private runTick;
|
|
35
|
+
private tick;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CheckpointScheduler = exports.TICK_MS = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* How often the scheduler asks "is a checkpoint due yet?".
|
|
15
|
+
*
|
|
16
|
+
* Polling rather than a `setTimeout` per checkpoint because the schedule is
|
|
17
|
+
* shared state that another page load may have advanced: a timer armed on this
|
|
18
|
+
* page would not know that a checkpoint had already been delivered elsewhere.
|
|
19
|
+
*/
|
|
20
|
+
exports.TICK_MS = 5000;
|
|
21
|
+
/**
|
|
22
|
+
* Drives the Device-Intelligence calls off the schedule record.
|
|
23
|
+
*
|
|
24
|
+
* Every tick it resolves the next outstanding checkpoint and fires it if its due
|
|
25
|
+
* time has passed; otherwise it keeps waiting. Once every checkpoint of the
|
|
26
|
+
* transaction has been delivered the scheduler stops itself, capping the
|
|
27
|
+
* transaction at `CHECKPOINT_COUNT`.
|
|
28
|
+
*/
|
|
29
|
+
class CheckpointScheduler {
|
|
30
|
+
constructor(store, onCheckpoint) {
|
|
31
|
+
this.store = store;
|
|
32
|
+
this.onCheckpoint = onCheckpoint;
|
|
33
|
+
this.timer = null;
|
|
34
|
+
this.inFlight = false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resumes (or starts) the schedule and begins polling. The first tick runs
|
|
38
|
+
* immediately so a checkpoint already overdue is not delayed another `TICK_MS`.
|
|
39
|
+
*/
|
|
40
|
+
start() {
|
|
41
|
+
this.stop();
|
|
42
|
+
const record = this.store.resumeOrCreate();
|
|
43
|
+
this.runTick();
|
|
44
|
+
this.timer = setInterval(() => this.runTick(), exports.TICK_MS);
|
|
45
|
+
return record;
|
|
46
|
+
}
|
|
47
|
+
stop() {
|
|
48
|
+
if (this.timer !== null) {
|
|
49
|
+
clearInterval(this.timer);
|
|
50
|
+
this.timer = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
isRunning() {
|
|
54
|
+
return this.timer !== null;
|
|
55
|
+
}
|
|
56
|
+
/** Fires a tick without letting its promise escape as an unhandled rejection. */
|
|
57
|
+
runTick() {
|
|
58
|
+
this.tick().catch(error => console.error('Error in Device-Intelligence checkpoint tick:', error));
|
|
59
|
+
}
|
|
60
|
+
tick() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
// A call already in flight owns the next checkpoint; a second tick must not
|
|
63
|
+
// fire it again while the request is still resolving.
|
|
64
|
+
if (this.inFlight)
|
|
65
|
+
return;
|
|
66
|
+
const record = this.store.resumeOrCreate();
|
|
67
|
+
const next = record.checkpoints.find(c => c.n > record.sent);
|
|
68
|
+
if (!next) {
|
|
69
|
+
// Nothing left, and nothing can appear: the LOI checkpoints are added
|
|
70
|
+
// before the schedule starts.
|
|
71
|
+
this.stop();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (new Date().getTime() < next.dueAt)
|
|
75
|
+
return;
|
|
76
|
+
this.inFlight = true;
|
|
77
|
+
try {
|
|
78
|
+
yield this.onCheckpoint(next.n, record);
|
|
79
|
+
// Persisted only after the call resolves, so a failed request leaves the
|
|
80
|
+
// checkpoint outstanding and the next tick retries it.
|
|
81
|
+
this.store.markSent(next.n);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// Swallowed on purpose: a rejected checkpoint must not surface as an
|
|
85
|
+
// unhandled rejection on the buyer's survey page.
|
|
86
|
+
console.error(`Error delivering Device-Intelligence checkpoint ${next.n}:`, error);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
this.inFlight = false;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.CheckpointScheduler = CheckpointScheduler;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./checkpoint-scheduler"), exports);
|
|
18
|
+
__exportStar(require("./response-delivery"), exports);
|
|
19
|
+
__exportStar(require("./schedule-store"), exports);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Name of the custom event carrying the Device-Intelligence response.
|
|
3
|
+
*
|
|
4
|
+
* The `ps:` prefix namespaces it so it cannot collide with an event the buyer's
|
|
5
|
+
* own survey platform dispatches.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PS_RESULT_EVENT = "ps:purescore:result";
|
|
8
|
+
/**
|
|
9
|
+
* Global the last response is also exposed on, for buyers who prefer reading it
|
|
10
|
+
* directly rather than listening.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PS_GLOBAL = "psPureScore";
|
|
13
|
+
/**
|
|
14
|
+
* Hands the Device-Intelligence response back to the buyer.
|
|
15
|
+
*
|
|
16
|
+
* Once the Device-Identifier owns the call it also owns the response, so it has
|
|
17
|
+
* to push it out. Three channels carry the same object and the buyer picks
|
|
18
|
+
* whichever suits their platform:
|
|
19
|
+
*
|
|
20
|
+
* - a `ps:purescore:result` CustomEvent on `window` (any number of listeners);
|
|
21
|
+
* - a global function named on the tag via `data-callback`;
|
|
22
|
+
* - `window.psPureScore.lastResult`, for code that would rather read than listen.
|
|
23
|
+
*/
|
|
24
|
+
export declare class ResponseDeliveryService {
|
|
25
|
+
private readonly callbackName?;
|
|
26
|
+
constructor(callbackName?: string | undefined);
|
|
27
|
+
/**
|
|
28
|
+
* Delivers a response that has just arrived, on every channel.
|
|
29
|
+
*/
|
|
30
|
+
deliver(response: Record<string, any>): void;
|
|
31
|
+
/**
|
|
32
|
+
* Re-emits a response that was produced on an earlier page (the replay buffer).
|
|
33
|
+
*
|
|
34
|
+
* Because the checkpoints now fire on the schedule rather than at a point the
|
|
35
|
+
* buyer chose, the call and the buyer's code are no longer guaranteed to be on
|
|
36
|
+
* the same page. The global is published synchronously — it is a read, so it
|
|
37
|
+
* has to be there before the buyer's code runs — while the event and the
|
|
38
|
+
* callback are deferred until the document has finished parsing, giving a
|
|
39
|
+
* listener or function declared further down the page a chance to exist.
|
|
40
|
+
*/
|
|
41
|
+
replay(response: Record<string, any>): void;
|
|
42
|
+
private publishGlobal;
|
|
43
|
+
private dispatch;
|
|
44
|
+
private invokeCallback;
|
|
45
|
+
private buildEvent;
|
|
46
|
+
private whenDocumentReady;
|
|
47
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResponseDeliveryService = exports.PS_GLOBAL = exports.PS_RESULT_EVENT = void 0;
|
|
4
|
+
const validation_1 = require("../../../validation");
|
|
5
|
+
/**
|
|
6
|
+
* Name of the custom event carrying the Device-Intelligence response.
|
|
7
|
+
*
|
|
8
|
+
* The `ps:` prefix namespaces it so it cannot collide with an event the buyer's
|
|
9
|
+
* own survey platform dispatches.
|
|
10
|
+
*/
|
|
11
|
+
exports.PS_RESULT_EVENT = 'ps:purescore:result';
|
|
12
|
+
/**
|
|
13
|
+
* Global the last response is also exposed on, for buyers who prefer reading it
|
|
14
|
+
* directly rather than listening.
|
|
15
|
+
*/
|
|
16
|
+
exports.PS_GLOBAL = 'psPureScore';
|
|
17
|
+
/**
|
|
18
|
+
* Hands the Device-Intelligence response back to the buyer.
|
|
19
|
+
*
|
|
20
|
+
* Once the Device-Identifier owns the call it also owns the response, so it has
|
|
21
|
+
* to push it out. Three channels carry the same object and the buyer picks
|
|
22
|
+
* whichever suits their platform:
|
|
23
|
+
*
|
|
24
|
+
* - a `ps:purescore:result` CustomEvent on `window` (any number of listeners);
|
|
25
|
+
* - a global function named on the tag via `data-callback`;
|
|
26
|
+
* - `window.psPureScore.lastResult`, for code that would rather read than listen.
|
|
27
|
+
*/
|
|
28
|
+
class ResponseDeliveryService {
|
|
29
|
+
constructor(callbackName) {
|
|
30
|
+
this.callbackName = callbackName;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Delivers a response that has just arrived, on every channel.
|
|
34
|
+
*/
|
|
35
|
+
deliver(response) {
|
|
36
|
+
if (typeof window === 'undefined')
|
|
37
|
+
return;
|
|
38
|
+
this.publishGlobal(response);
|
|
39
|
+
this.dispatch(response);
|
|
40
|
+
this.invokeCallback(response);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Re-emits a response that was produced on an earlier page (the replay buffer).
|
|
44
|
+
*
|
|
45
|
+
* Because the checkpoints now fire on the schedule rather than at a point the
|
|
46
|
+
* buyer chose, the call and the buyer's code are no longer guaranteed to be on
|
|
47
|
+
* the same page. The global is published synchronously — it is a read, so it
|
|
48
|
+
* has to be there before the buyer's code runs — while the event and the
|
|
49
|
+
* callback are deferred until the document has finished parsing, giving a
|
|
50
|
+
* listener or function declared further down the page a chance to exist.
|
|
51
|
+
*/
|
|
52
|
+
replay(response) {
|
|
53
|
+
if (typeof window === 'undefined')
|
|
54
|
+
return;
|
|
55
|
+
this.publishGlobal(response);
|
|
56
|
+
this.whenDocumentReady(() => {
|
|
57
|
+
this.dispatch(response);
|
|
58
|
+
this.invokeCallback(response);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
publishGlobal(response) {
|
|
62
|
+
var _a;
|
|
63
|
+
try {
|
|
64
|
+
const globals = (_a = window[exports.PS_GLOBAL]) !== null && _a !== void 0 ? _a : {};
|
|
65
|
+
globals.lastResult = response;
|
|
66
|
+
window[exports.PS_GLOBAL] = globals;
|
|
67
|
+
}
|
|
68
|
+
catch ( /* never let delivery bookkeeping break the survey page */_b) { /* never let delivery bookkeeping break the survey page */ }
|
|
69
|
+
}
|
|
70
|
+
dispatch(response) {
|
|
71
|
+
try {
|
|
72
|
+
window.dispatchEvent(this.buildEvent(response));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('Error dispatching PureScore result event:', error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
invokeCallback(response) {
|
|
79
|
+
if (!this.callbackName)
|
|
80
|
+
return;
|
|
81
|
+
const error = new validation_1.GlobalFunction(this.callbackName, 'data-callback').validate();
|
|
82
|
+
if (error) {
|
|
83
|
+
console.error(`PureScore callback: ${error.message}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const fn = window[this.callbackName];
|
|
87
|
+
try {
|
|
88
|
+
fn(response);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error(`Error in PureScore callback "${this.callbackName}":`, error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
buildEvent(response) {
|
|
95
|
+
try {
|
|
96
|
+
return new CustomEvent(exports.PS_RESULT_EVENT, { detail: response });
|
|
97
|
+
}
|
|
98
|
+
catch (_a) {
|
|
99
|
+
// Older browsers where CustomEvent is not constructible.
|
|
100
|
+
const event = document.createEvent('CustomEvent');
|
|
101
|
+
event.initCustomEvent(exports.PS_RESULT_EVENT, false, false, response);
|
|
102
|
+
return event;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
whenDocumentReady(run) {
|
|
106
|
+
if (typeof document === 'undefined' || document.readyState !== 'loading') {
|
|
107
|
+
// Already parsed: still defer by a macrotask so an inline listener placed
|
|
108
|
+
// right after the tag is registered before the replay fires.
|
|
109
|
+
setTimeout(run, 0);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
document.addEventListener('DOMContentLoaded', () => run(), { once: true });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.ResponseDeliveryService = ResponseDeliveryService;
|