expensify-common 2.0.13 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/API.js +48 -24
- package/dist/APIDeferred.js +48 -27
- package/dist/BrowserDetect.js +26 -3
- package/dist/CONST.d.ts +4 -4
- package/dist/CONST.js +4 -4
- package/dist/ExpenseRule.js +3 -7
- package/dist/ExpensiMark.js +33 -39
- package/dist/Func.d.ts +2 -2
- package/dist/Func.js +33 -10
- package/dist/Log.js +27 -5
- package/dist/Logger.js +3 -2
- package/dist/Network.js +32 -10
- package/dist/Num.js +1 -2
- package/dist/PubSub.js +34 -11
- package/dist/ReportHistoryStore.js +11 -15
- package/dist/Templates.js +34 -11
- package/dist/components/StepProgressBar.js +2 -3
- package/dist/components/form/element/combobox.d.ts +1 -0
- package/dist/components/form/element/combobox.js +61 -35
- package/dist/components/form/element/dropdown.js +3 -3
- package/dist/components/form/element/switch.js +3 -5
- package/dist/mixins/PubSub.d.ts +2 -2
- package/dist/mixins/PubSub.js +30 -5
- package/dist/mixins/extraClasses.js +25 -2
- package/dist/str.js +3 -15
- package/dist/utils.d.ts +26 -1
- package/dist/utils.js +60 -1
- package/package.json +2 -3
package/dist/API.js
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
2
|
/**
|
|
7
3
|
* ----------------------------------------------------------------------------------------------
|
|
8
4
|
* WIP, This is in the process of migration from web-e. Please add methods to this as is needed.|
|
|
9
5
|
* ----------------------------------------------------------------------------------------------
|
|
10
6
|
*/
|
|
11
|
-
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
24
|
+
if (mod && mod.__esModule) return mod;
|
|
25
|
+
var result = {};
|
|
26
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
27
|
+
__setModuleDefault(result, mod);
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
34
|
// Use this deferred lib so we don't have a dependency on jQuery (so we can use this module in mobile)
|
|
13
35
|
const simply_deferred_1 = require("simply-deferred");
|
|
36
|
+
const lodash_1 = require("lodash");
|
|
14
37
|
const APIDeferred_1 = __importDefault(require("./APIDeferred"));
|
|
15
|
-
const
|
|
38
|
+
const Utils = __importStar(require("./utils"));
|
|
16
39
|
/**
|
|
17
40
|
* @param {Network} network
|
|
18
41
|
* @param {Object} [args]
|
|
@@ -40,14 +63,14 @@ function API(network, args) {
|
|
|
40
63
|
* Returns a promise that is rejected if a change is detected
|
|
41
64
|
* Otherwise, it is resolved successfully
|
|
42
65
|
*
|
|
43
|
-
* @returns {Object}
|
|
66
|
+
* @returns {Object} Deferred
|
|
44
67
|
*/
|
|
45
68
|
function isRunningLatestVersionOfCode() {
|
|
46
69
|
const promise = new simply_deferred_1.Deferred();
|
|
47
70
|
network
|
|
48
71
|
.get('/revision.txt')
|
|
49
72
|
.done((codeRevision) => {
|
|
50
|
-
if (
|
|
73
|
+
if (Utils.isWindowAvailable() && codeRevision.trim() === window.CODE_REVISION) {
|
|
51
74
|
console.debug('Code revision is up to date');
|
|
52
75
|
promise.resolve();
|
|
53
76
|
}
|
|
@@ -72,7 +95,7 @@ function API(network, args) {
|
|
|
72
95
|
* @param {String} apiDeferred
|
|
73
96
|
*/
|
|
74
97
|
function attachJSONCodeCallbacks(apiDeferred) {
|
|
75
|
-
|
|
98
|
+
Object.entries(defaultHandlers).forEach(([code, callbacks]) => {
|
|
76
99
|
// The key, `code`, is returned as a string, so we must cast it to an Integer
|
|
77
100
|
const jsonCode = parseInt(code, 10);
|
|
78
101
|
callbacks.forEach((callback) => {
|
|
@@ -101,7 +124,7 @@ function API(network, args) {
|
|
|
101
124
|
function performPOSTRequest(command, parameters, returnedPropertyName, keepalive, checkCodeRevision) {
|
|
102
125
|
let newParameters = Object.assign(Object.assign({}, parameters), { command });
|
|
103
126
|
// If there was an enhanceParameters() method supplied in our args, then we will call that here
|
|
104
|
-
if (args &&
|
|
127
|
+
if (args && Utils.isFunction(args.enhanceParameters)) {
|
|
105
128
|
newParameters = args.enhanceParameters(newParameters);
|
|
106
129
|
}
|
|
107
130
|
// We need to setup multiple promises here depending on our arguments. If there is no argument, then we will just
|
|
@@ -142,17 +165,18 @@ function API(network, args) {
|
|
|
142
165
|
function requireParameters(parameterNames, parameters, commandName) {
|
|
143
166
|
// eslint-disable-next-line rulesdir/prefer-early-return
|
|
144
167
|
parameterNames.forEach((parameterName) => {
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
throw new Error(`Parameter ${parameterName} is required for "${commandName}". Supplied parameters: ${keys}`);
|
|
168
|
+
if ((0, lodash_1.has)(parameters, parameterName) && parameters[parameterName] !== null && parameters[parameterName] !== undefined) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const parametersCopy = Object.assign({}, parameters);
|
|
172
|
+
if ((0, lodash_1.has)(parametersCopy, 'authToken')) {
|
|
173
|
+
parametersCopy.authToken = '<redacted>';
|
|
174
|
+
}
|
|
175
|
+
if ((0, lodash_1.has)(parametersCopy, 'password')) {
|
|
176
|
+
parametersCopy.password = '<redacted>';
|
|
155
177
|
}
|
|
178
|
+
const keys = Object.keys(parametersCopy).join(', ') || 'none';
|
|
179
|
+
throw new Error(`Parameter ${parameterName} is required for "${commandName}". Supplied parameters: ${keys}`);
|
|
156
180
|
});
|
|
157
181
|
}
|
|
158
182
|
return {
|
|
@@ -161,7 +185,7 @@ function API(network, args) {
|
|
|
161
185
|
* @param {Function} callback
|
|
162
186
|
*/
|
|
163
187
|
registerDefaultHandler(jsonCodes, callback) {
|
|
164
|
-
if (!
|
|
188
|
+
if (!Utils.isFunction(callback)) {
|
|
165
189
|
return;
|
|
166
190
|
}
|
|
167
191
|
jsonCodes.forEach((jsonCode) => {
|
|
@@ -213,7 +237,7 @@ function API(network, args) {
|
|
|
213
237
|
}
|
|
214
238
|
return (parameters, keepalive = false) => {
|
|
215
239
|
// Optional validate function for required logic before making the call. e.g. validating params in the front-end etc.
|
|
216
|
-
if (
|
|
240
|
+
if (Utils.isFunction(data.validate)) {
|
|
217
241
|
data.validate(parameters);
|
|
218
242
|
}
|
|
219
243
|
requireParameters(data.requireParameters || [], parameters, data.commandName);
|
|
@@ -243,7 +267,7 @@ function API(network, args) {
|
|
|
243
267
|
const commandName = 'GetAccountStatus';
|
|
244
268
|
requireParameters(['email'], parameters, commandName);
|
|
245
269
|
// Tell the API not to set cookies for this request
|
|
246
|
-
const newParameters =
|
|
270
|
+
const newParameters = Object.assign(Object.assign({}, parameters), { api_setCookie: false });
|
|
247
271
|
return performPOSTRequest(commandName, newParameters);
|
|
248
272
|
},
|
|
249
273
|
/**
|
|
@@ -387,7 +411,7 @@ function API(network, args) {
|
|
|
387
411
|
resetPassword(parameters) {
|
|
388
412
|
const commandName = 'ResetPassword';
|
|
389
413
|
requireParameters(['email'], parameters, commandName);
|
|
390
|
-
const newParameters =
|
|
414
|
+
const newParameters = Object.assign(Object.assign({}, parameters), { api_setCookie: false });
|
|
391
415
|
return performPOSTRequest(commandName, newParameters);
|
|
392
416
|
},
|
|
393
417
|
/**
|
package/dist/APIDeferred.js
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2
26
|
/**
|
|
3
27
|
* ----------------------------------------------------------------------------------------------
|
|
4
28
|
* WIP, This is in the process of migration from web-e. Please add methods to this as is needed.|
|
|
5
29
|
* ----------------------------------------------------------------------------------------------
|
|
6
30
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
const underscore_1 = __importDefault(require("underscore"));
|
|
12
|
-
const Func_1 = require("./Func");
|
|
31
|
+
const lodash_1 = require("lodash");
|
|
32
|
+
const Utils = __importStar(require("./utils"));
|
|
33
|
+
const Func = __importStar(require("./Func"));
|
|
13
34
|
/**
|
|
14
35
|
* @param {jquery.Deferred} promise
|
|
15
36
|
* @param {String} [extractedProperty]
|
|
@@ -50,15 +71,15 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
50
71
|
function handleError(jsonCode, response) {
|
|
51
72
|
// Look for handlers for this error code
|
|
52
73
|
const handlers = errorHandlers[jsonCode];
|
|
53
|
-
if (
|
|
54
|
-
|
|
74
|
+
if (handlers.length > 0) {
|
|
75
|
+
Func.bulkInvoke(handlers, [jsonCode, response]);
|
|
55
76
|
}
|
|
56
77
|
else {
|
|
57
78
|
// No explicit handlers, call the unhandled callbacks
|
|
58
|
-
|
|
79
|
+
Func.bulkInvoke(unhandledCallbacks, [jsonCode, response]);
|
|
59
80
|
}
|
|
60
81
|
// Always run the "fail" callbacks in case of error
|
|
61
|
-
|
|
82
|
+
Func.bulkInvoke(failCallbacks, [jsonCode, response]);
|
|
62
83
|
}
|
|
63
84
|
/**
|
|
64
85
|
* Called when network call succeeds or when a callback is added via any of the following methods after the promise is resolved:
|
|
@@ -71,8 +92,8 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
71
92
|
let returnedData;
|
|
72
93
|
// Figure out if we need to extract a property from the response, and if it is there.
|
|
73
94
|
const jsonCode = extractJSONCode(response);
|
|
74
|
-
const propertyRequested = !
|
|
75
|
-
const requestedPropertyPresent = propertyRequested && response &&
|
|
95
|
+
const propertyRequested = !Number.isNull(extractedPropertyName);
|
|
96
|
+
const requestedPropertyPresent = propertyRequested && response && response[extractedPropertyName] !== undefined;
|
|
76
97
|
const propertyRequestedButMissing = propertyRequested && !requestedPropertyPresent;
|
|
77
98
|
// Save the response for any callbacks that might run in the future
|
|
78
99
|
cachedResponse = response;
|
|
@@ -81,9 +102,9 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
81
102
|
// Get the data that was requested
|
|
82
103
|
returnedData = propertyRequested && requestedPropertyPresent ? response[extractedPropertyName] : response;
|
|
83
104
|
// And then run the success callbacks
|
|
84
|
-
|
|
105
|
+
Func.bulkInvoke(doneCallbacks, [returnedData]);
|
|
85
106
|
}
|
|
86
|
-
else if (
|
|
107
|
+
else if (jsonCode !== null && jsonCode !== 200) {
|
|
87
108
|
// Exception thrown, handle it
|
|
88
109
|
handleError(jsonCode, response);
|
|
89
110
|
}
|
|
@@ -98,7 +119,7 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
98
119
|
}
|
|
99
120
|
}
|
|
100
121
|
// Always run the "always" callbacks
|
|
101
|
-
|
|
122
|
+
Func.bulkInvoke(alwaysCallbacks, [response]);
|
|
102
123
|
}
|
|
103
124
|
/**
|
|
104
125
|
* Re-runs the "done" flow with a saved response to ensure that all callbacks are invoked,
|
|
@@ -125,8 +146,8 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
125
146
|
* @returns {APIDeferred} itself, for chaining
|
|
126
147
|
*/
|
|
127
148
|
done(callback) {
|
|
128
|
-
if (
|
|
129
|
-
doneCallbacks.push((0,
|
|
149
|
+
if (Utils.isFunction(callback)) {
|
|
150
|
+
doneCallbacks.push((0, lodash_1.once)(callback));
|
|
130
151
|
ensureFutureCallbacksFire();
|
|
131
152
|
}
|
|
132
153
|
return this;
|
|
@@ -139,8 +160,8 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
139
160
|
* @returns {APIDeferred} itself, for chaining
|
|
140
161
|
*/
|
|
141
162
|
always(callback) {
|
|
142
|
-
if (
|
|
143
|
-
alwaysCallbacks.push((0,
|
|
163
|
+
if (Utils.isFunction(callback)) {
|
|
164
|
+
alwaysCallbacks.push((0, lodash_1.once)(callback));
|
|
144
165
|
ensureFutureCallbacksFire();
|
|
145
166
|
}
|
|
146
167
|
return this;
|
|
@@ -155,7 +176,7 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
155
176
|
* @returns {APIDeferred} itself, for chaining
|
|
156
177
|
*/
|
|
157
178
|
handle(jsonCodes, callback) {
|
|
158
|
-
if (
|
|
179
|
+
if (Utils.isFunction(callback)) {
|
|
159
180
|
jsonCodes.forEach((code) => {
|
|
160
181
|
if (code === 200) {
|
|
161
182
|
return;
|
|
@@ -163,7 +184,7 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
163
184
|
if (!errorHandlers[code]) {
|
|
164
185
|
errorHandlers[code] = [];
|
|
165
186
|
}
|
|
166
|
-
errorHandlers[code].push((0,
|
|
187
|
+
errorHandlers[code].push((0, lodash_1.once)(callback));
|
|
167
188
|
});
|
|
168
189
|
ensureFutureCallbacksFire();
|
|
169
190
|
}
|
|
@@ -177,8 +198,8 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
177
198
|
* @returns {APIDeferred} itself, for chaining
|
|
178
199
|
*/
|
|
179
200
|
unhandled(callback) {
|
|
180
|
-
if (
|
|
181
|
-
unhandledCallbacks.push((0,
|
|
201
|
+
if (Utils.isFunction(callback)) {
|
|
202
|
+
unhandledCallbacks.push((0, lodash_1.once)(callback));
|
|
182
203
|
ensureFutureCallbacksFire();
|
|
183
204
|
}
|
|
184
205
|
return this;
|
|
@@ -192,8 +213,8 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
192
213
|
* @returns {APIDeferred} itself, for chaining
|
|
193
214
|
*/
|
|
194
215
|
fail(callback) {
|
|
195
|
-
if (
|
|
196
|
-
failCallbacks.push((0,
|
|
216
|
+
if (Utils.isFunction(callback)) {
|
|
217
|
+
failCallbacks.push((0, lodash_1.once)(callback));
|
|
197
218
|
ensureFutureCallbacksFire();
|
|
198
219
|
}
|
|
199
220
|
return this;
|
|
@@ -208,10 +229,10 @@ function APIDeferred(promise, extractedProperty) {
|
|
|
208
229
|
then(callback) {
|
|
209
230
|
return promise.then((response) => {
|
|
210
231
|
const responseCode = extractJSONCode(response);
|
|
211
|
-
if (responseCode !== 200 || !
|
|
232
|
+
if (responseCode !== 200 || !Utils.isFunction(callback)) {
|
|
212
233
|
return;
|
|
213
234
|
}
|
|
214
|
-
|
|
235
|
+
Func.invoke(callback, [response]);
|
|
215
236
|
return this;
|
|
216
237
|
});
|
|
217
238
|
},
|
package/dist/BrowserDetect.js
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
26
|
+
const Utils = __importStar(require("./utils"));
|
|
4
27
|
const BROWSERS = {
|
|
5
28
|
EDGE: 'Edge',
|
|
6
29
|
CHROME: 'Chrome',
|
|
@@ -14,7 +37,7 @@ const MOBILE_PLATFORMS = {
|
|
|
14
37
|
android: 'android',
|
|
15
38
|
};
|
|
16
39
|
function searchString() {
|
|
17
|
-
if (!
|
|
40
|
+
if (!Utils.isWindowAvailable() || !Utils.isNavigatorAvailable()) {
|
|
18
41
|
return '';
|
|
19
42
|
}
|
|
20
43
|
const data = [
|
|
@@ -75,7 +98,7 @@ function searchString() {
|
|
|
75
98
|
return '';
|
|
76
99
|
}
|
|
77
100
|
function getMobileDevice() {
|
|
78
|
-
if (!
|
|
101
|
+
if (!Utils.isNavigatorAvailable() || !navigator.userAgent) {
|
|
79
102
|
return '';
|
|
80
103
|
}
|
|
81
104
|
const data = [
|
package/dist/CONST.d.ts
CHANGED
|
@@ -756,22 +756,22 @@ declare const CONST: {
|
|
|
756
756
|
readonly TOO_LIMITED: {
|
|
757
757
|
readonly id: "tooLimited";
|
|
758
758
|
readonly label: "Functionality needs improvement";
|
|
759
|
-
readonly prompt: "What software are you
|
|
759
|
+
readonly prompt: "What software are you moving to and why?";
|
|
760
760
|
};
|
|
761
761
|
readonly TOO_EXPENSIVE: {
|
|
762
762
|
readonly id: "tooExpensive";
|
|
763
763
|
readonly label: "Too expensive";
|
|
764
|
-
readonly prompt: "What software are you
|
|
764
|
+
readonly prompt: "What software are you moving to and why?";
|
|
765
765
|
};
|
|
766
766
|
readonly INADEQUATE_SUPPORT: {
|
|
767
767
|
readonly id: "inadequateSupport";
|
|
768
768
|
readonly label: "Inadequate customer support";
|
|
769
|
-
readonly prompt: "What software are you
|
|
769
|
+
readonly prompt: "What software are you moving to and why?";
|
|
770
770
|
};
|
|
771
771
|
readonly BUSINESS_CLOSING: {
|
|
772
772
|
readonly id: "businessClosing";
|
|
773
773
|
readonly label: "Company closing, downsizing, or acquired";
|
|
774
|
-
readonly prompt: "What software are you
|
|
774
|
+
readonly prompt: "What software are you moving to and why?";
|
|
775
775
|
};
|
|
776
776
|
};
|
|
777
777
|
};
|
package/dist/CONST.js
CHANGED
|
@@ -799,22 +799,22 @@ const CONST = {
|
|
|
799
799
|
TOO_LIMITED: {
|
|
800
800
|
id: 'tooLimited',
|
|
801
801
|
label: 'Functionality needs improvement',
|
|
802
|
-
prompt: 'What software are you
|
|
802
|
+
prompt: 'What software are you moving to and why?',
|
|
803
803
|
},
|
|
804
804
|
TOO_EXPENSIVE: {
|
|
805
805
|
id: 'tooExpensive',
|
|
806
806
|
label: 'Too expensive',
|
|
807
|
-
prompt: 'What software are you
|
|
807
|
+
prompt: 'What software are you moving to and why?',
|
|
808
808
|
},
|
|
809
809
|
INADEQUATE_SUPPORT: {
|
|
810
810
|
id: 'inadequateSupport',
|
|
811
811
|
label: 'Inadequate customer support',
|
|
812
|
-
prompt: 'What software are you
|
|
812
|
+
prompt: 'What software are you moving to and why?',
|
|
813
813
|
},
|
|
814
814
|
BUSINESS_CLOSING: {
|
|
815
815
|
id: 'businessClosing',
|
|
816
816
|
label: 'Company closing, downsizing, or acquired',
|
|
817
|
-
prompt: 'What software are you
|
|
817
|
+
prompt: 'What software are you moving to and why?',
|
|
818
818
|
},
|
|
819
819
|
},
|
|
820
820
|
};
|
package/dist/ExpenseRule.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const underscore_1 = __importDefault(require("underscore"));
|
|
7
3
|
class ExpenseRule {
|
|
8
4
|
/**
|
|
9
5
|
* Creates a new instance of this class.
|
|
@@ -11,7 +7,7 @@ class ExpenseRule {
|
|
|
11
7
|
* @param {Array} ruleArray
|
|
12
8
|
*/
|
|
13
9
|
constructor(ruleArray) {
|
|
14
|
-
|
|
10
|
+
ruleArray.forEach((value, key) => {
|
|
15
11
|
this[key] = value;
|
|
16
12
|
});
|
|
17
13
|
}
|
|
@@ -24,7 +20,7 @@ class ExpenseRule {
|
|
|
24
20
|
* @return {Object}
|
|
25
21
|
*/
|
|
26
22
|
getApplyWhenByField(field) {
|
|
27
|
-
return
|
|
23
|
+
return this.applyWhen.find((conditions) => conditions.field === field) || {};
|
|
28
24
|
}
|
|
29
25
|
/**
|
|
30
26
|
* Get the externalID saved deep in the tax field
|
|
@@ -42,7 +38,7 @@ class ExpenseRule {
|
|
|
42
38
|
*/
|
|
43
39
|
isMatch(expense) {
|
|
44
40
|
let isMatch = true;
|
|
45
|
-
|
|
41
|
+
this.applyWhen.forEach((conditions) => {
|
|
46
42
|
switch (conditions.field) {
|
|
47
43
|
case 'category':
|
|
48
44
|
if (!this.checkCondition(conditions.condition, conditions.value, expense.getCategory())) {
|
package/dist/ExpensiMark.js
CHANGED
|
@@ -26,11 +26,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const _ = __importStar(require("underscore"));
|
|
30
29
|
const str_1 = __importDefault(require("./str"));
|
|
31
30
|
const Constants = __importStar(require("./CONST"));
|
|
32
31
|
const UrlPatterns = __importStar(require("./Url"));
|
|
33
32
|
const Logger_1 = __importDefault(require("./Logger"));
|
|
33
|
+
const Utils = __importStar(require("./utils"));
|
|
34
34
|
const MARKDOWN_LINK_REGEX = new RegExp(`\\[([^\\][]*(?:\\[[^\\][]*][^\\][]*)*)]\\(${UrlPatterns.MARKDOWN_URL_REGEX}\\)(?![^<]*(<\\/pre>|<\\/code>))`, 'gi');
|
|
35
35
|
const MARKDOWN_IMAGE_REGEX = new RegExp(`\\!(?:\\[([^\\][]*(?:\\[[^\\][]*][^\\][]*)*)])?\\(${UrlPatterns.MARKDOWN_URL_REGEX}\\)(?![^<]*(<\\/pre>|<\\/code>))`, 'gi');
|
|
36
36
|
const SLACK_SPAN_NEW_LINE_TAG = '<span class="c-mrkdwn__br" data-stringify-type="paragraph-break" style="box-sizing: inherit; display: block; height: unset;"></span>';
|
|
@@ -426,27 +426,21 @@ class ExpensiMark {
|
|
|
426
426
|
.trim()
|
|
427
427
|
.split('\n');
|
|
428
428
|
// Wrap each string in the array with <blockquote> and </blockquote>
|
|
429
|
-
|
|
430
|
-
function wrapWithBlockquote(line) {
|
|
429
|
+
resultString = resultString.map((line) => {
|
|
431
430
|
return `<blockquote>${line}</blockquote>`;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
return `${'>'.repeat(depth)} ${modifiedText}`;
|
|
446
|
-
}
|
|
447
|
-
return replaceBlockquotes(m);
|
|
448
|
-
}
|
|
449
|
-
resultString = _.map(resultString, processString).join('\n');
|
|
431
|
+
});
|
|
432
|
+
resultString = resultString
|
|
433
|
+
.map((text) => {
|
|
434
|
+
let modifiedText = text;
|
|
435
|
+
let depth;
|
|
436
|
+
do {
|
|
437
|
+
depth = (modifiedText.match(/<blockquote>/gi) || []).length;
|
|
438
|
+
modifiedText = modifiedText.replace(/<blockquote>/gi, '');
|
|
439
|
+
modifiedText = modifiedText.replace(/<\/blockquote>/gi, '');
|
|
440
|
+
} while (/<blockquote>/i.test(modifiedText));
|
|
441
|
+
return `${'>'.repeat(depth)} ${modifiedText}`;
|
|
442
|
+
})
|
|
443
|
+
.join('\n');
|
|
450
444
|
// We want to keep <blockquote> tag here and let method replaceBlockElementWithNewLine to handle the line break later
|
|
451
445
|
return `<blockquote>${resultString}</blockquote>`;
|
|
452
446
|
},
|
|
@@ -591,12 +585,12 @@ class ExpensiMark {
|
|
|
591
585
|
* @param {Object} rule - The rule to check.
|
|
592
586
|
* @returns {boolean} Returns true if the rule should be applied, otherwise false.
|
|
593
587
|
*/
|
|
594
|
-
this.filterRules = (rule) => !
|
|
588
|
+
this.filterRules = (rule) => !this.whitespaceRulesToDisable.includes(rule.name);
|
|
595
589
|
/**
|
|
596
590
|
* Filters rules to determine which should keep whitespace.
|
|
597
591
|
* @returns {Object[]} The filtered rules.
|
|
598
592
|
*/
|
|
599
|
-
this.shouldKeepWhitespaceRules =
|
|
593
|
+
this.shouldKeepWhitespaceRules = this.rules.filter(this.filterRules);
|
|
600
594
|
/**
|
|
601
595
|
* maxQuoteDepth is the maximum depth of nested quotes that we want to support.
|
|
602
596
|
* @type {Number}
|
|
@@ -610,16 +604,16 @@ class ExpensiMark {
|
|
|
610
604
|
}
|
|
611
605
|
getHtmlRuleset(filterRules, disabledRules, shouldKeepRawInput) {
|
|
612
606
|
let rules = this.rules;
|
|
613
|
-
const hasRuleName = (rule) =>
|
|
614
|
-
const hasDisabledRuleName = (rule) => !
|
|
607
|
+
const hasRuleName = (rule) => filterRules.includes(rule.name);
|
|
608
|
+
const hasDisabledRuleName = (rule) => !disabledRules.includes(rule.name);
|
|
615
609
|
if (shouldKeepRawInput) {
|
|
616
610
|
rules = this.shouldKeepWhitespaceRules;
|
|
617
611
|
}
|
|
618
|
-
if (
|
|
619
|
-
rules =
|
|
612
|
+
if (filterRules.length > 0) {
|
|
613
|
+
rules = this.rules.filter(hasRuleName);
|
|
620
614
|
}
|
|
621
|
-
if (
|
|
622
|
-
rules =
|
|
615
|
+
if (disabledRules.length > 0) {
|
|
616
|
+
rules = rules.filter(hasDisabledRuleName);
|
|
623
617
|
}
|
|
624
618
|
return rules;
|
|
625
619
|
}
|
|
@@ -638,7 +632,7 @@ class ExpensiMark {
|
|
|
638
632
|
*/
|
|
639
633
|
replace(text, { filterRules = [], shouldEscapeText = true, shouldKeepRawInput = false, disabledRules = [] } = {}) {
|
|
640
634
|
// This ensures that any html the user puts into the comment field shows as raw html
|
|
641
|
-
let replacedText = shouldEscapeText ?
|
|
635
|
+
let replacedText = shouldEscapeText ? Utils.escape(text) : text;
|
|
642
636
|
const rules = this.getHtmlRuleset(filterRules, disabledRules, shouldKeepRawInput);
|
|
643
637
|
const processRule = (rule) => {
|
|
644
638
|
// Pre-process text before applying regex
|
|
@@ -664,7 +658,7 @@ class ExpensiMark {
|
|
|
664
658
|
// eslint-disable-next-line no-console
|
|
665
659
|
console.warn('Error replacing text with html in ExpensiMark.replace', { error: e });
|
|
666
660
|
// We want to return text without applying rules if exception occurs during replacing
|
|
667
|
-
return shouldEscapeText ?
|
|
661
|
+
return shouldEscapeText ? Utils.escape(text) : text;
|
|
668
662
|
}
|
|
669
663
|
return replacedText;
|
|
670
664
|
}
|
|
@@ -817,7 +811,7 @@ class ExpensiMark {
|
|
|
817
811
|
// eslint-disable-next-line max-len
|
|
818
812
|
let splitText = htmlString.split(/<div.*?>|<\/div>|<comment.*?>|\n<\/comment>|<\/comment>|<h1>|<\/h1>|<h2>|<\/h2>|<h3>|<\/h3>|<h4>|<\/h4>|<h5>|<\/h5>|<h6>|<\/h6>|<p>|<\/p>|<li>|<\/li>|<blockquote>|<\/blockquote>/);
|
|
819
813
|
const stripHTML = (text) => str_1.default.stripHTML(text);
|
|
820
|
-
splitText =
|
|
814
|
+
splitText = splitText.map(stripHTML);
|
|
821
815
|
let joinedText = '';
|
|
822
816
|
// Delete whitespace at the end
|
|
823
817
|
while (splitText.length) {
|
|
@@ -863,7 +857,7 @@ class ExpensiMark {
|
|
|
863
857
|
generatedMarkdown = rule.pre(generatedMarkdown);
|
|
864
858
|
}
|
|
865
859
|
// if replacement is a function, we want to pass optional extras to it
|
|
866
|
-
const replacementFunction =
|
|
860
|
+
const replacementFunction = Utils.isFunction(rule.replacement) ? (...args) => rule.replacement(...args, extras) : rule.replacement;
|
|
867
861
|
generatedMarkdown = generatedMarkdown.replace(rule.regex, replacementFunction);
|
|
868
862
|
};
|
|
869
863
|
this.htmlToMarkdownRules.forEach(processRule);
|
|
@@ -881,7 +875,7 @@ class ExpensiMark {
|
|
|
881
875
|
let replacedText = htmlString;
|
|
882
876
|
const processRule = (rule) => {
|
|
883
877
|
// if replacement is a function, we want to pass optional extras to it
|
|
884
|
-
const replacementFunction =
|
|
878
|
+
const replacementFunction = Utils.isFunction(rule.replacement) ? (...args) => rule.replacement(...args, extras) : rule.replacement;
|
|
885
879
|
replacedText = replacedText.replace(rule.regex, replacementFunction);
|
|
886
880
|
};
|
|
887
881
|
this.htmlToTextRules.forEach(processRule);
|
|
@@ -966,7 +960,7 @@ class ExpensiMark {
|
|
|
966
960
|
}
|
|
967
961
|
return quoteContent;
|
|
968
962
|
};
|
|
969
|
-
let textToFormat =
|
|
963
|
+
let textToFormat = textToCheck.split('\n').map(formatRow).join('\n');
|
|
970
964
|
// Remove leading and trailing line breaks
|
|
971
965
|
textToFormat = textToFormat.replace(/^\n+|\n+$/g, '');
|
|
972
966
|
return replacement(textToFormat);
|
|
@@ -1019,7 +1013,7 @@ class ExpensiMark {
|
|
|
1019
1013
|
const matches = [...htmlString.matchAll(regex)];
|
|
1020
1014
|
// Element 1 from match is the regex group if it exists which contains the link URLs
|
|
1021
1015
|
const sanitizeMatch = (match) => str_1.default.sanitizeURL(match[1]);
|
|
1022
|
-
const links =
|
|
1016
|
+
const links = matches.map(sanitizeMatch);
|
|
1023
1017
|
return links;
|
|
1024
1018
|
}
|
|
1025
1019
|
catch (e) {
|
|
@@ -1038,7 +1032,7 @@ class ExpensiMark {
|
|
|
1038
1032
|
getRemovedMarkdownLinks(oldComment, newComment) {
|
|
1039
1033
|
const linksInOld = this.extractLinksInMarkdownComment(oldComment);
|
|
1040
1034
|
const linksInNew = this.extractLinksInMarkdownComment(newComment);
|
|
1041
|
-
return linksInOld === undefined || linksInNew === undefined ? [] :
|
|
1035
|
+
return linksInOld === undefined || linksInNew === undefined ? [] : linksInOld.filter((link) => !linksInNew.includes(link));
|
|
1042
1036
|
}
|
|
1043
1037
|
/**
|
|
1044
1038
|
* Escapes the content of an HTML attribute value
|
|
@@ -1053,11 +1047,11 @@ class ExpensiMark {
|
|
|
1053
1047
|
// When the attribute contains HTML and is converted back to MD we need to re-escape it to avoid
|
|
1054
1048
|
// illegal attribute value characters like `," or ' which might break the HTML
|
|
1055
1049
|
originalContent = str_1.default.replaceAll(originalContent, '\n', '');
|
|
1056
|
-
return
|
|
1050
|
+
return Utils.escape(originalContent);
|
|
1057
1051
|
}
|
|
1058
1052
|
}
|
|
1059
1053
|
ExpensiMark.Log = new Logger_1.default({
|
|
1060
|
-
serverLoggingCallback:
|
|
1054
|
+
serverLoggingCallback: () => { },
|
|
1061
1055
|
// eslint-disable-next-line no-console
|
|
1062
1056
|
clientLoggingCallback: (message) => console.warn(message),
|
|
1063
1057
|
isDebug: true,
|
package/dist/Func.d.ts
CHANGED
|
@@ -16,9 +16,9 @@ export function invoke(callback: Function, args?: any[] | undefined, scope?: Obj
|
|
|
16
16
|
* @param {Array} [args]
|
|
17
17
|
* @param {Object} [scope]
|
|
18
18
|
*
|
|
19
|
-
* @returns {
|
|
19
|
+
* @returns {Promise}
|
|
20
20
|
*/
|
|
21
|
-
export function invokeAsync(callback: Function, args?: any[] | undefined, scope?: Object | undefined):
|
|
21
|
+
export function invokeAsync(callback: Function, args?: any[] | undefined, scope?: Object | undefined): Promise<any>;
|
|
22
22
|
/**
|
|
23
23
|
* Invokes all the given callbacks with the given arguments
|
|
24
24
|
*
|