flagsmith-nodejs 3.1.1 → 3.3.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/.husky/pre-commit +1 -1
- package/README.md +2 -1
- package/build/flagsmith-engine/environments/models.d.ts +2 -5
- package/build/flagsmith-engine/environments/models.js +1 -0
- package/build/flagsmith-engine/environments/util.js +8 -2
- package/build/flagsmith-engine/features/util.js +2 -2
- package/build/flagsmith-engine/index.d.ts +0 -1
- package/build/flagsmith-engine/index.js +11 -13
- package/build/index.d.ts +2 -1
- package/build/index.js +1 -2
- package/build/sdk/index.d.ts +20 -9
- package/build/sdk/index.js +119 -53
- package/build/sdk/offline_handlers.d.ts +9 -0
- package/build/sdk/offline_handlers.js +66 -0
- package/build/sdk/types.d.ts +4 -1
- package/flagsmith-engine/environments/models.ts +2 -5
- package/flagsmith-engine/environments/util.ts +6 -0
- package/flagsmith-engine/features/util.ts +14 -13
- package/flagsmith-engine/index.ts +0 -1
- package/index.ts +4 -1
- package/package.json +1 -1
- package/sdk/index.ts +119 -48
- package/sdk/offline_handlers.ts +22 -0
- package/sdk/types.ts +4 -1
- package/tests/sdk/data/environment.json +27 -1
- package/tests/sdk/data/offline-environment.json +93 -0
- package/tests/sdk/flagsmith.test.ts +115 -27
- package/tests/sdk/offline-handlers.test.ts +33 -0
- package/tests/sdk/utils.ts +2 -2
- package/build/flagsmith-engine/environments/integrations/models.d.ts +0 -4
- package/build/flagsmith-engine/environments/integrations/models.js +0 -11
- package/examples/README.md +0 -3
- package/flagsmith-engine/environments/integrations/models.ts +0 -4
package/.husky/pre-commit
CHANGED
package/README.md
CHANGED
|
@@ -22,7 +22,8 @@ If you encounter a bug or feature request we would like to hear about it. Before
|
|
|
22
22
|
## Testing
|
|
23
23
|
|
|
24
24
|
To run the local tests you need to run following command beforehand:
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
```bash
|
|
26
27
|
git submodule add git@github.com:Flagsmith/engine-test-data.git tests/engine/engine-tests/engine-test-data/
|
|
27
28
|
```
|
|
28
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FeatureStateModel } from '../features/models';
|
|
2
|
+
import { IdentityModel } from '../identities/models';
|
|
2
3
|
import { ProjectModel } from '../projects/models';
|
|
3
|
-
import { IntegrationModel } from './integrations/models';
|
|
4
4
|
export declare class EnvironmentAPIKeyModel {
|
|
5
5
|
id: number;
|
|
6
6
|
key: string;
|
|
@@ -17,9 +17,6 @@ export declare class EnvironmentModel {
|
|
|
17
17
|
apiKey: string;
|
|
18
18
|
project: ProjectModel;
|
|
19
19
|
featureStates: FeatureStateModel[];
|
|
20
|
-
|
|
21
|
-
segment_config?: IntegrationModel;
|
|
22
|
-
mixpanel_config?: IntegrationModel;
|
|
23
|
-
heap_config?: IntegrationModel;
|
|
20
|
+
identityOverrides: IdentityModel[];
|
|
24
21
|
constructor(id: number, apiKey: string, project: ProjectModel);
|
|
25
22
|
}
|
|
@@ -20,6 +20,7 @@ exports.EnvironmentAPIKeyModel = EnvironmentAPIKeyModel;
|
|
|
20
20
|
var EnvironmentModel = /** @class */ (function () {
|
|
21
21
|
function EnvironmentModel(id, apiKey, project) {
|
|
22
22
|
this.featureStates = [];
|
|
23
|
+
this.identityOverrides = [];
|
|
23
24
|
this.id = id;
|
|
24
25
|
this.apiKey = apiKey;
|
|
25
26
|
this.project = project;
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildEnvironmentAPIKeyModel = exports.buildEnvironmentModel = void 0;
|
|
4
4
|
var util_1 = require("../features/util");
|
|
5
|
-
var util_2 = require("../
|
|
5
|
+
var util_2 = require("../identities/util");
|
|
6
|
+
var util_3 = require("../projects/util");
|
|
6
7
|
var models_1 = require("./models");
|
|
7
8
|
function buildEnvironmentModel(environmentJSON) {
|
|
8
|
-
var project = (0,
|
|
9
|
+
var project = (0, util_3.buildProjectModel)(environmentJSON.project);
|
|
9
10
|
var featureStates = environmentJSON.feature_states.map(function (fs) {
|
|
10
11
|
return (0, util_1.buildFeatureStateModel)(fs);
|
|
11
12
|
});
|
|
12
13
|
var environmentModel = new models_1.EnvironmentModel(environmentJSON.id, environmentJSON.api_key, project);
|
|
13
14
|
environmentModel.featureStates = featureStates;
|
|
15
|
+
if (!!environmentJSON.identity_overrides) {
|
|
16
|
+
environmentModel.identityOverrides = environmentJSON.identity_overrides.map(function (identityData) {
|
|
17
|
+
return (0, util_2.buildIdentityModel)(identityData);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
14
20
|
return environmentModel;
|
|
15
21
|
}
|
|
16
22
|
exports.buildEnvironmentModel = buildEnvironmentModel;
|
|
@@ -7,14 +7,14 @@ function buildFeatureModel(featuresModelJSON) {
|
|
|
7
7
|
}
|
|
8
8
|
exports.buildFeatureModel = buildFeatureModel;
|
|
9
9
|
function buildFeatureStateModel(featuresStateModelJSON) {
|
|
10
|
-
var featureStateModel = new models_1.FeatureStateModel(buildFeatureModel(featuresStateModelJSON.feature), featuresStateModelJSON.enabled, featuresStateModelJSON.django_id, featuresStateModelJSON.feature_state_value, featuresStateModelJSON.
|
|
10
|
+
var featureStateModel = new models_1.FeatureStateModel(buildFeatureModel(featuresStateModelJSON.feature), featuresStateModelJSON.enabled, featuresStateModelJSON.django_id, featuresStateModelJSON.feature_state_value, featuresStateModelJSON.featurestate_uuid);
|
|
11
11
|
featureStateModel.featureSegment = featuresStateModelJSON.feature_segment ?
|
|
12
12
|
buildFeatureSegment(featuresStateModelJSON.feature_segment) :
|
|
13
13
|
undefined;
|
|
14
14
|
var multivariateFeatureStateValues = featuresStateModelJSON.multivariate_feature_state_values
|
|
15
15
|
? featuresStateModelJSON.multivariate_feature_state_values.map(function (fsv) {
|
|
16
16
|
var featureOption = new models_1.MultivariateFeatureOptionModel(fsv.multivariate_feature_option.value, fsv.multivariate_feature_option.id);
|
|
17
|
-
return new models_1.MultivariateFeatureStateValueModel(featureOption, fsv.percentage_allocation, fsv.id);
|
|
17
|
+
return new models_1.MultivariateFeatureStateValueModel(featureOption, fsv.percentage_allocation, fsv.id, fsv.mv_fs_value_uuid);
|
|
18
18
|
})
|
|
19
19
|
: [];
|
|
20
20
|
featureStateModel.multivariateFeatureStateValues = multivariateFeatureStateValues;
|
|
@@ -3,7 +3,6 @@ import { FeatureStateModel } from './features/models';
|
|
|
3
3
|
import { IdentityModel } from './identities/models';
|
|
4
4
|
import { TraitModel } from './identities/traits/models';
|
|
5
5
|
export { EnvironmentModel } from './environments/models';
|
|
6
|
-
export { IntegrationModel } from './environments/integrations/models';
|
|
7
6
|
export { FeatureStateModel } from './features/models';
|
|
8
7
|
export { IdentityModel } from './identities/models';
|
|
9
8
|
export { TraitModel } from './identities/traits/models';
|
|
@@ -11,23 +11,21 @@ var __values = (this && this.__values) || function(o) {
|
|
|
11
11
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.getEnvironmentFeatureStates = exports.getEnvironmentFeatureState = exports.getIdentityFeatureStates = exports.getIdentityFeatureState = exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.
|
|
14
|
+
exports.getEnvironmentFeatureStates = exports.getEnvironmentFeatureState = exports.getIdentityFeatureStates = exports.getIdentityFeatureState = exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.EnvironmentModel = void 0;
|
|
15
15
|
var evaluators_1 = require("./segments/evaluators");
|
|
16
16
|
var errors_1 = require("./utils/errors");
|
|
17
17
|
var models_1 = require("./environments/models");
|
|
18
18
|
Object.defineProperty(exports, "EnvironmentModel", { enumerable: true, get: function () { return models_1.EnvironmentModel; } });
|
|
19
|
-
var models_2 = require("./
|
|
20
|
-
Object.defineProperty(exports, "
|
|
21
|
-
var models_3 = require("./
|
|
22
|
-
Object.defineProperty(exports, "
|
|
23
|
-
var models_4 = require("./identities/models");
|
|
24
|
-
Object.defineProperty(exports, "
|
|
25
|
-
var models_5 = require("./
|
|
26
|
-
Object.defineProperty(exports, "
|
|
27
|
-
var models_6 = require("./
|
|
28
|
-
Object.defineProperty(exports, "
|
|
29
|
-
var models_7 = require("./organisations/models");
|
|
30
|
-
Object.defineProperty(exports, "OrganisationModel", { enumerable: true, get: function () { return models_7.OrganisationModel; } });
|
|
19
|
+
var models_2 = require("./features/models");
|
|
20
|
+
Object.defineProperty(exports, "FeatureStateModel", { enumerable: true, get: function () { return models_2.FeatureStateModel; } });
|
|
21
|
+
var models_3 = require("./identities/models");
|
|
22
|
+
Object.defineProperty(exports, "IdentityModel", { enumerable: true, get: function () { return models_3.IdentityModel; } });
|
|
23
|
+
var models_4 = require("./identities/traits/models");
|
|
24
|
+
Object.defineProperty(exports, "TraitModel", { enumerable: true, get: function () { return models_4.TraitModel; } });
|
|
25
|
+
var models_5 = require("./segments/models");
|
|
26
|
+
Object.defineProperty(exports, "SegmentModel", { enumerable: true, get: function () { return models_5.SegmentModel; } });
|
|
27
|
+
var models_6 = require("./organisations/models");
|
|
28
|
+
Object.defineProperty(exports, "OrganisationModel", { enumerable: true, get: function () { return models_6.OrganisationModel; } });
|
|
31
29
|
function getIdentityFeatureStatesDict(environment, identity, overrideTraits) {
|
|
32
30
|
var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
|
|
33
31
|
// Get feature states from the environment
|
package/build/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { AnalyticsProcessor, FlagsmithAPIError, FlagsmithClientError, EnvironmentDataPollingManager, FlagsmithCache, DefaultFlag, Flags, default } from './sdk';
|
|
2
|
-
export {
|
|
2
|
+
export { FlagsmithConfig } from './sdk/types';
|
|
3
|
+
export { EnvironmentModel, FeatureStateModel, IdentityModel, TraitModel, SegmentModel, OrganisationModel } from './flagsmith-engine';
|
package/build/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.
|
|
6
|
+
exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.EnvironmentModel = exports.default = exports.Flags = exports.DefaultFlag = exports.EnvironmentDataPollingManager = exports.FlagsmithClientError = exports.FlagsmithAPIError = exports.AnalyticsProcessor = void 0;
|
|
7
7
|
var sdk_1 = __importDefault(require("./sdk"));
|
|
8
8
|
var sdk_2 = require("./sdk");
|
|
9
9
|
Object.defineProperty(exports, "AnalyticsProcessor", { enumerable: true, get: function () { return sdk_2.AnalyticsProcessor; } });
|
|
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { r
|
|
|
15
15
|
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(sdk_2).default; } });
|
|
16
16
|
var flagsmith_engine_1 = require("./flagsmith-engine");
|
|
17
17
|
Object.defineProperty(exports, "EnvironmentModel", { enumerable: true, get: function () { return flagsmith_engine_1.EnvironmentModel; } });
|
|
18
|
-
Object.defineProperty(exports, "IntegrationModel", { enumerable: true, get: function () { return flagsmith_engine_1.IntegrationModel; } });
|
|
19
18
|
Object.defineProperty(exports, "FeatureStateModel", { enumerable: true, get: function () { return flagsmith_engine_1.FeatureStateModel; } });
|
|
20
19
|
Object.defineProperty(exports, "IdentityModel", { enumerable: true, get: function () { return flagsmith_engine_1.IdentityModel; } });
|
|
21
20
|
Object.defineProperty(exports, "TraitModel", { enumerable: true, get: function () { return flagsmith_engine_1.TraitModel; } });
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { RequestInit } from
|
|
1
|
+
import { RequestInit } from 'node-fetch';
|
|
2
2
|
import { EnvironmentModel } from '../flagsmith-engine/environments/models';
|
|
3
|
+
import { IdentityModel } from '../flagsmith-engine/identities/models';
|
|
4
|
+
import { BaseOfflineHandler } from './offline_handlers';
|
|
3
5
|
import { DefaultFlag, Flags } from './models';
|
|
4
6
|
import { EnvironmentDataPollingManager } from './polling_manager';
|
|
5
7
|
import { SegmentModel } from '../flagsmith-engine/segments/models';
|
|
@@ -11,7 +13,7 @@ export { EnvironmentDataPollingManager } from './polling_manager';
|
|
|
11
13
|
export { FlagsmithCache, FlagsmithConfig } from './types';
|
|
12
14
|
export declare class Flagsmith {
|
|
13
15
|
environmentKey?: string;
|
|
14
|
-
apiUrl
|
|
16
|
+
apiUrl?: string;
|
|
15
17
|
customHeaders?: {
|
|
16
18
|
[key: string]: any;
|
|
17
19
|
};
|
|
@@ -22,11 +24,14 @@ export declare class Flagsmith {
|
|
|
22
24
|
retries?: number;
|
|
23
25
|
enableAnalytics: boolean;
|
|
24
26
|
defaultFlagHandler?: (featureName: string) => DefaultFlag;
|
|
25
|
-
environmentFlagsUrl
|
|
26
|
-
identitiesUrl
|
|
27
|
-
environmentUrl
|
|
27
|
+
environmentFlagsUrl?: string;
|
|
28
|
+
identitiesUrl?: string;
|
|
29
|
+
environmentUrl?: string;
|
|
28
30
|
environmentDataPollingManager?: EnvironmentDataPollingManager;
|
|
29
31
|
environment: EnvironmentModel;
|
|
32
|
+
offlineMode: boolean;
|
|
33
|
+
offlineHandler?: BaseOfflineHandler;
|
|
34
|
+
identitiesWithOverridesByIdentifier?: Map<string, IdentityModel>;
|
|
30
35
|
private cache?;
|
|
31
36
|
private onEnvironmentChange?;
|
|
32
37
|
private analyticsProcessor?;
|
|
@@ -45,6 +50,7 @@ export declare class Flagsmith {
|
|
|
45
50
|
* const featureEnabledForIdentity = identityFlags.isFeatureEnabled("foo")
|
|
46
51
|
*
|
|
47
52
|
* @param {string} data.environmentKey: The environment key obtained from Flagsmith interface
|
|
53
|
+
* Required unless offlineMode is True.
|
|
48
54
|
@param {string} data.apiUrl: Override the URL of the Flagsmith API to communicate with
|
|
49
55
|
@param data.customHeaders: Additional headers to add to requests made to the
|
|
50
56
|
Flagsmith API
|
|
@@ -58,11 +64,16 @@ export declare class Flagsmith {
|
|
|
58
64
|
@param {boolean} data.enableAnalytics: if enabled, sends additional requests to the Flagsmith
|
|
59
65
|
API to power flag analytics charts
|
|
60
66
|
@param data.defaultFlagHandler: callable which will be used in the case where
|
|
61
|
-
flags cannot be retrieved from the API or a non
|
|
67
|
+
flags cannot be retrieved from the API or a non-existent feature is
|
|
62
68
|
requested
|
|
63
69
|
@param data.logger: an instance of the pino Logger class to use for logging
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
@param {boolean} data.offlineMode: sets the client into offline mode. Relies on offlineHandler for
|
|
71
|
+
evaluating flags.
|
|
72
|
+
@param {BaseOfflineHandler} data.offlineHandler: provide a handler for offline logic. Used to get environment
|
|
73
|
+
document from another source when in offlineMode. Works in place of
|
|
74
|
+
defaultFlagHandler if offlineMode is not set and using remote evaluation.
|
|
75
|
+
*/
|
|
76
|
+
constructor(data?: FlagsmithConfig);
|
|
66
77
|
/**
|
|
67
78
|
* Get all the default for flags for the current environment.
|
|
68
79
|
*
|
|
@@ -114,6 +125,6 @@ export declare class Flagsmith {
|
|
|
114
125
|
private getIdentityFlagsFromDocument;
|
|
115
126
|
private getEnvironmentFlagsFromApi;
|
|
116
127
|
private getIdentityFlagsFromApi;
|
|
117
|
-
private
|
|
128
|
+
private getIdentityModel;
|
|
118
129
|
}
|
|
119
130
|
export default Flagsmith;
|
package/build/sdk/index.js
CHANGED
|
@@ -105,6 +105,7 @@ var Flagsmith = /** @class */ (function () {
|
|
|
105
105
|
* const featureEnabledForIdentity = identityFlags.isFeatureEnabled("foo")
|
|
106
106
|
*
|
|
107
107
|
* @param {string} data.environmentKey: The environment key obtained from Flagsmith interface
|
|
108
|
+
* Required unless offlineMode is True.
|
|
108
109
|
@param {string} data.apiUrl: Override the URL of the Flagsmith API to communicate with
|
|
109
110
|
@param data.customHeaders: Additional headers to add to requests made to the
|
|
110
111
|
Flagsmith API
|
|
@@ -118,32 +119,54 @@ var Flagsmith = /** @class */ (function () {
|
|
|
118
119
|
@param {boolean} data.enableAnalytics: if enabled, sends additional requests to the Flagsmith
|
|
119
120
|
API to power flag analytics charts
|
|
120
121
|
@param data.defaultFlagHandler: callable which will be used in the case where
|
|
121
|
-
flags cannot be retrieved from the API or a non
|
|
122
|
+
flags cannot be retrieved from the API or a non-existent feature is
|
|
122
123
|
requested
|
|
123
124
|
@param data.logger: an instance of the pino Logger class to use for logging
|
|
124
|
-
|
|
125
|
+
@param {boolean} data.offlineMode: sets the client into offline mode. Relies on offlineHandler for
|
|
126
|
+
evaluating flags.
|
|
127
|
+
@param {BaseOfflineHandler} data.offlineHandler: provide a handler for offline logic. Used to get environment
|
|
128
|
+
document from another source when in offlineMode. Works in place of
|
|
129
|
+
defaultFlagHandler if offlineMode is not set and using remote evaluation.
|
|
130
|
+
*/
|
|
125
131
|
function Flagsmith(data) {
|
|
132
|
+
// if (!data.offlineMode && !data.environmentKey) {
|
|
133
|
+
// throw new Error('ValueError: environmentKey is required.');
|
|
134
|
+
// }
|
|
135
|
+
if (data === void 0) { data = {}; }
|
|
126
136
|
var _a;
|
|
127
|
-
this.
|
|
137
|
+
this.environmentKey = undefined;
|
|
138
|
+
this.apiUrl = undefined;
|
|
128
139
|
this.enableLocalEvaluation = false;
|
|
129
140
|
this.environmentRefreshIntervalSeconds = 60;
|
|
130
141
|
this.enableAnalytics = false;
|
|
142
|
+
this.offlineMode = false;
|
|
143
|
+
this.offlineHandler = undefined;
|
|
131
144
|
this.agent = data.agent;
|
|
132
145
|
this.environmentKey = data.environmentKey;
|
|
133
146
|
this.apiUrl = data.apiUrl || this.apiUrl;
|
|
134
147
|
this.customHeaders = data.customHeaders;
|
|
135
|
-
this.requestTimeoutMs =
|
|
148
|
+
this.requestTimeoutMs =
|
|
149
|
+
1000 * ((_a = data.requestTimeoutSeconds) !== null && _a !== void 0 ? _a : DEFAULT_REQUEST_TIMEOUT_SECONDS);
|
|
136
150
|
this.enableLocalEvaluation = data.enableLocalEvaluation;
|
|
137
151
|
this.environmentRefreshIntervalSeconds =
|
|
138
152
|
data.environmentRefreshIntervalSeconds || this.environmentRefreshIntervalSeconds;
|
|
139
153
|
this.retries = data.retries;
|
|
140
154
|
this.enableAnalytics = data.enableAnalytics || false;
|
|
141
155
|
this.defaultFlagHandler = data.defaultFlagHandler;
|
|
142
|
-
this.environmentFlagsUrl = "".concat(this.apiUrl, "flags/");
|
|
143
|
-
this.identitiesUrl = "".concat(this.apiUrl, "identities/");
|
|
144
|
-
this.environmentUrl = "".concat(this.apiUrl, "environment-document/");
|
|
145
156
|
this.onEnvironmentChange = data.onEnvironmentChange;
|
|
146
157
|
this.logger = data.logger || (0, pino_1.default)();
|
|
158
|
+
this.offlineMode = data.offlineMode || false;
|
|
159
|
+
this.offlineHandler = data.offlineHandler;
|
|
160
|
+
// argument validation
|
|
161
|
+
if (this.offlineMode && !this.offlineHandler) {
|
|
162
|
+
throw new Error('ValueError: offlineHandler must be provided to use offline mode.');
|
|
163
|
+
}
|
|
164
|
+
else if (this.defaultFlagHandler && this.offlineHandler) {
|
|
165
|
+
throw new Error('ValueError: Cannot use both defaultFlagHandler and offlineHandler.');
|
|
166
|
+
}
|
|
167
|
+
if (this.offlineHandler) {
|
|
168
|
+
this.environment = this.offlineHandler.getEnvironment();
|
|
169
|
+
}
|
|
147
170
|
if (!!data.cache) {
|
|
148
171
|
var missingMethods = ['has', 'get', 'set'].filter(function (method) { return data.cache && !data.cache[method]; });
|
|
149
172
|
if (missingMethods.length > 0) {
|
|
@@ -151,22 +174,32 @@ var Flagsmith = /** @class */ (function () {
|
|
|
151
174
|
}
|
|
152
175
|
this.cache = data.cache;
|
|
153
176
|
}
|
|
154
|
-
if (this.
|
|
155
|
-
if (!this.environmentKey
|
|
156
|
-
|
|
177
|
+
if (!this.offlineMode) {
|
|
178
|
+
if (!this.environmentKey) {
|
|
179
|
+
throw new Error('ValueError: environmentKey is required.');
|
|
157
180
|
}
|
|
158
|
-
|
|
159
|
-
this.
|
|
160
|
-
this.
|
|
181
|
+
var apiUrl = data.apiUrl || DEFAULT_API_URL;
|
|
182
|
+
this.apiUrl = apiUrl.endsWith('/') ? apiUrl : "".concat(apiUrl, "/");
|
|
183
|
+
this.environmentFlagsUrl = "".concat(this.apiUrl, "flags/");
|
|
184
|
+
this.identitiesUrl = "".concat(this.apiUrl, "identities/");
|
|
185
|
+
this.environmentUrl = "".concat(this.apiUrl, "environment-document/");
|
|
186
|
+
if (this.enableLocalEvaluation) {
|
|
187
|
+
if (!this.environmentKey.startsWith('ser.')) {
|
|
188
|
+
console.error('In order to use local evaluation, please generate a server key in the environment settings page.');
|
|
189
|
+
}
|
|
190
|
+
this.environmentDataPollingManager = new polling_manager_1.EnvironmentDataPollingManager(this, this.environmentRefreshIntervalSeconds);
|
|
191
|
+
this.environmentDataPollingManager.start();
|
|
192
|
+
this.updateEnvironment();
|
|
193
|
+
}
|
|
194
|
+
this.analyticsProcessor = data.enableAnalytics
|
|
195
|
+
? new analytics_1.AnalyticsProcessor({
|
|
196
|
+
environmentKey: this.environmentKey,
|
|
197
|
+
baseApiUrl: this.apiUrl,
|
|
198
|
+
requestTimeoutMs: this.requestTimeoutMs,
|
|
199
|
+
logger: this.logger
|
|
200
|
+
})
|
|
201
|
+
: undefined;
|
|
161
202
|
}
|
|
162
|
-
this.analyticsProcessor = data.enableAnalytics
|
|
163
|
-
? new analytics_1.AnalyticsProcessor({
|
|
164
|
-
environmentKey: this.environmentKey,
|
|
165
|
-
baseApiUrl: this.apiUrl,
|
|
166
|
-
requestTimeoutMs: this.requestTimeoutMs,
|
|
167
|
-
logger: this.logger
|
|
168
|
-
})
|
|
169
|
-
: undefined;
|
|
170
203
|
}
|
|
171
204
|
/**
|
|
172
205
|
* Get all the default for flags for the current environment.
|
|
@@ -191,7 +224,7 @@ var Flagsmith = /** @class */ (function () {
|
|
|
191
224
|
if (!!cachedItem) {
|
|
192
225
|
return [2 /*return*/, cachedItem];
|
|
193
226
|
}
|
|
194
|
-
if (this.enableLocalEvaluation) {
|
|
227
|
+
if (this.enableLocalEvaluation && !this.offlineMode) {
|
|
195
228
|
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
196
229
|
return _this.environmentPromise.then(function () {
|
|
197
230
|
resolve(_this.getEnvironmentFlagsFromDocument());
|
|
@@ -225,7 +258,7 @@ var Flagsmith = /** @class */ (function () {
|
|
|
225
258
|
switch (_b.label) {
|
|
226
259
|
case 0:
|
|
227
260
|
if (!identifier) {
|
|
228
|
-
throw new Error(
|
|
261
|
+
throw new Error('`identifier` argument is missing or invalid.');
|
|
229
262
|
}
|
|
230
263
|
_a = !!this.cache;
|
|
231
264
|
if (!_a) return [3 /*break*/, 2];
|
|
@@ -246,6 +279,9 @@ var Flagsmith = /** @class */ (function () {
|
|
|
246
279
|
}).catch(function (e) { return reject(e); });
|
|
247
280
|
})];
|
|
248
281
|
}
|
|
282
|
+
if (this.offlineMode) {
|
|
283
|
+
return [2 /*return*/, this.getIdentityFlagsFromDocument(identifier, traits || {})];
|
|
284
|
+
}
|
|
249
285
|
return [2 /*return*/, this.getIdentityFlagsFromApi(identifier, traits)];
|
|
250
286
|
}
|
|
251
287
|
});
|
|
@@ -265,13 +301,13 @@ var Flagsmith = /** @class */ (function () {
|
|
|
265
301
|
Flagsmith.prototype.getIdentitySegments = function (identifier, traits) {
|
|
266
302
|
var _this = this;
|
|
267
303
|
if (!identifier) {
|
|
268
|
-
throw new Error(
|
|
304
|
+
throw new Error('`identifier` argument is missing or invalid.');
|
|
269
305
|
}
|
|
270
306
|
traits = traits || {};
|
|
271
307
|
if (this.enableLocalEvaluation) {
|
|
272
308
|
return new Promise(function (resolve, reject) {
|
|
273
309
|
return _this.environmentPromise.then(function () {
|
|
274
|
-
var identityModel = _this.
|
|
310
|
+
var identityModel = _this.getIdentityModel(identifier, Object.keys(traits || {}).map(function (key) { return ({
|
|
275
311
|
key: key,
|
|
276
312
|
value: traits === null || traits === void 0 ? void 0 : traits[key]
|
|
277
313
|
}); }));
|
|
@@ -289,13 +325,14 @@ var Flagsmith = /** @class */ (function () {
|
|
|
289
325
|
* You only need to call this if you wish to bypass environmentRefreshIntervalSeconds.
|
|
290
326
|
*/
|
|
291
327
|
Flagsmith.prototype.updateEnvironment = function () {
|
|
328
|
+
var _a;
|
|
292
329
|
return __awaiter(this, void 0, void 0, function () {
|
|
293
|
-
var request,
|
|
330
|
+
var request, _b, e_1;
|
|
294
331
|
var _this = this;
|
|
295
|
-
return __generator(this, function (
|
|
296
|
-
switch (
|
|
332
|
+
return __generator(this, function (_c) {
|
|
333
|
+
switch (_c.label) {
|
|
297
334
|
case 0:
|
|
298
|
-
|
|
335
|
+
_c.trys.push([0, 5, , 6]);
|
|
299
336
|
request = this.getEnvironmentFromApi();
|
|
300
337
|
if (!!this.environmentPromise) return [3 /*break*/, 2];
|
|
301
338
|
this.environmentPromise = request.then(function (res) {
|
|
@@ -303,21 +340,24 @@ var Flagsmith = /** @class */ (function () {
|
|
|
303
340
|
});
|
|
304
341
|
return [4 /*yield*/, this.environmentPromise];
|
|
305
342
|
case 1:
|
|
306
|
-
|
|
343
|
+
_c.sent();
|
|
307
344
|
return [3 /*break*/, 4];
|
|
308
345
|
case 2:
|
|
309
|
-
|
|
346
|
+
_b = this;
|
|
310
347
|
return [4 /*yield*/, request];
|
|
311
348
|
case 3:
|
|
312
|
-
|
|
313
|
-
|
|
349
|
+
_b.environment = _c.sent();
|
|
350
|
+
_c.label = 4;
|
|
314
351
|
case 4:
|
|
352
|
+
if ((_a = this.environment.identityOverrides) === null || _a === void 0 ? void 0 : _a.length) {
|
|
353
|
+
this.identitiesWithOverridesByIdentifier = new Map(this.environment.identityOverrides.map(function (identity) { return [identity.identifier, identity]; }));
|
|
354
|
+
}
|
|
315
355
|
if (this.onEnvironmentChange) {
|
|
316
356
|
this.onEnvironmentChange(null, this.environment);
|
|
317
357
|
}
|
|
318
358
|
return [3 /*break*/, 6];
|
|
319
359
|
case 5:
|
|
320
|
-
e_1 =
|
|
360
|
+
e_1 = _c.sent();
|
|
321
361
|
if (this.onEnvironmentChange) {
|
|
322
362
|
this.onEnvironmentChange(e_1, this.environment);
|
|
323
363
|
}
|
|
@@ -383,7 +423,11 @@ var Flagsmith = /** @class */ (function () {
|
|
|
383
423
|
var environment_data;
|
|
384
424
|
return __generator(this, function (_a) {
|
|
385
425
|
switch (_a.label) {
|
|
386
|
-
case 0:
|
|
426
|
+
case 0:
|
|
427
|
+
if (!this.environmentUrl) {
|
|
428
|
+
throw new Error('`apiUrl` argument is missing or invalid.');
|
|
429
|
+
}
|
|
430
|
+
return [4 /*yield*/, this.getJSONResponse(this.environmentUrl, 'GET')];
|
|
387
431
|
case 1:
|
|
388
432
|
environment_data = _a.sent();
|
|
389
433
|
return [2 /*return*/, (0, util_1.buildEnvironmentModel)(environment_data)];
|
|
@@ -420,7 +464,7 @@ var Flagsmith = /** @class */ (function () {
|
|
|
420
464
|
return __generator(this, function (_a) {
|
|
421
465
|
switch (_a.label) {
|
|
422
466
|
case 0:
|
|
423
|
-
identityModel = this.
|
|
467
|
+
identityModel = this.getIdentityModel(identifier, Object.keys(traits).map(function (key) { return ({
|
|
424
468
|
key: key,
|
|
425
469
|
value: traits[key]
|
|
426
470
|
}); }));
|
|
@@ -449,25 +493,33 @@ var Flagsmith = /** @class */ (function () {
|
|
|
449
493
|
return __generator(this, function (_a) {
|
|
450
494
|
switch (_a.label) {
|
|
451
495
|
case 0:
|
|
452
|
-
|
|
453
|
-
|
|
496
|
+
if (!this.environmentFlagsUrl) {
|
|
497
|
+
throw new Error('`apiUrl` argument is missing or invalid.');
|
|
498
|
+
}
|
|
499
|
+
_a.label = 1;
|
|
454
500
|
case 1:
|
|
501
|
+
_a.trys.push([1, 5, , 6]);
|
|
502
|
+
return [4 /*yield*/, this.getJSONResponse(this.environmentFlagsUrl, 'GET')];
|
|
503
|
+
case 2:
|
|
455
504
|
apiFlags = _a.sent();
|
|
456
505
|
flags = models_3.Flags.fromAPIFlags({
|
|
457
506
|
apiFlags: apiFlags,
|
|
458
507
|
analyticsProcessor: this.analyticsProcessor,
|
|
459
508
|
defaultFlagHandler: this.defaultFlagHandler
|
|
460
509
|
});
|
|
461
|
-
if (!!!this.cache) return [3 /*break*/,
|
|
510
|
+
if (!!!this.cache) return [3 /*break*/, 4];
|
|
462
511
|
// @ts-ignore node-cache types are incorrect, ttl should be optional
|
|
463
512
|
return [4 /*yield*/, this.cache.set('flags', flags)];
|
|
464
|
-
case
|
|
513
|
+
case 3:
|
|
465
514
|
// @ts-ignore node-cache types are incorrect, ttl should be optional
|
|
466
515
|
_a.sent();
|
|
467
|
-
_a.label =
|
|
468
|
-
case
|
|
469
|
-
case
|
|
516
|
+
_a.label = 4;
|
|
517
|
+
case 4: return [2 /*return*/, flags];
|
|
518
|
+
case 5:
|
|
470
519
|
e_3 = _a.sent();
|
|
520
|
+
if (this.offlineHandler) {
|
|
521
|
+
return [2 /*return*/, this.getEnvironmentFlagsFromDocument()];
|
|
522
|
+
}
|
|
471
523
|
if (this.defaultFlagHandler) {
|
|
472
524
|
return [2 /*return*/, new models_3.Flags({
|
|
473
525
|
flags: {},
|
|
@@ -475,7 +527,7 @@ var Flagsmith = /** @class */ (function () {
|
|
|
475
527
|
})];
|
|
476
528
|
}
|
|
477
529
|
throw e_3;
|
|
478
|
-
case
|
|
530
|
+
case 6: return [2 /*return*/];
|
|
479
531
|
}
|
|
480
532
|
});
|
|
481
533
|
});
|
|
@@ -486,26 +538,34 @@ var Flagsmith = /** @class */ (function () {
|
|
|
486
538
|
return __generator(this, function (_a) {
|
|
487
539
|
switch (_a.label) {
|
|
488
540
|
case 0:
|
|
489
|
-
|
|
541
|
+
if (!this.identitiesUrl) {
|
|
542
|
+
throw new Error('`apiUrl` argument is missing or invalid.');
|
|
543
|
+
}
|
|
544
|
+
_a.label = 1;
|
|
545
|
+
case 1:
|
|
546
|
+
_a.trys.push([1, 5, , 6]);
|
|
490
547
|
data = (0, utils_1.generateIdentitiesData)(identifier, traits);
|
|
491
548
|
return [4 /*yield*/, this.getJSONResponse(this.identitiesUrl, 'POST', data)];
|
|
492
|
-
case
|
|
549
|
+
case 2:
|
|
493
550
|
jsonResponse = _a.sent();
|
|
494
551
|
flags = models_3.Flags.fromAPIFlags({
|
|
495
552
|
apiFlags: jsonResponse['flags'],
|
|
496
553
|
analyticsProcessor: this.analyticsProcessor,
|
|
497
554
|
defaultFlagHandler: this.defaultFlagHandler
|
|
498
555
|
});
|
|
499
|
-
if (!!!this.cache) return [3 /*break*/,
|
|
556
|
+
if (!!!this.cache) return [3 /*break*/, 4];
|
|
500
557
|
// @ts-ignore node-cache types are incorrect, ttl should be optional
|
|
501
558
|
return [4 /*yield*/, this.cache.set("flags-".concat(identifier), flags)];
|
|
502
|
-
case
|
|
559
|
+
case 3:
|
|
503
560
|
// @ts-ignore node-cache types are incorrect, ttl should be optional
|
|
504
561
|
_a.sent();
|
|
505
|
-
_a.label =
|
|
506
|
-
case
|
|
507
|
-
case
|
|
562
|
+
_a.label = 4;
|
|
563
|
+
case 4: return [2 /*return*/, flags];
|
|
564
|
+
case 5:
|
|
508
565
|
e_4 = _a.sent();
|
|
566
|
+
if (this.offlineHandler) {
|
|
567
|
+
return [2 /*return*/, this.getIdentityFlagsFromDocument(identifier, traits)];
|
|
568
|
+
}
|
|
509
569
|
if (this.defaultFlagHandler) {
|
|
510
570
|
return [2 /*return*/, new models_3.Flags({
|
|
511
571
|
flags: {},
|
|
@@ -513,13 +573,19 @@ var Flagsmith = /** @class */ (function () {
|
|
|
513
573
|
})];
|
|
514
574
|
}
|
|
515
575
|
throw e_4;
|
|
516
|
-
case
|
|
576
|
+
case 6: return [2 /*return*/];
|
|
517
577
|
}
|
|
518
578
|
});
|
|
519
579
|
});
|
|
520
580
|
};
|
|
521
|
-
Flagsmith.prototype.
|
|
581
|
+
Flagsmith.prototype.getIdentityModel = function (identifier, traits) {
|
|
582
|
+
var _a;
|
|
522
583
|
var traitModels = traits.map(function (trait) { return new models_2.TraitModel(trait.key, trait.value); });
|
|
584
|
+
var identityWithOverrides = (_a = this.identitiesWithOverridesByIdentifier) === null || _a === void 0 ? void 0 : _a.get(identifier);
|
|
585
|
+
if (identityWithOverrides) {
|
|
586
|
+
identityWithOverrides.updateTraits(traitModels);
|
|
587
|
+
return identityWithOverrides;
|
|
588
|
+
}
|
|
523
589
|
return new models_1.IdentityModel('0', traitModels, [], this.environment.apiKey, identifier);
|
|
524
590
|
};
|
|
525
591
|
return Flagsmith;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnvironmentModel } from '../flagsmith-engine/environments/models';
|
|
2
|
+
export declare class BaseOfflineHandler {
|
|
3
|
+
getEnvironment(): EnvironmentModel;
|
|
4
|
+
}
|
|
5
|
+
export declare class LocalFileHandler extends BaseOfflineHandler {
|
|
6
|
+
environment: EnvironmentModel;
|
|
7
|
+
constructor(environment_document_path: string);
|
|
8
|
+
getEnvironment(): EnvironmentModel;
|
|
9
|
+
}
|