@zoho_apptics/apptics-js-sdk 2.0.0-beta → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +191 -21
- package/README.md +519 -333
- package/dist/apptics.esm.min.js +2 -2
- package/dist/apptics.esm.min.js.map +1 -1
- package/dist/apptics.min.js +2 -2
- package/dist/apptics.min.js.map +1 -1
- package/dist/chunks/lifecycle-C6m1W7jo.min.js +3 -0
- package/dist/chunks/lifecycle-C6m1W7jo.min.js.map +1 -0
- package/dist/chunks/send-CgUO82ne.min.js +3 -0
- package/dist/chunks/send-CgUO82ne.min.js.map +1 -0
- package/dist/cjs/core/attempts.js +1 -1
- package/dist/cjs/core/batch.js +2 -2
- package/dist/cjs/core/consent.d.ts +18 -4
- package/dist/cjs/core/consent.js +31 -15
- package/dist/cjs/core/constants.d.ts +57 -27
- package/dist/cjs/core/constants.js +52 -33
- package/dist/cjs/core/db.d.ts +12 -4
- package/dist/cjs/core/db.js +167 -34
- package/dist/cjs/core/debug.js +1 -1
- package/dist/cjs/core/env.d.ts +0 -3
- package/dist/cjs/core/env.js +1 -9
- package/dist/cjs/core/framework-id.d.ts +1 -1
- package/dist/cjs/core/framework-id.js +3 -3
- package/dist/cjs/core/guard.d.ts +9 -0
- package/dist/cjs/core/guard.js +27 -13
- package/dist/cjs/core/hooks.d.ts +7 -4
- package/dist/cjs/core/hooks.js +3 -3
- package/dist/cjs/core/locks.d.ts +9 -0
- package/dist/cjs/core/locks.js +22 -0
- package/dist/cjs/core/logger.d.ts +3 -4
- package/dist/cjs/core/logger.js +4 -40
- package/dist/cjs/core/state.d.ts +9 -6
- package/dist/cjs/core/state.js +3 -5
- package/dist/cjs/core/storage.d.ts +20 -5
- package/dist/cjs/core/storage.js +115 -20
- package/dist/cjs/core/stylesheet.d.ts +8 -0
- package/dist/cjs/core/stylesheet.js +29 -0
- package/dist/cjs/core/transport.d.ts +2 -0
- package/dist/cjs/core/transport.js +30 -18
- package/dist/cjs/core/utils.js +1 -1
- package/dist/cjs/core/validate.js +2 -2
- package/dist/cjs/device/appversion.d.ts +10 -6
- package/dist/cjs/device/appversion.js +38 -3
- package/dist/cjs/device/index.d.ts +28 -2
- package/dist/cjs/device/index.js +312 -44
- package/dist/cjs/engagement/api-rules.d.ts +32 -67
- package/dist/cjs/engagement/api-rules.js +144 -157
- package/dist/cjs/engagement/auto-api.js +2 -2
- package/dist/cjs/engagement/auto-screen.d.ts +2 -0
- package/dist/cjs/engagement/auto-screen.js +67 -3
- package/dist/cjs/engagement/defined-events.js +1 -1
- package/dist/cjs/engagement/send.js +12 -3
- package/dist/cjs/engagement/session.d.ts +29 -3
- package/dist/cjs/engagement/session.js +253 -26
- package/dist/cjs/engagement/track.d.ts +4 -4
- package/dist/cjs/engagement/track.js +58 -30
- package/dist/cjs/errors/send.js +2 -2
- package/dist/cjs/errors/track.d.ts +2 -1
- package/dist/cjs/errors/track.js +49 -7
- package/dist/cjs/feedback/controls.d.ts +12 -0
- package/dist/cjs/feedback/controls.js +104 -25
- package/dist/cjs/feedback/index.d.ts +8 -7
- package/dist/cjs/feedback/index.js +32 -13
- package/dist/cjs/feedback/logs.d.ts +13 -11
- package/dist/cjs/feedback/logs.js +57 -28
- package/dist/cjs/feedback/quartz.d.ts +18 -0
- package/dist/cjs/feedback/quartz.js +105 -0
- package/dist/cjs/feedback/send.d.ts +5 -2
- package/dist/cjs/feedback/send.js +30 -28
- package/dist/cjs/feedback/styles.d.ts +10 -0
- package/dist/cjs/feedback/styles.js +8 -0
- package/dist/cjs/feedback/template.d.ts +1 -1
- package/dist/cjs/feedback/template.js +20 -12
- package/dist/cjs/feedback/ui.d.ts +21 -6
- package/dist/cjs/feedback/ui.js +283 -70
- package/dist/cjs/heatmap/send.d.ts +2 -0
- package/dist/cjs/heatmap/send.js +3 -5
- package/dist/cjs/heatmap/track.d.ts +1 -1
- package/dist/cjs/heatmap/track.js +87 -16
- package/dist/cjs/index.d.ts +16 -63
- package/dist/cjs/index.js +144 -95
- package/dist/cjs/lifecycle.d.ts +21 -3
- package/dist/cjs/lifecycle.js +353 -89
- package/dist/cjs/remoteconfig/country.d.ts +4 -0
- package/dist/cjs/remoteconfig/country.js +73 -0
- package/dist/cjs/remoteconfig/custom.d.ts +7 -7
- package/dist/cjs/remoteconfig/custom.js +31 -51
- package/dist/cjs/remoteconfig/evaluate.d.ts +3 -3
- package/dist/cjs/remoteconfig/evaluate.js +56 -43
- package/dist/cjs/remoteconfig/fetch.d.ts +16 -9
- package/dist/cjs/remoteconfig/fetch.js +120 -39
- package/dist/cjs/remoteconfig/index.d.ts +19 -8
- package/dist/cjs/remoteconfig/index.js +81 -39
- package/dist/cjs/remoteconfig/store.d.ts +15 -7
- package/dist/cjs/remoteconfig/store.js +68 -35
- package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/cjs/remoteconfig/tz-countries.js +13 -0
- package/dist/{esm/core → cjs/remotelog}/callsite.d.ts +11 -4
- package/dist/cjs/{core → remotelog}/callsite.js +30 -7
- package/dist/cjs/remotelog/gate.d.ts +2 -11
- package/dist/cjs/remotelog/gate.js +9 -35
- package/dist/cjs/remotelog/index.d.ts +4 -21
- package/dist/cjs/remotelog/logger.d.ts +11 -17
- package/dist/cjs/remotelog/logger.js +31 -59
- package/dist/cjs/remotelog/send.js +11 -11
- package/dist/cjs/remotelogger/index.d.ts +12 -0
- package/dist/cjs/remotelogger/index.js +18 -0
- package/dist/cjs/scheduler.d.ts +3 -1
- package/dist/cjs/scheduler.js +25 -22
- package/dist/cjs/types.d.ts +208 -90
- package/dist/cjs/user/index.js +16 -7
- package/dist/esm/core/attempts.js +1 -1
- package/dist/esm/core/batch.js +2 -2
- package/dist/esm/core/consent.d.ts +18 -4
- package/dist/esm/core/consent.js +32 -17
- package/dist/esm/core/constants.d.ts +57 -27
- package/dist/esm/core/constants.js +51 -33
- package/dist/esm/core/db.d.ts +12 -4
- package/dist/esm/core/db.js +164 -35
- package/dist/esm/core/debug.js +1 -1
- package/dist/esm/core/env.d.ts +0 -3
- package/dist/esm/core/env.js +2 -9
- package/dist/esm/core/framework-id.d.ts +1 -1
- package/dist/esm/core/framework-id.js +3 -3
- package/dist/esm/core/guard.d.ts +9 -0
- package/dist/esm/core/guard.js +27 -14
- package/dist/esm/core/hooks.d.ts +7 -4
- package/dist/esm/core/hooks.js +3 -3
- package/dist/esm/core/locks.d.ts +9 -0
- package/dist/esm/core/locks.js +20 -0
- package/dist/esm/core/logger.d.ts +3 -4
- package/dist/esm/core/logger.js +4 -40
- package/dist/esm/core/state.d.ts +9 -6
- package/dist/esm/core/state.js +3 -5
- package/dist/esm/core/storage.d.ts +20 -5
- package/dist/esm/core/storage.js +113 -21
- package/dist/esm/core/stylesheet.d.ts +8 -0
- package/dist/esm/core/stylesheet.js +27 -0
- package/dist/esm/core/transport.d.ts +2 -0
- package/dist/esm/core/transport.js +30 -19
- package/dist/esm/core/utils.js +1 -1
- package/dist/esm/core/validate.js +2 -2
- package/dist/esm/device/appversion.d.ts +10 -6
- package/dist/esm/device/appversion.js +37 -4
- package/dist/esm/device/index.d.ts +28 -2
- package/dist/esm/device/index.js +313 -49
- package/dist/esm/engagement/api-rules.d.ts +32 -67
- package/dist/esm/engagement/api-rules.js +143 -155
- package/dist/esm/engagement/auto-api.js +3 -3
- package/dist/esm/engagement/auto-screen.d.ts +2 -0
- package/dist/esm/engagement/auto-screen.js +67 -4
- package/dist/esm/engagement/defined-events.js +1 -1
- package/dist/esm/engagement/send.js +12 -3
- package/dist/esm/engagement/session.d.ts +29 -3
- package/dist/esm/engagement/session.js +251 -30
- package/dist/esm/engagement/track.d.ts +4 -4
- package/dist/esm/engagement/track.js +65 -37
- package/dist/esm/errors/send.js +2 -2
- package/dist/esm/errors/track.d.ts +2 -1
- package/dist/esm/errors/track.js +49 -7
- package/dist/esm/feedback/controls.d.ts +12 -0
- package/dist/esm/feedback/controls.js +103 -26
- package/dist/esm/feedback/index.d.ts +8 -7
- package/dist/esm/feedback/index.js +34 -13
- package/dist/esm/feedback/logs.d.ts +13 -11
- package/dist/esm/feedback/logs.js +59 -30
- package/dist/esm/feedback/quartz.d.ts +18 -0
- package/dist/esm/feedback/quartz.js +99 -0
- package/dist/esm/feedback/send.d.ts +5 -2
- package/dist/esm/feedback/send.js +31 -31
- package/dist/esm/feedback/styles.d.ts +10 -0
- package/dist/esm/feedback/styles.js +4 -0
- package/dist/esm/feedback/template.d.ts +1 -1
- package/dist/esm/feedback/template.js +20 -12
- package/dist/esm/feedback/ui.d.ts +21 -6
- package/dist/esm/feedback/ui.js +283 -71
- package/dist/esm/heatmap/send.d.ts +2 -0
- package/dist/esm/heatmap/send.js +3 -5
- package/dist/esm/heatmap/track.d.ts +1 -1
- package/dist/esm/heatmap/track.js +87 -16
- package/dist/esm/index.d.ts +16 -63
- package/dist/esm/index.js +148 -83
- package/dist/esm/lifecycle.d.ts +21 -3
- package/dist/esm/lifecycle.js +359 -98
- package/dist/esm/remoteconfig/country.d.ts +4 -0
- package/dist/esm/remoteconfig/country.js +70 -0
- package/dist/esm/remoteconfig/custom.d.ts +7 -7
- package/dist/esm/remoteconfig/custom.js +32 -52
- package/dist/esm/remoteconfig/evaluate.d.ts +3 -3
- package/dist/esm/remoteconfig/evaluate.js +57 -44
- package/dist/esm/remoteconfig/fetch.d.ts +16 -9
- package/dist/esm/remoteconfig/fetch.js +120 -39
- package/dist/esm/remoteconfig/index.d.ts +19 -8
- package/dist/esm/remoteconfig/index.js +82 -40
- package/dist/esm/remoteconfig/store.d.ts +15 -7
- package/dist/esm/remoteconfig/store.js +68 -36
- package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/esm/remoteconfig/tz-countries.js +11 -0
- package/dist/{cjs/core → esm/remotelog}/callsite.d.ts +11 -4
- package/dist/esm/{core → remotelog}/callsite.js +30 -8
- package/dist/esm/remotelog/gate.d.ts +2 -11
- package/dist/esm/remotelog/gate.js +10 -32
- package/dist/esm/remotelog/index.d.ts +4 -21
- package/dist/esm/remotelog/logger.d.ts +11 -17
- package/dist/esm/remotelog/logger.js +33 -61
- package/dist/esm/remotelog/send.js +13 -13
- package/dist/esm/remotelogger/index.d.ts +12 -0
- package/dist/esm/remotelogger/index.js +13 -0
- package/dist/esm/scheduler.d.ts +3 -1
- package/dist/esm/scheduler.js +26 -24
- package/dist/esm/types.d.ts +208 -90
- package/dist/esm/user/index.js +18 -8
- package/dist/feedback.esm.min.js +2 -2
- package/dist/feedback.esm.min.js.map +1 -1
- package/dist/remoteconfig.esm.min.js +3 -0
- package/dist/remoteconfig.esm.min.js.map +1 -0
- package/dist/remotelogger.esm.min.js +3 -0
- package/dist/remotelogger.esm.min.js.map +1 -0
- package/package.json +16 -17
- package/dist/chunks/batch-BU_mTpm1.min.js +0 -3
- package/dist/chunks/batch-BU_mTpm1.min.js.map +0 -1
- package/dist/chunks/logs-Bea5zUW_.min.js +0 -3
- package/dist/chunks/logs-Bea5zUW_.min.js.map +0 -1
- package/dist/cjs/auto-init.d.ts +0 -8
- package/dist/cjs/auto-init.js +0 -32
- package/dist/cjs/heatmap/index.d.ts +0 -16
- package/dist/cjs/heatmap/index.js +0 -22
- package/dist/cjs/remotelog/index.js +0 -55
- package/dist/esm/auto-init.d.ts +0 -8
- package/dist/esm/auto-init.js +0 -29
- package/dist/esm/heatmap/index.d.ts +0 -16
- package/dist/esm/heatmap/index.js +0 -17
- package/dist/esm/remotelog/index.js +0 -51
- package/dist/heatmap.esm.min.js +0 -3
- package/dist/heatmap.esm.min.js.map +0 -1
- package/dist/style.css +0 -1
package/dist/esm/device/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
import { SDK_MODULE } from '../core/constants.js';
|
|
3
|
-
import { _ZAP } from '../core/state.js';
|
|
3
|
+
import { _ZAP, getConfig } from '../core/state.js';
|
|
4
4
|
import { Console } from '../core/logger.js';
|
|
5
|
-
import { isEmpty, isSuccess, compareTwoObjects } from '../core/utils.js';
|
|
6
|
-
import { user_defaults, getKeyFromDeviceInfo } from '../core/storage.js';
|
|
5
|
+
import { isEmpty, nowMs, getNewUUID, isSuccess, compareTwoObjects } from '../core/utils.js';
|
|
6
|
+
import { user_defaults, getKeyFromDeviceInfo, setDeviceInfoKey, storedTrackingStatus, reloadSettings } from '../core/storage.js';
|
|
7
|
+
import { withLock } from '../core/locks.js';
|
|
7
8
|
import { getTimeZone, getConnectionType, getReferringURL, getDevice, getBrowserVersion, getBrowser, getOS } from '../core/env.js';
|
|
8
9
|
import { hasDoNotTrackEnabled } from '../core/consent.js';
|
|
9
|
-
import {
|
|
10
|
+
import { rejectIfDisabled, rejectIfOffline, apiHeaders, getHeaderParams, postToApptics, hasDeviceId, rejectIfNoDeviceIds } from '../core/transport.js';
|
|
10
11
|
import { hooks } from '../core/hooks.js';
|
|
11
12
|
import { applyStoredAppVersion } from './appversion.js';
|
|
12
13
|
|
|
@@ -93,7 +94,11 @@ function checkAndUpdateDeviceInfo() {
|
|
|
93
94
|
// appreleaseversionid from app/addversion
|
|
94
95
|
modelid: getKeyFromDeviceInfo('modelid'), // no i18n
|
|
95
96
|
appreleaseversionid: getKeyFromDeviceInfo('appreleaseversionid'), // no i18n
|
|
96
|
-
timezone: getTimeZone()
|
|
97
|
+
timezone: getTimeZone(),
|
|
98
|
+
// kept here rather than as keys of their own: the id the browser is registered under, and
|
|
99
|
+
// whether it has had a session (a session's firstsession says so)
|
|
100
|
+
uuid: _ZAP._uuid || getKeyFromDeviceInfo('uuid'), // no i18n
|
|
101
|
+
hadsession: getKeyFromDeviceInfo('hadsession') === true ? true : undefined, // no i18n
|
|
97
102
|
};
|
|
98
103
|
// the rebuild above starts from browser facts, so the ids app/addversion returned are put
|
|
99
104
|
// back before anything is stored or compared
|
|
@@ -101,10 +106,18 @@ function checkAndUpdateDeviceInfo() {
|
|
|
101
106
|
user_defaults.add('device_info', _ZAP._device_info); // no i18n
|
|
102
107
|
addOrUpdateDeviceID(_ZAP._device_info, previous);
|
|
103
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Whether device/add has registered this device: it has a deviceid. anonymousid is not required:
|
|
111
|
+
* not every Apptics server sends one, nothing the SDK sends carries it, and requiring it had a
|
|
112
|
+
* server that leaves it out register the same device again on every page load.
|
|
113
|
+
*/
|
|
114
|
+
function isRegistered(info) {
|
|
115
|
+
return !!info && !isEmpty(info.deviceid);
|
|
116
|
+
}
|
|
104
117
|
function addOrUpdateDeviceID(device_info, previous) {
|
|
105
118
|
var old_device_info = previous !== undefined ? previous : user_defaults.item('device_info') || {}; // no i18n
|
|
106
119
|
// Compare the old and new device infos and update the server if anything changed in the new.
|
|
107
|
-
if (device_info
|
|
120
|
+
if (!isRegistered(device_info) || device_info.frameworkid == null) {
|
|
108
121
|
device_info.frameworkid = _ZAP._frameworkID;
|
|
109
122
|
Console.log('addOrUpdateDeviceID: Initiated register the device'); // no i18n
|
|
110
123
|
registerDeviceWithApptics().then(function (result_device_info) {
|
|
@@ -141,7 +154,7 @@ function addOrUpdateDeviceID(device_info, previous) {
|
|
|
141
154
|
* out as an empty header.
|
|
142
155
|
*/
|
|
143
156
|
const DEVICE_RESPONSE_KEYS = ['deviceid', 'anonymousid', 'aaid', 'apid', 'mapid', 'appversionid', 'osversionid', 'timezoneid', 'platformid', 'devicetypeid', 'modelid']; // no i18n
|
|
144
|
-
/** Copies server-assigned ids into state and persists device info. */
|
|
157
|
+
/** Copies server-assigned ids into state and persists device info; resolves once it is stored. */
|
|
145
158
|
function applyDeviceResponse(data) {
|
|
146
159
|
DEVICE_RESPONSE_KEYS.forEach(function (key) {
|
|
147
160
|
// an id the answer does not mention is one we already hold, or one we never had:
|
|
@@ -157,12 +170,81 @@ function applyDeviceResponse(data) {
|
|
|
157
170
|
if (!isEmpty(data.mapid)) {
|
|
158
171
|
_ZAP._mapid = data.mapid;
|
|
159
172
|
}
|
|
160
|
-
//
|
|
161
|
-
user_defaults.
|
|
173
|
+
// stored before the registration counts as done, so another tab waiting to register reads it
|
|
174
|
+
return user_defaults.save('device_info', _ZAP._device_info); // no i18n
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The browser's uuid: the one in storage, or a new one stored now. Every tab of the site uses the
|
|
178
|
+
* same one, because the device is registered under it.
|
|
179
|
+
*/
|
|
180
|
+
function useStoredUuid() {
|
|
181
|
+
// kept in device_info: it is the id this browser is registered under
|
|
182
|
+
var uuid = getKeyFromDeviceInfo('uuid'); // no i18n
|
|
183
|
+
if (isEmpty(uuid)) {
|
|
184
|
+
uuid = getNewUUID();
|
|
185
|
+
setDeviceInfoKey('uuid', uuid); // no i18n
|
|
186
|
+
}
|
|
187
|
+
_ZAP._uuid = uuid;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The ids another tab of this site registered after this one loaded its settings: those are in
|
|
191
|
+
* storage but not in this tab's copy. Resolves with them, applied to this tab, or null when the
|
|
192
|
+
* browser is still unregistered and this tab has to register it.
|
|
193
|
+
*/
|
|
194
|
+
function adoptRegisteredDevice() {
|
|
195
|
+
return reloadSettings(['device_info']).then(function () {
|
|
196
|
+
var stored = user_defaults.item('device_info') || {}; // no i18n
|
|
197
|
+
if (!isRegistered(stored)) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
// the device is registered under the uuid the other tab sent
|
|
201
|
+
if (!isEmpty(stored.uuid)) {
|
|
202
|
+
_ZAP._uuid = stored.uuid;
|
|
203
|
+
}
|
|
204
|
+
Console.log('registerDeviceWithApptics: another tab registered this browser, using its device ' + stored.deviceid); // no i18n
|
|
205
|
+
return applyDeviceResponse(stored).then(function () {
|
|
206
|
+
return { result: 'success', data: stored }; // no i18n
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Sets up this browser's device at start-up: the uuid, the device info, and a registration when
|
|
212
|
+
* the browser has none.
|
|
213
|
+
*
|
|
214
|
+
* Settings are this tab's own copy, loaded when it started. On a browser with no device yet, two
|
|
215
|
+
* tabs started together would each register it and store two devices, so the first visit runs
|
|
216
|
+
* under a lock shared by every tab of the site: the tab that gets it re-reads storage, registers
|
|
217
|
+
* only when no other tab has, and keeps the lock until the new ids are stored. The next tab then
|
|
218
|
+
* finds them. Start-up goes on as soon as the device info is set, without waiting for the server.
|
|
219
|
+
*/
|
|
220
|
+
function prepareDevice() {
|
|
221
|
+
var cached = user_defaults.item('device_info') || {}; // no i18n
|
|
222
|
+
if (isRegistered(cached)) {
|
|
223
|
+
useStoredUuid();
|
|
224
|
+
checkAndUpdateDeviceInfo();
|
|
225
|
+
return Promise.resolve();
|
|
226
|
+
}
|
|
227
|
+
return new Promise(function (resolve) {
|
|
228
|
+
withLock('device', function () {
|
|
229
|
+
return reloadSettings(['device_info']).then(function () {
|
|
230
|
+
useStoredUuid();
|
|
231
|
+
checkAndUpdateDeviceInfo();
|
|
232
|
+
resolve();
|
|
233
|
+
// held until a registration this started is stored, or has failed
|
|
234
|
+
return deviceReady();
|
|
235
|
+
});
|
|
236
|
+
}).catch(function (err) {
|
|
237
|
+
Console.log('prepareDevice: ' + err); // no i18n
|
|
238
|
+
}).then(function () {
|
|
239
|
+
resolve();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
162
242
|
}
|
|
163
243
|
/** True while the device has no server ids, so nothing can be sent yet. */
|
|
164
244
|
function needsDevice() {
|
|
165
|
-
|
|
245
|
+
// the app ids from app/addversion, and the deviceid from device/add: either missing, and the
|
|
246
|
+
// device is registered before anything stored is sent
|
|
247
|
+
return (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))) || !hasDeviceId(); // no i18n
|
|
166
248
|
}
|
|
167
249
|
/**
|
|
168
250
|
* Resolves once a registration that is in flight has settled, succeeded or not, and right away
|
|
@@ -195,14 +277,14 @@ function registerDeviceWithApptics() {
|
|
|
195
277
|
return blocked;
|
|
196
278
|
}
|
|
197
279
|
if (!_ZAP._token) {
|
|
198
|
-
Console.warn(label + ': You must call
|
|
199
|
-
return Promise.reject(label + ': You must call
|
|
280
|
+
Console.warn(label + ': You must call Apptics.init() first'); // no i18n
|
|
281
|
+
return Promise.reject(label + ': You must call Apptics.init() first'); // no i18n
|
|
200
282
|
}
|
|
201
283
|
var offline = rejectIfOffline(label);
|
|
202
284
|
if (offline) {
|
|
203
285
|
return offline;
|
|
204
286
|
}
|
|
205
|
-
if (_ZAP._device_info
|
|
287
|
+
if (isRegistered(_ZAP._device_info)) {
|
|
206
288
|
return Promise.resolve(_ZAP._device_info);
|
|
207
289
|
}
|
|
208
290
|
return new Promise((resolve, reject) => {
|
|
@@ -213,17 +295,27 @@ function registerDeviceWithApptics() {
|
|
|
213
295
|
return;
|
|
214
296
|
}
|
|
215
297
|
_ZAP._regDeviceSending = true;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
298
|
+
adoptRegisteredDevice().then(function (adopted) {
|
|
299
|
+
if (adopted) {
|
|
300
|
+
return adopted;
|
|
301
|
+
}
|
|
302
|
+
var payload = deviceBody(_ZAP._device_info);
|
|
303
|
+
// device/add is the one url that allows all four: zak and uuid identify the caller,
|
|
304
|
+
// apid and mapid the app. app/addversion has already answered with apid and mapid by
|
|
305
|
+
// the time registration runs, so the first call can carry them like every later one.
|
|
306
|
+
var headers = { zak: getHeaderParams('zak'), uuid: getHeaderParams('uuid'), ...apiHeaders() }; // no i18n
|
|
307
|
+
return postToApptics('regdevice', payload, headers, label).then(function (result) {
|
|
308
|
+
return applyDeviceResponse(result.data || {}).then(function () {
|
|
309
|
+
return result;
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
}).then(function (result) {
|
|
223
313
|
settleRegistration(true, result);
|
|
224
314
|
resolve(result);
|
|
225
|
-
// first visit: the ids exist now, so fetch the server settings right away
|
|
226
|
-
|
|
315
|
+
// first visit: the ids exist now, so fetch the server settings right away. A device
|
|
316
|
+
// registered again later (its details or the framework id changed) asks nothing more:
|
|
317
|
+
// start-up has already asked on this page load
|
|
318
|
+
startServerSettingChecks();
|
|
227
319
|
}).catch(function (err) {
|
|
228
320
|
settleRegistration(false, err);
|
|
229
321
|
reject(err);
|
|
@@ -255,7 +347,15 @@ function getUpdatesFromServer() {
|
|
|
255
347
|
return postToApptics('sdkconfig', '', apiHeaders(), label).then(function (result) {
|
|
256
348
|
var data = result.data || {};
|
|
257
349
|
applyServerFlags(data);
|
|
258
|
-
|
|
350
|
+
if (_ZAP._nextConfigCheck === 0) {
|
|
351
|
+
// no next_check_after: getupdates_interval from now, stored so a later page load
|
|
352
|
+
// can tell whether the answer is still current
|
|
353
|
+
_ZAP._nextConfigCheck = nowMs() + getConfig('getupdates_interval'); // no i18n
|
|
354
|
+
_ZAP._trackinfo.next_check_after = _ZAP._nextConfigCheck;
|
|
355
|
+
}
|
|
356
|
+
// the visitor's tracking status lives in trackinfo too, and is not the server's to replace
|
|
357
|
+
var saved = storedTrackingStatus();
|
|
358
|
+
user_defaults.add('trackinfo', saved === undefined ? _ZAP._trackinfo : Object.assign({}, _ZAP._trackinfo, { tracking_status: saved })); // no i18n
|
|
259
359
|
Console.log('getUpdatesFromServer: ' + JSON.stringify(_ZAP._trackinfo)); // no i18n
|
|
260
360
|
return data;
|
|
261
361
|
});
|
|
@@ -288,6 +388,10 @@ function applyServerFlags(data) {
|
|
|
288
388
|
if (data.hasOwnProperty('tracking_enabled')) { // no i18n
|
|
289
389
|
_ZAP._shouldTrack = data.tracking_enabled !== false;
|
|
290
390
|
}
|
|
391
|
+
else if (data.hasOwnProperty('shouldtrack')) { // no i18n
|
|
392
|
+
// what this SDK saves, read back on the next visit
|
|
393
|
+
_ZAP._shouldTrack = data.shouldtrack !== false;
|
|
394
|
+
}
|
|
291
395
|
else {
|
|
292
396
|
// the old shape: archived versions and untracked customer groups
|
|
293
397
|
var versionArchived = !data.hasOwnProperty('versionarchivestatus') || isEmpty(data.versionarchivestatus)
|
|
@@ -297,9 +401,14 @@ function applyServerFlags(data) {
|
|
|
297
401
|
_ZAP._shouldTrack = versionArchived || !customerGroupTracking;
|
|
298
402
|
}
|
|
299
403
|
if (hasModules) {
|
|
300
|
-
//
|
|
301
|
-
_ZAP._engagementTracking =
|
|
302
|
-
|
|
404
|
+
// each kind of engagement item has its own module, so the server can turn one off alone
|
|
405
|
+
_ZAP._engagementTracking = {
|
|
406
|
+
event: moduleEnabled(status, SDK_MODULE.EVENT),
|
|
407
|
+
api: moduleEnabled(status, SDK_MODULE.API),
|
|
408
|
+
screen: moduleEnabled(status, SDK_MODULE.SCREEN),
|
|
409
|
+
session: moduleEnabled(status, SDK_MODULE.SESSION),
|
|
410
|
+
};
|
|
411
|
+
_ZAP._errorTracking = moduleEnabled(status, SDK_MODULE.JS_ERROR);
|
|
303
412
|
_ZAP._heatmapTracking = moduleEnabled(status, SDK_MODULE.HEATMAP);
|
|
304
413
|
_ZAP._remoteLoggerEnabled = moduleEnabled(status, SDK_MODULE.REMOTE_LOGGER);
|
|
305
414
|
_ZAP._feedbackEnabled = moduleEnabled(status, SDK_MODULE.FEEDBACK);
|
|
@@ -308,27 +417,52 @@ function applyServerFlags(data) {
|
|
|
308
417
|
_ZAP._remoteConfigEnabled = moduleEnabled(status, SDK_MODULE.REMOTE_CONFIG);
|
|
309
418
|
}
|
|
310
419
|
else {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
420
|
+
// this SDK saves one flag per kind under engagement; an earlier build saved one
|
|
421
|
+
// engagementtracking flag for all four
|
|
422
|
+
var saved = (data.engagement && typeof data.engagement === 'object' // no i18n
|
|
423
|
+
? data.engagement : null);
|
|
424
|
+
var kindOn = function (kind) {
|
|
425
|
+
return saved ? saved[kind] !== false : data.engagementtracking !== false;
|
|
426
|
+
};
|
|
427
|
+
_ZAP._engagementTracking = { event: kindOn('event'), api: kindOn('api'), screen: kindOn('screen'), session: kindOn('session') }; // no i18n
|
|
428
|
+
// the same for the others: read the short key this SDK saves, else the earlier build's
|
|
429
|
+
var flagOn = function (key, oldKey) {
|
|
430
|
+
return (data.hasOwnProperty(key) ? data[key] : data[oldKey]) !== false;
|
|
431
|
+
};
|
|
432
|
+
_ZAP._errorTracking = flagOn('error', 'errortracking'); // no i18n
|
|
433
|
+
_ZAP._heatmapTracking = flagOn('heatmap', 'heatmaptracking'); // no i18n
|
|
434
|
+
_ZAP._remoteLoggerEnabled = flagOn('remotelogger', 'remoteloggerenabled'); // no i18n
|
|
435
|
+
_ZAP._feedbackEnabled = flagOn('feedback', 'feedbackenabled'); // no i18n
|
|
316
436
|
}
|
|
437
|
+
// screen recording, set up in the console: everything the form needs comes from here
|
|
317
438
|
var quartz = (data.quartz && typeof data.quartz === 'object' ? data.quartz : {});
|
|
318
|
-
|
|
319
|
-
?
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
439
|
+
var text = function (value) {
|
|
440
|
+
return typeof value === 'string' ? value.trim() : ''; // no i18n
|
|
441
|
+
};
|
|
442
|
+
_ZAP._quartz = {
|
|
443
|
+
enabled: quartz.hasOwnProperty('quartz_enabled') ? quartz.quartz_enabled === true : data.quartzenabled === true, // no i18n
|
|
444
|
+
workspace: text(quartz.quartz_workspace),
|
|
445
|
+
department: text(quartz.quartz_department),
|
|
446
|
+
domain: text(quartz.quartz_domain),
|
|
447
|
+
cdnUrl: text(quartz.quartz_cdn_url),
|
|
448
|
+
};
|
|
449
|
+
// when to ask again, which replaces polling on a fixed interval. Kept as a timestamp, so the
|
|
450
|
+
// stored copy reads back the same. An answer without one falls back to getupdates_interval
|
|
451
|
+
_ZAP._nextConfigCheck = nextCheckTime(data.next_check_after, nowMs());
|
|
325
452
|
_ZAP._trackinfo = {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
453
|
+
engagement: _ZAP._engagementTracking,
|
|
454
|
+
error: _ZAP._errorTracking,
|
|
455
|
+
heatmap: _ZAP._heatmapTracking,
|
|
456
|
+
remotelogger: _ZAP._remoteLoggerEnabled,
|
|
457
|
+
feedback: _ZAP._feedbackEnabled,
|
|
458
|
+
// in the server's own shape, so restoring it on the next visit reads it the same way
|
|
459
|
+
quartz: {
|
|
460
|
+
quartz_enabled: _ZAP._quartz.enabled,
|
|
461
|
+
quartz_workspace: _ZAP._quartz.workspace,
|
|
462
|
+
quartz_department: _ZAP._quartz.department,
|
|
463
|
+
quartz_domain: _ZAP._quartz.domain,
|
|
464
|
+
quartz_cdn_url: _ZAP._quartz.cdnUrl,
|
|
465
|
+
},
|
|
332
466
|
shouldtrack: _ZAP._shouldTrack,
|
|
333
467
|
next_check_after: _ZAP._nextConfigCheck
|
|
334
468
|
};
|
|
@@ -341,22 +475,152 @@ function restoreServerSettings() {
|
|
|
341
475
|
var saved = user_defaults.item('trackinfo'); // no i18n
|
|
342
476
|
if (saved && typeof saved === 'object') { // no i18n
|
|
343
477
|
applyServerFlags(saved);
|
|
478
|
+
// saved by an earlier build under the old names: store it again in this SDK's shape now,
|
|
479
|
+
// rather than at the next getsdkconfig, which may be a while off. The visitor's tracking
|
|
480
|
+
// status is kept as it is
|
|
481
|
+
if (OLD_TRACKINFO_KEYS.some(function (key) { return saved.hasOwnProperty(key); })) {
|
|
482
|
+
user_defaults.add('trackinfo', saved.tracking_status === undefined ? _ZAP._trackinfo // no i18n
|
|
483
|
+
: Object.assign({}, _ZAP._trackinfo, { tracking_status: saved.tracking_status }));
|
|
484
|
+
}
|
|
344
485
|
Console.log('restoreServerSettings: ' + JSON.stringify(_ZAP._trackinfo)); // no i18n
|
|
345
486
|
}
|
|
346
487
|
}
|
|
488
|
+
/** trackinfo keys an earlier build saved, which this SDK saves under shorter names. */
|
|
489
|
+
var OLD_TRACKINFO_KEYS = ['engagementtracking', 'errortracking', 'heatmaptracking', 'remoteloggerenabled', 'feedbackenabled']; // no i18n
|
|
347
490
|
/**
|
|
348
|
-
*
|
|
349
|
-
*
|
|
491
|
+
* next_check_after as a time: the server's value is milliseconds, either a timestamp or a wait
|
|
492
|
+
* from now. Anything below 1e12 (2001 as a timestamp) can only be a wait.
|
|
493
|
+
*/
|
|
494
|
+
function nextCheckTime(value, now) {
|
|
495
|
+
if (typeof value !== 'number' || !(value > 0)) { // no i18n
|
|
496
|
+
return 0;
|
|
497
|
+
}
|
|
498
|
+
return value >= 1e12 ? value : now + value;
|
|
499
|
+
}
|
|
500
|
+
/** setTimeout's longest wait; a longer one fires straight away. */
|
|
501
|
+
var MAX_TIMEOUT = 2147483647;
|
|
502
|
+
var configTimer = null;
|
|
503
|
+
var configInFlight = false;
|
|
504
|
+
/** Bumped by stopServerSettingChecks(), so an answer to an ask from before a reset schedules nothing. */
|
|
505
|
+
var configRound = 0;
|
|
506
|
+
/** Whether this page load has asked, or set the timer from the saved answer instead. */
|
|
507
|
+
var configAsked = false;
|
|
508
|
+
/** A user registered, or getupdates reported a change, while a getsdkconfig was in flight: asked again when it answers. */
|
|
509
|
+
var configAskAgain = false;
|
|
510
|
+
/** When the next getsdkconfig is due, as a timestamp. 0 until the first answer. */
|
|
511
|
+
var configDueAt = 0;
|
|
512
|
+
/**
|
|
513
|
+
* Asks for the server settings now if the device is registered, then schedules the next ask
|
|
514
|
+
* for the time the answer gave in next_check_after. On a first visit the ids don't exist yet;
|
|
515
|
+
* registerDeviceWithApptics calls this as soon as device/add succeeds.
|
|
350
516
|
*/
|
|
351
517
|
function refreshServerSettings() {
|
|
352
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))) { // no i18n
|
|
518
|
+
if (configInFlight || !hasDeviceId() || (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid')))) { // no i18n
|
|
353
519
|
return;
|
|
354
520
|
}
|
|
521
|
+
if (configTimer !== null) {
|
|
522
|
+
clearTimeout(configTimer);
|
|
523
|
+
configTimer = null;
|
|
524
|
+
}
|
|
525
|
+
configInFlight = true;
|
|
526
|
+
configAsked = true;
|
|
527
|
+
markTabAsked();
|
|
528
|
+
var round = configRound;
|
|
529
|
+
var askedAt = nowMs();
|
|
355
530
|
getUpdatesFromServer().catch(function (err) {
|
|
356
531
|
Console.log(err);
|
|
532
|
+
}).then(function () {
|
|
533
|
+
if (round !== configRound) {
|
|
534
|
+
// stopServerSettingChecks() ran while this was in flight
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
configInFlight = false;
|
|
538
|
+
if (configAskAgain) {
|
|
539
|
+
configAskAgain = false;
|
|
540
|
+
refreshServerSettings();
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
// an answer without a usable next_check_after, or a failed call, waits getupdates_interval
|
|
544
|
+
configDueAt = _ZAP._nextConfigCheck > nowMs() ? _ZAP._nextConfigCheck : askedAt + getConfig('getupdates_interval'); // no i18n
|
|
545
|
+
scheduleServerSettingCheck();
|
|
357
546
|
});
|
|
358
547
|
}
|
|
548
|
+
/**
|
|
549
|
+
* getsdkconfig now, not at the next check: setUser registered a user, or getupdates reported a
|
|
550
|
+
* module changed.
|
|
551
|
+
*/
|
|
552
|
+
function askServerSettings() {
|
|
553
|
+
if (configInFlight) {
|
|
554
|
+
// the one in flight went out before the change: ask again once it answers
|
|
555
|
+
configAskAgain = true;
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
refreshServerSettings();
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Start-up's getsdkconfig. Asked on a first visit and on the first page load in each tab; any
|
|
562
|
+
* other load (a reload, a link to another page of the site, back/forward) uses the saved answer
|
|
563
|
+
* and waits for its next_check_after, unless that has already passed. Nothing happens if one has
|
|
564
|
+
* gone out already on this load (after device/add).
|
|
565
|
+
*/
|
|
566
|
+
function startServerSettingChecks() {
|
|
567
|
+
if (configAsked) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (tabHasAsked() && _ZAP._nextConfigCheck > nowMs()) {
|
|
571
|
+
Console.log('getsdkconfig: the saved answer is still current'); // no i18n
|
|
572
|
+
configAsked = true;
|
|
573
|
+
configDueAt = _ZAP._nextConfigCheck;
|
|
574
|
+
scheduleServerSettingCheck();
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
refreshServerSettings();
|
|
578
|
+
}
|
|
579
|
+
/** sessionStorage: per tab, and kept across a reload and the site's own links. */
|
|
580
|
+
var TAB_ASKED_KEY = '_apptics_sdkconfig_asked'; // no i18n
|
|
581
|
+
/** Whether getsdkconfig has gone out in this tab before, on an earlier page load. */
|
|
582
|
+
function tabHasAsked() {
|
|
583
|
+
try {
|
|
584
|
+
return sessionStorage.getItem(TAB_ASKED_KEY) === '1'; // no i18n
|
|
585
|
+
}
|
|
586
|
+
catch (e) {
|
|
587
|
+
return false; // no sessionStorage (private mode, sandboxed frame): every load asks
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function markTabAsked() {
|
|
591
|
+
try {
|
|
592
|
+
sessionStorage.setItem(TAB_ASKED_KEY, '1'); // no i18n
|
|
593
|
+
}
|
|
594
|
+
catch (e) {
|
|
595
|
+
// as above: without it, every load asks
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/** Sets the timer for the next getsdkconfig, at configDueAt. */
|
|
599
|
+
function scheduleServerSettingCheck() {
|
|
600
|
+
if (configTimer !== null) {
|
|
601
|
+
clearTimeout(configTimer);
|
|
602
|
+
}
|
|
603
|
+
var wait = Math.min(Math.max(configDueAt - nowMs(), 0), MAX_TIMEOUT);
|
|
604
|
+
Console.log('getsdkconfig: next check in ' + wait + ' ms'); // no i18n
|
|
605
|
+
configTimer = setTimeout(function () {
|
|
606
|
+
configTimer = null;
|
|
607
|
+
refreshServerSettings();
|
|
608
|
+
}, wait);
|
|
609
|
+
}
|
|
610
|
+
/** reset(): no more checks, and the next init() asks again straight away. */
|
|
611
|
+
function stopServerSettingChecks() {
|
|
612
|
+
if (configTimer !== null) {
|
|
613
|
+
clearTimeout(configTimer);
|
|
614
|
+
}
|
|
615
|
+
configTimer = null;
|
|
616
|
+
configRound++;
|
|
617
|
+
configInFlight = false;
|
|
618
|
+
configAsked = false;
|
|
619
|
+
configAskAgain = false;
|
|
620
|
+
configDueAt = 0;
|
|
621
|
+
}
|
|
359
622
|
hooks.updateDevice = updateDeviceWithApptics;
|
|
360
623
|
hooks.refreshDeviceInfo = checkAndUpdateDeviceInfo;
|
|
624
|
+
hooks.askServerSettings = askServerSettings;
|
|
361
625
|
|
|
362
|
-
export { addOrUpdateDeviceID, checkAndUpdateDeviceInfo, deviceReady, getUpdatesFromServer, needsDevice, refreshServerSettings, registerDeviceWithApptics, restoreServerSettings, updateDeviceWithApptics };
|
|
626
|
+
export { addOrUpdateDeviceID, checkAndUpdateDeviceInfo, deviceReady, getUpdatesFromServer, needsDevice, nextCheckTime, prepareDevice, refreshServerSettings, registerDeviceWithApptics, restoreServerSettings, startServerSettingChecks, stopServerSettingChecks, updateDeviceWithApptics };
|
|
@@ -1,62 +1,34 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What API tracking records, and under what name — Android's AppticsApiTracker.configure, built
|
|
3
|
-
* with ApiTrackingBuilder the way user properties are built with UserBuilder:
|
|
4
|
-
*
|
|
5
|
-
* configureApiTracking(new ApiTrackingBuilder()
|
|
6
|
-
* .allowOnlyDomains('api.zylker.com', 'api.zylker.in')
|
|
7
|
-
* .groupDomains('api.zylker.*')
|
|
8
|
-
* .ignoreEndpoint('/health', '/internal/**')
|
|
9
|
-
* .addPattern('/v2/catalog/{categoryId}/items/{itemId}')
|
|
10
|
-
* .build());
|
|
11
|
-
*
|
|
12
|
-
* Two jobs. Filtering decides whether a call is recorded at all: ignore rules first, and they
|
|
13
|
-
* always win, then the allow lists. Normalization decides the path it is recorded under, so that
|
|
14
|
-
* `/users/42/orders` and `/users/43/orders` are one endpoint on the console rather than two: the
|
|
15
|
-
* query string goes, an explicit pattern is used when one matches, and otherwise numeric ids,
|
|
16
|
-
* UUIDs and JWTs become `*`.
|
|
17
|
-
*
|
|
18
|
-
* Both apply to every call, the ones the fetch/XHR wrappers catch and the ones the app reports
|
|
19
|
-
* with trackApi() or startTrackApi(), so one set of rules decides what the API page shows.
|
|
20
|
-
*/
|
|
21
1
|
/** The rules, as ApiTrackingBuilder.build() returns them. Every list may be empty. */
|
|
22
2
|
export interface ApiTrackingConfig {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
patterns: string[];
|
|
32
|
-
preserveSegments: string[];
|
|
33
|
-
autoDetection: boolean;
|
|
3
|
+
/** URLs recorded, exactly; with any allow rule, only calls matching one are recorded. */
|
|
4
|
+
allowEquals: string[];
|
|
5
|
+
/** URLs never recorded, exactly. */
|
|
6
|
+
ignoreEquals: string[];
|
|
7
|
+
/** Regular expressions a recorded URL may match; with any allow rule, it must match one. */
|
|
8
|
+
allowRegex: RegExp[];
|
|
9
|
+
/** Regular expressions whose URLs are never recorded. */
|
|
10
|
+
ignoreRegex: RegExp[];
|
|
34
11
|
}
|
|
35
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* A URL as the rules compare it: `scheme://host[:port]/path`, the scheme and host lower-cased,
|
|
14
|
+
* the default port dropped, the query, fragment and a trailing slash removed. '' when it is not
|
|
15
|
+
* an absolute http(s) URL.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ruleUrl(raw: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Builds the rules configure takes. Each method may be called more than once, and takes any number
|
|
20
|
+
* of values: `new ApiTrackingBuilder().allowEquals(a, b).ignoreRegex(/x/).build()`.
|
|
21
|
+
*/
|
|
36
22
|
export declare class ApiTrackingBuilder {
|
|
37
23
|
private rules;
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
/** Records only
|
|
43
|
-
|
|
44
|
-
/** Never records
|
|
45
|
-
|
|
46
|
-
/** Never records hosts starting with these, e.g. `dev.`. */
|
|
47
|
-
ignoreDomainPrefixes(...prefixes: string[]): this;
|
|
48
|
-
/** Never records hosts ending with these, e.g. `.cdn.net`. */
|
|
49
|
-
ignoreDomainSuffixes(...suffixes: string[]): this;
|
|
50
|
-
/** Records the hosts a pattern such as `api.myapp.*` matches under that one name. */
|
|
51
|
-
groupDomains(...patterns: string[]): this;
|
|
52
|
-
/** Never records these paths: exact, `*` or `{name}` for one segment, `**` at the end for a prefix. */
|
|
53
|
-
ignoreEndpoint(...paths: string[]): this;
|
|
54
|
-
/** Records a path this pattern matches as the pattern, with each `{name}` as `*`. Tried before auto-detection. */
|
|
55
|
-
addPattern(...patterns: string[]): this;
|
|
56
|
-
/** Segments never turned into `*`, e.g. `v1` or `404`. */
|
|
57
|
-
preserveSegments(...segments: string[]): this;
|
|
58
|
-
/** `false`: only addPattern paths are normalized; every other path is recorded as it is. */
|
|
59
|
-
autoDetection(enabled: boolean): this;
|
|
24
|
+
/** Records only these URLs (and those any allowRegex matches): `https://api.example.com/orders`. */
|
|
25
|
+
allowEquals(...urls: string[]): this;
|
|
26
|
+
/** Never records these URLs: `https://api.example.com/health`. */
|
|
27
|
+
ignoreEquals(...urls: string[]): this;
|
|
28
|
+
/** Records only URLs these match (and those any allowEquals names): `/^https:\/\/api\.example\.com\//`. */
|
|
29
|
+
allowRegex(...patterns: Array<RegExp | string>): this;
|
|
30
|
+
/** Never records URLs these match: `/\/internal\//`. */
|
|
31
|
+
ignoreRegex(...patterns: Array<RegExp | string>): this;
|
|
60
32
|
build(): ApiTrackingConfig;
|
|
61
33
|
}
|
|
62
34
|
/**
|
|
@@ -66,19 +38,12 @@ export declare class ApiTrackingBuilder {
|
|
|
66
38
|
export declare function configureApiTracking(config: ApiTrackingConfig | ApiTrackingBuilder): void;
|
|
67
39
|
/** The rules in force, for tests and the playground. */
|
|
68
40
|
export declare function apiTrackingConfig(): ApiTrackingConfig;
|
|
69
|
-
/** Whether calls to this host are recorded. Ignore rules are checked first and always win. */
|
|
70
|
-
export declare function hostAllowed(hostname: string): boolean;
|
|
71
|
-
/** The name a host is recorded under: the first groupDomains pattern it matches, or itself. */
|
|
72
|
-
export declare function groupedHost(hostname: string): string;
|
|
73
|
-
/** Whether a host is one of the groupDomains names, which carry a `*` no real host has. */
|
|
74
|
-
export declare function isGroupedHost(hostname: string): boolean;
|
|
75
|
-
/** The path without its query string or fragment, which is where ids and tokens travel. */
|
|
76
|
-
export declare function withoutQuery(path: string): string;
|
|
77
|
-
/** Whether ignoreEndpoint leaves this path out. Matched on the path as called, query removed. */
|
|
78
|
-
export declare function endpointIgnored(path: string): boolean;
|
|
79
41
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* autoDetection on, numeric ids, UUIDs and JWTs become `*`, except preserveSegments.
|
|
42
|
+
* Whether a call to `url` is recorded. Ignore rules are tried first and always win; then, when
|
|
43
|
+
* there are allow rules, the URL must match one. A URL that cannot be read is not recorded.
|
|
83
44
|
*/
|
|
45
|
+
export declare function urlTracked(url: string): boolean;
|
|
46
|
+
/** The path without its query string or fragment, which is where ids and tokens travel. */
|
|
47
|
+
export declare function withoutQuery(path: string): string;
|
|
48
|
+
/** The path a call is recorded under: the query goes, and numeric ids, UUIDs and JWTs become `*`. */
|
|
84
49
|
export declare function normalizeApiPath(path: string): string;
|