@expressms/smartapp-sdk 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/build/main/index.d.ts +7 -0
- package/build/main/index.js +23 -0
- package/build/main/lib/contacts/index.d.ts +13 -0
- package/build/main/lib/contacts/index.js +43 -0
- package/build/main/lib/helpers/helpers.d.ts +4 -0
- package/build/main/lib/helpers/helpers.js +9 -0
- package/build/main/lib/index.d.ts +2 -0
- package/build/main/lib/index.js +17 -0
- package/build/main/lib/logging/index.d.ts +7 -0
- package/build/main/lib/logging/index.js +19 -0
- package/build/main/lib/notification/index.d.ts +2 -0
- package/build/main/lib/notification/index.js +20 -0
- package/build/main/lib/routing/index.d.ts +3 -0
- package/build/main/lib/routing/index.js +25 -0
- package/build/main/types/bridge.d.ts +10 -0
- package/build/main/types/bridge.js +15 -0
- package/build/main/types/contacts.d.ts +8 -0
- package/build/main/types/contacts.js +3 -0
- package/build/main/types/index.d.ts +2 -0
- package/build/main/types/index.js +19 -0
- package/build/main/types/routing.d.ts +4 -0
- package/build/main/types/routing.js +9 -0
- package/build/module/index.d.ts +7 -0
- package/build/module/index.js +8 -0
- package/build/module/lib/contacts/index.d.ts +13 -0
- package/build/module/lib/contacts/index.js +34 -0
- package/build/module/lib/helpers/helpers.d.ts +4 -0
- package/build/module/lib/helpers/helpers.js +6 -0
- package/build/module/lib/index.d.ts +2 -0
- package/build/module/lib/index.js +11 -0
- package/build/module/lib/logging/index.d.ts +7 -0
- package/build/module/lib/logging/index.js +12 -0
- package/build/module/lib/notification/index.d.ts +2 -0
- package/build/module/lib/notification/index.js +14 -0
- package/build/module/lib/routing/index.d.ts +3 -0
- package/build/module/lib/routing/index.js +18 -0
- package/build/module/types/bridge.d.ts +10 -0
- package/build/module/types/bridge.js +12 -0
- package/build/module/types/contacts.d.ts +8 -0
- package/build/module/types/contacts.js +2 -0
- package/build/module/types/index.d.ts +2 -0
- package/build/module/types/index.js +3 -0
- package/build/module/types/routing.d.ts +4 -0
- package/build/module/types/routing.js +6 -0
- package/build/umd/index.js +2063 -0
- package/package.json +60 -0
- package/workers/workbox.js +80 -0
|
@@ -0,0 +1,2063 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SmartAppBridge = {}));
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
|
+
|
|
7
|
+
var PLATFORM;
|
|
8
|
+
(function (PLATFORM) {
|
|
9
|
+
PLATFORM["WEB"] = "web";
|
|
10
|
+
PLATFORM["IOS"] = "ios";
|
|
11
|
+
PLATFORM["ANDROID"] = "android";
|
|
12
|
+
PLATFORM["UNKNOWN"] = "unknown";
|
|
13
|
+
})(PLATFORM || (PLATFORM = {}));
|
|
14
|
+
var EVENT_TYPE;
|
|
15
|
+
(function (EVENT_TYPE) {
|
|
16
|
+
EVENT_TYPE["RECEIVE"] = "recv";
|
|
17
|
+
EVENT_TYPE["SEND"] = "send";
|
|
18
|
+
})(EVENT_TYPE || (EVENT_TYPE = {}));
|
|
19
|
+
var HANDLER;
|
|
20
|
+
(function (HANDLER) {
|
|
21
|
+
HANDLER["BOTX"] = "botx";
|
|
22
|
+
HANDLER["EXPRESS"] = "express";
|
|
23
|
+
})(HANDLER || (HANDLER = {}));
|
|
24
|
+
const RESPONSE_TIMEOUT = 30000;
|
|
25
|
+
const WEB_COMMAND_TYPE = 'smartapp';
|
|
26
|
+
const WEB_COMMAND_TYPE_RPC = 'smartapp_rpc';
|
|
27
|
+
const WEB_COMMAND_TYPE_RPC_LOGS = 'smartAppLogs';
|
|
28
|
+
|
|
29
|
+
const getPlatformByGetParam = () => {
|
|
30
|
+
const platform = new URLSearchParams(location.search).get('platform');
|
|
31
|
+
const isValidPlatform = Object.values(PLATFORM).includes(platform);
|
|
32
|
+
if (isValidPlatform)
|
|
33
|
+
return platform;
|
|
34
|
+
return PLATFORM.UNKNOWN;
|
|
35
|
+
};
|
|
36
|
+
const detectPlatformByUserAgent = () => {
|
|
37
|
+
if (/android/i.test(navigator.userAgent)) {
|
|
38
|
+
return PLATFORM.ANDROID;
|
|
39
|
+
}
|
|
40
|
+
if ((/iPad|iPhone|iPod/.test(navigator.userAgent) ||
|
|
41
|
+
(navigator.userAgent.includes('Mac') && 'ontouchend' in document)) &&
|
|
42
|
+
!window.MSStream)
|
|
43
|
+
return PLATFORM.IOS;
|
|
44
|
+
return PLATFORM.WEB;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Get platform. Detection based on GET param `platform` or user agent.
|
|
48
|
+
*
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const platform = getPlatform();
|
|
51
|
+
*
|
|
52
|
+
* // => 'web' | 'ios' | 'android'
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
const getPlatform = () => {
|
|
56
|
+
return getPlatformByGetParam() || detectPlatformByUserAgent();
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Unique ID creation requires a high quality random # generator. In the browser we therefore
|
|
60
|
+
// require the crypto API and do not support built-in fallback to lower quality random number
|
|
61
|
+
// generators (like Math.random()).
|
|
62
|
+
var getRandomValues;
|
|
63
|
+
var rnds8 = new Uint8Array(16);
|
|
64
|
+
function rng() {
|
|
65
|
+
// lazy load so that environments that need to polyfill have a chance to do so
|
|
66
|
+
if (!getRandomValues) {
|
|
67
|
+
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
|
|
68
|
+
// find the complete implementation of crypto (msCrypto) on IE11.
|
|
69
|
+
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
|
|
70
|
+
|
|
71
|
+
if (!getRandomValues) {
|
|
72
|
+
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return getRandomValues(rnds8);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
80
|
+
|
|
81
|
+
function validate(uuid) {
|
|
82
|
+
return typeof uuid === 'string' && REGEX.test(uuid);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Convert array of 16 byte values to UUID string format of the form:
|
|
87
|
+
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
var byteToHex = [];
|
|
91
|
+
|
|
92
|
+
for (var i = 0; i < 256; ++i) {
|
|
93
|
+
byteToHex.push((i + 0x100).toString(16).substr(1));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function stringify(arr) {
|
|
97
|
+
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
98
|
+
// Note: Be careful editing this code! It's been tuned for performance
|
|
99
|
+
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
100
|
+
var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
|
|
101
|
+
// of the following:
|
|
102
|
+
// - One or more input array values don't map to a hex octet (leading to
|
|
103
|
+
// "undefined" in the uuid)
|
|
104
|
+
// - Invalid input values for the RFC `version` or `variant` fields
|
|
105
|
+
|
|
106
|
+
if (!validate(uuid)) {
|
|
107
|
+
throw TypeError('Stringified UUID is invalid');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return uuid;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function v4(options, buf, offset) {
|
|
114
|
+
options = options || {};
|
|
115
|
+
var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
|
116
|
+
|
|
117
|
+
rnds[6] = rnds[6] & 0x0f | 0x40;
|
|
118
|
+
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
|
|
119
|
+
|
|
120
|
+
if (buf) {
|
|
121
|
+
offset = offset || 0;
|
|
122
|
+
|
|
123
|
+
for (var i = 0; i < 16; ++i) {
|
|
124
|
+
buf[offset + i] = rnds[i];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return buf;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return stringify(rnds);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
134
|
+
|
|
135
|
+
function createCommonjsModule(fn) {
|
|
136
|
+
var module = { exports: {} };
|
|
137
|
+
return fn(module, module.exports), module.exports;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Detect free variable `global` from Node.js. */
|
|
141
|
+
|
|
142
|
+
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|
143
|
+
|
|
144
|
+
var _freeGlobal = freeGlobal;
|
|
145
|
+
|
|
146
|
+
/** Detect free variable `self`. */
|
|
147
|
+
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
148
|
+
|
|
149
|
+
/** Used as a reference to the global object. */
|
|
150
|
+
var root = _freeGlobal || freeSelf || Function('return this')();
|
|
151
|
+
|
|
152
|
+
var _root = root;
|
|
153
|
+
|
|
154
|
+
/** Built-in value references. */
|
|
155
|
+
var Symbol = _root.Symbol;
|
|
156
|
+
|
|
157
|
+
var _Symbol = Symbol;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* A specialized version of `_.map` for arrays without support for iteratee
|
|
161
|
+
* shorthands.
|
|
162
|
+
*
|
|
163
|
+
* @private
|
|
164
|
+
* @param {Array} [array] The array to iterate over.
|
|
165
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
166
|
+
* @returns {Array} Returns the new mapped array.
|
|
167
|
+
*/
|
|
168
|
+
function arrayMap(array, iteratee) {
|
|
169
|
+
var index = -1,
|
|
170
|
+
length = array == null ? 0 : array.length,
|
|
171
|
+
result = Array(length);
|
|
172
|
+
|
|
173
|
+
while (++index < length) {
|
|
174
|
+
result[index] = iteratee(array[index], index, array);
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var _arrayMap = arrayMap;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Checks if `value` is classified as an `Array` object.
|
|
183
|
+
*
|
|
184
|
+
* @static
|
|
185
|
+
* @memberOf _
|
|
186
|
+
* @since 0.1.0
|
|
187
|
+
* @category Lang
|
|
188
|
+
* @param {*} value The value to check.
|
|
189
|
+
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|
190
|
+
* @example
|
|
191
|
+
*
|
|
192
|
+
* _.isArray([1, 2, 3]);
|
|
193
|
+
* // => true
|
|
194
|
+
*
|
|
195
|
+
* _.isArray(document.body.children);
|
|
196
|
+
* // => false
|
|
197
|
+
*
|
|
198
|
+
* _.isArray('abc');
|
|
199
|
+
* // => false
|
|
200
|
+
*
|
|
201
|
+
* _.isArray(_.noop);
|
|
202
|
+
* // => false
|
|
203
|
+
*/
|
|
204
|
+
var isArray = Array.isArray;
|
|
205
|
+
|
|
206
|
+
var isArray_1 = isArray;
|
|
207
|
+
|
|
208
|
+
/** Used for built-in method references. */
|
|
209
|
+
var objectProto$1 = Object.prototype;
|
|
210
|
+
|
|
211
|
+
/** Used to check objects for own properties. */
|
|
212
|
+
var hasOwnProperty = objectProto$1.hasOwnProperty;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Used to resolve the
|
|
216
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
217
|
+
* of values.
|
|
218
|
+
*/
|
|
219
|
+
var nativeObjectToString$1 = objectProto$1.toString;
|
|
220
|
+
|
|
221
|
+
/** Built-in value references. */
|
|
222
|
+
var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|
226
|
+
*
|
|
227
|
+
* @private
|
|
228
|
+
* @param {*} value The value to query.
|
|
229
|
+
* @returns {string} Returns the raw `toStringTag`.
|
|
230
|
+
*/
|
|
231
|
+
function getRawTag(value) {
|
|
232
|
+
var isOwn = hasOwnProperty.call(value, symToStringTag$1),
|
|
233
|
+
tag = value[symToStringTag$1];
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
value[symToStringTag$1] = undefined;
|
|
237
|
+
var unmasked = true;
|
|
238
|
+
} catch (e) {}
|
|
239
|
+
|
|
240
|
+
var result = nativeObjectToString$1.call(value);
|
|
241
|
+
if (unmasked) {
|
|
242
|
+
if (isOwn) {
|
|
243
|
+
value[symToStringTag$1] = tag;
|
|
244
|
+
} else {
|
|
245
|
+
delete value[symToStringTag$1];
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var _getRawTag = getRawTag;
|
|
252
|
+
|
|
253
|
+
/** Used for built-in method references. */
|
|
254
|
+
var objectProto = Object.prototype;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Used to resolve the
|
|
258
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
259
|
+
* of values.
|
|
260
|
+
*/
|
|
261
|
+
var nativeObjectToString = objectProto.toString;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Converts `value` to a string using `Object.prototype.toString`.
|
|
265
|
+
*
|
|
266
|
+
* @private
|
|
267
|
+
* @param {*} value The value to convert.
|
|
268
|
+
* @returns {string} Returns the converted string.
|
|
269
|
+
*/
|
|
270
|
+
function objectToString(value) {
|
|
271
|
+
return nativeObjectToString.call(value);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
var _objectToString = objectToString;
|
|
275
|
+
|
|
276
|
+
/** `Object#toString` result references. */
|
|
277
|
+
var nullTag = '[object Null]',
|
|
278
|
+
undefinedTag = '[object Undefined]';
|
|
279
|
+
|
|
280
|
+
/** Built-in value references. */
|
|
281
|
+
var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|
285
|
+
*
|
|
286
|
+
* @private
|
|
287
|
+
* @param {*} value The value to query.
|
|
288
|
+
* @returns {string} Returns the `toStringTag`.
|
|
289
|
+
*/
|
|
290
|
+
function baseGetTag(value) {
|
|
291
|
+
if (value == null) {
|
|
292
|
+
return value === undefined ? undefinedTag : nullTag;
|
|
293
|
+
}
|
|
294
|
+
return (symToStringTag && symToStringTag in Object(value))
|
|
295
|
+
? _getRawTag(value)
|
|
296
|
+
: _objectToString(value);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
var _baseGetTag = baseGetTag;
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
303
|
+
* and has a `typeof` result of "object".
|
|
304
|
+
*
|
|
305
|
+
* @static
|
|
306
|
+
* @memberOf _
|
|
307
|
+
* @since 4.0.0
|
|
308
|
+
* @category Lang
|
|
309
|
+
* @param {*} value The value to check.
|
|
310
|
+
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
311
|
+
* @example
|
|
312
|
+
*
|
|
313
|
+
* _.isObjectLike({});
|
|
314
|
+
* // => true
|
|
315
|
+
*
|
|
316
|
+
* _.isObjectLike([1, 2, 3]);
|
|
317
|
+
* // => true
|
|
318
|
+
*
|
|
319
|
+
* _.isObjectLike(_.noop);
|
|
320
|
+
* // => false
|
|
321
|
+
*
|
|
322
|
+
* _.isObjectLike(null);
|
|
323
|
+
* // => false
|
|
324
|
+
*/
|
|
325
|
+
function isObjectLike(value) {
|
|
326
|
+
return value != null && typeof value == 'object';
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
var isObjectLike_1 = isObjectLike;
|
|
330
|
+
|
|
331
|
+
/** `Object#toString` result references. */
|
|
332
|
+
var symbolTag = '[object Symbol]';
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
336
|
+
*
|
|
337
|
+
* @static
|
|
338
|
+
* @memberOf _
|
|
339
|
+
* @since 4.0.0
|
|
340
|
+
* @category Lang
|
|
341
|
+
* @param {*} value The value to check.
|
|
342
|
+
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
343
|
+
* @example
|
|
344
|
+
*
|
|
345
|
+
* _.isSymbol(Symbol.iterator);
|
|
346
|
+
* // => true
|
|
347
|
+
*
|
|
348
|
+
* _.isSymbol('abc');
|
|
349
|
+
* // => false
|
|
350
|
+
*/
|
|
351
|
+
function isSymbol(value) {
|
|
352
|
+
return typeof value == 'symbol' ||
|
|
353
|
+
(isObjectLike_1(value) && _baseGetTag(value) == symbolTag);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
var isSymbol_1 = isSymbol;
|
|
357
|
+
|
|
358
|
+
/** Used as references for various `Number` constants. */
|
|
359
|
+
var INFINITY = 1 / 0;
|
|
360
|
+
|
|
361
|
+
/** Used to convert symbols to primitives and strings. */
|
|
362
|
+
var symbolProto = _Symbol ? _Symbol.prototype : undefined,
|
|
363
|
+
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* The base implementation of `_.toString` which doesn't convert nullish
|
|
367
|
+
* values to empty strings.
|
|
368
|
+
*
|
|
369
|
+
* @private
|
|
370
|
+
* @param {*} value The value to process.
|
|
371
|
+
* @returns {string} Returns the string.
|
|
372
|
+
*/
|
|
373
|
+
function baseToString(value) {
|
|
374
|
+
// Exit early for strings to avoid a performance hit in some environments.
|
|
375
|
+
if (typeof value == 'string') {
|
|
376
|
+
return value;
|
|
377
|
+
}
|
|
378
|
+
if (isArray_1(value)) {
|
|
379
|
+
// Recursively convert values (susceptible to call stack limits).
|
|
380
|
+
return _arrayMap(value, baseToString) + '';
|
|
381
|
+
}
|
|
382
|
+
if (isSymbol_1(value)) {
|
|
383
|
+
return symbolToString ? symbolToString.call(value) : '';
|
|
384
|
+
}
|
|
385
|
+
var result = (value + '');
|
|
386
|
+
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
var _baseToString = baseToString;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Converts `value` to a string. An empty string is returned for `null`
|
|
393
|
+
* and `undefined` values. The sign of `-0` is preserved.
|
|
394
|
+
*
|
|
395
|
+
* @static
|
|
396
|
+
* @memberOf _
|
|
397
|
+
* @since 4.0.0
|
|
398
|
+
* @category Lang
|
|
399
|
+
* @param {*} value The value to convert.
|
|
400
|
+
* @returns {string} Returns the converted string.
|
|
401
|
+
* @example
|
|
402
|
+
*
|
|
403
|
+
* _.toString(null);
|
|
404
|
+
* // => ''
|
|
405
|
+
*
|
|
406
|
+
* _.toString(-0);
|
|
407
|
+
* // => '-0'
|
|
408
|
+
*
|
|
409
|
+
* _.toString([1, 2, 3]);
|
|
410
|
+
* // => '1,2,3'
|
|
411
|
+
*/
|
|
412
|
+
function toString(value) {
|
|
413
|
+
return value == null ? '' : _baseToString(value);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
var toString_1 = toString;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* The base implementation of `_.slice` without an iteratee call guard.
|
|
420
|
+
*
|
|
421
|
+
* @private
|
|
422
|
+
* @param {Array} array The array to slice.
|
|
423
|
+
* @param {number} [start=0] The start position.
|
|
424
|
+
* @param {number} [end=array.length] The end position.
|
|
425
|
+
* @returns {Array} Returns the slice of `array`.
|
|
426
|
+
*/
|
|
427
|
+
function baseSlice(array, start, end) {
|
|
428
|
+
var index = -1,
|
|
429
|
+
length = array.length;
|
|
430
|
+
|
|
431
|
+
if (start < 0) {
|
|
432
|
+
start = -start > length ? 0 : (length + start);
|
|
433
|
+
}
|
|
434
|
+
end = end > length ? length : end;
|
|
435
|
+
if (end < 0) {
|
|
436
|
+
end += length;
|
|
437
|
+
}
|
|
438
|
+
length = start > end ? 0 : ((end - start) >>> 0);
|
|
439
|
+
start >>>= 0;
|
|
440
|
+
|
|
441
|
+
var result = Array(length);
|
|
442
|
+
while (++index < length) {
|
|
443
|
+
result[index] = array[index + start];
|
|
444
|
+
}
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
var _baseSlice = baseSlice;
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Casts `array` to a slice if it's needed.
|
|
452
|
+
*
|
|
453
|
+
* @private
|
|
454
|
+
* @param {Array} array The array to inspect.
|
|
455
|
+
* @param {number} start The start position.
|
|
456
|
+
* @param {number} [end=array.length] The end position.
|
|
457
|
+
* @returns {Array} Returns the cast slice.
|
|
458
|
+
*/
|
|
459
|
+
function castSlice(array, start, end) {
|
|
460
|
+
var length = array.length;
|
|
461
|
+
end = end === undefined ? length : end;
|
|
462
|
+
return (!start && end >= length) ? array : _baseSlice(array, start, end);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
var _castSlice = castSlice;
|
|
466
|
+
|
|
467
|
+
/** Used to compose unicode character classes. */
|
|
468
|
+
var rsAstralRange$2 = '\\ud800-\\udfff',
|
|
469
|
+
rsComboMarksRange$3 = '\\u0300-\\u036f',
|
|
470
|
+
reComboHalfMarksRange$3 = '\\ufe20-\\ufe2f',
|
|
471
|
+
rsComboSymbolsRange$3 = '\\u20d0-\\u20ff',
|
|
472
|
+
rsComboRange$3 = rsComboMarksRange$3 + reComboHalfMarksRange$3 + rsComboSymbolsRange$3,
|
|
473
|
+
rsVarRange$2 = '\\ufe0e\\ufe0f';
|
|
474
|
+
|
|
475
|
+
/** Used to compose unicode capture groups. */
|
|
476
|
+
var rsZWJ$2 = '\\u200d';
|
|
477
|
+
|
|
478
|
+
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
|
|
479
|
+
var reHasUnicode = RegExp('[' + rsZWJ$2 + rsAstralRange$2 + rsComboRange$3 + rsVarRange$2 + ']');
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Checks if `string` contains Unicode symbols.
|
|
483
|
+
*
|
|
484
|
+
* @private
|
|
485
|
+
* @param {string} string The string to inspect.
|
|
486
|
+
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
|
487
|
+
*/
|
|
488
|
+
function hasUnicode(string) {
|
|
489
|
+
return reHasUnicode.test(string);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
var _hasUnicode = hasUnicode;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Converts an ASCII `string` to an array.
|
|
496
|
+
*
|
|
497
|
+
* @private
|
|
498
|
+
* @param {string} string The string to convert.
|
|
499
|
+
* @returns {Array} Returns the converted array.
|
|
500
|
+
*/
|
|
501
|
+
function asciiToArray(string) {
|
|
502
|
+
return string.split('');
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
var _asciiToArray = asciiToArray;
|
|
506
|
+
|
|
507
|
+
/** Used to compose unicode character classes. */
|
|
508
|
+
var rsAstralRange$1 = '\\ud800-\\udfff',
|
|
509
|
+
rsComboMarksRange$2 = '\\u0300-\\u036f',
|
|
510
|
+
reComboHalfMarksRange$2 = '\\ufe20-\\ufe2f',
|
|
511
|
+
rsComboSymbolsRange$2 = '\\u20d0-\\u20ff',
|
|
512
|
+
rsComboRange$2 = rsComboMarksRange$2 + reComboHalfMarksRange$2 + rsComboSymbolsRange$2,
|
|
513
|
+
rsVarRange$1 = '\\ufe0e\\ufe0f';
|
|
514
|
+
|
|
515
|
+
/** Used to compose unicode capture groups. */
|
|
516
|
+
var rsAstral = '[' + rsAstralRange$1 + ']',
|
|
517
|
+
rsCombo$2 = '[' + rsComboRange$2 + ']',
|
|
518
|
+
rsFitz$1 = '\\ud83c[\\udffb-\\udfff]',
|
|
519
|
+
rsModifier$1 = '(?:' + rsCombo$2 + '|' + rsFitz$1 + ')',
|
|
520
|
+
rsNonAstral$1 = '[^' + rsAstralRange$1 + ']',
|
|
521
|
+
rsRegional$1 = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|
522
|
+
rsSurrPair$1 = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|
523
|
+
rsZWJ$1 = '\\u200d';
|
|
524
|
+
|
|
525
|
+
/** Used to compose unicode regexes. */
|
|
526
|
+
var reOptMod$1 = rsModifier$1 + '?',
|
|
527
|
+
rsOptVar$1 = '[' + rsVarRange$1 + ']?',
|
|
528
|
+
rsOptJoin$1 = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral$1, rsRegional$1, rsSurrPair$1].join('|') + ')' + rsOptVar$1 + reOptMod$1 + ')*',
|
|
529
|
+
rsSeq$1 = rsOptVar$1 + reOptMod$1 + rsOptJoin$1,
|
|
530
|
+
rsSymbol = '(?:' + [rsNonAstral$1 + rsCombo$2 + '?', rsCombo$2, rsRegional$1, rsSurrPair$1, rsAstral].join('|') + ')';
|
|
531
|
+
|
|
532
|
+
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
|
533
|
+
var reUnicode = RegExp(rsFitz$1 + '(?=' + rsFitz$1 + ')|' + rsSymbol + rsSeq$1, 'g');
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Converts a Unicode `string` to an array.
|
|
537
|
+
*
|
|
538
|
+
* @private
|
|
539
|
+
* @param {string} string The string to convert.
|
|
540
|
+
* @returns {Array} Returns the converted array.
|
|
541
|
+
*/
|
|
542
|
+
function unicodeToArray(string) {
|
|
543
|
+
return string.match(reUnicode) || [];
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
var _unicodeToArray = unicodeToArray;
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Converts `string` to an array.
|
|
550
|
+
*
|
|
551
|
+
* @private
|
|
552
|
+
* @param {string} string The string to convert.
|
|
553
|
+
* @returns {Array} Returns the converted array.
|
|
554
|
+
*/
|
|
555
|
+
function stringToArray(string) {
|
|
556
|
+
return _hasUnicode(string)
|
|
557
|
+
? _unicodeToArray(string)
|
|
558
|
+
: _asciiToArray(string);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
var _stringToArray = stringToArray;
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Creates a function like `_.lowerFirst`.
|
|
565
|
+
*
|
|
566
|
+
* @private
|
|
567
|
+
* @param {string} methodName The name of the `String` case method to use.
|
|
568
|
+
* @returns {Function} Returns the new case function.
|
|
569
|
+
*/
|
|
570
|
+
function createCaseFirst(methodName) {
|
|
571
|
+
return function(string) {
|
|
572
|
+
string = toString_1(string);
|
|
573
|
+
|
|
574
|
+
var strSymbols = _hasUnicode(string)
|
|
575
|
+
? _stringToArray(string)
|
|
576
|
+
: undefined;
|
|
577
|
+
|
|
578
|
+
var chr = strSymbols
|
|
579
|
+
? strSymbols[0]
|
|
580
|
+
: string.charAt(0);
|
|
581
|
+
|
|
582
|
+
var trailing = strSymbols
|
|
583
|
+
? _castSlice(strSymbols, 1).join('')
|
|
584
|
+
: string.slice(1);
|
|
585
|
+
|
|
586
|
+
return chr[methodName]() + trailing;
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
var _createCaseFirst = createCaseFirst;
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Converts the first character of `string` to upper case.
|
|
594
|
+
*
|
|
595
|
+
* @static
|
|
596
|
+
* @memberOf _
|
|
597
|
+
* @since 4.0.0
|
|
598
|
+
* @category String
|
|
599
|
+
* @param {string} [string=''] The string to convert.
|
|
600
|
+
* @returns {string} Returns the converted string.
|
|
601
|
+
* @example
|
|
602
|
+
*
|
|
603
|
+
* _.upperFirst('fred');
|
|
604
|
+
* // => 'Fred'
|
|
605
|
+
*
|
|
606
|
+
* _.upperFirst('FRED');
|
|
607
|
+
* // => 'FRED'
|
|
608
|
+
*/
|
|
609
|
+
var upperFirst = _createCaseFirst('toUpperCase');
|
|
610
|
+
|
|
611
|
+
var upperFirst_1 = upperFirst;
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Converts the first character of `string` to upper case and the remaining
|
|
615
|
+
* to lower case.
|
|
616
|
+
*
|
|
617
|
+
* @static
|
|
618
|
+
* @memberOf _
|
|
619
|
+
* @since 3.0.0
|
|
620
|
+
* @category String
|
|
621
|
+
* @param {string} [string=''] The string to capitalize.
|
|
622
|
+
* @returns {string} Returns the capitalized string.
|
|
623
|
+
* @example
|
|
624
|
+
*
|
|
625
|
+
* _.capitalize('FRED');
|
|
626
|
+
* // => 'Fred'
|
|
627
|
+
*/
|
|
628
|
+
function capitalize(string) {
|
|
629
|
+
return upperFirst_1(toString_1(string).toLowerCase());
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
var capitalize_1 = capitalize;
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* A specialized version of `_.reduce` for arrays without support for
|
|
636
|
+
* iteratee shorthands.
|
|
637
|
+
*
|
|
638
|
+
* @private
|
|
639
|
+
* @param {Array} [array] The array to iterate over.
|
|
640
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
641
|
+
* @param {*} [accumulator] The initial value.
|
|
642
|
+
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
|
643
|
+
* the initial value.
|
|
644
|
+
* @returns {*} Returns the accumulated value.
|
|
645
|
+
*/
|
|
646
|
+
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|
647
|
+
var index = -1,
|
|
648
|
+
length = array == null ? 0 : array.length;
|
|
649
|
+
|
|
650
|
+
if (initAccum && length) {
|
|
651
|
+
accumulator = array[++index];
|
|
652
|
+
}
|
|
653
|
+
while (++index < length) {
|
|
654
|
+
accumulator = iteratee(accumulator, array[index], index, array);
|
|
655
|
+
}
|
|
656
|
+
return accumulator;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
var _arrayReduce = arrayReduce;
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* The base implementation of `_.propertyOf` without support for deep paths.
|
|
663
|
+
*
|
|
664
|
+
* @private
|
|
665
|
+
* @param {Object} object The object to query.
|
|
666
|
+
* @returns {Function} Returns the new accessor function.
|
|
667
|
+
*/
|
|
668
|
+
function basePropertyOf(object) {
|
|
669
|
+
return function(key) {
|
|
670
|
+
return object == null ? undefined : object[key];
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
var _basePropertyOf = basePropertyOf;
|
|
675
|
+
|
|
676
|
+
/** Used to map Latin Unicode letters to basic Latin letters. */
|
|
677
|
+
var deburredLetters = {
|
|
678
|
+
// Latin-1 Supplement block.
|
|
679
|
+
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
|
680
|
+
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
|
681
|
+
'\xc7': 'C', '\xe7': 'c',
|
|
682
|
+
'\xd0': 'D', '\xf0': 'd',
|
|
683
|
+
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
|
684
|
+
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
|
685
|
+
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
|
686
|
+
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
|
687
|
+
'\xd1': 'N', '\xf1': 'n',
|
|
688
|
+
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
|
689
|
+
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
|
690
|
+
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
|
691
|
+
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
|
692
|
+
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
|
693
|
+
'\xc6': 'Ae', '\xe6': 'ae',
|
|
694
|
+
'\xde': 'Th', '\xfe': 'th',
|
|
695
|
+
'\xdf': 'ss',
|
|
696
|
+
// Latin Extended-A block.
|
|
697
|
+
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
|
|
698
|
+
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
|
|
699
|
+
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
|
|
700
|
+
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
|
|
701
|
+
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
|
|
702
|
+
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
|
|
703
|
+
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
|
|
704
|
+
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
|
|
705
|
+
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
|
|
706
|
+
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
|
|
707
|
+
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
|
|
708
|
+
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
|
|
709
|
+
'\u0134': 'J', '\u0135': 'j',
|
|
710
|
+
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
|
|
711
|
+
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
|
|
712
|
+
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
|
|
713
|
+
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
|
|
714
|
+
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
|
|
715
|
+
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
|
|
716
|
+
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
|
|
717
|
+
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
|
|
718
|
+
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
|
|
719
|
+
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
|
|
720
|
+
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
|
|
721
|
+
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
|
|
722
|
+
'\u0163': 't', '\u0165': 't', '\u0167': 't',
|
|
723
|
+
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
|
|
724
|
+
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
|
|
725
|
+
'\u0174': 'W', '\u0175': 'w',
|
|
726
|
+
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
|
|
727
|
+
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
|
|
728
|
+
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
|
|
729
|
+
'\u0132': 'IJ', '\u0133': 'ij',
|
|
730
|
+
'\u0152': 'Oe', '\u0153': 'oe',
|
|
731
|
+
'\u0149': "'n", '\u017f': 's'
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
|
|
736
|
+
* letters to basic Latin letters.
|
|
737
|
+
*
|
|
738
|
+
* @private
|
|
739
|
+
* @param {string} letter The matched letter to deburr.
|
|
740
|
+
* @returns {string} Returns the deburred letter.
|
|
741
|
+
*/
|
|
742
|
+
var deburrLetter = _basePropertyOf(deburredLetters);
|
|
743
|
+
|
|
744
|
+
var _deburrLetter = deburrLetter;
|
|
745
|
+
|
|
746
|
+
/** Used to match Latin Unicode letters (excluding mathematical operators). */
|
|
747
|
+
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
|
|
748
|
+
|
|
749
|
+
/** Used to compose unicode character classes. */
|
|
750
|
+
var rsComboMarksRange$1 = '\\u0300-\\u036f',
|
|
751
|
+
reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f',
|
|
752
|
+
rsComboSymbolsRange$1 = '\\u20d0-\\u20ff',
|
|
753
|
+
rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1;
|
|
754
|
+
|
|
755
|
+
/** Used to compose unicode capture groups. */
|
|
756
|
+
var rsCombo$1 = '[' + rsComboRange$1 + ']';
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
|
|
760
|
+
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
|
|
761
|
+
*/
|
|
762
|
+
var reComboMark = RegExp(rsCombo$1, 'g');
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Deburrs `string` by converting
|
|
766
|
+
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
|
767
|
+
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
|
|
768
|
+
* letters to basic Latin letters and removing
|
|
769
|
+
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
|
770
|
+
*
|
|
771
|
+
* @static
|
|
772
|
+
* @memberOf _
|
|
773
|
+
* @since 3.0.0
|
|
774
|
+
* @category String
|
|
775
|
+
* @param {string} [string=''] The string to deburr.
|
|
776
|
+
* @returns {string} Returns the deburred string.
|
|
777
|
+
* @example
|
|
778
|
+
*
|
|
779
|
+
* _.deburr('déjà vu');
|
|
780
|
+
* // => 'deja vu'
|
|
781
|
+
*/
|
|
782
|
+
function deburr(string) {
|
|
783
|
+
string = toString_1(string);
|
|
784
|
+
return string && string.replace(reLatin, _deburrLetter).replace(reComboMark, '');
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
var deburr_1 = deburr;
|
|
788
|
+
|
|
789
|
+
/** Used to match words composed of alphanumeric characters. */
|
|
790
|
+
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Splits an ASCII `string` into an array of its words.
|
|
794
|
+
*
|
|
795
|
+
* @private
|
|
796
|
+
* @param {string} The string to inspect.
|
|
797
|
+
* @returns {Array} Returns the words of `string`.
|
|
798
|
+
*/
|
|
799
|
+
function asciiWords(string) {
|
|
800
|
+
return string.match(reAsciiWord) || [];
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
var _asciiWords = asciiWords;
|
|
804
|
+
|
|
805
|
+
/** Used to detect strings that need a more robust regexp to match words. */
|
|
806
|
+
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Checks if `string` contains a word composed of Unicode symbols.
|
|
810
|
+
*
|
|
811
|
+
* @private
|
|
812
|
+
* @param {string} string The string to inspect.
|
|
813
|
+
* @returns {boolean} Returns `true` if a word is found, else `false`.
|
|
814
|
+
*/
|
|
815
|
+
function hasUnicodeWord(string) {
|
|
816
|
+
return reHasUnicodeWord.test(string);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
var _hasUnicodeWord = hasUnicodeWord;
|
|
820
|
+
|
|
821
|
+
/** Used to compose unicode character classes. */
|
|
822
|
+
var rsAstralRange = '\\ud800-\\udfff',
|
|
823
|
+
rsComboMarksRange = '\\u0300-\\u036f',
|
|
824
|
+
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
|
|
825
|
+
rsComboSymbolsRange = '\\u20d0-\\u20ff',
|
|
826
|
+
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
|
|
827
|
+
rsDingbatRange = '\\u2700-\\u27bf',
|
|
828
|
+
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
|
|
829
|
+
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
|
|
830
|
+
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
|
|
831
|
+
rsPunctuationRange = '\\u2000-\\u206f',
|
|
832
|
+
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
|
|
833
|
+
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
|
|
834
|
+
rsVarRange = '\\ufe0e\\ufe0f',
|
|
835
|
+
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
|
|
836
|
+
|
|
837
|
+
/** Used to compose unicode capture groups. */
|
|
838
|
+
var rsApos$1 = "['\u2019]",
|
|
839
|
+
rsBreak = '[' + rsBreakRange + ']',
|
|
840
|
+
rsCombo = '[' + rsComboRange + ']',
|
|
841
|
+
rsDigits = '\\d+',
|
|
842
|
+
rsDingbat = '[' + rsDingbatRange + ']',
|
|
843
|
+
rsLower = '[' + rsLowerRange + ']',
|
|
844
|
+
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
|
|
845
|
+
rsFitz = '\\ud83c[\\udffb-\\udfff]',
|
|
846
|
+
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
|
|
847
|
+
rsNonAstral = '[^' + rsAstralRange + ']',
|
|
848
|
+
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|
849
|
+
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|
850
|
+
rsUpper = '[' + rsUpperRange + ']',
|
|
851
|
+
rsZWJ = '\\u200d';
|
|
852
|
+
|
|
853
|
+
/** Used to compose unicode regexes. */
|
|
854
|
+
var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
|
|
855
|
+
rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
|
|
856
|
+
rsOptContrLower = '(?:' + rsApos$1 + '(?:d|ll|m|re|s|t|ve))?',
|
|
857
|
+
rsOptContrUpper = '(?:' + rsApos$1 + '(?:D|LL|M|RE|S|T|VE))?',
|
|
858
|
+
reOptMod = rsModifier + '?',
|
|
859
|
+
rsOptVar = '[' + rsVarRange + ']?',
|
|
860
|
+
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
|
|
861
|
+
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
|
|
862
|
+
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
|
|
863
|
+
rsSeq = rsOptVar + reOptMod + rsOptJoin,
|
|
864
|
+
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;
|
|
865
|
+
|
|
866
|
+
/** Used to match complex or compound words. */
|
|
867
|
+
var reUnicodeWord = RegExp([
|
|
868
|
+
rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
|
|
869
|
+
rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
|
|
870
|
+
rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
|
|
871
|
+
rsUpper + '+' + rsOptContrUpper,
|
|
872
|
+
rsOrdUpper,
|
|
873
|
+
rsOrdLower,
|
|
874
|
+
rsDigits,
|
|
875
|
+
rsEmoji
|
|
876
|
+
].join('|'), 'g');
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Splits a Unicode `string` into an array of its words.
|
|
880
|
+
*
|
|
881
|
+
* @private
|
|
882
|
+
* @param {string} The string to inspect.
|
|
883
|
+
* @returns {Array} Returns the words of `string`.
|
|
884
|
+
*/
|
|
885
|
+
function unicodeWords(string) {
|
|
886
|
+
return string.match(reUnicodeWord) || [];
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
var _unicodeWords = unicodeWords;
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* Splits `string` into an array of its words.
|
|
893
|
+
*
|
|
894
|
+
* @static
|
|
895
|
+
* @memberOf _
|
|
896
|
+
* @since 3.0.0
|
|
897
|
+
* @category String
|
|
898
|
+
* @param {string} [string=''] The string to inspect.
|
|
899
|
+
* @param {RegExp|string} [pattern] The pattern to match words.
|
|
900
|
+
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
901
|
+
* @returns {Array} Returns the words of `string`.
|
|
902
|
+
* @example
|
|
903
|
+
*
|
|
904
|
+
* _.words('fred, barney, & pebbles');
|
|
905
|
+
* // => ['fred', 'barney', 'pebbles']
|
|
906
|
+
*
|
|
907
|
+
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
|
908
|
+
* // => ['fred', 'barney', '&', 'pebbles']
|
|
909
|
+
*/
|
|
910
|
+
function words(string, pattern, guard) {
|
|
911
|
+
string = toString_1(string);
|
|
912
|
+
pattern = guard ? undefined : pattern;
|
|
913
|
+
|
|
914
|
+
if (pattern === undefined) {
|
|
915
|
+
return _hasUnicodeWord(string) ? _unicodeWords(string) : _asciiWords(string);
|
|
916
|
+
}
|
|
917
|
+
return string.match(pattern) || [];
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
var words_1 = words;
|
|
921
|
+
|
|
922
|
+
/** Used to compose unicode capture groups. */
|
|
923
|
+
var rsApos = "['\u2019]";
|
|
924
|
+
|
|
925
|
+
/** Used to match apostrophes. */
|
|
926
|
+
var reApos = RegExp(rsApos, 'g');
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Creates a function like `_.camelCase`.
|
|
930
|
+
*
|
|
931
|
+
* @private
|
|
932
|
+
* @param {Function} callback The function to combine each word.
|
|
933
|
+
* @returns {Function} Returns the new compounder function.
|
|
934
|
+
*/
|
|
935
|
+
function createCompounder(callback) {
|
|
936
|
+
return function(string) {
|
|
937
|
+
return _arrayReduce(words_1(deburr_1(string).replace(reApos, '')), callback, '');
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
var _createCompounder = createCompounder;
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
|
945
|
+
*
|
|
946
|
+
* @static
|
|
947
|
+
* @memberOf _
|
|
948
|
+
* @since 3.0.0
|
|
949
|
+
* @category String
|
|
950
|
+
* @param {string} [string=''] The string to convert.
|
|
951
|
+
* @returns {string} Returns the camel cased string.
|
|
952
|
+
* @example
|
|
953
|
+
*
|
|
954
|
+
* _.camelCase('Foo Bar');
|
|
955
|
+
* // => 'fooBar'
|
|
956
|
+
*
|
|
957
|
+
* _.camelCase('--foo-bar--');
|
|
958
|
+
* // => 'fooBar'
|
|
959
|
+
*
|
|
960
|
+
* _.camelCase('__FOO_BAR__');
|
|
961
|
+
* // => 'fooBar'
|
|
962
|
+
*/
|
|
963
|
+
var camelCase = _createCompounder(function(result, word, index) {
|
|
964
|
+
word = word.toLowerCase();
|
|
965
|
+
return result + (index ? capitalize_1(word) : word);
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
var camelCase_1 = camelCase;
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Converts `string` to
|
|
972
|
+
* [snake case](https://en.wikipedia.org/wiki/Snake_case).
|
|
973
|
+
*
|
|
974
|
+
* @static
|
|
975
|
+
* @memberOf _
|
|
976
|
+
* @since 3.0.0
|
|
977
|
+
* @category String
|
|
978
|
+
* @param {string} [string=''] The string to convert.
|
|
979
|
+
* @returns {string} Returns the snake cased string.
|
|
980
|
+
* @example
|
|
981
|
+
*
|
|
982
|
+
* _.snakeCase('Foo Bar');
|
|
983
|
+
* // => 'foo_bar'
|
|
984
|
+
*
|
|
985
|
+
* _.snakeCase('fooBar');
|
|
986
|
+
* // => 'foo_bar'
|
|
987
|
+
*
|
|
988
|
+
* _.snakeCase('--FOO-BAR--');
|
|
989
|
+
* // => 'foo_bar'
|
|
990
|
+
*/
|
|
991
|
+
var snakeCase = _createCompounder(function(result, word, index) {
|
|
992
|
+
return result + (index ? '_' : '') + word.toLowerCase();
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
var snakeCase_1 = snakeCase;
|
|
996
|
+
|
|
997
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
998
|
+
const isUuid = (value) => {
|
|
999
|
+
return /[0-9a-fA-F-]{32}/.test(value);
|
|
1000
|
+
};
|
|
1001
|
+
const snakeCaseToCamelCase = (data) => {
|
|
1002
|
+
if (Array.isArray(data))
|
|
1003
|
+
return data.map(snakeCaseToCamelCase);
|
|
1004
|
+
if (!data || data.constructor?.name !== 'Object')
|
|
1005
|
+
return data;
|
|
1006
|
+
return Object.keys(data).reduce((result, key) => {
|
|
1007
|
+
const value = snakeCaseToCamelCase(data[key]);
|
|
1008
|
+
const keyValue = isUuid(key) ? key : camelCase_1(key);
|
|
1009
|
+
return { ...result, [keyValue]: value };
|
|
1010
|
+
}, {});
|
|
1011
|
+
};
|
|
1012
|
+
const camelCaseToSnakeCase = (data) => {
|
|
1013
|
+
if (Array.isArray(data))
|
|
1014
|
+
return data.map(camelCaseToSnakeCase);
|
|
1015
|
+
if (!data || data.constructor?.name !== 'Object')
|
|
1016
|
+
return data;
|
|
1017
|
+
return Object.keys(data).reduce((result, key) => {
|
|
1018
|
+
const value = camelCaseToSnakeCase(data[key]);
|
|
1019
|
+
return { ...result, [snakeCase_1(key)]: value };
|
|
1020
|
+
}, {});
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
var eventemitter3 = createCommonjsModule(function (module) {
|
|
1024
|
+
|
|
1025
|
+
var has = Object.prototype.hasOwnProperty
|
|
1026
|
+
, prefix = '~';
|
|
1027
|
+
|
|
1028
|
+
/**
|
|
1029
|
+
* Constructor to create a storage for our `EE` objects.
|
|
1030
|
+
* An `Events` instance is a plain object whose properties are event names.
|
|
1031
|
+
*
|
|
1032
|
+
* @constructor
|
|
1033
|
+
* @private
|
|
1034
|
+
*/
|
|
1035
|
+
function Events() {}
|
|
1036
|
+
|
|
1037
|
+
//
|
|
1038
|
+
// We try to not inherit from `Object.prototype`. In some engines creating an
|
|
1039
|
+
// instance in this way is faster than calling `Object.create(null)` directly.
|
|
1040
|
+
// If `Object.create(null)` is not supported we prefix the event names with a
|
|
1041
|
+
// character to make sure that the built-in object properties are not
|
|
1042
|
+
// overridden or used as an attack vector.
|
|
1043
|
+
//
|
|
1044
|
+
if (Object.create) {
|
|
1045
|
+
Events.prototype = Object.create(null);
|
|
1046
|
+
|
|
1047
|
+
//
|
|
1048
|
+
// This hack is needed because the `__proto__` property is still inherited in
|
|
1049
|
+
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
|
|
1050
|
+
//
|
|
1051
|
+
if (!new Events().__proto__) prefix = false;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Representation of a single event listener.
|
|
1056
|
+
*
|
|
1057
|
+
* @param {Function} fn The listener function.
|
|
1058
|
+
* @param {*} context The context to invoke the listener with.
|
|
1059
|
+
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
|
|
1060
|
+
* @constructor
|
|
1061
|
+
* @private
|
|
1062
|
+
*/
|
|
1063
|
+
function EE(fn, context, once) {
|
|
1064
|
+
this.fn = fn;
|
|
1065
|
+
this.context = context;
|
|
1066
|
+
this.once = once || false;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Add a listener for a given event.
|
|
1071
|
+
*
|
|
1072
|
+
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
|
1073
|
+
* @param {(String|Symbol)} event The event name.
|
|
1074
|
+
* @param {Function} fn The listener function.
|
|
1075
|
+
* @param {*} context The context to invoke the listener with.
|
|
1076
|
+
* @param {Boolean} once Specify if the listener is a one-time listener.
|
|
1077
|
+
* @returns {EventEmitter}
|
|
1078
|
+
* @private
|
|
1079
|
+
*/
|
|
1080
|
+
function addListener(emitter, event, fn, context, once) {
|
|
1081
|
+
if (typeof fn !== 'function') {
|
|
1082
|
+
throw new TypeError('The listener must be a function');
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
var listener = new EE(fn, context || emitter, once)
|
|
1086
|
+
, evt = prefix ? prefix + event : event;
|
|
1087
|
+
|
|
1088
|
+
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
|
|
1089
|
+
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
|
|
1090
|
+
else emitter._events[evt] = [emitter._events[evt], listener];
|
|
1091
|
+
|
|
1092
|
+
return emitter;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Clear event by name.
|
|
1097
|
+
*
|
|
1098
|
+
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
|
1099
|
+
* @param {(String|Symbol)} evt The Event name.
|
|
1100
|
+
* @private
|
|
1101
|
+
*/
|
|
1102
|
+
function clearEvent(emitter, evt) {
|
|
1103
|
+
if (--emitter._eventsCount === 0) emitter._events = new Events();
|
|
1104
|
+
else delete emitter._events[evt];
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Minimal `EventEmitter` interface that is molded against the Node.js
|
|
1109
|
+
* `EventEmitter` interface.
|
|
1110
|
+
*
|
|
1111
|
+
* @constructor
|
|
1112
|
+
* @public
|
|
1113
|
+
*/
|
|
1114
|
+
function EventEmitter() {
|
|
1115
|
+
this._events = new Events();
|
|
1116
|
+
this._eventsCount = 0;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* Return an array listing the events for which the emitter has registered
|
|
1121
|
+
* listeners.
|
|
1122
|
+
*
|
|
1123
|
+
* @returns {Array}
|
|
1124
|
+
* @public
|
|
1125
|
+
*/
|
|
1126
|
+
EventEmitter.prototype.eventNames = function eventNames() {
|
|
1127
|
+
var names = []
|
|
1128
|
+
, events
|
|
1129
|
+
, name;
|
|
1130
|
+
|
|
1131
|
+
if (this._eventsCount === 0) return names;
|
|
1132
|
+
|
|
1133
|
+
for (name in (events = this._events)) {
|
|
1134
|
+
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (Object.getOwnPropertySymbols) {
|
|
1138
|
+
return names.concat(Object.getOwnPropertySymbols(events));
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
return names;
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Return the listeners registered for a given event.
|
|
1146
|
+
*
|
|
1147
|
+
* @param {(String|Symbol)} event The event name.
|
|
1148
|
+
* @returns {Array} The registered listeners.
|
|
1149
|
+
* @public
|
|
1150
|
+
*/
|
|
1151
|
+
EventEmitter.prototype.listeners = function listeners(event) {
|
|
1152
|
+
var evt = prefix ? prefix + event : event
|
|
1153
|
+
, handlers = this._events[evt];
|
|
1154
|
+
|
|
1155
|
+
if (!handlers) return [];
|
|
1156
|
+
if (handlers.fn) return [handlers.fn];
|
|
1157
|
+
|
|
1158
|
+
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
|
|
1159
|
+
ee[i] = handlers[i].fn;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
return ee;
|
|
1163
|
+
};
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Return the number of listeners listening to a given event.
|
|
1167
|
+
*
|
|
1168
|
+
* @param {(String|Symbol)} event The event name.
|
|
1169
|
+
* @returns {Number} The number of listeners.
|
|
1170
|
+
* @public
|
|
1171
|
+
*/
|
|
1172
|
+
EventEmitter.prototype.listenerCount = function listenerCount(event) {
|
|
1173
|
+
var evt = prefix ? prefix + event : event
|
|
1174
|
+
, listeners = this._events[evt];
|
|
1175
|
+
|
|
1176
|
+
if (!listeners) return 0;
|
|
1177
|
+
if (listeners.fn) return 1;
|
|
1178
|
+
return listeners.length;
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Calls each of the listeners registered for a given event.
|
|
1183
|
+
*
|
|
1184
|
+
* @param {(String|Symbol)} event The event name.
|
|
1185
|
+
* @returns {Boolean} `true` if the event had listeners, else `false`.
|
|
1186
|
+
* @public
|
|
1187
|
+
*/
|
|
1188
|
+
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
|
1189
|
+
var evt = prefix ? prefix + event : event;
|
|
1190
|
+
|
|
1191
|
+
if (!this._events[evt]) return false;
|
|
1192
|
+
|
|
1193
|
+
var listeners = this._events[evt]
|
|
1194
|
+
, len = arguments.length
|
|
1195
|
+
, args
|
|
1196
|
+
, i;
|
|
1197
|
+
|
|
1198
|
+
if (listeners.fn) {
|
|
1199
|
+
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
|
|
1200
|
+
|
|
1201
|
+
switch (len) {
|
|
1202
|
+
case 1: return listeners.fn.call(listeners.context), true;
|
|
1203
|
+
case 2: return listeners.fn.call(listeners.context, a1), true;
|
|
1204
|
+
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
|
|
1205
|
+
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
|
1206
|
+
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
|
1207
|
+
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
for (i = 1, args = new Array(len -1); i < len; i++) {
|
|
1211
|
+
args[i - 1] = arguments[i];
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
listeners.fn.apply(listeners.context, args);
|
|
1215
|
+
} else {
|
|
1216
|
+
var length = listeners.length
|
|
1217
|
+
, j;
|
|
1218
|
+
|
|
1219
|
+
for (i = 0; i < length; i++) {
|
|
1220
|
+
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
|
|
1221
|
+
|
|
1222
|
+
switch (len) {
|
|
1223
|
+
case 1: listeners[i].fn.call(listeners[i].context); break;
|
|
1224
|
+
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
|
|
1225
|
+
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
|
|
1226
|
+
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
|
|
1227
|
+
default:
|
|
1228
|
+
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
|
|
1229
|
+
args[j - 1] = arguments[j];
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
listeners[i].fn.apply(listeners[i].context, args);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
return true;
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* Add a listener for a given event.
|
|
1242
|
+
*
|
|
1243
|
+
* @param {(String|Symbol)} event The event name.
|
|
1244
|
+
* @param {Function} fn The listener function.
|
|
1245
|
+
* @param {*} [context=this] The context to invoke the listener with.
|
|
1246
|
+
* @returns {EventEmitter} `this`.
|
|
1247
|
+
* @public
|
|
1248
|
+
*/
|
|
1249
|
+
EventEmitter.prototype.on = function on(event, fn, context) {
|
|
1250
|
+
return addListener(this, event, fn, context, false);
|
|
1251
|
+
};
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* Add a one-time listener for a given event.
|
|
1255
|
+
*
|
|
1256
|
+
* @param {(String|Symbol)} event The event name.
|
|
1257
|
+
* @param {Function} fn The listener function.
|
|
1258
|
+
* @param {*} [context=this] The context to invoke the listener with.
|
|
1259
|
+
* @returns {EventEmitter} `this`.
|
|
1260
|
+
* @public
|
|
1261
|
+
*/
|
|
1262
|
+
EventEmitter.prototype.once = function once(event, fn, context) {
|
|
1263
|
+
return addListener(this, event, fn, context, true);
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* Remove the listeners of a given event.
|
|
1268
|
+
*
|
|
1269
|
+
* @param {(String|Symbol)} event The event name.
|
|
1270
|
+
* @param {Function} fn Only remove the listeners that match this function.
|
|
1271
|
+
* @param {*} context Only remove the listeners that have this context.
|
|
1272
|
+
* @param {Boolean} once Only remove one-time listeners.
|
|
1273
|
+
* @returns {EventEmitter} `this`.
|
|
1274
|
+
* @public
|
|
1275
|
+
*/
|
|
1276
|
+
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
|
1277
|
+
var evt = prefix ? prefix + event : event;
|
|
1278
|
+
|
|
1279
|
+
if (!this._events[evt]) return this;
|
|
1280
|
+
if (!fn) {
|
|
1281
|
+
clearEvent(this, evt);
|
|
1282
|
+
return this;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
var listeners = this._events[evt];
|
|
1286
|
+
|
|
1287
|
+
if (listeners.fn) {
|
|
1288
|
+
if (
|
|
1289
|
+
listeners.fn === fn &&
|
|
1290
|
+
(!once || listeners.once) &&
|
|
1291
|
+
(!context || listeners.context === context)
|
|
1292
|
+
) {
|
|
1293
|
+
clearEvent(this, evt);
|
|
1294
|
+
}
|
|
1295
|
+
} else {
|
|
1296
|
+
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
|
1297
|
+
if (
|
|
1298
|
+
listeners[i].fn !== fn ||
|
|
1299
|
+
(once && !listeners[i].once) ||
|
|
1300
|
+
(context && listeners[i].context !== context)
|
|
1301
|
+
) {
|
|
1302
|
+
events.push(listeners[i]);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
//
|
|
1307
|
+
// Reset the array, or remove it completely if we have no more listeners.
|
|
1308
|
+
//
|
|
1309
|
+
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
|
|
1310
|
+
else clearEvent(this, evt);
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
return this;
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* Remove all listeners, or those of the specified event.
|
|
1318
|
+
*
|
|
1319
|
+
* @param {(String|Symbol)} [event] The event name.
|
|
1320
|
+
* @returns {EventEmitter} `this`.
|
|
1321
|
+
* @public
|
|
1322
|
+
*/
|
|
1323
|
+
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
|
1324
|
+
var evt;
|
|
1325
|
+
|
|
1326
|
+
if (event) {
|
|
1327
|
+
evt = prefix ? prefix + event : event;
|
|
1328
|
+
if (this._events[evt]) clearEvent(this, evt);
|
|
1329
|
+
} else {
|
|
1330
|
+
this._events = new Events();
|
|
1331
|
+
this._eventsCount = 0;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
return this;
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
//
|
|
1338
|
+
// Alias methods names because people roll like that.
|
|
1339
|
+
//
|
|
1340
|
+
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
1341
|
+
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
|
1342
|
+
|
|
1343
|
+
//
|
|
1344
|
+
// Expose the prefix.
|
|
1345
|
+
//
|
|
1346
|
+
EventEmitter.prefixed = prefix;
|
|
1347
|
+
|
|
1348
|
+
//
|
|
1349
|
+
// Allow `EventEmitter` to be imported as module namespace.
|
|
1350
|
+
//
|
|
1351
|
+
EventEmitter.EventEmitter = EventEmitter;
|
|
1352
|
+
|
|
1353
|
+
//
|
|
1354
|
+
// Expose the module.
|
|
1355
|
+
//
|
|
1356
|
+
{
|
|
1357
|
+
module.exports = EventEmitter;
|
|
1358
|
+
}
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1361
|
+
/**
|
|
1362
|
+
* Extended Event Emitted class
|
|
1363
|
+
*
|
|
1364
|
+
* ```typescript
|
|
1365
|
+
* const emitter = new EmitterEventPayload();
|
|
1366
|
+
*
|
|
1367
|
+
* // promise will be rejected in 20 secs
|
|
1368
|
+
* // if no one event has been received with type 'ref-uuid-value'
|
|
1369
|
+
* // otherwise promise will be fulfilled with payload object
|
|
1370
|
+
* const promise = emitter.onceWithTimeout('ref-uuid-value', 20000)
|
|
1371
|
+
* ```
|
|
1372
|
+
*/
|
|
1373
|
+
class ExtendedEventEmitter extends eventemitter3 {
|
|
1374
|
+
constructor() {
|
|
1375
|
+
super();
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Wait when event with `type` will be emitted for `timeout` ms.
|
|
1379
|
+
*
|
|
1380
|
+
* ```js
|
|
1381
|
+
* emitter.onceWithTimeout('d6910a9d-ea24-5fc6-a654-28781ef21f8f', 20000)
|
|
1382
|
+
* // => Promise
|
|
1383
|
+
* ```
|
|
1384
|
+
* @param type - Event type, uuid or EVENT_TYPE.RECV for standalone events from client
|
|
1385
|
+
* @param timeout - Timeout in ms
|
|
1386
|
+
* @returns Promise.
|
|
1387
|
+
*/
|
|
1388
|
+
onceWithTimeout(type, timeout) {
|
|
1389
|
+
return new Promise((resolve, reject) => {
|
|
1390
|
+
const timer = setTimeout(reject, timeout);
|
|
1391
|
+
this.once(type, (event) => {
|
|
1392
|
+
clearTimeout(timer);
|
|
1393
|
+
resolve(event);
|
|
1394
|
+
});
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/** @ignore */
|
|
1400
|
+
const log = (...args) => {
|
|
1401
|
+
const text = args.map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg))).join(' ');
|
|
1402
|
+
alert(text);
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
class AndroidBridge {
|
|
1406
|
+
eventEmitter;
|
|
1407
|
+
hasCommunicationObject;
|
|
1408
|
+
logsEnabled;
|
|
1409
|
+
isRenameParamsEnabled;
|
|
1410
|
+
constructor() {
|
|
1411
|
+
this.hasCommunicationObject = typeof window.express !== 'undefined' && !!window.express.handleSmartAppEvent;
|
|
1412
|
+
this.eventEmitter = new ExtendedEventEmitter();
|
|
1413
|
+
this.logsEnabled = false;
|
|
1414
|
+
this.isRenameParamsEnabled = true;
|
|
1415
|
+
if (!this.hasCommunicationObject) {
|
|
1416
|
+
log('No method "express.handleSmartAppEvent", cannot send message to Android');
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
// Expect json data as string
|
|
1420
|
+
window.handleAndroidEvent = ({ ref, data, files, }) => {
|
|
1421
|
+
if (this.logsEnabled)
|
|
1422
|
+
console.log('Bridge ~ Incoming event', JSON.stringify({
|
|
1423
|
+
ref,
|
|
1424
|
+
data,
|
|
1425
|
+
files,
|
|
1426
|
+
}, null, 2));
|
|
1427
|
+
const { type, ...payload } = data;
|
|
1428
|
+
const emitterType = ref || EVENT_TYPE.RECEIVE;
|
|
1429
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1430
|
+
files?.map((file) => snakeCaseToCamelCase(file)) : files;
|
|
1431
|
+
const event = {
|
|
1432
|
+
ref,
|
|
1433
|
+
type,
|
|
1434
|
+
payload: this.isRenameParamsEnabled ? snakeCaseToCamelCase(payload) : payload,
|
|
1435
|
+
files: eventFiles,
|
|
1436
|
+
};
|
|
1437
|
+
this.eventEmitter.emit(emitterType, event);
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Set callback function to handle events without **ref**
|
|
1442
|
+
* (notifications for example).
|
|
1443
|
+
*
|
|
1444
|
+
* ```js
|
|
1445
|
+
* bridge.onReceive(({ type, handler, payload }) => {
|
|
1446
|
+
* // Handle event data
|
|
1447
|
+
* console.log('event', type, handler, payload)
|
|
1448
|
+
* })
|
|
1449
|
+
* ```
|
|
1450
|
+
* @param callback - Callback function.
|
|
1451
|
+
*/
|
|
1452
|
+
onReceive(callback) {
|
|
1453
|
+
this.eventEmitter.on(EVENT_TYPE.RECEIVE, callback);
|
|
1454
|
+
}
|
|
1455
|
+
sendEvent({ handler, method, params, files, timeout = RESPONSE_TIMEOUT, guaranteed_delivery_required = false, }) {
|
|
1456
|
+
if (!this.hasCommunicationObject)
|
|
1457
|
+
return Promise.reject();
|
|
1458
|
+
const ref = v4(); // UUID to detect express response.
|
|
1459
|
+
const eventParams = {
|
|
1460
|
+
ref,
|
|
1461
|
+
type: WEB_COMMAND_TYPE_RPC,
|
|
1462
|
+
method,
|
|
1463
|
+
handler,
|
|
1464
|
+
payload: this.isRenameParamsEnabled ? camelCaseToSnakeCase(params) : params,
|
|
1465
|
+
guaranteed_delivery_required,
|
|
1466
|
+
};
|
|
1467
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1468
|
+
files?.map((file) => camelCaseToSnakeCase(file)) : files;
|
|
1469
|
+
const event = JSON.stringify(files ? { ...eventParams, files: eventFiles } : eventParams);
|
|
1470
|
+
if (this.logsEnabled)
|
|
1471
|
+
console.log('Bridge ~ Outgoing event', JSON.stringify(event, null, ' '));
|
|
1472
|
+
window.express.handleSmartAppEvent(event);
|
|
1473
|
+
return this.eventEmitter.onceWithTimeout(ref, timeout);
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* Send event and wait response from express client.
|
|
1477
|
+
*
|
|
1478
|
+
* ```js
|
|
1479
|
+
* bridge
|
|
1480
|
+
* .sendBotEvent(
|
|
1481
|
+
* {
|
|
1482
|
+
* method: 'get_weather',
|
|
1483
|
+
* params: {
|
|
1484
|
+
* city: 'Moscow',
|
|
1485
|
+
* },
|
|
1486
|
+
* files: []
|
|
1487
|
+
* }
|
|
1488
|
+
* )
|
|
1489
|
+
* .then(data => {
|
|
1490
|
+
* // Handle response
|
|
1491
|
+
* console.log('response', data)
|
|
1492
|
+
* })
|
|
1493
|
+
* ```
|
|
1494
|
+
* @param method - Event type.
|
|
1495
|
+
* @param params
|
|
1496
|
+
* @param files
|
|
1497
|
+
* @param timeout - Timeout in ms.
|
|
1498
|
+
* @param guaranteed_delivery_required - boolean.
|
|
1499
|
+
* @returns Promise.
|
|
1500
|
+
*/
|
|
1501
|
+
sendBotEvent({ method, params, files, timeout, guaranteed_delivery_required }) {
|
|
1502
|
+
return this.sendEvent({ handler: HANDLER.BOTX, method, params, files, timeout, guaranteed_delivery_required });
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Send event and wait response from express client.
|
|
1506
|
+
*
|
|
1507
|
+
* ```js
|
|
1508
|
+
* bridge
|
|
1509
|
+
* .sendClientEvent(
|
|
1510
|
+
* {
|
|
1511
|
+
* type: 'get_weather',
|
|
1512
|
+
* handler: 'express',
|
|
1513
|
+
* payload: {
|
|
1514
|
+
* city: 'Moscow',
|
|
1515
|
+
* },
|
|
1516
|
+
* }
|
|
1517
|
+
* )
|
|
1518
|
+
* .then(data => {
|
|
1519
|
+
* // Handle response
|
|
1520
|
+
* console.log('response', data)
|
|
1521
|
+
* })
|
|
1522
|
+
* ```
|
|
1523
|
+
* @param method - Event type.
|
|
1524
|
+
* @param params
|
|
1525
|
+
* @param timeout - Timeout in ms.
|
|
1526
|
+
* @returns Promise.
|
|
1527
|
+
*/
|
|
1528
|
+
sendClientEvent({ method, params, timeout }) {
|
|
1529
|
+
return this.sendEvent({ handler: HANDLER.EXPRESS, method, params, timeout });
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Enabling logs.
|
|
1533
|
+
*
|
|
1534
|
+
* ```js
|
|
1535
|
+
* bridge
|
|
1536
|
+
* .enableLogs()
|
|
1537
|
+
* ```
|
|
1538
|
+
*/
|
|
1539
|
+
enableLogs() {
|
|
1540
|
+
this.logsEnabled = true;
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Disabling logs.
|
|
1544
|
+
*
|
|
1545
|
+
* ```js
|
|
1546
|
+
* bridge
|
|
1547
|
+
* .disableLogs()
|
|
1548
|
+
* ```
|
|
1549
|
+
*/
|
|
1550
|
+
disableLogs() {
|
|
1551
|
+
this.logsEnabled = false;
|
|
1552
|
+
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1555
|
+
* ```js
|
|
1556
|
+
* bridge
|
|
1557
|
+
* .enableRenameParams()
|
|
1558
|
+
* ```
|
|
1559
|
+
*/
|
|
1560
|
+
enableRenameParams() {
|
|
1561
|
+
this.isRenameParamsEnabled = true;
|
|
1562
|
+
console.log('Bridge ~ Enabled renaming event params from camelCase to snake_case and vice versa');
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1566
|
+
* ```js
|
|
1567
|
+
* bridge
|
|
1568
|
+
* .disableRenameParams()
|
|
1569
|
+
* ```
|
|
1570
|
+
*/
|
|
1571
|
+
disableRenameParams() {
|
|
1572
|
+
this.isRenameParamsEnabled = false;
|
|
1573
|
+
console.log('Bridge ~ Disabled renaming event params from camelCase to snake_case and vice versa');
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
class IosBridge {
|
|
1578
|
+
eventEmitter;
|
|
1579
|
+
hasCommunicationObject;
|
|
1580
|
+
logsEnabled;
|
|
1581
|
+
isRenameParamsEnabled;
|
|
1582
|
+
constructor() {
|
|
1583
|
+
this.hasCommunicationObject =
|
|
1584
|
+
window.webkit &&
|
|
1585
|
+
window.webkit.messageHandlers &&
|
|
1586
|
+
window.webkit.messageHandlers.express &&
|
|
1587
|
+
!!window.webkit.messageHandlers.express.postMessage;
|
|
1588
|
+
this.eventEmitter = new ExtendedEventEmitter();
|
|
1589
|
+
this.logsEnabled = false;
|
|
1590
|
+
this.isRenameParamsEnabled = true;
|
|
1591
|
+
if (!this.hasCommunicationObject) {
|
|
1592
|
+
log('No method "express.postMessage", cannot send message to iOS');
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
// Expect json data as string
|
|
1596
|
+
window.handleIosEvent = ({ ref, data, files, }) => {
|
|
1597
|
+
if (this.logsEnabled)
|
|
1598
|
+
console.log('Bridge ~ Incoming event', JSON.stringify({
|
|
1599
|
+
ref,
|
|
1600
|
+
data,
|
|
1601
|
+
files,
|
|
1602
|
+
}, null, 2));
|
|
1603
|
+
const { type, ...payload } = data;
|
|
1604
|
+
const emitterType = ref || EVENT_TYPE.RECEIVE;
|
|
1605
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1606
|
+
files?.map((file) => snakeCaseToCamelCase(file)) : files;
|
|
1607
|
+
const event = {
|
|
1608
|
+
ref,
|
|
1609
|
+
type,
|
|
1610
|
+
payload: this.isRenameParamsEnabled ? snakeCaseToCamelCase(payload) : payload,
|
|
1611
|
+
files: eventFiles,
|
|
1612
|
+
};
|
|
1613
|
+
this.eventEmitter.emit(emitterType, event);
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Set callback function to handle events without **ref**
|
|
1618
|
+
* (notifications for example).
|
|
1619
|
+
*
|
|
1620
|
+
* ```js
|
|
1621
|
+
* bridge.onRecieve(({ type, handler, payload }) => {
|
|
1622
|
+
* // Handle event data
|
|
1623
|
+
* console.log('event', type, handler, payload)
|
|
1624
|
+
* })
|
|
1625
|
+
* ```
|
|
1626
|
+
* @param callback - Callback function.
|
|
1627
|
+
*/
|
|
1628
|
+
onReceive(callback) {
|
|
1629
|
+
this.eventEmitter.on(EVENT_TYPE.RECEIVE, callback);
|
|
1630
|
+
}
|
|
1631
|
+
sendEvent({ handler, method, params, files, timeout = RESPONSE_TIMEOUT, guaranteed_delivery_required = false, }) {
|
|
1632
|
+
if (!this.hasCommunicationObject)
|
|
1633
|
+
return Promise.reject();
|
|
1634
|
+
const ref = v4(); // UUID to detect express response.
|
|
1635
|
+
const eventProps = {
|
|
1636
|
+
ref,
|
|
1637
|
+
type: WEB_COMMAND_TYPE_RPC,
|
|
1638
|
+
method,
|
|
1639
|
+
handler,
|
|
1640
|
+
payload: this.isRenameParamsEnabled ? camelCaseToSnakeCase(params) : params,
|
|
1641
|
+
guaranteed_delivery_required,
|
|
1642
|
+
};
|
|
1643
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1644
|
+
files?.map((file) => camelCaseToSnakeCase(file)) : files;
|
|
1645
|
+
const event = files ? { ...eventProps, files: eventFiles } : eventProps;
|
|
1646
|
+
if (this.logsEnabled)
|
|
1647
|
+
console.log('Bridge ~ Outgoing event', JSON.stringify(event, null, ' '));
|
|
1648
|
+
window.webkit.messageHandlers.express.postMessage(event);
|
|
1649
|
+
return this.eventEmitter.onceWithTimeout(ref, timeout);
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Send event and wait response from express client.
|
|
1653
|
+
*
|
|
1654
|
+
* ```js
|
|
1655
|
+
* bridge
|
|
1656
|
+
* .sendBotEvent(
|
|
1657
|
+
* {
|
|
1658
|
+
* method: 'get_weather',
|
|
1659
|
+
* params: {
|
|
1660
|
+
* city: 'Moscow',
|
|
1661
|
+
* },
|
|
1662
|
+
* files: []
|
|
1663
|
+
* }
|
|
1664
|
+
* )
|
|
1665
|
+
* .then(data => {
|
|
1666
|
+
* // Handle response
|
|
1667
|
+
* console.log('response', data)
|
|
1668
|
+
* })
|
|
1669
|
+
* ```
|
|
1670
|
+
* @param method - Event type.
|
|
1671
|
+
* @param params
|
|
1672
|
+
* @param files
|
|
1673
|
+
* @param timeout - Timeout in ms.
|
|
1674
|
+
* @param guaranteed_delivery_required - boolean.
|
|
1675
|
+
*/
|
|
1676
|
+
sendBotEvent({ method, params, files, timeout = RESPONSE_TIMEOUT, guaranteed_delivery_required, }) {
|
|
1677
|
+
return this.sendEvent({ handler: HANDLER.BOTX, method, params, files, timeout, guaranteed_delivery_required });
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Send event and wait response from express client.
|
|
1681
|
+
*
|
|
1682
|
+
* ```js
|
|
1683
|
+
* bridge
|
|
1684
|
+
* .sendClientEvent(
|
|
1685
|
+
* {
|
|
1686
|
+
* type: 'get_weather',
|
|
1687
|
+
* handler: 'express',
|
|
1688
|
+
* payload: {
|
|
1689
|
+
* city: 'Moscow',
|
|
1690
|
+
* },
|
|
1691
|
+
* }
|
|
1692
|
+
* )
|
|
1693
|
+
* .then(data => {
|
|
1694
|
+
* // Handle response
|
|
1695
|
+
* console.log('response', data)
|
|
1696
|
+
* })
|
|
1697
|
+
* ```
|
|
1698
|
+
* @param method - Event type.
|
|
1699
|
+
* @param params
|
|
1700
|
+
* @param timeout - Timeout in ms.
|
|
1701
|
+
*/
|
|
1702
|
+
sendClientEvent({ method, params, timeout = RESPONSE_TIMEOUT }) {
|
|
1703
|
+
return this.sendEvent({ handler: HANDLER.EXPRESS, method, params, timeout });
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Enabling logs.
|
|
1707
|
+
*
|
|
1708
|
+
* ```js
|
|
1709
|
+
* bridge
|
|
1710
|
+
* .enableLogs()
|
|
1711
|
+
* ```
|
|
1712
|
+
*/
|
|
1713
|
+
enableLogs() {
|
|
1714
|
+
this.logsEnabled = true;
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Disabling logs.
|
|
1718
|
+
*
|
|
1719
|
+
* ```js
|
|
1720
|
+
* bridge
|
|
1721
|
+
* .disableLogs()
|
|
1722
|
+
* ```
|
|
1723
|
+
*/
|
|
1724
|
+
disableLogs() {
|
|
1725
|
+
this.logsEnabled = false;
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1729
|
+
* ```js
|
|
1730
|
+
* bridge
|
|
1731
|
+
* .enableRenameParams()
|
|
1732
|
+
* ```
|
|
1733
|
+
*/
|
|
1734
|
+
enableRenameParams() {
|
|
1735
|
+
this.isRenameParamsEnabled = true;
|
|
1736
|
+
console.log('Bridge ~ Enabled renaming event params from camelCase to snake_case and vice versa');
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1740
|
+
* ```js
|
|
1741
|
+
* bridge
|
|
1742
|
+
* .disableRenameParams()
|
|
1743
|
+
* ```
|
|
1744
|
+
*/
|
|
1745
|
+
disableRenameParams() {
|
|
1746
|
+
this.isRenameParamsEnabled = false;
|
|
1747
|
+
console.log('Bridge ~ Disabled renaming event params from camelCase to snake_case and vice versa');
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
class WebBridge {
|
|
1752
|
+
eventEmitter;
|
|
1753
|
+
logsEnabled;
|
|
1754
|
+
isRenameParamsEnabled;
|
|
1755
|
+
constructor() {
|
|
1756
|
+
this.eventEmitter = new ExtendedEventEmitter();
|
|
1757
|
+
this.addGlobalListener();
|
|
1758
|
+
this.logsEnabled = false;
|
|
1759
|
+
this.isRenameParamsEnabled = true;
|
|
1760
|
+
}
|
|
1761
|
+
addGlobalListener() {
|
|
1762
|
+
window.addEventListener('message', (event) => {
|
|
1763
|
+
if (typeof event.data !== 'object' ||
|
|
1764
|
+
typeof event.data.data !== 'object' ||
|
|
1765
|
+
typeof event.data.data.type !== 'string')
|
|
1766
|
+
return;
|
|
1767
|
+
if (this.logsEnabled)
|
|
1768
|
+
console.log('Bridge ~ Incoming event', event.data);
|
|
1769
|
+
const { ref, data: { type, ...payload }, files, } = event.data;
|
|
1770
|
+
const emitterType = ref || EVENT_TYPE.RECEIVE;
|
|
1771
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1772
|
+
files?.map((file) => snakeCaseToCamelCase(file)) : files;
|
|
1773
|
+
this.eventEmitter.emit(emitterType, {
|
|
1774
|
+
ref,
|
|
1775
|
+
type,
|
|
1776
|
+
payload: this.isRenameParamsEnabled ? snakeCaseToCamelCase(payload) : payload,
|
|
1777
|
+
files: eventFiles,
|
|
1778
|
+
});
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
/**
|
|
1782
|
+
* Set callback function to handle events without **ref**
|
|
1783
|
+
* (notifications for example).
|
|
1784
|
+
*
|
|
1785
|
+
* ```js
|
|
1786
|
+
* bridge.onReceive(({ type, handler, payload }) => {
|
|
1787
|
+
* // Handle event data
|
|
1788
|
+
* console.log('event', type, handler, payload)
|
|
1789
|
+
* })
|
|
1790
|
+
* ```
|
|
1791
|
+
* @param callback - Callback function.
|
|
1792
|
+
*/
|
|
1793
|
+
onReceive(callback) {
|
|
1794
|
+
this.eventEmitter.on(EVENT_TYPE.RECEIVE, callback);
|
|
1795
|
+
}
|
|
1796
|
+
sendEvent({ handler, method, params, files, timeout = RESPONSE_TIMEOUT, guaranteed_delivery_required = false, }) {
|
|
1797
|
+
const ref = v4(); // UUID to detect express response.
|
|
1798
|
+
const payload = {
|
|
1799
|
+
ref,
|
|
1800
|
+
type: WEB_COMMAND_TYPE_RPC,
|
|
1801
|
+
method,
|
|
1802
|
+
handler,
|
|
1803
|
+
payload: this.isRenameParamsEnabled ? camelCaseToSnakeCase(params) : params,
|
|
1804
|
+
guaranteed_delivery_required,
|
|
1805
|
+
};
|
|
1806
|
+
const eventFiles = this.isRenameParamsEnabled ?
|
|
1807
|
+
files?.map((file) => camelCaseToSnakeCase(file)) : files;
|
|
1808
|
+
const event = files ? { ...payload, files: eventFiles } : payload;
|
|
1809
|
+
if (this.logsEnabled)
|
|
1810
|
+
console.log('Bridge ~ Outgoing event', event);
|
|
1811
|
+
window.parent.postMessage({
|
|
1812
|
+
type: WEB_COMMAND_TYPE,
|
|
1813
|
+
payload: event,
|
|
1814
|
+
}, '*');
|
|
1815
|
+
return this.eventEmitter.onceWithTimeout(ref, timeout);
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Send event and wait response from express client.
|
|
1819
|
+
*
|
|
1820
|
+
* ```js
|
|
1821
|
+
* bridge
|
|
1822
|
+
* .sendClientEvent(
|
|
1823
|
+
* {
|
|
1824
|
+
* method: 'get_weather',
|
|
1825
|
+
* params: {
|
|
1826
|
+
* city: 'Moscow',
|
|
1827
|
+
* },
|
|
1828
|
+
* }
|
|
1829
|
+
* )
|
|
1830
|
+
* .then(data => {
|
|
1831
|
+
* // Handle response
|
|
1832
|
+
* console.log('response', data)
|
|
1833
|
+
* })
|
|
1834
|
+
* ```
|
|
1835
|
+
* @param method - Event type.
|
|
1836
|
+
* @param params
|
|
1837
|
+
* @param files
|
|
1838
|
+
* @param is_rename_params_fields - boolean.
|
|
1839
|
+
* @param timeout - Timeout in ms.
|
|
1840
|
+
* @param guaranteed_delivery_required - boolean.
|
|
1841
|
+
*/
|
|
1842
|
+
sendBotEvent({ method, params, files, timeout, guaranteed_delivery_required, }) {
|
|
1843
|
+
return this.sendEvent({
|
|
1844
|
+
handler: HANDLER.BOTX,
|
|
1845
|
+
method,
|
|
1846
|
+
params,
|
|
1847
|
+
files,
|
|
1848
|
+
timeout,
|
|
1849
|
+
guaranteed_delivery_required,
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* Send event and wait response from express client.
|
|
1854
|
+
*
|
|
1855
|
+
* ```js
|
|
1856
|
+
* bridge
|
|
1857
|
+
* .sendClientEvent(
|
|
1858
|
+
* {
|
|
1859
|
+
* method: 'get_weather',
|
|
1860
|
+
* params: {
|
|
1861
|
+
* city: 'Moscow',
|
|
1862
|
+
* },
|
|
1863
|
+
* }
|
|
1864
|
+
* )
|
|
1865
|
+
* .then(data => {
|
|
1866
|
+
* // Handle response
|
|
1867
|
+
* console.log('response', data)
|
|
1868
|
+
* })
|
|
1869
|
+
* ```
|
|
1870
|
+
* @param method - Event type.
|
|
1871
|
+
* @param params
|
|
1872
|
+
* @param timeout - Timeout in ms.
|
|
1873
|
+
*/
|
|
1874
|
+
sendClientEvent({ method, params, timeout }) {
|
|
1875
|
+
return this.sendEvent({ handler: HANDLER.EXPRESS, method, params, timeout });
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* Enabling logs.
|
|
1879
|
+
*
|
|
1880
|
+
* ```js
|
|
1881
|
+
* bridge
|
|
1882
|
+
* .enableLogs()
|
|
1883
|
+
* ```
|
|
1884
|
+
*/
|
|
1885
|
+
enableLogs() {
|
|
1886
|
+
this.logsEnabled = true;
|
|
1887
|
+
const _log = console.log;
|
|
1888
|
+
console.log = function (...rest) {
|
|
1889
|
+
window.parent.postMessage({
|
|
1890
|
+
type: WEB_COMMAND_TYPE_RPC_LOGS,
|
|
1891
|
+
payload: rest,
|
|
1892
|
+
}, '*');
|
|
1893
|
+
_log.apply(console, rest);
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Disabling logs.
|
|
1898
|
+
*
|
|
1899
|
+
* ```js
|
|
1900
|
+
* bridge
|
|
1901
|
+
* .disableLogs()
|
|
1902
|
+
* ```
|
|
1903
|
+
*/
|
|
1904
|
+
disableLogs() {
|
|
1905
|
+
this.logsEnabled = false;
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1909
|
+
* ```js
|
|
1910
|
+
* bridge
|
|
1911
|
+
* .enableRenameParams()
|
|
1912
|
+
* ```
|
|
1913
|
+
*/
|
|
1914
|
+
enableRenameParams() {
|
|
1915
|
+
this.isRenameParamsEnabled = true;
|
|
1916
|
+
console.log('Bridge ~ Enabled renaming event params from camelCase to snake_case and vice versa');
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Enabling renaming event params from camelCase to snake_case and vice versa
|
|
1920
|
+
* ```js
|
|
1921
|
+
* bridge
|
|
1922
|
+
* .disableRenameParams()
|
|
1923
|
+
* ```
|
|
1924
|
+
*/
|
|
1925
|
+
disableRenameParams() {
|
|
1926
|
+
this.isRenameParamsEnabled = false;
|
|
1927
|
+
console.log('Bridge ~ Disabled renaming event params from camelCase to snake_case and vice versa');
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
const LIB_VERSION = "1.0.0";
|
|
1932
|
+
|
|
1933
|
+
const getBridge = () => {
|
|
1934
|
+
if (process.env.NODE_ENV === 'test')
|
|
1935
|
+
return null;
|
|
1936
|
+
const platform = getPlatform();
|
|
1937
|
+
console.log('Bridge ~ version', LIB_VERSION);
|
|
1938
|
+
switch (platform) {
|
|
1939
|
+
case PLATFORM.ANDROID:
|
|
1940
|
+
return new AndroidBridge();
|
|
1941
|
+
case PLATFORM.IOS:
|
|
1942
|
+
return new IosBridge();
|
|
1943
|
+
case PLATFORM.WEB:
|
|
1944
|
+
return new WebBridge();
|
|
1945
|
+
default:
|
|
1946
|
+
console.error('Wrong platform');
|
|
1947
|
+
break;
|
|
1948
|
+
}
|
|
1949
|
+
return null;
|
|
1950
|
+
};
|
|
1951
|
+
var bridge = getBridge();
|
|
1952
|
+
|
|
1953
|
+
var EVENT_TYPES;
|
|
1954
|
+
(function (EVENT_TYPES) {
|
|
1955
|
+
EVENT_TYPES["READY"] = "ready";
|
|
1956
|
+
EVENT_TYPES["ROUTING_CHANGED"] = "routing_changes";
|
|
1957
|
+
EVENT_TYPES["BACK_PRESSED"] = "back_pressed";
|
|
1958
|
+
EVENT_TYPES["ADD_CONTACT"] = "add_contact";
|
|
1959
|
+
EVENT_TYPES["GET_CONTACT"] = "get_contact";
|
|
1960
|
+
EVENT_TYPES["CREATE_PERSONAL_CHAT"] = "create_personal_chat";
|
|
1961
|
+
EVENT_TYPES["SEND_MESSAGE"] = "send_message";
|
|
1962
|
+
EVENT_TYPES["NOTIFICATION"] = "notification";
|
|
1963
|
+
})(EVENT_TYPES || (EVENT_TYPES = {}));
|
|
1964
|
+
|
|
1965
|
+
var LOCATION;
|
|
1966
|
+
(function (LOCATION) {
|
|
1967
|
+
LOCATION["ROOT"] = "root";
|
|
1968
|
+
LOCATION["NESTED"] = "nested";
|
|
1969
|
+
})(LOCATION || (LOCATION = {}));
|
|
1970
|
+
|
|
1971
|
+
const addContact = async ({ phone, name }) => {
|
|
1972
|
+
return bridge?.sendClientEvent({
|
|
1973
|
+
method: EVENT_TYPES.ADD_CONTACT,
|
|
1974
|
+
params: {
|
|
1975
|
+
phone,
|
|
1976
|
+
name,
|
|
1977
|
+
},
|
|
1978
|
+
});
|
|
1979
|
+
};
|
|
1980
|
+
const getContact = async ({ phone }) => {
|
|
1981
|
+
return bridge?.sendClientEvent({
|
|
1982
|
+
method: EVENT_TYPES.GET_CONTACT,
|
|
1983
|
+
params: { phone },
|
|
1984
|
+
});
|
|
1985
|
+
};
|
|
1986
|
+
const createPersonalChat = async ({ huid }) => {
|
|
1987
|
+
return bridge?.sendClientEvent({
|
|
1988
|
+
method: EVENT_TYPES.CREATE_PERSONAL_CHAT,
|
|
1989
|
+
params: { huid },
|
|
1990
|
+
});
|
|
1991
|
+
};
|
|
1992
|
+
const sendMessage = ({ userHuid = null, groupChatId = null, messageBody = '', messageMeta = {} }) => {
|
|
1993
|
+
return bridge?.sendClientEvent({
|
|
1994
|
+
method: EVENT_TYPES.SEND_MESSAGE,
|
|
1995
|
+
params: { userHuid, groupChatId, message: {
|
|
1996
|
+
body: messageBody,
|
|
1997
|
+
meta: messageMeta,
|
|
1998
|
+
} },
|
|
1999
|
+
});
|
|
2000
|
+
};
|
|
2001
|
+
|
|
2002
|
+
const useQuery = () => {
|
|
2003
|
+
const urlSearchParams = new URLSearchParams(window.location.search);
|
|
2004
|
+
return Object.fromEntries(urlSearchParams.entries());
|
|
2005
|
+
};
|
|
2006
|
+
|
|
2007
|
+
const bridgeSendReady = async (timeout) => {
|
|
2008
|
+
const event = {
|
|
2009
|
+
method: EVENT_TYPES.READY,
|
|
2010
|
+
params: {},
|
|
2011
|
+
};
|
|
2012
|
+
return bridge?.sendClientEvent(timeout ? { ...event, timeout } : event);
|
|
2013
|
+
};
|
|
2014
|
+
|
|
2015
|
+
const ready = async (timeout) => {
|
|
2016
|
+
const response = await bridgeSendReady(timeout);
|
|
2017
|
+
const Bridge = bridge;
|
|
2018
|
+
const isLogsEnabled = response?.payload?.logsEnabled;
|
|
2019
|
+
if (isLogsEnabled)
|
|
2020
|
+
Bridge?.enableLogs?.();
|
|
2021
|
+
return response;
|
|
2022
|
+
};
|
|
2023
|
+
|
|
2024
|
+
const onNotification = async (handleNotification) => {
|
|
2025
|
+
const response = await bridge?.sendClientEvent({
|
|
2026
|
+
method: EVENT_TYPES.NOTIFICATION,
|
|
2027
|
+
params: {},
|
|
2028
|
+
});
|
|
2029
|
+
return bridge?.onReceive((event) => {
|
|
2030
|
+
if (event.type === EVENT_TYPES.NOTIFICATION)
|
|
2031
|
+
handleNotification(response);
|
|
2032
|
+
});
|
|
2033
|
+
};
|
|
2034
|
+
|
|
2035
|
+
const routingChanged = async (isRoot) => {
|
|
2036
|
+
return bridge?.sendClientEvent({
|
|
2037
|
+
method: EVENT_TYPES.ROUTING_CHANGED,
|
|
2038
|
+
params: {
|
|
2039
|
+
location: isRoot ? LOCATION.ROOT : LOCATION.NESTED,
|
|
2040
|
+
},
|
|
2041
|
+
});
|
|
2042
|
+
};
|
|
2043
|
+
const onBackPressed = async (handleBackPressed) => {
|
|
2044
|
+
return bridge?.onReceive((event) => {
|
|
2045
|
+
if (event.type === EVENT_TYPES.BACK_PRESSED)
|
|
2046
|
+
handleBackPressed();
|
|
2047
|
+
});
|
|
2048
|
+
};
|
|
2049
|
+
|
|
2050
|
+
exports.Bridge = bridge;
|
|
2051
|
+
exports.addContact = addContact;
|
|
2052
|
+
exports.createPersonalChat = createPersonalChat;
|
|
2053
|
+
exports.getContact = getContact;
|
|
2054
|
+
exports.onBackPressed = onBackPressed;
|
|
2055
|
+
exports.onNotification = onNotification;
|
|
2056
|
+
exports.ready = ready;
|
|
2057
|
+
exports.routingChanged = routingChanged;
|
|
2058
|
+
exports.sendMessage = sendMessage;
|
|
2059
|
+
exports.useQuery = useQuery;
|
|
2060
|
+
|
|
2061
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2062
|
+
|
|
2063
|
+
}));
|