launchdarkly-js-sdk-common 5.1.0 → 5.2.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/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to the `launchdarkly-js-sdk-common` package will be documented in this file. Changes that affect the dependent SDKs such as `launchdarkly-js-client-sdk` should also be logged in those projects, in the next release that uses the updated version of this package. This project adheres to [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## [5.1.0] - 2024-03-19
6
+ ### Changed:
7
+ - Redact anonymous attributes within feature events
8
+ - Always inline contexts for feature events
9
+
10
+ ### Fixed:
11
+ - Pin dev version of node to compatible types.
12
+
13
+ ### Removed:
14
+ - HTTP fallback ping
15
+
5
16
  ## [5.0.3] - 2023-03-21
6
17
  ### Changed:
7
18
  - Update `LDContext` to allow for key to be optional. This is used when making an anonymous context with a generated key.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "launchdarkly-js-sdk-common",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "LaunchDarkly SDK for JavaScript - common code",
5
5
  "author": "LaunchDarkly <team@launchdarkly.com>",
6
6
  "license": "Apache-2.0",
@@ -38,10 +38,10 @@
38
38
  "eslint-formatter-pretty": "^1.3.0",
39
39
  "eslint-plugin-babel": "^5.0.0",
40
40
  "eslint-plugin-prettier": "^2.6.0",
41
- "jest": "^25.5.4",
41
+ "jest": "^26.6.3",
42
42
  "jsdom": "^11.11.0",
43
43
  "launchdarkly-js-test-helpers": "1.1.0",
44
- "prettier": "1.11.1",
44
+ "prettier": "1.19.1",
45
45
  "readline-sync": "^1.4.9",
46
46
  "typescript": "~4.4.4"
47
47
  },
@@ -118,8 +118,8 @@ function ContextFilter(config) {
118
118
  filtered._meta = filtered._meta || {};
119
119
  // If any private attributes started with '/' we need to convert them to references, otherwise the '/' will
120
120
  // cause the literal to incorrectly be treated as a reference.
121
- filtered._meta.privateAttributes = user.privateAttributeNames.map(
122
- literal => (literal.startsWith('/') ? AttributeReference.literalToReference(literal) : literal)
121
+ filtered._meta.privateAttributes = user.privateAttributeNames.map(literal =>
122
+ literal.startsWith('/') ? AttributeReference.literalToReference(literal) : literal
123
123
  );
124
124
  }
125
125
 
@@ -10,7 +10,10 @@ import { MockEventSender } from './testUtils';
10
10
  // tests; here, we use a mock EventSender.
11
11
 
12
12
  describe.each([
13
- [{ key: 'userKey', name: 'Red' }, { key: 'userKey', kind: 'user', _meta: { redactedAttributes: ['/name'] } }],
13
+ [
14
+ { key: 'userKey', name: 'Red' },
15
+ { key: 'userKey', kind: 'user', _meta: { redactedAttributes: ['/name'] } },
16
+ ],
14
17
  [
15
18
  { kind: 'user', key: 'userKey', name: 'Red' },
16
19
  { key: 'userKey', kind: 'user', _meta: { redactedAttributes: ['/name'] } },
@@ -99,7 +99,10 @@ describe('EventSummarizer', () => {
99
99
  key1: {
100
100
  contextKinds: ['user'],
101
101
  default: 111,
102
- counters: [{ variation: 0, value: 100, version: 11, count: 1 }, { value: 111, version: 11, count: 2 }],
102
+ counters: [
103
+ { variation: 0, value: 100, version: 11, count: 1 },
104
+ { value: 111, version: 11, count: 2 },
105
+ ],
103
106
  },
104
107
  };
105
108
  expect(data.features).toEqual(expectedFeatures);
@@ -77,7 +77,7 @@ describe('LDClient events', () => {
77
77
 
78
78
  it('sends an identify event at startup', async () => {
79
79
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
80
- await client.waitForInitialization();
80
+ await client.waitForInitialization(5);
81
81
 
82
82
  expect(ep.events.length).toEqual(1);
83
83
  expectIdentifyEvent(ep.events[0], user);
@@ -87,7 +87,7 @@ describe('LDClient events', () => {
87
87
  it('stringifies user attributes in the identify event at startup', async () => {
88
88
  // This just verifies that the event is being sent with the sanitized user, not the user that was passed in
89
89
  await withClientAndEventProcessor(numericUser, {}, async (client, ep) => {
90
- await client.waitForInitialization();
90
+ await client.waitForInitialization(5);
91
91
 
92
92
  expect(ep.events.length).toEqual(1);
93
93
  expectIdentifyEvent(ep.events[0], stringifiedNumericUser);
@@ -99,7 +99,7 @@ describe('LDClient events', () => {
99
99
  await withServer(async server => {
100
100
  await withClientAndEventProcessor(user, { baseUrl: server.url }, async (client, ep) => {
101
101
  const user1 = { key: 'user1' };
102
- await client.waitForInitialization();
102
+ await client.waitForInitialization(5);
103
103
 
104
104
  expect(ep.events.length).toEqual(1);
105
105
  await client.identify(user1);
@@ -114,7 +114,7 @@ describe('LDClient events', () => {
114
114
  // This just verifies that the event is being sent with the sanitized user, not the user that was passed in
115
115
  await withServer(async server => {
116
116
  await withClientAndEventProcessor(user, { baseUrl: server.url }, async (client, ep) => {
117
- await client.waitForInitialization();
117
+ await client.waitForInitialization(5);
118
118
 
119
119
  expect(ep.events.length).toEqual(1);
120
120
  await client.identify(numericUser);
@@ -131,7 +131,7 @@ describe('LDClient events', () => {
131
131
  await withClientAndEventProcessor(user, { baseUrl: server.url }, async (client, ep) => {
132
132
  const user1 = { key: 'user1' };
133
133
 
134
- await client.waitForInitialization();
134
+ await client.waitForInitialization(5);
135
135
  await client.identify(user1);
136
136
 
137
137
  expect(ep.events.length).toEqual(0);
@@ -142,7 +142,7 @@ describe('LDClient events', () => {
142
142
  it('sends a feature event for variation()', async () => {
143
143
  const initData = makeBootstrap({ foo: { value: 'a', variation: 1, version: 2, flagVersion: 2000 } });
144
144
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
145
- await client.waitForInitialization();
145
+ await client.waitForInitialization(5);
146
146
 
147
147
  client.variation('foo', 'x');
148
148
 
@@ -165,7 +165,7 @@ describe('LDClient events', () => {
165
165
  await withServer(async server => {
166
166
  const anonUser = { key: 'anon-user', anonymous: true };
167
167
  await withClientAndEventProcessor(anonUser, { baseUrl: server.url, bootstrap: initData }, async (client, ep) => {
168
- await client.waitForInitialization();
168
+ await client.waitForInitialization(5);
169
169
 
170
170
  client.variation('foo', 'x');
171
171
 
@@ -189,7 +189,7 @@ describe('LDClient events', () => {
189
189
  foo: { value: 'a', variation: 1, version: 2, flagVersion: 2000, reason: { kind: 'OFF' } },
190
190
  });
191
191
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
192
- await client.waitForInitialization();
192
+ await client.waitForInitialization(5);
193
193
  client.variationDetail('foo', 'x');
194
194
 
195
195
  expect(ep.events.length).toEqual(2);
@@ -212,7 +212,7 @@ describe('LDClient events', () => {
212
212
  foo: { value: 'a', variation: 1, version: 2, flagVersion: 2000, reason: { kind: 'OFF' } },
213
213
  });
214
214
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
215
- await client.waitForInitialization();
215
+ await client.waitForInitialization(5);
216
216
  client.variation('foo', 'x');
217
217
 
218
218
  expect(ep.events.length).toEqual(2);
@@ -235,7 +235,7 @@ describe('LDClient events', () => {
235
235
  foo: { value: 'a', variation: 1, version: 2, flagVersion: 2000, reason: { kind: 'OFF' }, trackReason: true },
236
236
  });
237
237
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
238
- await client.waitForInitialization();
238
+ await client.waitForInitialization(5);
239
239
  client.variation('foo', 'x');
240
240
 
241
241
  expect(ep.events.length).toEqual(2);
@@ -260,7 +260,7 @@ describe('LDClient events', () => {
260
260
  await withServer(async server => {
261
261
  server.byDefault(respondJson(newFlags));
262
262
  await withClientAndEventProcessor(user, { baseUrl: server.url, bootstrap: initData }, async (client, ep) => {
263
- await client.waitForInitialization();
263
+ await client.waitForInitialization(5);
264
264
 
265
265
  const user1 = { key: 'user1' };
266
266
  await client.identify(user1);
@@ -281,7 +281,7 @@ describe('LDClient events', () => {
281
281
  server.byDefault(respondJson(newFlags));
282
282
  const extraConfig = { sendEventsOnlyForVariation: true, baseUrl: server.url, bootstrap: initData };
283
283
  await withClientAndEventProcessor(user, extraConfig, async (client, ep) => {
284
- await client.waitForInitialization();
284
+ await client.waitForInitialization(5);
285
285
 
286
286
  const user1 = { key: 'user1' };
287
287
  await client.identify(user1);
@@ -301,7 +301,7 @@ describe('LDClient events', () => {
301
301
  server.byDefault(respondJson(newFlags));
302
302
  const extraConfig = { stateProvider: sp, baseUrl: server.url };
303
303
  await withClientAndEventProcessor(user, extraConfig, async (client, ep) => {
304
- await client.waitForInitialization();
304
+ await client.waitForInitialization(5);
305
305
 
306
306
  sp.emit('update', { flags: newFlags });
307
307
 
@@ -317,7 +317,7 @@ describe('LDClient events', () => {
317
317
  bar: { value: 'b', variation: 1, version: 3 },
318
318
  });
319
319
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
320
- await client.waitForInitialization();
320
+ await client.waitForInitialization(5);
321
321
  client.allFlags();
322
322
 
323
323
  expect(ep.events.length).toEqual(3);
@@ -334,7 +334,7 @@ describe('LDClient events', () => {
334
334
  });
335
335
  const extraConfig = { sendEventsOnlyForVariation: true, bootstrap: initData };
336
336
  await withClientAndEventProcessor(user, extraConfig, async (client, ep) => {
337
- await client.waitForInitialization();
337
+ await client.waitForInitialization(5);
338
338
  client.allFlags();
339
339
 
340
340
  expect(ep.events.length).toEqual(1);
@@ -345,7 +345,7 @@ describe('LDClient events', () => {
345
345
  it('uses "version" instead of "flagVersion" in event if "flagVersion" is absent', async () => {
346
346
  const initData = makeBootstrap({ foo: { value: 'a', variation: 1, version: 2 } });
347
347
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
348
- await client.waitForInitialization();
348
+ await client.waitForInitialization(5);
349
349
  client.variation('foo', 'x');
350
350
 
351
351
  expect(ep.events.length).toEqual(2);
@@ -356,7 +356,7 @@ describe('LDClient events', () => {
356
356
 
357
357
  it('omits event version if flag does not exist', async () => {
358
358
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
359
- await client.waitForInitialization();
359
+ await client.waitForInitialization(5);
360
360
  client.variation('foo', 'x');
361
361
 
362
362
  expect(ep.events.length).toEqual(2);
@@ -377,7 +377,7 @@ describe('LDClient events', () => {
377
377
  });
378
378
  await withClientAndEventProcessor(user, { bootstrap: initData }, async (client, ep) => {
379
379
  await withCloseable(client, async () => {
380
- await client.waitForInitialization();
380
+ await client.waitForInitialization(5);
381
381
  client.variation('foo', 'x');
382
382
 
383
383
  expect(ep.events.length).toEqual(2);
@@ -399,7 +399,7 @@ describe('LDClient events', () => {
399
399
 
400
400
  it('sends an event for track()', async () => {
401
401
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
402
- await client.waitForInitialization();
402
+ await client.waitForInitialization(5);
403
403
  client.track('eventkey');
404
404
 
405
405
  expect(ep.events.length).toEqual(2);
@@ -417,7 +417,7 @@ describe('LDClient events', () => {
417
417
  await withServer(async server => {
418
418
  const anonUser = { key: 'anon-user', anonymous: true };
419
419
  await withClientAndEventProcessor(anonUser, { baseUrl: server.url }, async (client, ep) => {
420
- await client.waitForInitialization();
420
+ await client.waitForInitialization(5);
421
421
  client.track('eventkey');
422
422
 
423
423
  expect(ep.events.length).toEqual(2);
@@ -435,7 +435,7 @@ describe('LDClient events', () => {
435
435
  it('sends an event for track() with data', async () => {
436
436
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
437
437
  const eventData = { thing: 'stuff' };
438
- await client.waitForInitialization();
438
+ await client.waitForInitialization(5);
439
439
  client.track('eventkey', eventData);
440
440
 
441
441
  expect(ep.events.length).toEqual(2);
@@ -453,7 +453,7 @@ describe('LDClient events', () => {
453
453
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
454
454
  const eventData = { thing: 'stuff' };
455
455
  const metricValue = 1.5;
456
- await client.waitForInitialization();
456
+ await client.waitForInitialization(5);
457
457
  client.track('eventkey', eventData, metricValue);
458
458
 
459
459
  expect(ep.events.length).toEqual(2);
@@ -472,7 +472,7 @@ describe('LDClient events', () => {
472
472
  platform.testing.setDoNotTrack(true);
473
473
  await withClientAndEventProcessor(user, {}, async (client, ep) => {
474
474
  const eventData = { thing: 'stuff' };
475
- await client.waitForInitialization();
475
+ await client.waitForInitialization(5);
476
476
  client.track('eventkey', eventData);
477
477
  expect(ep.events.length).toEqual(0);
478
478
  });
@@ -480,16 +480,28 @@ describe('LDClient events', () => {
480
480
 
481
481
  it('does not warn by default when tracking a custom event', async () => {
482
482
  await withClientAndEventProcessor(user, {}, async client => {
483
- await client.waitForInitialization();
483
+ await client.waitForInitialization(5);
484
484
 
485
485
  client.track('known');
486
486
  expect(platform.testing.logger.output.warn).toEqual([]);
487
487
  });
488
488
  });
489
489
 
490
+ it('does warn when a metric value is non-numeric', async () => {
491
+ await withClientAndEventProcessor(user, {}, async client => {
492
+ await client.waitForInitialization(5);
493
+
494
+ client.track('known', undefined, '12');
495
+ expect(platform.testing.logger.output.warn).toEqual([
496
+ 'The track function was called with a non-numeric "metricValue" (string), ' +
497
+ 'only numeric metric values are supported.',
498
+ ]);
499
+ });
500
+ });
501
+
490
502
  it('emits an error when tracking a non-string custom event', async () => {
491
503
  await withClientAndEventProcessor(user, {}, async client => {
492
- await client.waitForInitialization();
504
+ await client.waitForInitialization(5);
493
505
 
494
506
  const badCustomEventKeys = [123, [], {}, null, undefined];
495
507
  badCustomEventKeys.forEach(key => {
@@ -513,7 +525,7 @@ describe('LDClient events', () => {
513
525
  sp.enqueueEvent = event => divertedEvents.push(event);
514
526
 
515
527
  await withClientAndEventProcessor(user, { stateProvider: sp }, async (client, ep) => {
516
- await client.waitForInitialization();
528
+ await client.waitForInitialization(5);
517
529
 
518
530
  client.track('eventkey');
519
531
  expect(ep.events.length).toEqual(0);
@@ -555,7 +567,7 @@ describe('LDClient events', () => {
555
567
  };
556
568
  const client = platform.testing.makeClient(envName, user, config);
557
569
  await withCloseable(client, async () => {
558
- await client.waitForInitialization();
570
+ await client.waitForInitialization(5);
559
571
  await client.flush();
560
572
  const data = await expectDiagnosticEventAndDiscardRegularEvent(server);
561
573
  expect(data.kind).toEqual('diagnostic-init');
@@ -579,7 +591,7 @@ describe('LDClient events', () => {
579
591
  };
580
592
  const client = platform1.testing.makeClient(envName, user, config);
581
593
  await withCloseable(client, async () => {
582
- await client.waitForInitialization();
594
+ await client.waitForInitialization(5);
583
595
  await client.flush();
584
596
  const data = await expectDiagnosticEventAndDiscardRegularEvent(server);
585
597
  expect(data.kind).toEqual('diagnostic-combined');
@@ -602,7 +614,7 @@ describe('LDClient events', () => {
602
614
  };
603
615
  const client = platform.testing.makeClient(envName, user, config);
604
616
  await withCloseable(client, async () => {
605
- await client.waitForInitialization();
617
+ await client.waitForInitialization(5);
606
618
  await client.flush();
607
619
  expect(server.requests.length()).toEqual(1);
608
620
  const req = await server.nextRequest();
@@ -38,7 +38,7 @@ describe('LDClient local storage', () => {
38
38
 
39
39
  await withServer(async server => {
40
40
  await withClient(user, { baseUrl: server.url }, async client => {
41
- await client.waitForInitialization();
41
+ await client.waitForInitialization(5);
42
42
 
43
43
  // should see a flag request to the server right away, as if bootstrap was not specified
44
44
  expect(server.requests.length()).toEqual(1);
@@ -58,7 +58,7 @@ describe('LDClient local storage', () => {
58
58
  server.byDefault(() => {});
59
59
 
60
60
  await withClient(user, { baseUrl: server.url }, async client => {
61
- await client.waitForInitialization();
61
+ await client.waitForInitialization(5);
62
62
 
63
63
  expect(client.variation('flag-key')).toEqual(1);
64
64
 
@@ -79,7 +79,7 @@ describe('LDClient local storage', () => {
79
79
  expect(client.variation('flag-key', 0)).toEqual(0);
80
80
 
81
81
  // verify that the flags get requested from LD
82
- await client.waitForInitialization();
82
+ await client.waitForInitialization(5);
83
83
  expect(client.variation('flag-key')).toEqual(1);
84
84
  });
85
85
  });
@@ -93,7 +93,7 @@ describe('LDClient local storage', () => {
93
93
  await withServer(async server => {
94
94
  server.byDefault(respondJson(flags));
95
95
  await withClient(user, { baseUrl: server.url }, async client => {
96
- await client.waitForInitialization();
96
+ await client.waitForInitialization(5);
97
97
  expect(platform.testing.logger.output.warn).toEqual([messages.localStorageUnavailable(myError)]);
98
98
  });
99
99
  });
@@ -107,7 +107,7 @@ describe('LDClient local storage', () => {
107
107
  await withServer(async server => {
108
108
  server.byDefault(respondJson(flags));
109
109
  await withClient(user, { baseUrl: server.url }, async client => {
110
- await client.waitForInitialization();
110
+ await client.waitForInitialization(5);
111
111
 
112
112
  await sleepAsync(0); // allow any pending async tasks to complete
113
113
 
@@ -123,7 +123,7 @@ describe('LDClient local storage', () => {
123
123
  await withServer(async server => {
124
124
  server.byDefault(respond(503));
125
125
  await withClient(user, { baseUrl: server.url }, async client => {
126
- await client.waitForInitialization();
126
+ await client.waitForInitialization(5);
127
127
 
128
128
  await sleepAsync(0); // allow any pending async tasks to complete
129
129
 
@@ -141,7 +141,7 @@ describe('LDClient local storage', () => {
141
141
  await withServer(async server => {
142
142
  server.byDefault(respondJson(flags));
143
143
  await withClient(user, { baseUrl: server.url, hash }, async client => {
144
- await client.waitForInitialization();
144
+ await client.waitForInitialization(5);
145
145
  const value = platform.testing.getLocalStorageImmediately(lsKeyHash);
146
146
  expect(JSON.parse(value)).toEqual({
147
147
  $schema: 1,
@@ -159,7 +159,7 @@ describe('LDClient local storage', () => {
159
159
  await withServer(async server => {
160
160
  server.byDefault(respondJson(flags));
161
161
  await withClient(user, { baseUrl: server.url }, async client => {
162
- await client.waitForInitialization();
162
+ await client.waitForInitialization(5);
163
163
 
164
164
  await sleepAsync(0); // allow any pending async tasks to complete
165
165