@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/cjs/errors/track.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('../core/constants.js');
|
|
@@ -38,19 +38,59 @@ function stackOf(errorEvent) {
|
|
|
38
38
|
}
|
|
39
39
|
/** Said in place of a stack when there is none, so `message` is never sent empty. */
|
|
40
40
|
const NO_STACK = 'no stack available'; // no i18n
|
|
41
|
+
/** The element an event came from, as `<script src="…">`, so a failed load says what failed. */
|
|
42
|
+
function describeTarget(target) {
|
|
43
|
+
var el = target;
|
|
44
|
+
if (!el || typeof el.tagName !== 'string') { // no i18n
|
|
45
|
+
return ''; // no i18n
|
|
46
|
+
}
|
|
47
|
+
var tag = el.tagName.toLowerCase();
|
|
48
|
+
var url = el.currentSrc || el.src || el.href || ''; // no i18n
|
|
49
|
+
return ' on <' + tag + (url ? (el.href && !el.src ? ' href="' : ' src="') + url + '"' : '') + '>'; // no i18n
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* What was thrown or rejected, as text an issue can be named by. An Error reads as itself. A
|
|
53
|
+
* promise rejected with an Event - what a failed script or image load hands over - used to be
|
|
54
|
+
* recorded as "[object Event]"; it is named by its type and where it came from instead. Anything
|
|
55
|
+
* else that is an object is shown as its JSON, cut short.
|
|
56
|
+
*/
|
|
57
|
+
function describeThrown(thrown) {
|
|
58
|
+
if (thrown === null || thrown === undefined) {
|
|
59
|
+
return ''; // no i18n
|
|
60
|
+
}
|
|
61
|
+
if (typeof thrown !== 'object') { // no i18n
|
|
62
|
+
return String(thrown);
|
|
63
|
+
}
|
|
64
|
+
if (thrown instanceof Error || typeof thrown.message === 'string' && typeof thrown.name === 'string') { // no i18n
|
|
65
|
+
return String(thrown);
|
|
66
|
+
}
|
|
67
|
+
if (typeof Event !== 'undefined' && thrown instanceof Event) { // no i18n
|
|
68
|
+
return 'Event "' + thrown.type + '"' + describeTarget(thrown.target); // no i18n
|
|
69
|
+
}
|
|
70
|
+
var text = String(thrown);
|
|
71
|
+
if (text !== '[object Object]') { // no i18n
|
|
72
|
+
return text;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
return JSON.stringify(thrown).slice(0, 300);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return text;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
41
81
|
function trackError(errorEvent, jsonObj) {
|
|
42
82
|
if (!consent.canTrackErrors('trackError')) { // no i18n
|
|
43
83
|
return;
|
|
44
84
|
}
|
|
45
85
|
if (utils.isEmpty(errorEvent)) {
|
|
46
|
-
logger.Console.warn('
|
|
86
|
+
logger.Console.warn('AppticsError.trackError: Invalid error'); // no i18n
|
|
47
87
|
return;
|
|
48
88
|
}
|
|
49
89
|
var _jsonObj = validate.validateJSON(jsonObj);
|
|
50
90
|
var stack = stackOf(errorEvent);
|
|
51
91
|
var methodName = extractMethodNameFromStackTrace(stack) || "";
|
|
52
92
|
var issuetype = errorEvent.type || "";
|
|
53
|
-
var thrown = errorEvent.reason || errorEvent.error || errorEvent.message || "";
|
|
93
|
+
var thrown = describeThrown(errorEvent.reason || errorEvent.error || errorEvent.message || "");
|
|
54
94
|
// "Error: x at handler", or just "Error: x" when the stack names no method. issuename is
|
|
55
95
|
// required too, so something that carried no message at all is still named rather than blank
|
|
56
96
|
var described = !utils.isEmpty(String(thrown)) ? String(thrown) : (!utils.isEmpty(issuetype) ? String(issuetype) : 'Unknown error'); // no i18n
|
|
@@ -76,11 +116,13 @@ function trackError(errorEvent, jsonObj) {
|
|
|
76
116
|
session.commitPendingSession();
|
|
77
117
|
debug.noteDebugActivity();
|
|
78
118
|
storage.error_transactions.add(errorData);
|
|
79
|
-
logger.Console.log('
|
|
119
|
+
logger.Console.log('AppticsError.trackError(\'' + issuetype + '\',\'' + message + '\',' + JSON.stringify(_jsonObj || {}) + ')'); // no i18n
|
|
80
120
|
logger.Console.dir(errorData);
|
|
81
121
|
}
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
/** AppticsError.setErrorTracking: uncaught errors on or off, as the `track_error` config sets it. */
|
|
123
|
+
function setErrorTracking(status) {
|
|
124
|
+
state._ZAP._config.track_error = typeof status === "boolean" ? status : true; // no i18n
|
|
125
|
+
logger.Console.log('automatic error tracking: ' + (state._ZAP._config.track_error ? 'on' : 'off')); // no i18n
|
|
84
126
|
}
|
|
85
127
|
function extractMethodNameFromStackTrace(stackTrace) {
|
|
86
128
|
let methodName = ''; // no i18n
|
|
@@ -122,6 +164,6 @@ function extractMethodNameFromStackTrace(stackTrace) {
|
|
|
122
164
|
return methodName;
|
|
123
165
|
}
|
|
124
166
|
|
|
125
|
-
exports.enableGlobalErrorHandler = enableGlobalErrorHandler;
|
|
126
167
|
exports.extractMethodNameFromStackTrace = extractMethodNameFromStackTrace;
|
|
168
|
+
exports.setErrorTracking = setErrorTracking;
|
|
127
169
|
exports.trackError = trackError;
|
|
@@ -12,6 +12,12 @@ export declare const logChoice: {
|
|
|
12
12
|
includeLog?: boolean;
|
|
13
13
|
includeDyninfo?: boolean;
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Who a sendFeedback() report, made without the form, is attributed to: nobody when `anonymous`,
|
|
17
|
+
* else the user AppticsUser.setUser set (or the active registered one, status 1). Returns a function
|
|
18
|
+
* that puts back the choice that was there, so a form left open keeps its own.
|
|
19
|
+
*/
|
|
20
|
+
export declare function chooseUserForSend(anonymous: boolean): () => void;
|
|
15
21
|
/**
|
|
16
22
|
* The "User" dropdown above the description. It lists Anonymous plus every registered user, and
|
|
17
23
|
* starts on the active one (status 1) unless the caller asked for anonymous.
|
|
@@ -29,3 +35,9 @@ export declare function wireLogControls(modal: HTMLElement, opts: Dict): void;
|
|
|
29
35
|
* kept inside the viewport.
|
|
30
36
|
*/
|
|
31
37
|
export declare function wireDrag(box: HTMLElement): void;
|
|
38
|
+
/**
|
|
39
|
+
* Lets the recording timer be dragged anywhere on the page. A press that moves it is a drag, and
|
|
40
|
+
* does not also stop the recording, as a plain click on it does. Call before the click listener
|
|
41
|
+
* is added, so a drag's click is stopped ahead of it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function wireTimerDrag(timer: HTMLElement): void;
|
|
@@ -1,10 +1,11 @@
|
|
|
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
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var logger = require('../core/logger.js');
|
|
5
5
|
var hooks = require('../core/hooks.js');
|
|
6
6
|
var storage = require('../core/storage.js');
|
|
7
7
|
var utils = require('../core/utils.js');
|
|
8
|
+
var state = require('../core/state.js');
|
|
8
9
|
var logs = require('./logs.js');
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -25,6 +26,34 @@ function resetUserChoice() {
|
|
|
25
26
|
userChoice.userid = ''; // no i18n
|
|
26
27
|
userChoice.groupid = ''; // no i18n
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Who a sendFeedback() report, made without the form, is attributed to: nobody when `anonymous`,
|
|
31
|
+
* else the user AppticsUser.setUser set (or the active registered one, status 1). Returns a function
|
|
32
|
+
* that puts back the choice that was there, so a form left open keeps its own.
|
|
33
|
+
*/
|
|
34
|
+
function chooseUserForSend(anonymous) {
|
|
35
|
+
var before = { anonymous: userChoice.anonymous, userid: userChoice.userid, groupid: userChoice.groupid };
|
|
36
|
+
resetUserChoice();
|
|
37
|
+
if (!anonymous) {
|
|
38
|
+
// the user setUser set on this page, else the active one of those registered before
|
|
39
|
+
var active = !utils.isEmpty(state._ZAP._user_info.userid) ? state._ZAP._user_info : null;
|
|
40
|
+
storedUsers().forEach(function (user) {
|
|
41
|
+
if (!active && user && user.status == 1 && !utils.isEmpty(user.userid)) {
|
|
42
|
+
active = user;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
if (active) {
|
|
46
|
+
userChoice.anonymous = false;
|
|
47
|
+
userChoice.userid = String(active.userid);
|
|
48
|
+
userChoice.groupid = String(active.groupid || ''); // no i18n
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return function restore() {
|
|
52
|
+
userChoice.anonymous = before.anonymous;
|
|
53
|
+
userChoice.userid = before.userid;
|
|
54
|
+
userChoice.groupid = before.groupid;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
28
57
|
/** Every distinct registered user, by the address the picker shows. */
|
|
29
58
|
function storedUsers() {
|
|
30
59
|
var users = storage.user_defaults.item('users'); // no i18n
|
|
@@ -238,49 +267,99 @@ function wireDrag(box) {
|
|
|
238
267
|
if (!header) {
|
|
239
268
|
return;
|
|
240
269
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
270
|
+
makeDraggable(box, header, function (target) {
|
|
271
|
+
// the close button is not a drag handle
|
|
272
|
+
return !!target.closest('.zasdk-close'); // no i18n
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/** Where the recording timer was last dragged to, so the next recording's timer starts there. */
|
|
276
|
+
var timerSpot = null;
|
|
277
|
+
/**
|
|
278
|
+
* Lets the recording timer be dragged anywhere on the page. A press that moves it is a drag, and
|
|
279
|
+
* does not also stop the recording, as a plain click on it does. Call before the click listener
|
|
280
|
+
* is added, so a drag's click is stopped ahead of it.
|
|
281
|
+
*/
|
|
282
|
+
function wireTimerDrag(timer) {
|
|
283
|
+
if (timerSpot) {
|
|
284
|
+
placeAt(timer, timerSpot.left, timerSpot.top);
|
|
285
|
+
}
|
|
286
|
+
makeDraggable(timer, timer, undefined, function (left, top) {
|
|
287
|
+
timerSpot = { left: left, top: top };
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/** Puts a fixed box at left/top, inside the viewport. */
|
|
291
|
+
function placeAt(box, left, top) {
|
|
292
|
+
box.style.right = 'auto'; // no i18n
|
|
293
|
+
box.style.bottom = 'auto'; // no i18n
|
|
294
|
+
box.style.left = Math.max(0, Math.min(left, window.innerWidth - box.offsetWidth)) + 'px'; // no i18n
|
|
295
|
+
box.style.top = Math.max(0, Math.min(top, window.innerHeight - box.offsetHeight)) + 'px'; // no i18n
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Moves `box` with the mouse or a finger pressed on `handle`. `skip` says which presses are not a
|
|
299
|
+
* drag; `moved` hears where the box ended up. A click that ends a drag goes no further.
|
|
300
|
+
*/
|
|
301
|
+
function makeDraggable(box, handle, skip, moved) {
|
|
302
|
+
var startX = 0, startY = 0, boxLeft = 0, boxTop = 0, dragging = false, dragged = false;
|
|
303
|
+
handle.addEventListener('pointerdown', function (event) {
|
|
304
|
+
if (event.button !== 0 || (skip && skip(event.target))) {
|
|
305
|
+
return;
|
|
252
306
|
}
|
|
307
|
+
var rect = box.getBoundingClientRect();
|
|
253
308
|
dragging = true;
|
|
309
|
+
dragged = false;
|
|
254
310
|
startX = event.clientX;
|
|
255
311
|
startY = event.clientY;
|
|
256
|
-
boxLeft =
|
|
257
|
-
boxTop =
|
|
258
|
-
|
|
312
|
+
boxLeft = rect.left;
|
|
313
|
+
boxTop = rect.top;
|
|
314
|
+
handle.style.cursor = 'move'; // no i18n
|
|
315
|
+
// the moves and the release come to the handle however far the pointer goes, so nothing
|
|
316
|
+
// is left listening on the document once the box is gone
|
|
317
|
+
try {
|
|
318
|
+
handle.setPointerCapture(event.pointerId);
|
|
319
|
+
}
|
|
320
|
+
catch (err) { /* a pointer already released */ }
|
|
259
321
|
event.preventDefault();
|
|
260
322
|
});
|
|
261
|
-
|
|
323
|
+
handle.addEventListener('pointermove', function (event) {
|
|
262
324
|
if (!dragging) {
|
|
263
325
|
return;
|
|
264
326
|
}
|
|
265
|
-
var
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
box.style.top = Math.max(0, Math.min(top, window.innerHeight - box.offsetHeight)) + 'px'; // no i18n
|
|
269
|
-
});
|
|
270
|
-
document.addEventListener('mouseup', function () {
|
|
271
|
-
if (dragging) {
|
|
272
|
-
dragging = false;
|
|
273
|
-
header.style.cursor = 'grab'; // no i18n
|
|
327
|
+
var dx = event.clientX - startX, dy = event.clientY - startY;
|
|
328
|
+
if (!dragged && Math.abs(dx) < 4 && Math.abs(dy) < 4) {
|
|
329
|
+
return; // a press that wobbles is still a click
|
|
274
330
|
}
|
|
331
|
+
dragged = true;
|
|
332
|
+
placeAt(box, boxLeft + dx, boxTop + dy);
|
|
275
333
|
});
|
|
334
|
+
function stop() {
|
|
335
|
+
if (!dragging) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
dragging = false;
|
|
339
|
+
handle.style.cursor = ''; // no i18n
|
|
340
|
+
if (dragged && moved) {
|
|
341
|
+
moved(parseInt(box.style.left, 10), parseInt(box.style.top, 10));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
handle.addEventListener('pointerup', stop); // no i18n
|
|
345
|
+
handle.addEventListener('pointercancel', stop); // no i18n
|
|
346
|
+
box.addEventListener('click', function (event) {
|
|
347
|
+
if (dragged) {
|
|
348
|
+
dragged = false;
|
|
349
|
+
event.stopImmediatePropagation();
|
|
350
|
+
event.preventDefault();
|
|
351
|
+
}
|
|
352
|
+
}, true);
|
|
276
353
|
}
|
|
277
354
|
// core/transport asks for the picked user when it builds the feedback request's parameters
|
|
278
355
|
hooks.hooks.feedbackUser = function () {
|
|
279
356
|
return userChoice.anonymous || utils.isEmpty(userChoice.userid) ? null : userChoice;
|
|
280
357
|
};
|
|
281
358
|
|
|
359
|
+
exports.chooseUserForSend = chooseUserForSend;
|
|
282
360
|
exports.logChoice = logChoice;
|
|
283
361
|
exports.userChoice = userChoice;
|
|
284
362
|
exports.wireDrag = wireDrag;
|
|
285
363
|
exports.wireLogControls = wireLogControls;
|
|
364
|
+
exports.wireTimerDrag = wireTimerDrag;
|
|
286
365
|
exports.wireUserPicker = wireUserPicker;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { feedbackClose as feedbackCloseImpl } from './ui.js';
|
|
2
1
|
import type { AppticsFeedbackApi } from '../types.js';
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
export type { FeedbackOpenOptions, SendFeedbackOptions } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Android's AppticsFeedback: the form, sending feedback without it, and the context recorded for
|
|
5
|
+
* the next one. Every feedback call, addFeedbackLog and addDiagnosticsInfo included, is here and
|
|
6
|
+
* only here: the main entry has no AppticsFeedback.
|
|
7
|
+
*/
|
|
8
|
+
export declare const AppticsFeedback: AppticsFeedbackApi;
|
|
9
|
+
export default AppticsFeedback;
|
|
@@ -1,37 +1,56 @@
|
|
|
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
|
'use strict';
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var guard = require('../core/guard.js');
|
|
7
|
+
var constants = require('../core/constants.js');
|
|
7
8
|
var logger = require('../core/logger.js');
|
|
8
9
|
var lifecycle = require('../lifecycle.js');
|
|
9
10
|
var ui = require('./ui.js');
|
|
11
|
+
var logs = require('./logs.js');
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Optional feedback modal, shipped as its own entry point:
|
|
13
|
-
* import {
|
|
14
|
-
*
|
|
15
|
+
* import { AppticsFeedback } from '@zoho_apptics/apptics-js-sdk/feedback';
|
|
16
|
+
* AppticsFeedback.feedbackFormOpen();
|
|
15
17
|
* Apps that never import it don't pay for the modal or its markup.
|
|
16
18
|
* The <script> build includes it, so snippet users are unaffected.
|
|
17
19
|
*/
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
+
const feedbackFormOpenGuarded = guard.guard('AppticsFeedback.feedbackFormOpen', ui.feedbackFormOpen); // no i18n
|
|
21
|
+
const feedbackFormCloseGuarded = guard.guard('AppticsFeedback.feedbackFormClose', ui.feedbackFormClose); // no i18n
|
|
22
|
+
const addFeedbackLogGuarded = guard.guard('AppticsFeedback.addFeedbackLog', logs.addFeedbackLog); // no i18n
|
|
23
|
+
const addDiagnosticsInfoGuarded = guard.guard('AppticsFeedback.addDiagnosticsInfo', logs.addDiagnosticsInfo); // no i18n
|
|
24
|
+
const setFeedbackThemeGuarded = guard.guard('AppticsFeedback.setFeedbackTheme', ui.setFeedbackTheme); // no i18n
|
|
20
25
|
/** Resolves once the feedback is sent; rejects when it wasn't (SDK not started, offline, refused). */
|
|
21
|
-
const
|
|
26
|
+
const sendFeedbackGuarded = guard.guard('AppticsFeedback.sendFeedback', function (...args) {
|
|
22
27
|
return lifecycle.ready().then(function (started) {
|
|
23
28
|
if (!started) {
|
|
24
|
-
throw new Error('
|
|
29
|
+
throw new Error('AppticsFeedback.sendFeedback: not sent, the SDK has not started; call Apptics.init() first'); // no i18n
|
|
25
30
|
}
|
|
26
31
|
return ui.sendFeedback(...args);
|
|
27
32
|
}).catch(function (err) {
|
|
28
|
-
logger.Console.error('
|
|
33
|
+
logger.Console.error('AppticsFeedback.sendFeedback failed:', err); // no i18n
|
|
29
34
|
throw err;
|
|
30
35
|
});
|
|
31
36
|
});
|
|
32
|
-
|
|
37
|
+
/* each call a function of its own, with the parameter names the console shows (see forward) */
|
|
38
|
+
/**
|
|
39
|
+
* Android's AppticsFeedback: the form, sending feedback without it, and the context recorded for
|
|
40
|
+
* the next one. Every feedback call, addFeedbackLog and addDiagnosticsInfo included, is here and
|
|
41
|
+
* only here: the main entry has no AppticsFeedback.
|
|
42
|
+
*/
|
|
43
|
+
const AppticsFeedback = {
|
|
44
|
+
/** The feedback types: BUG, FEEDBACK, HELP, REPORT. */
|
|
45
|
+
AP_FEEDBACK_TYPE: constants.AP_FEEDBACK_TYPE,
|
|
46
|
+
feedbackFormOpen: function feedbackFormOpen(options) { return guard.forward(feedbackFormOpenGuarded, arguments); },
|
|
47
|
+
feedbackFormClose: function feedbackFormClose() { return guard.forward(feedbackFormCloseGuarded, arguments); },
|
|
48
|
+
sendFeedback: function sendFeedback(options) { return guard.forward(sendFeedbackGuarded, arguments); },
|
|
49
|
+
addFeedbackLog: function addFeedbackLog(message) { return guard.forward(addFeedbackLogGuarded, arguments); },
|
|
50
|
+
addDiagnosticsInfo: function addDiagnosticsInfo(heading, key, value) { return guard.forward(addDiagnosticsInfoGuarded, arguments); },
|
|
51
|
+
/** The form's theme from now on, and of a form open now: 'light', 'dark' or 'auto'. */
|
|
52
|
+
setFeedbackTheme: function setFeedbackTheme(theme) { return guard.forward(setFeedbackThemeGuarded, arguments); },
|
|
53
|
+
};
|
|
33
54
|
|
|
34
|
-
exports.
|
|
35
|
-
exports.
|
|
36
|
-
exports.feedbackOpen = feedbackOpen;
|
|
37
|
-
exports.sendFeedback = sendFeedback;
|
|
55
|
+
exports.AppticsFeedback = AppticsFeedback;
|
|
56
|
+
exports.default = AppticsFeedback;
|
|
@@ -15,26 +15,28 @@ export declare function trimStoredLogs(): Promise<void>;
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function addFeedbackLog(message: string): void;
|
|
17
17
|
/**
|
|
18
|
-
* Records a diagnostics
|
|
19
|
-
*
|
|
18
|
+
* Records a diagnostics entry, `value` under `key` in the `heading` block of dyninfo.txt. All three
|
|
19
|
+
* are required: an entry without a value says nothing, so it is refused and the console says why.
|
|
20
|
+
* A value of 0 or false is a value.
|
|
20
21
|
*/
|
|
21
|
-
export declare function addDiagnosticsInfo(heading: string, key: string, value
|
|
22
|
+
export declare function addDiagnosticsInfo(heading: string, key: string, value: unknown): void;
|
|
22
23
|
/** Removes every stored entry. */
|
|
23
24
|
export declare function clearFeedbackLogs(): Promise<void>;
|
|
24
25
|
/** Removes the entries a submission carried, by the ids the rendered files reported. */
|
|
25
|
-
export declare function
|
|
26
|
+
export declare function feedbacklog_transactions_remove(sentIds: string[]): Promise<void>;
|
|
26
27
|
/** feedbacklog.txt from the stored log lines, or null when there are none. */
|
|
27
28
|
export declare function toLogFile(): Promise<RenderedFile | null>;
|
|
28
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The log lines for showing in the modal before sending, each time in the visitor's local zone.
|
|
31
|
+
* The file that is sent (toLogFile) keeps the ISO 8601 UTC stamps, so the server and anything
|
|
32
|
+
* that parses it are unaffected.
|
|
33
|
+
*/
|
|
29
34
|
export declare function logText(): Promise<string>;
|
|
30
|
-
/** The diagnostics entries as dyninfo.txt
|
|
35
|
+
/** The diagnostics entries as dyninfo.txt carries them. */
|
|
31
36
|
export declare function diagnosticsText(): Promise<string>;
|
|
32
37
|
/** True when any log line is waiting, so the modal knows whether to offer the toggle. */
|
|
33
38
|
export declare function hasLogLines(): Promise<boolean>;
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
* `deviceInfo`. Returns null only when there is nothing at all to put in it.
|
|
37
|
-
*/
|
|
38
|
-
export declare function toDyninfoFile(deviceInfo: string | null): Promise<RenderedFile | null>;
|
|
39
|
+
/** dyninfo.txt: the stored diagnostics entries. Returns null when there are none. */
|
|
40
|
+
export declare function toDyninfoFile(): Promise<RenderedFile | null>;
|
|
39
41
|
/** True when any diagnostics entry is waiting, so a submission knows to send dyninfo unasked. */
|
|
40
42
|
export declare function hasDiagnostics(): Promise<boolean>;
|
|
@@ -1,7 +1,8 @@
|
|
|
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
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var logger = require('../core/logger.js');
|
|
5
|
+
var db = require('../core/db.js');
|
|
5
6
|
var storage = require('../core/storage.js');
|
|
6
7
|
var state = require('../core/state.js');
|
|
7
8
|
var utils = require('../core/utils.js');
|
|
@@ -26,18 +27,19 @@ const MAX_LOG_FILE_SIZE = 2 * 1024 * 1024;
|
|
|
26
27
|
const TRIM_DELAY_MS = 2000;
|
|
27
28
|
const LOG_FILE_NAME = 'feedbacklog.txt'; // no i18n
|
|
28
29
|
const DYNINFO_FILE_NAME = 'dyninfo.txt'; // no i18n
|
|
29
|
-
|
|
30
|
-
const
|
|
30
|
+
// the types the entries are stored under (2.0.0-beta and 1.x said log and diagnostics)
|
|
31
|
+
const LOG = db.FEEDBACK_LOG;
|
|
32
|
+
const DIAGNOSTICS = db.FEEDBACK_DIAGNOSTICS;
|
|
31
33
|
let trimScheduled = false;
|
|
32
34
|
/** Drops the oldest entries once the store is over MAX_ENTRIES. */
|
|
33
35
|
function trimStoredLogs() {
|
|
34
|
-
return storage.
|
|
36
|
+
return storage.feedbacklog_transactions.all().then(function (items) {
|
|
35
37
|
const excess = items.length - MAX_ENTRIES;
|
|
36
38
|
if (excess <= 0) {
|
|
37
39
|
return undefined;
|
|
38
40
|
}
|
|
39
41
|
logger.Console.warn('apptics: dropping ' + excess + ' oldest feedback log entries (cap is ' + MAX_ENTRIES + ')'); // no i18n
|
|
40
|
-
return storage.
|
|
42
|
+
return storage.feedbacklog_transactions.remove(items.slice(0, excess));
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
/** One trim per burst of adds, so a chatty app pays for one pass over the store, not one per line. */
|
|
@@ -52,7 +54,7 @@ function scheduleTrim() {
|
|
|
52
54
|
}, TRIM_DELAY_MS);
|
|
53
55
|
}
|
|
54
56
|
function store(item) {
|
|
55
|
-
storage.
|
|
57
|
+
storage.feedbacklog_transactions.add(item);
|
|
56
58
|
scheduleTrim();
|
|
57
59
|
}
|
|
58
60
|
function truncate(text) {
|
|
@@ -72,11 +74,30 @@ function addFeedbackLog(message) {
|
|
|
72
74
|
* Records a diagnostics key/value under a heading, sent inside dyninfo.txt.
|
|
73
75
|
* Entries sharing a heading are grouped together in the file.
|
|
74
76
|
*/
|
|
77
|
+
/** Messages already printed, so a call repeated in a loop says so once. */
|
|
78
|
+
const refusedSaid = {};
|
|
79
|
+
function refuse(message) {
|
|
80
|
+
if (!refusedSaid[message]) {
|
|
81
|
+
refusedSaid[message] = true;
|
|
82
|
+
logger.warnAlways('AppticsFeedback.addDiagnosticsInfo: ' + message + ', so the entry is not recorded'); // no i18n
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Records a diagnostics entry, `value` under `key` in the `heading` block of dyninfo.txt. All three
|
|
87
|
+
* are required: an entry without a value says nothing, so it is refused and the console says why.
|
|
88
|
+
* A value of 0 or false is a value.
|
|
89
|
+
*/
|
|
75
90
|
function addDiagnosticsInfo(heading, key, value) {
|
|
76
91
|
if (typeof heading !== 'string' || heading.length === 0) { // no i18n
|
|
92
|
+
refuse('a heading is required');
|
|
77
93
|
return;
|
|
78
94
|
}
|
|
79
95
|
if (typeof key !== 'string' || key.length === 0) { // no i18n
|
|
96
|
+
refuse('a key is required');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (value === undefined || value === null || value === '') { // no i18n
|
|
100
|
+
refuse('a value is required for "' + heading + '" / "' + key + '"');
|
|
80
101
|
return;
|
|
81
102
|
}
|
|
82
103
|
store({
|
|
@@ -84,16 +105,16 @@ function addDiagnosticsInfo(heading, key, value) {
|
|
|
84
105
|
happenedat: utils.nowMs(),
|
|
85
106
|
heading: heading,
|
|
86
107
|
key: key,
|
|
87
|
-
value: truncate(String(value
|
|
108
|
+
value: truncate(String(value)),
|
|
88
109
|
});
|
|
89
110
|
}
|
|
90
111
|
/** Removes the entries a submission carried, by the ids the rendered files reported. */
|
|
91
|
-
function
|
|
92
|
-
return storage.
|
|
112
|
+
function feedbacklog_transactions_remove(sentIds) {
|
|
113
|
+
return storage.feedbacklog_transactions.remove(sentIds.map(function (id) { return { id: id }; }));
|
|
93
114
|
}
|
|
94
115
|
/** Entries of one type, oldest first, skipping any that have passed batch_request_timeout. */
|
|
95
116
|
function entriesOfType(type) {
|
|
96
|
-
return storage.
|
|
117
|
+
return storage.feedbacklog_transactions.all().then(function (items) {
|
|
97
118
|
return items.filter(function (item) {
|
|
98
119
|
return item.type === type && !state.isExpired(item.happenedat);
|
|
99
120
|
});
|
|
@@ -147,11 +168,29 @@ function toLogFile() {
|
|
|
147
168
|
return asFile(LOG_FILE_NAME, renderLogLines(items), items);
|
|
148
169
|
});
|
|
149
170
|
}
|
|
150
|
-
/**
|
|
171
|
+
/** `16 Oct 2026, 11:53:48 PM`: a log line's time in the visitor's own zone, for the viewer. */
|
|
172
|
+
function readableStamp(item) {
|
|
173
|
+
var iso = stamp(item);
|
|
174
|
+
var d = new Date(iso);
|
|
175
|
+
if (isNaN(d.getTime())) {
|
|
176
|
+
return iso;
|
|
177
|
+
}
|
|
178
|
+
return d.toLocaleDateString(undefined, { day: '2-digit', month: 'short', year: 'numeric' }) + ', ' + // no i18n
|
|
179
|
+
d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' }); // no i18n
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The log lines for showing in the modal before sending, each time in the visitor's local zone.
|
|
183
|
+
* The file that is sent (toLogFile) keeps the ISO 8601 UTC stamps, so the server and anything
|
|
184
|
+
* that parses it are unaffected.
|
|
185
|
+
*/
|
|
151
186
|
function logText() {
|
|
152
|
-
return entriesOfType(LOG).then(
|
|
187
|
+
return entriesOfType(LOG).then(function (items) {
|
|
188
|
+
return items.map(function (item) {
|
|
189
|
+
return '[' + readableStamp(item) + '] ' + item.message; // no i18n
|
|
190
|
+
}).join('\n'); // no i18n
|
|
191
|
+
});
|
|
153
192
|
}
|
|
154
|
-
/** The diagnostics entries as dyninfo.txt
|
|
193
|
+
/** The diagnostics entries as dyninfo.txt carries them. */
|
|
155
194
|
function diagnosticsText() {
|
|
156
195
|
return entriesOfType(DIAGNOSTICS).then(groupDiagnostics);
|
|
157
196
|
}
|
|
@@ -161,23 +200,13 @@ function hasLogLines() {
|
|
|
161
200
|
return items.length > 0;
|
|
162
201
|
});
|
|
163
202
|
}
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
* `deviceInfo`. Returns null only when there is nothing at all to put in it.
|
|
167
|
-
*/
|
|
168
|
-
function toDyninfoFile(deviceInfo) {
|
|
203
|
+
/** dyninfo.txt: the stored diagnostics entries. Returns null when there are none. */
|
|
204
|
+
function toDyninfoFile() {
|
|
169
205
|
return entriesOfType(DIAGNOSTICS).then(function (items) {
|
|
170
|
-
|
|
171
|
-
if (items.length > 0) {
|
|
172
|
-
blocks.push(groupDiagnostics(items));
|
|
173
|
-
}
|
|
174
|
-
if (deviceInfo) {
|
|
175
|
-
blocks.push('[Device Info]\n' + deviceInfo); // no i18n
|
|
176
|
-
}
|
|
177
|
-
if (blocks.length === 0) {
|
|
206
|
+
if (items.length === 0) {
|
|
178
207
|
return null;
|
|
179
208
|
}
|
|
180
|
-
return asFile(DYNINFO_FILE_NAME,
|
|
209
|
+
return asFile(DYNINFO_FILE_NAME, groupDiagnostics(items), items);
|
|
181
210
|
});
|
|
182
211
|
}
|
|
183
212
|
/** True when any diagnostics entry is waiting, so a submission knows to send dyninfo unasked. */
|
|
@@ -193,10 +222,10 @@ exports.MAX_LOG_FILE_SIZE = MAX_LOG_FILE_SIZE;
|
|
|
193
222
|
exports.addDiagnosticsInfo = addDiagnosticsInfo;
|
|
194
223
|
exports.addFeedbackLog = addFeedbackLog;
|
|
195
224
|
exports.diagnosticsText = diagnosticsText;
|
|
225
|
+
exports.feedbacklog_transactions_remove = feedbacklog_transactions_remove;
|
|
196
226
|
exports.hasDiagnostics = hasDiagnostics;
|
|
197
227
|
exports.hasLogLines = hasLogLines;
|
|
198
228
|
exports.logText = logText;
|
|
199
|
-
exports.log_transactions_remove = log_transactions_remove;
|
|
200
229
|
exports.toDyninfoFile = toDyninfoFile;
|
|
201
230
|
exports.toLogFile = toLogFile;
|
|
202
231
|
exports.trimStoredLogs = trimStoredLogs;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** quartz_domain as a recording host: zoho.com → https://quartz.zoho.com. '' when it isn't a domain. */
|
|
2
|
+
export declare function recordingDomain(domain: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The Quartz script for an app whose getsdkconfig answer carries no quartz_cdn_url, chosen by
|
|
5
|
+
* the serviceUrl: a localzoho server's apps load it from Zoho's local CDN, every other app from
|
|
6
|
+
* the public one.
|
|
7
|
+
*/
|
|
8
|
+
export declare function defaultQuartzScriptUrl(serviceUrl: string): string;
|
|
9
|
+
/** The script to load: quartz_cdn_url when getsdkconfig gave one, else the CDN the serviceUrl points to. */
|
|
10
|
+
export declare function quartzScriptSource(cdnUrl: string, serviceUrl: string): string;
|
|
11
|
+
/** The url to load, or '' when it isn't an https url on a Zoho host. */
|
|
12
|
+
export declare function quartzScriptUrl(url: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Makes Quartz available: resolves true once it is on the page, false when it can't be (no url,
|
|
15
|
+
* a url that isn't allowed, or a script that failed to load). Adds the script once; every caller
|
|
16
|
+
* waits on the same load, and a failed one may be tried again on the next open.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadQuartz(url: string): Promise<boolean>;
|