radar-sdk-js 5.0.0-beta.9 → 5.1.0-beta.0

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
@@ -46,10 +46,8 @@ Then import and initialize:
46
46
  ```js
47
47
  import Radar from 'radar-sdk-js';
48
48
 
49
- // initialize with your test or live publishable key
50
- Radar.initialize('prj_test_pk_...', {
51
- /* options */
52
- });
49
+ // initialize with your publishable key
50
+ Radar.initialize({ publishableKey: 'prj_test_pk_...' });
53
51
  ```
54
52
 
55
53
  ### With a script tag
@@ -57,12 +55,10 @@ Radar.initialize('prj_test_pk_...', {
57
55
  Add the following to your HTML:
58
56
 
59
57
  ```html
60
- <script src="https://js.radar.com/v5.0.0-beta.9/radar.min.js"></script>
58
+ <script src="https://js.radar.com/v5.1.0-beta.0/radar.min.js"></script>
61
59
 
62
60
  <script>
63
- Radar.initialize('prj_test_pk_...', {
64
- /* options */
65
- });
61
+ Radar.initialize({ publishableKey: 'prj_test_pk_...' });
66
62
  </script>
67
63
  ```
68
64
 
@@ -84,7 +80,7 @@ import { createMapsPlugin } from '@radarlabs/plugin-maps';
84
80
  import '@radarlabs/plugin-maps/dist/radar-maps.css';
85
81
 
86
82
  Radar.registerPlugin(createMapsPlugin());
87
- Radar.initialize('prj_test_pk_...');
83
+ Radar.initialize({ publishableKey: 'prj_test_pk_...' });
88
84
 
89
85
  const map = Radar.ui.map({
90
86
  container: 'map',
@@ -103,7 +99,7 @@ import { createAutocompletePlugin } from '@radarlabs/plugin-autocomplete';
103
99
  import '@radarlabs/plugin-autocomplete/dist/radar-autocomplete.css';
104
100
 
105
101
  Radar.registerPlugin(createAutocompletePlugin());
106
- Radar.initialize('prj_test_pk_...');
102
+ Radar.initialize({ publishableKey: 'prj_test_pk_...' });
107
103
 
108
104
  Radar.ui.autocomplete({
109
105
  container: 'autocomplete',
@@ -124,7 +120,7 @@ import Radar from 'radar-sdk-js';
124
120
  import { createFraudPlugin } from '@radarlabs/plugin-fraud';
125
121
 
126
122
  Radar.registerPlugin(createFraudPlugin());
127
- Radar.initialize('prj_live_pk_...');
123
+ Radar.initialize({ publishableKey: 'prj_live_pk_...' });
128
124
 
129
125
  const { token, user, events } = await Radar.fraud.trackVerified();
130
126
  ```
@@ -135,13 +131,13 @@ Plugin CDN bundles auto-register with the core SDK when loaded. Load
135
131
  the core SDK first, then any plugins you need:
136
132
 
137
133
  ```html
138
- <link href="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.css" rel="stylesheet" />
139
- <link href="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.css" rel="stylesheet" />
134
+ <link href="https://js.radar.com/maps/v1.0.0/radar-maps.css" rel="stylesheet" />
135
+ <link href="https://js.radar.com/autocomplete/v1.1.0/radar-autocomplete.css" rel="stylesheet" />
140
136
 
141
- <script src="https://js.radar.com/v5.0.0-beta.9/radar.min.js"></script>
142
- <script src="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.min.js"></script>
143
- <script src="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.min.js"></script>
144
- <script src="https://js.radar.com/fraud/v5.0.0-beta.1/radar-fraud.min.js"></script>
137
+ <script src="https://js.radar.com/v5.1.0-beta.0/radar.min.js"></script>
138
+ <script src="https://js.radar.com/maps/v1.0.0/radar-maps.min.js"></script>
139
+ <script src="https://js.radar.com/autocomplete/v1.1.0/radar-autocomplete.min.js"></script>
140
+ <script src="https://js.radar.com/fraud/v1.0.0/radar-fraud.min.js"></script>
145
141
  ```
146
142
 
147
143
  ## Quickstart
@@ -154,16 +150,16 @@ by ID or element reference.
154
150
  ```html
155
151
  <html>
156
152
  <head>
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.9/radar.min.js"></script>
159
- <script src="https://js.radar.com/maps/v5.0.0-beta.4/radar-maps.min.js"></script>
153
+ <link href="https://js.radar.com/maps/v1.0.0/radar-maps.css" rel="stylesheet" />
154
+ <script src="https://js.radar.com/v5.1.0-beta.0/radar.min.js"></script>
155
+ <script src="https://js.radar.com/maps/v1.0.0/radar-maps.min.js"></script>
160
156
  </head>
161
157
 
162
158
  <body>
163
159
  <div id="map" style="width: 100%; height: 500px;" />
164
160
 
165
161
  <script>
166
- Radar.initialize('<RADAR_PUBLISHABLE_KEY>');
162
+ Radar.initialize({ publishableKey: '<RADAR_PUBLISHABLE_KEY>' });
167
163
 
168
164
  const map = Radar.ui.map({
169
165
  container: 'map', // OR document.getElementById('map')
@@ -181,16 +177,16 @@ by ID or element reference.
181
177
  ```html
182
178
  <html>
183
179
  <head>
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.9/radar.min.js"></script>
186
- <script src="https://js.radar.com/autocomplete/v5.0.0-beta.4/radar-autocomplete.min.js"></script>
180
+ <link href="https://js.radar.com/autocomplete/v1.1.0/radar-autocomplete.css" rel="stylesheet" />
181
+ <script src="https://js.radar.com/v5.1.0-beta.0/radar.min.js"></script>
182
+ <script src="https://js.radar.com/autocomplete/v1.1.0/radar-autocomplete.min.js"></script>
187
183
  </head>
188
184
 
189
185
  <body>
190
186
  <div id="autocomplete" />
191
187
 
192
188
  <script>
193
- Radar.initialize('<RADAR_PUBLISHABLE_KEY>');
189
+ Radar.initialize({ publishableKey: '<RADAR_PUBLISHABLE_KEY>' });
194
190
 
195
191
  // create autocomplete widget
196
192
  Radar.ui.autocomplete({
@@ -215,12 +211,12 @@ are needed for geofencing.
215
211
  ```html
216
212
  <html>
217
213
  <head>
218
- <script src="https://js.radar.com/v5.0.0-beta.9/radar.min.js"></script>
214
+ <script src="https://js.radar.com/v5.1.0-beta.0/radar.min.js"></script>
219
215
  </head>
220
216
 
221
217
  <body>
222
218
  <script>
223
- Radar.initialize('<RADAR_PUBLISHABLE_KEY>');
219
+ Radar.initialize({ publishableKey: '<RADAR_PUBLISHABLE_KEY>' });
224
220
 
225
221
  Radar.trackOnce({ userId: 'example-user-id' }).then(({ location, user, events }) => {
226
222
  // do something with user location or events
@@ -254,7 +250,7 @@ import { createFraudPlugin } from '@radarlabs/plugin-fraud';
254
250
  Radar.registerPlugin(createMapsPlugin());
255
251
  Radar.registerPlugin(createAutocompletePlugin());
256
252
  Radar.registerPlugin(createFraudPlugin());
257
- Radar.initialize('prj_test_pk_...');
253
+ Radar.initialize({ publishableKey: 'prj_test_pk_...' });
258
254
  ```
259
255
 
260
256
  If you're building a custom plugin, import the plugin types from the
package/dist/api.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import * as errors from './errors';
2
2
  import type { RadarError } from './errors';
3
3
  import type { RadarPlugin } from './plugin';
4
- import type { Location, NavigatorPosition, RadarAutocompleteParams, RadarAutocompleteResponse, RadarContextResponse, RadarConversionParams, RadarConversionResponse, RadarDistanceParams, RadarForwardGeocodeParams, RadarGeocodeResponse, RadarIPGeocodeResponse, RadarMatrixParams, RadarMatrixResponse, RadarMetadata, RadarOptions, RadarReverseGeocodeParams, RadarRouteResponse, RadarSearchGeofencesParams, RadarSearchGeofencesResponse, RadarSearchPlacesParams, RadarSearchPlacesResponse, RadarTrackParams, RadarTrackResponse, RadarTripOptions, RadarTripResponse, RadarValidateAddressParams, RadarValidateAddressResponse } from './types';
4
+ import type { Location, NavigatorPosition, RadarAutocompleteParams, RadarAutocompleteResponse, RadarContextResponse, RadarConversionParams, RadarConversionResponse, RadarDistanceParams, RadarForwardGeocodeParams, RadarGeocodeResponse, RadarIPGeocodeResponse, RadarMatrixParams, RadarMatrixResponse, RadarMetadata, RadarInitOptions, RadarOptions, RadarReverseGeocodeParams, RadarRouteResponse, RadarSearchGeofencesParams, RadarSearchGeofencesResponse, RadarSearchPlacesParams, RadarSearchPlacesResponse, RadarTrackParams, RadarTrackResponse, RadarTripOptions, RadarTripResponse, RadarValidateAddressParams, RadarValidateAddressResponse } from './types';
5
5
  /**
6
6
  * main entry point for the Radar SDK. all methods are static — do not instantiate.
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * Radar.initialize('prj_test_pk_...');
10
+ * Radar.initialize({ publishableKey: 'prj_test_pk_...' });
11
11
  * const { user, events } = await Radar.trackOnce();
12
12
  * ```
13
13
  */
@@ -20,7 +20,13 @@ declare class Radar {
20
20
  static registerPlugin(...plugins: RadarPlugin[]): void;
21
21
  private static _getPluginContext;
22
22
  /**
23
- * initialize the SDK with a publishable key. must be called before any other method.
23
+ * initialize the SDK with an authToken or publishable key via options object.
24
+ * @param options - SDK configuration with `authToken` or `publishableKey`
25
+ * @throws {RadarPublishableKeyError} if credentials are missing or invalid
26
+ */
27
+ static initialize(options: RadarInitOptions): void;
28
+ /**
29
+ * initialize the SDK with a publishable key string.
24
30
  * @param publishableKey - your Radar publishable key (starts with `prj_test_pk_` or `prj_live_pk_`)
25
31
  * @param options - optional SDK configuration
26
32
  * @throws {RadarPublishableKeyError} if the key is missing or is a secret key
package/dist/config.d.ts CHANGED
@@ -24,5 +24,9 @@ declare class Config {
24
24
  static onError(callback: (error: RadarError) => void): void;
25
25
  /** dispatch an error to the registered callback */
26
26
  static sendError(error: any): void;
27
+ /** build standard Radar request headers (Authorization, Device-Type, SDK-Version).
28
+ * Callers must ensure credentials are set before calling (e.g. via Radar.initialize).
29
+ * */
30
+ static getDefaultHeaders(): Record<string, string>;
27
31
  }
28
32
  export default Config;
package/dist/http.d.ts CHANGED
@@ -43,7 +43,7 @@ declare class Http {
43
43
  * send an HTTP request to the Radar API
44
44
  * @param options - request configuration
45
45
  * @returns parsed response body, typed as `T`
46
- * @throws {RadarPublishableKeyError} if publishable key is not set
46
+ * @throws {RadarPublishableKeyError} if neither publishable key nor authToken is set
47
47
  * @throws {RadarBadRequestError} on 400 responses
48
48
  * @throws {RadarUnauthorizedError} on 401 responses
49
49
  * @throws {RadarNetworkError} on network failures
package/dist/radar.js CHANGED
@@ -1,3 +1,5 @@
1
+ var SDK_VERSION = '5.1.0-beta.0';
2
+
1
3
  /** global SDK configuration singleton */
2
4
  class Config {
3
5
  /** store SDK options (called by Radar.initialize) */
@@ -23,6 +25,26 @@ class Config {
23
25
  Config.errorCallback(error);
24
26
  }
25
27
  }
28
+ /** build standard Radar request headers (Authorization, Device-Type, SDK-Version).
29
+ * Callers must ensure credentials are set before calling (e.g. via Radar.initialize).
30
+ * */
31
+ static getDefaultHeaders() {
32
+ const { publishableKey, authToken, getRequestHeaders: getHeaders } = Config.get();
33
+ const headers = {
34
+ 'X-Radar-Device-Type': 'Web',
35
+ 'X-Radar-SDK-Version': SDK_VERSION,
36
+ };
37
+ if (authToken) {
38
+ headers.Authorization = `Bearer ${authToken}`;
39
+ }
40
+ else if (publishableKey) {
41
+ headers.Authorization = publishableKey;
42
+ }
43
+ if (typeof getHeaders === 'function') {
44
+ Object.assign(headers, getHeaders());
45
+ }
46
+ return headers;
47
+ }
26
48
  }
27
49
  /** registered error callback, if any */
28
50
  Config.errorCallback = null;
@@ -180,17 +202,11 @@ const LOG_LEVELS = {
180
202
  // get the numeric level for logLevel option
181
203
  const getLevel = () => {
182
204
  // disable logging in tests
183
- if (window && window.RADAR_TEST_ENV) {
205
+ if (typeof window !== 'undefined' && window.RADAR_TEST_ENV) {
184
206
  return LOG_LEVELS.none;
185
207
  }
186
- const { logLevel, debug } = Config.get();
187
- if (debug) {
188
- return LOG_LEVELS.debug;
189
- }
190
- if (logLevel) {
191
- return LOG_LEVELS[logLevel];
192
- }
193
- return LOG_LEVELS.error; // default to error-level logging if not set
208
+ const { logLevel } = Config.get();
209
+ return logLevel ? LOG_LEVELS[logLevel] : LOG_LEVELS.error;
194
210
  };
195
211
  /** leveled console logger controlled by SDK config */
196
212
  class Logger {
@@ -451,8 +467,6 @@ class Navigator {
451
467
  }
452
468
  }
453
469
 
454
- var SDK_VERSION = '5.0.0-beta.9';
455
-
456
470
  const inFlightRequests = new Map();
457
471
  /** fetch-based HTTP client for Radar API requests */
458
472
  class Http {
@@ -466,9 +480,9 @@ class Http {
466
480
  }
467
481
  static async request({ method, path, data, host, version, headers = {}, responseType, requestId, }) {
468
482
  const options = Config.get();
469
- const publishableKey = options.publishableKey;
470
- if (!publishableKey) {
471
- throw new RadarPublishableKeyError('publishableKey not set.');
483
+ const { publishableKey, authToken } = options;
484
+ if (!publishableKey && !authToken) {
485
+ throw new RadarPublishableKeyError('publishableKey or authToken not set.');
472
486
  }
473
487
  const urlHost = host || options.host;
474
488
  const urlVersion = version || options.version;
@@ -494,17 +508,11 @@ class Http {
494
508
  if (requestId) {
495
509
  inFlightRequests.set(requestId, abortController);
496
510
  }
497
- const defaultHeaders = {
498
- Authorization: publishableKey,
511
+ const allHeaders = {
499
512
  'Content-Type': 'application/json',
500
- 'X-Radar-Device-Type': 'Web',
501
- 'X-Radar-SDK-Version': SDK_VERSION,
513
+ ...Config.getDefaultHeaders(),
514
+ ...headers,
502
515
  };
503
- let configHeaders = {};
504
- if (typeof options.getRequestHeaders === 'function') {
505
- configHeaders = options.getRequestHeaders();
506
- }
507
- const allHeaders = { ...defaultHeaders, ...configHeaders, ...headers };
508
516
  let response;
509
517
  try {
510
518
  response = await fetch(url, {
@@ -1351,12 +1359,20 @@ class TrackAPI {
1351
1359
 
1352
1360
  const isSecretKey = (key) => key.includes('_sk_');
1353
1361
  const isLiveKey = (key) => key.includes('_live_');
1362
+ const isJWTShape = (value) => {
1363
+ // NOTE(jasonl): keep this check lightweight since we're doing real validation server-side
1364
+ if (!value.startsWith('eyJ')) {
1365
+ return false;
1366
+ }
1367
+ const parts = value.split('.');
1368
+ return parts.length === 3 && parts.every((s) => s.length > 0);
1369
+ };
1354
1370
  /**
1355
1371
  * main entry point for the Radar SDK. all methods are static — do not instantiate.
1356
1372
  *
1357
1373
  * @example
1358
1374
  * ```ts
1359
- * Radar.initialize('prj_test_pk_...');
1375
+ * Radar.initialize({ publishableKey: 'prj_test_pk_...' });
1360
1376
  * const { user, events } = await Radar.trackOnce();
1361
1377
  * ```
1362
1378
  */
@@ -1400,34 +1416,38 @@ class Radar {
1400
1416
  },
1401
1417
  };
1402
1418
  }
1403
- /**
1404
- * initialize the SDK with a publishable key. must be called before any other method.
1405
- * @param publishableKey - your Radar publishable key (starts with `prj_test_pk_` or `prj_live_pk_`)
1406
- * @param options - optional SDK configuration
1407
- * @throws {RadarPublishableKeyError} if the key is missing or is a secret key
1408
- */
1409
- static initialize(publishableKey, options = {}) {
1410
- if (!publishableKey) {
1411
- throw new RadarPublishableKeyError('Publishable key required in initialization.');
1412
- }
1413
- if (isSecretKey(publishableKey)) {
1414
- throw new RadarPublishableKeyError('Secret keys are not allowed. Please use your Radar publishable key.');
1415
- }
1416
- // store settings in global config
1417
- const live = isLiveKey(publishableKey);
1418
- const logLevel = live ? 'error' : 'info';
1419
- const debug = !live;
1420
- const radarOptions = Object.assign(Config.defaultOptions, {
1421
- publishableKey,
1422
- live,
1423
- logLevel,
1424
- debug,
1425
- }, options);
1426
- Config.setup(radarOptions);
1427
- Logger.info(`initialized with ${live ? 'live' : 'test'} publishableKey.`);
1428
- if (options.debug) {
1429
- Logger.debug('using options', options);
1419
+ static initialize(publishableKeyOrOptions, extraOptions = {}) {
1420
+ // NOTE(jasonl): shim the string signature into the options object to handle both cases
1421
+ const options = typeof publishableKeyOrOptions === 'string'
1422
+ ? { ...extraOptions, publishableKey: publishableKeyOrOptions }
1423
+ : { ...publishableKeyOrOptions };
1424
+ if (options.publishableKey && options.authToken) {
1425
+ throw new RadarPublishableKeyError('Token and publishableKey are mutually exclusive.');
1426
+ }
1427
+ let credentialLabel;
1428
+ if (options.publishableKey) {
1429
+ if (isSecretKey(options.publishableKey)) {
1430
+ throw new RadarPublishableKeyError('Secret keys are not allowed. Please use your Radar publishable key.');
1431
+ }
1432
+ options.live = isLiveKey(options.publishableKey);
1433
+ credentialLabel = 'publishableKey';
1434
+ }
1435
+ else if (options.authToken) {
1436
+ if (!isJWTShape(options.authToken)) {
1437
+ throw new RadarPublishableKeyError('Invalid authToken format. Expected a JWT.');
1438
+ }
1439
+ credentialLabel = 'authToken';
1430
1440
  }
1441
+ else {
1442
+ throw new RadarPublishableKeyError('Publishable key or authToken required in initialization.');
1443
+ }
1444
+ // NOTE(jasonl): for backwards compat with the old `live` option - if `debug` isn't explicitly set, we'll set it to the inverse of `live`
1445
+ options.debug = options.debug ?? (options.live !== undefined ? !options.live : false);
1446
+ options.logLevel = options.logLevel ?? (options.debug ? 'debug' : 'error');
1447
+ const radarOptions = Object.assign({}, Config.defaultOptions, options);
1448
+ Config.setup(radarOptions);
1449
+ Logger.info(`initialized with ${credentialLabel}.`);
1450
+ Logger.debug('using options', options);
1431
1451
  // NOTE(jasonl): this allows us to run jest tests
1432
1452
  // without having to mock the ConfigAPI.getConfig call
1433
1453
  if (!window?.RADAR_TEST_ENV) {