radar-sdk-js 5.0.0-beta.6 → 5.0.0-beta.7

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 CHANGED
@@ -57,7 +57,7 @@ Radar.initialize('prj_test_pk_...', {
57
57
  Add the following to your HTML:
58
58
 
59
59
  ```html
60
- <script src="https://js.radar.com/v5.0.0-beta.6/radar.min.js"></script>
60
+ <script src="https://js.radar.com/v5.0.0-beta.7/radar.min.js"></script>
61
61
 
62
62
  <script>
63
63
  Radar.initialize('prj_test_pk_...', {
@@ -138,7 +138,7 @@ the core SDK first, then any plugins you need:
138
138
  <link href="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.css" rel="stylesheet" />
139
139
  <link href="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.css" rel="stylesheet" />
140
140
 
141
- <script src="https://js.radar.com/v5.0.0-beta.6/radar.min.js"></script>
141
+ <script src="https://js.radar.com/v5.0.0-beta.7/radar.min.js"></script>
142
142
  <script src="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.min.js"></script>
143
143
  <script src="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.min.js"></script>
144
144
  <script src="https://js.radar.com/fraud/v5.0.0-beta.1/radar-fraud.min.js"></script>
@@ -155,7 +155,7 @@ by ID or element reference.
155
155
  <html>
156
156
  <head>
157
157
  <link href="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.css" rel="stylesheet" />
158
- <script src="https://js.radar.com/v5.0.0-beta.6/radar.min.js"></script>
158
+ <script src="https://js.radar.com/v5.0.0-beta.7/radar.min.js"></script>
159
159
  <script src="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.min.js"></script>
160
160
  </head>
161
161
 
@@ -182,7 +182,7 @@ by ID or element reference.
182
182
  <html>
183
183
  <head>
184
184
  <link href="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.css" rel="stylesheet" />
185
- <script src="https://js.radar.com/v5.0.0-beta.6/radar.min.js"></script>
185
+ <script src="https://js.radar.com/v5.0.0-beta.7/radar.min.js"></script>
186
186
  <script src="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.min.js"></script>
187
187
  </head>
188
188
 
@@ -215,7 +215,7 @@ are needed for geofencing.
215
215
  ```html
216
216
  <html>
217
217
  <head>
218
- <script src="https://js.radar.com/v5.0.0-beta.6/radar.min.js"></script>
218
+ <script src="https://js.radar.com/v5.0.0-beta.7/radar.min.js"></script>
219
219
  </head>
220
220
 
221
221
  <body>
@@ -1,10 +1,19 @@
1
- import type { RadarTrackParams } from '../types';
1
+ import type { RadarConfigResponse, RadarTrackParams } from '../types';
2
+ /** options for customizing the config request (e.g. host, headers) */
3
+ interface ConfigRequestOptions {
4
+ /** override the API host */
5
+ host?: string;
6
+ /** additional headers to include in the request */
7
+ headers?: Record<string, string>;
8
+ }
2
9
  /** @internal SDK configuration API for fetching remote config */
3
10
  declare class ConfigAPI {
4
11
  /**
5
- * fetch remote SDK configuration from the Radar API
12
+ * fetch remote SDK configuration from the Radar API. Generic so plugins can extend the response shape.
13
+ *
6
14
  * @param params - optional tracking params for device/session identification
15
+ * @param options - optional request overrides (host, headers)
7
16
  */
8
- static getConfig(params?: RadarTrackParams): Promise<void>;
17
+ static getConfig<T extends RadarConfigResponse = RadarConfigResponse>(params?: RadarTrackParams, options?: ConfigRequestOptions): Promise<T>;
9
18
  }
10
19
  export default ConfigAPI;
package/dist/api.d.ts CHANGED
@@ -65,7 +65,7 @@ declare class Radar {
65
65
  /** geocode the device's IP address to a rough location */
66
66
  static ipGeocode(): Promise<RadarIPGeocodeResponse>;
67
67
  /** autocomplete partial addresses and place names */
68
- static autocomplete(params: RadarAutocompleteParams): Promise<RadarAutocompleteResponse>;
68
+ static autocomplete(params: RadarAutocompleteParams, requestId?: string): Promise<RadarAutocompleteResponse>;
69
69
  /** search for geofences near a location */
70
70
  static searchGeofences(params: RadarSearchGeofencesParams): Promise<RadarSearchGeofencesResponse>;
71
71
  /** search for places (POIs) near a location */
package/dist/errors.d.ts CHANGED
@@ -1,71 +1,96 @@
1
1
  import type { RadarResponse } from './http';
2
2
  /** base error class for all Radar SDK errors */
3
- export declare class RadarError extends Error {
3
+ export declare abstract class RadarError extends Error {
4
4
  /** legacy status code string (e.g. `'ERROR_PUBLISHABLE_KEY'`) */
5
- status: string;
5
+ abstract readonly status: string;
6
+ abstract readonly name: string;
6
7
  constructor(message: string);
7
8
  }
8
9
  /** thrown when a publishable key is missing or invalid (e.g. secret key used) */
9
10
  export declare class RadarPublishableKeyError extends RadarError {
11
+ readonly name = "RadarPublishableKeyError";
12
+ readonly status = "ERROR_PUBLISHABLE_KEY";
10
13
  constructor(message: string);
11
14
  }
12
15
  /** thrown when the device location cannot be determined */
13
16
  export declare class RadarLocationError extends RadarError {
17
+ readonly name = "RadarLocationError";
18
+ readonly status = "ERROR_LOCATION";
14
19
  constructor(message: string);
15
20
  }
16
21
  /** thrown when location permissions are denied by the browser */
17
22
  export declare class RadarPermissionsError extends RadarError {
23
+ readonly name = "RadarPermissionsError";
24
+ readonly status = "ERROR_PERMISSIONS";
18
25
  constructor(message: string);
19
26
  }
20
27
  /** thrown on HTTP 400 Bad Request responses */
21
28
  export declare class RadarBadRequestError extends RadarError {
22
- code: number;
23
- response?: RadarResponse;
29
+ readonly name = "RadarBadRequestError";
30
+ readonly status = "ERROR_BAD_REQUEST";
31
+ readonly code = 400;
32
+ readonly response?: RadarResponse;
24
33
  constructor(response?: RadarResponse);
25
34
  }
26
35
  /** thrown on HTTP 401 Unauthorized responses */
27
36
  export declare class RadarUnauthorizedError extends RadarError {
28
- code: number;
29
- response?: RadarResponse;
37
+ readonly name = "RadarUnauthorizedError";
38
+ readonly status = "ERROR_UNAUTHORIZED";
39
+ readonly code = 401;
40
+ readonly response?: RadarResponse;
30
41
  constructor(response?: RadarResponse);
31
42
  }
32
43
  /** thrown on HTTP 402 Payment Required responses */
33
44
  export declare class RadarPaymentRequiredError extends RadarError {
34
- code: number;
35
- response?: RadarResponse;
45
+ readonly name = "RadarPaymentRequiredError";
46
+ readonly status = "ERROR_PAYMENT_REQUIRED";
47
+ readonly code = 402;
48
+ readonly response?: RadarResponse;
36
49
  constructor(response?: RadarResponse);
37
50
  }
38
51
  /** thrown on HTTP 403 Forbidden responses */
39
52
  export declare class RadarForbiddenError extends RadarError {
40
- code: number;
41
- response?: RadarResponse;
53
+ readonly name = "RadarForbiddenError";
54
+ readonly status = "ERROR_FORBIDDEN";
55
+ readonly code = 403;
56
+ readonly response?: RadarResponse;
42
57
  constructor(response?: RadarResponse);
43
58
  }
44
59
  /** thrown on HTTP 404 Not Found responses */
45
60
  export declare class RadarNotFoundError extends RadarError {
46
- code: number;
47
- response?: RadarResponse;
61
+ readonly name = "RadarNotFoundError";
62
+ readonly status = "ERROR_NOT_FOUND";
63
+ readonly code = 404;
64
+ readonly response?: RadarResponse;
48
65
  constructor(response?: RadarResponse);
49
66
  }
50
67
  /** thrown on HTTP 429 Rate Limit responses */
51
68
  export declare class RadarRateLimitError extends RadarError {
52
- code: number;
53
- response?: RadarResponse;
69
+ readonly name = "RadarRateLimitError";
70
+ readonly status = "ERROR_RATE_LIMIT";
71
+ readonly code = 429;
72
+ readonly response?: RadarResponse;
54
73
  /** rate limit type from the API response (e.g. `'hourly'`) */
55
- type?: string;
74
+ readonly type?: string;
56
75
  constructor(response?: RadarResponse);
57
76
  }
58
77
  /** thrown on HTTP 5xx server errors */
59
78
  export declare class RadarServerError extends RadarError {
60
- response?: RadarResponse;
79
+ readonly name = "RadarServerError";
80
+ readonly status = "ERROR_SERVER";
81
+ readonly response?: RadarResponse;
61
82
  constructor(response?: RadarResponse);
62
83
  }
63
84
  /** thrown when a request times out or the network is unavailable */
64
85
  export declare class RadarNetworkError extends RadarError {
86
+ readonly name = "RadarNetworkError";
87
+ readonly status = "ERROR_NETWORK";
65
88
  constructor();
66
89
  }
67
90
  /** thrown for unexpected/unclassified errors */
68
91
  export declare class RadarUnknownError extends RadarError {
69
- response?: RadarResponse;
92
+ readonly name = "RadarUnknownError";
93
+ readonly status = "ERROR_UNKNOWN";
94
+ readonly response?: RadarResponse;
70
95
  constructor(response?: RadarResponse);
71
96
  }
package/dist/radar.js CHANGED
@@ -39,7 +39,6 @@ Config.defaultOptions = {
39
39
  class RadarError extends Error {
40
40
  constructor(message) {
41
41
  super(message);
42
- this.status = ''; // to be overridden (support for legacy status)
43
42
  }
44
43
  }
45
44
  /** thrown when a publishable key is missing or invalid (e.g. secret key used) */
@@ -71,9 +70,9 @@ class RadarBadRequestError extends RadarError {
71
70
  constructor(response) {
72
71
  super(response?.meta?.message || 'Bad request.');
73
72
  this.name = 'RadarBadRequestError';
73
+ this.status = 'ERROR_BAD_REQUEST';
74
74
  this.code = 400;
75
75
  this.response = response;
76
- this.status = 'ERROR_BAD_REQUEST';
77
76
  }
78
77
  }
79
78
  /** thrown on HTTP 401 Unauthorized responses */
@@ -81,9 +80,9 @@ class RadarUnauthorizedError extends RadarError {
81
80
  constructor(response) {
82
81
  super(response?.meta?.message || 'Unauthorized.');
83
82
  this.name = 'RadarUnauthorizedError';
83
+ this.status = 'ERROR_UNAUTHORIZED';
84
84
  this.code = 401;
85
85
  this.response = response;
86
- this.status = 'ERROR_UNAUTHORIZED';
87
86
  }
88
87
  }
89
88
  /** thrown on HTTP 402 Payment Required responses */
@@ -91,9 +90,9 @@ class RadarPaymentRequiredError extends RadarError {
91
90
  constructor(response) {
92
91
  super(response?.meta?.message || 'Payment required.');
93
92
  this.name = 'RadarPaymentRequiredError';
93
+ this.status = 'ERROR_PAYMENT_REQUIRED';
94
94
  this.code = 402;
95
95
  this.response = response;
96
- this.status = 'ERROR_PAYMENT_REQUIRED';
97
96
  }
98
97
  }
99
98
  /** thrown on HTTP 403 Forbidden responses */
@@ -101,9 +100,9 @@ class RadarForbiddenError extends RadarError {
101
100
  constructor(response) {
102
101
  super(response?.meta?.message || 'Forbidden.');
103
102
  this.name = 'RadarForbiddenError';
103
+ this.status = 'ERROR_FORBIDDEN';
104
104
  this.code = 403;
105
105
  this.response = response;
106
- this.status = 'ERROR_FORBIDDEN';
107
106
  }
108
107
  }
109
108
  /** thrown on HTTP 404 Not Found responses */
@@ -111,9 +110,9 @@ class RadarNotFoundError extends RadarError {
111
110
  constructor(response) {
112
111
  super(response?.meta?.message || 'Not found.');
113
112
  this.name = 'RadarNotFoundError';
113
+ this.status = 'ERROR_NOT_FOUND';
114
114
  this.code = 404;
115
115
  this.response = response;
116
- this.status = 'ERROR_NOT_FOUND';
117
116
  }
118
117
  }
119
118
  /** thrown on HTTP 429 Rate Limit responses */
@@ -121,10 +120,10 @@ class RadarRateLimitError extends RadarError {
121
120
  constructor(response) {
122
121
  super(response?.meta?.message || 'Rate limit exceeded.');
123
122
  this.name = 'RadarRateLimitError';
123
+ this.status = 'ERROR_RATE_LIMIT';
124
124
  this.code = 429;
125
125
  this.response = response;
126
126
  this.type = response?.meta?.type;
127
- this.status = 'ERROR_RATE_LIMIT';
128
127
  }
129
128
  }
130
129
  /** thrown on HTTP 5xx server errors */
@@ -132,8 +131,8 @@ class RadarServerError extends RadarError {
132
131
  constructor(response) {
133
132
  super(response?.meta?.message || 'Internal server error.');
134
133
  this.name = 'RadarServerError';
135
- this.response = response;
136
134
  this.status = 'ERROR_SERVER';
135
+ this.response = response;
137
136
  }
138
137
  }
139
138
  /** thrown when a request times out or the network is unavailable */
@@ -149,8 +148,8 @@ class RadarUnknownError extends RadarError {
149
148
  constructor(response) {
150
149
  super(response?.meta?.message || 'Something went wrong.');
151
150
  this.name = 'RadarUnknownError';
152
- this.response = response;
153
151
  this.status = 'ERROR_UNKNOWN';
152
+ this.response = response;
154
153
  }
155
154
  }
156
155
 
@@ -452,7 +451,7 @@ class Navigator {
452
451
  }
453
452
  }
454
453
 
455
- var SDK_VERSION = '5.0.0-beta.6';
454
+ var SDK_VERSION = '5.0.0-beta.7';
456
455
 
457
456
  const inFlightRequests = new Map();
458
457
  /** fetch-based HTTP client for Radar API requests */
@@ -516,7 +515,8 @@ class Http {
516
515
  });
517
516
  }
518
517
  catch {
519
- if (requestId) {
518
+ // Delete abort controller instance for this request ID if it hasn't yet been replaced with a different one
519
+ if (requestId && inFlightRequests.get(requestId) === abortController) {
520
520
  inFlightRequests.delete(requestId);
521
521
  }
522
522
  if (host) {
@@ -528,7 +528,7 @@ class Http {
528
528
  }
529
529
  throw new RadarNetworkError();
530
530
  }
531
- if (requestId) {
531
+ if (requestId && inFlightRequests.get(requestId) === abortController) {
532
532
  inFlightRequests.delete(requestId);
533
533
  }
534
534
  let parsed;
@@ -540,8 +540,17 @@ class Http {
540
540
  parsed = (await response.json());
541
541
  }
542
542
  }
543
- catch {
544
- throw new RadarServerError(parsed);
543
+ catch (err) {
544
+ if (parsed) {
545
+ throw new RadarServerError(parsed);
546
+ }
547
+ else {
548
+ if (options.debug) {
549
+ Logger.debug(`API call failed: ${url}`);
550
+ Logger.debug(String(err));
551
+ }
552
+ throw new RadarUnknownError(parsed);
553
+ }
545
554
  }
546
555
  if (parsed && typeof parsed === 'object' && 'meta' in parsed) {
547
556
  const error = parsed.meta?.error;
@@ -555,7 +564,7 @@ class Http {
555
564
  throw new RadarNetworkError();
556
565
  }
557
566
  }
558
- if (response.status === 200) {
567
+ if (response.ok) {
559
568
  return parsed;
560
569
  }
561
570
  if (options.debug) {
@@ -692,15 +701,12 @@ class Session {
692
701
  /** @internal SDK configuration API for fetching remote config */
693
702
  class ConfigAPI {
694
703
  /**
695
- * fetch remote SDK configuration from the Radar API
704
+ * fetch remote SDK configuration from the Radar API. Generic so plugins can extend the response shape.
705
+ *
696
706
  * @param params - optional tracking params for device/session identification
707
+ * @param options - optional request overrides (host, headers)
697
708
  */
698
- static async getConfig(params = {}) {
699
- const options = Config.get();
700
- if (options.version != 'v1') {
701
- Logger.info('Skipping /config call.');
702
- return;
703
- }
709
+ static async getConfig(params = {}, options = {}) {
704
710
  const deviceId = params.deviceId || Device.getDeviceId();
705
711
  const installId = params.installId || Device.getInstallId();
706
712
  const sessionId = Session.getSessionId();
@@ -718,16 +724,13 @@ class ConfigAPI {
718
724
  sessionId,
719
725
  locationAuthorization,
720
726
  };
721
- try {
722
- await Http.request({
723
- method: 'GET',
724
- path: 'config',
725
- data,
726
- });
727
- }
728
- catch (err) {
729
- Logger.warn(`Error calling /config: ${err.message}`);
730
- }
727
+ return Http.request({
728
+ method: 'GET',
729
+ path: 'config',
730
+ data,
731
+ host: options.host,
732
+ headers: options.headers,
733
+ });
731
734
  }
732
735
  }
733
736
 
@@ -1430,7 +1433,9 @@ class Radar {
1430
1433
  // NOTE(jasonl): this allows us to run jest tests
1431
1434
  // without having to mock the ConfigAPI.getConfig call
1432
1435
  if (!window?.RADAR_TEST_ENV) {
1433
- void ConfigAPI.getConfig();
1436
+ ConfigAPI.getConfig().catch((err) => {
1437
+ Logger.warn(`Error calling /config: ${err.message}`);
1438
+ });
1434
1439
  }
1435
1440
  }
1436
1441
  /** clear all SDK state and configuration */
@@ -1474,7 +1479,10 @@ class Radar {
1474
1479
  return TrackAPI.trackOnce(params);
1475
1480
  }
1476
1481
  finally {
1477
- void ConfigAPI.getConfig(params); // call with updated permissions
1482
+ // call with updated permissions
1483
+ ConfigAPI.getConfig(params).catch((err) => {
1484
+ Logger.warn(`Error calling /config: ${err.message}`);
1485
+ });
1478
1486
  }
1479
1487
  }
1480
1488
  /** get context (geofences, place, regions) for a location without tracking */
@@ -1544,8 +1552,8 @@ class Radar {
1544
1552
  return Geocoding.ipGeocode();
1545
1553
  }
1546
1554
  /** autocomplete partial addresses and place names */
1547
- static autocomplete(params) {
1548
- return SearchAPI.autocomplete(params);
1555
+ static autocomplete(params, requestId) {
1556
+ return SearchAPI.autocomplete(params, requestId);
1549
1557
  }
1550
1558
  /** search for geofences near a location */
1551
1559
  static searchGeofences(params) {