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.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radar.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"radar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -344,15 +344,20 @@ export interface RadarSearchGeofencesParams {
|
|
|
344
344
|
export interface RadarSearchGeofencesResponse extends RadarResponse {
|
|
345
345
|
geofences: RadarGeofence[];
|
|
346
346
|
}
|
|
347
|
-
export interface RadarMapOptions extends maplibregl.MapOptions {
|
|
348
|
-
|
|
347
|
+
export interface RadarMapOptions extends Omit<maplibregl.MapOptions, 'transformRequest'> {
|
|
348
|
+
languages?: string[];
|
|
349
|
+
navigatorFallbackLanguage?: string;
|
|
350
|
+
}
|
|
351
|
+
export interface RadarMarkerImage {
|
|
352
|
+
url?: string;
|
|
353
|
+
radarMarkerId?: string;
|
|
354
|
+
width?: number;
|
|
355
|
+
height?: number;
|
|
349
356
|
}
|
|
350
|
-
export interface RadarMarkerOptions {
|
|
351
|
-
color?: string;
|
|
357
|
+
export interface RadarMarkerOptions extends maplibregl.MarkerOptions {
|
|
352
358
|
text?: string;
|
|
353
359
|
html?: string;
|
|
354
|
-
|
|
355
|
-
scale?: number;
|
|
360
|
+
image?: RadarMarkerImage;
|
|
356
361
|
}
|
|
357
362
|
export interface RadarAutocompleteUIOptions {
|
|
358
363
|
container: string | HTMLElement;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import maplibregl from 'maplibre-gl';
|
|
2
|
+
import RadarMarker from './RadarMarker';
|
|
3
|
+
import type { RadarMapOptions } from '../types';
|
|
4
|
+
declare class RadarMap extends maplibregl.Map {
|
|
5
|
+
_markers: RadarMarker[];
|
|
6
|
+
constructor(mapOptions: RadarMapOptions);
|
|
7
|
+
addMarker(marker: RadarMarker): void;
|
|
8
|
+
removeMarker(marker: RadarMarker): void;
|
|
9
|
+
getMarkers(): RadarMarker[];
|
|
10
|
+
}
|
|
11
|
+
export default RadarMap;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import maplibregl from 'maplibre-gl';
|
|
2
|
+
import type RadarMap from './RadarMap';
|
|
3
|
+
import type { RadarMarkerImage, RadarMarkerOptions } from '../types';
|
|
4
|
+
declare class RadarMarker extends maplibregl.Marker {
|
|
5
|
+
_map: RadarMap;
|
|
6
|
+
_image?: RadarMarkerImage;
|
|
7
|
+
constructor(markerOptions: RadarMarkerOptions);
|
|
8
|
+
addTo(map: RadarMap): this;
|
|
9
|
+
remove(): this;
|
|
10
|
+
}
|
|
11
|
+
export default RadarMarker;
|
package/dist/ui/map.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="mapbox__point-geometry" />
|
|
2
|
+
import RadarMap from './RadarMap';
|
|
3
|
+
import RadarMarker from './RadarMarker';
|
|
2
4
|
import type { RadarMapOptions, RadarMarkerOptions } from '../types';
|
|
3
5
|
declare class MapUI {
|
|
4
6
|
static getMapLibre(): {
|
|
@@ -45,7 +47,7 @@ declare class MapUI {
|
|
|
45
47
|
addProtocol(customProtocol: string, loadFn: (requestParameters: import("maplibre-gl").RequestParameters, callback: import("maplibre-gl").ResponseCallback<any>) => import("maplibre-gl").Cancelable): void;
|
|
46
48
|
removeProtocol(customProtocol: string): void;
|
|
47
49
|
};
|
|
48
|
-
static createMap(mapOptions: RadarMapOptions):
|
|
49
|
-
static createMarker(markerOptions?: RadarMarkerOptions):
|
|
50
|
+
static createMap(mapOptions: RadarMapOptions): RadarMap;
|
|
51
|
+
static createMarker(markerOptions?: RadarMarkerOptions): RadarMarker;
|
|
50
52
|
}
|
|
51
53
|
export default MapUI;
|
package/dist/util/_.d.ts
ADDED
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "4.
|
|
1
|
+
declare const _default: "4.3.0-beta.1";
|
|
2
2
|
export default _default;
|
package/package.json
CHANGED
package/src/api/track.ts
CHANGED
|
@@ -137,14 +137,14 @@ class TrackAPI {
|
|
|
137
137
|
}),
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
const
|
|
140
|
+
const token = await signJWT(payload, dk);
|
|
141
141
|
|
|
142
142
|
response = await Http.request({
|
|
143
143
|
host,
|
|
144
144
|
method: 'POST',
|
|
145
145
|
path: 'track',
|
|
146
146
|
data: {
|
|
147
|
-
token
|
|
147
|
+
token,
|
|
148
148
|
},
|
|
149
149
|
headers: {
|
|
150
150
|
'X-Radar-Body-Is-Token': 'true',
|
|
@@ -160,33 +160,33 @@ class TrackAPI {
|
|
|
160
160
|
sclVal,
|
|
161
161
|
cslVal,
|
|
162
162
|
};
|
|
163
|
-
}
|
|
164
163
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
let { user, events, token, expiresAt } = response;
|
|
165
|
+
const location = { latitude, longitude, accuracy };
|
|
166
|
+
let passed;
|
|
167
|
+
let expiresIn;
|
|
168
|
+
if (expiresAt) {
|
|
169
|
+
expiresAt = new Date(expiresAt);
|
|
170
|
+
passed = user?.fraud?.passed && user?.country?.passed && user?.state?.passed;
|
|
171
|
+
expiresIn = (expiresAt.getTime() - Date.now()) / 1000;
|
|
172
|
+
}
|
|
174
173
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
174
|
+
const trackRes = {
|
|
175
|
+
user,
|
|
176
|
+
events,
|
|
177
|
+
location,
|
|
178
|
+
token,
|
|
179
|
+
expiresAt,
|
|
180
|
+
expiresIn,
|
|
181
|
+
passed,
|
|
182
|
+
} as RadarTrackVerifiedResponse;
|
|
183
|
+
|
|
184
|
+
if (options.debug) {
|
|
185
|
+
trackRes.response = response;
|
|
186
|
+
}
|
|
188
187
|
|
|
189
|
-
|
|
188
|
+
return trackRes;
|
|
189
|
+
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
response = await Http.request({
|
package/src/http.ts
CHANGED
|
@@ -31,13 +31,17 @@ class Http {
|
|
|
31
31
|
path,
|
|
32
32
|
data,
|
|
33
33
|
host,
|
|
34
|
-
|
|
34
|
+
version,
|
|
35
|
+
headers = {},
|
|
36
|
+
responseType,
|
|
35
37
|
}: {
|
|
36
38
|
method: HttpMethod;
|
|
37
39
|
path: string;
|
|
38
40
|
data?: any;
|
|
39
41
|
host?: string;
|
|
42
|
+
version?: string;
|
|
40
43
|
headers?: Record<string, string>;
|
|
44
|
+
responseType?: XMLHttpRequestResponseType;
|
|
41
45
|
}) {
|
|
42
46
|
return new Promise<HttpResponse>((resolve, reject) => {
|
|
43
47
|
const options = Config.get();
|
|
@@ -51,8 +55,8 @@ class Http {
|
|
|
51
55
|
|
|
52
56
|
// setup request URL
|
|
53
57
|
const urlHost = host || options.host;
|
|
54
|
-
const
|
|
55
|
-
let url = `${urlHost}/${
|
|
58
|
+
const urlVersion = version || options.version;
|
|
59
|
+
let url = `${urlHost}/${urlVersion}/${path}`;
|
|
56
60
|
|
|
57
61
|
// remove undefined values from request data
|
|
58
62
|
let body: any = {};
|
|
@@ -78,32 +82,39 @@ class Http {
|
|
|
78
82
|
const xhr = new XMLHttpRequest();
|
|
79
83
|
xhr.open(method, url, true);
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// set passed custom headers if present
|
|
88
|
-
if (headers) {
|
|
89
|
-
Object.keys(headers).forEach(key => {
|
|
90
|
-
const val = headers[key];
|
|
91
|
-
xhr.setRequestHeader(key, val);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
85
|
+
const defaultHeaders = {
|
|
86
|
+
'Authorization': publishableKey,
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
'X-Radar-Device-Type': 'Web',
|
|
89
|
+
'X-Radar-SDK-Version': SDK_VERSION,
|
|
90
|
+
};
|
|
94
91
|
|
|
95
|
-
// set config
|
|
92
|
+
// set custom config headers if present
|
|
93
|
+
let configHeaders: { [key: string]: string } = {};
|
|
96
94
|
if (typeof options.getRequestHeaders === 'function') {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
configHeaders = options.getRequestHeaders();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// combines default headers with custom headers and config headers
|
|
99
|
+
const allHeaders = Object.assign(defaultHeaders, configHeaders, headers);
|
|
100
|
+
|
|
101
|
+
// set headers
|
|
102
|
+
Object.keys(allHeaders).forEach((key) => {
|
|
103
|
+
xhr.setRequestHeader(key, allHeaders[key]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (responseType) {
|
|
107
|
+
xhr.responseType = responseType;
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
xhr.onload = () => {
|
|
104
111
|
let response: any;
|
|
105
112
|
try {
|
|
106
|
-
|
|
113
|
+
if (xhr.responseType === 'blob') {
|
|
114
|
+
response = { code: xhr.status, data: xhr.response };
|
|
115
|
+
} else {
|
|
116
|
+
response = JSON.parse(xhr.response);
|
|
117
|
+
}
|
|
107
118
|
} catch (e) {
|
|
108
119
|
return reject(new RadarServerError(response));
|
|
109
120
|
}
|
|
@@ -152,7 +163,7 @@ class Http {
|
|
|
152
163
|
}
|
|
153
164
|
}
|
|
154
165
|
|
|
155
|
-
xhr.onerror = function() {
|
|
166
|
+
xhr.onerror = function () {
|
|
156
167
|
if (host && (host === 'http://localhost:52516' || host === 'https://radar-verify.com:52516')) {
|
|
157
168
|
reject(new RadarVerifyAppError());
|
|
158
169
|
} else {
|
|
@@ -160,7 +171,7 @@ class Http {
|
|
|
160
171
|
}
|
|
161
172
|
}
|
|
162
173
|
|
|
163
|
-
xhr.ontimeout = function() {
|
|
174
|
+
xhr.ontimeout = function () {
|
|
164
175
|
reject(new RadarVerifyAppError());
|
|
165
176
|
}
|
|
166
177
|
|
package/src/types.ts
CHANGED
|
@@ -459,16 +459,22 @@ export interface RadarSearchGeofencesResponse extends RadarResponse {
|
|
|
459
459
|
geofences: RadarGeofence[];
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
export interface RadarMapOptions extends maplibregl.MapOptions {
|
|
463
|
-
|
|
462
|
+
export interface RadarMapOptions extends Omit<maplibregl.MapOptions, 'transformRequest'> {
|
|
463
|
+
languages?: string[];
|
|
464
|
+
navigatorFallbackLanguage?: string;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export interface RadarMarkerImage {
|
|
468
|
+
url?: string;
|
|
469
|
+
radarMarkerId?: string;
|
|
470
|
+
width?: number;
|
|
471
|
+
height?: number;
|
|
464
472
|
}
|
|
465
473
|
|
|
466
|
-
export interface RadarMarkerOptions {
|
|
467
|
-
color?: string;
|
|
474
|
+
export interface RadarMarkerOptions extends maplibregl.MarkerOptions {
|
|
468
475
|
text?: string;
|
|
469
476
|
html?: string;
|
|
470
|
-
|
|
471
|
-
scale?: number;
|
|
477
|
+
image?: RadarMarkerImage;
|
|
472
478
|
}
|
|
473
479
|
|
|
474
480
|
export interface RadarAutocompleteUIOptions {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const RADAR_LOGO_URL = 'https://api.radar.io/maps/static/images/logo.svg';
|
|
2
|
+
|
|
3
|
+
class RadarLogoControl {
|
|
4
|
+
link: HTMLAnchorElement | undefined;
|
|
5
|
+
|
|
6
|
+
onAdd() {
|
|
7
|
+
const img = document.createElement('img');
|
|
8
|
+
img.src = RADAR_LOGO_URL;
|
|
9
|
+
|
|
10
|
+
this.link = document.createElement('a');
|
|
11
|
+
this.link.id = 'radar-map-logo';
|
|
12
|
+
this.link.href = 'https://radar.com?ref=powered_by_radar';
|
|
13
|
+
this.link.target = '_blank';
|
|
14
|
+
this.link.appendChild(img);
|
|
15
|
+
|
|
16
|
+
return this.link;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
onRemove() {
|
|
20
|
+
this.link?.remove();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default RadarLogoControl;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import maplibregl from 'maplibre-gl';
|
|
2
|
+
|
|
3
|
+
import RadarMarker from './RadarMarker';
|
|
4
|
+
import RadarLogoControl from './RadarLogoControl';
|
|
5
|
+
|
|
6
|
+
import Config from '../config';
|
|
7
|
+
import Logger from '../logger';
|
|
8
|
+
import SDK_VERSION from '../version';
|
|
9
|
+
|
|
10
|
+
import { transformMapStyle } from '../util/mapStyle';
|
|
11
|
+
|
|
12
|
+
import type { RadarOptions, RadarMapOptions } from '../types';
|
|
13
|
+
|
|
14
|
+
const DEFAULT_STYLE = 'radar-default-v1';
|
|
15
|
+
|
|
16
|
+
const RADAR_STYLES = [
|
|
17
|
+
'radar-default-v1',
|
|
18
|
+
'radar-light-v1',
|
|
19
|
+
'radar-dark-v1',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const defaultMapOptions: Partial<RadarMapOptions> = {
|
|
23
|
+
minZoom: 1,
|
|
24
|
+
maxZoom: 20,
|
|
25
|
+
attributionControl: false,
|
|
26
|
+
dragRotate: false,
|
|
27
|
+
touchPitch: false,
|
|
28
|
+
maplibreLogo: false,
|
|
29
|
+
navigatorFallbackLanguage: 'en',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const createStyleURL = (options: RadarOptions, style: string = DEFAULT_STYLE) => (
|
|
33
|
+
`${options.host}/maps/styles/${style}?publishableKey=${options.publishableKey}`
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// check if style is a Radar style or a custom style
|
|
37
|
+
const isRadarStyle = (style: string) => {
|
|
38
|
+
if (RADAR_STYLES.includes(style)) { // Radar built-in style
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (!/^(http:|https:)/.test(style)) { // Radar custom style (not a URL)
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// use formatted style URL if using one of Radar's out-of-the-box styles or is a Radar custom style
|
|
48
|
+
const getStyle = (options: RadarOptions, mapOptions: RadarMapOptions) => {
|
|
49
|
+
const style = mapOptions.style;
|
|
50
|
+
|
|
51
|
+
if (!style || (typeof style === 'string' && isRadarStyle(style))) {
|
|
52
|
+
return createStyleURL(options, style);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return mapOptions.style; // style object or URL
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
class RadarMap extends maplibregl.Map {
|
|
59
|
+
_markers: RadarMarker[] = [];
|
|
60
|
+
|
|
61
|
+
constructor(mapOptions: RadarMapOptions) {
|
|
62
|
+
const config = Config.get();
|
|
63
|
+
|
|
64
|
+
if (!config.publishableKey) {
|
|
65
|
+
Logger.warn('publishableKey not set. Call Radar.initialize() with key before creating a new map.');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// configure maplibre options
|
|
69
|
+
const style = getStyle(config, mapOptions);
|
|
70
|
+
const maplibreOptions: RadarMapOptions = Object.assign({},
|
|
71
|
+
defaultMapOptions,
|
|
72
|
+
mapOptions,
|
|
73
|
+
{ style },
|
|
74
|
+
);
|
|
75
|
+
Logger.debug(`initialize map with options: ${JSON.stringify(maplibreOptions)}`);
|
|
76
|
+
|
|
77
|
+
(maplibreOptions as maplibregl.MapOptions).transformRequest = (url, resourceType) => {
|
|
78
|
+
if (resourceType === 'Style' && isRadarStyle(url)) {
|
|
79
|
+
url = createStyleURL(config, url);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let headers = {
|
|
83
|
+
'Authorization': config.publishableKey,
|
|
84
|
+
'X-Radar-Device-Type': 'Web',
|
|
85
|
+
'X-Radar-SDK-Version': SDK_VERSION,
|
|
86
|
+
};
|
|
87
|
+
if (typeof config.getRequestHeaders === 'function') {
|
|
88
|
+
headers = Object.assign(headers, config.getRequestHeaders());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { url, headers };
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
super(maplibreOptions);
|
|
95
|
+
|
|
96
|
+
const container = this.getContainer();
|
|
97
|
+
if (!container.style.width && !container.style.height) {
|
|
98
|
+
Logger.warn('map container does not have a set "width" or "height"');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// add radar logo
|
|
102
|
+
const radarLogo = new RadarLogoControl();
|
|
103
|
+
this.addControl(radarLogo, 'bottom-left');
|
|
104
|
+
|
|
105
|
+
// add attribution
|
|
106
|
+
const attribution = new maplibregl.AttributionControl({ compact: false });
|
|
107
|
+
this.addControl(attribution, 'bottom-right');
|
|
108
|
+
|
|
109
|
+
// add zoom controls
|
|
110
|
+
const nav = new maplibregl.NavigationControl({ showCompass: false });
|
|
111
|
+
this.addControl(nav, 'bottom-right');
|
|
112
|
+
|
|
113
|
+
// handle map resize actions
|
|
114
|
+
const onResize = () => {
|
|
115
|
+
const attrib = document.querySelector('.maplibregl-ctrl-attrib');
|
|
116
|
+
if (attrib) {
|
|
117
|
+
const width = this.getContainer().clientWidth;
|
|
118
|
+
if (width < 380) {
|
|
119
|
+
attrib.classList.add('hidden');
|
|
120
|
+
} else {
|
|
121
|
+
attrib.classList.remove('hidden');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const onStyleLoad = (e: maplibregl.MapStyleDataEvent) => {
|
|
127
|
+
const styleJSON = (e as any).style?.stylesheet; // for some reason, style does not exist in the types
|
|
128
|
+
if (!styleJSON) {
|
|
129
|
+
Logger.warn('style data not available');
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// transform text-field expressions to use local language
|
|
134
|
+
const newStyleJSON = transformMapStyle(styleJSON, maplibreOptions);
|
|
135
|
+
this.setStyle(newStyleJSON);
|
|
136
|
+
};
|
|
137
|
+
this.on('resize', onResize);
|
|
138
|
+
this.on('load', onResize);
|
|
139
|
+
this.on('styledata', onStyleLoad);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
addMarker(marker: RadarMarker) {
|
|
143
|
+
this._markers.push(marker);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
removeMarker(marker: RadarMarker) {
|
|
147
|
+
this._markers = this._markers.filter((mapMarker: RadarMarker) => mapMarker !== marker);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getMarkers(): RadarMarker[] {
|
|
151
|
+
return this._markers;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export default RadarMap;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import maplibregl from 'maplibre-gl';
|
|
2
|
+
|
|
3
|
+
import Http from '../http';
|
|
4
|
+
import Logger from '../logger';
|
|
5
|
+
|
|
6
|
+
import type RadarMap from './RadarMap';
|
|
7
|
+
|
|
8
|
+
import type { RadarMarkerImage, RadarMarkerOptions } from '../types';
|
|
9
|
+
|
|
10
|
+
const defaultMarkerOptions: maplibregl.MarkerOptions = {
|
|
11
|
+
color: '#000257',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const fileExtensionToContentType: Record<string, string> = {
|
|
15
|
+
svg: 'image/svg+xml',
|
|
16
|
+
png: 'image/png',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const getFileExtension = (file: string): string => {
|
|
20
|
+
return file.split('.').pop() || '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const createImageElement = (options: RadarMarkerImage) => {
|
|
24
|
+
const element = document.createElement('img');
|
|
25
|
+
element.src = options.url!;
|
|
26
|
+
|
|
27
|
+
if (options.width) {
|
|
28
|
+
element.width = options.width;
|
|
29
|
+
}
|
|
30
|
+
if (options.height) {
|
|
31
|
+
element.height = options.height;
|
|
32
|
+
}
|
|
33
|
+
if (!options.width && !options.height) {
|
|
34
|
+
element.style.maxWidth = '64px';
|
|
35
|
+
element.style.maxHeight = '64px';
|
|
36
|
+
}
|
|
37
|
+
return element;
|
|
38
|
+
}
|
|
39
|
+
class RadarMarker extends maplibregl.Marker {
|
|
40
|
+
_map!: RadarMap;
|
|
41
|
+
_image?: RadarMarkerImage;
|
|
42
|
+
|
|
43
|
+
constructor(markerOptions: RadarMarkerOptions) {
|
|
44
|
+
const maplibreOptions: maplibregl.MarkerOptions = Object.assign({}, defaultMarkerOptions);
|
|
45
|
+
|
|
46
|
+
if (markerOptions.color) {
|
|
47
|
+
maplibreOptions.color = markerOptions.color;
|
|
48
|
+
}
|
|
49
|
+
if (markerOptions.element) {
|
|
50
|
+
maplibreOptions.element = markerOptions.element;
|
|
51
|
+
}
|
|
52
|
+
if (markerOptions.scale) {
|
|
53
|
+
maplibreOptions.scale = markerOptions.scale;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
super(maplibreOptions);
|
|
57
|
+
|
|
58
|
+
if (markerOptions.image) {
|
|
59
|
+
this._image = markerOptions.image;
|
|
60
|
+
|
|
61
|
+
const originalElement = this._element.cloneNode(true);
|
|
62
|
+
this._element.childNodes.forEach((child) => {
|
|
63
|
+
child.remove();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const onSuccess = (blob: Blob) => {
|
|
67
|
+
const markerObject = URL.createObjectURL(blob);
|
|
68
|
+
this._element.replaceChildren(createImageElement({ url: markerObject }));
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const onError = (err: any) => {
|
|
72
|
+
Logger.error(`Could not load marker: ${err.message} - falling back to default marker`);
|
|
73
|
+
this._element.replaceChildren(...Array.from(originalElement.childNodes));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (markerOptions.image.url) {
|
|
77
|
+
fetch(markerOptions.image.url)
|
|
78
|
+
.then(res => {
|
|
79
|
+
if (res.status === 200) {
|
|
80
|
+
res.blob()
|
|
81
|
+
.then(onSuccess)
|
|
82
|
+
.catch(onError);
|
|
83
|
+
} else {
|
|
84
|
+
onError(new Error(res.statusText));
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
.catch(onError)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (markerOptions.image.radarMarkerId) {
|
|
91
|
+
// fetch custom marker
|
|
92
|
+
Http.request({
|
|
93
|
+
method: 'GET',
|
|
94
|
+
version: 'maps',
|
|
95
|
+
path: `markers/${markerOptions.image.radarMarkerId}`,
|
|
96
|
+
responseType: 'blob',
|
|
97
|
+
})
|
|
98
|
+
.then(({ data }) => onSuccess(data))
|
|
99
|
+
.catch(onError);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// set popup text or HTML
|
|
104
|
+
if (markerOptions.text) {
|
|
105
|
+
const popup = new maplibregl.Popup({ offset: 35 }).setText(markerOptions.text);
|
|
106
|
+
this.setPopup(popup);
|
|
107
|
+
} else if (markerOptions.html) {
|
|
108
|
+
const popup = new maplibregl.Popup({ offset: 35 }).setHTML(markerOptions.html);
|
|
109
|
+
this.setPopup(popup);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
addTo(map: RadarMap) {
|
|
114
|
+
map.addMarker(this);
|
|
115
|
+
return super.addTo(map);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
remove() {
|
|
119
|
+
if (this._map) {
|
|
120
|
+
this._map.removeMarker(this);
|
|
121
|
+
}
|
|
122
|
+
return super.remove();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export default RadarMarker;
|