flagsmith-nodejs 1.1.0 → 2.0.0-beta.2
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/.github/workflows/pull_request.yaml +33 -0
- package/.gitmodules +3 -0
- package/.husky/pre-commit +6 -0
- package/{LICENCE.md → LICENCE} +4 -5
- package/README.md +1 -1
- package/build/flagsmith-engine/environments/integrations/models.d.ts +4 -0
- package/build/flagsmith-engine/environments/integrations/models.js +8 -0
- package/build/flagsmith-engine/environments/models.d.ts +25 -0
- package/build/flagsmith-engine/environments/models.js +40 -0
- package/build/flagsmith-engine/environments/util.d.ts +3 -0
- package/build/flagsmith-engine/environments/util.js +19 -0
- package/build/flagsmith-engine/features/constants.d.ts +4 -0
- package/build/flagsmith-engine/features/constants.js +7 -0
- package/build/flagsmith-engine/features/models.d.ts +32 -0
- package/build/flagsmith-engine/features/models.js +85 -0
- package/build/flagsmith-engine/features/util.d.ts +3 -0
- package/build/flagsmith-engine/features/util.js +20 -0
- package/build/flagsmith-engine/identities/models.d.ts +15 -0
- package/build/flagsmith-engine/identities/models.js +47 -0
- package/build/flagsmith-engine/identities/traits/models.d.ts +5 -0
- package/build/flagsmith-engine/identities/traits/models.js +12 -0
- package/build/flagsmith-engine/identities/util.d.ts +4 -0
- package/build/flagsmith-engine/identities/util.js +22 -0
- package/build/flagsmith-engine/index.d.ts +8 -0
- package/build/flagsmith-engine/index.js +61 -0
- package/build/flagsmith-engine/organisations/models.d.ts +9 -0
- package/build/flagsmith-engine/organisations/models.js +21 -0
- package/build/flagsmith-engine/organisations/util.d.ts +2 -0
- package/build/flagsmith-engine/organisations/util.js +8 -0
- package/build/flagsmith-engine/projects/models.d.ts +10 -0
- package/build/flagsmith-engine/projects/models.js +17 -0
- package/build/flagsmith-engine/projects/util.d.ts +2 -0
- package/build/flagsmith-engine/projects/util.js +15 -0
- package/build/flagsmith-engine/segments/constants.d.ts +26 -0
- package/build/flagsmith-engine/segments/constants.js +31 -0
- package/build/flagsmith-engine/segments/evaluators.d.ts +6 -0
- package/build/flagsmith-engine/segments/evaluators.js +29 -0
- package/build/flagsmith-engine/segments/models.d.ts +31 -0
- package/build/flagsmith-engine/segments/models.js +83 -0
- package/build/flagsmith-engine/segments/util.d.ts +4 -0
- package/build/flagsmith-engine/segments/util.js +23 -0
- package/build/flagsmith-engine/utils/collections.d.ts +4 -0
- package/build/flagsmith-engine/utils/collections.js +16 -0
- package/build/flagsmith-engine/utils/errors.d.ts +2 -0
- package/build/flagsmith-engine/utils/errors.js +6 -0
- package/build/flagsmith-engine/utils/hashing/index.d.ts +9 -0
- package/build/flagsmith-engine/utils/hashing/index.js +54 -0
- package/build/flagsmith-engine/utils/index.d.ts +1 -0
- package/build/flagsmith-engine/utils/index.js +14 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +11 -0
- package/build/sdk/analytics.d.ts +28 -0
- package/build/sdk/analytics.js +60 -0
- package/build/sdk/errors.d.ts +4 -0
- package/build/sdk/errors.js +9 -0
- package/build/sdk/index.d.ts +98 -0
- package/build/sdk/index.js +215 -0
- package/build/sdk/models.d.ts +55 -0
- package/build/sdk/models.js +102 -0
- package/build/sdk/polling_manager.d.ts +9 -0
- package/build/sdk/polling_manager.js +31 -0
- package/build/sdk/utils.d.ts +12 -0
- package/build/sdk/utils.js +45 -0
- package/example/README.md +0 -6
- package/example/package-lock.json +1070 -2
- package/example/package.json +4 -3
- package/example/server/api/index.js +18 -18
- package/example/server/index.js +4 -6
- package/flagsmith-engine/environments/integrations/models.ts +4 -0
- package/flagsmith-engine/environments/models.ts +50 -0
- package/flagsmith-engine/environments/util.ts +29 -0
- package/flagsmith-engine/features/constants.ts +4 -0
- package/flagsmith-engine/features/models.ts +105 -0
- package/flagsmith-engine/features/util.ts +38 -0
- package/flagsmith-engine/identities/models.ts +60 -0
- package/flagsmith-engine/identities/traits/models.ts +9 -0
- package/flagsmith-engine/identities/util.ts +30 -0
- package/flagsmith-engine/index.ts +93 -0
- package/flagsmith-engine/organisations/models.ts +25 -0
- package/flagsmith-engine/organisations/util.ts +11 -0
- package/flagsmith-engine/projects/models.ts +22 -0
- package/flagsmith-engine/projects/util.ts +18 -0
- package/flagsmith-engine/segments/constants.ts +31 -0
- package/flagsmith-engine/segments/evaluators.ts +72 -0
- package/flagsmith-engine/segments/models.ts +103 -0
- package/flagsmith-engine/segments/util.ts +29 -0
- package/flagsmith-engine/utils/collections.ts +14 -0
- package/flagsmith-engine/utils/errors.ts +1 -0
- package/flagsmith-engine/utils/hashing/index.ts +52 -0
- package/flagsmith-engine/utils/index.ts +10 -0
- package/index.ts +6 -0
- package/jest.config.js +5 -0
- package/package.json +28 -12
- package/sdk/analytics.ts +60 -0
- package/sdk/errors.ts +2 -0
- package/sdk/index.ts +270 -0
- package/sdk/models.ts +145 -0
- package/sdk/polling_manager.ts +31 -0
- package/sdk/utils.ts +45 -0
- package/tests/engine/e2e/engine.test.ts +51 -0
- package/tests/engine/engine-tests/engine-test-data/data/environment_n9fbf9h3v4fFgH3U3ngWhb.json +12393 -0
- package/tests/engine/engine-tests/engine-test-data/readme.md +30 -0
- package/tests/engine/unit/egine.test.ts +96 -0
- package/tests/engine/unit/environments/builder.test.ts +148 -0
- package/tests/engine/unit/environments/models.test.ts +49 -0
- package/tests/engine/unit/features/models.test.ts +72 -0
- package/tests/engine/unit/identities/identities_builders.test.ts +85 -0
- package/tests/engine/unit/identities/identities_models.test.ts +105 -0
- package/tests/engine/unit/organization/models.test.ts +12 -0
- package/tests/engine/unit/segments/segments_model.test.ts +101 -0
- package/tests/engine/unit/segments/util.ts +151 -0
- package/tests/engine/unit/utils.ts +114 -0
- package/tests/index.js +0 -0
- package/tests/sdk/analytics.test.ts +43 -0
- package/tests/sdk/data/environment.json +33 -0
- package/tests/sdk/data/flags.json +20 -0
- package/tests/sdk/data/identities.json +29 -0
- package/tests/sdk/flagsmith.test.ts +184 -0
- package/tests/sdk/polling.test.ts +34 -0
- package/tests/sdk/utils.ts +39 -0
- package/tsconfig.json +19 -0
- package/.idea/codeStyles/Project.xml +0 -52
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/flagsmith-core.js +0 -241
- package/index.d.ts +0 -85
- package/index.js +0 -3
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Flagsmith from '../../sdk';
|
|
2
|
+
import { EnvironmentDataPollingManager } from '../../sdk/polling_manager';
|
|
3
|
+
import { delay } from '../../sdk/utils';
|
|
4
|
+
jest.mock('../../sdk');
|
|
5
|
+
jest.mock('node-fetch');
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
Flagsmith.mockClear();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('test_polling_manager_calls_update_environment_on_start', async () => {
|
|
13
|
+
const flagsmith = new Flagsmith({
|
|
14
|
+
environmentKey: 'key'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const pollingManager = new EnvironmentDataPollingManager(flagsmith, 0.1);
|
|
18
|
+
pollingManager.start();
|
|
19
|
+
await delay(500);
|
|
20
|
+
pollingManager.stop();
|
|
21
|
+
expect(flagsmith.updateEnvironment).toHaveBeenCalled();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('test_polling_manager_calls_update_environment_on_each_refresh', async () => {
|
|
25
|
+
const flagsmith = new Flagsmith({
|
|
26
|
+
environmentKey: 'key'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const pollingManager = new EnvironmentDataPollingManager(flagsmith, 0.1);
|
|
30
|
+
pollingManager.start();
|
|
31
|
+
await delay(450);
|
|
32
|
+
pollingManager.stop();
|
|
33
|
+
expect(flagsmith.updateEnvironment).toHaveBeenCalledTimes(5);
|
|
34
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { buildEnvironmentModel } from '../../flagsmith-engine/environments/util';
|
|
3
|
+
import { AnalyticsProcessor } from '../../sdk/analytics';
|
|
4
|
+
import Flagsmith from '../../sdk';
|
|
5
|
+
|
|
6
|
+
const DATA_DIR = __dirname + '/data/';
|
|
7
|
+
|
|
8
|
+
export function analyticsProcessor() {
|
|
9
|
+
return new AnalyticsProcessor({
|
|
10
|
+
environmentKey: 'test-key',
|
|
11
|
+
baseApiUrl: 'http://testUrl'
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function apiKey(): string {
|
|
16
|
+
return 'sometestfakekey';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function flagsmith() {
|
|
20
|
+
return new Flagsmith({
|
|
21
|
+
environmentKey: apiKey()
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function environmentJSON() {
|
|
26
|
+
return readFileSync(DATA_DIR + 'environment.json', 'utf-8');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function environmentModel(environmentJSON: any) {
|
|
30
|
+
return buildEnvironmentModel(environmentJSON);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function flagsJSON() {
|
|
34
|
+
return readFileSync(DATA_DIR + 'flags.json', 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function identitiesJSON() {
|
|
38
|
+
return readFileSync(DATA_DIR + 'identities.json', 'utf-8');
|
|
39
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"./flagsmith-engine",
|
|
4
|
+
"./sdk",
|
|
5
|
+
"./index.ts"
|
|
6
|
+
],
|
|
7
|
+
"compilerOptions": {
|
|
8
|
+
"outDir": "./build",
|
|
9
|
+
"target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
10
|
+
/* Modules */
|
|
11
|
+
"module": "commonjs", /* Specify what module code is generated. */
|
|
12
|
+
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
|
|
13
|
+
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"strict": true, /* Enable all strict type-checking options. */
|
|
16
|
+
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
|
17
|
+
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
-
<code_scheme name="Project" version="173">
|
|
3
|
-
<HTMLCodeStyleSettings>
|
|
4
|
-
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
|
5
|
-
<option name="HTML_KEEP_WHITESPACES_INSIDE" value="pre,textarea" />
|
|
6
|
-
<option name="HTML_QUOTE_STYLE" value="Single" />
|
|
7
|
-
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
|
8
|
-
<option name="HTML_NEWLINE_AFTER_LAST_ATTRIBUTE" value="When multiline" />
|
|
9
|
-
</HTMLCodeStyleSettings>
|
|
10
|
-
<JSCodeStyleSettings version="0">
|
|
11
|
-
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
12
|
-
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
13
|
-
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
14
|
-
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
15
|
-
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
16
|
-
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
17
|
-
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
18
|
-
</JSCodeStyleSettings>
|
|
19
|
-
<TypeScriptCodeStyleSettings version="0">
|
|
20
|
-
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
21
|
-
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
22
|
-
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
23
|
-
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
24
|
-
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
25
|
-
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
26
|
-
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
27
|
-
</TypeScriptCodeStyleSettings>
|
|
28
|
-
<VueCodeStyleSettings>
|
|
29
|
-
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
|
30
|
-
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
|
31
|
-
</VueCodeStyleSettings>
|
|
32
|
-
<codeStyleSettings language="HTML">
|
|
33
|
-
<option name="SOFT_MARGINS" value="100" />
|
|
34
|
-
<indentOptions>
|
|
35
|
-
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
|
36
|
-
</indentOptions>
|
|
37
|
-
</codeStyleSettings>
|
|
38
|
-
<codeStyleSettings language="JavaScript">
|
|
39
|
-
<option name="SOFT_MARGINS" value="100" />
|
|
40
|
-
</codeStyleSettings>
|
|
41
|
-
<codeStyleSettings language="TypeScript">
|
|
42
|
-
<option name="SOFT_MARGINS" value="100" />
|
|
43
|
-
</codeStyleSettings>
|
|
44
|
-
<codeStyleSettings language="Vue">
|
|
45
|
-
<option name="SOFT_MARGINS" value="100" />
|
|
46
|
-
<indentOptions>
|
|
47
|
-
<option name="INDENT_SIZE" value="4" />
|
|
48
|
-
<option name="TAB_SIZE" value="4" />
|
|
49
|
-
</indentOptions>
|
|
50
|
-
</codeStyleSettings>
|
|
51
|
-
</code_scheme>
|
|
52
|
-
</component>
|
package/flagsmith-core.js
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
const fetch = require('node-fetch');
|
|
2
|
-
|
|
3
|
-
module.exports = class FlagsmithCore {
|
|
4
|
-
normalizeFlags(flags) {
|
|
5
|
-
const _flags = {};
|
|
6
|
-
|
|
7
|
-
for (const { feature, enabled, feature_state_value } of flags) {
|
|
8
|
-
const normalizedKey = feature.name.toLowerCase().replace(/ /g, '_');
|
|
9
|
-
_flags[normalizedKey] = {
|
|
10
|
-
enabled,
|
|
11
|
-
value: feature_state_value
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return _flags;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
normalizeTraits(traits) {
|
|
19
|
-
const _traits = {};
|
|
20
|
-
|
|
21
|
-
for (const { trait_key, trait_value } of traits) {
|
|
22
|
-
const normalizedKey = trait_key.toLowerCase().replace(/ /g, '_');
|
|
23
|
-
_traits[normalizedKey] = trait_value;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return _traits;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async getJSON(url, method, body) {
|
|
30
|
-
const { environmentID } = this;
|
|
31
|
-
const options = {
|
|
32
|
-
method: method || 'GET',
|
|
33
|
-
body,
|
|
34
|
-
headers: {
|
|
35
|
-
'x-environment-key': environmentID
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
if (method !== 'GET') {
|
|
40
|
-
options.headers['Content-Type'] = 'application/json; charset=utf-8';
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const res = await fetch(url, options);
|
|
44
|
-
const result = await res.json();
|
|
45
|
-
|
|
46
|
-
if (res.status >= 400) {
|
|
47
|
-
throw new Error(result.detail);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
init({ environmentID, api, onError, cache }) {
|
|
54
|
-
if (!environmentID) {
|
|
55
|
-
throw new Error('Please specify a environment id');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
this.environmentID = environmentID;
|
|
59
|
-
|
|
60
|
-
this.api = api || 'https://api.flagsmith.com/api/v1';
|
|
61
|
-
this.onError = onError;
|
|
62
|
-
|
|
63
|
-
if (cache) {
|
|
64
|
-
const missingMethods = [];
|
|
65
|
-
|
|
66
|
-
['has', 'get', 'set'].forEach(method => {
|
|
67
|
-
if (!cache[method]) missingMethods.push(method);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
if (missingMethods.length > 0) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
`Please implement the following methods in your cache: ${missingMethods.join(
|
|
73
|
-
', '
|
|
74
|
-
)}`
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
this.cache = cache;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async getFlags() {
|
|
83
|
-
if (this.cache && (await this.cache.has('flags'))) {
|
|
84
|
-
return this.cache.get('flags');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const { onError, api } = this;
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const flags = await this.getJSON(`${api}/flags/`);
|
|
91
|
-
const normalizedFlags = this.normalizeFlags(flags);
|
|
92
|
-
|
|
93
|
-
if (this.cache) await this.cache.set('flags', normalizedFlags);
|
|
94
|
-
|
|
95
|
-
return normalizedFlags;
|
|
96
|
-
} catch (err) {
|
|
97
|
-
onError && onError({ message: err.message });
|
|
98
|
-
throw err;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
async getFlagsForUser(identity) {
|
|
103
|
-
const cacheKey = `flags-${identity}`;
|
|
104
|
-
|
|
105
|
-
if (this.cache && (await this.cache.has(cacheKey))) {
|
|
106
|
-
return this.cache.get(cacheKey);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const { onError, api } = this;
|
|
110
|
-
|
|
111
|
-
if (!identity) {
|
|
112
|
-
const errMsg = 'getFlagsForUser() called without a user identity';
|
|
113
|
-
onError && onError({ message: errMsg });
|
|
114
|
-
throw new Error(errMsg);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
const { flags } = await this.getJSON(`${api}/identities/?identifier=${identity}`);
|
|
119
|
-
const normalizedFlags = this.normalizeFlags(flags);
|
|
120
|
-
|
|
121
|
-
if (this.cache) await this.cache.set(cacheKey, normalizedFlags);
|
|
122
|
-
|
|
123
|
-
return normalizedFlags;
|
|
124
|
-
} catch (err) {
|
|
125
|
-
onError && onError({ message: err.message });
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async getUserIdentity(identity) {
|
|
131
|
-
const cacheKey = `flags_traits-${identity}`;
|
|
132
|
-
|
|
133
|
-
if (this.cache && (await this.cache.has(cacheKey))) {
|
|
134
|
-
return this.cache.get(cacheKey);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const { onError, api } = this;
|
|
138
|
-
|
|
139
|
-
if (!identity) {
|
|
140
|
-
const errMsg = 'getUserIdentity() called without a user identity';
|
|
141
|
-
onError && onError({ message: errMsg });
|
|
142
|
-
throw new Error(errMsg);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
const { flags, traits } = await this.getJSON(
|
|
147
|
-
`${api}/identities/?identifier=${identity}`
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
const normalizedFlags = this.normalizeFlags(flags);
|
|
151
|
-
const normalizedTraits = this.normalizeTraits(traits);
|
|
152
|
-
const res = { flags: normalizedFlags, traits: normalizedTraits };
|
|
153
|
-
|
|
154
|
-
if (this.cache) await this.cache.set(cacheKey, res);
|
|
155
|
-
|
|
156
|
-
return res;
|
|
157
|
-
} catch (err) {
|
|
158
|
-
onError && onError({ message: err.message });
|
|
159
|
-
throw err;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async getValue(key, userId) {
|
|
164
|
-
const flags = userId ? await this.getFlagsForUser(userId) : await this.getFlags();
|
|
165
|
-
|
|
166
|
-
return this.getValueFromFeatures(key, flags);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async hasFeature(key, userId) {
|
|
170
|
-
const flags = userId ? await this.getFlagsForUser(userId) : await this.getFlags();
|
|
171
|
-
|
|
172
|
-
return this.checkFeatureEnabled(key, flags);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
getValueFromFeatures(key, flags) {
|
|
176
|
-
if (!flags) return null;
|
|
177
|
-
|
|
178
|
-
const flag = flags[key];
|
|
179
|
-
|
|
180
|
-
//todo record check for value
|
|
181
|
-
return flag ? flag.value : null;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
checkFeatureEnabled(key, flags) {
|
|
185
|
-
if (!flags) return false;
|
|
186
|
-
|
|
187
|
-
const flag = flags[key];
|
|
188
|
-
return flag && flag.enabled;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async getTrait(identity, key) {
|
|
192
|
-
const { onError } = this;
|
|
193
|
-
|
|
194
|
-
if (!identity || !key) {
|
|
195
|
-
const errMsg = `getTrait() called without a ${
|
|
196
|
-
!identity ? 'user identity' : 'trait key'
|
|
197
|
-
}`;
|
|
198
|
-
onError && onError({ message: errMsg });
|
|
199
|
-
throw new Error(errMsg);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
try {
|
|
203
|
-
const { traits } = await this.getUserIdentity(identity);
|
|
204
|
-
return traits[key];
|
|
205
|
-
} catch (err) {
|
|
206
|
-
onError && onError({ message: err.message });
|
|
207
|
-
throw err;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async setTrait(identity, key, value) {
|
|
212
|
-
const { onError, api } = this;
|
|
213
|
-
|
|
214
|
-
if (!identity || !key) {
|
|
215
|
-
const errMsg = `setTrait() called without a ${
|
|
216
|
-
!identity ? 'user identity' : 'trait key'
|
|
217
|
-
}`;
|
|
218
|
-
onError &&
|
|
219
|
-
onError({
|
|
220
|
-
message: errMsg
|
|
221
|
-
});
|
|
222
|
-
throw new Error(errMsg);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const body = {
|
|
226
|
-
identity: {
|
|
227
|
-
identifier: identity
|
|
228
|
-
},
|
|
229
|
-
trait_key: key,
|
|
230
|
-
trait_value: value
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
try {
|
|
234
|
-
await this.getJSON(`${api}/traits/`, 'POST', JSON.stringify(body));
|
|
235
|
-
return await this.getUserIdentity(identity);
|
|
236
|
-
} catch (err) {
|
|
237
|
-
onError && onError({ message: err.message });
|
|
238
|
-
throw err;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
};
|
package/index.d.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
declare module 'flagsmith-nodejs' {
|
|
2
|
-
/**
|
|
3
|
-
* Initialise the sdk against a particular environment
|
|
4
|
-
*/
|
|
5
|
-
export function init(config: {
|
|
6
|
-
environmentID: string;
|
|
7
|
-
onError?: Function;
|
|
8
|
-
defaultFlags?: string[];
|
|
9
|
-
api?: string;
|
|
10
|
-
cache?: ICache;
|
|
11
|
-
}): void;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get the whether a flag is enabled e.g. flagsmith.hasFeature("powerUserFeature")
|
|
15
|
-
*/
|
|
16
|
-
export function hasFeature(key: string): Promise<boolean>;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Get the value of a whether a flag is enabled for a user e.g. flagsmith.hasFeature("powerUserFeature", 1234)
|
|
20
|
-
*/
|
|
21
|
-
export function hasFeature(key: string, userId: string): Promise<boolean>;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Get the value of a particular remote config e.g. flagsmith.getValue("font_size")
|
|
25
|
-
*/
|
|
26
|
-
export function getValue(key: string): Promise<string | number | boolean>;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Get the value of a particular remote config for a specified user e.g. flagsmith.getValue("font_size", 1234)
|
|
30
|
-
*/
|
|
31
|
-
export function getValue(key: string, userId: string): Promise<string | number | boolean>;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Trigger a manual fetch of the environment features
|
|
35
|
-
*/
|
|
36
|
-
export function getFlags(): Promise<IFlags>;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Trigger a manual fetch of the environment features for a given user id
|
|
40
|
-
*/
|
|
41
|
-
export function getFlagsForUser(userId: string): Promise<IFlags>;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Trigger a manual fetch of both the environment features and users' traits for a given user id
|
|
45
|
-
*/
|
|
46
|
-
export function getUserIdentity(userId: string): Promise<IUserIdentity>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Trigger a manual fetch of a specific trait for a given user id
|
|
50
|
-
*/
|
|
51
|
-
export function getTrait(userId: string, key: string): Promise<ITraits>;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Set a specific trait for a given user id
|
|
55
|
-
*/
|
|
56
|
-
export function setTrait(
|
|
57
|
-
userId: string,
|
|
58
|
-
key: string,
|
|
59
|
-
value: string | number | boolean
|
|
60
|
-
): IUserIdentity;
|
|
61
|
-
|
|
62
|
-
interface IFeature {
|
|
63
|
-
enabled: boolean;
|
|
64
|
-
value?: string | number | boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
interface IFlags {
|
|
68
|
-
[key: string]: IFeature;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface ITraits {
|
|
72
|
-
[key: string]: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
interface IUserIdentity {
|
|
76
|
-
flags: IFeature;
|
|
77
|
-
traits: ITraits;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
interface ICache {
|
|
81
|
-
has(key: string): boolean | Promise<boolean>;
|
|
82
|
-
get(key: string): any | Promise<any>;
|
|
83
|
-
set(key: string, val: any): void | Promise<void>;
|
|
84
|
-
}
|
|
85
|
-
}
|
package/index.js
DELETED