flagsmith-nodejs 5.1.0 → 6.0.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/build/cjs/sdk/analytics.d.ts +1 -1
- package/build/cjs/sdk/analytics.js +1 -1
- package/build/cjs/sdk/index.d.ts +44 -42
- package/build/cjs/sdk/index.js +150 -152
- package/build/cjs/sdk/polling_manager.d.ts +3 -1
- package/build/cjs/sdk/polling_manager.js +9 -2
- package/build/cjs/sdk/types.d.ts +73 -5
- package/build/cjs/sdk/utils.d.ts +24 -1
- package/build/cjs/sdk/utils.js +50 -18
- package/build/esm/sdk/analytics.d.ts +1 -1
- package/build/esm/sdk/analytics.js +1 -1
- package/build/esm/sdk/index.d.ts +44 -42
- package/build/esm/sdk/index.js +151 -153
- package/build/esm/sdk/polling_manager.d.ts +3 -1
- package/build/esm/sdk/polling_manager.js +9 -2
- package/build/esm/sdk/types.d.ts +73 -5
- package/build/esm/sdk/utils.d.ts +24 -1
- package/build/esm/sdk/utils.js +48 -17
- package/package.json +1 -1
- package/sdk/analytics.ts +5 -5
- package/sdk/index.ts +173 -176
- package/sdk/polling_manager.ts +9 -2
- package/sdk/types.ts +74 -3
- package/sdk/utils.ts +50 -16
- package/tests/sdk/analytics.test.ts +0 -4
- package/tests/sdk/flagsmith-cache.test.ts +5 -17
- package/tests/sdk/flagsmith-environment-flags.test.ts +1 -29
- package/tests/sdk/flagsmith-identity-flags.test.ts +20 -15
- package/tests/sdk/flagsmith.test.ts +88 -83
- package/tests/sdk/polling.test.ts +0 -4
- package/tests/sdk/utils.ts +28 -6
- package/vitest.config.ts +1 -0
- /package/{.prettierrc.js → .prettierrc.cjs} +0 -0
package/build/cjs/sdk/types.d.ts
CHANGED
|
@@ -21,24 +21,92 @@ export interface FlagsmithCache {
|
|
|
21
21
|
set(key: string, value: Flags): Promise<void>;
|
|
22
22
|
}
|
|
23
23
|
export type Fetch = typeof fetch;
|
|
24
|
+
/**
|
|
25
|
+
* The configuration options for a {@link Flagsmith} client.
|
|
26
|
+
*/
|
|
24
27
|
export interface FlagsmithConfig {
|
|
28
|
+
/**
|
|
29
|
+
* The environment's client-side or server-side key.
|
|
30
|
+
*/
|
|
25
31
|
environmentKey?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The Flagsmith API URL. Set this if you are not using Flagsmith's public service, i.e. https://app.flagsmith.com.
|
|
34
|
+
*
|
|
35
|
+
* @default https://edge.api.flagsmith.com/api/v1/
|
|
36
|
+
*/
|
|
26
37
|
apiUrl?: string;
|
|
38
|
+
/**
|
|
39
|
+
* A custom {@link Dispatcher} to use when making HTTP requests.
|
|
40
|
+
*/
|
|
27
41
|
agent?: Dispatcher;
|
|
42
|
+
/**
|
|
43
|
+
* A custom {@link fetch} implementation to use when making HTTP requests.
|
|
44
|
+
*/
|
|
28
45
|
fetch?: Fetch;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Custom headers to use in all HTTP requests.
|
|
48
|
+
*/
|
|
49
|
+
customHeaders?: HeadersInit;
|
|
50
|
+
/**
|
|
51
|
+
* The network request timeout duration, in seconds.
|
|
52
|
+
*
|
|
53
|
+
* @default 10
|
|
54
|
+
*/
|
|
32
55
|
requestTimeoutSeconds?: number;
|
|
56
|
+
/**
|
|
57
|
+
* The amount of time, in milliseconds, to wait before retrying failed network requests.
|
|
58
|
+
*/
|
|
59
|
+
requestRetryDelayMilliseconds?: number;
|
|
60
|
+
/**
|
|
61
|
+
* If enabled, flags are evaluated locally using the environment state cached in memory.
|
|
62
|
+
*
|
|
63
|
+
* The client will lazily fetch the environment from the Flagsmith API, and poll it every {@link environmentRefreshIntervalSeconds}.
|
|
64
|
+
*/
|
|
33
65
|
enableLocalEvaluation?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The time, in seconds, to wait before refreshing the cached environment state.
|
|
68
|
+
* @default 60
|
|
69
|
+
*/
|
|
34
70
|
environmentRefreshIntervalSeconds?: number;
|
|
71
|
+
/**
|
|
72
|
+
* How many times to retry any failed network request before giving up.
|
|
73
|
+
* @default 3
|
|
74
|
+
*/
|
|
35
75
|
retries?: number;
|
|
76
|
+
/**
|
|
77
|
+
* If enabled, the client will keep track of any flags evaluated using {@link Flags.isFeatureEnabled},
|
|
78
|
+
* {@link Flags.getFeatureValue} or {@link Flags.getFlag}, and periodically flush this data to the Flagsmith API.
|
|
79
|
+
*/
|
|
36
80
|
enableAnalytics?: boolean;
|
|
37
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Used to return fallback values for flags when evaluation fails for any reason. If not provided and flag
|
|
83
|
+
* evaluation fails, an error will be thrown intsead.
|
|
84
|
+
*
|
|
85
|
+
* @param flagKey The key of the flag that failed to evaluate.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // All flags disabled and with no value by default
|
|
89
|
+
* const defaultHandler = () => new DefaultFlag(undefined, false)
|
|
90
|
+
*
|
|
91
|
+
* // Enable only VIP flags by default
|
|
92
|
+
* const vipDefaultHandler = (key: string) => new Default(undefined, key.startsWith('vip_'))
|
|
93
|
+
*/
|
|
94
|
+
defaultFlagHandler?: (flagKey: string) => DefaultFlag;
|
|
38
95
|
cache?: FlagsmithCache;
|
|
39
|
-
|
|
96
|
+
/**
|
|
97
|
+
* A callback function to invoke whenever the cached environment is updated.
|
|
98
|
+
* @param error The error that occurred when the environment state failed to update, if any.
|
|
99
|
+
* @param result The updated environment state, if no error was thrown.
|
|
100
|
+
*/
|
|
101
|
+
onEnvironmentChange?: (error: Error | null, result?: EnvironmentModel) => void;
|
|
40
102
|
logger?: Logger;
|
|
103
|
+
/**
|
|
104
|
+
* If enabled, the client will work offline and not make any network requests. Requires {@link offlineHandler}.
|
|
105
|
+
*/
|
|
41
106
|
offlineMode?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* If {@link offlineMode} is enabled, this handler is used to calculate the values of all flags.
|
|
109
|
+
*/
|
|
42
110
|
offlineHandler?: BaseOfflineHandler;
|
|
43
111
|
}
|
|
44
112
|
export interface ITraitConfig {
|
package/build/cjs/sdk/utils.d.ts
CHANGED
|
@@ -32,5 +32,28 @@ export declare function generateIdentitiesData(identifier: string, traits: Trait
|
|
|
32
32
|
export declare const delay: (ms: number) => Promise<unknown>;
|
|
33
33
|
export declare const retryFetch: (url: string, fetchOptions: RequestInit & {
|
|
34
34
|
dispatcher?: Dispatcher;
|
|
35
|
-
}, retries: number | undefined, timeoutMs: number | undefined, customFetch: Fetch) => Promise<Response>;
|
|
35
|
+
}, retries: number | undefined, timeoutMs: number | undefined, retryDelayMs: number | undefined, customFetch: Fetch) => Promise<Response>;
|
|
36
|
+
/**
|
|
37
|
+
* A deferred promise can be resolved or rejected outside its creation scope.
|
|
38
|
+
*
|
|
39
|
+
* @template T The type of the value that the deferred promise will resolve to.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* const deferred = new Deferred<string>()
|
|
43
|
+
*
|
|
44
|
+
* // Pass the promise somewhere
|
|
45
|
+
* performAsyncOperation(deferred.promise)
|
|
46
|
+
*
|
|
47
|
+
* // Resolve it when ready from anywhere
|
|
48
|
+
* deferred.resolve("Operation completed")
|
|
49
|
+
* deferred.failed("Error")
|
|
50
|
+
*/
|
|
51
|
+
export declare class Deferred<T> {
|
|
52
|
+
readonly promise: Promise<T>;
|
|
53
|
+
private resolvePromise;
|
|
54
|
+
private rejectPromise;
|
|
55
|
+
constructor(initial?: T);
|
|
56
|
+
resolve(value: T | PromiseLike<T>): void;
|
|
57
|
+
reject(reason?: unknown): void;
|
|
58
|
+
}
|
|
36
59
|
export {};
|
package/build/cjs/sdk/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.retryFetch = exports.delay = exports.generateIdentitiesData = exports.isTraitConfig = void 0;
|
|
3
|
+
exports.Deferred = exports.retryFetch = exports.delay = exports.generateIdentitiesData = exports.isTraitConfig = void 0;
|
|
4
4
|
function isTraitConfig(traitValue) {
|
|
5
5
|
return !!traitValue && typeof traitValue == 'object' && traitValue.value !== undefined;
|
|
6
6
|
}
|
|
@@ -39,25 +39,57 @@ exports.delay = delay;
|
|
|
39
39
|
const retryFetch = (url,
|
|
40
40
|
// built-in RequestInit type doesn't have dispatcher/agent
|
|
41
41
|
fetchOptions, retries = 3, timeoutMs = 10, // set an overall timeout for this function
|
|
42
|
-
customFetch) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
customFetch(url, {
|
|
42
|
+
retryDelayMs = 1000, customFetch) => {
|
|
43
|
+
const retryWrapper = async (n) => {
|
|
44
|
+
try {
|
|
45
|
+
return await customFetch(url, {
|
|
46
46
|
...fetchOptions,
|
|
47
47
|
signal: AbortSignal.timeout(timeoutMs)
|
|
48
|
-
})
|
|
49
|
-
.then(res => resolve(res))
|
|
50
|
-
.catch(async (err) => {
|
|
51
|
-
if (n > 0) {
|
|
52
|
-
await (0, exports.delay)(1000);
|
|
53
|
-
retryWrapper(--n);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
reject(err);
|
|
57
|
-
}
|
|
58
48
|
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
if (n > 0) {
|
|
52
|
+
await (0, exports.delay)(retryDelayMs);
|
|
53
|
+
return await retryWrapper(n - 1);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw e;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return retryWrapper(retries);
|
|
62
61
|
};
|
|
63
62
|
exports.retryFetch = retryFetch;
|
|
63
|
+
/**
|
|
64
|
+
* A deferred promise can be resolved or rejected outside its creation scope.
|
|
65
|
+
*
|
|
66
|
+
* @template T The type of the value that the deferred promise will resolve to.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const deferred = new Deferred<string>()
|
|
70
|
+
*
|
|
71
|
+
* // Pass the promise somewhere
|
|
72
|
+
* performAsyncOperation(deferred.promise)
|
|
73
|
+
*
|
|
74
|
+
* // Resolve it when ready from anywhere
|
|
75
|
+
* deferred.resolve("Operation completed")
|
|
76
|
+
* deferred.failed("Error")
|
|
77
|
+
*/
|
|
78
|
+
class Deferred {
|
|
79
|
+
promise;
|
|
80
|
+
resolvePromise;
|
|
81
|
+
rejectPromise;
|
|
82
|
+
constructor(initial) {
|
|
83
|
+
this.promise = new Promise((resolve, reject) => {
|
|
84
|
+
this.resolvePromise = resolve;
|
|
85
|
+
this.rejectPromise = reject;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
resolve(value) {
|
|
89
|
+
this.resolvePromise(value);
|
|
90
|
+
}
|
|
91
|
+
reject(reason) {
|
|
92
|
+
this.rejectPromise(reason);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.Deferred = Deferred;
|
|
@@ -44,7 +44,7 @@ export declare class AnalyticsProcessor {
|
|
|
44
44
|
/**
|
|
45
45
|
* Track a single evaluation event for a feature.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
47
|
+
* @see FlagsmithConfig.enableAnalytics
|
|
48
48
|
*/
|
|
49
49
|
trackFeature(featureName: string): void;
|
|
50
50
|
}
|
|
@@ -64,7 +64,7 @@ export class AnalyticsProcessor {
|
|
|
64
64
|
/**
|
|
65
65
|
* Track a single evaluation event for a feature.
|
|
66
66
|
*
|
|
67
|
-
*
|
|
67
|
+
* @see FlagsmithConfig.enableAnalytics
|
|
68
68
|
*/
|
|
69
69
|
trackFeature(featureName) {
|
|
70
70
|
this.analyticsData[featureName] = (this.analyticsData[featureName] || 0) + 1;
|
package/build/esm/sdk/index.d.ts
CHANGED
|
@@ -11,6 +11,30 @@ export { FlagsmithAPIError, FlagsmithClientError } from './errors.js';
|
|
|
11
11
|
export { DefaultFlag, Flags } from './models.js';
|
|
12
12
|
export { EnvironmentDataPollingManager } from './polling_manager.js';
|
|
13
13
|
export { FlagsmithCache, FlagsmithConfig } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* A client for evaluating Flagsmith feature flags.
|
|
16
|
+
*
|
|
17
|
+
* Flags are evaluated remotely by the Flagsmith API over HTTP by default.
|
|
18
|
+
* To evaluate flags locally, create the client using {@link FlagsmithConfig.enableLocalEvaluation} and a server-side SDK key.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* import { Flagsmith, Flags, DefaultFlag } from 'flagsmith-nodejs'
|
|
22
|
+
*
|
|
23
|
+
* const flagsmith = new Flagsmith({
|
|
24
|
+
* environmentKey: 'your_sdk_key',
|
|
25
|
+
* defaultFlagHandler: (flagKey: string) => { new DefaultFlag(...) },
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // Fetch the current environment flags
|
|
29
|
+
* const environmentFlags: Flags = flagsmith.getEnvironmentFlags()
|
|
30
|
+
* const isFooEnabled: boolean = environmentFlags.isFeatureEnabled('foo')
|
|
31
|
+
*
|
|
32
|
+
* // Evaluate flags for any identity
|
|
33
|
+
* const identityFlags: Flags = flagsmith.getIdentityFlags('my_user_123', {'vip': true})
|
|
34
|
+
* const bannerVariation: string = identityFlags.getFeatureValue('banner_flag')
|
|
35
|
+
*
|
|
36
|
+
* @see FlagsmithConfig
|
|
37
|
+
*/
|
|
14
38
|
export declare class Flagsmith {
|
|
15
39
|
environmentKey?: string;
|
|
16
40
|
apiUrl?: string;
|
|
@@ -29,53 +53,24 @@ export declare class Flagsmith {
|
|
|
29
53
|
identitiesUrl?: string;
|
|
30
54
|
environmentUrl?: string;
|
|
31
55
|
environmentDataPollingManager?: EnvironmentDataPollingManager;
|
|
32
|
-
environment
|
|
56
|
+
private environment?;
|
|
33
57
|
offlineMode: boolean;
|
|
34
58
|
offlineHandler?: BaseOfflineHandler;
|
|
35
59
|
identitiesWithOverridesByIdentifier?: Map<string, IdentityModel>;
|
|
36
60
|
private cache?;
|
|
37
|
-
private onEnvironmentChange
|
|
61
|
+
private onEnvironmentChange;
|
|
38
62
|
private analyticsProcessor?;
|
|
39
63
|
private logger;
|
|
40
64
|
private customFetch;
|
|
65
|
+
private readonly requestRetryDelayMilliseconds;
|
|
41
66
|
/**
|
|
42
|
-
*
|
|
67
|
+
* Creates a new {@link Flagsmith} client.
|
|
43
68
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* const environmentFlags = flagsmith.getEnvironmentFlags();
|
|
50
|
-
* const featureEnabled = environmentFlags.isFeatureEnabled('foo');
|
|
51
|
-
* const identityFlags = flagsmith.getIdentityFlags('identifier', {'foo': 'bar'});
|
|
52
|
-
* const featureEnabledForIdentity = identityFlags.isFeatureEnabled("foo")
|
|
53
|
-
*
|
|
54
|
-
* @param {string} data.environmentKey: The environment key obtained from Flagsmith interface
|
|
55
|
-
* Required unless offlineMode is True.
|
|
56
|
-
@param {string} data.apiUrl: Override the URL of the Flagsmith API to communicate with
|
|
57
|
-
@param data.customHeaders: Additional headers to add to requests made to the
|
|
58
|
-
Flagsmith API
|
|
59
|
-
@param {number} data.requestTimeoutSeconds: Number of seconds to wait for a request to
|
|
60
|
-
complete before terminating the request
|
|
61
|
-
@param {boolean} data.enableLocalEvaluation: Enables local evaluation of flags
|
|
62
|
-
@param {number} data.environmentRefreshIntervalSeconds: If using local evaluation,
|
|
63
|
-
specify the interval period between refreshes of local environment data
|
|
64
|
-
@param {number} data.retries: a urllib3.Retry object to use on all http requests to the
|
|
65
|
-
Flagsmith API
|
|
66
|
-
@param {boolean} data.enableAnalytics: if enabled, sends additional requests to the Flagsmith
|
|
67
|
-
API to power flag analytics charts
|
|
68
|
-
@param data.defaultFlagHandler: callable which will be used in the case where
|
|
69
|
-
flags cannot be retrieved from the API or a non-existent feature is
|
|
70
|
-
requested
|
|
71
|
-
@param data.logger: an instance of the pino Logger class to use for logging
|
|
72
|
-
@param {boolean} data.offlineMode: sets the client into offline mode. Relies on offlineHandler for
|
|
73
|
-
evaluating flags.
|
|
74
|
-
@param {BaseOfflineHandler} data.offlineHandler: provide a handler for offline logic. Used to get environment
|
|
75
|
-
document from another source when in offlineMode. Works in place of
|
|
76
|
-
defaultFlagHandler if offlineMode is not set and using remote evaluation.
|
|
77
|
-
*/
|
|
78
|
-
constructor(data?: FlagsmithConfig);
|
|
69
|
+
* If using local evaluation, the environment will be fetched lazily when needed by any method. Polling the
|
|
70
|
+
* environment for updates will start after {@link environmentRefreshIntervalSeconds} once the client is created.
|
|
71
|
+
* @param data The {@link FlagsmithConfig} options for this client.
|
|
72
|
+
*/
|
|
73
|
+
constructor(data: FlagsmithConfig);
|
|
79
74
|
/**
|
|
80
75
|
* Get all the default for flags for the current environment.
|
|
81
76
|
*
|
|
@@ -110,10 +105,11 @@ export declare class Flagsmith {
|
|
|
110
105
|
getIdentitySegments(identifier: string, traits?: {
|
|
111
106
|
[key: string]: any;
|
|
112
107
|
}): Promise<SegmentModel[]>;
|
|
108
|
+
private fetchEnvironment;
|
|
113
109
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
110
|
+
* Fetch the latest environment state from the Flagsmith API to use for local flag evaluation.
|
|
111
|
+
*
|
|
112
|
+
* If the environment is currently being fetched, calling this method will not cause additional fetches.
|
|
117
113
|
*/
|
|
118
114
|
updateEnvironment(): Promise<void>;
|
|
119
115
|
close(): Promise<void>;
|
|
@@ -121,7 +117,13 @@ export declare class Flagsmith {
|
|
|
121
117
|
/**
|
|
122
118
|
* This promise ensures that the environment is retrieved before attempting to locally evaluate.
|
|
123
119
|
*/
|
|
124
|
-
private environmentPromise
|
|
120
|
+
private environmentPromise?;
|
|
121
|
+
/**
|
|
122
|
+
* Returns the current environment, fetching it from the API if needed.
|
|
123
|
+
*
|
|
124
|
+
* Calling this method concurrently while the environment is being fetched will not cause additional requests.
|
|
125
|
+
*/
|
|
126
|
+
getEnvironment(): Promise<EnvironmentModel>;
|
|
125
127
|
private getEnvironmentFromApi;
|
|
126
128
|
private getEnvironmentFlagsFromDocument;
|
|
127
129
|
private getIdentityFlagsFromDocument;
|