@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.
- package/.babelrc +16 -0
- package/.circleci/config.yml +89 -0
- package/.eslintignore +5 -0
- package/.eslintrc.yaml +114 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- package/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/pull_request_template.md +21 -0
- package/.github/workflows/stale.yml +8 -0
- package/.hound.yml +33 -0
- package/.ldrelease/config.yml +28 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +603 -0
- package/CODEOWNERS +2 -0
- package/CONTRIBUTING.md +55 -0
- package/LICENSE.txt +13 -0
- package/README.md +36 -0
- package/SECURITY.md +5 -0
- package/attribute_reference.js +217 -0
- package/big_segments.js +117 -0
- package/caching_store_wrapper.js +240 -0
- package/changes.json +30 -0
- package/configuration.js +235 -0
- package/context.js +98 -0
- package/context_filter.js +137 -0
- package/contract-tests/README.md +7 -0
- package/contract-tests/index.js +109 -0
- package/contract-tests/log.js +23 -0
- package/contract-tests/package.json +15 -0
- package/contract-tests/sdkClientEntity.js +110 -0
- package/contract-tests/testharness-suppressions.txt +2 -0
- package/diagnostic_events.js +151 -0
- package/docs/typedoc.js +10 -0
- package/errors.js +26 -0
- package/evaluator.js +822 -0
- package/event_factory.js +121 -0
- package/event_processor.js +320 -0
- package/event_summarizer.js +101 -0
- package/feature_store.js +120 -0
- package/feature_store_event_wrapper.js +258 -0
- package/file_data_source.js +192 -0
- package/flags_state.js +46 -0
- package/index.d.ts +2426 -0
- package/index.js +452 -0
- package/integrations.js +7 -0
- package/interfaces.js +2 -0
- package/loggers.js +125 -0
- package/messages.js +31 -0
- package/operators.js +106 -0
- package/package.json +105 -0
- package/polling.js +70 -0
- package/requestor.js +62 -0
- package/scripts/better-audit.sh +76 -0
- package/sharedtest/big_segment_store_tests.js +86 -0
- package/sharedtest/feature_store_tests.js +177 -0
- package/sharedtest/persistent_feature_store_tests.js +183 -0
- package/sharedtest/store_tests.js +7 -0
- package/streaming.js +179 -0
- package/test/LDClient-big-segments-test.js +92 -0
- package/test/LDClient-end-to-end-test.js +218 -0
- package/test/LDClient-evaluation-all-flags-test.js +226 -0
- package/test/LDClient-evaluation-test.js +204 -0
- package/test/LDClient-events-test.js +502 -0
- package/test/LDClient-listeners-test.js +180 -0
- package/test/LDClient-test.js +96 -0
- package/test/LDClient-tls-test.js +110 -0
- package/test/attribute_reference-test.js +494 -0
- package/test/big_segments-test.js +182 -0
- package/test/caching_store_wrapper-test.js +434 -0
- package/test/configuration-test.js +249 -0
- package/test/context-test.js +93 -0
- package/test/context_filter-test.js +424 -0
- package/test/diagnostic_events-test.js +152 -0
- package/test/evaluator-big-segments-test.js +301 -0
- package/test/evaluator-bucketing-test.js +333 -0
- package/test/evaluator-clause-test.js +277 -0
- package/test/evaluator-flag-test.js +452 -0
- package/test/evaluator-pre-conditions-test.js +105 -0
- package/test/evaluator-rule-test.js +131 -0
- package/test/evaluator-segment-match-test.js +310 -0
- package/test/evaluator_helpers.js +106 -0
- package/test/event_processor-test.js +680 -0
- package/test/event_summarizer-test.js +146 -0
- package/test/feature_store-test.js +42 -0
- package/test/feature_store_event_wrapper-test.js +182 -0
- package/test/feature_store_test_base.js +60 -0
- package/test/file_data_source-test.js +255 -0
- package/test/loggers-test.js +126 -0
- package/test/operators-test.js +102 -0
- package/test/polling-test.js +158 -0
- package/test/requestor-test.js +60 -0
- package/test/store_tests_big_segments-test.js +61 -0
- package/test/streaming-test.js +323 -0
- package/test/stubs.js +107 -0
- package/test/test_data-test.js +341 -0
- package/test/update_queue-test.js +61 -0
- package/test-types.ts +210 -0
- package/test_data.js +323 -0
- package/tsconfig.json +14 -0
- package/update_queue.js +28 -0
- package/utils/__tests__/httpUtils-test.js +39 -0
- package/utils/__tests__/wrapPromiseCallback-test.js +33 -0
- package/utils/asyncUtils.js +32 -0
- package/utils/httpUtils.js +105 -0
- package/utils/stringifyAttrs.js +14 -0
- package/utils/wrapPromiseCallback.js +36 -0
- package/versioned_data_kind.js +34 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,2426 @@
|
|
|
1
|
+
// Type definitions for launchdarkly-node-server-sdk
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This is the API reference for the LaunchDarkly Server-Side SDK for Node.js.
|
|
5
|
+
*
|
|
6
|
+
* In typical usage, you will call [[init]] once at startup time to obtain an instance of
|
|
7
|
+
* [[LDClient]], which provides access to all of the SDK's functionality.
|
|
8
|
+
*
|
|
9
|
+
* For more information, see the [SDK reference guide](https://docs.launchdarkly.com/sdk/server-side/node-js).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
declare module 'launchdarkly-node-server-sdk' {
|
|
13
|
+
import { EventEmitter } from 'events';
|
|
14
|
+
import * as interfaces from 'launchdarkly-node-server-sdk/interfaces';
|
|
15
|
+
|
|
16
|
+
namespace errors {
|
|
17
|
+
export const LDPollingError: ErrorConstructor;
|
|
18
|
+
export const LDStreamingError: ErrorConstructor;
|
|
19
|
+
export const LDClientError: ErrorConstructor;
|
|
20
|
+
export const LDUnexpectedResponseError: ErrorConstructor;
|
|
21
|
+
export const LDInvalidSDKKeyError: ErrorConstructor;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates an instance of the LaunchDarkly client.
|
|
26
|
+
*
|
|
27
|
+
* Applications should instantiate a single instance for the lifetime of the application.
|
|
28
|
+
* The client will begin attempting to connect to LaunchDarkly as soon as it is created. To
|
|
29
|
+
* determine when it is ready to use, call [[LDClient.waitForInitialization]], or register an
|
|
30
|
+
* event listener for the `"ready"` event using [[LDClient.on]].
|
|
31
|
+
*
|
|
32
|
+
* **Important:** Do **not** try to instantiate `LDClient` with its constructor (`new LDClient()`); the SDK
|
|
33
|
+
* does not currently support this.
|
|
34
|
+
*
|
|
35
|
+
* @param key
|
|
36
|
+
* The SDK key.
|
|
37
|
+
* @param options
|
|
38
|
+
* Optional configuration settings.
|
|
39
|
+
* @return
|
|
40
|
+
* The new client instance.
|
|
41
|
+
*/
|
|
42
|
+
export function init(key: string, options?: LDOptions): LDClient;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The types of values a feature flag can have.
|
|
46
|
+
*
|
|
47
|
+
* Flags can have any JSON-serializable value.
|
|
48
|
+
*/
|
|
49
|
+
export type LDFlagValue = any;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A map of feature flags from their keys to their values.
|
|
53
|
+
*/
|
|
54
|
+
export interface LDFlagSet {
|
|
55
|
+
[key: string]: LDFlagValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* An object that contains the state of all feature flags, generated by [[LDClient.allFlagsState]].
|
|
60
|
+
*/
|
|
61
|
+
export interface LDFlagsState {
|
|
62
|
+
/**
|
|
63
|
+
* True if this object contains a valid snapshot of feature flag state, or false if the
|
|
64
|
+
* state could not be computed (for instance, because the client was offline or there
|
|
65
|
+
* was no user).
|
|
66
|
+
*/
|
|
67
|
+
valid: boolean;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns the value of an individual feature flag at the time the state was recorded.
|
|
71
|
+
* It will be null if the flag returned the default value, or if there was no such flag.
|
|
72
|
+
*
|
|
73
|
+
* @param key
|
|
74
|
+
* The flag key.
|
|
75
|
+
*/
|
|
76
|
+
getFlagValue(key: string): LDFlagValue;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns the evaluation reason for a feature flag at the time the state was recorded.
|
|
80
|
+
* It will be null if reasons were not recorded, or if there was no such flag.
|
|
81
|
+
*
|
|
82
|
+
* @param key
|
|
83
|
+
* The flag key.
|
|
84
|
+
*/
|
|
85
|
+
getFlagReason(key: string): LDEvaluationReason;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns a map of feature flag keys to values. If a flag would have evaluated to the
|
|
89
|
+
* default value, its value will be null.
|
|
90
|
+
*
|
|
91
|
+
* Do not use this method if you are passing data to the front end to "bootstrap" the
|
|
92
|
+
* JavaScript client. Instead, use [[toJSON]].
|
|
93
|
+
*/
|
|
94
|
+
allValues(): LDFlagSet;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns a Javascript representation of the entire state map, in the format used by
|
|
98
|
+
* the Javascript SDK. Use this method if you are passing data to the front end in
|
|
99
|
+
* order to "bootstrap" the JavaScript client.
|
|
100
|
+
*
|
|
101
|
+
* Do not rely on the exact shape of this data, as it may change in future to support
|
|
102
|
+
* the needs of the JavaScript client.
|
|
103
|
+
*/
|
|
104
|
+
toJSON(): object;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Describes the reason that a flag evaluation produced a particular value. This is
|
|
109
|
+
* part of the [[LDEvaluationDetail]] object returned by [[LDClient.variationDetail]].
|
|
110
|
+
*/
|
|
111
|
+
export interface LDEvaluationReason {
|
|
112
|
+
/**
|
|
113
|
+
* The general category of the reason:
|
|
114
|
+
*
|
|
115
|
+
* - `'OFF'`: The flag was off and therefore returned its configured off value.
|
|
116
|
+
* - `'FALLTHROUGH'`: The flag was on but the context did not match any targets or rules.
|
|
117
|
+
* - `'TARGET_MATCH'`: The context key was specifically targeted for this flag.
|
|
118
|
+
* - `'RULE_MATCH'`: the context matched one of the flag's rules.
|
|
119
|
+
* - `'PREREQUISITE_FAILED'`: The flag was considered off because it had at least one
|
|
120
|
+
* prerequisite flag that either was off or did not return the desired variation.
|
|
121
|
+
* - `'ERROR'`: The flag could not be evaluated, e.g. because it does not exist or due
|
|
122
|
+
* to an unexpected error.
|
|
123
|
+
*/
|
|
124
|
+
kind: string;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* A further description of the error condition, if the kind was `'ERROR'`.
|
|
128
|
+
*/
|
|
129
|
+
errorKind?: string;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The index of the matched rule (0 for the first), if the kind was `'RULE_MATCH'`.
|
|
133
|
+
*/
|
|
134
|
+
ruleIndex?: number;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The unique identifier of the matched rule, if the kind was `'RULE_MATCH'`.
|
|
138
|
+
*/
|
|
139
|
+
ruleId?: string;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The key of the failed prerequisite flag, if the kind was `'PREREQUISITE_FAILED'`.
|
|
143
|
+
*/
|
|
144
|
+
prerequisiteKey?: string;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Whether the evaluation was part of an experiment.
|
|
148
|
+
*
|
|
149
|
+
* This is true if the evaluation resulted in an experiment rollout and served one of
|
|
150
|
+
* the variations in the experiment. Otherwise it is false or undefined.
|
|
151
|
+
*/
|
|
152
|
+
inExperiment?: boolean;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Describes the validity of Big Segment information, if and only if the flag evaluation
|
|
156
|
+
* required querying at least one Big Segment.
|
|
157
|
+
*
|
|
158
|
+
* - `'HEALTHY'`: The Big Segment query involved in the flag evaluation was successful, and
|
|
159
|
+
* the segment state is considered up to date.
|
|
160
|
+
* - `'STALE'`: The Big Segment query involved in the flag evaluation was successful, but
|
|
161
|
+
* the segment state may not be up to date
|
|
162
|
+
* - `'NOT_CONFIGURED'`: Big Segments could not be queried for the flag evaluation because
|
|
163
|
+
* the SDK configuration did not include a Big Segment store.
|
|
164
|
+
* - `'STORE_ERROR'`: The Big Segment query involved in the flag evaluation failed, for
|
|
165
|
+
* instance due to a database error.
|
|
166
|
+
*/
|
|
167
|
+
bigSegmentsStatus?: "HEALTHY" | "STALE" | "NOT_CONFIGURED" | "STORE_ERROR";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* An object that combines the result of a feature flag evaluation with information about
|
|
172
|
+
* how it was calculated.
|
|
173
|
+
*
|
|
174
|
+
* This is the result of calling [[LDClient.variationDetail]].
|
|
175
|
+
*
|
|
176
|
+
* For more information, see the [SDK reference guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side).
|
|
177
|
+
*/
|
|
178
|
+
export interface LDEvaluationDetail {
|
|
179
|
+
/**
|
|
180
|
+
* The result of the flag evaluation. This will be either one of the flag's variations or
|
|
181
|
+
* the default value that was passed to [[LDClient.variationDetail]].
|
|
182
|
+
*/
|
|
183
|
+
value: LDFlagValue;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The index of the returned value within the flag's list of variations, e.g. 0 for the
|
|
187
|
+
* first variation-- or `null` if the default value was returned.
|
|
188
|
+
*/
|
|
189
|
+
variationIndex?: number;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* An object describing the main factor that influenced the flag evaluation value.
|
|
193
|
+
*/
|
|
194
|
+
reason: LDEvaluationReason;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* LaunchDarkly initialization options.
|
|
199
|
+
*/
|
|
200
|
+
export interface LDOptions {
|
|
201
|
+
/**
|
|
202
|
+
* The base URI for the LaunchDarkly server.
|
|
203
|
+
*
|
|
204
|
+
* Most users should use the default value.
|
|
205
|
+
*/
|
|
206
|
+
baseUri?: string;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The base URI for the LaunchDarkly streaming server.
|
|
210
|
+
*
|
|
211
|
+
* Most users should use the default value.
|
|
212
|
+
*/
|
|
213
|
+
streamUri?: string;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The base URI for the LaunchDarkly events server.
|
|
217
|
+
*
|
|
218
|
+
* Most users should use the default value.
|
|
219
|
+
*/
|
|
220
|
+
eventsUri?: string;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The connection timeout, in seconds.
|
|
224
|
+
*/
|
|
225
|
+
timeout?: number;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The capacity of the analytics events queue.
|
|
229
|
+
*
|
|
230
|
+
* The client buffers up to this many events in memory before flushing. If the capacity is
|
|
231
|
+
* exceeded before the buffer is flushed, events will be discarded.
|
|
232
|
+
*/
|
|
233
|
+
capacity?: number;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Configures a logger for warnings and errors generated by the SDK.
|
|
237
|
+
*
|
|
238
|
+
* The logger can be any object that conforms to the [[LDLogger]] interface.
|
|
239
|
+
* For a simple implementation that lets you filter by log level, see
|
|
240
|
+
* [[basicLogger]]. You can also use an instance of `winston.Logger` from
|
|
241
|
+
* the Winston logging package.
|
|
242
|
+
*
|
|
243
|
+
* If you do not set this property, the SDK uses [[basicLogger]] with a
|
|
244
|
+
* minimum level of `info`.
|
|
245
|
+
*/
|
|
246
|
+
logger?: LDLogger;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A component that stores feature flags and related data received from LaunchDarkly.
|
|
250
|
+
*
|
|
251
|
+
* By default, this is an in-memory data structure. Database integrations are also
|
|
252
|
+
* available, as described in the
|
|
253
|
+
* [SDK features guide](https://docs.launchdarkly.com/sdk/concepts/data-stores).
|
|
254
|
+
*
|
|
255
|
+
* Some implementations provide the store implementation object itself, while others
|
|
256
|
+
* provide a factory function that creates the store implementation based on the SDK
|
|
257
|
+
* configuration; this property accepts either.
|
|
258
|
+
*/
|
|
259
|
+
featureStore?: LDFeatureStore | ((options: LDOptions) => LDFeatureStore);
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Additional parameters for configuring the SDK's Big Segments behavior.
|
|
263
|
+
*
|
|
264
|
+
* Big Segments are a specific type of user segments. For more information, read the
|
|
265
|
+
* LaunchDarkly documentation: https://docs.launchdarkly.com/home/users/big-segments
|
|
266
|
+
*
|
|
267
|
+
* By default, there is no configuration and Big Segments cannot be evaluated. In this
|
|
268
|
+
* case, any flag evaluation that references a Big Segment will behave as if no users
|
|
269
|
+
* are included in any Big Segments, and the {@link LDEvaluationReason} associated with any
|
|
270
|
+
* such flag evaluation will have a `bigSegmentsStatus` of `"NOT_CONFIGURED"`.
|
|
271
|
+
*/
|
|
272
|
+
bigSegments?: LDBigSegmentsOptions;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* A component that obtains feature flag data and puts it in the feature store.
|
|
276
|
+
*
|
|
277
|
+
* By default, this is the client's default streaming or polling component. It can be changed
|
|
278
|
+
* for testing purposes; see [[FileDataSource]].
|
|
279
|
+
*/
|
|
280
|
+
updateProcessor?: object;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The interval in between flushes of the analytics events queue, in seconds.
|
|
284
|
+
*/
|
|
285
|
+
flushInterval?: number;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* The time between polling requests, in seconds. Ignored in streaming mode.
|
|
289
|
+
*/
|
|
290
|
+
pollInterval?: number;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Allows you to specify a host for an optional HTTP proxy.
|
|
294
|
+
*/
|
|
295
|
+
proxyHost?: string;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Allows you to specify a port for an optional HTTP proxy.
|
|
299
|
+
*
|
|
300
|
+
* Both the host and port must be specified to enable proxy support.
|
|
301
|
+
*/
|
|
302
|
+
proxyPort?: number;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* When using an HTTP proxy, specifies whether it is accessed via `http` or `https`.
|
|
306
|
+
*/
|
|
307
|
+
proxyScheme?: string;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Allows you to specify basic authentication parameters for an optional HTTP proxy.
|
|
311
|
+
* Usually of the form `username:password`.
|
|
312
|
+
*/
|
|
313
|
+
proxyAuth?: string;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Whether the client should be initialized in offline mode.
|
|
317
|
+
*/
|
|
318
|
+
offline?: boolean;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Whether streaming mode should be used to receive flag updates.
|
|
322
|
+
*
|
|
323
|
+
* This is true by default. If you set it to false, the client will use polling.
|
|
324
|
+
* Streaming should only be disabled on the advice of LaunchDarkly support.
|
|
325
|
+
*/
|
|
326
|
+
stream?: boolean;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Sets the initial reconnect delay for the streaming connection, in seconds.
|
|
330
|
+
*
|
|
331
|
+
* The streaming service uses a backoff algorithm (with jitter) every time the connection needs
|
|
332
|
+
* to be reestablished. The delay for the first reconnection will start near this value, and then
|
|
333
|
+
* increase exponentially for any subsequent connection failures.
|
|
334
|
+
*
|
|
335
|
+
* The default value is 1.
|
|
336
|
+
*/
|
|
337
|
+
streamInitialReconnectDelay?: number;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Whether you are using the LaunchDarkly Relay Proxy in daemon mode.
|
|
341
|
+
*
|
|
342
|
+
* In this configuration, the client will not connect to LaunchDarkly to get feature flags,
|
|
343
|
+
* but will instead get feature state from a database (Redis or another supported feature
|
|
344
|
+
* store integration) that is populated by the Relay Proxy. By default, this is false.
|
|
345
|
+
* To learn more, read [Using daemon mode](https://docs.launchdarkly.com/home/relay-proxy/using#using-daemon-mode).
|
|
346
|
+
*/
|
|
347
|
+
useLdd?: boolean;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Whether to send analytics events back to LaunchDarkly. By default, this is true.
|
|
351
|
+
*/
|
|
352
|
+
sendEvents?: boolean;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Whether all context attributes (except the contexy key) should be marked as private, and
|
|
356
|
+
* not sent to LaunchDarkly.
|
|
357
|
+
*
|
|
358
|
+
* By default, this is false.
|
|
359
|
+
*/
|
|
360
|
+
allAttributesPrivate?: boolean;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* The names of any context attributes that should be marked as private, and not sent
|
|
364
|
+
* to LaunchDarkly.
|
|
365
|
+
*
|
|
366
|
+
* Any contexts sent to LaunchDarkly with this configuration active will have attributes with
|
|
367
|
+
* these names removed. This is in addition to any attributes that were marked as private for an
|
|
368
|
+
* individual context with {@link LDContextMeta.privateAttributes}. Setting
|
|
369
|
+
* {@link LDOptions.allAttributesPrivate} to true overrides this.
|
|
370
|
+
*
|
|
371
|
+
* If and only if a parameter starts with a slash, it is interpreted as a slash-delimited path
|
|
372
|
+
* that can denote a nested property within a JSON object. For instance, "/address/street" means
|
|
373
|
+
* that if there is an attribute called "address" that is a JSON object, and one of the object's
|
|
374
|
+
* properties is "street", the "street" property will be redacted from the analytics data but
|
|
375
|
+
* other properties within "address" will still be sent. This syntax also uses the JSON Pointer
|
|
376
|
+
* convention of escaping a literal slash character as "~1" and a tilde as "~0".
|
|
377
|
+
*/
|
|
378
|
+
privateAttributes?: Array<string>;
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* The number of context keys that the event processor can remember at any one time,
|
|
382
|
+
* so that duplicate context details will not be sent in analytics events.
|
|
383
|
+
*
|
|
384
|
+
* Defaults to 1000.
|
|
385
|
+
*/
|
|
386
|
+
contextKeysCapacity?: number;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* The interval (in seconds) at which the event processor will reset its set of
|
|
390
|
+
* known context keys.
|
|
391
|
+
*
|
|
392
|
+
* Defaults to 300.
|
|
393
|
+
*/
|
|
394
|
+
contextKeysFlushInterval?: number;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* The number of user keys that the event processor can remember at any one time,
|
|
398
|
+
* so that duplicate user details will not be sent in analytics events.
|
|
399
|
+
*
|
|
400
|
+
* Defaults to 1000.
|
|
401
|
+
*
|
|
402
|
+
* @deprecated Use contextKeysCapacity instead.
|
|
403
|
+
*/
|
|
404
|
+
userKeysCapacity?: number;
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* The interval (in seconds) at which the event processor will reset its set of
|
|
408
|
+
* known user keys.
|
|
409
|
+
*
|
|
410
|
+
* Defaults to 300.
|
|
411
|
+
*
|
|
412
|
+
* @deprecated Use contextKeysFlushInterval instead.
|
|
413
|
+
*/
|
|
414
|
+
userKeysFlushInterval?: number;
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Additional parameters to pass to the Node HTTPS API for secure requests. These can include any
|
|
418
|
+
* of the TLS-related parameters supported by `https.request()`, such as `ca`, `cert`, and `key`.
|
|
419
|
+
*
|
|
420
|
+
* For more information, see the Node documentation for `https.request()` and `tls.connect()`.
|
|
421
|
+
*/
|
|
422
|
+
tlsParams?: LDTLSOptions;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Set to true to opt out of sending diagnostics data.
|
|
426
|
+
*
|
|
427
|
+
* Unless the `diagnosticOptOut` field is set to true, the client will send some diagnostics data to the
|
|
428
|
+
* LaunchDarkly servers in order to assist in the development of future SDK improvements. These diagnostics
|
|
429
|
+
* consist of an initial payload containing some details of SDK in use, the SDK's configuration, and the platform
|
|
430
|
+
* the SDK is being run on, as well as payloads sent periodically with information on irregular occurrences such
|
|
431
|
+
* as dropped events.
|
|
432
|
+
*/
|
|
433
|
+
diagnosticOptOut?: boolean;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* The interval at which periodic diagnostic data is sent, in seconds.
|
|
437
|
+
*
|
|
438
|
+
* The default is 900 (every 15 minutes) and the minimum value is 60 (every minute).
|
|
439
|
+
*/
|
|
440
|
+
diagnosticRecordingInterval?: number;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* For use by wrapper libraries to set an identifying name for the wrapper being used.
|
|
444
|
+
*
|
|
445
|
+
* This will be sent in User-Agent headers during requests to the LaunchDarkly servers to allow recording
|
|
446
|
+
* metrics on the usage of these wrapper libraries.
|
|
447
|
+
*/
|
|
448
|
+
wrapperName?: string;
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* For use by wrapper libraries to report the version of the library in use.
|
|
452
|
+
*
|
|
453
|
+
* If `wrapperName` is not set, this field will be ignored. Otherwise the version string will be included in
|
|
454
|
+
* the User-Agent headers along with the `wrapperName` during requests to the LaunchDarkly servers.
|
|
455
|
+
*/
|
|
456
|
+
wrapperVersion?: string;
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Information about the application where the LaunchDarkly SDK is running.
|
|
460
|
+
*/
|
|
461
|
+
application?: {
|
|
462
|
+
/**
|
|
463
|
+
* A unique identifier representing the application where the LaunchDarkly SDK is running.
|
|
464
|
+
*
|
|
465
|
+
* This can be specified as any string value as long as it only uses the following characters: ASCII letters,
|
|
466
|
+
* ASCII digits, period, hyphen, underscore. A string containing any other characters will be ignored.
|
|
467
|
+
*
|
|
468
|
+
* Example: `authentication-service`
|
|
469
|
+
*/
|
|
470
|
+
id?: string;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* A unique identifier representing the version of the application where the LaunchDarkly SDK is running.
|
|
474
|
+
*
|
|
475
|
+
* This can be specified as any string value as long as it only uses the following characters: ASCII letters,
|
|
476
|
+
* ASCII digits, period, hyphen, underscore. A string containing any other characters will be ignored.
|
|
477
|
+
*
|
|
478
|
+
* Example: `1.0.0` (standard version string) or `abcdef` (sha prefix)
|
|
479
|
+
*/
|
|
480
|
+
version?: string;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Additional parameters for configuring the SDK's Big Segments behavior.
|
|
486
|
+
*
|
|
487
|
+
* Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
|
|
488
|
+
* documentation: https://docs.launchdarkly.com/home/users/big-segments
|
|
489
|
+
*
|
|
490
|
+
* @see {@link LDOptions.bigSegments}
|
|
491
|
+
*/
|
|
492
|
+
export interface LDBigSegmentsOptions {
|
|
493
|
+
/**
|
|
494
|
+
* Specifies the storage component that provides Big Segments data.
|
|
495
|
+
*
|
|
496
|
+
* This property is mandatory. It must be obtained from one of the SDK's database integrations,
|
|
497
|
+
* such as https://github.com/launchdarkly/node-server-sdk-redis. You will normally specify a
|
|
498
|
+
* database implementation that matches how the LaunchDarkly Relay Proxy is configured, since the
|
|
499
|
+
* Relay Proxy manages the Big Segment data.
|
|
500
|
+
*/
|
|
501
|
+
store: (options: LDOptions) => interfaces.BigSegmentStore;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* The maximum number of users whose Big Segment state will be cached by the SDK at any given time.
|
|
505
|
+
*
|
|
506
|
+
* To reduce database traffic, the SDK maintains a least-recently-used cache by user key. When a feature
|
|
507
|
+
* flag that references a Big Segment is evaluated for some user who is not currently in the cache, the
|
|
508
|
+
* SDK queries the database for all Big Segment memberships of that user, and stores them together in a
|
|
509
|
+
* single cache entry. If the cache is full, the oldest entry is dropped.
|
|
510
|
+
*
|
|
511
|
+
* A higher value for `userCacheSize` means that database queries for Big Segments will be done
|
|
512
|
+
* less often for recently-referenced users, if the application has many users, at the cost of
|
|
513
|
+
* increased memory used by the cache.
|
|
514
|
+
*
|
|
515
|
+
* Cache entries can also expire based on the setting of {@link userCacheTime}.
|
|
516
|
+
*
|
|
517
|
+
* If not specified, the default value is 1000.
|
|
518
|
+
*/
|
|
519
|
+
userCacheSize?: number;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* The maximum length of time that the Big Segment state for a user will be cached by the SDK,
|
|
523
|
+
* in seconds.
|
|
524
|
+
*
|
|
525
|
+
* See {@link userCacheSize} for more about this cache. A higher value for `userCacheTime` means
|
|
526
|
+
* that database queries for the Big Segment state of any given user will be done less often, but
|
|
527
|
+
* that changes to segment membership may not be detected as soon.
|
|
528
|
+
*
|
|
529
|
+
* If not specified, the default value is 5. Negative values are changed to the default.
|
|
530
|
+
*/
|
|
531
|
+
userCacheTime?: number;
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* The interval at which the SDK will poll the Big Segment store to make sure it is available
|
|
535
|
+
* and to determine how long ago it was updated, in seconds.
|
|
536
|
+
*
|
|
537
|
+
* If not specified, the default value is 5. Zero or negative values are changed to the default.
|
|
538
|
+
*/
|
|
539
|
+
statusPollInterval?: number;
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* The maximum length of time between updates of the Big Segments data before the data is
|
|
543
|
+
* considered out of date, in seconds.
|
|
544
|
+
*
|
|
545
|
+
* Normally, the LaunchDarkly Relay Proxy updates a timestamp in the Big Segment store at intervals to
|
|
546
|
+
* confirm that it is still in sync with the LaunchDarkly data, even if there have been no changes to the
|
|
547
|
+
* If the timestamp falls behind the current time by the amount specified in `staleAfter`, the SDK
|
|
548
|
+
* assumes that something is not working correctly in this process and that the data may not be accurate.
|
|
549
|
+
*
|
|
550
|
+
* While in a stale state, the SDK will still continue using the last known data, but the status from
|
|
551
|
+
* {@link interfaces.BigSegmentStoreStatusProvider.getStatus} will have `stale: true`, and any
|
|
552
|
+
* {@link LDEvaluationReason} generated from a feature flag that references a Big Segment will have a
|
|
553
|
+
* `bigSegmentsStatus` of `"STALE"`.
|
|
554
|
+
*
|
|
555
|
+
* If not specified, the default value is 120 (two minutes). Zero or negative values are changed to
|
|
556
|
+
* the default.
|
|
557
|
+
*/
|
|
558
|
+
staleAfter?: number;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Additional parameters to pass to the Node HTTPS API for secure requests. These can include any
|
|
563
|
+
* of the TLS-related parameters supported by `https.request()`, such as `ca`, `cert`, and `key`.
|
|
564
|
+
*
|
|
565
|
+
* For more information, see the Node documentation for `https.request()` and `tls.connect()`.
|
|
566
|
+
*/
|
|
567
|
+
export interface LDTLSOptions {
|
|
568
|
+
ca?: string | string[] | Buffer | Buffer[];
|
|
569
|
+
cert?: string | string[] | Buffer | Buffer[];
|
|
570
|
+
checkServerIdentity?: (servername: string, cert: any) => Error | undefined;
|
|
571
|
+
ciphers?: string;
|
|
572
|
+
pfx?: string | string[] | Buffer | Buffer[] | object[];
|
|
573
|
+
key?: string | string[] | Buffer | Buffer[] | object[];
|
|
574
|
+
passphrase?: string;
|
|
575
|
+
rejectUnauthorized?: boolean;
|
|
576
|
+
secureProtocol?: string;
|
|
577
|
+
servername?: string;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Meta attributes are used to control behavioral aspects of the Context.
|
|
582
|
+
* They cannot be addressed in targeting rules.
|
|
583
|
+
*/
|
|
584
|
+
export interface LDContextMeta {
|
|
585
|
+
/**
|
|
586
|
+
*
|
|
587
|
+
* Designate any number of Context attributes, or properties within them, as private: that is,
|
|
588
|
+
* their values will not be sent to LaunchDarkly.
|
|
589
|
+
*
|
|
590
|
+
* Each parameter can be a simple attribute name, such as "email". Or, if the first character is
|
|
591
|
+
* a slash, the parameter is interpreted as a slash-delimited path to a property within a JSON
|
|
592
|
+
* object, where the first path component is a Context attribute name and each following
|
|
593
|
+
* component is a nested property name: for example, suppose the attribute "address" had the
|
|
594
|
+
* following JSON object value:
|
|
595
|
+
*
|
|
596
|
+
* ```
|
|
597
|
+
* {"street": {"line1": "abc", "line2": "def"}}
|
|
598
|
+
* ```
|
|
599
|
+
*
|
|
600
|
+
* Using ["/address/street/line1"] in this case would cause the "line1" property to be marked as
|
|
601
|
+
* private. This syntax deliberately resembles JSON Pointer, but other JSON Pointer features
|
|
602
|
+
* such as array indexing are not supported for Private.
|
|
603
|
+
*
|
|
604
|
+
* This action only affects analytics events that involve this particular Context. To mark some
|
|
605
|
+
* (or all) Context attributes as private for all users, use the overall configuration for the
|
|
606
|
+
* SDK.
|
|
607
|
+
* See {@link LDOptions.allAttributesPrivate} and {@link LDOptions.privateAttributes}.
|
|
608
|
+
*
|
|
609
|
+
* The attributes "kind" and "key", and the "_meta" attributes cannot be made private.
|
|
610
|
+
*
|
|
611
|
+
* In this example, firstName is marked as private, but lastName is not:
|
|
612
|
+
*
|
|
613
|
+
* ```
|
|
614
|
+
* const context = {
|
|
615
|
+
* kind: 'org',
|
|
616
|
+
* key: 'my-key',
|
|
617
|
+
* firstName: 'Pierre',
|
|
618
|
+
* lastName: 'Menard',
|
|
619
|
+
* _meta: {
|
|
620
|
+
* privateAttributes: ['firstName'],
|
|
621
|
+
* }
|
|
622
|
+
* };
|
|
623
|
+
* ```
|
|
624
|
+
*
|
|
625
|
+
* This is a metadata property, rather than an attribute that can be addressed in evaluations:
|
|
626
|
+
* that is, a rule clause that references the attribute name "privateAttributes", will not use
|
|
627
|
+
* this value, but would use a "privateAttributes" attribute set on the context.
|
|
628
|
+
*/
|
|
629
|
+
privateAttributes?: string[];
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
interface LDContextCommon {
|
|
633
|
+
/**
|
|
634
|
+
* If true, the context will _not_ appear on the Contexts page in the LaunchDarkly dashboard.
|
|
635
|
+
*/
|
|
636
|
+
anonymous?: boolean;
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* A unique string identifying a context.
|
|
640
|
+
*/
|
|
641
|
+
key: string;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* The context's name.
|
|
645
|
+
*
|
|
646
|
+
* You can search for contexts on the Contexts page by name.
|
|
647
|
+
*/
|
|
648
|
+
name?: string;
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Meta attributes are used to control behavioral aspects of the Context, such as private
|
|
652
|
+
* private attributes. See {@link LDContextMeta.privateAttributes} as an example.
|
|
653
|
+
*
|
|
654
|
+
* They cannot be addressed in targeting rules.
|
|
655
|
+
*/
|
|
656
|
+
_meta?: LDContextMeta;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Any additional attributes associated with the context.
|
|
660
|
+
*/
|
|
661
|
+
[attribute: string]: any;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* A context which represents a single kind.
|
|
667
|
+
*
|
|
668
|
+
* For a single kind context the 'kind' may not be 'multi'.
|
|
669
|
+
*
|
|
670
|
+
* ```
|
|
671
|
+
* const myOrgContext = {
|
|
672
|
+
* kind: 'org',
|
|
673
|
+
* key: 'my-org-key',
|
|
674
|
+
* someAttribute: 'my-attribute-value'
|
|
675
|
+
* };
|
|
676
|
+
* ```
|
|
677
|
+
*
|
|
678
|
+
* The above context would be a single kind context representing an organization. It has a key
|
|
679
|
+
* for that organization, and a single attribute 'someAttribute'.
|
|
680
|
+
*/
|
|
681
|
+
interface LDSingleKindContext extends LDContextCommon {
|
|
682
|
+
/**
|
|
683
|
+
* The kind of the context.
|
|
684
|
+
*/
|
|
685
|
+
kind: string;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* A context which represents multiple kinds. Each kind having its own key and attributes.
|
|
690
|
+
*
|
|
691
|
+
* A multi-context must contain `kind: 'multi'` at the root.
|
|
692
|
+
*
|
|
693
|
+
* ```
|
|
694
|
+
* const myMultiContext = {
|
|
695
|
+
* // Multi-contexts must be of kind 'multi'.
|
|
696
|
+
* kind: 'multi',
|
|
697
|
+
* // The context is namespaced by its kind. This is an 'org' kind context.
|
|
698
|
+
* org: {
|
|
699
|
+
* // Each component context has its own key and attributes.
|
|
700
|
+
* key: 'my-org-key',
|
|
701
|
+
* someAttribute: 'my-attribute-value',
|
|
702
|
+
* },
|
|
703
|
+
* user: {
|
|
704
|
+
* key: 'my-user-key',
|
|
705
|
+
* firstName: 'Bob',
|
|
706
|
+
* lastName: 'Bobberson',
|
|
707
|
+
* _meta: {
|
|
708
|
+
* // Each component context has its own _meta attributes. This will only apply the this
|
|
709
|
+
* // 'user' context.
|
|
710
|
+
* privateAttributes: ['firstName']
|
|
711
|
+
* }
|
|
712
|
+
* }
|
|
713
|
+
* };
|
|
714
|
+
* ```
|
|
715
|
+
*
|
|
716
|
+
* The above multi-context contains both an 'org' and a 'user'. Each with their own key,
|
|
717
|
+
* attributes, and _meta attributes.
|
|
718
|
+
*/
|
|
719
|
+
interface LDMultiKindContext {
|
|
720
|
+
/**
|
|
721
|
+
* The kind of the context.
|
|
722
|
+
*/
|
|
723
|
+
kind: "multi",
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* The contexts which compose this multi-kind context.
|
|
727
|
+
*
|
|
728
|
+
* These should be of type LDContextCommon. "multi" is to allow
|
|
729
|
+
* for the top level "kind" attribute.
|
|
730
|
+
*/
|
|
731
|
+
[kind: string]: "multi" | LDContextCommon;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* A LaunchDarkly context object.
|
|
736
|
+
*/
|
|
737
|
+
export type LDContext = LDUser | LDSingleKindContext | LDMultiKindContext;
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* A legacy LaunchDarkly user object.
|
|
741
|
+
*
|
|
742
|
+
* This type exists for easing migration to contexts, but code should be moved to use single/multi
|
|
743
|
+
* contexts.
|
|
744
|
+
*
|
|
745
|
+
* The LDUser object is currently supported for ease of upgrade. It may be removed in a future
|
|
746
|
+
* release.
|
|
747
|
+
* In order to convert an LDUser into a LDSingleKindContext the following changes should
|
|
748
|
+
* be made.
|
|
749
|
+
*
|
|
750
|
+
* 1.) Add a kind to the object. `kind: 'user'`.
|
|
751
|
+
*
|
|
752
|
+
* 2.) Move custom attributes to the top level of the object.
|
|
753
|
+
*
|
|
754
|
+
* 3.) Move `privateAttributeNames` to `_meta.privateAttributes`.
|
|
755
|
+
*
|
|
756
|
+
* ```
|
|
757
|
+
* const LDUser: user = {
|
|
758
|
+
* key: '1234',
|
|
759
|
+
* privateAttributeNames: ['myAttr']
|
|
760
|
+
* custom: {
|
|
761
|
+
* myAttr: 'value'
|
|
762
|
+
* }
|
|
763
|
+
* }
|
|
764
|
+
*
|
|
765
|
+
* const LDSingleKindContext: context = {
|
|
766
|
+
* kind: 'user',
|
|
767
|
+
* key: '1234',
|
|
768
|
+
* myAttr: 'value'
|
|
769
|
+
* _meta: {
|
|
770
|
+
* privateAttributes: ['myAttr']
|
|
771
|
+
* }
|
|
772
|
+
* }
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
775
|
+
export interface LDUser {
|
|
776
|
+
/**
|
|
777
|
+
* A unique string identifying a user.
|
|
778
|
+
*/
|
|
779
|
+
key: string;
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* The user's name.
|
|
783
|
+
*
|
|
784
|
+
* You can search for users on the User page by name.
|
|
785
|
+
*/
|
|
786
|
+
name?: string;
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* The user's first name.
|
|
790
|
+
*/
|
|
791
|
+
firstName?: string;
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* The user's last name.
|
|
795
|
+
*/
|
|
796
|
+
lastName?: string;
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* The user's email address.
|
|
800
|
+
*
|
|
801
|
+
* If an `avatar` URL is not provided, LaunchDarkly will use Gravatar
|
|
802
|
+
* to try to display an avatar for the user on the Users page.
|
|
803
|
+
*/
|
|
804
|
+
email?: string;
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* An absolute URL to an avatar image for the user.
|
|
808
|
+
*/
|
|
809
|
+
avatar?: string;
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* The user's IP address.
|
|
813
|
+
*
|
|
814
|
+
* If you provide an IP, LaunchDarkly will use a geolocation service to
|
|
815
|
+
* automatically infer a `country` for the user, unless you've already
|
|
816
|
+
* specified one.
|
|
817
|
+
*/
|
|
818
|
+
ip?: string;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* The country associated with the user.
|
|
822
|
+
*/
|
|
823
|
+
country?: string;
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* If true, the user will _not_ appear on the Users page in the LaunchDarkly dashboard.
|
|
827
|
+
*/
|
|
828
|
+
anonymous?: boolean;
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Any additional attributes associated with the user.
|
|
832
|
+
*/
|
|
833
|
+
custom?: {
|
|
834
|
+
[key: string]:
|
|
835
|
+
| string
|
|
836
|
+
| boolean
|
|
837
|
+
| number
|
|
838
|
+
| Array<string | boolean | number>;
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Specifies a list of attribute names (either built-in or custom) which should be
|
|
843
|
+
* marked as private, and not sent to LaunchDarkly in analytics events. This is in
|
|
844
|
+
* addition to any private attributes designated in the global configuration
|
|
845
|
+
* with [[LDOptions.privateAttributeNames]] or [[LDOptions.allAttributesPrivate]].
|
|
846
|
+
*/
|
|
847
|
+
privateAttributeNames?: Array<string>;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* The LaunchDarkly client logger interface.
|
|
852
|
+
*
|
|
853
|
+
* The [[LDOptions.logger]] property accepts any object that conforms to this
|
|
854
|
+
* interface. The SDK only uses four logging levels: `error`, `warn`, `info`, and
|
|
855
|
+
* `debug`. It will call the corresponding method of the `LDLogger` either with a
|
|
856
|
+
* single string argument, or with a format string and variable arguments in the
|
|
857
|
+
* format used by Node's `util.format()`.
|
|
858
|
+
*
|
|
859
|
+
* The [Winston](https://github.com/winstonjs/winston) logging package provides a
|
|
860
|
+
* logger that conforms to this interface, so if you have created a logger with
|
|
861
|
+
* Winston, you can simply put it into the [[LDOptions.logger]] property.
|
|
862
|
+
*
|
|
863
|
+
* If you do not provide a logger object, the SDK uses the [[basicLogger]]
|
|
864
|
+
* implementation with a minimum level of `info`.
|
|
865
|
+
*/
|
|
866
|
+
export interface LDLogger {
|
|
867
|
+
/**
|
|
868
|
+
* The error logger.
|
|
869
|
+
*
|
|
870
|
+
* @param args
|
|
871
|
+
* A sequence of any JavaScript values.
|
|
872
|
+
*/
|
|
873
|
+
error(...args: any[]): void;
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* The warning logger.
|
|
877
|
+
*
|
|
878
|
+
* @param args
|
|
879
|
+
* A sequence of any JavaScript values.
|
|
880
|
+
*/
|
|
881
|
+
warn(...args: any[]): void;
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* The info logger.
|
|
885
|
+
*
|
|
886
|
+
* @param args
|
|
887
|
+
* A sequence of any JavaScript values.
|
|
888
|
+
*/
|
|
889
|
+
info(...args: any[]): void;
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* The debug logger.
|
|
893
|
+
*
|
|
894
|
+
* @param args
|
|
895
|
+
* A sequence of any JavaScript values.
|
|
896
|
+
*/
|
|
897
|
+
debug(...args: any[]): void;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Interface for a feature store component.
|
|
902
|
+
*
|
|
903
|
+
* The feature store is what the client uses to store feature flag data that has been received
|
|
904
|
+
* from LaunchDarkly. By default, it uses an in-memory implementation; database integrations are
|
|
905
|
+
* also available. Read the [SDK features guide](https://docs.launchdarkly.com/sdk/concepts/data-stores).
|
|
906
|
+
* You will not need to use this interface unless you are writing your own implementation.
|
|
907
|
+
*
|
|
908
|
+
* Feature store methods can and should call their callbacks directly whenever possible, rather
|
|
909
|
+
* than deferring them with setImmediate() or process.nextTick(). This means that if for any
|
|
910
|
+
* reason you are updating or querying a feature store directly in your application code (which
|
|
911
|
+
* is not part of normal use of the SDK) you should be aware that the callback may be executed
|
|
912
|
+
* immediately.
|
|
913
|
+
*/
|
|
914
|
+
export interface LDFeatureStore {
|
|
915
|
+
/**
|
|
916
|
+
* Get an entity from the store.
|
|
917
|
+
*
|
|
918
|
+
* The store should treat any entity with the property `deleted: true` as "not found".
|
|
919
|
+
*
|
|
920
|
+
* @param kind
|
|
921
|
+
* The type of data to be accessed. The store should not make any assumptions about the format
|
|
922
|
+
* of the data, but just return a JSON object. The actual type of this parameter is
|
|
923
|
+
* [[interfaces.DataKind]].
|
|
924
|
+
*
|
|
925
|
+
* @param key
|
|
926
|
+
* The unique key of the entity within the specified collection.
|
|
927
|
+
*
|
|
928
|
+
* @param callback
|
|
929
|
+
* Will be called with the retrieved entity, or null if not found. The actual type of the result
|
|
930
|
+
* value is [[interfaces.VersionedData]].
|
|
931
|
+
*/
|
|
932
|
+
get(kind: object, key: string, callback: (res: object) => void): void;
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Get all entities from a collection.
|
|
936
|
+
*
|
|
937
|
+
* The store should filter out any entities with the property `deleted: true`.
|
|
938
|
+
*
|
|
939
|
+
* @param kind
|
|
940
|
+
* The type of data to be accessed. The store should not make any assumptions about the format
|
|
941
|
+
* of the data, but just return an object in which each key is the `key` property of an entity
|
|
942
|
+
* and the value is the entity. The actual type of this parameter is [[interfaces.DataKind]].
|
|
943
|
+
*
|
|
944
|
+
* @param callback
|
|
945
|
+
* Will be called with the resulting map. The actual type of the result value is
|
|
946
|
+
* `interfaces.KeyedItems<VersionedData>`.
|
|
947
|
+
*/
|
|
948
|
+
all(kind: object, callback: (res: object) => void): void;
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Initialize the store, overwriting any existing data.
|
|
952
|
+
*
|
|
953
|
+
* @param allData
|
|
954
|
+
* An object in which each key is the "namespace" of a collection (e.g. `"features"`) and
|
|
955
|
+
* the value is an object that maps keys to entities. The actual type of this parameter is
|
|
956
|
+
* `interfaces.FullDataSet<VersionedData>`.
|
|
957
|
+
*
|
|
958
|
+
* @param callback
|
|
959
|
+
* Will be called when the store has been initialized.
|
|
960
|
+
*/
|
|
961
|
+
init(allData: object, callback: () => void): void;
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Delete an entity from the store.
|
|
965
|
+
*
|
|
966
|
+
* Deletion should be implemented by storing a placeholder object with the property
|
|
967
|
+
* `deleted: true` and a `version` property equal to the provided version. In other words,
|
|
968
|
+
* it should be exactly the same as calling `upsert` with such an object.
|
|
969
|
+
*
|
|
970
|
+
* @param kind
|
|
971
|
+
* The type of data to be accessed. The actual type of this parameter is
|
|
972
|
+
* [[interfaces.DataKind]].
|
|
973
|
+
*
|
|
974
|
+
* @param key
|
|
975
|
+
* The unique key of the entity within the specified collection.
|
|
976
|
+
*
|
|
977
|
+
* @param version
|
|
978
|
+
* A number that must be greater than the `version` property of the existing entity in
|
|
979
|
+
* order for it to be deleted. If it is less than or equal to the existing version, the
|
|
980
|
+
* method should do nothing.
|
|
981
|
+
*
|
|
982
|
+
* @param callback
|
|
983
|
+
* Will be called when the delete operation is complete.
|
|
984
|
+
*/
|
|
985
|
+
delete(kind: object, key: string, version: string, callback: () => void): void;
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Add an entity or update an existing entity.
|
|
989
|
+
*
|
|
990
|
+
* @param kind
|
|
991
|
+
* The type of data to be accessed. The actual type of this parameter is
|
|
992
|
+
* [[interfaces.DataKind]].
|
|
993
|
+
*
|
|
994
|
+
* @param data
|
|
995
|
+
* The contents of the entity, as an object that can be converted to JSON. The store
|
|
996
|
+
* should check the `version` property of this object, and should *not* overwrite any
|
|
997
|
+
* existing data if the existing `version` is greater than or equal to that value.
|
|
998
|
+
* The actual type of this parameter is [[interfaces.VersionedData]].
|
|
999
|
+
*
|
|
1000
|
+
* @param callback
|
|
1001
|
+
* Will be called after the upsert operation is complete.
|
|
1002
|
+
*/
|
|
1003
|
+
upsert(kind: object, data: object, callback: () => void): void;
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Tests whether the store is initialized.
|
|
1007
|
+
*
|
|
1008
|
+
* "Initialized" means that the store has been populated with data, either by the client
|
|
1009
|
+
* having called `init()` within this process, or by another process (if this is a shared
|
|
1010
|
+
* database).
|
|
1011
|
+
*
|
|
1012
|
+
* @param callback
|
|
1013
|
+
* Will be called back with the boolean result.
|
|
1014
|
+
*/
|
|
1015
|
+
initialized(callback: (isInitialized: boolean) => void): void;
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Releases any resources being used by the feature store.
|
|
1019
|
+
*/
|
|
1020
|
+
close(): void;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
/**
|
|
1024
|
+
* The LaunchDarkly client stream processor
|
|
1025
|
+
*
|
|
1026
|
+
* The client uses this internally to retrieve updates from LaunchDarkly.
|
|
1027
|
+
*
|
|
1028
|
+
* @ignore
|
|
1029
|
+
*/
|
|
1030
|
+
export interface LDStreamProcessor {
|
|
1031
|
+
start: (fn?: (err?: any) => void) => void;
|
|
1032
|
+
stop: () => void;
|
|
1033
|
+
close: () => void;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* The LaunchDarkly client feature flag requestor
|
|
1038
|
+
*
|
|
1039
|
+
* The client uses this internally to retrieve feature flags from LaunchDarkly.
|
|
1040
|
+
*
|
|
1041
|
+
* @ignore
|
|
1042
|
+
*/
|
|
1043
|
+
export interface LDFeatureRequestor {
|
|
1044
|
+
requestObject: (
|
|
1045
|
+
kind: any,
|
|
1046
|
+
key: string,
|
|
1047
|
+
cb: (err: any, body: any) => void
|
|
1048
|
+
) => void;
|
|
1049
|
+
requestAllData: (cb: (err: any, body: any) => void) => void;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
/**
|
|
1053
|
+
* Optional settings that can be passed to [[LDClient.allFlagsState]].
|
|
1054
|
+
*/
|
|
1055
|
+
export interface LDFlagsStateOptions {
|
|
1056
|
+
/**
|
|
1057
|
+
* True if the state should include only flags that have been marked for use with the
|
|
1058
|
+
* client-side SDK. By default, all flags are included.
|
|
1059
|
+
*/
|
|
1060
|
+
clientSideOnly?: boolean;
|
|
1061
|
+
/**
|
|
1062
|
+
* True if evaluation reason data should be captured in the state object (see LDClient.variationDetail).
|
|
1063
|
+
* By default, it is not.
|
|
1064
|
+
*/
|
|
1065
|
+
withReasons?: boolean;
|
|
1066
|
+
/**
|
|
1067
|
+
* True if any flag metadata that is normally only used for event generation-- such as flag versions and
|
|
1068
|
+
* evaluation reasons-- should be omitted for any flag that does not have event tracking or debugging turned on.
|
|
1069
|
+
* This reduces the size of the JSON data if you are passing the flag state to the front end.
|
|
1070
|
+
*/
|
|
1071
|
+
detailsOnlyForTrackedFlags?: boolean;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* The LaunchDarkly SDK client object.
|
|
1076
|
+
*
|
|
1077
|
+
* Create this object with [[init]]. Applications should configure the client at startup time and continue
|
|
1078
|
+
* to use it throughout the lifetime of the application, rather than creating instances on the fly.
|
|
1079
|
+
*
|
|
1080
|
+
* Note that `LDClient` inherits from `EventEmitter`, so you can use the standard `on()`, `once()`, and
|
|
1081
|
+
* `off()` methods to receive events. The standard `EventEmitter` methods are not documented here; see the
|
|
1082
|
+
* {@link https://nodejs.org/api/events.html#events_class_eventemitter|Node API documentation}. For a
|
|
1083
|
+
* description of events you can listen for, see [[on]].
|
|
1084
|
+
*
|
|
1085
|
+
* @see {@link https://docs.launchdarkly.com/sdk/server-side/node-js|SDK Reference Guide}
|
|
1086
|
+
*/
|
|
1087
|
+
export interface LDClient extends EventEmitter {
|
|
1088
|
+
/**
|
|
1089
|
+
* Tests whether the client has completed initialization.
|
|
1090
|
+
*
|
|
1091
|
+
* If this returns false, it means that the client has not yet successfully connected to LaunchDarkly.
|
|
1092
|
+
* It might still be in the process of starting up, or it might be attempting to reconnect after an
|
|
1093
|
+
* unsuccessful attempt, or it might have received an unrecoverable error (such as an invalid SDK key)
|
|
1094
|
+
* and given up.
|
|
1095
|
+
*
|
|
1096
|
+
* @returns
|
|
1097
|
+
* True if the client has successfully initialized.
|
|
1098
|
+
*/
|
|
1099
|
+
initialized(): boolean;
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Returns a Promise that tracks the client's initialization state.
|
|
1103
|
+
*
|
|
1104
|
+
* The Promise will be resolved if the client successfully initializes, or rejected if client
|
|
1105
|
+
* initialization has failed unrecoverably (for instance, if it detects that the SDK key is invalid).
|
|
1106
|
+
* Keep in mind that unhandled Promise rejections can be fatal in Node, so if you call this method,
|
|
1107
|
+
* be sure to attach a rejection handler to it (or, if using `async`/`await`, a catch block).
|
|
1108
|
+
*
|
|
1109
|
+
* Note that you can also use event listeners ([[on]]) for the same purpose: the event `"ready"`
|
|
1110
|
+
* indicates success, and `"failed"` indicates failure.
|
|
1111
|
+
*
|
|
1112
|
+
* There is no built-in timeout for this method. If you want your code to stop waiting on the
|
|
1113
|
+
* Promise after some amount of time, you could use
|
|
1114
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race|`Promise.race()`}
|
|
1115
|
+
* or one of the several NPM helper packages that provides a standard mechanism for this. Regardless
|
|
1116
|
+
* of whether you continue to wait, the SDK will still retry all connection failures indefinitely
|
|
1117
|
+
* unless it gets an unrecoverable error as described above.
|
|
1118
|
+
*
|
|
1119
|
+
* @returns
|
|
1120
|
+
* A Promise that will be resolved if the client initializes successfully, or rejected if it
|
|
1121
|
+
* fails. If successful, the result is the same client object.
|
|
1122
|
+
*
|
|
1123
|
+
* @example
|
|
1124
|
+
* This example shows use of Promise chaining methods for specifying handlers:
|
|
1125
|
+
* ```javascript
|
|
1126
|
+
* client.waitForInitialization().then(() => {
|
|
1127
|
+
* // do whatever is appropriate if initialization has succeeded
|
|
1128
|
+
* }).catch(err => {
|
|
1129
|
+
* // do whatever is appropriate if initialization has failed
|
|
1130
|
+
* })
|
|
1131
|
+
* ```
|
|
1132
|
+
*
|
|
1133
|
+
* @example
|
|
1134
|
+
* This example shows use of `async`/`await` syntax for specifying handlers:
|
|
1135
|
+
* ```javascript
|
|
1136
|
+
* try {
|
|
1137
|
+
* await client.waitForInitialization();
|
|
1138
|
+
* // do whatever is appropriate if initialization has succeeded
|
|
1139
|
+
* } catch (err) {
|
|
1140
|
+
* // do whatever is appropriate if initialization has failed
|
|
1141
|
+
* }
|
|
1142
|
+
* ```
|
|
1143
|
+
*/
|
|
1144
|
+
waitForInitialization(): Promise<LDClient>;
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* Determines the variation of a feature flag for a context.
|
|
1148
|
+
*
|
|
1149
|
+
* @param key
|
|
1150
|
+
* The unique key of the feature flag.
|
|
1151
|
+
* @param context
|
|
1152
|
+
* The context requesting the flag. The client will generate an analytics event to register
|
|
1153
|
+
* this context with LaunchDarkly if the context does not already exist.
|
|
1154
|
+
* @param defaultValue
|
|
1155
|
+
* The default value of the flag, to be used if the value is not available from LaunchDarkly.
|
|
1156
|
+
* @param callback
|
|
1157
|
+
* A Node-style callback to receive the result value. If omitted, you will receive a Promise instead.
|
|
1158
|
+
* @returns
|
|
1159
|
+
* If you provided a callback, then nothing. Otherwise, a Promise which will be resolved
|
|
1160
|
+
* with the result value.
|
|
1161
|
+
*/
|
|
1162
|
+
variation(
|
|
1163
|
+
key: string,
|
|
1164
|
+
context: LDContext,
|
|
1165
|
+
defaultValue: LDFlagValue,
|
|
1166
|
+
callback?: (err: any, res: LDFlagValue) => void
|
|
1167
|
+
): Promise<LDFlagValue>;
|
|
1168
|
+
|
|
1169
|
+
/**
|
|
1170
|
+
* Determines the variation of a feature flag for a context, along with information about how it was
|
|
1171
|
+
* calculated.
|
|
1172
|
+
*
|
|
1173
|
+
* The `reason` property of the result will also be included in analytics events, if you are
|
|
1174
|
+
* capturing detailed event data for this flag.
|
|
1175
|
+
*
|
|
1176
|
+
* For more information, see the [SDK reference guide](https://docs.launchdarkly.com/sdk/features/evaluation-reasons#nodejs-server-side).
|
|
1177
|
+
*
|
|
1178
|
+
* @param key
|
|
1179
|
+
* The unique key of the feature flag.
|
|
1180
|
+
* @param context
|
|
1181
|
+
* The context requesting the flag. The client will generate an analytics event to register
|
|
1182
|
+
* this context with LaunchDarkly if the context does not already exist.
|
|
1183
|
+
* @param defaultValue
|
|
1184
|
+
* The default value of the flag, to be used if the value is not available from LaunchDarkly.
|
|
1185
|
+
* @param callback
|
|
1186
|
+
* A Node-style callback to receive the result (as an [[LDEvaluationDetail]]). If omitted, you
|
|
1187
|
+
* will receive a Promise instead.
|
|
1188
|
+
* @returns
|
|
1189
|
+
* If you provided a callback, then nothing. Otherwise, a Promise which will be resolved
|
|
1190
|
+
* with the result (as an [[LDEvaluationDetail]]).
|
|
1191
|
+
*/
|
|
1192
|
+
variationDetail(
|
|
1193
|
+
key: string,
|
|
1194
|
+
context: LDContext,
|
|
1195
|
+
defaultValue: LDFlagValue,
|
|
1196
|
+
callback?: (err: any, res: LDEvaluationDetail) => void
|
|
1197
|
+
): Promise<LDEvaluationDetail>;
|
|
1198
|
+
|
|
1199
|
+
/**
|
|
1200
|
+
* Builds an object that encapsulates the state of all feature flags for a given context.
|
|
1201
|
+
* This includes the flag values and also metadata that can be used on the front end. This
|
|
1202
|
+
* method does not send analytics events back to LaunchDarkly.
|
|
1203
|
+
*
|
|
1204
|
+
* The most common use case for this method is to bootstrap a set of client-side
|
|
1205
|
+
* feature flags from a back-end service. Call the `toJSON()` method of the returned object
|
|
1206
|
+
* to convert it to the data structure used by the client-side SDK.
|
|
1207
|
+
*
|
|
1208
|
+
* @param context
|
|
1209
|
+
* The context requesting the feature flags.
|
|
1210
|
+
* @param options
|
|
1211
|
+
* Optional [[LDFlagsStateOptions]] to determine how the state is computed.
|
|
1212
|
+
* @param callback
|
|
1213
|
+
* A Node-style callback to receive the result (as an [[LDFlagsState]]). If omitted, you
|
|
1214
|
+
* will receive a Promise instead.
|
|
1215
|
+
* @returns
|
|
1216
|
+
* If you provided a callback, then nothing. Otherwise, a Promise which will be resolved
|
|
1217
|
+
* with the result as an [[LDFlagsState]].
|
|
1218
|
+
*/
|
|
1219
|
+
allFlagsState(
|
|
1220
|
+
context: LDContext,
|
|
1221
|
+
options?: LDFlagsStateOptions,
|
|
1222
|
+
callback?: (err: Error, res: LDFlagsState) => void
|
|
1223
|
+
): Promise<LDFlagsState>;
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Computes an HMAC signature of a context signed with the client's SDK key.
|
|
1227
|
+
*
|
|
1228
|
+
* For more information, see the JavaScript SDK Reference Guide on
|
|
1229
|
+
* [Secure mode](https://github.com/launchdarkly/js-client#secure-mode).
|
|
1230
|
+
*
|
|
1231
|
+
* @param context
|
|
1232
|
+
* The context properties.
|
|
1233
|
+
*
|
|
1234
|
+
* @returns
|
|
1235
|
+
* The hash string.
|
|
1236
|
+
*/
|
|
1237
|
+
secureModeHash(context: LDContext): string;
|
|
1238
|
+
|
|
1239
|
+
/**
|
|
1240
|
+
* Discards all network connections, background tasks, and other resources held by the client.
|
|
1241
|
+
*
|
|
1242
|
+
* Do not attempt to use the client after calling this method.
|
|
1243
|
+
*/
|
|
1244
|
+
close(): void;
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Tests whether the client is configured in offline mode.
|
|
1248
|
+
*
|
|
1249
|
+
* @returns
|
|
1250
|
+
* True if the `offline` property is true in your [[LDOptions]].
|
|
1251
|
+
*/
|
|
1252
|
+
isOffline(): boolean;
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Tracks that a context performed an event.
|
|
1256
|
+
*
|
|
1257
|
+
* LaunchDarkly automatically tracks pageviews and clicks that are specified in the Metrics
|
|
1258
|
+
* section of the dashboard. This can be used to track custom metrics (goals) or other events that do
|
|
1259
|
+
* not currently have metrics.
|
|
1260
|
+
*
|
|
1261
|
+
* Note that event delivery is asynchronous, so the event may not actually be sent until later;
|
|
1262
|
+
* see [[flush]].
|
|
1263
|
+
*
|
|
1264
|
+
* If the context is omitted or has no key, the client will log a warning and will not send an event.
|
|
1265
|
+
*
|
|
1266
|
+
* @param key
|
|
1267
|
+
* The name of the event, which may correspond to a metric in experiments.
|
|
1268
|
+
* @param context
|
|
1269
|
+
* The context to track.
|
|
1270
|
+
* @param data
|
|
1271
|
+
* Optional additional information to associate with the event.
|
|
1272
|
+
* @param metricValue
|
|
1273
|
+
* A numeric value used by the LaunchDarkly experimentation feature in numeric custom metrics. Can
|
|
1274
|
+
* be omitted if this event is used by only non-numeric metrics. This field will also be returned
|
|
1275
|
+
* as part of the custom event for Data Export.
|
|
1276
|
+
*/
|
|
1277
|
+
track(key: string, context: LDContext, data?: any, metricValue?: number): void;
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Identifies a context to LaunchDarkly.
|
|
1281
|
+
*
|
|
1282
|
+
* This simply creates an analytics event that will transmit the given user properties to
|
|
1283
|
+
* LaunchDarkly, so that the context will be visible on your dashboard even if you have not
|
|
1284
|
+
* evaluated any flags for that user. It has no other effect.
|
|
1285
|
+
*
|
|
1286
|
+
* If the context is omitted or has no key, the client will log a warning
|
|
1287
|
+
* and will not send an event.
|
|
1288
|
+
*
|
|
1289
|
+
* @param context
|
|
1290
|
+
* The context properties. Must contain at least the `key` property.
|
|
1291
|
+
*/
|
|
1292
|
+
identify(context: LDContext): void;
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* Flushes all pending analytics events.
|
|
1296
|
+
*
|
|
1297
|
+
* Normally, batches of events are delivered in the background at intervals determined by the
|
|
1298
|
+
* `flushInterval` property of [[LDOptions]]. Calling `flush()` triggers an immediate delivery.
|
|
1299
|
+
* However, like Node I/O in general, this is still an asynchronous operation so you must still
|
|
1300
|
+
* use Promise chaining, a callback, or `async`/`await` to detect when it has finished or failed.
|
|
1301
|
+
*
|
|
1302
|
+
* @param callback
|
|
1303
|
+
* A function which will be called when the flush completes (meaning that all pending events
|
|
1304
|
+
* have been delivered to LaunchDarkly). If omitted, you will receive a Promise instead.
|
|
1305
|
+
*
|
|
1306
|
+
* @returns
|
|
1307
|
+
* If you provided a callback, then nothing. Otherwise, a Promise which resolves once
|
|
1308
|
+
* flushing is finished. Note that the Promise will be rejected if the HTTP request
|
|
1309
|
+
* fails, so be sure to attach a rejection handler to it.
|
|
1310
|
+
*/
|
|
1311
|
+
flush(callback?: (err: Error, res: boolean) => void): Promise<void>;
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
* A mechanism for tracking the status of a Big Segment store.
|
|
1315
|
+
*
|
|
1316
|
+
* This object has methods for checking whether the Big Segment store is (as far as the SDK
|
|
1317
|
+
* knows) currently operational and tracking changes in this status. See
|
|
1318
|
+
* {@link interfaces.BigSegmentStoreStatusProvider} for more about this functionality.
|
|
1319
|
+
*/
|
|
1320
|
+
readonly bigSegmentStoreStatusProvider: interfaces.BigSegmentStoreStatusProvider;
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* Registers an event listener that will be called when the client triggers some type of event.
|
|
1324
|
+
*
|
|
1325
|
+
* This is the standard `on` method inherited from Node's `EventEmitter`; see the
|
|
1326
|
+
* {@link https://nodejs.org/api/events.html#events_class_eventemitter|Node API docs} for more
|
|
1327
|
+
* details on how to manage event listeners. Here is a description of the event types defined
|
|
1328
|
+
* by `LDClient`.
|
|
1329
|
+
*
|
|
1330
|
+
* - `"ready"`: Sent only once, when the client has successfully connected to LaunchDarkly.
|
|
1331
|
+
* Alternately, you can detect this with [[waitForInitialization]].
|
|
1332
|
+
* - `"failed"`: Sent only once, if the client has permanently failed to connect to LaunchDarkly.
|
|
1333
|
+
* Alternately, you can detect this with [[waitForInitialization]].
|
|
1334
|
+
* - `"error"`: Contains an error object describing some abnormal condition that the client has detected
|
|
1335
|
+
* (such as a network error).
|
|
1336
|
+
* - `"update"`: The client has received a change to a feature flag. The event parameter is an object
|
|
1337
|
+
* containing a single property, `key`, the flag key. Note that this does not necessarily mean the flag's
|
|
1338
|
+
* value has changed for any particular context, only that some part of the flag configuration was changed.
|
|
1339
|
+
* - `"update:KEY"`: The client has received a change to the feature flag whose key is KEY. This is the
|
|
1340
|
+
* same as `"update"` but allows you to listen for a specific flag.
|
|
1341
|
+
*
|
|
1342
|
+
* @param event the name of the event to listen for
|
|
1343
|
+
* @param listener the function to call when the event happens
|
|
1344
|
+
*/
|
|
1345
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1346
|
+
|
|
1347
|
+
// The following are symbols that LDClient inherits from EventEmitter, which we are declaring
|
|
1348
|
+
// again here only so that we can use @ignore to exclude them from the generated docs.
|
|
1349
|
+
// Unfortunately it does not seem possible to exclude these inherited methods en masse without
|
|
1350
|
+
// using a Typedoc plugin.
|
|
1351
|
+
|
|
1352
|
+
/** @ignore */ addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1353
|
+
/** @ignore */ emit(event: string | symbol, ...args: any[]): boolean;
|
|
1354
|
+
/** @ignore */ eventNames(): Array<string | symbol>;
|
|
1355
|
+
/** @ignore */ getMaxListeners(): number;
|
|
1356
|
+
/** @ignore */ listenerCount(type: string | symbol): number;
|
|
1357
|
+
/** @ignore */ listeners(event: string | symbol): Function[];
|
|
1358
|
+
/** @ignore */ prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1359
|
+
/** @ignore */ prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1360
|
+
/** @ignore */ rawListeners(event: string | symbol): Function[];
|
|
1361
|
+
/** @ignore */ removeAllListeners(event?: string | symbol): this;
|
|
1362
|
+
/** @ignore */ removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1363
|
+
/** @ignore */ setMaxListeners(n: number): this;
|
|
1364
|
+
/** @ignore */ once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1365
|
+
/** @ignore */ off(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Provides a simple [[LDLogger]] implementation.
|
|
1370
|
+
*
|
|
1371
|
+
* This logging implementation uses a simple format that includes only the log level
|
|
1372
|
+
* and the message text. Output is written to the standard error stream (`console.error`).
|
|
1373
|
+
* You can filter by log level as described in [[BasicLoggerOptions.level]].
|
|
1374
|
+
*
|
|
1375
|
+
* To use the logger created by this function, put it into [[LDOptions.logger]]. If
|
|
1376
|
+
* you do not set [[LDOptions.logger]] to anything, the SDK uses a default logger
|
|
1377
|
+
* that is equivalent to `ld.basicLogger({ level: 'info' })`.
|
|
1378
|
+
*
|
|
1379
|
+
* @param options Configuration for the logger. If no options are specified, the
|
|
1380
|
+
* logger uses `{ level: 'info' }`.
|
|
1381
|
+
*
|
|
1382
|
+
* @example
|
|
1383
|
+
* This example shows how to use `basicLogger` in your SDK options to enable console
|
|
1384
|
+
* logging only at `warn` and `error` levels.
|
|
1385
|
+
* ```javascript
|
|
1386
|
+
* const ldOptions = {
|
|
1387
|
+
* logger: ld.basicLogger({ level: 'warn' }),
|
|
1388
|
+
* };
|
|
1389
|
+
* ```
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* This example shows how to use `basicLogger` in your SDK options to cause log
|
|
1393
|
+
* output to go to `console.log` instead of `console.error`.
|
|
1394
|
+
* ```javascript
|
|
1395
|
+
* const ldOptions = {
|
|
1396
|
+
* logger: ld.basicLogger({ destination: console.log }),
|
|
1397
|
+
* };
|
|
1398
|
+
* ```
|
|
1399
|
+
*/
|
|
1400
|
+
export function basicLogger(
|
|
1401
|
+
options?: BasicLoggerOptions
|
|
1402
|
+
): LDLogger;
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* Configuration for [[basicLogger]].
|
|
1406
|
+
*/
|
|
1407
|
+
export interface BasicLoggerOptions {
|
|
1408
|
+
/**
|
|
1409
|
+
* The lowest level of log message to enable.
|
|
1410
|
+
*
|
|
1411
|
+
* See [[LDLogLevel]] for a list of possible levels. Setting a level here causes
|
|
1412
|
+
* all lower-importance levels to be disabled: for instance, if you specify
|
|
1413
|
+
* `'warn'`, then `'debug'` and `'info'` are disabled.
|
|
1414
|
+
*
|
|
1415
|
+
* If not specified, the default is `'info'` (meaning that `'debug'` is disabled).
|
|
1416
|
+
*/
|
|
1417
|
+
level?: LDLogLevel;
|
|
1418
|
+
|
|
1419
|
+
/**
|
|
1420
|
+
* An optional function to use to print each log line.
|
|
1421
|
+
*
|
|
1422
|
+
* If this is specified, `basicLogger` calls it to write each line of output. The
|
|
1423
|
+
* argument is a fully formatted log line, not including a linefeed. The function
|
|
1424
|
+
* is only called for log levels that are enabled.
|
|
1425
|
+
*
|
|
1426
|
+
* If not specified, the default is `console.error`.
|
|
1427
|
+
*
|
|
1428
|
+
* Setting this property to anything other than a function will cause SDK
|
|
1429
|
+
* initialization to fail.
|
|
1430
|
+
*/
|
|
1431
|
+
destination?: (line: string) => void,
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* Logging levels that can be used with [[basicLogger]].
|
|
1436
|
+
*
|
|
1437
|
+
* Set [[BasicLoggerOptions.level]] to one of these values to control what levels
|
|
1438
|
+
* of log messages are enabled. Going from lowest importance (and most verbose)
|
|
1439
|
+
* to most importance, the levels are `'debug'`, `'info'`, `'warn'`, and `'error'`.
|
|
1440
|
+
* You can also specify `'none'` instead to disable all logging.
|
|
1441
|
+
*/
|
|
1442
|
+
export type LDLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
1443
|
+
|
|
1444
|
+
/**
|
|
1445
|
+
* Configuration for [[FileDataSource]].
|
|
1446
|
+
*
|
|
1447
|
+
* @deprecated Import this type from the `launchdarkly-node-server-sdk/integrations` module instead.
|
|
1448
|
+
* It will be removed from the main SDK module in a future release.
|
|
1449
|
+
*/
|
|
1450
|
+
export interface FileDataSourceOptions {
|
|
1451
|
+
paths: Array<string>;
|
|
1452
|
+
autoUpdate?: boolean;
|
|
1453
|
+
logger?: LDLogger | object;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
* Creates an object that allows you to use local files as a source of feature flag state,
|
|
1458
|
+
* instead of connecting to LaunchDarkly. This would typically be used in a test environment.
|
|
1459
|
+
*
|
|
1460
|
+
* @deprecated Import this function from the `launchdarkly-node-server-sdk/integrations` module instead.
|
|
1461
|
+
* It will be removed from the main SDK module in a future release.
|
|
1462
|
+
*/
|
|
1463
|
+
export function FileDataSource(
|
|
1464
|
+
options: FileDataSourceOptions
|
|
1465
|
+
): object;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
/**
|
|
1469
|
+
* This module contains tools for connecting the LaunchDarkly client to other software, or
|
|
1470
|
+
* to test fixtures.
|
|
1471
|
+
*/
|
|
1472
|
+
declare module 'launchdarkly-node-server-sdk/integrations' {
|
|
1473
|
+
import { LDLogger } from 'launchdarkly-node-server-sdk';
|
|
1474
|
+
|
|
1475
|
+
/**
|
|
1476
|
+
* Configuration for [[FileDataSource]].
|
|
1477
|
+
*/
|
|
1478
|
+
export interface FileDataSourceOptions {
|
|
1479
|
+
/**
|
|
1480
|
+
* The path(s) of the file(s) that FileDataSource will read.
|
|
1481
|
+
*/
|
|
1482
|
+
paths: Array<string>;
|
|
1483
|
+
|
|
1484
|
+
/**
|
|
1485
|
+
* True if FileDataSource should reload flags whenever one of the data files is modified.
|
|
1486
|
+
* This feature uses Node's `fs.watch()` API, so it is subject to
|
|
1487
|
+
* the limitations described [here](https://nodejs.org/docs/latest/api/fs.html#fs_fs_watch_filename_options_listener).
|
|
1488
|
+
*/
|
|
1489
|
+
autoUpdate?: boolean;
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* Configures a logger for warnings and errors. This can be a custom logger or an instance of
|
|
1493
|
+
* `winston.Logger`. By default, it uses the same logger as the rest of the SDK.
|
|
1494
|
+
*/
|
|
1495
|
+
logger?: LDLogger | object;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* Creates an object that allows you to use local files as a source of feature flag state,
|
|
1500
|
+
* instead of connecting to LaunchDarkly. This would typically be used in a test environment.
|
|
1501
|
+
*
|
|
1502
|
+
* For more information about this feature, see the
|
|
1503
|
+
* [SDK features guide](https://docs.launchdarkly.com/sdk/features/flags-from-files#nodejs-server-side).
|
|
1504
|
+
*
|
|
1505
|
+
* To use this component, call `FileDataSource(options)` and store the result in the `updateProcessor`
|
|
1506
|
+
* property of your LaunchDarkly client configuration:
|
|
1507
|
+
*
|
|
1508
|
+
* const { FileDataSource } = require('launchdarkly-node-server-sdk/integrations');
|
|
1509
|
+
*
|
|
1510
|
+
* const dataSource = FileDataSource({ paths: [ myFilePath ] });
|
|
1511
|
+
* const config = { updateProcessor: dataSource };
|
|
1512
|
+
*
|
|
1513
|
+
* This will cause the client not to connect to LaunchDarkly to get feature flags, and use
|
|
1514
|
+
* the file data instead.
|
|
1515
|
+
*
|
|
1516
|
+
* The client may still make network connections to send analytics events, unless you have
|
|
1517
|
+
* disabled this in your configuration by setting [[LDOptions.sendEvents]] to `false`.
|
|
1518
|
+
*
|
|
1519
|
+
* The supported file formats are as follows:
|
|
1520
|
+
*
|
|
1521
|
+
* - JSON files in the format described in the
|
|
1522
|
+
* [SDK features guide](https://docs.launchdarkly.com/sdk/features/flags-from-files#nodejs-server-side)
|
|
1523
|
+
* are always supported.
|
|
1524
|
+
* - The SDK can also read YAML files with an equivalent schema, if you explicitly install
|
|
1525
|
+
* the [`yaml`](https://www.npmjs.com/package/yaml) package in your application. This
|
|
1526
|
+
* package is not installed by default, to avoid adding to the size of the SDK bundle
|
|
1527
|
+
* for this rarely-used feature. The SDK is compatible with any version of the package
|
|
1528
|
+
* that supports calling `yaml.parse(string)` with no custom options.
|
|
1529
|
+
*
|
|
1530
|
+
* @param options
|
|
1531
|
+
* Configuration for the data source. You should at least set the `paths` property.
|
|
1532
|
+
* @returns
|
|
1533
|
+
* An object to put in the `updateProcessor` property for [[LDOptions]].
|
|
1534
|
+
*/
|
|
1535
|
+
export function FileDataSource(
|
|
1536
|
+
options: FileDataSourceOptions
|
|
1537
|
+
): object;
|
|
1538
|
+
|
|
1539
|
+
/**
|
|
1540
|
+
* A mechanism for providing dynamically updatable feature flag state in a simplified form to
|
|
1541
|
+
* an SDK client in test scenarios.
|
|
1542
|
+
*
|
|
1543
|
+
* This function constructs a new [[TestData]] object. See [[TestData]] for usage details.
|
|
1544
|
+
*
|
|
1545
|
+
* @example
|
|
1546
|
+
* const { TestData } = require('launchdarkly-node-server-sdk/interfaces');
|
|
1547
|
+
*
|
|
1548
|
+
* const td = TestData();
|
|
1549
|
+
* testData.update(td.flag("flag-key-1").booleanFlag().variationForAll(true));
|
|
1550
|
+
* const client = new LDClient(sdkKey, { updateProcessor: td });
|
|
1551
|
+
*
|
|
1552
|
+
* // flags can be updated at any time:
|
|
1553
|
+
* td.update(td.flag("flag-key-2")
|
|
1554
|
+
* .variationForContext("user", "some-user-key", true)
|
|
1555
|
+
* .fallthroughVariation(false));
|
|
1556
|
+
*/
|
|
1557
|
+
export function TestData(): TestData;
|
|
1558
|
+
|
|
1559
|
+
/**
|
|
1560
|
+
* A mechanism for providing dynamically updatable feature flag state in a simplified form to an SDK
|
|
1561
|
+
* client in test scenarios.
|
|
1562
|
+
*
|
|
1563
|
+
* Unlike [[FileData]], this mechanism does not use any external resources. It provides only
|
|
1564
|
+
* the data that the application has put into it using the [[TestData.update]] method.
|
|
1565
|
+
*
|
|
1566
|
+
* @example
|
|
1567
|
+
* const { TestData } = require('launchdarkly-node-server-sdk/interfaces');
|
|
1568
|
+
*
|
|
1569
|
+
* const td = TestData();
|
|
1570
|
+
* testData.update(td.flag("flag-key-1").booleanFlag().variationForAll(true));
|
|
1571
|
+
* const client = new LDClient(sdkKey, { updateProcessor: td });
|
|
1572
|
+
*
|
|
1573
|
+
* // flags can be updated at any time:
|
|
1574
|
+
* td.update(td.flag("flag-key-2")
|
|
1575
|
+
* .variationForContext("user", "some-user-key", true)
|
|
1576
|
+
* .fallthroughVariation(false));
|
|
1577
|
+
*
|
|
1578
|
+
* The above example uses a simple boolean flag, but more complex configurations are possible using
|
|
1579
|
+
* the methods of the [[TestDataFlagBuilder]] that is returned by [[TestData.flag]]. [[TestDataFlagBuilder]]
|
|
1580
|
+
* supports many of the ways a flag can be configured on the LaunchDarkly dashboard, but does not
|
|
1581
|
+
* currently support 1. rule operators other than "in" and "not in", or 2. percentage rollouts.
|
|
1582
|
+
*
|
|
1583
|
+
* If the same `TestData` instance is used to configure multiple `LDClient` instances,
|
|
1584
|
+
* any changes made to the data will propagate to all of the `LDClient`s.
|
|
1585
|
+
*
|
|
1586
|
+
* @see [[FileDataSource]]
|
|
1587
|
+
*/
|
|
1588
|
+
export interface TestData {
|
|
1589
|
+
/**
|
|
1590
|
+
* Creates or copies a [[TestDataFlagBuilder]] for building a test flag configuration.
|
|
1591
|
+
*
|
|
1592
|
+
* If the flag key has already been defined in this `TestData` instance,
|
|
1593
|
+
* then the builder starts with the same configuration that was last
|
|
1594
|
+
* provided for this flag.
|
|
1595
|
+
*
|
|
1596
|
+
* Otherwise, it starts with a new default configuration in which the flag
|
|
1597
|
+
* has `true` and `false` variations, is `true` for all users when targeting
|
|
1598
|
+
* is turned on and `false` otherwise, and currently has targeting turned on.
|
|
1599
|
+
* You can change any of those properties and provide more complex behavior
|
|
1600
|
+
* using the `TestDataFlagBuilder` methods.
|
|
1601
|
+
*
|
|
1602
|
+
* Once you have set the desired configuration, pass the builder to
|
|
1603
|
+
* [[TestData.update]].
|
|
1604
|
+
*
|
|
1605
|
+
* @param key the flag key
|
|
1606
|
+
* @returns a flag configuration builder
|
|
1607
|
+
*
|
|
1608
|
+
*/
|
|
1609
|
+
flag(key: string): TestDataFlagBuilder;
|
|
1610
|
+
|
|
1611
|
+
/**
|
|
1612
|
+
* Updates the test data with the specified flag configuration.
|
|
1613
|
+
*
|
|
1614
|
+
* This has the same effect as if a flag were added or modified in the
|
|
1615
|
+
* LaunchDarkly dashboard. It immediately propagates the flag changes to
|
|
1616
|
+
* any [[LDClient]] instance(s) that you have already configured to use
|
|
1617
|
+
* this `TestData`. If no `LDClient` has been started yet, it simply adds
|
|
1618
|
+
* this flag to the test data which will be provided to any `LDClient`
|
|
1619
|
+
* that you subsequently configure.
|
|
1620
|
+
*
|
|
1621
|
+
* Any subsequent changes to this `TestDataFlagBuilder` instance do not affect
|
|
1622
|
+
* the test data unless you call `update` again.
|
|
1623
|
+
*
|
|
1624
|
+
* @param flagBuilder a flag configuration builder
|
|
1625
|
+
* @return a promise that will resolve when the feature stores are updated
|
|
1626
|
+
*/
|
|
1627
|
+
update(flagBuilder: TestDataFlagBuilder): Promise<any>;
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* Copies a full feature flag data model object into the test data.
|
|
1631
|
+
*
|
|
1632
|
+
* It immediately propagates the flag change to any [[LDClient]] instance(s) that you have already
|
|
1633
|
+
* configured to use this `TestData`. If no [[LDClient]] has been started yet, it simply adds
|
|
1634
|
+
* this flag to the test data which will be provided to any LDClient that you subsequently
|
|
1635
|
+
* configure.
|
|
1636
|
+
*
|
|
1637
|
+
* Use this method if you need to use advanced flag configuration properties that are not supported by
|
|
1638
|
+
* the simplified [[TestDataFlagBuilder]] API. Otherwise it is recommended to use the regular
|
|
1639
|
+
* [[flag]]/[[update]] mechanism to avoid dependencies on details of the data model.
|
|
1640
|
+
*
|
|
1641
|
+
* You cannot make incremental changes with [[flag]]/[[update]] to a flag that has been added in this way;
|
|
1642
|
+
* you can only replace it with an entirely new flag configuration.
|
|
1643
|
+
*
|
|
1644
|
+
* @param flagConfig the flag configuration as a JSON object
|
|
1645
|
+
* @return a promise that will resolve when the feature stores are updated
|
|
1646
|
+
*/
|
|
1647
|
+
usePreconfiguredFlag(flagConfig: any): Promise<any>;
|
|
1648
|
+
|
|
1649
|
+
/**
|
|
1650
|
+
* Copies a full segment data model object into the test data.
|
|
1651
|
+
*
|
|
1652
|
+
* It immediately propagates the change to any [[LDClient]] instance(s) that you have already
|
|
1653
|
+
* configured to use this `TestData`. If no [[LDClient]] has been started yet, it simply adds
|
|
1654
|
+
* this segment to the test data which will be provided to any LDClient that you subsequently
|
|
1655
|
+
* configure.
|
|
1656
|
+
*
|
|
1657
|
+
* This method is currently the only way to inject segment data, since there is no builder
|
|
1658
|
+
* API for segments. It is mainly intended for the SDK's own tests of segment functionality,
|
|
1659
|
+
* since application tests that need to produce a desired evaluation state could do so more easily
|
|
1660
|
+
* by just setting flag values.
|
|
1661
|
+
*
|
|
1662
|
+
* @param segmentConfig the segment configuration as a JSON object
|
|
1663
|
+
* @return a promise that will resolve when the feature stores are updated
|
|
1664
|
+
*/
|
|
1665
|
+
usePreconfiguredSegment(segmentConfig: any): Promise<any>;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* A builder for feature flag configurations to be used with [[TestData]].
|
|
1670
|
+
*/
|
|
1671
|
+
export interface TestDataFlagBuilder {
|
|
1672
|
+
/**
|
|
1673
|
+
* A shortcut for setting the flag to use the standard boolean configuration.
|
|
1674
|
+
*
|
|
1675
|
+
* This is the default for all new flags created with [[TestData.flag]]. The
|
|
1676
|
+
* flag will have two variations, `true` and `false` (in that order). It
|
|
1677
|
+
* will return `false` whenever targeting is off and `true` when targeting
|
|
1678
|
+
* is on unless other settings specify otherwise.
|
|
1679
|
+
*
|
|
1680
|
+
* @return the flag builder
|
|
1681
|
+
*/
|
|
1682
|
+
booleanFlag(): TestDataFlagBuilder;
|
|
1683
|
+
|
|
1684
|
+
/**
|
|
1685
|
+
* Sets the allowable variation values for the flag.
|
|
1686
|
+
*
|
|
1687
|
+
* The values may be of any JSON-compatible type: boolean, number, string, array,
|
|
1688
|
+
* or object. For instance, a boolean flag normally has `variations(true, false)`;
|
|
1689
|
+
* a string-valued flag might have `variations("red", "green")`; etc.
|
|
1690
|
+
*
|
|
1691
|
+
* @param values any number of variation values
|
|
1692
|
+
* @return the flag builder
|
|
1693
|
+
*/
|
|
1694
|
+
variations(...values: any[]): TestDataFlagBuilder;
|
|
1695
|
+
|
|
1696
|
+
/**
|
|
1697
|
+
* Sets targeting to be on or off for this flag.
|
|
1698
|
+
*
|
|
1699
|
+
* The effect of this depends on the rest of the flag configuration, just
|
|
1700
|
+
* as it does on the real LaunchDarkly dashboard. In the default configuration
|
|
1701
|
+
* that you get from calling [[TestData.flag]] with a new flag key, the flag
|
|
1702
|
+
* will return `false` whenever targeting is off and `true` when targeting
|
|
1703
|
+
* is on.
|
|
1704
|
+
*
|
|
1705
|
+
* @param targetingOn true if targeting should be on
|
|
1706
|
+
* @return the flag builder
|
|
1707
|
+
*/
|
|
1708
|
+
on(targetingOn: boolean): TestDataFlagBuilder;
|
|
1709
|
+
|
|
1710
|
+
/**
|
|
1711
|
+
* Specifies the fallthrough variation for a flag. The fallthrough is
|
|
1712
|
+
* the value that is returned if targeting is on and the user was not
|
|
1713
|
+
* matched by a more specific target or rule.
|
|
1714
|
+
*
|
|
1715
|
+
* If a boolean is supplied, and the flag was previously configured with
|
|
1716
|
+
* other variations, this also changes it to a boolean flag.
|
|
1717
|
+
*
|
|
1718
|
+
* @param variation
|
|
1719
|
+
* either `true` or `false` or the index of the desired fallthrough
|
|
1720
|
+
* variation: 0 for the first, 1 for the second, etc.
|
|
1721
|
+
* @return the flag builder
|
|
1722
|
+
*/
|
|
1723
|
+
fallthroughVariation(variation: boolean | number): TestDataFlagBuilder;
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* Specifies the off variation for a flag. This is the variation that is
|
|
1727
|
+
* returned whenever targeting is off.
|
|
1728
|
+
*
|
|
1729
|
+
* If a boolean is supplied, and the flag was previously configured with
|
|
1730
|
+
* other variations, this also changes it to a boolean flag.
|
|
1731
|
+
*
|
|
1732
|
+
* @param variation
|
|
1733
|
+
* either `true` or `false` or the index of the desired off
|
|
1734
|
+
* variation: 0 for the first, 1 for the second, etc.
|
|
1735
|
+
* @return the flag builder
|
|
1736
|
+
*/
|
|
1737
|
+
offVariation(variation: boolean | number): TestDataFlagBuilder;
|
|
1738
|
+
|
|
1739
|
+
/**
|
|
1740
|
+
* Sets the flag to always return the specified variation for all contexts.
|
|
1741
|
+
*
|
|
1742
|
+
* Targeting is switched on, any existing targets or rules are removed,
|
|
1743
|
+
* and the fallthrough variation is set to the specified value. The off
|
|
1744
|
+
* variation is left unchanged.
|
|
1745
|
+
*
|
|
1746
|
+
* If a boolean is supplied, and the flag was previously configured with
|
|
1747
|
+
* other variations, this also changes it to a boolean flag.
|
|
1748
|
+
*
|
|
1749
|
+
* @param varation
|
|
1750
|
+
* either `true` or `false` or the index of the desired variation:
|
|
1751
|
+
* 0 for the first, 1 for the second, etc.
|
|
1752
|
+
* @return the flag builder
|
|
1753
|
+
*/
|
|
1754
|
+
variationForAll(variation: boolean | number): TestDataFlagBuilder;
|
|
1755
|
+
|
|
1756
|
+
/**
|
|
1757
|
+
* Sets the flag to always return the specified variation value for all contexts.
|
|
1758
|
+
*
|
|
1759
|
+
* The value may be of any valid JSON type. This method changes the flag to have
|
|
1760
|
+
* only a single variation, which is this value, and to return the same variation
|
|
1761
|
+
* regardless of whether targeting is on or off. Any existing targets or rules
|
|
1762
|
+
* are removed.
|
|
1763
|
+
*
|
|
1764
|
+
* @param value The desired value to be returned for all contexts.
|
|
1765
|
+
* @return the flag builder
|
|
1766
|
+
*/
|
|
1767
|
+
valueForAll(value: any): TestDataFlagBuilder;
|
|
1768
|
+
|
|
1769
|
+
/**
|
|
1770
|
+
* Sets the flag to return the specified variation for a specific context key
|
|
1771
|
+
* when targeting is on. The context kind for contexts created with this method
|
|
1772
|
+
* will be 'user'.
|
|
1773
|
+
*
|
|
1774
|
+
* This has no effect when targeting is turned off for the flag.
|
|
1775
|
+
*
|
|
1776
|
+
* If the variation is a boolean value and the flag was not already a boolean
|
|
1777
|
+
* flag, this also changes it to be a boolean flag.
|
|
1778
|
+
*
|
|
1779
|
+
* If the variation is an integer, it specifies a variation out of whatever
|
|
1780
|
+
* variation values have already been defined.
|
|
1781
|
+
*
|
|
1782
|
+
* @param contextKey a context key
|
|
1783
|
+
* @param variation
|
|
1784
|
+
* either `true` or `false` or the index of the desired variation:
|
|
1785
|
+
* 0 for the first, 1 for the second, etc.
|
|
1786
|
+
* @return the flag builder
|
|
1787
|
+
*/
|
|
1788
|
+
variationForUser(contextKey: string, variation: boolean | number): TestDataFlagBuilder;
|
|
1789
|
+
|
|
1790
|
+
/**
|
|
1791
|
+
* Sets the flag to return the specified variation for a specific context key
|
|
1792
|
+
* when targeting is on.
|
|
1793
|
+
*
|
|
1794
|
+
* This has no effect when targeting is turned off for the flag.
|
|
1795
|
+
*
|
|
1796
|
+
* If the variation is a boolean value and the flag was not already a boolean
|
|
1797
|
+
* flag, this also changes it to be a boolean flag.
|
|
1798
|
+
*
|
|
1799
|
+
* If the variation is an integer, it specifies a variation out of whatever
|
|
1800
|
+
* variation values have already been defined.
|
|
1801
|
+
*
|
|
1802
|
+
* @param contextKind a context kind
|
|
1803
|
+
* @param contextKey a context key
|
|
1804
|
+
* @param variation
|
|
1805
|
+
* either `true` or `false` or the index of the desired variation:
|
|
1806
|
+
* 0 for the first, 1 for the second, etc.
|
|
1807
|
+
* @return the flag builder
|
|
1808
|
+
*/
|
|
1809
|
+
variationForContext(contextKind: string, contextKey: string, variation: boolean | number): TestDataFlagBuilder;
|
|
1810
|
+
|
|
1811
|
+
/**
|
|
1812
|
+
* Removes any existing rules from the flag. This undoes the effect of methods
|
|
1813
|
+
* like [[ifMatch]].
|
|
1814
|
+
*
|
|
1815
|
+
* @return the same flag builder
|
|
1816
|
+
*/
|
|
1817
|
+
clearRules(): TestDataFlagBuilder;
|
|
1818
|
+
|
|
1819
|
+
/**
|
|
1820
|
+
* Removes any existing targets from the flag. This undoes the effect of
|
|
1821
|
+
* methods like [[variationForContext]].
|
|
1822
|
+
*
|
|
1823
|
+
* @return the same flag builder
|
|
1824
|
+
*/
|
|
1825
|
+
clearAlltargets(): TestDataFlagBuilder;
|
|
1826
|
+
|
|
1827
|
+
/**
|
|
1828
|
+
* Starts defining a flag rule using the "is one of" operator.
|
|
1829
|
+
*
|
|
1830
|
+
* For example, this creates a rule that returnes `true` if the name is
|
|
1831
|
+
* "Patsy" or "Edina":
|
|
1832
|
+
*
|
|
1833
|
+
* testData.flag('flag')
|
|
1834
|
+
* .ifMatch('user', name', 'Patsy', 'Edina')
|
|
1835
|
+
* .thenReturn(true)
|
|
1836
|
+
*
|
|
1837
|
+
* @param contextKind the kind of the context
|
|
1838
|
+
* @param attribute the context attribute to match against
|
|
1839
|
+
* @param values values to compare to
|
|
1840
|
+
* @return
|
|
1841
|
+
* a flag rule builder; call `thenReturn` to finish the rule
|
|
1842
|
+
* or add more tests with another method like `andMatch`
|
|
1843
|
+
*/
|
|
1844
|
+
ifMatch(contextKind: string, attribute: string, ...values: any): TestDataRuleBuilder;
|
|
1845
|
+
|
|
1846
|
+
/**
|
|
1847
|
+
* Starts defining a flag rule using the "is not one of" operator.
|
|
1848
|
+
*
|
|
1849
|
+
* For example, this creates a rule that returnes `true` if the name is
|
|
1850
|
+
* neither "Saffron" nor "Bubble":
|
|
1851
|
+
*
|
|
1852
|
+
* testData.flag('flag')
|
|
1853
|
+
* .ifNotMatch('user', 'name', 'Saffron', 'Bubble')
|
|
1854
|
+
* .thenReturn(true)
|
|
1855
|
+
*
|
|
1856
|
+
* @param contextKind the kind of the context
|
|
1857
|
+
* @param attribute the user attribute to match against
|
|
1858
|
+
* @param values values to compare to
|
|
1859
|
+
* @return
|
|
1860
|
+
* a flag rule builder; call `thenReturn` to finish the rule
|
|
1861
|
+
* or add more tests with another method like `andNotMatch`
|
|
1862
|
+
*/
|
|
1863
|
+
ifNotMatch(contextKind: string, attribute: string, ...values: any): TestDataRuleBuilder;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
/**
|
|
1867
|
+
* A builder for feature flag rules to be used with [[TestDataFlagBuilder]].
|
|
1868
|
+
*
|
|
1869
|
+
* In the LaunchDarkly model, a flag can have any number of rules, and
|
|
1870
|
+
* a rule can have any number of clauses. A clause is an individual test
|
|
1871
|
+
* such as "name is 'X'". A rule matches a user if all of the rule's
|
|
1872
|
+
* clauses match the user.
|
|
1873
|
+
*
|
|
1874
|
+
* To start defining a rule, use one of the flag builder's matching methods
|
|
1875
|
+
* such as `ifMatch`. This defines the first clause for the rule. Optionally,
|
|
1876
|
+
* you may add more clauses with the rule builder's methods such as `andMatch`.
|
|
1877
|
+
* Finally, call `thenReturn` to finish defining the rule.
|
|
1878
|
+
*/
|
|
1879
|
+
export interface TestDataRuleBuilder {
|
|
1880
|
+
/**
|
|
1881
|
+
* Adds another clause using the "is one of" operator.
|
|
1882
|
+
*
|
|
1883
|
+
* For example, this creates a rule that returns `true` if the name is
|
|
1884
|
+
* "Patsy" and the country is "gb":
|
|
1885
|
+
*
|
|
1886
|
+
* testData.flag('flag')
|
|
1887
|
+
* .ifMatch('name', 'Patsy')
|
|
1888
|
+
* .andMatch('country', 'gb')
|
|
1889
|
+
* .thenReturn(true)
|
|
1890
|
+
*
|
|
1891
|
+
* @param contextKind the kind of the context
|
|
1892
|
+
* @param attribute the user attribute to match against
|
|
1893
|
+
* @param values values to compare to
|
|
1894
|
+
* @return the flag rule builder
|
|
1895
|
+
*/
|
|
1896
|
+
andMatch(contextKind: string, attribute: string, ...values: any): TestDataRuleBuilder;
|
|
1897
|
+
|
|
1898
|
+
/**
|
|
1899
|
+
* Adds another clause using the "is not one of" operator.
|
|
1900
|
+
*
|
|
1901
|
+
* For example, this creates a rule that returns `true` if the name is
|
|
1902
|
+
* "Patsy" and the country is not "gb":
|
|
1903
|
+
*
|
|
1904
|
+
* testData.flag('flag')
|
|
1905
|
+
* .ifMatch('name', 'Patsy')
|
|
1906
|
+
* .andNotMatch('country', 'gb')
|
|
1907
|
+
* .thenReturn(true)
|
|
1908
|
+
*
|
|
1909
|
+
* @param contextKind the kind of the context
|
|
1910
|
+
* @param attribute the user attribute to match against
|
|
1911
|
+
* @param values values to compare to
|
|
1912
|
+
* @return the flag rule builder
|
|
1913
|
+
*/
|
|
1914
|
+
andNotMatch(contextKind: string, attribute: string, ...values: any): TestDataRuleBuilder;
|
|
1915
|
+
|
|
1916
|
+
/**
|
|
1917
|
+
* Finishes defining the rule, specifying the result value as either a boolean or an index
|
|
1918
|
+
*
|
|
1919
|
+
* If the variation is a boolean value and the flag was not already a boolean
|
|
1920
|
+
* flag, this also changes it to be a boolean flag.
|
|
1921
|
+
*
|
|
1922
|
+
* If the variation is an integer, it specifies a variation out of whatever
|
|
1923
|
+
* variation values have already been defined.
|
|
1924
|
+
|
|
1925
|
+
* @param variation
|
|
1926
|
+
* either `true` or `false` or the index of the desired variation:
|
|
1927
|
+
* 0 for the first, 1 for the second, etc.
|
|
1928
|
+
* @return the flag rule builder
|
|
1929
|
+
*/
|
|
1930
|
+
thenReturn(variation: boolean | number): TestDataFlagBuilder;
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
/**
|
|
1935
|
+
* This module contains types that allow customization of LaunchDarkly components, and
|
|
1936
|
+
* interfaces to other advanced SDK features.
|
|
1937
|
+
*
|
|
1938
|
+
* Most applications will not need to refer to these types. You will use them if you are creating a
|
|
1939
|
+
* plug-in component, such as a database integration, or if you use advanced SDK features.
|
|
1940
|
+
*
|
|
1941
|
+
* Currently this module contains no implementation code, but only TypeScript interfaces.
|
|
1942
|
+
*/
|
|
1943
|
+
declare module 'launchdarkly-node-server-sdk/interfaces' {
|
|
1944
|
+
import { EventEmitter } from 'events';
|
|
1945
|
+
|
|
1946
|
+
/**
|
|
1947
|
+
* A read-only data store that allows querying of user membership in Big Segments.
|
|
1948
|
+
*
|
|
1949
|
+
* Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
|
|
1950
|
+
* documentation: https://docs.launchdarkly.com/home/users/big-segments
|
|
1951
|
+
*/
|
|
1952
|
+
export interface BigSegmentStore {
|
|
1953
|
+
/**
|
|
1954
|
+
* Queries information about the overall state of the store.
|
|
1955
|
+
*
|
|
1956
|
+
* The resolved value of the Promise should always be a [[BigSegmentStoreMetadata]] object. If
|
|
1957
|
+
* the store is accessible but contains no metadata, the object's `lastUpToDate` property can be
|
|
1958
|
+
* undefined. If the store is not accessible due to a database error, the method can throw an
|
|
1959
|
+
* exception/reject the promise.
|
|
1960
|
+
*
|
|
1961
|
+
* This method will be called only when the SDK needs the latest state, so it should not be cached.
|
|
1962
|
+
*
|
|
1963
|
+
* @returns a Promise for the result of the query
|
|
1964
|
+
*/
|
|
1965
|
+
getMetadata(): Promise<BigSegmentStoreMetadata>;
|
|
1966
|
+
|
|
1967
|
+
/**
|
|
1968
|
+
* Queries the store for a snapshot of the current segment state for a specific user.
|
|
1969
|
+
*
|
|
1970
|
+
* The userHash is a base64-encoded string produced by hashing the user key as defined by
|
|
1971
|
+
* the Big Segments specification; the store implementation does not need to know the details
|
|
1972
|
+
* of how this is done, because it deals only with already-hashed keys, but the string can be
|
|
1973
|
+
* assumed to only contain characters that are valid in base64.
|
|
1974
|
+
*
|
|
1975
|
+
* The resolved value of the Promise should be either a [[BigSegmentStoreMembership]], or
|
|
1976
|
+
* undefined if the user is not referenced in any Big Segments (this is equivalent to a
|
|
1977
|
+
* [[BigSegmentStoreMembership]] that has no properties).
|
|
1978
|
+
*
|
|
1979
|
+
* @param userHash identifies the user
|
|
1980
|
+
* @returns a Promise for the result of the query.
|
|
1981
|
+
*/
|
|
1982
|
+
getUserMembership(userHash: string): Promise<BigSegmentStoreMembership | undefined>;
|
|
1983
|
+
|
|
1984
|
+
/**
|
|
1985
|
+
* Releases any resources being used by the store.
|
|
1986
|
+
*/
|
|
1987
|
+
close(): void;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/**
|
|
1991
|
+
* Values returned by BigSegmentStore.getMetadata().
|
|
1992
|
+
*/
|
|
1993
|
+
export interface BigSegmentStoreMetadata {
|
|
1994
|
+
/**
|
|
1995
|
+
* The Unix epoch millisecond timestamp of the last update to the BigSegmentStore. It is
|
|
1996
|
+
* undefined if the store has never been updated.
|
|
1997
|
+
*/
|
|
1998
|
+
lastUpToDate?: number
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
/**
|
|
2002
|
+
* The return type of [[BigSegmentStore.getUserMembership]], describing which Big Segments a
|
|
2003
|
+
* specific user is included in or excluded from.
|
|
2004
|
+
*
|
|
2005
|
+
* This object may be cached by the SDK, so it should not be modified after it is created. It
|
|
2006
|
+
* is a snapshot of the segment membership state at one point in time.
|
|
2007
|
+
*/
|
|
2008
|
+
export interface BigSegmentStoreMembership {
|
|
2009
|
+
/**
|
|
2010
|
+
* Each property key in this object is a "segment reference", which is how segments are
|
|
2011
|
+
* identified in Big Segment data. This string is not identical to the segment key-- the SDK
|
|
2012
|
+
* will add other information. The store implementation should not be concerned with the
|
|
2013
|
+
* format of the string.
|
|
2014
|
+
*
|
|
2015
|
+
* A true value means that the user is explicitly included in the segment. A false value
|
|
2016
|
+
* means that the user is explicitly excluded from the segment-- and is not also explicitly
|
|
2017
|
+
* included (that is, if both an include and an exclude existed in the data, the include would
|
|
2018
|
+
* take precedence). If the user's status in a particular segment is undefined, there should
|
|
2019
|
+
* be no key or value for that segment.
|
|
2020
|
+
*/
|
|
2021
|
+
[segmentRef: string]: boolean;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* An interface for querying the status of a Big Segment store.
|
|
2026
|
+
*
|
|
2027
|
+
* The Big Segment store is the component that receives information about Big Segments, normally
|
|
2028
|
+
* from a database populated by the LaunchDarkly Relay Proxy. Big Segments are a specific type
|
|
2029
|
+
* of user segments. For more information, read the LaunchDarkly documentation:
|
|
2030
|
+
* https://docs.launchdarkly.com/home/users/big-segments
|
|
2031
|
+
*
|
|
2032
|
+
* An implementation of this interface is returned by {@link LDClient.bigSegmentStoreStatusProvider}.
|
|
2033
|
+
* Application code never needs to implement this interface.
|
|
2034
|
+
*
|
|
2035
|
+
* Note that this type inherits from `EventEmitter`, so you can use the standard `on()`, `once()`,
|
|
2036
|
+
* and `off()` methods to receive status change events. The standard `EventEmitter` methods are
|
|
2037
|
+
* not documented here; see the {@link https://nodejs.org/api/events.html#events_class_eventemitter|Node API documentation}.
|
|
2038
|
+
* The type of the status change event is `"change"`, and its value is the same value that would
|
|
2039
|
+
* be returned by {@link getStatus}.
|
|
2040
|
+
*/
|
|
2041
|
+
export interface BigSegmentStoreStatusProvider extends EventEmitter {
|
|
2042
|
+
/**
|
|
2043
|
+
* Gets the current status of the store, if known.
|
|
2044
|
+
*
|
|
2045
|
+
* @returns a {@link BigSegmentStoreStatus}, or `undefined` if the SDK has not yet queried the
|
|
2046
|
+
* Big Segment store status
|
|
2047
|
+
*/
|
|
2048
|
+
getStatus(): BigSegmentStoreStatus | undefined;
|
|
2049
|
+
|
|
2050
|
+
/**
|
|
2051
|
+
* Gets the current status of the store, querying it if the status has not already been queried.
|
|
2052
|
+
*
|
|
2053
|
+
* @returns a Promise for the status of the store
|
|
2054
|
+
*/
|
|
2055
|
+
requireStatus(): Promise<BigSegmentStoreStatus>;
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
/**
|
|
2059
|
+
* Information about the status of a Big Segment store, provided by {@link BigSegmentStoreStatusProvider}.
|
|
2060
|
+
*
|
|
2061
|
+
* Big Segments are a specific type of user segments. For more information, read the LaunchDarkly
|
|
2062
|
+
* documentation: https://docs.launchdarkly.com/home/users/big-segments
|
|
2063
|
+
*/
|
|
2064
|
+
export interface BigSegmentStoreStatus {
|
|
2065
|
+
/**
|
|
2066
|
+
* True if the Big Segment store is able to respond to queries, so that the SDK can
|
|
2067
|
+
* evaluate whether a user is in a segment or not.
|
|
2068
|
+
*
|
|
2069
|
+
* If this property is false, the store is not able to make queries (for instance, it may not have
|
|
2070
|
+
* a valid database connection). In this case, the SDK will treat any reference to a Big Segment
|
|
2071
|
+
* as if no users are included in that segment. Also, the {@link LDEvaluationReason} associated
|
|
2072
|
+
* with any flag evaluation that references a Big Segment when the store is not available will
|
|
2073
|
+
* have a `bigSegmentsStatus` of `"STORE_ERROR"`.
|
|
2074
|
+
*/
|
|
2075
|
+
available: boolean;
|
|
2076
|
+
|
|
2077
|
+
/**
|
|
2078
|
+
* True if the Big Segment store is available, but has not been updated within the amount of time
|
|
2079
|
+
* specified by {@link LDBigSegmentsOptions.staleAfter}.
|
|
2080
|
+
*
|
|
2081
|
+
* This may indicate that the LaunchDarkly Relay Proxy, which populates the store, has stopped
|
|
2082
|
+
* running or has become unable to receive fresh data from LaunchDarkly. Any feature flag
|
|
2083
|
+
* evaluations that reference a Big Segment will be using the last known data, which may be out
|
|
2084
|
+
* of date.
|
|
2085
|
+
*/
|
|
2086
|
+
stale: boolean;
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
/**
|
|
2090
|
+
* Used internally to describe the type of data being queried or updated, such as feature flags or
|
|
2091
|
+
* user segments.
|
|
2092
|
+
*
|
|
2093
|
+
* This is the actual type of the `kind` parameter in `LDFeatureStore` methods. Those methods are
|
|
2094
|
+
* still declared as taking `any` for backward compatibility, but in the future they will reference
|
|
2095
|
+
* this type.
|
|
2096
|
+
*/
|
|
2097
|
+
export interface DataKind {
|
|
2098
|
+
/**
|
|
2099
|
+
* A string such as `"features"` or `"segments"` which can be used in keys to distinguish this
|
|
2100
|
+
* kind of data from other kinds.
|
|
2101
|
+
*/
|
|
2102
|
+
namespace: string;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
/**
|
|
2106
|
+
* Used internally to describe the basic properties of stored data such as feature flags or user
|
|
2107
|
+
* segments.
|
|
2108
|
+
*
|
|
2109
|
+
* This is the actual type of parameters and return values in `LDFeatureStore` methods that refer
|
|
2110
|
+
* to a flag or segment item. Those methods still use the `object` type for backward compatibility.
|
|
2111
|
+
*/
|
|
2112
|
+
export interface VersionedData {
|
|
2113
|
+
/**
|
|
2114
|
+
* The item's unique key, such as a feature flag key.
|
|
2115
|
+
*/
|
|
2116
|
+
key: string;
|
|
2117
|
+
|
|
2118
|
+
/**
|
|
2119
|
+
* A version number that LaunchDarkly will increment each time this item is changed.
|
|
2120
|
+
*/
|
|
2121
|
+
version: number;
|
|
2122
|
+
|
|
2123
|
+
/**
|
|
2124
|
+
* True if this is a deleted item placeholder (tombstone).
|
|
2125
|
+
*/
|
|
2126
|
+
deleted?: boolean;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
/**
|
|
2130
|
+
* Used internally to describe a set of stored data items of the same kind, such as feature flags
|
|
2131
|
+
* or user segments. The string key for each item is the same as the item's `key` property.
|
|
2132
|
+
*/
|
|
2133
|
+
export type KeyedItems<T> = Record<string, T>;
|
|
2134
|
+
|
|
2135
|
+
/**
|
|
2136
|
+
* Used internally for data store implementations that require items in an ordered list rather
|
|
2137
|
+
* than as object properties.
|
|
2138
|
+
*/
|
|
2139
|
+
export interface DataCollection<T> {
|
|
2140
|
+
/**
|
|
2141
|
+
* Describes the kind of items, such as feature flags or user segments.
|
|
2142
|
+
*/
|
|
2143
|
+
kind: DataKind;
|
|
2144
|
+
|
|
2145
|
+
/**
|
|
2146
|
+
* An ordered list of items of this kind.
|
|
2147
|
+
*/
|
|
2148
|
+
items: Array<T>;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
/**
|
|
2152
|
+
* Used internally to describe a full set of environment data, which can include both feature
|
|
2153
|
+
* flags and user segments. The string key for each item is the `namespace` property of a
|
|
2154
|
+
* [[DataKind]].
|
|
2155
|
+
*/
|
|
2156
|
+
export type FullDataSet<T> = Record<string, KeyedItems<T>>;
|
|
2157
|
+
|
|
2158
|
+
/**
|
|
2159
|
+
* Base interface for a simplified subset of the functionality of `LDFeatureStore`, to be used in
|
|
2160
|
+
* conjunction with `CachingStoreWrapper`.
|
|
2161
|
+
*
|
|
2162
|
+
* @see [[PersistentDataStore]]
|
|
2163
|
+
* @see [[PersistentDataStoreNonAtomic]]
|
|
2164
|
+
*/
|
|
2165
|
+
export interface PersistentDataStoreBase {
|
|
2166
|
+
/**
|
|
2167
|
+
* Get an entity from the store.
|
|
2168
|
+
*
|
|
2169
|
+
* @param kind
|
|
2170
|
+
* The type of data to be accessed. The store should not make any assumptions about the format
|
|
2171
|
+
* of the data, but just return a JSON object.
|
|
2172
|
+
*
|
|
2173
|
+
* @param key
|
|
2174
|
+
* The unique key of the entity within the specified collection.
|
|
2175
|
+
*
|
|
2176
|
+
* @param callback
|
|
2177
|
+
* Will be called with the retrieved entity, or null if not found.
|
|
2178
|
+
*/
|
|
2179
|
+
getInternal(kind: DataKind, key: string, callback: (res: VersionedData) => void): void;
|
|
2180
|
+
|
|
2181
|
+
/**
|
|
2182
|
+
* Get all entities from a collection.
|
|
2183
|
+
*
|
|
2184
|
+
* The store should filter out any entities with the property `deleted: true`.
|
|
2185
|
+
*
|
|
2186
|
+
* @param kind
|
|
2187
|
+
* The type of data to be accessed. The store should not make any assumptions about the format
|
|
2188
|
+
* of the data, but just return an object in which each key is the `key` property of an entity
|
|
2189
|
+
* and the value is the entity. The actual type of this parameter is [[interfaces.DataKind]].
|
|
2190
|
+
*
|
|
2191
|
+
* @param callback
|
|
2192
|
+
* Will be called with the resulting map.
|
|
2193
|
+
*/
|
|
2194
|
+
getAllInternal(kind: DataKind, callback: (res: KeyedItems<VersionedData>) => void): void;
|
|
2195
|
+
|
|
2196
|
+
/**
|
|
2197
|
+
* Add an entity or update an existing entity.
|
|
2198
|
+
*
|
|
2199
|
+
* @param kind
|
|
2200
|
+
* The type of data to be accessed.
|
|
2201
|
+
*
|
|
2202
|
+
* @param item
|
|
2203
|
+
* The contents of the entity, as an object that can be converted to JSON. The store
|
|
2204
|
+
* should check the `version` property of this object, and should *not* overwrite any
|
|
2205
|
+
* existing data if the existing `version` is greater than or equal to that value.
|
|
2206
|
+
*
|
|
2207
|
+
* @param callback
|
|
2208
|
+
* Will be called after the upsert operation is complete.
|
|
2209
|
+
*/
|
|
2210
|
+
upsertInternal(kind: DataKind, item: VersionedData, callback: (err: Error, finalItem: VersionedData) => void): void;
|
|
2211
|
+
|
|
2212
|
+
/**
|
|
2213
|
+
* Tests whether the store is initialized.
|
|
2214
|
+
*
|
|
2215
|
+
* "Initialized" means that the store has been populated with data, either by the client
|
|
2216
|
+
* having called `init()` within this process, or by another process (if this is a shared
|
|
2217
|
+
* database).
|
|
2218
|
+
*
|
|
2219
|
+
* @param callback
|
|
2220
|
+
* Will be called back with the boolean result.
|
|
2221
|
+
*/
|
|
2222
|
+
initializedInternal(callback: (isInitialized: boolean) => void): void;
|
|
2223
|
+
|
|
2224
|
+
/**
|
|
2225
|
+
* Releases any resources being used by the feature store.
|
|
2226
|
+
*/
|
|
2227
|
+
close(): void;
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
/**
|
|
2231
|
+
* Interface for a simplified subset of the functionality of `LDFeatureStore`, to be used in
|
|
2232
|
+
* conjunction with `CachingStoreWrapper`.
|
|
2233
|
+
*
|
|
2234
|
+
* @see [[PersistentDataStoreNonAtomic]]
|
|
2235
|
+
*/
|
|
2236
|
+
export interface PersistentDataStore extends PersistentDataStoreBase {
|
|
2237
|
+
/**
|
|
2238
|
+
* Initialize the store, overwriting any existing data.
|
|
2239
|
+
*
|
|
2240
|
+
* @param allData
|
|
2241
|
+
* An object in which each key is the "namespace" of a collection (e.g. `"features"`) and
|
|
2242
|
+
* the value is an object that maps keys to entities.
|
|
2243
|
+
*
|
|
2244
|
+
* @param callback
|
|
2245
|
+
* Will be called when the store has been initialized.
|
|
2246
|
+
*/
|
|
2247
|
+
initInternal(allData: FullDataSet<VersionedData>, callback: () => void): void;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
/**
|
|
2251
|
+
* Interface for a simplified subset of the functionality of `LDFeatureStore`, to be used in
|
|
2252
|
+
* conjunction with `CachingStoreWrapper`.
|
|
2253
|
+
*
|
|
2254
|
+
* This is a variant of [[PersistentDataStore]] for databases that require somewhat different
|
|
2255
|
+
* initialization semantics, where we must specify a consistent ordering of writes.
|
|
2256
|
+
*
|
|
2257
|
+
* @see [[PersistentDataStore]]
|
|
2258
|
+
*/
|
|
2259
|
+
export interface PersistentDataStoreNonAtomic {
|
|
2260
|
+
/**
|
|
2261
|
+
* Initialize the store, overwriting any existing data.
|
|
2262
|
+
*
|
|
2263
|
+
* @param allData
|
|
2264
|
+
* A list of data item collections in the order they should be written.
|
|
2265
|
+
*
|
|
2266
|
+
* @param callback
|
|
2267
|
+
* Will be called when the store has been initialized.
|
|
2268
|
+
*/
|
|
2269
|
+
initOrderedInternal(allData: Array<DataCollection<VersionedData>>, callback: () => void): void;
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
/**
|
|
2274
|
+
* @ignore
|
|
2275
|
+
*/
|
|
2276
|
+
declare module 'launchdarkly-node-server-sdk/streaming' {
|
|
2277
|
+
import {
|
|
2278
|
+
LDOptions,
|
|
2279
|
+
LDFeatureRequestor,
|
|
2280
|
+
LDStreamProcessor
|
|
2281
|
+
} from 'launchdarkly-node-server-sdk';
|
|
2282
|
+
|
|
2283
|
+
function StreamProcessor(
|
|
2284
|
+
sdkKey: string,
|
|
2285
|
+
options: LDOptions,
|
|
2286
|
+
requestor: LDFeatureRequestor
|
|
2287
|
+
): LDStreamProcessor;
|
|
2288
|
+
export = StreamProcessor;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
/**
|
|
2292
|
+
* @ignore
|
|
2293
|
+
*/
|
|
2294
|
+
declare module 'launchdarkly-node-server-sdk/requestor' {
|
|
2295
|
+
import { LDOptions, LDFeatureRequestor } from 'launchdarkly-node-server-sdk';
|
|
2296
|
+
|
|
2297
|
+
function Requestor(sdkKey: string, options: LDOptions): LDFeatureRequestor;
|
|
2298
|
+
export = Requestor;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
/**
|
|
2302
|
+
* @ignore
|
|
2303
|
+
*/
|
|
2304
|
+
declare module 'launchdarkly-node-server-sdk/feature_store' {
|
|
2305
|
+
import { LDFeatureStore } from 'launchdarkly-node-server-sdk';
|
|
2306
|
+
|
|
2307
|
+
function InMemoryFeatureStore(): LDFeatureStore;
|
|
2308
|
+
export = InMemoryFeatureStore;
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
/**
|
|
2312
|
+
* @ignore
|
|
2313
|
+
*/
|
|
2314
|
+
declare module 'launchdarkly-node-server-sdk/caching_store_wrapper' {
|
|
2315
|
+
import { LDFeatureStore } from 'launchdarkly-node-server-sdk';
|
|
2316
|
+
import { PersistentDataStore, PersistentDataStoreNonAtomic } from 'launchdarkly-node-server-sdk/interfaces';
|
|
2317
|
+
|
|
2318
|
+
/**
|
|
2319
|
+
* A base feature store implementation used by database integrations.
|
|
2320
|
+
*/
|
|
2321
|
+
class CachingStoreWrapper implements LDFeatureStore {
|
|
2322
|
+
/**
|
|
2323
|
+
* Creates a feature store implementation with standard caching behavior for a persistent store.
|
|
2324
|
+
*
|
|
2325
|
+
* @param storeImplementation internal implementation object for a specific database type
|
|
2326
|
+
* @param ttl cache TTL in seconds, or 0 for no caching
|
|
2327
|
+
* @param description name of the database
|
|
2328
|
+
*/
|
|
2329
|
+
public constructor(
|
|
2330
|
+
storeImplementation: PersistentDataStore | PersistentDataStoreNonAtomic,
|
|
2331
|
+
ttl: number,
|
|
2332
|
+
description: string
|
|
2333
|
+
);
|
|
2334
|
+
|
|
2335
|
+
public get(kind: object, key: string, callback: (res: object) => void): void;
|
|
2336
|
+
|
|
2337
|
+
public all(kind: object, callback: (res: object) => void): void;
|
|
2338
|
+
|
|
2339
|
+
public init(allData: object, callback: () => void): void;
|
|
2340
|
+
|
|
2341
|
+
public delete(kind: object, key: string, version: string, callback: () => void): void;
|
|
2342
|
+
|
|
2343
|
+
public upsert(kind: object, data: object, callback: () => void): void;
|
|
2344
|
+
|
|
2345
|
+
public initialized(callback: (isInitialized: boolean) => void): void;
|
|
2346
|
+
|
|
2347
|
+
public close(): void;
|
|
2348
|
+
}
|
|
2349
|
+
export = CachingStoreWrapper;
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
/**
|
|
2353
|
+
* @ignore
|
|
2354
|
+
*/
|
|
2355
|
+
declare module 'launchdarkly-node-server-sdk/sharedtest/store_tests' {
|
|
2356
|
+
import * as ld from 'launchdarkly-node-server-sdk';
|
|
2357
|
+
import * as interfaces from 'launchdarkly-node-server-sdk/interfaces';
|
|
2358
|
+
|
|
2359
|
+
/**
|
|
2360
|
+
* A standard test suite that should be run on every persistent feature store implementation.
|
|
2361
|
+
*
|
|
2362
|
+
* This test suite uses `jest` and should be run inside a `describe` block.
|
|
2363
|
+
*
|
|
2364
|
+
* Store implementations must meet the following requirements to be testable with this suite:
|
|
2365
|
+
*
|
|
2366
|
+
* - They must support setting a key prefix. The tests will always pass a non-empty prefix.
|
|
2367
|
+
*
|
|
2368
|
+
* - They must support caching with a positive cache TTL in seconds, or a zero cache TTL to
|
|
2369
|
+
* disable caching.
|
|
2370
|
+
*
|
|
2371
|
+
* - All instances created during the tests must share the same database, so that the tests
|
|
2372
|
+
* can verify that they can read pre-existing data and will not interfere with any keys
|
|
2373
|
+
* that use a different prefix.
|
|
2374
|
+
*
|
|
2375
|
+
* Do not call `runPersistentFeatureStoreTests` and `runBigSegmentStoreTests` from tests
|
|
2376
|
+
* in separate files, if `jest` parallelization is enabled; they can interfere with each
|
|
2377
|
+
* other's database state if they are interleaved.
|
|
2378
|
+
*
|
|
2379
|
+
* @param createStore A function that creates a feature store instance with the specified
|
|
2380
|
+
* key prefix and cache TTL.
|
|
2381
|
+
* @param clearExistingData An asynchronous function that removes any existing data from
|
|
2382
|
+
* the database for the specified key prefix only.
|
|
2383
|
+
* @param setConcurrentModificationHook If provided, this enables additional tests in which
|
|
2384
|
+
* another store instance is used to make a competing update to the same data while an
|
|
2385
|
+
* update is already in progress. The function should create a store instance which,
|
|
2386
|
+
* during any upsert operation, will call "hook" and await the result at a point when a
|
|
2387
|
+
* race condition is possible (for instance, after reading the old version of an item but
|
|
2388
|
+
* before writing the new version, if those are not atomic). Caching should be disabled.
|
|
2389
|
+
*/
|
|
2390
|
+
export function runPersistentFeatureStoreTests(
|
|
2391
|
+
createStore: (prefix: string, cacheTTL: number, logger: ld.LDLogger) => ld.LDFeatureStore,
|
|
2392
|
+
clearExistingData: (prefix: string) => Promise<void>,
|
|
2393
|
+
createStoreWithConcurrentUpdateHook?: (prefix: string, logger: ld.LDLogger, hook: () => Promise<void>) => void,
|
|
2394
|
+
): void;
|
|
2395
|
+
|
|
2396
|
+
/**
|
|
2397
|
+
* A standard test suite that should be run on every Big Segment store implementation.
|
|
2398
|
+
*
|
|
2399
|
+
* This test suite uses `jest` and should be run inside a `describe` block.
|
|
2400
|
+
*
|
|
2401
|
+
* Store implementations must meet the following requirements to be testable with this suite:
|
|
2402
|
+
*
|
|
2403
|
+
* - They must support setting a key prefix. The tests will always pass a non-empty prefix.
|
|
2404
|
+
*
|
|
2405
|
+
* - All instances created during the tests must share the same database, so that the tests
|
|
2406
|
+
* can verify that they can read pre-existing data and will not interfere with any keys
|
|
2407
|
+
* that use a different prefix.
|
|
2408
|
+
*
|
|
2409
|
+
* Do not call `runPersistentFeatureStoreTests` and `runBigSegmentStoreTests` from tests
|
|
2410
|
+
* in separate files, if `jest` parallelization is enabled; they can interfere with each
|
|
2411
|
+
* other's database state if they are interleaved.
|
|
2412
|
+
*
|
|
2413
|
+
* @param createStore A function that creates a Big Segment store instance with the
|
|
2414
|
+
* specified key prefix.
|
|
2415
|
+
* @param clearExistingData An asynchronous function that removes any existing data from
|
|
2416
|
+
* the database for the specified key prefix only.
|
|
2417
|
+
* @param setMetadata An asynchronous function that updates the store metadata.
|
|
2418
|
+
* @param setSegments An asynchronous function that sets a user's Big Segment state.
|
|
2419
|
+
*/
|
|
2420
|
+
export function runBigSegmentStoreTests(
|
|
2421
|
+
createStore: (prefix: string, logger: ld.LDLogger) => interfaces.BigSegmentStore,
|
|
2422
|
+
clearExistingData: (prefix: string) => Promise<void>,
|
|
2423
|
+
setMetadata: (prefix: string, metadata: interfaces.BigSegmentStoreMetadata) => Promise<void>,
|
|
2424
|
+
setSegments: (prefix: string, userHashKey: string, included: string[], excluded: string[]) => Promise<void>
|
|
2425
|
+
): void;
|
|
2426
|
+
}
|