@depup/launchdarkly-node-server-sdk 7.0.4-depup.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.
Files changed (107) hide show
  1. package/.babelrc +16 -0
  2. package/.circleci/config.yml +89 -0
  3. package/.eslintignore +5 -0
  4. package/.eslintrc.yaml +114 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  6. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  8. package/.github/pull_request_template.md +21 -0
  9. package/.github/workflows/stale.yml +8 -0
  10. package/.hound.yml +33 -0
  11. package/.ldrelease/config.yml +28 -0
  12. package/.prettierrc +6 -0
  13. package/CHANGELOG.md +603 -0
  14. package/CODEOWNERS +2 -0
  15. package/CONTRIBUTING.md +55 -0
  16. package/LICENSE.txt +13 -0
  17. package/README.md +36 -0
  18. package/SECURITY.md +5 -0
  19. package/attribute_reference.js +217 -0
  20. package/big_segments.js +117 -0
  21. package/caching_store_wrapper.js +240 -0
  22. package/changes.json +30 -0
  23. package/configuration.js +235 -0
  24. package/context.js +98 -0
  25. package/context_filter.js +137 -0
  26. package/contract-tests/README.md +7 -0
  27. package/contract-tests/index.js +109 -0
  28. package/contract-tests/log.js +23 -0
  29. package/contract-tests/package.json +15 -0
  30. package/contract-tests/sdkClientEntity.js +110 -0
  31. package/contract-tests/testharness-suppressions.txt +2 -0
  32. package/diagnostic_events.js +151 -0
  33. package/docs/typedoc.js +10 -0
  34. package/errors.js +26 -0
  35. package/evaluator.js +822 -0
  36. package/event_factory.js +121 -0
  37. package/event_processor.js +320 -0
  38. package/event_summarizer.js +101 -0
  39. package/feature_store.js +120 -0
  40. package/feature_store_event_wrapper.js +258 -0
  41. package/file_data_source.js +192 -0
  42. package/flags_state.js +46 -0
  43. package/index.d.ts +2426 -0
  44. package/index.js +452 -0
  45. package/integrations.js +7 -0
  46. package/interfaces.js +2 -0
  47. package/loggers.js +125 -0
  48. package/messages.js +31 -0
  49. package/operators.js +106 -0
  50. package/package.json +105 -0
  51. package/polling.js +70 -0
  52. package/requestor.js +62 -0
  53. package/scripts/better-audit.sh +76 -0
  54. package/sharedtest/big_segment_store_tests.js +86 -0
  55. package/sharedtest/feature_store_tests.js +177 -0
  56. package/sharedtest/persistent_feature_store_tests.js +183 -0
  57. package/sharedtest/store_tests.js +7 -0
  58. package/streaming.js +179 -0
  59. package/test/LDClient-big-segments-test.js +92 -0
  60. package/test/LDClient-end-to-end-test.js +218 -0
  61. package/test/LDClient-evaluation-all-flags-test.js +226 -0
  62. package/test/LDClient-evaluation-test.js +204 -0
  63. package/test/LDClient-events-test.js +502 -0
  64. package/test/LDClient-listeners-test.js +180 -0
  65. package/test/LDClient-test.js +96 -0
  66. package/test/LDClient-tls-test.js +110 -0
  67. package/test/attribute_reference-test.js +494 -0
  68. package/test/big_segments-test.js +182 -0
  69. package/test/caching_store_wrapper-test.js +434 -0
  70. package/test/configuration-test.js +249 -0
  71. package/test/context-test.js +93 -0
  72. package/test/context_filter-test.js +424 -0
  73. package/test/diagnostic_events-test.js +152 -0
  74. package/test/evaluator-big-segments-test.js +301 -0
  75. package/test/evaluator-bucketing-test.js +333 -0
  76. package/test/evaluator-clause-test.js +277 -0
  77. package/test/evaluator-flag-test.js +452 -0
  78. package/test/evaluator-pre-conditions-test.js +105 -0
  79. package/test/evaluator-rule-test.js +131 -0
  80. package/test/evaluator-segment-match-test.js +310 -0
  81. package/test/evaluator_helpers.js +106 -0
  82. package/test/event_processor-test.js +680 -0
  83. package/test/event_summarizer-test.js +146 -0
  84. package/test/feature_store-test.js +42 -0
  85. package/test/feature_store_event_wrapper-test.js +182 -0
  86. package/test/feature_store_test_base.js +60 -0
  87. package/test/file_data_source-test.js +255 -0
  88. package/test/loggers-test.js +126 -0
  89. package/test/operators-test.js +102 -0
  90. package/test/polling-test.js +158 -0
  91. package/test/requestor-test.js +60 -0
  92. package/test/store_tests_big_segments-test.js +61 -0
  93. package/test/streaming-test.js +323 -0
  94. package/test/stubs.js +107 -0
  95. package/test/test_data-test.js +341 -0
  96. package/test/update_queue-test.js +61 -0
  97. package/test-types.ts +210 -0
  98. package/test_data.js +323 -0
  99. package/tsconfig.json +14 -0
  100. package/update_queue.js +28 -0
  101. package/utils/__tests__/httpUtils-test.js +39 -0
  102. package/utils/__tests__/wrapPromiseCallback-test.js +33 -0
  103. package/utils/asyncUtils.js +32 -0
  104. package/utils/httpUtils.js +105 -0
  105. package/utils/stringifyAttrs.js +14 -0
  106. package/utils/wrapPromiseCallback.js +36 -0
  107. package/versioned_data_kind.js +34 -0
@@ -0,0 +1,341 @@
1
+ const LDClient = require('../index');
2
+ const TestData = require('../test_data');
3
+ const InMemoryFeatureStore = require('../feature_store');
4
+ const dataKind = require('../versioned_data_kind');
5
+ const { promisify, promisifySingle } = require('launchdarkly-js-test-helpers');
6
+
7
+ describe('TestData', function() {
8
+ it('initializes the datastore with flags configured before client is started', async function() {
9
+ const td = TestData();
10
+ td.update(td.flag('new-flag').variationForAll(true));
11
+
12
+ const store = InMemoryFeatureStore();
13
+ const client = LDClient.init('sdk_key', { offline: true, featureStore: store, updateProcessor: td });
14
+
15
+ await client.waitForInitialization();
16
+
17
+ const res = await promisifySingle(store.all)(dataKind.features);
18
+ expect(res).toEqual({
19
+ 'new-flag': {
20
+ fallthrough: {
21
+ variation: 0,
22
+ },
23
+ key: 'new-flag',
24
+ offVariation: 1,
25
+ on: true,
26
+ variations: [ true, false ],
27
+ version: 1
28
+ }
29
+ });
30
+ });
31
+
32
+ it('updates the datastore with its flags when update is called', async function() {
33
+ const td = TestData();
34
+ const store = InMemoryFeatureStore();
35
+ const client = LDClient.init('sdk_key', { offline: true, featureStore: store, updateProcessor: td });
36
+
37
+ await client.waitForInitialization();
38
+ const res = await promisifySingle(store.all)(dataKind.features);
39
+ expect(res).toEqual({});
40
+
41
+ await td.update(td.flag('new-flag').variationForAll(true));
42
+
43
+ const postUpdateRes = await promisifySingle(store.all)(dataKind.features);
44
+ expect(postUpdateRes).toEqual({
45
+ 'new-flag': {
46
+ fallthrough: {
47
+ variation: 0,
48
+ },
49
+ key: 'new-flag',
50
+ offVariation: 1,
51
+ on: true,
52
+ variations: [ true, false ],
53
+ version: 1
54
+ }
55
+ });
56
+ });
57
+
58
+ it('can include preconfigured items', async function() {
59
+ const td = TestData();
60
+ td.usePreconfiguredFlag({ key: 'my-flag', version: 1000, on: true });
61
+ td.usePreconfiguredSegment({ key: 'my-segment', version: 2000 });
62
+
63
+ const store = InMemoryFeatureStore();
64
+ const client = LDClient.init('sdk_key', { offline: true, featureStore: store, updateProcessor: td });
65
+
66
+ await client.waitForInitialization();
67
+
68
+ const flags = await promisifySingle(store.all)(dataKind.features);
69
+ expect(flags).toEqual({
70
+ 'my-flag': {
71
+ key: 'my-flag',
72
+ version: 1000,
73
+ on: true,
74
+ }
75
+ });
76
+
77
+ const segments = await promisifySingle(store.all)(dataKind.segments);
78
+ expect(segments).toEqual({
79
+ 'my-segment': {
80
+ key: 'my-segment',
81
+ version: 2000
82
+ }
83
+ });
84
+
85
+ td.usePreconfiguredFlag({ key: 'my-flag', on: false });
86
+
87
+ const updatedFlag = await promisifySingle(store.get)(dataKind.features, 'my-flag');
88
+ expect(updatedFlag).toEqual({
89
+ key: 'my-flag',
90
+ version: 1001,
91
+ on: false,
92
+ });
93
+
94
+ td.usePreconfiguredSegment({ key: 'my-segment', included: [ 'x' ] });
95
+
96
+ const updatedSegment = await promisifySingle(store.get)(dataKind.segments, 'my-segment');
97
+ expect(updatedSegment).toEqual({
98
+ key: 'my-segment',
99
+ version: 2001,
100
+ included: [ 'x' ],
101
+ });
102
+ });
103
+
104
+ it('the datasource does not update the store after stop is called', async function() {
105
+ const td = TestData();
106
+ const store = InMemoryFeatureStore();
107
+ const tds = td({featureStore: store});
108
+ await promisifySingle(tds.start)();
109
+
110
+ const res = await promisifySingle(store.all)(dataKind.features);
111
+ expect(res).toEqual({});
112
+
113
+ tds.stop();
114
+ await td.update(td.flag('new-flag').variationForAll(true));
115
+
116
+ const postUpdateRes = await promisifySingle(store.all)(dataKind.features);
117
+ expect(postUpdateRes).toEqual({});
118
+ });
119
+
120
+ it('can update a flag that exists in the store already', async function() {
121
+ const td = TestData();
122
+ const store = InMemoryFeatureStore();
123
+ const tds = td({featureStore: store});
124
+ await promisifySingle(tds.start)();
125
+
126
+ await td.update(td.flag('new-flag').variationForAll(true));
127
+ const res = await promisifySingle(store.all)(dataKind.features);
128
+ expect(res).toEqual({
129
+ 'new-flag': {
130
+ fallthrough: {
131
+ variation: 0,
132
+ },
133
+ key: 'new-flag',
134
+ offVariation: 1,
135
+ on: true,
136
+ variations: [ true, false ],
137
+ version: 1
138
+ }
139
+ });
140
+
141
+ await td.update(td.flag('new-flag').variationForAll(false));
142
+ const res2 = await promisifySingle(store.all)(dataKind.features);
143
+ expect(res2).toEqual({
144
+ 'new-flag': {
145
+ fallthrough: {
146
+ variation: 1,
147
+ },
148
+ key: 'new-flag',
149
+ offVariation: 1,
150
+ on: true,
151
+ variations: [ true, false ],
152
+ version: 2
153
+ }
154
+ });
155
+ });
156
+
157
+ it('should perform an immutable copy when TestData.flag is called after update', function() {
158
+ const td = TestData();
159
+ const flag = td.flag('test-flag');
160
+ td.update(flag);
161
+ const flag_copy = td.flag('test-flag');
162
+ flag_copy.on(false);
163
+ expect(flag_copy).not.toEqual(flag);
164
+ });
165
+
166
+ it('a new FlagBuilder defaults to on', function() {
167
+ const td = TestData();
168
+ expect(td.flag('whatever').build(0).on).toBe(true);
169
+ });
170
+
171
+ it('a new FlagBuilder defaults to boolean flag', function() {
172
+ const td = TestData();
173
+ const flag = td.flag('test-flag-booleanFlags');
174
+ expect(flag.isBooleanFlag()).toBe(true)
175
+ const flag2 = td.flag('test-flag-notBooleanFlags').valueForAll('yes');
176
+ expect(flag2.isBooleanFlag()).toBe(false)
177
+ });
178
+
179
+ it('FlagBuilder can set variations', function() {
180
+ const td = TestData();
181
+ const flag = td.flag('test-flag');
182
+ flag.variations('a', 'b');
183
+ expect(flag.build(0).variations).toEqual([ 'a', 'b' ]);
184
+ });
185
+
186
+ it('can handle boolean values for *Variation setters', function() {
187
+ const td = TestData();
188
+ const flag = td.flag('test-flag').fallthroughVariation(false);
189
+ expect(flag.isBooleanFlag()).toBe(true);
190
+ expect(flag.build(0).fallthrough).toEqual({variation: 1});
191
+
192
+ const offFlag = td.flag('off-flag').offVariation(true);
193
+ expect(offFlag.isBooleanFlag()).toBe(true);
194
+ expect(offFlag.build(0).fallthrough).toEqual({variation: 0});
195
+ });
196
+
197
+ it.each([
198
+ ['variationForContext', ['user', 'ben', false]],
199
+ ['variationForUser', ['ben', false]]
200
+ ])('can set boolean values for a specific user target', function(method, params) {
201
+ const td = TestData();
202
+ const flag = td.flag('test-flag')[method](...params);
203
+ expect(flag.build(0).contextTargets).toEqual([
204
+ {
205
+ contextKind: 'user',
206
+ variation: 1,
207
+ values: ['ben']
208
+ }
209
+ ]);
210
+ const clearedFlag = flag.copy().clearAllTargets();
211
+ expect(clearedFlag.build(0)).not.toHaveProperty('targets');
212
+ });
213
+
214
+ it('can add and remove a rule', function() {
215
+ const td = TestData();
216
+ const flag = td.flag('test-flag')
217
+ .ifMatch('user', 'name', 'ben', 'christian')
218
+ .andNotMatch('user', 'country', 'fr')
219
+ .thenReturn(true);
220
+
221
+ expect(flag.build().rules).toEqual([
222
+ {
223
+ "id": "rule0",
224
+ "variation": 0,
225
+ "clauses": [
226
+ {
227
+ "attribute": "name",
228
+ "contextKind": "user",
229
+ "negate": false,
230
+ "op": "in",
231
+ "values": [
232
+ "ben",
233
+ "christian",
234
+ ],
235
+ },
236
+ {
237
+ "contextKind": "user",
238
+ "attribute": "country",
239
+ "negate": true,
240
+ "op": "in",
241
+ "values": [
242
+ "fr",
243
+ ],
244
+ },
245
+ ],
246
+ }
247
+ ]);
248
+
249
+ const clearedRulesFlag = flag.clearRules();
250
+ expect(clearedRulesFlag.build(0)).not.toHaveProperty('rules');
251
+ });
252
+
253
+ it('can move a targeted context from one variation to another', () => {
254
+ const td = TestData();
255
+
256
+ const flag = td.flag('test-flag').variationForContext('user', 'ben', false).variationForContext('user', 'ben', true);
257
+ // Because there was only one target in the first variation there will be only
258
+ // a single variation after that target is removed.
259
+ expect(flag.build(1).contextTargets).toEqual([
260
+ {
261
+ contextKind: 'user',
262
+ variation: 0,
263
+ values: ['ben']
264
+ }
265
+ ]);
266
+ });
267
+
268
+ it('if a targeted context is moved from one variation to another, then other targets remain for that variation', () => {
269
+ const td = TestData();
270
+
271
+ const flag = td.flag('test-flag')
272
+ .variationForContext('user', 'ben', false)
273
+ .variationForContext('user', 'joe', false)
274
+ .variationForContext('user', 'ben', true);
275
+
276
+ expect(flag.build(1).contextTargets).toEqual([
277
+ {
278
+ contextKind: 'user',
279
+ variation: 1,
280
+ values: ['joe']
281
+ },
282
+ {
283
+ contextKind: 'user',
284
+ variation: 0,
285
+ values: ['ben']
286
+ }
287
+ ]);
288
+ });
289
+
290
+ it('should allow targets from multiple contexts in the same variation', () => {
291
+ const td = TestData();
292
+
293
+ const flag = td.flag('test-flag')
294
+ .variationForContext('user', 'ben', false)
295
+ .variationForContext('potato', 'russet', false)
296
+ .variationForContext('potato', 'yukon', false);
297
+ // Because there was only one target in the first variation there will be only
298
+ // a single variation after that target is removed.
299
+ expect(flag.build(0).contextTargets).toEqual([
300
+ {
301
+ contextKind: 'user',
302
+ variation: 1,
303
+ values: ['ben']
304
+ },
305
+ {
306
+ contextKind: 'potato',
307
+ variation: 1,
308
+ values: ['russet', 'yukon']
309
+ }
310
+ ]);
311
+ });
312
+
313
+ it('can add evaluate a rule', async function() {
314
+ const td = TestData();
315
+ td.update(td.flag('test-flag')
316
+ .fallthroughVariation(false)
317
+ .ifMatch('user', 'name', 'ben', 'christian')
318
+ .andNotMatch('user', 'country', 'fr')
319
+ .thenReturn(true));
320
+
321
+ const store = InMemoryFeatureStore();
322
+ const client = LDClient.init('sdk_key', { featureStore: store, updateProcessor: td, sendEvents: false });
323
+
324
+
325
+ // User1 should pass because matching name and not matching country
326
+ const user1 = { 'key': 'user1', 'name': 'christian', 'country': 'us' };
327
+ const eval1 = await client.variationDetail('test-flag', user1, 'default' );
328
+
329
+ expect(eval1.value).toEqual(true);
330
+ expect(eval1.variationIndex).toEqual(0);
331
+ expect(eval1.reason.kind).toEqual('RULE_MATCH');
332
+
333
+ // User2 should NOT pass because matching name but incorrectly matching country
334
+ const user2 = { 'key': 'user2', 'name': 'ben', 'country': 'fr' };
335
+ const eval2 = await client.variationDetail('test-flag', user2, 'default' );
336
+
337
+ expect(eval2.value).toEqual(false);
338
+ expect(eval2.variationIndex).toEqual(1);
339
+ expect(eval2.reason.kind).toEqual('FALLTHROUGH');
340
+ });
341
+ });
@@ -0,0 +1,61 @@
1
+ var UpdateQueue = require('../update_queue');
2
+
3
+ describe('UpdateQueue', function() {
4
+ it('executes task immediately if there are no pending tasks', function(done) {
5
+ const q = new UpdateQueue();
6
+
7
+ var updated = false;
8
+ const updateFn = function(a, b, cb) {
9
+ expect(a).toEqual(1);
10
+ expect(b).toEqual(2);
11
+ updated = true;
12
+ cb();
13
+ };
14
+
15
+ q.enqueue(updateFn, [1, 2], function() {
16
+ expect(updated).toEqual(true);
17
+ done();
18
+ });
19
+ });
20
+
21
+ it('serializes async tasks in the order submitted', function(done) {
22
+ const q = new UpdateQueue();
23
+
24
+ var progress = [];
25
+
26
+ // This simulates a condition in which events are being received asynchronously and each
27
+ // event triggers an asynchronous task. We want to make sure that the tasks are executed in
28
+ // the order submitted, even if one is submitted during the execution of the previous one.
29
+ const taskFn = function(i, cb) {
30
+ progress.push('start ' + i);
31
+ // assume that we're doing something asynchronous here - make sure it takes a little time
32
+ setTimeout(cb, 20);
33
+ };
34
+
35
+ const expected = [
36
+ 'submit 1',
37
+ 'start 1', // note, this one executes immediately because there was nothing pending
38
+ 'submit 2',
39
+ 'submit 3',
40
+ 'end 1',
41
+ 'start 2',
42
+ 'end 2',
43
+ 'start 3',
44
+ 'end 3'
45
+ ];
46
+
47
+ for (var i = 1; i <= 3; i++) {
48
+ const j = i;
49
+ setImmediate(function() {
50
+ progress.push('submit ' + j);
51
+ q.enqueue(taskFn, [j], function() {
52
+ progress.push('end ' + j);
53
+ if (j >= 3) {
54
+ expect(progress).toEqual(expected);
55
+ done();
56
+ }
57
+ });
58
+ });
59
+ }
60
+ });
61
+ });
package/test-types.ts ADDED
@@ -0,0 +1,210 @@
1
+
2
+ // This file exists only so that we can run the TypeScript compiler in the CI build
3
+ // to validate our index.d.ts file. This code will not actually be run - the point is
4
+ // just to verify that the type declarations exist and are correct so a TypeScript
5
+ // developer can use all of the SDK features.
6
+
7
+ import * as ld from 'launchdarkly-node-server-sdk';
8
+ import * as integrations from 'launchdarkly-node-server-sdk/integrations';
9
+ import * as interfaces from 'launchdarkly-node-server-sdk/interfaces';
10
+
11
+ const logger: ld.LDLogger = {
12
+ error: (...args) => { },
13
+ warn: (...args) => { },
14
+ info: (...args) => { },
15
+ debug: (...args) => { }
16
+ };
17
+ const emptyOptions: ld.LDOptions = {};
18
+ const allOptions: ld.LDOptions = {
19
+ baseUri: '',
20
+ eventsUri: '',
21
+ streamUri: '',
22
+ stream: true,
23
+ streamInitialReconnectDelay: 1.5,
24
+ sendEvents: true,
25
+ allAttributesPrivate: true,
26
+ privateAttributes: [ 'x' ],
27
+ capacity: 100,
28
+ flushInterval: 1,
29
+ contextKeysCapacity: 100,
30
+ contextKeysFlushInterval: 1,
31
+ pollInterval: 5,
32
+ timeout: 1,
33
+ logger: logger,
34
+ tlsParams: {
35
+ ca: 'x',
36
+ cert: 'y',
37
+ key: 'z'
38
+ },
39
+ diagnosticOptOut: true,
40
+ diagnosticRecordingInterval: 100,
41
+ wrapperName: 'x',
42
+ wrapperVersion: 'y',
43
+ application: {
44
+ id: 'test-id',
45
+ version: 'test-version'
46
+ }
47
+ };
48
+ const userWithKeyOnly: ld.LDUser = { key: 'user' };
49
+ const anonymousUser: ld.LDUser = { key: 'anon-user', anonymous: true };
50
+ const user: ld.LDUser = {
51
+ key: 'user',
52
+ name: 'name',
53
+ firstName: 'first',
54
+ lastName: 'last',
55
+ email: 'test@example.com',
56
+ avatar: 'http://avatar.url',
57
+ ip: '1.1.1.1',
58
+ country: 'us',
59
+ anonymous: true,
60
+ custom: {
61
+ 'a': 's',
62
+ 'b': true,
63
+ 'c': 3,
64
+ 'd': [ 'x', 'y' ],
65
+ 'e': [ true, false ],
66
+ 'f': [ 1, 2 ]
67
+ },
68
+ privateAttributeNames: [ 'name', 'email' ]
69
+ };
70
+
71
+ const singleKindContextWithOnlyKey: ld.LDContext = {
72
+ kind: 'user',
73
+ key: 'user'
74
+ };
75
+
76
+ const anonymousContext: ld.LDContext = {
77
+ kind: 'user',
78
+ key: 'user',
79
+ anonymous: true,
80
+ };
81
+
82
+ const singleKindContext: ld.LDContext = {
83
+ kind: 'user',
84
+ key: 'user',
85
+ name: 'name',
86
+ firstName: 'first',
87
+ lastName: 'last',
88
+ email: 'test@example.com',
89
+ avatar: 'http://avatar.url',
90
+ ip: '1.1.1.1',
91
+ country: 'us',
92
+ anonymous: true,
93
+ custom: {
94
+ 'a': 's',
95
+ 'b': true,
96
+ 'c': 3,
97
+ 'd': [ 'x', 'y' ],
98
+ 'e': [ true, false ],
99
+ 'f': [ 1, 2 ]
100
+ },
101
+ _meta: {
102
+ privateAttributes: [ 'name', 'email' ]
103
+ }
104
+ }
105
+
106
+ const singleKindPart: ld.LDContextCommon = {...singleKindContext};
107
+ delete singleKindPart["kind"];
108
+
109
+ const multiKindContext: ld.LDContext = {
110
+ kind: 'multi',
111
+ user: singleKindPart,
112
+ org: {
113
+ key: 'org',
114
+ }
115
+ }
116
+
117
+ const client: ld.LDClient = ld.init('sdk-key', allOptions);
118
+
119
+ client.identify(user);
120
+ client.identify(singleKindContext);
121
+
122
+ client.track('key', user);
123
+ client.track('key', user, { ok: 1 });
124
+ client.track('key', user, null, 1.5);
125
+
126
+ client.track('key', singleKindContext);
127
+ client.track('key', singleKindContext, { ok: 1 });
128
+ client.track('key', singleKindContext, null, 1.5);
129
+
130
+ client.track('key', multiKindContext);
131
+ client.track('key', multiKindContext, { ok: 1 });
132
+ client.track('key', multiKindContext, null, 1.5);
133
+
134
+ // evaluation methods with callbacks
135
+ client.variation('key', user, false, (value: ld.LDFlagValue) => { });
136
+ client.variation('key', user, 2, (value: ld.LDFlagValue) => { });
137
+ client.variation('key', user, 'default', (value: ld.LDFlagValue) => { });
138
+ client.variationDetail('key', user, 'default', (detail: ld.LDEvaluationDetail) => {
139
+ const detailValue: ld.LDFlagValue = detail.value;
140
+ const detailIndex: number | undefined = detail.variationIndex;
141
+ const detailReason: ld.LDEvaluationReason = detail.reason;
142
+ });
143
+ client.allFlagsState(user, {}, (err: Error, flagSet: ld.LDFlagsState) => { });
144
+
145
+ client.variation('key', singleKindContext, false, (value: ld.LDFlagValue) => { });
146
+ client.variation('key', singleKindContext, 2, (value: ld.LDFlagValue) => { });
147
+ client.variation('key', singleKindContext, 'default', (value: ld.LDFlagValue) => { });
148
+ client.variationDetail('key', singleKindContext, 'default', (detail: ld.LDEvaluationDetail) => {
149
+ const detailValue: ld.LDFlagValue = detail.value;
150
+ const detailIndex: number | undefined = detail.variationIndex;
151
+ const detailReason: ld.LDEvaluationReason = detail.reason;
152
+ });
153
+ client.allFlagsState(singleKindContext, {}, (err: Error, flagSet: ld.LDFlagsState) => { });
154
+
155
+ client.variation('key', multiKindContext, false, (value: ld.LDFlagValue) => { });
156
+ client.variation('key', multiKindContext, 2, (value: ld.LDFlagValue) => { });
157
+ client.variation('key', multiKindContext, 'default', (value: ld.LDFlagValue) => { });
158
+ client.variationDetail('key', multiKindContext, 'default', (detail: ld.LDEvaluationDetail) => {
159
+ const detailValue: ld.LDFlagValue = detail.value;
160
+ const detailIndex: number | undefined = detail.variationIndex;
161
+ const detailReason: ld.LDEvaluationReason = detail.reason;
162
+ });
163
+ client.allFlagsState(multiKindContext, {}, (err: Error, flagSet: ld.LDFlagsState) => { });
164
+
165
+ // evaluation methods with promises
166
+ client.variation('key', singleKindContext, false).then((value: ld.LDFlagValue) => { });
167
+ client.variation('key', singleKindContext, 2).then((value: ld.LDFlagValue) => { });
168
+ client.variation('key', singleKindContext, 'default').then((value: ld.LDFlagValue) => { });
169
+ client.variationDetail('key', singleKindContext, 'default').then((detail: ld.LDEvaluationDetail) => { });
170
+ client.allFlagsState(singleKindContext).then((flagSet: ld.LDFlagsState) => { });
171
+
172
+ client.variation('key', singleKindContext, false).then((value: ld.LDFlagValue) => { });
173
+ client.variation('key', singleKindContext, 2).then((value: ld.LDFlagValue) => { });
174
+ client.variation('key', singleKindContext, 'default').then((value: ld.LDFlagValue) => { });
175
+ client.variationDetail('key', singleKindContext, 'default').then((detail: ld.LDEvaluationDetail) => { });
176
+ client.allFlagsState(singleKindContext).then((flagSet: ld.LDFlagsState) => { });
177
+
178
+ client.variation('key', multiKindContext, false).then((value: ld.LDFlagValue) => { });
179
+ client.variation('key', multiKindContext, 2).then((value: ld.LDFlagValue) => { });
180
+ client.variation('key', multiKindContext, 'default').then((value: ld.LDFlagValue) => { });
181
+ client.variationDetail('key', multiKindContext, 'default').then((detail: ld.LDEvaluationDetail) => { });
182
+ client.allFlagsState(multiKindContext).then((flagSet: ld.LDFlagsState) => { });
183
+
184
+ // basicLogger
185
+ const logger1: ld.LDLogger = ld.basicLogger();
186
+ const logger2: ld.LDLogger = ld.basicLogger({ level: 'info' });
187
+ const logger3: ld.LDLogger = ld.basicLogger({ destination: console.log });
188
+
189
+ // integrations module:
190
+
191
+ // FileDataSource
192
+ const fdsOptions: integrations.FileDataSourceOptions = {
193
+ paths: [ 'filepath' ],
194
+ autoUpdate: true,
195
+ logger: ld.basicLogger(),
196
+ };
197
+ const fds = integrations.FileDataSource(fdsOptions);
198
+
199
+ // TestData
200
+ const td: integrations.TestData = integrations.TestData();
201
+ const fb: integrations.TestDataFlagBuilder = td.flag('key');
202
+ td.update(fb);
203
+ fb.ifMatch('name', 'x').thenReturn(true);
204
+
205
+ // interfaces module:
206
+
207
+ // BigSegmentStoreStatusProvider
208
+ const bsssp: interfaces.BigSegmentStoreStatusProvider = client.bigSegmentStoreStatusProvider
209
+ const bssStatus: interfaces.BigSegmentStoreStatus | undefined = bsssp.getStatus();
210
+ bsssp.requireStatus().then((value: interfaces.BigSegmentStoreStatus) => { });