radar-sdk-js 4.2.1-beta.2 → 4.3.0-beta.1
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 +7 -7
- package/dist/http.d.ts +3 -1
- package/dist/radar.js +1677 -1875
- package/dist/radar.js.map +1 -1
- package/dist/types.d.ts +11 -6
- package/dist/ui/RadarLogoControl.d.ts +6 -0
- package/dist/ui/RadarMap.d.ts +11 -0
- package/dist/ui/RadarMarker.d.ts +11 -0
- package/dist/ui/map.d.ts +4 -2
- package/dist/util/_.d.ts +2 -0
- package/dist/util/mapStyle.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/api/track.ts +26 -26
- package/src/http.ts +35 -24
- package/src/types.ts +12 -6
- package/src/ui/RadarLogoControl.ts +24 -0
- package/src/ui/RadarMap.ts +155 -0
- package/src/ui/RadarMarker.ts +126 -0
- package/src/ui/map.ts +9 -143
- package/src/util/_.ts +30 -0
- package/src/util/mapStyle.ts +85 -0
- package/src/version.ts +1 -1
package/dist/radar.js
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
import maplibregl from 'maplibre-gl';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
Config.setup = function (options) {
|
|
7
|
-
if (options === void 0) { options = {}; }
|
|
3
|
+
class Config {
|
|
4
|
+
static setup(options = {}) {
|
|
8
5
|
Config.options = options;
|
|
9
|
-
}
|
|
10
|
-
|
|
6
|
+
}
|
|
7
|
+
static get() {
|
|
11
8
|
return Config.options || {};
|
|
12
|
-
}
|
|
13
|
-
|
|
9
|
+
}
|
|
10
|
+
static clear() {
|
|
14
11
|
Config.options = {};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}());
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
Config.defaultOptions = {
|
|
15
|
+
live: false,
|
|
16
|
+
logLevel: 'error',
|
|
17
|
+
host: 'https://api.radar.io',
|
|
18
|
+
version: 'v1',
|
|
19
|
+
debug: false,
|
|
20
|
+
};
|
|
25
21
|
|
|
26
|
-
|
|
22
|
+
const LOG_LEVELS = {
|
|
27
23
|
none: 0,
|
|
28
24
|
error: 1,
|
|
29
25
|
warn: 2,
|
|
@@ -31,12 +27,12 @@ var LOG_LEVELS = {
|
|
|
31
27
|
debug: 4,
|
|
32
28
|
};
|
|
33
29
|
// get the numeric level for logLevel option
|
|
34
|
-
|
|
30
|
+
const getLevel = () => {
|
|
35
31
|
// disable logging in tests
|
|
36
32
|
if (window && window.RADAR_TEST_ENV) {
|
|
37
33
|
return LOG_LEVELS.none;
|
|
38
34
|
}
|
|
39
|
-
|
|
35
|
+
const { logLevel, debug } = Config.get();
|
|
40
36
|
if (debug) {
|
|
41
37
|
return LOG_LEVELS.debug;
|
|
42
38
|
}
|
|
@@ -45,101 +41,64 @@ var getLevel = function () {
|
|
|
45
41
|
}
|
|
46
42
|
return LOG_LEVELS.error; // default to error-level logging if not set
|
|
47
43
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
Logger.debug = function (message) {
|
|
44
|
+
class Logger {
|
|
45
|
+
static debug(message) {
|
|
52
46
|
if (getLevel() === LOG_LEVELS.debug) {
|
|
53
|
-
console.log(
|
|
47
|
+
console.log(`Radar SDK (debug): ${message.trim()}`);
|
|
54
48
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
49
|
+
}
|
|
50
|
+
static info(message) {
|
|
57
51
|
if (getLevel() >= LOG_LEVELS.info) {
|
|
58
|
-
console.log(
|
|
52
|
+
console.log(`Radar SDK: ${message.trim()}`);
|
|
59
53
|
}
|
|
60
|
-
}
|
|
61
|
-
|
|
54
|
+
}
|
|
55
|
+
static warn(message) {
|
|
62
56
|
if (getLevel() >= LOG_LEVELS.warn) {
|
|
63
|
-
console.warn(
|
|
57
|
+
console.warn(`Radar SDK: ${message.trim()}`);
|
|
64
58
|
}
|
|
65
|
-
}
|
|
66
|
-
|
|
59
|
+
}
|
|
60
|
+
static error(message) {
|
|
67
61
|
if (getLevel() >= LOG_LEVELS.error) {
|
|
68
|
-
console.error(
|
|
62
|
+
console.error(`Radar SDK: ${message.trim()}`);
|
|
69
63
|
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
}());
|
|
64
|
+
}
|
|
65
|
+
}
|
|
73
66
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
103
|
-
enumerable: false,
|
|
104
|
-
configurable: true
|
|
105
|
-
});
|
|
106
|
-
Object.defineProperty(Storage, "DESCRIPTION", {
|
|
107
|
-
get: function () {
|
|
108
|
-
return 'radar-description';
|
|
109
|
-
},
|
|
110
|
-
enumerable: false,
|
|
111
|
-
configurable: true
|
|
112
|
-
});
|
|
113
|
-
Object.defineProperty(Storage, "METADATA", {
|
|
114
|
-
get: function () {
|
|
115
|
-
return 'radar-metadata';
|
|
116
|
-
},
|
|
117
|
-
enumerable: false,
|
|
118
|
-
configurable: true
|
|
119
|
-
});
|
|
120
|
-
Object.defineProperty(Storage, "CACHED_LOCATION", {
|
|
121
|
-
get: function () {
|
|
122
|
-
return 'radar-cached-location';
|
|
123
|
-
},
|
|
124
|
-
enumerable: false,
|
|
125
|
-
configurable: true
|
|
126
|
-
});
|
|
127
|
-
Object.defineProperty(Storage, "TRIP_OPTIONS", {
|
|
128
|
-
get: function () {
|
|
129
|
-
return 'radar-trip-options';
|
|
130
|
-
},
|
|
131
|
-
enumerable: false,
|
|
132
|
-
configurable: true
|
|
133
|
-
});
|
|
134
|
-
Storage.getStorage = function () {
|
|
135
|
-
var storage = window === null || window === void 0 ? void 0 : window.localStorage;
|
|
67
|
+
class Storage {
|
|
68
|
+
// local storage key definitions for identifying track users
|
|
69
|
+
static get USER_ID() {
|
|
70
|
+
return 'radar-userId';
|
|
71
|
+
}
|
|
72
|
+
static get DEVICE_ID() {
|
|
73
|
+
return 'radar-deviceId';
|
|
74
|
+
}
|
|
75
|
+
static get INSTALL_ID() {
|
|
76
|
+
return 'radar-installId';
|
|
77
|
+
}
|
|
78
|
+
static get SESSION_ID() {
|
|
79
|
+
return 'radar-sessionId';
|
|
80
|
+
}
|
|
81
|
+
static get DESCRIPTION() {
|
|
82
|
+
return 'radar-description';
|
|
83
|
+
}
|
|
84
|
+
static get METADATA() {
|
|
85
|
+
return 'radar-metadata';
|
|
86
|
+
}
|
|
87
|
+
static get CACHED_LOCATION() {
|
|
88
|
+
return 'radar-cached-location';
|
|
89
|
+
}
|
|
90
|
+
static get TRIP_OPTIONS() {
|
|
91
|
+
return 'radar-trip-options';
|
|
92
|
+
}
|
|
93
|
+
static getStorage() {
|
|
94
|
+
const storage = window === null || window === void 0 ? void 0 : window.localStorage;
|
|
136
95
|
if (!storage) {
|
|
137
96
|
Logger.warn('localStorage not available.');
|
|
138
97
|
}
|
|
139
98
|
return storage;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
99
|
+
}
|
|
100
|
+
static setItem(key, value) {
|
|
101
|
+
const storage = this.getStorage();
|
|
143
102
|
if (!storage) {
|
|
144
103
|
return;
|
|
145
104
|
}
|
|
@@ -147,20 +106,20 @@ var Storage = /** @class */ (function () {
|
|
|
147
106
|
return;
|
|
148
107
|
}
|
|
149
108
|
storage.setItem(key, value);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
109
|
+
}
|
|
110
|
+
static getItem(key) {
|
|
111
|
+
const storage = this.getStorage();
|
|
153
112
|
if (!storage) {
|
|
154
113
|
return null;
|
|
155
114
|
}
|
|
156
|
-
|
|
115
|
+
const value = storage.getItem(key);
|
|
157
116
|
if (value !== undefined && value !== null) {
|
|
158
117
|
return value;
|
|
159
118
|
}
|
|
160
119
|
return null;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
120
|
+
}
|
|
121
|
+
static getJSON(key) {
|
|
122
|
+
const item = this.getItem(key);
|
|
164
123
|
if (!item) {
|
|
165
124
|
return null;
|
|
166
125
|
}
|
|
@@ -168,26 +127,25 @@ var Storage = /** @class */ (function () {
|
|
|
168
127
|
return JSON.parse(item);
|
|
169
128
|
}
|
|
170
129
|
catch (err) {
|
|
171
|
-
Logger.warn(
|
|
130
|
+
Logger.warn(`could not getJSON from storage for key: ${key}`);
|
|
172
131
|
return null;
|
|
173
132
|
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
133
|
+
}
|
|
134
|
+
static removeItem(key) {
|
|
135
|
+
const storage = this.getStorage();
|
|
177
136
|
if (!storage) {
|
|
178
137
|
return null;
|
|
179
138
|
}
|
|
180
139
|
storage.removeItem(key);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
|
|
140
|
+
}
|
|
141
|
+
static clear() {
|
|
142
|
+
const storage = this.getStorage();
|
|
184
143
|
if (!storage) {
|
|
185
144
|
return null;
|
|
186
145
|
}
|
|
187
146
|
storage.clear();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
}());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
191
149
|
|
|
192
150
|
/******************************************************************************
|
|
193
151
|
Copyright (c) Microsoft Corporation.
|
|
@@ -205,31 +163,6 @@ PERFORMANCE OF THIS SOFTWARE.
|
|
|
205
163
|
***************************************************************************** */
|
|
206
164
|
/* global Reflect, Promise */
|
|
207
165
|
|
|
208
|
-
var extendStatics = function(d, b) {
|
|
209
|
-
extendStatics = Object.setPrototypeOf ||
|
|
210
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
211
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
212
|
-
return extendStatics(d, b);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
function __extends(d, b) {
|
|
216
|
-
if (typeof b !== "function" && b !== null)
|
|
217
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
218
|
-
extendStatics(d, b);
|
|
219
|
-
function __() { this.constructor = d; }
|
|
220
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
var __assign = function() {
|
|
224
|
-
__assign = Object.assign || function __assign(t) {
|
|
225
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
226
|
-
s = arguments[i];
|
|
227
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
228
|
-
}
|
|
229
|
-
return t;
|
|
230
|
-
};
|
|
231
|
-
return __assign.apply(this, arguments);
|
|
232
|
-
};
|
|
233
166
|
|
|
234
167
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
235
168
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -239,1307 +172,1021 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
239
172
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
240
173
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
241
174
|
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function __generator(thisArg, body) {
|
|
245
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
246
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
247
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
248
|
-
function step(op) {
|
|
249
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
250
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
251
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
252
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
253
|
-
switch (op[0]) {
|
|
254
|
-
case 0: case 1: t = op; break;
|
|
255
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
256
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
257
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
258
|
-
default:
|
|
259
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
260
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
261
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
262
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
263
|
-
if (t[2]) _.ops.pop();
|
|
264
|
-
_.trys.pop(); continue;
|
|
265
|
-
}
|
|
266
|
-
op = body.call(thisArg, _);
|
|
267
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
268
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
269
|
-
}
|
|
270
175
|
}
|
|
271
176
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
_this.status = 'ERROR_PERMISSIONS';
|
|
307
|
-
return _this;
|
|
308
|
-
}
|
|
309
|
-
return RadarPermissionsError;
|
|
310
|
-
}(RadarError));
|
|
311
|
-
var RadarVerifyAppError = /** @class */ (function (_super) {
|
|
312
|
-
__extends(RadarVerifyAppError, _super);
|
|
313
|
-
function RadarVerifyAppError() {
|
|
314
|
-
var _this = _super.call(this, 'Radar Verify app not running.') || this;
|
|
315
|
-
_this.name = 'RadarVerifyAppError';
|
|
316
|
-
_this.status = 'ERROR_VERIFY_APP';
|
|
317
|
-
return _this;
|
|
318
|
-
}
|
|
319
|
-
return RadarVerifyAppError;
|
|
320
|
-
}(RadarError));
|
|
177
|
+
class RadarError extends Error {
|
|
178
|
+
constructor(message) {
|
|
179
|
+
super(message);
|
|
180
|
+
this.status = ''; // to be overridden (support for legacy status)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
class RadarPublishableKeyError extends RadarError {
|
|
184
|
+
constructor(message) {
|
|
185
|
+
super(message);
|
|
186
|
+
this.name = 'RadarPublishableKeyError';
|
|
187
|
+
this.status = 'ERROR_PUBLISHABLE_KEY';
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
class RadarLocationError extends RadarError {
|
|
191
|
+
constructor(message) {
|
|
192
|
+
super(message);
|
|
193
|
+
this.name = 'RadarLocationError';
|
|
194
|
+
this.status = 'ERROR_LOCATION';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
class RadarPermissionsError extends RadarError {
|
|
198
|
+
constructor(message) {
|
|
199
|
+
super(message);
|
|
200
|
+
this.name = 'RadarPermissionsError';
|
|
201
|
+
this.status = 'ERROR_PERMISSIONS';
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
class RadarVerifyAppError extends RadarError {
|
|
205
|
+
constructor() {
|
|
206
|
+
super('Radar Verify app not running.');
|
|
207
|
+
this.name = 'RadarVerifyAppError';
|
|
208
|
+
this.status = 'ERROR_VERIFY_APP';
|
|
209
|
+
}
|
|
210
|
+
}
|
|
321
211
|
// HTTP Errors
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
function RadarBadRequestError(response) {
|
|
325
|
-
var _this = this;
|
|
212
|
+
class RadarBadRequestError extends RadarError {
|
|
213
|
+
constructor(response) {
|
|
326
214
|
var _a;
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
var RadarUnauthorizedError = /** @class */ (function (_super) {
|
|
337
|
-
__extends(RadarUnauthorizedError, _super);
|
|
338
|
-
function RadarUnauthorizedError(response) {
|
|
339
|
-
var _this = this;
|
|
215
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Bad request.');
|
|
216
|
+
this.name = 'RadarBadRequestError';
|
|
217
|
+
this.code = 400;
|
|
218
|
+
this.response = response;
|
|
219
|
+
this.status = 'ERROR_BAD_REQUEST';
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
class RadarUnauthorizedError extends RadarError {
|
|
223
|
+
constructor(response) {
|
|
340
224
|
var _a;
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
var RadarPaymentRequiredError = /** @class */ (function (_super) {
|
|
351
|
-
__extends(RadarPaymentRequiredError, _super);
|
|
352
|
-
function RadarPaymentRequiredError(response) {
|
|
353
|
-
var _this = this;
|
|
225
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Unauthorized.');
|
|
226
|
+
this.name = 'RadarUnauthorizedError';
|
|
227
|
+
this.code = 401;
|
|
228
|
+
this.response = response;
|
|
229
|
+
this.status = 'ERROR_UNAUTHORIZED';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
class RadarPaymentRequiredError extends RadarError {
|
|
233
|
+
constructor(response) {
|
|
354
234
|
var _a;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
var RadarForbiddenError = /** @class */ (function (_super) {
|
|
365
|
-
__extends(RadarForbiddenError, _super);
|
|
366
|
-
function RadarForbiddenError(response) {
|
|
367
|
-
var _this = this;
|
|
235
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Payment required.');
|
|
236
|
+
this.name = 'RadarPaymentRequiredError';
|
|
237
|
+
this.code = 402;
|
|
238
|
+
this.response = response;
|
|
239
|
+
this.status = 'ERROR_PAYMENT_REQUIRED';
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
class RadarForbiddenError extends RadarError {
|
|
243
|
+
constructor(response) {
|
|
368
244
|
var _a;
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
var RadarNotFoundError = /** @class */ (function (_super) {
|
|
379
|
-
__extends(RadarNotFoundError, _super);
|
|
380
|
-
function RadarNotFoundError(response) {
|
|
381
|
-
var _this = this;
|
|
245
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Forbidden.');
|
|
246
|
+
this.name = 'RadarForbiddenError';
|
|
247
|
+
this.code = 403;
|
|
248
|
+
this.response = response;
|
|
249
|
+
this.status = 'ERROR_FORBIDDEN';
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
class RadarNotFoundError extends RadarError {
|
|
253
|
+
constructor(response) {
|
|
382
254
|
var _a;
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
var RadarRateLimitError = /** @class */ (function (_super) {
|
|
393
|
-
__extends(RadarRateLimitError, _super);
|
|
394
|
-
function RadarRateLimitError(response) {
|
|
395
|
-
var _this = this;
|
|
255
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Not found.');
|
|
256
|
+
this.name = 'RadarNotFoundError';
|
|
257
|
+
this.code = 404;
|
|
258
|
+
this.response = response;
|
|
259
|
+
this.status = 'ERROR_NOT_FOUND';
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
class RadarRateLimitError extends RadarError {
|
|
263
|
+
constructor(response) {
|
|
396
264
|
var _a, _b;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
var RadarServerError = /** @class */ (function (_super) {
|
|
408
|
-
__extends(RadarServerError, _super);
|
|
409
|
-
function RadarServerError(response) {
|
|
410
|
-
var _this = this;
|
|
265
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Rate limit exceeded.');
|
|
266
|
+
this.name = 'RadarRateLimitError';
|
|
267
|
+
this.code = 429;
|
|
268
|
+
this.response = response;
|
|
269
|
+
this.type = (_b = response === null || response === void 0 ? void 0 : response.meta) === null || _b === void 0 ? void 0 : _b.type;
|
|
270
|
+
this.status = 'ERROR_RATE_LIMIT';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
class RadarServerError extends RadarError {
|
|
274
|
+
constructor(response) {
|
|
411
275
|
var _a;
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
return RadarNetworkError;
|
|
429
|
-
}(RadarError));
|
|
430
|
-
var RadarUnknownError = /** @class */ (function (_super) {
|
|
431
|
-
__extends(RadarUnknownError, _super);
|
|
432
|
-
function RadarUnknownError(response) {
|
|
433
|
-
var _this = this;
|
|
276
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Internal server error.');
|
|
277
|
+
this.name = 'RadarServerError';
|
|
278
|
+
this.response = response;
|
|
279
|
+
this.status = 'ERROR_SERVER';
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
class RadarNetworkError extends RadarError {
|
|
283
|
+
constructor() {
|
|
284
|
+
super('Request timed out.');
|
|
285
|
+
this.name = 'RadarNetworkError';
|
|
286
|
+
this.status = 'ERROR_NETWORK';
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
class RadarUnknownError extends RadarError {
|
|
290
|
+
constructor(response) {
|
|
434
291
|
var _a;
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
_this.status = 'CONTAINER_NOT_FOUND';
|
|
449
|
-
return _this;
|
|
450
|
-
}
|
|
451
|
-
return RadarAutocompleteContainerNotFound;
|
|
452
|
-
}(RadarError));
|
|
292
|
+
super(((_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.message) || 'Something went wrong.');
|
|
293
|
+
this.name = 'RadarUnknownError';
|
|
294
|
+
this.response = response;
|
|
295
|
+
this.status = 'ERROR_UNKNOWN';
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
class RadarAutocompleteContainerNotFound extends RadarError {
|
|
299
|
+
constructor(message) {
|
|
300
|
+
super(message);
|
|
301
|
+
this.name = 'RadarAutocompleteContainerNotFound';
|
|
302
|
+
this.status = 'CONTAINER_NOT_FOUND';
|
|
303
|
+
}
|
|
304
|
+
}
|
|
453
305
|
|
|
454
|
-
|
|
306
|
+
const DEFAULT_POSITION_OPTIONS = {
|
|
455
307
|
maximumAge: 0,
|
|
456
308
|
timeout: 1000 * 30,
|
|
457
309
|
enableHighAccuracy: true,
|
|
458
310
|
};
|
|
459
311
|
// set "enableHighAccuracy" for navigator only when desiredAccuracy is "high"
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
if (
|
|
478
|
-
|
|
479
|
-
var _a = cachedLocation || {}, latitude = _a.latitude, longitude = _a.longitude, accuracy = _a.accuracy, expiresAt = _a.expiresAt;
|
|
480
|
-
if (Date.now() < parseInt(expiresAt)) {
|
|
481
|
-
if (latitude && longitude && accuracy) {
|
|
482
|
-
return resolve({ latitude: latitude, longitude: longitude, accuracy: accuracy });
|
|
483
|
-
}
|
|
484
|
-
}
|
|
312
|
+
const useHighAccuracy = (desiredAccuracy) => (Boolean(desiredAccuracy === 'high'));
|
|
313
|
+
class Navigator {
|
|
314
|
+
static getCurrentPosition(overrides = {}) {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
return new Promise((resolve, reject) => {
|
|
317
|
+
const options = Config.get();
|
|
318
|
+
if (!navigator || !navigator.geolocation) {
|
|
319
|
+
return reject(new RadarLocationError('navigator.geolocation is not available.'));
|
|
320
|
+
}
|
|
321
|
+
// use cached location if available and options are set
|
|
322
|
+
if (options.cacheLocationMinutes) {
|
|
323
|
+
try {
|
|
324
|
+
const rawCachedLocation = Storage.getItem(Storage.CACHED_LOCATION);
|
|
325
|
+
if (rawCachedLocation) {
|
|
326
|
+
const cachedLocation = JSON.parse(rawCachedLocation);
|
|
327
|
+
const { latitude, longitude, accuracy, expiresAt } = cachedLocation || {};
|
|
328
|
+
if (Date.now() < parseInt(expiresAt)) {
|
|
329
|
+
if (latitude && longitude && accuracy) {
|
|
330
|
+
return resolve({ latitude, longitude, accuracy });
|
|
485
331
|
}
|
|
486
332
|
}
|
|
487
|
-
catch (e) {
|
|
488
|
-
Logger.warn('could not load cached location.');
|
|
489
|
-
}
|
|
490
333
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
334
|
+
}
|
|
335
|
+
catch (e) {
|
|
336
|
+
Logger.warn('could not load cached location.');
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// set options from config
|
|
340
|
+
const positionOptions = Object.assign({}, DEFAULT_POSITION_OPTIONS);
|
|
341
|
+
if (options.locationMaximumAge !== undefined) {
|
|
342
|
+
positionOptions.maximumAge = options.locationMaximumAge;
|
|
343
|
+
}
|
|
344
|
+
if (options.locationTimeout !== undefined) {
|
|
345
|
+
positionOptions.timeout = options.locationTimeout;
|
|
346
|
+
}
|
|
347
|
+
if (options.desiredAccuracy !== undefined) {
|
|
348
|
+
positionOptions.enableHighAccuracy = useHighAccuracy(options.desiredAccuracy);
|
|
349
|
+
}
|
|
350
|
+
// set options from overrides
|
|
351
|
+
if (overrides.desiredAccuracy !== undefined) {
|
|
352
|
+
positionOptions.enableHighAccuracy = useHighAccuracy(overrides.desiredAccuracy);
|
|
353
|
+
}
|
|
354
|
+
Logger.info(`Using geolocation options: ${JSON.stringify(positionOptions)}`);
|
|
355
|
+
// get current location from browser
|
|
356
|
+
navigator.geolocation.getCurrentPosition((position) => {
|
|
357
|
+
if (!position || !position.coords) {
|
|
358
|
+
return reject(new RadarLocationError('device location return empty coordinates.'));
|
|
359
|
+
}
|
|
360
|
+
const { latitude, longitude, accuracy } = position.coords;
|
|
361
|
+
// cache location if option is set
|
|
362
|
+
if (options.cacheLocationMinutes) {
|
|
363
|
+
const cacheLocationMinutes = Number.parseFloat(options.cacheLocationMinutes);
|
|
364
|
+
const updatedAt = Date.now();
|
|
365
|
+
const expiresAt = updatedAt + (cacheLocationMinutes * 60 * 1000); // convert to ms
|
|
366
|
+
const lastLocation = { latitude, longitude, accuracy, updatedAt, expiresAt };
|
|
367
|
+
Storage.setItem(Storage.CACHED_LOCATION, JSON.stringify(lastLocation));
|
|
368
|
+
}
|
|
369
|
+
return resolve({ latitude, longitude, accuracy });
|
|
370
|
+
}, (err) => {
|
|
371
|
+
if (err && err.code === 1) {
|
|
372
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError
|
|
373
|
+
// code 1 means location permissions denied
|
|
374
|
+
// codes 2 and 3 mean location unavailable or timeout
|
|
375
|
+
return reject(new RadarPermissionsError('Location permissions denied.'));
|
|
376
|
+
}
|
|
377
|
+
return reject(new RadarLocationError('Could not determine location.'));
|
|
378
|
+
}, positionOptions);
|
|
532
379
|
});
|
|
533
380
|
});
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
537
|
-
return
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
});
|
|
557
|
-
})];
|
|
381
|
+
}
|
|
382
|
+
static getPermissionStatus() {
|
|
383
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
384
|
+
return new Promise((resolve, reject) => {
|
|
385
|
+
if (!navigator || !navigator.permissions) {
|
|
386
|
+
return reject(new RadarLocationError('navigator.permissions is not available.'));
|
|
387
|
+
}
|
|
388
|
+
navigator.permissions.query({ name: 'geolocation' }).then((permissionsStatus) => {
|
|
389
|
+
let locationAuthorization = 'NOT_DETERMINED';
|
|
390
|
+
switch (permissionsStatus.state) {
|
|
391
|
+
case 'granted':
|
|
392
|
+
locationAuthorization = 'GRANTED_FOREGROUND';
|
|
393
|
+
break;
|
|
394
|
+
case 'denied':
|
|
395
|
+
locationAuthorization = 'DENIED';
|
|
396
|
+
break;
|
|
397
|
+
case 'prompt':
|
|
398
|
+
locationAuthorization = 'NOT_DETERMINED';
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
return resolve(locationAuthorization);
|
|
402
|
+
});
|
|
558
403
|
});
|
|
559
404
|
});
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
}());
|
|
405
|
+
}
|
|
406
|
+
}
|
|
563
407
|
|
|
564
|
-
var SDK_VERSION = '4.
|
|
408
|
+
var SDK_VERSION = '4.3.0-beta.1';
|
|
565
409
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
410
|
+
class Http {
|
|
411
|
+
static request({ method, path, data, host, version, headers = {}, responseType, }) {
|
|
412
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
413
|
+
return new Promise((resolve, reject) => {
|
|
414
|
+
const options = Config.get();
|
|
415
|
+
// check for publishableKey on request
|
|
416
|
+
const publishableKey = options.publishableKey;
|
|
417
|
+
if (!publishableKey) {
|
|
418
|
+
reject(new RadarPublishableKeyError('publishableKey not set.'));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// setup request URL
|
|
422
|
+
const urlHost = host || options.host;
|
|
423
|
+
const urlVersion = version || options.version;
|
|
424
|
+
let url = `${urlHost}/${urlVersion}/${path}`;
|
|
425
|
+
// remove undefined values from request data
|
|
426
|
+
let body = {};
|
|
427
|
+
Object.keys(data || {}).forEach((key) => {
|
|
428
|
+
const value = data[key];
|
|
429
|
+
if (value !== undefined) {
|
|
430
|
+
body[key] = value;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
// convert data to querystring for GET requests
|
|
434
|
+
if (method === 'GET') {
|
|
435
|
+
const params = Object.keys(body).map((key) => (`${key}=${encodeURIComponent(body[key])}`));
|
|
436
|
+
if (params.length > 0) {
|
|
437
|
+
const queryString = params.join('&');
|
|
438
|
+
url = `${url}?${queryString}`;
|
|
439
|
+
}
|
|
440
|
+
body = undefined; // dont send body for GET request
|
|
441
|
+
}
|
|
442
|
+
const xhr = new XMLHttpRequest();
|
|
443
|
+
xhr.open(method, url, true);
|
|
444
|
+
const defaultHeaders = {
|
|
445
|
+
'Authorization': publishableKey,
|
|
446
|
+
'Content-Type': 'application/json',
|
|
447
|
+
'X-Radar-Device-Type': 'Web',
|
|
448
|
+
'X-Radar-SDK-Version': SDK_VERSION,
|
|
449
|
+
};
|
|
450
|
+
// set custom config headers if present
|
|
451
|
+
let configHeaders = {};
|
|
452
|
+
if (typeof options.getRequestHeaders === 'function') {
|
|
453
|
+
configHeaders = options.getRequestHeaders();
|
|
454
|
+
}
|
|
455
|
+
// combines default headers with custom headers and config headers
|
|
456
|
+
const allHeaders = Object.assign(defaultHeaders, configHeaders, headers);
|
|
457
|
+
// set headers
|
|
458
|
+
Object.keys(allHeaders).forEach((key) => {
|
|
459
|
+
xhr.setRequestHeader(key, allHeaders[key]);
|
|
460
|
+
});
|
|
461
|
+
if (responseType) {
|
|
462
|
+
xhr.responseType = responseType;
|
|
463
|
+
}
|
|
464
|
+
xhr.onload = () => {
|
|
465
|
+
var _a;
|
|
466
|
+
let response;
|
|
467
|
+
try {
|
|
468
|
+
if (xhr.responseType === 'blob') {
|
|
469
|
+
response = { code: xhr.status, data: xhr.response };
|
|
615
470
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
var headers_1 = options.getRequestHeaders();
|
|
619
|
-
Object.keys(headers_1 || {}).forEach(function (key) {
|
|
620
|
-
xhr.setRequestHeader(key, headers_1[key]);
|
|
621
|
-
});
|
|
471
|
+
else {
|
|
472
|
+
response = JSON.parse(xhr.response);
|
|
622
473
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
};
|
|
682
|
-
xhr.ontimeout = function () {
|
|
683
|
-
reject(new RadarVerifyAppError());
|
|
684
|
-
};
|
|
685
|
-
xhr.send(JSON.stringify(body));
|
|
686
|
-
})];
|
|
474
|
+
}
|
|
475
|
+
catch (e) {
|
|
476
|
+
return reject(new RadarServerError(response));
|
|
477
|
+
}
|
|
478
|
+
const error = (_a = response === null || response === void 0 ? void 0 : response.meta) === null || _a === void 0 ? void 0 : _a.error;
|
|
479
|
+
if (error === 'ERROR_PERMISSIONS') {
|
|
480
|
+
return reject(new RadarPermissionsError('Location permissions not granted.'));
|
|
481
|
+
}
|
|
482
|
+
else if (error === 'ERROR_LOCATION') {
|
|
483
|
+
return reject(new RadarLocationError('Could not determine location.'));
|
|
484
|
+
}
|
|
485
|
+
else if (error === 'ERROR_NETWORK') {
|
|
486
|
+
return reject(new RadarNetworkError());
|
|
487
|
+
}
|
|
488
|
+
if (xhr.status == 200) {
|
|
489
|
+
return resolve(response);
|
|
490
|
+
}
|
|
491
|
+
if (options.debug) {
|
|
492
|
+
Logger.debug(`API call failed: ${url}`);
|
|
493
|
+
Logger.debug(JSON.stringify(response));
|
|
494
|
+
}
|
|
495
|
+
if (xhr.status === 400) {
|
|
496
|
+
reject(new RadarBadRequestError(response));
|
|
497
|
+
}
|
|
498
|
+
else if (xhr.status === 401) {
|
|
499
|
+
reject(new RadarUnauthorizedError(response));
|
|
500
|
+
}
|
|
501
|
+
else if (xhr.status === 402) {
|
|
502
|
+
reject(new RadarPaymentRequiredError(response));
|
|
503
|
+
}
|
|
504
|
+
else if (xhr.status === 403) {
|
|
505
|
+
reject(new RadarForbiddenError(response));
|
|
506
|
+
}
|
|
507
|
+
else if (xhr.status === 404) {
|
|
508
|
+
reject(new RadarNotFoundError(response));
|
|
509
|
+
}
|
|
510
|
+
else if (xhr.status === 429) {
|
|
511
|
+
reject(new RadarRateLimitError(response));
|
|
512
|
+
}
|
|
513
|
+
else if (500 <= xhr.status && xhr.status < 600) {
|
|
514
|
+
reject(new RadarServerError(response));
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
reject(new RadarUnknownError(response));
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
xhr.onerror = function () {
|
|
521
|
+
if (host && (host === 'http://localhost:52516' || host === 'https://radar-verify.com:52516')) {
|
|
522
|
+
reject(new RadarVerifyAppError());
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
reject(new RadarServerError());
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
xhr.ontimeout = function () {
|
|
529
|
+
reject(new RadarVerifyAppError());
|
|
530
|
+
};
|
|
531
|
+
xhr.send(JSON.stringify(body));
|
|
687
532
|
});
|
|
688
533
|
});
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
}());
|
|
534
|
+
}
|
|
535
|
+
}
|
|
692
536
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
case 0:
|
|
702
|
-
options = Config.get();
|
|
703
|
-
return [4 /*yield*/, Http.request({
|
|
704
|
-
method: 'GET',
|
|
705
|
-
path: 'addresses/validate',
|
|
706
|
-
data: params,
|
|
707
|
-
})];
|
|
708
|
-
case 1:
|
|
709
|
-
response = _a.sent();
|
|
710
|
-
address = response.address, result = response.result;
|
|
711
|
-
validateAddressRes = {
|
|
712
|
-
address: address,
|
|
713
|
-
result: result,
|
|
714
|
-
};
|
|
715
|
-
if (options.debug) {
|
|
716
|
-
validateAddressRes.response = response;
|
|
717
|
-
}
|
|
718
|
-
return [2 /*return*/, validateAddressRes];
|
|
719
|
-
}
|
|
537
|
+
class AddressesAPI {
|
|
538
|
+
static validateAddress(params) {
|
|
539
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
540
|
+
const options = Config.get();
|
|
541
|
+
const response = yield Http.request({
|
|
542
|
+
method: 'GET',
|
|
543
|
+
path: 'addresses/validate',
|
|
544
|
+
data: params,
|
|
720
545
|
});
|
|
546
|
+
const { address, result } = response;
|
|
547
|
+
const validateAddressRes = {
|
|
548
|
+
address,
|
|
549
|
+
result,
|
|
550
|
+
};
|
|
551
|
+
if (options.debug) {
|
|
552
|
+
validateAddressRes.response = response;
|
|
553
|
+
}
|
|
554
|
+
return validateAddressRes;
|
|
721
555
|
});
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
}());
|
|
556
|
+
}
|
|
557
|
+
}
|
|
725
558
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
559
|
+
const generateUUID = () => {
|
|
560
|
+
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => {
|
|
561
|
+
const r = Math.random() * 16 | 0;
|
|
562
|
+
const v = (char == 'x') ? r : (r & 0x3 | 0x8);
|
|
730
563
|
return v.toString(16);
|
|
731
564
|
});
|
|
732
565
|
return uuid;
|
|
733
566
|
};
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
737
|
-
Device.getDeviceId = function () {
|
|
567
|
+
class Device {
|
|
568
|
+
static getDeviceId() {
|
|
738
569
|
// use existing deviceId if present
|
|
739
|
-
|
|
570
|
+
const deviceId = Storage.getItem(Storage.DEVICE_ID);
|
|
740
571
|
if (deviceId) {
|
|
741
572
|
return deviceId;
|
|
742
573
|
}
|
|
743
574
|
// generate new deviceId
|
|
744
|
-
|
|
575
|
+
const uuid = generateUUID();
|
|
745
576
|
Storage.setItem(Storage.DEVICE_ID, uuid);
|
|
746
577
|
return uuid;
|
|
747
|
-
}
|
|
748
|
-
|
|
578
|
+
}
|
|
579
|
+
static getInstallId() {
|
|
749
580
|
// use existing installId if present
|
|
750
|
-
|
|
581
|
+
const deviceId = Storage.getItem(Storage.INSTALL_ID);
|
|
751
582
|
if (deviceId) {
|
|
752
583
|
return deviceId;
|
|
753
584
|
}
|
|
754
585
|
// generate new installId
|
|
755
|
-
|
|
586
|
+
const uuid = generateUUID();
|
|
756
587
|
Storage.setItem(Storage.INSTALL_ID, uuid);
|
|
757
588
|
return uuid;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
}());
|
|
589
|
+
}
|
|
590
|
+
}
|
|
761
591
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
592
|
+
const SESSION_TIMEOUT_SECS = 300; // 5 mins
|
|
593
|
+
const isValid = (sessionId) => {
|
|
594
|
+
const now = Math.trunc(Date.now() / 1000);
|
|
595
|
+
const session = Number.parseInt(sessionId);
|
|
596
|
+
const diff = Math.abs(now - session);
|
|
767
597
|
return diff < SESSION_TIMEOUT_SECS;
|
|
768
598
|
};
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
Session.getSessionId = function () {
|
|
773
|
-
var sessionId = Storage.getItem(Storage.SESSION_ID);
|
|
599
|
+
class Session {
|
|
600
|
+
static getSessionId() {
|
|
601
|
+
const sessionId = Storage.getItem(Storage.SESSION_ID);
|
|
774
602
|
// reuse session if still within 5 min threshold
|
|
775
603
|
if (sessionId && isValid(sessionId)) {
|
|
776
604
|
return sessionId;
|
|
777
605
|
}
|
|
778
606
|
// create new session if does not already exist or expired
|
|
779
|
-
|
|
607
|
+
const newSessionId = Math.trunc(Date.now() / 1000).toString(); // unix ts in seconds
|
|
780
608
|
Storage.setItem(Storage.SESSION_ID, newSessionId);
|
|
781
609
|
return newSessionId;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
}());
|
|
610
|
+
}
|
|
611
|
+
}
|
|
785
612
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
case 2:
|
|
815
|
-
_a.trys.push([2, 4, , 5]);
|
|
816
|
-
return [4 /*yield*/, Http.request({
|
|
817
|
-
method: 'GET',
|
|
818
|
-
path: 'config',
|
|
819
|
-
data: data,
|
|
820
|
-
})];
|
|
821
|
-
case 3:
|
|
822
|
-
_a.sent();
|
|
823
|
-
return [3 /*break*/, 5];
|
|
824
|
-
case 4:
|
|
825
|
-
err_1 = _a.sent();
|
|
826
|
-
Logger.warn("Error calling /config: ".concat(err_1.message));
|
|
827
|
-
return [3 /*break*/, 5];
|
|
828
|
-
case 5: return [2 /*return*/];
|
|
829
|
-
}
|
|
830
|
-
});
|
|
613
|
+
class ConfigAPI {
|
|
614
|
+
static getConfig(params = {}) {
|
|
615
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
616
|
+
const options = Config.get();
|
|
617
|
+
if (options.version != 'v1') {
|
|
618
|
+
Logger.info('Skipping /config call.');
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
const deviceId = params.deviceId || Device.getDeviceId();
|
|
622
|
+
const installId = params.installId || Device.getInstallId();
|
|
623
|
+
const sessionId = Session.getSessionId();
|
|
624
|
+
const locationAuthorization = yield Navigator.getPermissionStatus();
|
|
625
|
+
const data = {
|
|
626
|
+
deviceId,
|
|
627
|
+
installId,
|
|
628
|
+
sessionId,
|
|
629
|
+
locationAuthorization,
|
|
630
|
+
};
|
|
631
|
+
try {
|
|
632
|
+
yield Http.request({
|
|
633
|
+
method: 'GET',
|
|
634
|
+
path: 'config',
|
|
635
|
+
data,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
catch (err) {
|
|
639
|
+
Logger.warn(`Error calling /config: ${err.message}`);
|
|
640
|
+
}
|
|
831
641
|
});
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
}());
|
|
642
|
+
}
|
|
643
|
+
}
|
|
835
644
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
latitude = location.latitude, longitude = location.longitude, accuracy = location.accuracy;
|
|
853
|
-
return [4 /*yield*/, Http.request({
|
|
854
|
-
method: 'GET',
|
|
855
|
-
path: 'context',
|
|
856
|
-
data: {
|
|
857
|
-
coordinates: "".concat(latitude, ",").concat(longitude),
|
|
858
|
-
accuracy: accuracy,
|
|
859
|
-
},
|
|
860
|
-
})];
|
|
861
|
-
case 3:
|
|
862
|
-
response = _a.sent();
|
|
863
|
-
geofences = response.geofences, place = response.place, country = response.country, state = response.state, dma = response.dma, postalCode = response.postalCode;
|
|
864
|
-
contextRes = {
|
|
865
|
-
location: location,
|
|
866
|
-
geofences: geofences,
|
|
867
|
-
place: place,
|
|
868
|
-
country: country,
|
|
869
|
-
state: state,
|
|
870
|
-
dma: dma,
|
|
871
|
-
postalCode: postalCode,
|
|
872
|
-
};
|
|
873
|
-
if (options.debug) {
|
|
874
|
-
contextRes.response = response;
|
|
875
|
-
}
|
|
876
|
-
return [2 /*return*/, contextRes];
|
|
877
|
-
}
|
|
645
|
+
class ContextAPI {
|
|
646
|
+
static getContext(location) {
|
|
647
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
648
|
+
const options = Config.get();
|
|
649
|
+
// get device location if coordinates not provided
|
|
650
|
+
if (!location.latitude || !location.longitude) {
|
|
651
|
+
location = yield Navigator.getCurrentPosition();
|
|
652
|
+
}
|
|
653
|
+
const { latitude, longitude, accuracy } = location;
|
|
654
|
+
const response = yield Http.request({
|
|
655
|
+
method: 'GET',
|
|
656
|
+
path: 'context',
|
|
657
|
+
data: {
|
|
658
|
+
coordinates: `${latitude},${longitude}`,
|
|
659
|
+
accuracy,
|
|
660
|
+
},
|
|
878
661
|
});
|
|
662
|
+
const { geofences, place, country, state, dma, postalCode, } = response;
|
|
663
|
+
const contextRes = {
|
|
664
|
+
location,
|
|
665
|
+
geofences,
|
|
666
|
+
place,
|
|
667
|
+
country,
|
|
668
|
+
state,
|
|
669
|
+
dma,
|
|
670
|
+
postalCode,
|
|
671
|
+
};
|
|
672
|
+
if (options.debug) {
|
|
673
|
+
contextRes.response = response;
|
|
674
|
+
}
|
|
675
|
+
return contextRes;
|
|
879
676
|
});
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
}());
|
|
677
|
+
}
|
|
678
|
+
}
|
|
883
679
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
data.createdAt = (new Date()).toISOString();
|
|
918
|
-
}
|
|
919
|
-
return [4 /*yield*/, Http.request({
|
|
920
|
-
method: 'POST',
|
|
921
|
-
path: 'events',
|
|
922
|
-
data: data,
|
|
923
|
-
})];
|
|
924
|
-
case 1:
|
|
925
|
-
response = _a.sent();
|
|
926
|
-
conversionRes = {
|
|
927
|
-
event: response.event,
|
|
928
|
-
};
|
|
929
|
-
if (options.debug) {
|
|
930
|
-
conversionRes.response = response;
|
|
931
|
-
}
|
|
932
|
-
return [2 /*return*/, conversionRes];
|
|
933
|
-
}
|
|
680
|
+
class ConversionsAPI {
|
|
681
|
+
static logConversion(params) {
|
|
682
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
683
|
+
const options = Config.get();
|
|
684
|
+
const name = params.name;
|
|
685
|
+
const userId = params.userId || Storage.getItem(Storage.USER_ID);
|
|
686
|
+
const deviceId = params.deviceId || Device.getDeviceId();
|
|
687
|
+
const installId = params.installId || Device.getInstallId();
|
|
688
|
+
const metadata = params.metadata || {};
|
|
689
|
+
const createdAt = params.createdAt;
|
|
690
|
+
if (params.revenue) {
|
|
691
|
+
metadata.revenue = params.revenue;
|
|
692
|
+
}
|
|
693
|
+
const data = {
|
|
694
|
+
name,
|
|
695
|
+
userId,
|
|
696
|
+
deviceId,
|
|
697
|
+
installId,
|
|
698
|
+
metadata,
|
|
699
|
+
};
|
|
700
|
+
if (typeof createdAt === 'string') {
|
|
701
|
+
data.createdAt = createdAt;
|
|
702
|
+
}
|
|
703
|
+
else if (createdAt instanceof Date) {
|
|
704
|
+
data.createdAt = createdAt.toISOString();
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
data.createdAt = (new Date()).toISOString();
|
|
708
|
+
}
|
|
709
|
+
const response = yield Http.request({
|
|
710
|
+
method: 'POST',
|
|
711
|
+
path: 'events',
|
|
712
|
+
data,
|
|
934
713
|
});
|
|
714
|
+
const conversionRes = {
|
|
715
|
+
event: response.event,
|
|
716
|
+
};
|
|
717
|
+
if (options.debug) {
|
|
718
|
+
conversionRes.response = response;
|
|
719
|
+
}
|
|
720
|
+
return conversionRes;
|
|
935
721
|
});
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
}());
|
|
722
|
+
}
|
|
723
|
+
}
|
|
939
724
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
path: 'geocode/forward',
|
|
954
|
-
data: {
|
|
955
|
-
query: query,
|
|
956
|
-
layers: layers,
|
|
957
|
-
country: country,
|
|
958
|
-
},
|
|
959
|
-
})];
|
|
960
|
-
case 1:
|
|
961
|
-
response = _a.sent();
|
|
962
|
-
forwardGeocodeRes = {
|
|
963
|
-
addresses: response.addresses,
|
|
964
|
-
};
|
|
965
|
-
if (options.debug) {
|
|
966
|
-
forwardGeocodeRes.response = response;
|
|
967
|
-
}
|
|
968
|
-
return [2 /*return*/, forwardGeocodeRes];
|
|
969
|
-
}
|
|
725
|
+
class Geocoding {
|
|
726
|
+
static forwardGeocode(params) {
|
|
727
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
728
|
+
const options = Config.get();
|
|
729
|
+
const { query, layers, country } = params;
|
|
730
|
+
const response = yield Http.request({
|
|
731
|
+
method: 'GET',
|
|
732
|
+
path: 'geocode/forward',
|
|
733
|
+
data: {
|
|
734
|
+
query,
|
|
735
|
+
layers,
|
|
736
|
+
country,
|
|
737
|
+
},
|
|
970
738
|
});
|
|
739
|
+
const forwardGeocodeRes = {
|
|
740
|
+
addresses: response.addresses,
|
|
741
|
+
};
|
|
742
|
+
if (options.debug) {
|
|
743
|
+
forwardGeocodeRes.response = response;
|
|
744
|
+
}
|
|
745
|
+
return forwardGeocodeRes;
|
|
971
746
|
});
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
method: 'GET',
|
|
990
|
-
path: 'geocode/reverse',
|
|
991
|
-
data: {
|
|
992
|
-
coordinates: "".concat(latitude, ",").concat(longitude),
|
|
993
|
-
layers: layers,
|
|
994
|
-
},
|
|
995
|
-
})];
|
|
996
|
-
case 3:
|
|
997
|
-
response = _a.sent();
|
|
998
|
-
reverseGeocodeRes = {
|
|
999
|
-
addresses: response.addresses,
|
|
1000
|
-
};
|
|
1001
|
-
if (options.debug) {
|
|
1002
|
-
reverseGeocodeRes.response = response;
|
|
1003
|
-
}
|
|
1004
|
-
return [2 /*return*/, reverseGeocodeRes];
|
|
1005
|
-
}
|
|
747
|
+
}
|
|
748
|
+
static reverseGeocode(params) {
|
|
749
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
750
|
+
const options = Config.get();
|
|
751
|
+
let { latitude, longitude, layers } = params;
|
|
752
|
+
if (!latitude || !longitude) {
|
|
753
|
+
const location = yield Navigator.getCurrentPosition();
|
|
754
|
+
latitude = location.latitude;
|
|
755
|
+
longitude = location.longitude;
|
|
756
|
+
}
|
|
757
|
+
const response = yield Http.request({
|
|
758
|
+
method: 'GET',
|
|
759
|
+
path: 'geocode/reverse',
|
|
760
|
+
data: {
|
|
761
|
+
coordinates: `${latitude},${longitude}`,
|
|
762
|
+
layers,
|
|
763
|
+
},
|
|
1006
764
|
});
|
|
765
|
+
const reverseGeocodeRes = {
|
|
766
|
+
addresses: response.addresses,
|
|
767
|
+
};
|
|
768
|
+
if (options.debug) {
|
|
769
|
+
reverseGeocodeRes.response = response;
|
|
770
|
+
}
|
|
771
|
+
return reverseGeocodeRes;
|
|
1007
772
|
});
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
options = Config.get();
|
|
1016
|
-
return [4 /*yield*/, Http.request({
|
|
1017
|
-
method: 'GET',
|
|
1018
|
-
path: 'geocode/ip',
|
|
1019
|
-
})];
|
|
1020
|
-
case 1:
|
|
1021
|
-
response = _a.sent();
|
|
1022
|
-
ipGeocodeRes = {
|
|
1023
|
-
ip: response.ip,
|
|
1024
|
-
address: response.address,
|
|
1025
|
-
proxy: response.proxy,
|
|
1026
|
-
};
|
|
1027
|
-
if (options.debug) {
|
|
1028
|
-
ipGeocodeRes.response = response;
|
|
1029
|
-
}
|
|
1030
|
-
return [2 /*return*/, ipGeocodeRes];
|
|
1031
|
-
}
|
|
773
|
+
}
|
|
774
|
+
static ipGeocode() {
|
|
775
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
776
|
+
const options = Config.get();
|
|
777
|
+
const response = yield Http.request({
|
|
778
|
+
method: 'GET',
|
|
779
|
+
path: 'geocode/ip',
|
|
1032
780
|
});
|
|
781
|
+
const ipGeocodeRes = {
|
|
782
|
+
ip: response.ip,
|
|
783
|
+
address: response.address,
|
|
784
|
+
proxy: response.proxy,
|
|
785
|
+
};
|
|
786
|
+
if (options.debug) {
|
|
787
|
+
ipGeocodeRes.response = response;
|
|
788
|
+
}
|
|
789
|
+
return ipGeocodeRes;
|
|
1033
790
|
});
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
}());
|
|
791
|
+
}
|
|
792
|
+
}
|
|
1037
793
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
path: 'route/distance',
|
|
1075
|
-
data: {
|
|
1076
|
-
origin: origin,
|
|
1077
|
-
destination: destination,
|
|
1078
|
-
modes: modes,
|
|
1079
|
-
units: units,
|
|
1080
|
-
geometry: geometry,
|
|
1081
|
-
geometryPoints: geometryPoints,
|
|
1082
|
-
avoid: avoid,
|
|
1083
|
-
},
|
|
1084
|
-
})];
|
|
1085
|
-
case 4:
|
|
1086
|
-
response = _b.sent();
|
|
1087
|
-
distanceRes = {
|
|
1088
|
-
routes: response.routes,
|
|
1089
|
-
};
|
|
1090
|
-
if (options.debug) {
|
|
1091
|
-
distanceRes.response = response;
|
|
1092
|
-
}
|
|
1093
|
-
return [2 /*return*/, distanceRes];
|
|
1094
|
-
}
|
|
794
|
+
class RoutingAPI {
|
|
795
|
+
static distance(params) {
|
|
796
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
797
|
+
const options = Config.get();
|
|
798
|
+
let { origin, destination, modes, units, geometry, geometryPoints, avoid, } = params;
|
|
799
|
+
// use browser location if "near" not provided
|
|
800
|
+
if (!origin) {
|
|
801
|
+
const { latitude, longitude } = yield Navigator.getCurrentPosition();
|
|
802
|
+
origin = `${latitude},${longitude}`;
|
|
803
|
+
}
|
|
804
|
+
else if (typeof origin !== 'string') { // origin is "Location" object
|
|
805
|
+
const { latitude, longitude } = origin;
|
|
806
|
+
origin = `${latitude},${longitude}`;
|
|
807
|
+
}
|
|
808
|
+
if (typeof destination !== 'string') {
|
|
809
|
+
const { latitude, longitude } = destination;
|
|
810
|
+
destination = `${latitude},${longitude}`;
|
|
811
|
+
}
|
|
812
|
+
if (Array.isArray(modes)) {
|
|
813
|
+
modes = modes.join(',');
|
|
814
|
+
}
|
|
815
|
+
if (Array.isArray(avoid)) {
|
|
816
|
+
avoid = avoid.join(',');
|
|
817
|
+
}
|
|
818
|
+
const response = yield Http.request({
|
|
819
|
+
method: 'GET',
|
|
820
|
+
path: 'route/distance',
|
|
821
|
+
data: {
|
|
822
|
+
origin,
|
|
823
|
+
destination,
|
|
824
|
+
modes,
|
|
825
|
+
units,
|
|
826
|
+
geometry,
|
|
827
|
+
geometryPoints,
|
|
828
|
+
avoid,
|
|
829
|
+
},
|
|
1095
830
|
});
|
|
831
|
+
const distanceRes = {
|
|
832
|
+
routes: response.routes,
|
|
833
|
+
};
|
|
834
|
+
if (options.debug) {
|
|
835
|
+
distanceRes.response = response;
|
|
836
|
+
}
|
|
837
|
+
return distanceRes;
|
|
1096
838
|
});
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
case 1:
|
|
1109
|
-
_a = _b.sent(), latitude = _a.latitude, longitude = _a.longitude;
|
|
1110
|
-
originStrings = [];
|
|
1111
|
-
for (i = 0; i < destinations.length; i++) {
|
|
1112
|
-
originStrings.push("".concat(latitude, ",").concat(longitude));
|
|
1113
|
-
}
|
|
1114
|
-
origins = originStrings.join('|');
|
|
1115
|
-
return [3 /*break*/, 3];
|
|
1116
|
-
case 2:
|
|
1117
|
-
if (Array.isArray(origins)) { // origin is a list of "Location" objects
|
|
1118
|
-
origins = origins.map(function (location) { return "".concat(location.latitude, ",").concat(location.longitude); }).join('|');
|
|
1119
|
-
}
|
|
1120
|
-
_b.label = 3;
|
|
1121
|
-
case 3:
|
|
1122
|
-
// convert array to pipe-delimited string
|
|
1123
|
-
if (Array.isArray(destinations)) {
|
|
1124
|
-
destinations = destinations.map(function (location) { return "".concat(location.latitude, ",").concat(location.longitude); }).join('|');
|
|
1125
|
-
}
|
|
1126
|
-
if (Array.isArray(avoid)) {
|
|
1127
|
-
avoid = avoid.join(',');
|
|
1128
|
-
}
|
|
1129
|
-
return [4 /*yield*/, Http.request({
|
|
1130
|
-
method: 'GET',
|
|
1131
|
-
path: 'route/matrix',
|
|
1132
|
-
data: {
|
|
1133
|
-
origins: origins,
|
|
1134
|
-
destinations: destinations,
|
|
1135
|
-
mode: mode,
|
|
1136
|
-
units: units,
|
|
1137
|
-
avoid: avoid,
|
|
1138
|
-
},
|
|
1139
|
-
})];
|
|
1140
|
-
case 4:
|
|
1141
|
-
response = _b.sent();
|
|
1142
|
-
matrixRes = {
|
|
1143
|
-
origins: response.origins,
|
|
1144
|
-
destinations: response.destinations,
|
|
1145
|
-
matrix: response.matrix,
|
|
1146
|
-
};
|
|
1147
|
-
if (options.debug) {
|
|
1148
|
-
matrixRes.response = response;
|
|
1149
|
-
}
|
|
1150
|
-
return [2 /*return*/, matrixRes];
|
|
839
|
+
}
|
|
840
|
+
static matrix(params) {
|
|
841
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
842
|
+
const options = Config.get();
|
|
843
|
+
let { origins, destinations, mode, units, avoid, } = params;
|
|
844
|
+
// use browser location if "near" not provided
|
|
845
|
+
if (!origins) {
|
|
846
|
+
const { latitude, longitude } = yield Navigator.getCurrentPosition();
|
|
847
|
+
let originStrings = [];
|
|
848
|
+
for (let i = 0; i < destinations.length; i++) {
|
|
849
|
+
originStrings.push(`${latitude},${longitude}`);
|
|
1151
850
|
}
|
|
851
|
+
origins = originStrings.join('|');
|
|
852
|
+
}
|
|
853
|
+
else if (Array.isArray(origins)) { // origin is a list of "Location" objects
|
|
854
|
+
origins = origins.map((location) => `${location.latitude},${location.longitude}`).join('|');
|
|
855
|
+
}
|
|
856
|
+
// convert array to pipe-delimited string
|
|
857
|
+
if (Array.isArray(destinations)) {
|
|
858
|
+
destinations = destinations.map((location) => `${location.latitude},${location.longitude}`).join('|');
|
|
859
|
+
}
|
|
860
|
+
if (Array.isArray(avoid)) {
|
|
861
|
+
avoid = avoid.join(',');
|
|
862
|
+
}
|
|
863
|
+
const response = yield Http.request({
|
|
864
|
+
method: 'GET',
|
|
865
|
+
path: 'route/matrix',
|
|
866
|
+
data: {
|
|
867
|
+
origins,
|
|
868
|
+
destinations,
|
|
869
|
+
mode,
|
|
870
|
+
units,
|
|
871
|
+
avoid,
|
|
872
|
+
},
|
|
1152
873
|
});
|
|
874
|
+
const matrixRes = {
|
|
875
|
+
origins: response.origins,
|
|
876
|
+
destinations: response.destinations,
|
|
877
|
+
matrix: response.matrix,
|
|
878
|
+
};
|
|
879
|
+
if (options.debug) {
|
|
880
|
+
matrixRes.response = response;
|
|
881
|
+
}
|
|
882
|
+
return matrixRes;
|
|
1153
883
|
});
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
}());
|
|
884
|
+
}
|
|
885
|
+
}
|
|
1157
886
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
query = params.query, near = params.near, limit = params.limit, layers = params.layers, countryCode = params.countryCode, expandUnits = params.expandUnits, mailable = params.mailable;
|
|
1169
|
-
// near can be provided as a string or Location object
|
|
1170
|
-
// if "near" is not provided, request will fallback to IP based location
|
|
1171
|
-
if (near && typeof near !== 'string') {
|
|
1172
|
-
if (near.latitude && near.longitude) {
|
|
1173
|
-
near = "".concat(near.latitude, ",").concat(near.longitude);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
return [4 /*yield*/, Http.request({
|
|
1177
|
-
method: 'GET',
|
|
1178
|
-
path: 'search/autocomplete',
|
|
1179
|
-
data: {
|
|
1180
|
-
query: query,
|
|
1181
|
-
near: near,
|
|
1182
|
-
limit: limit,
|
|
1183
|
-
layers: layers,
|
|
1184
|
-
countryCode: countryCode,
|
|
1185
|
-
expandUnits: expandUnits,
|
|
1186
|
-
mailable: mailable,
|
|
1187
|
-
},
|
|
1188
|
-
})];
|
|
1189
|
-
case 1:
|
|
1190
|
-
response = _a.sent();
|
|
1191
|
-
autocompleteRes = {
|
|
1192
|
-
addresses: response.addresses,
|
|
1193
|
-
};
|
|
1194
|
-
if (options.debug) {
|
|
1195
|
-
autocompleteRes.response = response;
|
|
1196
|
-
}
|
|
1197
|
-
return [2 /*return*/, autocompleteRes];
|
|
887
|
+
class SearchAPI {
|
|
888
|
+
static autocomplete(params) {
|
|
889
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
890
|
+
const options = Config.get();
|
|
891
|
+
let { query, near, limit, layers, countryCode, expandUnits, mailable, } = params;
|
|
892
|
+
// near can be provided as a string or Location object
|
|
893
|
+
// if "near" is not provided, request will fallback to IP based location
|
|
894
|
+
if (near && typeof near !== 'string') {
|
|
895
|
+
if (near.latitude && near.longitude) {
|
|
896
|
+
near = `${near.latitude},${near.longitude}`;
|
|
1198
897
|
}
|
|
898
|
+
}
|
|
899
|
+
const response = yield Http.request({
|
|
900
|
+
method: 'GET',
|
|
901
|
+
path: 'search/autocomplete',
|
|
902
|
+
data: {
|
|
903
|
+
query,
|
|
904
|
+
near,
|
|
905
|
+
limit,
|
|
906
|
+
layers,
|
|
907
|
+
countryCode,
|
|
908
|
+
expandUnits,
|
|
909
|
+
mailable,
|
|
910
|
+
},
|
|
1199
911
|
});
|
|
912
|
+
const autocompleteRes = {
|
|
913
|
+
addresses: response.addresses,
|
|
914
|
+
};
|
|
915
|
+
if (options.debug) {
|
|
916
|
+
autocompleteRes.response = response;
|
|
917
|
+
}
|
|
918
|
+
return autocompleteRes;
|
|
1200
919
|
});
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
data: {
|
|
1231
|
-
near: near,
|
|
1232
|
-
radius: radius,
|
|
1233
|
-
tags: tags,
|
|
1234
|
-
metadata: metadata,
|
|
1235
|
-
limit: limit,
|
|
1236
|
-
includeGeometry: includeGeometry,
|
|
1237
|
-
},
|
|
1238
|
-
})];
|
|
1239
|
-
case 4:
|
|
1240
|
-
response = _b.sent();
|
|
1241
|
-
geofencesSearchRes = {
|
|
1242
|
-
geofences: response.geofences,
|
|
1243
|
-
};
|
|
1244
|
-
if (options.debug) {
|
|
1245
|
-
geofencesSearchRes.response = response;
|
|
1246
|
-
}
|
|
1247
|
-
return [2 /*return*/, geofencesSearchRes];
|
|
1248
|
-
}
|
|
920
|
+
}
|
|
921
|
+
static searchGeofences(params) {
|
|
922
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
923
|
+
const options = Config.get();
|
|
924
|
+
let { near, radius, tags, metadata, limit, includeGeometry, } = params;
|
|
925
|
+
// use browser location if "near" not provided
|
|
926
|
+
if (!near) {
|
|
927
|
+
const { latitude, longitude } = yield Navigator.getCurrentPosition();
|
|
928
|
+
near = `${latitude},${longitude}`;
|
|
929
|
+
}
|
|
930
|
+
else if (typeof near !== 'string') { // near is "Location" object
|
|
931
|
+
const { latitude, longitude } = near;
|
|
932
|
+
near = `${latitude},${longitude}`;
|
|
933
|
+
}
|
|
934
|
+
// convert arrays to comma-strings
|
|
935
|
+
if (Array.isArray(tags)) {
|
|
936
|
+
tags = tags.join(',');
|
|
937
|
+
}
|
|
938
|
+
const response = yield Http.request({
|
|
939
|
+
method: 'GET',
|
|
940
|
+
path: 'search/geofences',
|
|
941
|
+
data: {
|
|
942
|
+
near,
|
|
943
|
+
radius,
|
|
944
|
+
tags,
|
|
945
|
+
metadata,
|
|
946
|
+
limit,
|
|
947
|
+
includeGeometry,
|
|
948
|
+
},
|
|
1249
949
|
});
|
|
950
|
+
const geofencesSearchRes = {
|
|
951
|
+
geofences: response.geofences,
|
|
952
|
+
};
|
|
953
|
+
if (options.debug) {
|
|
954
|
+
geofencesSearchRes.response = response;
|
|
955
|
+
}
|
|
956
|
+
return geofencesSearchRes;
|
|
1250
957
|
});
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
data: {
|
|
1287
|
-
near: near,
|
|
1288
|
-
radius: radius,
|
|
1289
|
-
chains: chains,
|
|
1290
|
-
categories: categories,
|
|
1291
|
-
groups: groups,
|
|
1292
|
-
limit: limit,
|
|
1293
|
-
},
|
|
1294
|
-
})];
|
|
1295
|
-
case 4:
|
|
1296
|
-
response = _b.sent();
|
|
1297
|
-
placeSearchRes = {
|
|
1298
|
-
places: response.places,
|
|
1299
|
-
};
|
|
1300
|
-
if (options.debug) {
|
|
1301
|
-
placeSearchRes.response = response;
|
|
1302
|
-
}
|
|
1303
|
-
return [2 /*return*/, placeSearchRes];
|
|
1304
|
-
}
|
|
958
|
+
}
|
|
959
|
+
static searchPlaces(params) {
|
|
960
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
961
|
+
const options = Config.get();
|
|
962
|
+
let { near, radius, chains, categories, groups, limit, } = params;
|
|
963
|
+
// use browser location if "near" not provided
|
|
964
|
+
if (!near) {
|
|
965
|
+
const { latitude, longitude } = yield Navigator.getCurrentPosition();
|
|
966
|
+
near = `${latitude},${longitude}`;
|
|
967
|
+
}
|
|
968
|
+
else if (typeof near !== 'string') { // near is "Location" object
|
|
969
|
+
const { latitude, longitude } = near;
|
|
970
|
+
near = `${latitude},${longitude}`;
|
|
971
|
+
}
|
|
972
|
+
// convert arrays to comma-strings
|
|
973
|
+
if (Array.isArray(chains)) {
|
|
974
|
+
chains = chains.join(',');
|
|
975
|
+
}
|
|
976
|
+
if (Array.isArray(categories)) {
|
|
977
|
+
categories = categories.join(',');
|
|
978
|
+
}
|
|
979
|
+
if (Array.isArray(groups)) {
|
|
980
|
+
groups = groups.join(',');
|
|
981
|
+
}
|
|
982
|
+
const response = yield Http.request({
|
|
983
|
+
method: 'GET',
|
|
984
|
+
path: 'search/places',
|
|
985
|
+
data: {
|
|
986
|
+
near,
|
|
987
|
+
radius,
|
|
988
|
+
chains,
|
|
989
|
+
categories,
|
|
990
|
+
groups,
|
|
991
|
+
limit,
|
|
992
|
+
},
|
|
1305
993
|
});
|
|
994
|
+
const placeSearchRes = {
|
|
995
|
+
places: response.places,
|
|
996
|
+
};
|
|
997
|
+
if (options.debug) {
|
|
998
|
+
placeSearchRes.response = response;
|
|
999
|
+
}
|
|
1000
|
+
return placeSearchRes;
|
|
1306
1001
|
});
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
}());
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1310
1004
|
|
|
1311
1005
|
// https://stackoverflow.com/a/44198641
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
}
|
|
1316
|
-
TripsAPI.setTripOptions = function (tripOptions) {
|
|
1006
|
+
const isValidDate = (date) => date && Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date);
|
|
1007
|
+
class TripsAPI {
|
|
1008
|
+
static setTripOptions(tripOptions) {
|
|
1317
1009
|
if (!tripOptions) {
|
|
1318
1010
|
TripsAPI.clearTripOptions();
|
|
1319
1011
|
return;
|
|
1320
1012
|
}
|
|
1321
|
-
|
|
1322
|
-
Logger.debug(
|
|
1013
|
+
const tripOptionsString = JSON.stringify(tripOptions);
|
|
1014
|
+
Logger.debug(`Saving trip options: ${tripOptionsString}`);
|
|
1323
1015
|
Storage.setItem(Storage.TRIP_OPTIONS, tripOptionsString);
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1016
|
+
}
|
|
1017
|
+
static getTripOptions() {
|
|
1018
|
+
let tripOptions = Storage.getItem(Storage.TRIP_OPTIONS);
|
|
1327
1019
|
if (tripOptions) {
|
|
1328
1020
|
tripOptions = JSON.parse(tripOptions);
|
|
1329
1021
|
}
|
|
1330
1022
|
return tripOptions;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1023
|
+
}
|
|
1024
|
+
static clearTripOptions() {
|
|
1333
1025
|
Storage.removeItem(Storage.TRIP_OPTIONS);
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
}
|
|
1364
|
-
else {
|
|
1365
|
-
if (scheduledArrivalAt) {
|
|
1366
|
-
Logger.warn('Invalid date format for scheduledArrivalAt');
|
|
1367
|
-
}
|
|
1368
|
-
data.scheduledArrivalAt = undefined;
|
|
1369
|
-
}
|
|
1370
|
-
return [4 /*yield*/, Http.request({
|
|
1371
|
-
method: 'POST',
|
|
1372
|
-
path: 'trips',
|
|
1373
|
-
data: data,
|
|
1374
|
-
})];
|
|
1375
|
-
case 1:
|
|
1376
|
-
response = _a.sent();
|
|
1377
|
-
// save trip options
|
|
1378
|
-
TripsAPI.setTripOptions(tripOptions);
|
|
1379
|
-
tripRes = {
|
|
1380
|
-
trip: response.trip,
|
|
1381
|
-
events: response.events,
|
|
1382
|
-
};
|
|
1383
|
-
if (options.debug) {
|
|
1384
|
-
tripRes.response = response;
|
|
1385
|
-
}
|
|
1386
|
-
return [2 /*return*/, tripRes];
|
|
1026
|
+
}
|
|
1027
|
+
static startTrip(tripOptions) {
|
|
1028
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1029
|
+
const options = Config.get();
|
|
1030
|
+
tripOptions = tripOptions || TripsAPI.getTripOptions();
|
|
1031
|
+
if (!tripOptions) {
|
|
1032
|
+
Logger.warn('tripOptions not set when calling "startTrip"');
|
|
1033
|
+
}
|
|
1034
|
+
const userId = tripOptions.userId || Storage.getItem(Storage.USER_ID);
|
|
1035
|
+
if (userId && userId !== Storage.getItem(Storage.USER_ID)) {
|
|
1036
|
+
// set as userId for tracking if provided
|
|
1037
|
+
Storage.setItem(Storage.USER_ID, userId);
|
|
1038
|
+
}
|
|
1039
|
+
const { externalId, destinationGeofenceTag, destinationGeofenceExternalId, mode, metadata, approachingThreshold, scheduledArrivalAt, } = tripOptions;
|
|
1040
|
+
const data = {
|
|
1041
|
+
userId,
|
|
1042
|
+
externalId,
|
|
1043
|
+
destinationGeofenceTag,
|
|
1044
|
+
destinationGeofenceExternalId,
|
|
1045
|
+
mode,
|
|
1046
|
+
metadata,
|
|
1047
|
+
approachingThreshold,
|
|
1048
|
+
};
|
|
1049
|
+
if (isValidDate(scheduledArrivalAt)) {
|
|
1050
|
+
data.scheduledArrivalAt = scheduledArrivalAt === null || scheduledArrivalAt === void 0 ? void 0 : scheduledArrivalAt.toJSON();
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
if (scheduledArrivalAt) {
|
|
1054
|
+
Logger.warn('Invalid date format for scheduledArrivalAt');
|
|
1387
1055
|
}
|
|
1056
|
+
data.scheduledArrivalAt = undefined;
|
|
1057
|
+
}
|
|
1058
|
+
const response = yield Http.request({
|
|
1059
|
+
method: 'POST',
|
|
1060
|
+
path: 'trips',
|
|
1061
|
+
data,
|
|
1388
1062
|
});
|
|
1063
|
+
// save trip options
|
|
1064
|
+
TripsAPI.setTripOptions(tripOptions);
|
|
1065
|
+
const tripRes = {
|
|
1066
|
+
trip: response.trip,
|
|
1067
|
+
events: response.events,
|
|
1068
|
+
};
|
|
1069
|
+
if (options.debug) {
|
|
1070
|
+
tripRes.response = response;
|
|
1071
|
+
}
|
|
1072
|
+
return tripRes;
|
|
1389
1073
|
});
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1415
|
-
else {
|
|
1416
|
-
if (scheduledArrivalAt) {
|
|
1417
|
-
Logger.warn('Invalid date format for scheduledArrivalAt');
|
|
1418
|
-
}
|
|
1419
|
-
data.scheduledArrivalAt = undefined;
|
|
1420
|
-
}
|
|
1421
|
-
return [4 /*yield*/, Http.request({
|
|
1422
|
-
method: 'PATCH',
|
|
1423
|
-
path: "trips/".concat(externalId, "/update"),
|
|
1424
|
-
data: data,
|
|
1425
|
-
})];
|
|
1426
|
-
case 1:
|
|
1427
|
-
response = _a.sent();
|
|
1428
|
-
tripRes = {
|
|
1429
|
-
trip: response.trip,
|
|
1430
|
-
events: response.events,
|
|
1431
|
-
};
|
|
1432
|
-
if (options.debug) {
|
|
1433
|
-
tripRes.response = response;
|
|
1434
|
-
}
|
|
1435
|
-
return [2 /*return*/, tripRes];
|
|
1074
|
+
}
|
|
1075
|
+
static updateTrip(tripOptions, status) {
|
|
1076
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1077
|
+
const options = Config.get();
|
|
1078
|
+
tripOptions = tripOptions || TripsAPI.getTripOptions();
|
|
1079
|
+
if (!tripOptions) {
|
|
1080
|
+
Logger.warn('tripOptions not set when calling "startTrip"');
|
|
1081
|
+
}
|
|
1082
|
+
const { externalId, destinationGeofenceTag, destinationGeofenceExternalId, mode, metadata, approachingThreshold, scheduledArrivalAt, } = tripOptions;
|
|
1083
|
+
const data = {
|
|
1084
|
+
status,
|
|
1085
|
+
externalId,
|
|
1086
|
+
destinationGeofenceTag,
|
|
1087
|
+
destinationGeofenceExternalId,
|
|
1088
|
+
mode,
|
|
1089
|
+
metadata,
|
|
1090
|
+
approachingThreshold,
|
|
1091
|
+
};
|
|
1092
|
+
if (isValidDate(scheduledArrivalAt)) {
|
|
1093
|
+
data.scheduledArrivalAt = scheduledArrivalAt === null || scheduledArrivalAt === void 0 ? void 0 : scheduledArrivalAt.toJSON();
|
|
1094
|
+
}
|
|
1095
|
+
else {
|
|
1096
|
+
if (scheduledArrivalAt) {
|
|
1097
|
+
Logger.warn('Invalid date format for scheduledArrivalAt');
|
|
1436
1098
|
}
|
|
1099
|
+
data.scheduledArrivalAt = undefined;
|
|
1100
|
+
}
|
|
1101
|
+
const response = yield Http.request({
|
|
1102
|
+
method: 'PATCH',
|
|
1103
|
+
path: `trips/${externalId}/update`,
|
|
1104
|
+
data,
|
|
1437
1105
|
});
|
|
1106
|
+
const tripRes = {
|
|
1107
|
+
trip: response.trip,
|
|
1108
|
+
events: response.events,
|
|
1109
|
+
};
|
|
1110
|
+
if (options.debug) {
|
|
1111
|
+
tripRes.response = response;
|
|
1112
|
+
}
|
|
1113
|
+
return tripRes;
|
|
1438
1114
|
});
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
return [4 /*yield*/, TripsAPI.updateTrip(tripOptions, 'completed')];
|
|
1448
|
-
case 1:
|
|
1449
|
-
tripResponse = _a.sent();
|
|
1450
|
-
// clear local trip options
|
|
1451
|
-
TripsAPI.clearTripOptions();
|
|
1452
|
-
return [2 /*return*/, tripResponse];
|
|
1453
|
-
}
|
|
1454
|
-
});
|
|
1115
|
+
}
|
|
1116
|
+
static completeTrip() {
|
|
1117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1118
|
+
const tripOptions = TripsAPI.getTripOptions();
|
|
1119
|
+
const tripResponse = yield TripsAPI.updateTrip(tripOptions, 'completed');
|
|
1120
|
+
// clear local trip options
|
|
1121
|
+
TripsAPI.clearTripOptions();
|
|
1122
|
+
return tripResponse;
|
|
1455
1123
|
});
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
return [4 /*yield*/, TripsAPI.updateTrip(tripOptions, 'canceled')];
|
|
1465
|
-
case 1:
|
|
1466
|
-
tripResponse = _a.sent();
|
|
1467
|
-
// clear local trip options
|
|
1468
|
-
TripsAPI.clearTripOptions();
|
|
1469
|
-
return [2 /*return*/, tripResponse];
|
|
1470
|
-
}
|
|
1471
|
-
});
|
|
1124
|
+
}
|
|
1125
|
+
static cancelTrip() {
|
|
1126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1127
|
+
const tripOptions = TripsAPI.getTripOptions();
|
|
1128
|
+
const tripResponse = yield TripsAPI.updateTrip(tripOptions, 'canceled');
|
|
1129
|
+
// clear local trip options
|
|
1130
|
+
TripsAPI.clearTripOptions();
|
|
1131
|
+
return tripResponse;
|
|
1472
1132
|
});
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
}());
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1476
1135
|
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
messageData = encoder.encode("".concat(encodedHeader, ".").concat(encodedPayload));
|
|
1493
|
-
return [4 /*yield*/, crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign'])];
|
|
1494
|
-
case 1:
|
|
1495
|
-
cryptoKey = _a.sent();
|
|
1496
|
-
return [4 /*yield*/, crypto.subtle.sign('HMAC', cryptoKey, messageData)];
|
|
1497
|
-
case 2:
|
|
1498
|
-
signatureArrayBuffer = _a.sent();
|
|
1499
|
-
signature = base64Encode(String.fromCharCode.apply(String, Array.from(new Uint8Array(signatureArrayBuffer))));
|
|
1500
|
-
return [2 /*return*/, "".concat(encodedHeader, ".").concat(encodedPayload, ".").concat(signature)];
|
|
1501
|
-
}
|
|
1502
|
-
});
|
|
1503
|
-
}); };
|
|
1136
|
+
const base64Encode = (str) => btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
1137
|
+
const signJWT = (payload, key) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1138
|
+
const encoder = new TextEncoder();
|
|
1139
|
+
const encodedHeader = base64Encode(JSON.stringify({
|
|
1140
|
+
alg: 'HS256',
|
|
1141
|
+
typ: 'JWT',
|
|
1142
|
+
}));
|
|
1143
|
+
const encodedPayload = base64Encode(JSON.stringify(payload));
|
|
1144
|
+
const keyData = encoder.encode(key);
|
|
1145
|
+
const messageData = encoder.encode(`${encodedHeader}.${encodedPayload}`);
|
|
1146
|
+
const cryptoKey = yield crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);
|
|
1147
|
+
const signatureArrayBuffer = yield crypto.subtle.sign('HMAC', cryptoKey, messageData);
|
|
1148
|
+
const signature = base64Encode(String.fromCharCode(...Array.from(new Uint8Array(signatureArrayBuffer))));
|
|
1149
|
+
return `${encodedHeader}.${encodedPayload}.${signature}`;
|
|
1150
|
+
});
|
|
1504
1151
|
|
|
1505
|
-
|
|
1506
|
-
return new Promise(
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1152
|
+
const ping = (host) => {
|
|
1153
|
+
return new Promise((resolve) => {
|
|
1154
|
+
const socket = new WebSocket(host);
|
|
1155
|
+
let pings = 0;
|
|
1156
|
+
const latencies = [];
|
|
1157
|
+
let pingInterval;
|
|
1158
|
+
let timeoutInterval;
|
|
1159
|
+
const ping = () => {
|
|
1513
1160
|
pings++;
|
|
1514
|
-
|
|
1161
|
+
const start = Date.now();
|
|
1515
1162
|
socket.send('ping');
|
|
1516
|
-
socket.onmessage =
|
|
1163
|
+
socket.onmessage = (event) => {
|
|
1517
1164
|
if (event.data === 'pong') {
|
|
1518
|
-
|
|
1165
|
+
const latency = Date.now() - start;
|
|
1519
1166
|
latencies.push(latency);
|
|
1520
1167
|
if (pings >= 3) {
|
|
1521
1168
|
clearInterval(pingInterval);
|
|
1522
1169
|
clearInterval(timeoutInterval);
|
|
1523
|
-
|
|
1170
|
+
const median = latencies.sort((a, b) => a - b)[1];
|
|
1524
1171
|
socket.close();
|
|
1525
1172
|
resolve(median);
|
|
1526
1173
|
}
|
|
1527
1174
|
}
|
|
1528
1175
|
};
|
|
1529
1176
|
};
|
|
1530
|
-
|
|
1177
|
+
const timeout = () => {
|
|
1531
1178
|
Logger.warn('Socket timeout');
|
|
1532
1179
|
clearInterval(pingInterval);
|
|
1533
1180
|
clearInterval(timeoutInterval);
|
|
1534
1181
|
socket.close();
|
|
1535
1182
|
resolve(-1);
|
|
1536
1183
|
};
|
|
1537
|
-
socket.onerror =
|
|
1184
|
+
socket.onerror = (err) => {
|
|
1538
1185
|
Logger.warn('Error opening socket');
|
|
1539
1186
|
socket.close();
|
|
1540
1187
|
resolve(-1);
|
|
1541
1188
|
};
|
|
1542
|
-
socket.onopen =
|
|
1189
|
+
socket.onopen = () => {
|
|
1543
1190
|
ping();
|
|
1544
1191
|
pingInterval = setInterval(ping, 1000);
|
|
1545
1192
|
timeoutInterval = setInterval(timeout, 10000);
|
|
@@ -1547,338 +1194,422 @@ var ping = function (host) {
|
|
|
1547
1194
|
});
|
|
1548
1195
|
};
|
|
1549
1196
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
}
|
|
1553
|
-
TrackAPI.trackOnce = function (params) {
|
|
1197
|
+
class TrackAPI {
|
|
1198
|
+
static trackOnce(params) {
|
|
1554
1199
|
var _a, _b, _c;
|
|
1555
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
payload = {
|
|
1651
|
-
payload: JSON.stringify(__assign(__assign({}, body), { scl: sclVal, csl: cslVal, lang: lang, langs: langs })),
|
|
1652
|
-
};
|
|
1653
|
-
return [4 /*yield*/, signJWT(payload, dk)];
|
|
1654
|
-
case 11:
|
|
1655
|
-
reqToken = _e.sent();
|
|
1656
|
-
return [4 /*yield*/, Http.request({
|
|
1657
|
-
host: host,
|
|
1658
|
-
method: 'POST',
|
|
1659
|
-
path: 'track',
|
|
1660
|
-
data: {
|
|
1661
|
-
token: reqToken,
|
|
1662
|
-
},
|
|
1663
|
-
headers: {
|
|
1664
|
-
'X-Radar-Body-Is-Token': 'true',
|
|
1665
|
-
},
|
|
1666
|
-
})];
|
|
1667
|
-
case 12:
|
|
1668
|
-
response = _e.sent();
|
|
1669
|
-
if (options.debug && response && response.user) {
|
|
1670
|
-
if (!response.user.metadata) {
|
|
1671
|
-
response.user.metadata = {};
|
|
1672
|
-
}
|
|
1673
|
-
response.user.metadata['radar:debug'] = {
|
|
1674
|
-
sclVal: sclVal,
|
|
1675
|
-
cslVal: cslVal,
|
|
1676
|
-
};
|
|
1677
|
-
}
|
|
1678
|
-
user_1 = response.user, events_1 = response.events, token = response.token, expiresAt = response.expiresAt;
|
|
1679
|
-
location_1 = { latitude: latitude, longitude: longitude, accuracy: accuracy };
|
|
1680
|
-
passed = void 0;
|
|
1681
|
-
expiresIn = void 0;
|
|
1682
|
-
if (expiresAt) {
|
|
1683
|
-
expiresAt = new Date(expiresAt);
|
|
1684
|
-
passed = ((_a = user_1 === null || user_1 === void 0 ? void 0 : user_1.fraud) === null || _a === void 0 ? void 0 : _a.passed) && ((_b = user_1 === null || user_1 === void 0 ? void 0 : user_1.country) === null || _b === void 0 ? void 0 : _b.passed) && ((_c = user_1 === null || user_1 === void 0 ? void 0 : user_1.state) === null || _c === void 0 ? void 0 : _c.passed);
|
|
1685
|
-
expiresIn = (expiresAt.getTime() - Date.now()) / 1000;
|
|
1686
|
-
}
|
|
1687
|
-
trackRes_1 = {
|
|
1688
|
-
user: user_1,
|
|
1689
|
-
events: events_1,
|
|
1690
|
-
location: location_1,
|
|
1691
|
-
token: token,
|
|
1692
|
-
expiresAt: expiresAt,
|
|
1693
|
-
expiresIn: expiresIn,
|
|
1694
|
-
passed: passed,
|
|
1695
|
-
};
|
|
1696
|
-
if (options.debug) {
|
|
1697
|
-
trackRes_1.response = response;
|
|
1698
|
-
}
|
|
1699
|
-
return [2 /*return*/, trackRes_1];
|
|
1700
|
-
case 13: return [4 /*yield*/, Http.request({
|
|
1701
|
-
method: 'POST',
|
|
1702
|
-
path: 'track',
|
|
1703
|
-
data: body,
|
|
1704
|
-
})];
|
|
1705
|
-
case 14:
|
|
1706
|
-
response = _e.sent();
|
|
1707
|
-
user = response.user, events = response.events;
|
|
1708
|
-
location = { latitude: latitude, longitude: longitude, accuracy: accuracy };
|
|
1709
|
-
trackRes = {
|
|
1710
|
-
user: user,
|
|
1711
|
-
events: events,
|
|
1712
|
-
location: location,
|
|
1713
|
-
};
|
|
1714
|
-
if (options.debug) {
|
|
1715
|
-
trackRes.response = response;
|
|
1716
|
-
}
|
|
1717
|
-
return [2 /*return*/, trackRes];
|
|
1200
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1201
|
+
const options = Config.get();
|
|
1202
|
+
let { latitude, longitude, accuracy, desiredAccuracy, fraud } = params;
|
|
1203
|
+
// if latitude & longitude are not provided,
|
|
1204
|
+
// try and retrieve device location (will prompt for location permissions)
|
|
1205
|
+
if (!latitude || !longitude) {
|
|
1206
|
+
const deviceLocation = yield Navigator.getCurrentPosition({ desiredAccuracy });
|
|
1207
|
+
latitude = deviceLocation.latitude;
|
|
1208
|
+
longitude = deviceLocation.longitude;
|
|
1209
|
+
accuracy = deviceLocation.accuracy;
|
|
1210
|
+
}
|
|
1211
|
+
// location authorization
|
|
1212
|
+
let locationAuthorization;
|
|
1213
|
+
try {
|
|
1214
|
+
locationAuthorization = yield Navigator.getPermissionStatus();
|
|
1215
|
+
}
|
|
1216
|
+
catch (err) {
|
|
1217
|
+
Logger.warn(`Location authorization error: ${err.message}`);
|
|
1218
|
+
}
|
|
1219
|
+
// user indentification fields
|
|
1220
|
+
const userId = params.userId || Storage.getItem(Storage.USER_ID);
|
|
1221
|
+
const deviceId = params.deviceId || Device.getDeviceId();
|
|
1222
|
+
const installId = params.installId || Device.getInstallId();
|
|
1223
|
+
const sessionId = Session.getSessionId();
|
|
1224
|
+
const deviceType = params.deviceType || 'Web';
|
|
1225
|
+
const description = params.description || Storage.getItem(Storage.DESCRIPTION);
|
|
1226
|
+
let timeZone;
|
|
1227
|
+
try {
|
|
1228
|
+
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
1229
|
+
}
|
|
1230
|
+
catch (err) {
|
|
1231
|
+
Logger.warn(`Error getting time zone: ${err.message}`);
|
|
1232
|
+
}
|
|
1233
|
+
// save userId for trip tracking
|
|
1234
|
+
if (!userId) {
|
|
1235
|
+
Logger.warn('userId not provided for trackOnce.');
|
|
1236
|
+
}
|
|
1237
|
+
else {
|
|
1238
|
+
Storage.setItem(Storage.USER_ID, userId);
|
|
1239
|
+
}
|
|
1240
|
+
// other info
|
|
1241
|
+
const metadata = params.metadata || Storage.getJSON(Storage.METADATA);
|
|
1242
|
+
// trips
|
|
1243
|
+
const tripOptions = params.tripOptions || TripsAPI.getTripOptions();
|
|
1244
|
+
if (tripOptions) {
|
|
1245
|
+
tripOptions.version = '2';
|
|
1246
|
+
}
|
|
1247
|
+
const body = Object.assign(Object.assign({}, params), { locationAuthorization,
|
|
1248
|
+
accuracy,
|
|
1249
|
+
description,
|
|
1250
|
+
deviceId,
|
|
1251
|
+
deviceType, foreground: true, installId,
|
|
1252
|
+
sessionId,
|
|
1253
|
+
latitude,
|
|
1254
|
+
longitude,
|
|
1255
|
+
metadata, sdkVersion: SDK_VERSION, stopped: true, userId,
|
|
1256
|
+
tripOptions,
|
|
1257
|
+
timeZone });
|
|
1258
|
+
let response;
|
|
1259
|
+
if (fraud) {
|
|
1260
|
+
const host = 'https://api-verified.radar.io';
|
|
1261
|
+
const pingHost = 'ping.radar-verify.com';
|
|
1262
|
+
const lang = navigator.language;
|
|
1263
|
+
const langs = navigator.languages;
|
|
1264
|
+
const { dk } = yield Http.request({
|
|
1265
|
+
host,
|
|
1266
|
+
method: 'GET',
|
|
1267
|
+
path: 'config',
|
|
1268
|
+
data: {
|
|
1269
|
+
deviceId,
|
|
1270
|
+
installId,
|
|
1271
|
+
sessionId,
|
|
1272
|
+
locationAuthorization,
|
|
1273
|
+
},
|
|
1274
|
+
headers: {
|
|
1275
|
+
'X-Radar-Desktop-Device-Type': 'Web',
|
|
1276
|
+
},
|
|
1277
|
+
});
|
|
1278
|
+
let sclVal = -1;
|
|
1279
|
+
let cslVal = -1;
|
|
1280
|
+
try {
|
|
1281
|
+
const [sclRes, csl] = yield Promise.all([
|
|
1282
|
+
Http.request({
|
|
1283
|
+
host: `https://${pingHost}`,
|
|
1284
|
+
method: 'GET',
|
|
1285
|
+
path: 'ping',
|
|
1286
|
+
}),
|
|
1287
|
+
ping(`wss://${pingHost}`),
|
|
1288
|
+
]);
|
|
1289
|
+
const { scl } = sclRes;
|
|
1290
|
+
sclVal = scl;
|
|
1291
|
+
cslVal = csl;
|
|
1292
|
+
}
|
|
1293
|
+
catch (err) {
|
|
1294
|
+
// do nothing, send scl = -1 and csl = -1
|
|
1718
1295
|
}
|
|
1296
|
+
const payload = {
|
|
1297
|
+
payload: JSON.stringify(Object.assign(Object.assign({}, body), { scl: sclVal, csl: cslVal, lang,
|
|
1298
|
+
langs })),
|
|
1299
|
+
};
|
|
1300
|
+
const token = yield signJWT(payload, dk);
|
|
1301
|
+
response = yield Http.request({
|
|
1302
|
+
host,
|
|
1303
|
+
method: 'POST',
|
|
1304
|
+
path: 'track',
|
|
1305
|
+
data: {
|
|
1306
|
+
token,
|
|
1307
|
+
},
|
|
1308
|
+
headers: {
|
|
1309
|
+
'X-Radar-Body-Is-Token': 'true',
|
|
1310
|
+
},
|
|
1311
|
+
});
|
|
1312
|
+
if (options.debug && response && response.user) {
|
|
1313
|
+
if (!response.user.metadata) {
|
|
1314
|
+
response.user.metadata = {};
|
|
1315
|
+
}
|
|
1316
|
+
response.user.metadata['radar:debug'] = {
|
|
1317
|
+
sclVal,
|
|
1318
|
+
cslVal,
|
|
1319
|
+
};
|
|
1320
|
+
let { user, events, token, expiresAt } = response;
|
|
1321
|
+
const location = { latitude, longitude, accuracy };
|
|
1322
|
+
let passed;
|
|
1323
|
+
let expiresIn;
|
|
1324
|
+
if (expiresAt) {
|
|
1325
|
+
expiresAt = new Date(expiresAt);
|
|
1326
|
+
passed = ((_a = user === null || user === void 0 ? void 0 : user.fraud) === null || _a === void 0 ? void 0 : _a.passed) && ((_b = user === null || user === void 0 ? void 0 : user.country) === null || _b === void 0 ? void 0 : _b.passed) && ((_c = user === null || user === void 0 ? void 0 : user.state) === null || _c === void 0 ? void 0 : _c.passed);
|
|
1327
|
+
expiresIn = (expiresAt.getTime() - Date.now()) / 1000;
|
|
1328
|
+
}
|
|
1329
|
+
const trackRes = {
|
|
1330
|
+
user,
|
|
1331
|
+
events,
|
|
1332
|
+
location,
|
|
1333
|
+
token,
|
|
1334
|
+
expiresAt,
|
|
1335
|
+
expiresIn,
|
|
1336
|
+
passed,
|
|
1337
|
+
};
|
|
1338
|
+
if (options.debug) {
|
|
1339
|
+
trackRes.response = response;
|
|
1340
|
+
}
|
|
1341
|
+
return trackRes;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
response = yield Http.request({
|
|
1345
|
+
method: 'POST',
|
|
1346
|
+
path: 'track',
|
|
1347
|
+
data: body,
|
|
1719
1348
|
});
|
|
1349
|
+
const { user, events } = response;
|
|
1350
|
+
const location = { latitude, longitude, accuracy };
|
|
1351
|
+
const trackRes = {
|
|
1352
|
+
user,
|
|
1353
|
+
events,
|
|
1354
|
+
location,
|
|
1355
|
+
};
|
|
1356
|
+
if (options.debug) {
|
|
1357
|
+
trackRes.response = response;
|
|
1358
|
+
}
|
|
1359
|
+
return trackRes;
|
|
1720
1360
|
});
|
|
1721
|
-
};
|
|
1722
|
-
return TrackAPI;
|
|
1723
|
-
}());
|
|
1724
|
-
|
|
1725
|
-
var VerifyAPI = /** @class */ (function () {
|
|
1726
|
-
function VerifyAPI() {
|
|
1727
1361
|
}
|
|
1728
|
-
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
class VerifyAPI {
|
|
1365
|
+
static trackVerified(params, encrypted = false) {
|
|
1729
1366
|
var _a, _b, _c;
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
case 1:
|
|
1760
|
-
response = _d.sent();
|
|
1761
|
-
user = response.user, events = response.events, token = response.token, expiresAt = response.expiresAt;
|
|
1762
|
-
if (user && user.location && user.location.coordinates && user.locationAccuracy) {
|
|
1763
|
-
location = {
|
|
1764
|
-
latitude: user.location.coordinates[1],
|
|
1765
|
-
longitude: user.location.coordinates[0],
|
|
1766
|
-
accuracy: user.locationAccuracy,
|
|
1767
|
-
};
|
|
1768
|
-
}
|
|
1769
|
-
if (expiresAt) {
|
|
1770
|
-
expiresAt = new Date(expiresAt);
|
|
1771
|
-
passed = ((_a = user === null || user === void 0 ? void 0 : user.fraud) === null || _a === void 0 ? void 0 : _a.passed) && ((_b = user === null || user === void 0 ? void 0 : user.country) === null || _b === void 0 ? void 0 : _b.passed) && ((_c = user === null || user === void 0 ? void 0 : user.state) === null || _c === void 0 ? void 0 : _c.passed);
|
|
1772
|
-
expiresIn = (expiresAt.getTime() - Date.now()) / 1000;
|
|
1773
|
-
}
|
|
1774
|
-
trackRes = {
|
|
1775
|
-
user: user,
|
|
1776
|
-
events: events,
|
|
1777
|
-
location: location,
|
|
1778
|
-
token: token,
|
|
1779
|
-
expiresAt: expiresAt,
|
|
1780
|
-
expiresIn: expiresIn,
|
|
1781
|
-
passed: passed,
|
|
1782
|
-
};
|
|
1783
|
-
if (options.debug) {
|
|
1784
|
-
trackRes.response = response;
|
|
1785
|
-
}
|
|
1786
|
-
return [2 /*return*/, trackRes];
|
|
1787
|
-
}
|
|
1367
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1368
|
+
const options = Config.get();
|
|
1369
|
+
// user indentification fields
|
|
1370
|
+
const userId = params.userId || Storage.getItem(Storage.USER_ID);
|
|
1371
|
+
const deviceId = params.deviceId || Device.getDeviceId();
|
|
1372
|
+
const installId = params.installId || Device.getInstallId();
|
|
1373
|
+
const sessionId = Session.getSessionId();
|
|
1374
|
+
const description = params.description || Storage.getItem(Storage.DESCRIPTION);
|
|
1375
|
+
// save userId
|
|
1376
|
+
if (!userId) {
|
|
1377
|
+
Logger.warn('userId not provided for trackVerified.');
|
|
1378
|
+
}
|
|
1379
|
+
else {
|
|
1380
|
+
Storage.setItem(Storage.USER_ID, userId);
|
|
1381
|
+
}
|
|
1382
|
+
// other info
|
|
1383
|
+
const metadata = params.metadata || Storage.getJSON(Storage.METADATA);
|
|
1384
|
+
const body = Object.assign(Object.assign({}, params), { description,
|
|
1385
|
+
deviceId, foreground: true, installId,
|
|
1386
|
+
sessionId,
|
|
1387
|
+
metadata, sdkVersion: SDK_VERSION, stopped: true, userId,
|
|
1388
|
+
encrypted });
|
|
1389
|
+
let userAgent = navigator.userAgent;
|
|
1390
|
+
const apple = userAgent && (userAgent.toLowerCase().includes('mac') || userAgent.toLowerCase().includes('iphone') || userAgent.toLowerCase().includes('ipod') || userAgent.toLowerCase().includes('ipad'));
|
|
1391
|
+
const response = yield Http.request({
|
|
1392
|
+
method: 'GET',
|
|
1393
|
+
path: 'verify',
|
|
1394
|
+
data: body,
|
|
1395
|
+
host: apple ? 'https://radar-verify.com:52516' : 'http://localhost:52516',
|
|
1788
1396
|
});
|
|
1397
|
+
let { user, events, token, expiresAt } = response;
|
|
1398
|
+
let location;
|
|
1399
|
+
if (user && user.location && user.location.coordinates && user.locationAccuracy) {
|
|
1400
|
+
location = {
|
|
1401
|
+
latitude: user.location.coordinates[1],
|
|
1402
|
+
longitude: user.location.coordinates[0],
|
|
1403
|
+
accuracy: user.locationAccuracy,
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
let passed;
|
|
1407
|
+
let expiresIn;
|
|
1408
|
+
if (expiresAt) {
|
|
1409
|
+
expiresAt = new Date(expiresAt);
|
|
1410
|
+
passed = ((_a = user === null || user === void 0 ? void 0 : user.fraud) === null || _a === void 0 ? void 0 : _a.passed) && ((_b = user === null || user === void 0 ? void 0 : user.country) === null || _b === void 0 ? void 0 : _b.passed) && ((_c = user === null || user === void 0 ? void 0 : user.state) === null || _c === void 0 ? void 0 : _c.passed);
|
|
1411
|
+
expiresIn = (expiresAt.getTime() - Date.now()) / 1000;
|
|
1412
|
+
}
|
|
1413
|
+
const trackRes = {
|
|
1414
|
+
user,
|
|
1415
|
+
events,
|
|
1416
|
+
location,
|
|
1417
|
+
token,
|
|
1418
|
+
expiresAt,
|
|
1419
|
+
expiresIn,
|
|
1420
|
+
passed,
|
|
1421
|
+
};
|
|
1422
|
+
if (options.debug) {
|
|
1423
|
+
trackRes.response = response;
|
|
1424
|
+
}
|
|
1425
|
+
return trackRes;
|
|
1789
1426
|
});
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
|
-
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
const RADAR_LOGO_URL = 'https://api.radar.io/maps/static/images/logo.svg';
|
|
1431
|
+
class RadarLogoControl {
|
|
1432
|
+
onAdd() {
|
|
1433
|
+
const img = document.createElement('img');
|
|
1434
|
+
img.src = RADAR_LOGO_URL;
|
|
1435
|
+
this.link = document.createElement('a');
|
|
1436
|
+
this.link.id = 'radar-map-logo';
|
|
1437
|
+
this.link.href = 'https://radar.com?ref=powered_by_radar';
|
|
1438
|
+
this.link.target = '_blank';
|
|
1439
|
+
this.link.appendChild(img);
|
|
1440
|
+
return this.link;
|
|
1441
|
+
}
|
|
1442
|
+
onRemove() {
|
|
1443
|
+
var _a;
|
|
1444
|
+
(_a = this.link) === null || _a === void 0 ? void 0 : _a.remove();
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1793
1447
|
|
|
1794
|
-
|
|
1795
|
-
|
|
1448
|
+
//check if value is primitive
|
|
1449
|
+
const isPrimitive = (obj) => {
|
|
1450
|
+
return (obj !== Object(obj));
|
|
1451
|
+
};
|
|
1452
|
+
const deepEqual = (obj1, obj2) => {
|
|
1453
|
+
if (obj1 === obj2) // it's just the same object. No need to compare.
|
|
1454
|
+
return true;
|
|
1455
|
+
if (isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
|
|
1456
|
+
return obj1 === obj2;
|
|
1457
|
+
if (Object.keys(obj1).length !== Object.keys(obj2).length)
|
|
1458
|
+
return false;
|
|
1459
|
+
// compare objects with same number of keys
|
|
1460
|
+
for (let key in obj1) {
|
|
1461
|
+
if (!(key in obj2))
|
|
1462
|
+
return false; //other object doesn't have this prop
|
|
1463
|
+
if (!deepEqual(obj1[key], obj2[key]))
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
return true;
|
|
1467
|
+
};
|
|
1468
|
+
const uniq = (arr) => {
|
|
1469
|
+
const outputArray = arr.filter((v, i, self) => i === self.indexOf(v));
|
|
1470
|
+
return outputArray;
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
// NOTE(jasonl): ENSURE THIS STAYS IN SYNC WITH THE SERVER IMPLEMENTATION
|
|
1474
|
+
const RADAR_LANGUAGE_EXPR = ['get', 'radar:name_client_language'];
|
|
1475
|
+
/** get an array of languages set in the browser in RFC 5646 format */
|
|
1476
|
+
const getBrowserLanguages = (options = { fallback: 'en', format: 'RFC-5646' }) => {
|
|
1477
|
+
let languagesRFC5646 = [options.fallback];
|
|
1478
|
+
if (navigator.languages.length > 0) {
|
|
1479
|
+
languagesRFC5646 = [...navigator.languages];
|
|
1480
|
+
}
|
|
1481
|
+
else if (navigator.language) {
|
|
1482
|
+
languagesRFC5646 = [navigator.language];
|
|
1483
|
+
}
|
|
1484
|
+
if (options.format === 'ISO-639-1') {
|
|
1485
|
+
// RFC 5646 format is always prefixed by the ISO 639-1 language code so we need to strip that out
|
|
1486
|
+
const languagesISO6391 = uniq(languagesRFC5646.map(l => l.split('-')[0]));
|
|
1487
|
+
return languagesISO6391;
|
|
1488
|
+
}
|
|
1489
|
+
return languagesRFC5646;
|
|
1490
|
+
};
|
|
1491
|
+
const replaceAllValuesInExpression = (expr, target, value) => {
|
|
1492
|
+
if (target.length !== value.length) {
|
|
1493
|
+
Logger.warn('replaceAllValueInExpression: Target and value arrays must be the same length');
|
|
1494
|
+
return expr;
|
|
1495
|
+
}
|
|
1496
|
+
const findIndex = target.findIndex((t) => deepEqual(t, expr));
|
|
1497
|
+
if (findIndex !== -1) {
|
|
1498
|
+
return value[findIndex];
|
|
1499
|
+
}
|
|
1500
|
+
if (Array.isArray(expr)) {
|
|
1501
|
+
return expr.map((e) => replaceAllValuesInExpression(e, target, value));
|
|
1502
|
+
}
|
|
1503
|
+
return expr;
|
|
1504
|
+
};
|
|
1505
|
+
const transformMapStyle = (styleJSON, options) => {
|
|
1506
|
+
var _a;
|
|
1507
|
+
let languages = [];
|
|
1508
|
+
// use browser language if style language is set to local
|
|
1509
|
+
if (((_a = styleJSON === null || styleJSON === void 0 ? void 0 : styleJSON.metadata) === null || _a === void 0 ? void 0 : _a['radar:language']) === 'local') {
|
|
1510
|
+
const fallbackLanguage = options.navigatorFallbackLanguage || 'en';
|
|
1511
|
+
languages = getBrowserLanguages({ fallback: fallbackLanguage, format: 'ISO-639-1' });
|
|
1512
|
+
}
|
|
1513
|
+
// client set language takes precedence
|
|
1514
|
+
if (options.languages) {
|
|
1515
|
+
languages = options.languages;
|
|
1516
|
+
}
|
|
1517
|
+
if (languages.length > 0) {
|
|
1518
|
+
// construct expression ordered by language preference
|
|
1519
|
+
const localLanguageExpression = ['coalesce'];
|
|
1520
|
+
languages.forEach((l) => {
|
|
1521
|
+
localLanguageExpression.push(['get', `name_${l}`], ['get', `name:${l}`]);
|
|
1522
|
+
});
|
|
1523
|
+
const transformedLayers = styleJSON.layers.map((layer) => {
|
|
1524
|
+
if (layer.type === 'symbol' && layer.layout['text-field']) {
|
|
1525
|
+
layer.layout['text-field'] = replaceAllValuesInExpression(layer.layout['text-field'], [RADAR_LANGUAGE_EXPR], [localLanguageExpression]);
|
|
1526
|
+
return layer;
|
|
1527
|
+
}
|
|
1528
|
+
return layer;
|
|
1529
|
+
});
|
|
1530
|
+
return Object.assign(Object.assign({}, styleJSON), { layers: transformedLayers });
|
|
1531
|
+
}
|
|
1532
|
+
return styleJSON;
|
|
1533
|
+
};
|
|
1534
|
+
|
|
1535
|
+
const DEFAULT_STYLE = 'radar-default-v1';
|
|
1536
|
+
const RADAR_STYLES = [
|
|
1796
1537
|
'radar-default-v1',
|
|
1797
1538
|
'radar-light-v1',
|
|
1798
1539
|
'radar-dark-v1',
|
|
1799
1540
|
];
|
|
1800
|
-
|
|
1801
|
-
var defaultMaplibreOptions = {
|
|
1541
|
+
const defaultMapOptions = {
|
|
1802
1542
|
minZoom: 1,
|
|
1803
1543
|
maxZoom: 20,
|
|
1804
1544
|
attributionControl: false,
|
|
1805
1545
|
dragRotate: false,
|
|
1806
1546
|
touchPitch: false,
|
|
1807
1547
|
maplibreLogo: false,
|
|
1548
|
+
navigatorFallbackLanguage: 'en',
|
|
1808
1549
|
};
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
return ("".concat(options.host, "/maps/styles/").concat(style, "?publishableKey=").concat(options.publishableKey));
|
|
1815
|
-
};
|
|
1816
|
-
// use formatted style URL if using one of Radar's out-of-the-box styles
|
|
1817
|
-
var getStyle = function (options, mapOptions) {
|
|
1818
|
-
var style = mapOptions.style;
|
|
1819
|
-
if (!style || (typeof style === 'string' && RADAR_STYLES.includes(style))) {
|
|
1820
|
-
return createStyleURL(options, mapOptions.style);
|
|
1550
|
+
const createStyleURL = (options, style = DEFAULT_STYLE) => (`${options.host}/maps/styles/${style}?publishableKey=${options.publishableKey}`);
|
|
1551
|
+
// check if style is a Radar style or a custom style
|
|
1552
|
+
const isRadarStyle = (style) => {
|
|
1553
|
+
if (RADAR_STYLES.includes(style)) { // Radar built-in style
|
|
1554
|
+
return true;
|
|
1821
1555
|
}
|
|
1822
|
-
|
|
1556
|
+
if (!/^(http:|https:)/.test(style)) { // Radar custom style (not a URL)
|
|
1557
|
+
return true;
|
|
1558
|
+
}
|
|
1559
|
+
return false;
|
|
1823
1560
|
};
|
|
1824
|
-
|
|
1825
|
-
|
|
1561
|
+
// use formatted style URL if using one of Radar's out-of-the-box styles or is a Radar custom style
|
|
1562
|
+
const getStyle = (options, mapOptions) => {
|
|
1563
|
+
const style = mapOptions.style;
|
|
1564
|
+
if (!style || (typeof style === 'string' && isRadarStyle(style))) {
|
|
1565
|
+
return createStyleURL(options, style);
|
|
1826
1566
|
}
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
if (!
|
|
1567
|
+
return mapOptions.style; // style object or URL
|
|
1568
|
+
};
|
|
1569
|
+
class RadarMap extends maplibregl.Map {
|
|
1570
|
+
constructor(mapOptions) {
|
|
1571
|
+
const config = Config.get();
|
|
1572
|
+
if (!config.publishableKey) {
|
|
1833
1573
|
Logger.warn('publishableKey not set. Call Radar.initialize() with key before creating a new map.');
|
|
1834
1574
|
}
|
|
1835
1575
|
// configure maplibre options
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
Logger.debug(
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
maplibreOptions.transformRequest = function (url, resourceType) {
|
|
1843
|
-
if (resourceType === 'Style' && RADAR_STYLES.includes(url)) {
|
|
1844
|
-
var radarStyleURL = createStyleURL(options, url);
|
|
1845
|
-
return { url: radarStyleURL };
|
|
1576
|
+
const style = getStyle(config, mapOptions);
|
|
1577
|
+
const maplibreOptions = Object.assign({}, defaultMapOptions, mapOptions, { style });
|
|
1578
|
+
Logger.debug(`initialize map with options: ${JSON.stringify(maplibreOptions)}`);
|
|
1579
|
+
maplibreOptions.transformRequest = (url, resourceType) => {
|
|
1580
|
+
if (resourceType === 'Style' && isRadarStyle(url)) {
|
|
1581
|
+
url = createStyleURL(config, url);
|
|
1846
1582
|
}
|
|
1847
|
-
|
|
1848
|
-
|
|
1583
|
+
let headers = {
|
|
1584
|
+
'Authorization': config.publishableKey,
|
|
1585
|
+
'X-Radar-Device-Type': 'Web',
|
|
1586
|
+
'X-Radar-SDK-Version': SDK_VERSION,
|
|
1587
|
+
};
|
|
1588
|
+
if (typeof config.getRequestHeaders === 'function') {
|
|
1589
|
+
headers = Object.assign(headers, config.getRequestHeaders());
|
|
1849
1590
|
}
|
|
1591
|
+
return { url, headers };
|
|
1850
1592
|
};
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1593
|
+
super(maplibreOptions);
|
|
1594
|
+
this._markers = [];
|
|
1595
|
+
const container = this.getContainer();
|
|
1854
1596
|
if (!container.style.width && !container.style.height) {
|
|
1855
1597
|
Logger.warn('map container does not have a set "width" or "height"');
|
|
1856
1598
|
}
|
|
1857
1599
|
// add radar logo
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
var link = document.createElement('a');
|
|
1861
|
-
link.id = 'radar-map-logo';
|
|
1862
|
-
link.href = 'https://radar.com?ref=powered_by_radar';
|
|
1863
|
-
link.target = '_blank';
|
|
1864
|
-
link.style.position = 'absolute';
|
|
1865
|
-
link.style.bottom = '0';
|
|
1866
|
-
link.style.left = '5px';
|
|
1867
|
-
link.style.width = '80px';
|
|
1868
|
-
link.style.height = '38px';
|
|
1869
|
-
link.appendChild(img);
|
|
1870
|
-
map.getContainer().appendChild(link);
|
|
1600
|
+
const radarLogo = new RadarLogoControl();
|
|
1601
|
+
this.addControl(radarLogo, 'bottom-left');
|
|
1871
1602
|
// add attribution
|
|
1872
|
-
|
|
1873
|
-
|
|
1603
|
+
const attribution = new maplibregl.AttributionControl({ compact: false });
|
|
1604
|
+
this.addControl(attribution, 'bottom-right');
|
|
1874
1605
|
// add zoom controls
|
|
1875
|
-
|
|
1876
|
-
|
|
1606
|
+
const nav = new maplibregl.NavigationControl({ showCompass: false });
|
|
1607
|
+
this.addControl(nav, 'bottom-right');
|
|
1877
1608
|
// handle map resize actions
|
|
1878
|
-
|
|
1879
|
-
|
|
1609
|
+
const onResize = () => {
|
|
1610
|
+
const attrib = document.querySelector('.maplibregl-ctrl-attrib');
|
|
1880
1611
|
if (attrib) {
|
|
1881
|
-
|
|
1612
|
+
const width = this.getContainer().clientWidth;
|
|
1882
1613
|
if (width < 380) {
|
|
1883
1614
|
attrib.classList.add('hidden');
|
|
1884
1615
|
}
|
|
@@ -1887,13 +1618,53 @@ var MapUI = /** @class */ (function () {
|
|
|
1887
1618
|
}
|
|
1888
1619
|
}
|
|
1889
1620
|
};
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1621
|
+
const onStyleLoad = (e) => {
|
|
1622
|
+
var _a;
|
|
1623
|
+
const styleJSON = (_a = e.style) === null || _a === void 0 ? void 0 : _a.stylesheet; // for some reason, style does not exist in the types
|
|
1624
|
+
if (!styleJSON) {
|
|
1625
|
+
Logger.warn('style data not available');
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
// transform text-field expressions to use local language
|
|
1629
|
+
const newStyleJSON = transformMapStyle(styleJSON, maplibreOptions);
|
|
1630
|
+
this.setStyle(newStyleJSON);
|
|
1631
|
+
};
|
|
1632
|
+
this.on('resize', onResize);
|
|
1633
|
+
this.on('load', onResize);
|
|
1634
|
+
this.on('styledata', onStyleLoad);
|
|
1635
|
+
}
|
|
1636
|
+
addMarker(marker) {
|
|
1637
|
+
this._markers.push(marker);
|
|
1638
|
+
}
|
|
1639
|
+
removeMarker(marker) {
|
|
1640
|
+
this._markers = this._markers.filter((mapMarker) => mapMarker !== marker);
|
|
1641
|
+
}
|
|
1642
|
+
getMarkers() {
|
|
1643
|
+
return this._markers;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
const defaultMarkerOptions = {
|
|
1648
|
+
color: '#000257',
|
|
1649
|
+
};
|
|
1650
|
+
const createImageElement = (options) => {
|
|
1651
|
+
const element = document.createElement('img');
|
|
1652
|
+
element.src = options.url;
|
|
1653
|
+
if (options.width) {
|
|
1654
|
+
element.width = options.width;
|
|
1655
|
+
}
|
|
1656
|
+
if (options.height) {
|
|
1657
|
+
element.height = options.height;
|
|
1658
|
+
}
|
|
1659
|
+
if (!options.width && !options.height) {
|
|
1660
|
+
element.style.maxWidth = '64px';
|
|
1661
|
+
element.style.maxHeight = '64px';
|
|
1662
|
+
}
|
|
1663
|
+
return element;
|
|
1664
|
+
};
|
|
1665
|
+
class RadarMarker extends maplibregl.Marker {
|
|
1666
|
+
constructor(markerOptions) {
|
|
1667
|
+
const maplibreOptions = Object.assign({}, defaultMarkerOptions);
|
|
1897
1668
|
if (markerOptions.color) {
|
|
1898
1669
|
maplibreOptions.color = markerOptions.color;
|
|
1899
1670
|
}
|
|
@@ -1903,22 +1674,84 @@ var MapUI = /** @class */ (function () {
|
|
|
1903
1674
|
if (markerOptions.scale) {
|
|
1904
1675
|
maplibreOptions.scale = markerOptions.scale;
|
|
1905
1676
|
}
|
|
1906
|
-
|
|
1677
|
+
super(maplibreOptions);
|
|
1678
|
+
if (markerOptions.image) {
|
|
1679
|
+
this._image = markerOptions.image;
|
|
1680
|
+
const originalElement = this._element.cloneNode(true);
|
|
1681
|
+
this._element.childNodes.forEach((child) => {
|
|
1682
|
+
child.remove();
|
|
1683
|
+
});
|
|
1684
|
+
const onSuccess = (blob) => {
|
|
1685
|
+
const markerObject = URL.createObjectURL(blob);
|
|
1686
|
+
this._element.replaceChildren(createImageElement({ url: markerObject }));
|
|
1687
|
+
};
|
|
1688
|
+
const onError = (err) => {
|
|
1689
|
+
Logger.error(`Could not load marker: ${err.message} - falling back to default marker`);
|
|
1690
|
+
this._element.replaceChildren(...Array.from(originalElement.childNodes));
|
|
1691
|
+
};
|
|
1692
|
+
if (markerOptions.image.url) {
|
|
1693
|
+
fetch(markerOptions.image.url)
|
|
1694
|
+
.then(res => {
|
|
1695
|
+
if (res.status === 200) {
|
|
1696
|
+
res.blob()
|
|
1697
|
+
.then(onSuccess)
|
|
1698
|
+
.catch(onError);
|
|
1699
|
+
}
|
|
1700
|
+
else {
|
|
1701
|
+
onError(new Error(res.statusText));
|
|
1702
|
+
}
|
|
1703
|
+
})
|
|
1704
|
+
.catch(onError);
|
|
1705
|
+
}
|
|
1706
|
+
if (markerOptions.image.radarMarkerId) {
|
|
1707
|
+
// fetch custom marker
|
|
1708
|
+
Http.request({
|
|
1709
|
+
method: 'GET',
|
|
1710
|
+
version: 'maps',
|
|
1711
|
+
path: `markers/${markerOptions.image.radarMarkerId}`,
|
|
1712
|
+
responseType: 'blob',
|
|
1713
|
+
})
|
|
1714
|
+
.then(({ data }) => onSuccess(data))
|
|
1715
|
+
.catch(onError);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1907
1718
|
// set popup text or HTML
|
|
1908
1719
|
if (markerOptions.text) {
|
|
1909
|
-
|
|
1910
|
-
|
|
1720
|
+
const popup = new maplibregl.Popup({ offset: 35 }).setText(markerOptions.text);
|
|
1721
|
+
this.setPopup(popup);
|
|
1911
1722
|
}
|
|
1912
1723
|
else if (markerOptions.html) {
|
|
1913
|
-
|
|
1914
|
-
|
|
1724
|
+
const popup = new maplibregl.Popup({ offset: 35 }).setHTML(markerOptions.html);
|
|
1725
|
+
this.setPopup(popup);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
addTo(map) {
|
|
1729
|
+
map.addMarker(this);
|
|
1730
|
+
return super.addTo(map);
|
|
1731
|
+
}
|
|
1732
|
+
remove() {
|
|
1733
|
+
if (this._map) {
|
|
1734
|
+
this._map.removeMarker(this);
|
|
1915
1735
|
}
|
|
1916
|
-
return
|
|
1917
|
-
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1736
|
+
return super.remove();
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
class MapUI {
|
|
1741
|
+
static getMapLibre() {
|
|
1742
|
+
return maplibregl;
|
|
1743
|
+
}
|
|
1744
|
+
static createMap(mapOptions) {
|
|
1745
|
+
const radarMap = new RadarMap(mapOptions);
|
|
1746
|
+
return radarMap;
|
|
1747
|
+
}
|
|
1748
|
+
static createMarker(markerOptions = {}) {
|
|
1749
|
+
const radarMarker = new RadarMarker(markerOptions);
|
|
1750
|
+
return radarMarker;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1920
1753
|
|
|
1921
|
-
|
|
1754
|
+
const CLASSNAMES = {
|
|
1922
1755
|
WRAPPER: 'radar-autocomplete-wrapper',
|
|
1923
1756
|
INPUT: 'radar-autocomplete-input',
|
|
1924
1757
|
SEARCH_ICON: 'radar-autocomplete-search-icon',
|
|
@@ -1929,10 +1762,10 @@ var CLASSNAMES = {
|
|
|
1929
1762
|
POWERED_BY_RADAR: 'radar-powered',
|
|
1930
1763
|
NO_RESULTS: 'radar-no-results',
|
|
1931
1764
|
};
|
|
1932
|
-
|
|
1765
|
+
const ARIA = {
|
|
1933
1766
|
EXPANDED: 'aria-expanded',
|
|
1934
1767
|
};
|
|
1935
|
-
|
|
1768
|
+
const defaultAutocompleteOptions = {
|
|
1936
1769
|
container: 'autocomplete',
|
|
1937
1770
|
debounceMS: 200,
|
|
1938
1771
|
minCharacters: 3,
|
|
@@ -1944,14 +1777,14 @@ var defaultAutocompleteOptions = {
|
|
|
1944
1777
|
hideResultsOnBlur: true,
|
|
1945
1778
|
};
|
|
1946
1779
|
// determine whether to use px or CSS string
|
|
1947
|
-
|
|
1780
|
+
const formatCSSValue = (value) => {
|
|
1948
1781
|
if (typeof value === 'number') {
|
|
1949
|
-
return
|
|
1782
|
+
return `${value}px`;
|
|
1950
1783
|
}
|
|
1951
1784
|
return value;
|
|
1952
1785
|
};
|
|
1953
|
-
|
|
1954
|
-
|
|
1786
|
+
const DEFAULT_WIDTH = 400;
|
|
1787
|
+
const setWidth = (input, options) => {
|
|
1955
1788
|
// if responsive and width is provided, treat it as maxWidth
|
|
1956
1789
|
if (options.responsive) {
|
|
1957
1790
|
input.style.width = '100%';
|
|
@@ -1964,21 +1797,25 @@ var setWidth = function (input, options) {
|
|
|
1964
1797
|
input.style.width = formatCSSValue(options.width || DEFAULT_WIDTH);
|
|
1965
1798
|
input.style.removeProperty('max-width');
|
|
1966
1799
|
};
|
|
1967
|
-
|
|
1800
|
+
const setHeight = (resultsList, options) => {
|
|
1968
1801
|
if (options.maxHeight) {
|
|
1969
1802
|
resultsList.style.maxHeight = formatCSSValue(options.maxHeight);
|
|
1970
1803
|
resultsList.style.overflowY = 'auto'; /* allow overflow when maxHeight is applied */
|
|
1971
1804
|
}
|
|
1972
1805
|
};
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1806
|
+
const getMarkerIcon = (color = "#ACBDC8") => {
|
|
1807
|
+
const fill = color.replace('#', '%23');
|
|
1808
|
+
const svg = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
1809
|
+
<path d="M12.5704 6.57036C12.5704 4.11632 10.6342 2.11257 8.21016 2C8.14262 2 8.06757 2 8.00003 2C7.93249 2 7.85744 2 7.7899 2C5.35838 2.11257 3.42967 4.11632 3.42967 6.57036C3.42967 6.60037 3.42967 6.6379 3.42967 6.66792C3.42967 6.69794 3.42967 6.73546 3.42967 6.76548C3.42967 9.46717 7.09196 13.3621 7.4672 13.7598C7.61729 13.9174 7.84994 14 8.00003 14C8.15012 14 8.38277 13.9174 8.53286 13.7598C8.9156 13.3621 12.5704 9.46717 12.5704 6.76548C12.5704 6.72795 12.5704 6.69794 12.5704 6.66792C12.5704 6.6379 12.5704 6.60037 12.5704 6.57036ZM7.99252 8.28893C7.04693 8.28893 6.27395 7.52345 6.27395 6.57036C6.27395 5.61726 7.03943 4.85178 7.99252 4.85178C8.94562 4.85178 9.7111 5.61726 9.7111 6.57036C9.7111 7.52345 8.94562 8.28893 7.99252 8.28893Z" fill="${fill}"/>
|
|
1810
|
+
</svg>`.trim();
|
|
1811
|
+
return `data:image/svg+xml;charset=utf-8,${svg}`;
|
|
1978
1812
|
};
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1813
|
+
class AutocompleteUI {
|
|
1814
|
+
// create a new AutocompleteUI instance
|
|
1815
|
+
static createAutocomplete(autocompleteOptions) {
|
|
1816
|
+
return new AutocompleteUI(autocompleteOptions);
|
|
1817
|
+
}
|
|
1818
|
+
constructor(options = {}) {
|
|
1982
1819
|
this.config = Object.assign({}, defaultAutocompleteOptions, options);
|
|
1983
1820
|
// setup state
|
|
1984
1821
|
this.isOpen = false;
|
|
@@ -1995,11 +1832,11 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
1995
1832
|
this.near = options.near;
|
|
1996
1833
|
}
|
|
1997
1834
|
else {
|
|
1998
|
-
this.near =
|
|
1835
|
+
this.near = `${options.near.latitude},${options.near.longitude}`;
|
|
1999
1836
|
}
|
|
2000
1837
|
}
|
|
2001
1838
|
// get container element
|
|
2002
|
-
|
|
1839
|
+
let containerEL;
|
|
2003
1840
|
if (typeof this.config.container === 'string') { // lookup container element by ID
|
|
2004
1841
|
containerEL = document.getElementById(this.config.container);
|
|
2005
1842
|
}
|
|
@@ -2007,7 +1844,7 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2007
1844
|
containerEL = this.config.container; // HTMLElement
|
|
2008
1845
|
}
|
|
2009
1846
|
if (!containerEL) {
|
|
2010
|
-
throw new RadarAutocompleteContainerNotFound(
|
|
1847
|
+
throw new RadarAutocompleteContainerNotFound(`Could not find container element: ${this.config.container}`);
|
|
2011
1848
|
}
|
|
2012
1849
|
this.container = containerEL;
|
|
2013
1850
|
// create wrapper for input and result list
|
|
@@ -2036,7 +1873,7 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2036
1873
|
this.inputField.type = 'text';
|
|
2037
1874
|
this.inputField.disabled = this.config.disabled;
|
|
2038
1875
|
// search icon
|
|
2039
|
-
|
|
1876
|
+
const searchIcon = document.createElement('div');
|
|
2040
1877
|
searchIcon.classList.add(CLASSNAMES.SEARCH_ICON);
|
|
2041
1878
|
// append to DOM
|
|
2042
1879
|
this.wrapper.appendChild(this.inputField);
|
|
@@ -2050,123 +1887,104 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2050
1887
|
if (this.config.hideResultsOnBlur) {
|
|
2051
1888
|
this.inputField.addEventListener('blur', this.close.bind(this), true);
|
|
2052
1889
|
}
|
|
2053
|
-
Logger.debug(
|
|
1890
|
+
Logger.debug(`AutocompleteUI iniailized with options: ${JSON.stringify(this.config)}`);
|
|
2054
1891
|
}
|
|
2055
|
-
|
|
2056
|
-
AutocompleteUI.createAutocomplete = function (autocompleteOptions) {
|
|
2057
|
-
return new AutocompleteUI(autocompleteOptions);
|
|
2058
|
-
};
|
|
2059
|
-
AutocompleteUI.prototype.handleInput = function () {
|
|
2060
|
-
var _this = this;
|
|
1892
|
+
handleInput() {
|
|
2061
1893
|
// Fetch autocomplete results and display them
|
|
2062
|
-
|
|
1894
|
+
const query = this.inputField.value;
|
|
2063
1895
|
if (query.length < this.config.minCharacters) {
|
|
2064
1896
|
return;
|
|
2065
1897
|
}
|
|
2066
1898
|
this.debouncedFetchResults(query)
|
|
2067
|
-
.then(
|
|
2068
|
-
|
|
1899
|
+
.then((results) => {
|
|
1900
|
+
const onResults = this.config.onResults;
|
|
2069
1901
|
if (onResults) {
|
|
2070
1902
|
onResults(results);
|
|
2071
1903
|
}
|
|
2072
|
-
|
|
1904
|
+
this.displayResults(results);
|
|
2073
1905
|
})
|
|
2074
|
-
.catch(
|
|
2075
|
-
Logger.warn(
|
|
2076
|
-
|
|
1906
|
+
.catch((error) => {
|
|
1907
|
+
Logger.warn(`Autocomplete ui error: ${error.message}`);
|
|
1908
|
+
const onError = this.config.onError;
|
|
2077
1909
|
if (onError) {
|
|
2078
1910
|
onError(error);
|
|
2079
1911
|
}
|
|
2080
1912
|
});
|
|
2081
|
-
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
return function () {
|
|
2088
|
-
var args = [];
|
|
2089
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2090
|
-
args[_i] = arguments[_i];
|
|
2091
|
-
}
|
|
1913
|
+
}
|
|
1914
|
+
debounce(fn, delay) {
|
|
1915
|
+
let timeoutId;
|
|
1916
|
+
let resolveFn;
|
|
1917
|
+
let rejectFn;
|
|
1918
|
+
return (...args) => {
|
|
2092
1919
|
clearTimeout(timeoutId);
|
|
2093
|
-
timeoutId = setTimeout(
|
|
2094
|
-
|
|
1920
|
+
timeoutId = setTimeout(() => {
|
|
1921
|
+
const result = fn.apply(this, args);
|
|
2095
1922
|
if (result instanceof Promise) {
|
|
2096
1923
|
result
|
|
2097
|
-
.then(
|
|
1924
|
+
.then((value) => {
|
|
2098
1925
|
if (resolveFn) {
|
|
2099
1926
|
resolveFn(value);
|
|
2100
1927
|
}
|
|
2101
1928
|
})
|
|
2102
|
-
.catch(
|
|
1929
|
+
.catch((error) => {
|
|
2103
1930
|
if (rejectFn) {
|
|
2104
1931
|
rejectFn(error);
|
|
2105
1932
|
}
|
|
2106
1933
|
});
|
|
2107
1934
|
}
|
|
2108
1935
|
}, delay);
|
|
2109
|
-
return new Promise(
|
|
1936
|
+
return new Promise((resolve, reject) => {
|
|
2110
1937
|
resolveFn = resolve;
|
|
2111
1938
|
rejectFn = reject;
|
|
2112
1939
|
});
|
|
2113
1940
|
};
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
onRequest(params);
|
|
2135
|
-
}
|
|
2136
|
-
return [4 /*yield*/, SearchAPI.autocomplete(params)];
|
|
2137
|
-
case 1:
|
|
2138
|
-
addresses = (_b.sent()).addresses;
|
|
2139
|
-
return [2 /*return*/, addresses];
|
|
2140
|
-
}
|
|
2141
|
-
});
|
|
1941
|
+
}
|
|
1942
|
+
fetchResults(query) {
|
|
1943
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1944
|
+
const { limit, layers, countryCode, expandUnits, mailable, onRequest } = this.config;
|
|
1945
|
+
const params = {
|
|
1946
|
+
query,
|
|
1947
|
+
limit,
|
|
1948
|
+
layers,
|
|
1949
|
+
countryCode,
|
|
1950
|
+
expandUnits,
|
|
1951
|
+
mailable,
|
|
1952
|
+
};
|
|
1953
|
+
if (this.near) {
|
|
1954
|
+
params.near = this.near;
|
|
1955
|
+
}
|
|
1956
|
+
if (onRequest) {
|
|
1957
|
+
onRequest(params);
|
|
1958
|
+
}
|
|
1959
|
+
const { addresses } = yield SearchAPI.autocomplete(params);
|
|
1960
|
+
return addresses;
|
|
2142
1961
|
});
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
var _this = this;
|
|
1962
|
+
}
|
|
1963
|
+
displayResults(results) {
|
|
2146
1964
|
// Clear the previous results
|
|
2147
1965
|
this.clearResultsList();
|
|
2148
1966
|
this.results = results;
|
|
2149
|
-
|
|
1967
|
+
let marker;
|
|
2150
1968
|
if (this.config.showMarkers) {
|
|
2151
1969
|
marker = document.createElement('img');
|
|
2152
1970
|
marker.classList.add(CLASSNAMES.RESULTS_MARKER);
|
|
2153
1971
|
marker.setAttribute('src', getMarkerIcon(this.config.markerColor));
|
|
2154
1972
|
}
|
|
2155
1973
|
// Create and append list items for each result
|
|
2156
|
-
results.forEach(
|
|
2157
|
-
|
|
1974
|
+
results.forEach((result, index) => {
|
|
1975
|
+
const li = document.createElement('li');
|
|
2158
1976
|
li.classList.add(CLASSNAMES.RESULTS_ITEM);
|
|
2159
1977
|
// construct result with bolded label
|
|
2160
|
-
|
|
1978
|
+
let listContent;
|
|
2161
1979
|
if (result.formattedAddress.includes(result.addressLabel) && result.layer !== 'postalCode') {
|
|
2162
1980
|
// if addressLabel is contained in the formatted address, bold the address label
|
|
2163
|
-
|
|
1981
|
+
const regex = new RegExp(`(${result.addressLabel}),?`);
|
|
2164
1982
|
listContent = result.formattedAddress.replace(regex, '<b>$1</b>');
|
|
2165
1983
|
}
|
|
2166
1984
|
else {
|
|
2167
1985
|
// otherwise append the address or place label to formatted address
|
|
2168
|
-
|
|
2169
|
-
listContent =
|
|
1986
|
+
const label = result.placeLabel || result.addressLabel;
|
|
1987
|
+
listContent = `<b>${label}</b> ${result.formattedAddress}`;
|
|
2170
1988
|
}
|
|
2171
1989
|
li.innerHTML = listContent;
|
|
2172
1990
|
// prepend marker if enabled
|
|
@@ -2174,60 +1992,59 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2174
1992
|
li.prepend(marker.cloneNode());
|
|
2175
1993
|
}
|
|
2176
1994
|
// add click handler to each result, use mousedown to fire before blur event
|
|
2177
|
-
li.addEventListener('mousedown',
|
|
2178
|
-
|
|
1995
|
+
li.addEventListener('mousedown', () => {
|
|
1996
|
+
this.select(index);
|
|
2179
1997
|
});
|
|
2180
|
-
|
|
1998
|
+
this.resultsList.appendChild(li);
|
|
2181
1999
|
});
|
|
2182
2000
|
this.open();
|
|
2183
2001
|
if (results.length > 0) {
|
|
2184
|
-
|
|
2002
|
+
const link = document.createElement('a');
|
|
2185
2003
|
link.href = 'https://radar.com?ref=powered_by_radar';
|
|
2186
2004
|
link.target = '_blank';
|
|
2187
2005
|
this.poweredByLink = link;
|
|
2188
|
-
|
|
2006
|
+
const poweredByText = document.createElement('span');
|
|
2189
2007
|
poweredByText.textContent = 'Powered by';
|
|
2190
2008
|
link.appendChild(poweredByText);
|
|
2191
|
-
|
|
2009
|
+
const radarLogo = document.createElement('span');
|
|
2192
2010
|
radarLogo.id = 'radar-powered-logo';
|
|
2193
2011
|
link.appendChild(radarLogo);
|
|
2194
|
-
|
|
2012
|
+
const poweredByContainer = document.createElement('div');
|
|
2195
2013
|
poweredByContainer.classList.add(CLASSNAMES.POWERED_BY_RADAR);
|
|
2196
2014
|
poweredByContainer.appendChild(link);
|
|
2197
2015
|
this.resultsList.appendChild(poweredByContainer);
|
|
2198
2016
|
}
|
|
2199
2017
|
else {
|
|
2200
|
-
|
|
2018
|
+
const noResultsText = document.createElement('div');
|
|
2201
2019
|
noResultsText.classList.add(CLASSNAMES.NO_RESULTS);
|
|
2202
2020
|
noResultsText.textContent = 'No results';
|
|
2203
2021
|
this.resultsList.appendChild(noResultsText);
|
|
2204
2022
|
}
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2023
|
+
}
|
|
2024
|
+
open() {
|
|
2207
2025
|
if (this.isOpen) {
|
|
2208
2026
|
return;
|
|
2209
2027
|
}
|
|
2210
2028
|
this.wrapper.setAttribute(ARIA.EXPANDED, 'true');
|
|
2211
2029
|
this.resultsList.removeAttribute('hidden');
|
|
2212
2030
|
this.isOpen = true;
|
|
2213
|
-
}
|
|
2214
|
-
|
|
2215
|
-
var _this = this;
|
|
2031
|
+
}
|
|
2032
|
+
close(e) {
|
|
2216
2033
|
if (!this.isOpen) {
|
|
2217
2034
|
return;
|
|
2218
2035
|
}
|
|
2219
2036
|
// run this code async to allow link click to propagate before blur
|
|
2220
2037
|
// (add 100ms delay if closed from link click)
|
|
2221
|
-
|
|
2222
|
-
setTimeout(
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2038
|
+
const linkClick = e && (e.relatedTarget === this.poweredByLink);
|
|
2039
|
+
setTimeout(() => {
|
|
2040
|
+
this.wrapper.removeAttribute(ARIA.EXPANDED);
|
|
2041
|
+
this.resultsList.setAttribute('hidden', '');
|
|
2042
|
+
this.highlightedIndex = -1;
|
|
2043
|
+
this.isOpen = false;
|
|
2044
|
+
this.clearResultsList();
|
|
2228
2045
|
}, linkClick ? 100 : 0);
|
|
2229
|
-
}
|
|
2230
|
-
|
|
2046
|
+
}
|
|
2047
|
+
goTo(index) {
|
|
2231
2048
|
if (!this.isOpen || !this.results.length) {
|
|
2232
2049
|
return;
|
|
2233
2050
|
}
|
|
@@ -2238,7 +2055,7 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2238
2055
|
else if (index >= this.results.length) {
|
|
2239
2056
|
index = 0;
|
|
2240
2057
|
}
|
|
2241
|
-
|
|
2058
|
+
const resultItems = this.resultsList.getElementsByTagName('li');
|
|
2242
2059
|
if (this.highlightedIndex > -1) {
|
|
2243
2060
|
// clear class names on previously highlighted item
|
|
2244
2061
|
resultItems[this.highlightedIndex].classList.remove(CLASSNAMES.SELECTED_ITEM);
|
|
@@ -2246,10 +2063,10 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2246
2063
|
// add class name to newly highlighted item
|
|
2247
2064
|
resultItems[index].classList.add(CLASSNAMES.SELECTED_ITEM);
|
|
2248
2065
|
this.highlightedIndex = index;
|
|
2249
|
-
}
|
|
2250
|
-
|
|
2066
|
+
}
|
|
2067
|
+
handleKeyboardNavigation(event) {
|
|
2251
2068
|
// fallback to deprecated "keyCode" if event.code not set
|
|
2252
|
-
|
|
2069
|
+
const code = event.code !== undefined ? event.code : event.keyCode;
|
|
2253
2070
|
// allow event to propagate if result list is not open
|
|
2254
2071
|
if (!this.isOpen) {
|
|
2255
2072
|
return;
|
|
@@ -2279,41 +2096,41 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2279
2096
|
this.close();
|
|
2280
2097
|
break;
|
|
2281
2098
|
}
|
|
2282
|
-
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2099
|
+
}
|
|
2100
|
+
select(index) {
|
|
2101
|
+
const result = this.results[index];
|
|
2285
2102
|
if (!result) {
|
|
2286
|
-
Logger.warn(
|
|
2103
|
+
Logger.warn(`No autocomplete result found at index: ${index}`);
|
|
2287
2104
|
return;
|
|
2288
2105
|
}
|
|
2289
|
-
|
|
2106
|
+
let inputValue;
|
|
2290
2107
|
if (result.formattedAddress.includes(result.addressLabel)) {
|
|
2291
2108
|
inputValue = result.formattedAddress;
|
|
2292
2109
|
}
|
|
2293
2110
|
else {
|
|
2294
|
-
|
|
2295
|
-
inputValue =
|
|
2111
|
+
const label = result.placeLabel || result.addressLabel;
|
|
2112
|
+
inputValue = `${label}, ${result.formattedAddress}`;
|
|
2296
2113
|
}
|
|
2297
2114
|
this.inputField.value = inputValue;
|
|
2298
|
-
|
|
2115
|
+
const onSelection = this.config.onSelection;
|
|
2299
2116
|
if (onSelection) {
|
|
2300
2117
|
onSelection(result);
|
|
2301
2118
|
}
|
|
2302
2119
|
// clear results list
|
|
2303
2120
|
this.close();
|
|
2304
|
-
}
|
|
2305
|
-
|
|
2121
|
+
}
|
|
2122
|
+
clearResultsList() {
|
|
2306
2123
|
this.resultsList.innerHTML = '';
|
|
2307
2124
|
this.results = [];
|
|
2308
|
-
}
|
|
2125
|
+
}
|
|
2309
2126
|
// remove elements from DOM
|
|
2310
|
-
|
|
2127
|
+
remove() {
|
|
2311
2128
|
Logger.debug('AutocompleteUI removed.');
|
|
2312
2129
|
this.inputField.remove();
|
|
2313
2130
|
this.resultsList.remove();
|
|
2314
2131
|
this.wrapper.remove();
|
|
2315
|
-
}
|
|
2316
|
-
|
|
2132
|
+
}
|
|
2133
|
+
setNear(near) {
|
|
2317
2134
|
if (near === undefined || near === null) {
|
|
2318
2135
|
this.near = undefined;
|
|
2319
2136
|
}
|
|
@@ -2321,78 +2138,78 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2321
2138
|
this.near = near;
|
|
2322
2139
|
}
|
|
2323
2140
|
else {
|
|
2324
|
-
this.near =
|
|
2141
|
+
this.near = `${near.latitude},${near.longitude}`;
|
|
2325
2142
|
}
|
|
2326
2143
|
return this;
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2144
|
+
}
|
|
2145
|
+
setPlaceholder(placeholder) {
|
|
2329
2146
|
this.config.placeholder = placeholder;
|
|
2330
2147
|
this.inputField.placeholder = placeholder;
|
|
2331
2148
|
return this;
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2149
|
+
}
|
|
2150
|
+
setDisabled(disabled) {
|
|
2334
2151
|
this.config.disabled = disabled;
|
|
2335
2152
|
this.inputField.disabled = disabled;
|
|
2336
2153
|
return this;
|
|
2337
|
-
}
|
|
2338
|
-
|
|
2154
|
+
}
|
|
2155
|
+
setResponsive(responsive) {
|
|
2339
2156
|
this.config.responsive = responsive;
|
|
2340
2157
|
setWidth(this.wrapper, this.config);
|
|
2341
2158
|
return this;
|
|
2342
|
-
}
|
|
2343
|
-
|
|
2159
|
+
}
|
|
2160
|
+
setWidth(width) {
|
|
2344
2161
|
this.config.width = width;
|
|
2345
2162
|
setWidth(this.wrapper, this.config);
|
|
2346
2163
|
return this;
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2164
|
+
}
|
|
2165
|
+
setMaxHeight(height) {
|
|
2349
2166
|
this.config.maxHeight = height;
|
|
2350
2167
|
setHeight(this.resultsList, this.config);
|
|
2351
2168
|
return this;
|
|
2352
|
-
}
|
|
2353
|
-
|
|
2169
|
+
}
|
|
2170
|
+
setMinCharacters(minCharacters) {
|
|
2354
2171
|
this.config.minCharacters = minCharacters;
|
|
2355
2172
|
this.config.threshold = minCharacters;
|
|
2356
2173
|
return this;
|
|
2357
|
-
}
|
|
2358
|
-
|
|
2174
|
+
}
|
|
2175
|
+
setLimit(limit) {
|
|
2359
2176
|
this.config.limit = limit;
|
|
2360
2177
|
return this;
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2178
|
+
}
|
|
2179
|
+
setShowMarkers(showMarkers) {
|
|
2363
2180
|
this.config.showMarkers = showMarkers;
|
|
2364
2181
|
if (showMarkers) {
|
|
2365
|
-
|
|
2182
|
+
const marker = document.createElement('img');
|
|
2366
2183
|
marker.classList.add(CLASSNAMES.RESULTS_MARKER);
|
|
2367
2184
|
marker.setAttribute('src', getMarkerIcon(this.config.markerColor));
|
|
2368
|
-
|
|
2369
|
-
for (
|
|
2370
|
-
|
|
2185
|
+
const resultItems = this.resultsList.getElementsByTagName('li');
|
|
2186
|
+
for (let i = 0; i < resultItems.length; i++) {
|
|
2187
|
+
const currentMarker = resultItems[i].getElementsByClassName(CLASSNAMES.RESULTS_MARKER)[0];
|
|
2371
2188
|
if (!currentMarker) {
|
|
2372
2189
|
resultItems[i].prepend(marker.cloneNode());
|
|
2373
2190
|
}
|
|
2374
2191
|
}
|
|
2375
2192
|
}
|
|
2376
2193
|
else {
|
|
2377
|
-
|
|
2378
|
-
for (
|
|
2379
|
-
|
|
2194
|
+
const resultItems = this.resultsList.getElementsByTagName('li');
|
|
2195
|
+
for (let i = 0; i < resultItems.length; i++) {
|
|
2196
|
+
const marker = resultItems[i].getElementsByClassName(CLASSNAMES.RESULTS_MARKER)[0];
|
|
2380
2197
|
if (marker) {
|
|
2381
2198
|
marker.remove();
|
|
2382
2199
|
}
|
|
2383
2200
|
}
|
|
2384
2201
|
}
|
|
2385
2202
|
return this;
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2203
|
+
}
|
|
2204
|
+
setMarkerColor(color) {
|
|
2388
2205
|
this.config.markerColor = color;
|
|
2389
|
-
|
|
2390
|
-
for (
|
|
2206
|
+
const marker = this.resultsList.getElementsByClassName(CLASSNAMES.RESULTS_MARKER);
|
|
2207
|
+
for (let i = 0; i < marker.length; i++) {
|
|
2391
2208
|
marker[i].setAttribute('src', getMarkerIcon(color));
|
|
2392
2209
|
}
|
|
2393
2210
|
return this;
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2211
|
+
}
|
|
2212
|
+
setHideResultsOnBlur(hideResultsOnBlur) {
|
|
2396
2213
|
this.config.hideResultsOnBlur = hideResultsOnBlur;
|
|
2397
2214
|
if (hideResultsOnBlur) {
|
|
2398
2215
|
this.inputField.addEventListener('blur', this.close.bind(this), true);
|
|
@@ -2401,37 +2218,25 @@ var AutocompleteUI = /** @class */ (function () {
|
|
|
2401
2218
|
this.inputField.removeEventListener('blur', this.close.bind(this), true);
|
|
2402
2219
|
}
|
|
2403
2220
|
return this;
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
}());
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2407
2223
|
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
maplibregl: MapUI.getMapLibre(),
|
|
2425
|
-
map: MapUI.createMap,
|
|
2426
|
-
marker: MapUI.createMarker,
|
|
2427
|
-
autocomplete: AutocompleteUI.createAutocomplete,
|
|
2428
|
-
};
|
|
2429
|
-
},
|
|
2430
|
-
enumerable: false,
|
|
2431
|
-
configurable: true
|
|
2432
|
-
});
|
|
2433
|
-
Radar.initialize = function (publishableKey, options) {
|
|
2434
|
-
if (options === void 0) { options = {}; }
|
|
2224
|
+
const isSecretKey = (key) => (key.includes('_sk_'));
|
|
2225
|
+
const isLiveKey = (key) => (key.includes('_live_'));
|
|
2226
|
+
class Radar {
|
|
2227
|
+
static get VERSION() {
|
|
2228
|
+
return SDK_VERSION;
|
|
2229
|
+
}
|
|
2230
|
+
// "ui" namespace
|
|
2231
|
+
static get ui() {
|
|
2232
|
+
return {
|
|
2233
|
+
maplibregl: MapUI.getMapLibre(),
|
|
2234
|
+
map: MapUI.createMap,
|
|
2235
|
+
marker: MapUI.createMarker,
|
|
2236
|
+
autocomplete: AutocompleteUI.createAutocomplete,
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
static initialize(publishableKey, options = {}) {
|
|
2435
2240
|
if (!publishableKey) {
|
|
2436
2241
|
throw new RadarPublishableKeyError('Publishable key required in initialization.');
|
|
2437
2242
|
}
|
|
@@ -2439,128 +2244,125 @@ var Radar = /** @class */ (function () {
|
|
|
2439
2244
|
throw new RadarPublishableKeyError('Secret keys are not allowed. Please use your Radar publishable key.');
|
|
2440
2245
|
}
|
|
2441
2246
|
// store settings in global config
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
publishableKey
|
|
2447
|
-
live
|
|
2448
|
-
logLevel
|
|
2449
|
-
debug
|
|
2247
|
+
const live = isLiveKey(publishableKey);
|
|
2248
|
+
const logLevel = live ? 'error' : 'info';
|
|
2249
|
+
const debug = !live;
|
|
2250
|
+
const radarOptions = Object.assign(Config.defaultOptions, {
|
|
2251
|
+
publishableKey,
|
|
2252
|
+
live,
|
|
2253
|
+
logLevel,
|
|
2254
|
+
debug,
|
|
2450
2255
|
}, options);
|
|
2451
2256
|
Config.setup(radarOptions);
|
|
2452
|
-
Logger.info(
|
|
2257
|
+
Logger.info(`initialized with ${live ? 'live' : 'test'} publishableKey.`);
|
|
2453
2258
|
if (options.debug) {
|
|
2454
|
-
Logger.info(
|
|
2259
|
+
Logger.info(`using options: ${JSON.stringify(options)}`);
|
|
2455
2260
|
}
|
|
2456
2261
|
// NOTE(jasonl): this allows us to run jest tests
|
|
2457
2262
|
// without having to mock the ConfigAPI.getConfig call
|
|
2458
2263
|
if (!(window === null || window === void 0 ? void 0 : window.RADAR_TEST_ENV)) {
|
|
2459
2264
|
ConfigAPI.getConfig();
|
|
2460
2265
|
}
|
|
2461
|
-
}
|
|
2462
|
-
|
|
2266
|
+
}
|
|
2267
|
+
static clear() {
|
|
2463
2268
|
Config.clear();
|
|
2464
|
-
}
|
|
2269
|
+
}
|
|
2465
2270
|
///////////////////////
|
|
2466
2271
|
// geofencing platform
|
|
2467
2272
|
///////////////////////
|
|
2468
|
-
|
|
2273
|
+
static setUserId(userId) {
|
|
2469
2274
|
if (!userId) {
|
|
2470
2275
|
Storage.removeItem(Storage.USER_ID);
|
|
2471
2276
|
return;
|
|
2472
2277
|
}
|
|
2473
2278
|
Storage.setItem(Storage.USER_ID, String(userId).trim());
|
|
2474
|
-
}
|
|
2475
|
-
|
|
2279
|
+
}
|
|
2280
|
+
static setDescription(description) {
|
|
2476
2281
|
if (!description) {
|
|
2477
2282
|
Storage.removeItem(Storage.DESCRIPTION);
|
|
2478
2283
|
return;
|
|
2479
2284
|
}
|
|
2480
2285
|
Storage.setItem(Storage.DESCRIPTION, String(description).trim());
|
|
2481
|
-
}
|
|
2482
|
-
|
|
2286
|
+
}
|
|
2287
|
+
static setMetadata(metadata) {
|
|
2483
2288
|
if (!metadata) {
|
|
2484
2289
|
Storage.removeItem(Storage.METADATA);
|
|
2485
2290
|
return;
|
|
2486
2291
|
}
|
|
2487
2292
|
Storage.setItem(Storage.METADATA, JSON.stringify(metadata));
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2293
|
+
}
|
|
2294
|
+
static getLocation() {
|
|
2490
2295
|
return Navigator.getCurrentPosition();
|
|
2491
|
-
}
|
|
2492
|
-
|
|
2493
|
-
if (params === void 0) { params = {}; }
|
|
2296
|
+
}
|
|
2297
|
+
static trackOnce(params = {}) {
|
|
2494
2298
|
try {
|
|
2495
2299
|
return TrackAPI.trackOnce(params);
|
|
2496
2300
|
}
|
|
2497
2301
|
finally {
|
|
2498
2302
|
ConfigAPI.getConfig(params); // call with updated permissions
|
|
2499
2303
|
}
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
|
-
if (params === void 0) { params = {}; }
|
|
2304
|
+
}
|
|
2305
|
+
static trackVerified(params = {}) {
|
|
2503
2306
|
return VerifyAPI.trackVerified(params);
|
|
2504
|
-
}
|
|
2505
|
-
|
|
2307
|
+
}
|
|
2308
|
+
static getContext(params) {
|
|
2506
2309
|
return ContextAPI.getContext(params);
|
|
2507
|
-
}
|
|
2508
|
-
|
|
2310
|
+
}
|
|
2311
|
+
static setTripOptions(tripOptions) {
|
|
2509
2312
|
TripsAPI.setTripOptions(tripOptions);
|
|
2510
|
-
}
|
|
2511
|
-
|
|
2313
|
+
}
|
|
2314
|
+
static clearTripOptions() {
|
|
2512
2315
|
TripsAPI.clearTripOptions();
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2316
|
+
}
|
|
2317
|
+
static getTripOptions() {
|
|
2515
2318
|
return TripsAPI.getTripOptions();
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2319
|
+
}
|
|
2320
|
+
static startTrip(tripOptions) {
|
|
2518
2321
|
return TripsAPI.startTrip(tripOptions);
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2322
|
+
}
|
|
2323
|
+
static updateTrip(tripOptions) {
|
|
2521
2324
|
return TripsAPI.updateTrip(tripOptions);
|
|
2522
|
-
}
|
|
2523
|
-
|
|
2325
|
+
}
|
|
2326
|
+
static completeTrip() {
|
|
2524
2327
|
return TripsAPI.completeTrip();
|
|
2525
|
-
}
|
|
2526
|
-
|
|
2328
|
+
}
|
|
2329
|
+
static cancelTrip() {
|
|
2527
2330
|
return TripsAPI.cancelTrip();
|
|
2528
|
-
}
|
|
2529
|
-
|
|
2331
|
+
}
|
|
2332
|
+
static logConversion(params) {
|
|
2530
2333
|
return ConversionsAPI.logConversion(params);
|
|
2531
|
-
}
|
|
2334
|
+
}
|
|
2532
2335
|
/////////////////
|
|
2533
2336
|
// maps platform
|
|
2534
2337
|
/////////////////
|
|
2535
|
-
|
|
2338
|
+
static forwardGeocode(params) {
|
|
2536
2339
|
return Geocoding.forwardGeocode(params);
|
|
2537
|
-
}
|
|
2538
|
-
|
|
2340
|
+
}
|
|
2341
|
+
static reverseGeocode(params) {
|
|
2539
2342
|
return Geocoding.reverseGeocode(params);
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2343
|
+
}
|
|
2344
|
+
static ipGeocode() {
|
|
2542
2345
|
return Geocoding.ipGeocode();
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2346
|
+
}
|
|
2347
|
+
static autocomplete(params) {
|
|
2545
2348
|
return SearchAPI.autocomplete(params);
|
|
2546
|
-
}
|
|
2547
|
-
|
|
2349
|
+
}
|
|
2350
|
+
static searchGeofences(params) {
|
|
2548
2351
|
return SearchAPI.searchGeofences(params);
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2352
|
+
}
|
|
2353
|
+
static searchPlaces(params) {
|
|
2551
2354
|
return SearchAPI.searchPlaces(params);
|
|
2552
|
-
}
|
|
2553
|
-
|
|
2355
|
+
}
|
|
2356
|
+
static validateAddress(params) {
|
|
2554
2357
|
return AddressesAPI.validateAddress(params);
|
|
2555
|
-
}
|
|
2556
|
-
|
|
2358
|
+
}
|
|
2359
|
+
static distance(params) {
|
|
2557
2360
|
return RoutingAPI.distance(params);
|
|
2558
|
-
}
|
|
2559
|
-
|
|
2361
|
+
}
|
|
2362
|
+
static matrix(params) {
|
|
2560
2363
|
return RoutingAPI.matrix(params);
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
}());
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2564
2366
|
|
|
2565
2367
|
export { Radar as default };
|
|
2566
2368
|
//# sourceMappingURL=radar.js.map
|