flagsmith-nodejs 6.0.1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.github/workflows/conventional-commit.yml +29 -0
  2. package/.github/workflows/pull_request.yaml +1 -1
  3. package/.github/workflows/release-please.yml +18 -0
  4. package/.gitmodules +1 -0
  5. package/.husky/pre-commit +0 -0
  6. package/.prettierignore +2 -1
  7. package/.prettierrc.cjs +9 -1
  8. package/.release-please-manifest.json +1 -0
  9. package/CHANGELOG.md +552 -0
  10. package/CODEOWNERS +1 -0
  11. package/README.md +2 -3
  12. package/build/cjs/flagsmith-engine/features/util.js +3 -3
  13. package/build/cjs/flagsmith-engine/index.d.ts +1 -1
  14. package/build/cjs/flagsmith-engine/index.js +2 -1
  15. package/build/cjs/flagsmith-engine/segments/models.js +7 -7
  16. package/build/cjs/flagsmith-engine/utils/hashing/index.js +1 -1
  17. package/build/cjs/index.d.ts +4 -4
  18. package/build/cjs/index.js +3 -1
  19. package/build/cjs/sdk/analytics.d.ts +1 -1
  20. package/build/cjs/sdk/analytics.js +3 -1
  21. package/build/cjs/sdk/index.d.ts +5 -5
  22. package/build/cjs/sdk/index.js +48 -10
  23. package/build/cjs/sdk/models.d.ts +25 -0
  24. package/build/cjs/sdk/models.js +25 -0
  25. package/build/cjs/sdk/types.d.ts +14 -4
  26. package/build/cjs/sdk/utils.d.ts +5 -4
  27. package/build/cjs/sdk/utils.js +16 -3
  28. package/build/esm/flagsmith-engine/features/models.js +1 -1
  29. package/build/esm/flagsmith-engine/features/util.js +3 -3
  30. package/build/esm/flagsmith-engine/index.d.ts +1 -1
  31. package/build/esm/flagsmith-engine/index.js +1 -1
  32. package/build/esm/flagsmith-engine/segments/models.js +7 -7
  33. package/build/esm/flagsmith-engine/utils/hashing/index.js +2 -2
  34. package/build/esm/flagsmith-engine/utils/index.js +1 -1
  35. package/build/esm/index.d.ts +4 -4
  36. package/build/esm/index.js +3 -3
  37. package/build/esm/sdk/analytics.d.ts +1 -1
  38. package/build/esm/sdk/analytics.js +3 -1
  39. package/build/esm/sdk/index.d.ts +5 -5
  40. package/build/esm/sdk/index.js +48 -11
  41. package/build/esm/sdk/models.d.ts +25 -0
  42. package/build/esm/sdk/models.js +25 -0
  43. package/build/esm/sdk/types.d.ts +14 -4
  44. package/build/esm/sdk/utils.d.ts +5 -4
  45. package/build/esm/sdk/utils.js +14 -2
  46. package/flagsmith-engine/environments/util.ts +2 -2
  47. package/flagsmith-engine/features/models.ts +1 -1
  48. package/flagsmith-engine/features/util.ts +14 -14
  49. package/flagsmith-engine/identities/models.ts +1 -1
  50. package/flagsmith-engine/index.ts +1 -1
  51. package/flagsmith-engine/segments/evaluators.ts +2 -3
  52. package/flagsmith-engine/segments/models.ts +25 -15
  53. package/flagsmith-engine/utils/hashing/index.ts +3 -3
  54. package/flagsmith-engine/utils/index.ts +4 -2
  55. package/index.ts +19 -22
  56. package/package.json +1 -1
  57. package/release-please-config.json +62 -0
  58. package/sdk/analytics.ts +10 -6
  59. package/sdk/index.ts +91 -28
  60. package/sdk/models.ts +25 -0
  61. package/sdk/offline_handlers.ts +1 -1
  62. package/sdk/types.ts +17 -8
  63. package/sdk/utils.ts +21 -8
  64. package/tests/engine/e2e/engine.test.ts +2 -4
  65. package/tests/engine/unit/engine.test.ts +1 -6
  66. package/tests/engine/unit/features/models.test.ts +2 -2
  67. package/tests/engine/unit/identities/identities_builders.test.ts +1 -1
  68. package/tests/engine/unit/segments/segment_evaluators.test.ts +52 -23
  69. package/tests/engine/unit/segments/segments_model.test.ts +35 -37
  70. package/tests/engine/unit/utils/utils.test.ts +28 -30
  71. package/tests/sdk/analytics.test.ts +30 -26
  72. package/tests/sdk/flagsmith-cache.test.ts +84 -76
  73. package/tests/sdk/flagsmith-environment-flags.test.ts +121 -93
  74. package/tests/sdk/flagsmith-identity-flags.test.ts +155 -149
  75. package/tests/sdk/flagsmith.test.ts +202 -43
  76. package/tests/sdk/offline-handlers.test.ts +32 -32
  77. package/tests/sdk/polling.test.ts +0 -1
  78. package/tests/sdk/utils.ts +26 -18
  79. package/vitest.config.ts +10 -15
@@ -1,154 +1,182 @@
1
1
  import Flagsmith from '../../sdk/index.js';
2
2
  import { environmentJSON, environmentModel, flagsJSON, flagsmith, fetch } from './utils.js';
3
3
  import { DefaultFlag } from '../../sdk/models.js';
4
+ import { getUserAgent } from '../../sdk/utils.js';
4
5
 
5
6
  vi.mock('../../sdk/polling_manager');
6
7
 
7
8
  test('test_get_environment_flags_calls_api_when_no_local_environment', async () => {
8
- const flg = flagsmith();
9
- const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
9
+ const flg = flagsmith();
10
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
10
11
 
11
- expect(fetch).toBeCalledTimes(1);
12
- expect(allFlags[0].enabled).toBe(true);
13
- expect(allFlags[0].value).toBe('some-value');
14
- expect(allFlags[0].featureName).toBe('some_feature');
12
+ expect(fetch).toBeCalledTimes(1);
13
+ expect(allFlags[0].enabled).toBe(true);
14
+ expect(allFlags[0].value).toBe('some-value');
15
+ expect(allFlags[0].featureName).toBe('some_feature');
15
16
  });
16
17
 
17
18
  test('test_default_flag_is_used_when_no_environment_flags_returned', async () => {
18
- fetch.mockResolvedValue(new Response(JSON.stringify([])));
19
+ fetch.mockResolvedValue(new Response(JSON.stringify([])));
19
20
 
20
- const defaultFlag = new DefaultFlag('some-default-value', true);
21
+ const defaultFlag = new DefaultFlag('some-default-value', true);
21
22
 
22
- const defaultFlagHandler = (featureName: string) => defaultFlag;
23
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
23
24
 
24
- const flg = new Flagsmith({
25
- environmentKey: 'key',
26
- defaultFlagHandler: defaultFlagHandler,
27
- customHeaders: {
28
- 'X-Test-Header': '1',
29
- }
30
- });
25
+ const flg = new Flagsmith({
26
+ environmentKey: 'key',
27
+ defaultFlagHandler: defaultFlagHandler,
28
+ customHeaders: {
29
+ 'X-Test-Header': '1'
30
+ }
31
+ });
31
32
 
32
- const flags = await flg.getEnvironmentFlags();
33
- const flag = flags.getFlag('some_feature');
34
- expect(flag.isDefault).toBe(true);
35
- expect(flag.enabled).toBe(defaultFlag.enabled);
36
- expect(flag.value).toBe(defaultFlag.value);
33
+ const flags = await flg.getEnvironmentFlags();
34
+ const flag = flags.getFlag('some_feature');
35
+ expect(flag.isDefault).toBe(true);
36
+ expect(flag.enabled).toBe(defaultFlag.enabled);
37
+ expect(flag.value).toBe(defaultFlag.value);
37
38
  });
38
39
 
39
40
  test('test_analytics_processor_tracks_flags', async () => {
40
- const defaultFlag = new DefaultFlag('some-default-value', true);
41
+ const defaultFlag = new DefaultFlag('some-default-value', true);
41
42
 
42
- const defaultFlagHandler = (featureName: string) => defaultFlag;
43
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
43
44
 
44
- const flg = flagsmith({
45
- environmentKey: 'key',
46
- defaultFlagHandler: defaultFlagHandler,
47
- enableAnalytics: true,
48
- });
45
+ const flg = flagsmith({
46
+ environmentKey: 'key',
47
+ defaultFlagHandler: defaultFlagHandler,
48
+ enableAnalytics: true
49
+ });
49
50
 
50
- const flags = await flg.getEnvironmentFlags();
51
- const flag = flags.getFlag('some_feature');
51
+ const flags = await flg.getEnvironmentFlags();
52
+ const flag = flags.getFlag('some_feature');
52
53
 
53
- expect(flag.isDefault).toBe(false);
54
- expect(flag.enabled).toBe(true);
55
- expect(flag.value).toBe('some-value');
54
+ expect(flag.isDefault).toBe(false);
55
+ expect(flag.enabled).toBe(true);
56
+ expect(flag.value).toBe('some-value');
56
57
  });
57
58
 
58
59
  test('test_getFeatureValue', async () => {
59
- const defaultFlag = new DefaultFlag('some-default-value', true);
60
+ const defaultFlag = new DefaultFlag('some-default-value', true);
60
61
 
61
- const defaultFlagHandler = (featureName: string) => defaultFlag;
62
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
62
63
 
63
- const flg = flagsmith({
64
- environmentKey: 'key',
65
- defaultFlagHandler: defaultFlagHandler,
66
- enableAnalytics: true,
67
- });
64
+ const flg = flagsmith({
65
+ environmentKey: 'key',
66
+ defaultFlagHandler: defaultFlagHandler,
67
+ enableAnalytics: true
68
+ });
68
69
 
69
- const flags = await flg.getEnvironmentFlags();
70
- const featureValue = flags.getFeatureValue('some_feature');
70
+ const flags = await flg.getEnvironmentFlags();
71
+ const featureValue = flags.getFeatureValue('some_feature');
71
72
 
72
- expect(featureValue).toBe('some-value');
73
+ expect(featureValue).toBe('some-value');
74
+ });
75
+
76
+ test('test_user_agent_is_set_when_fetching_environment_flags', async () => {
77
+ const defaultFlag = new DefaultFlag('some-default-value', true);
78
+
79
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
80
+
81
+ const flg = flagsmith({
82
+ environmentKey: 'key',
83
+ defaultFlagHandler: defaultFlagHandler,
84
+ enableAnalytics: true
85
+ });
86
+ const flags = await flg.getEnvironmentFlags();
87
+ const featureValue = flags.getFeatureValue('some_feature');
88
+
89
+ expect(featureValue).toBe('some-value');
90
+ expect(fetch).toHaveBeenCalledWith(
91
+ `https://edge.api.flagsmith.com/api/v1/flags/`,
92
+ expect.objectContaining({
93
+ method: 'GET',
94
+ headers: {
95
+ 'Content-Type': 'application/json',
96
+ 'X-Environment-Key': 'key',
97
+ 'User-Agent': getUserAgent()
98
+ }
99
+ })
100
+ );
73
101
  });
74
102
 
75
103
  test('test_throws_when_no_default_flag_handler_after_multiple_API_errors', async () => {
76
- fetch.mockRejectedValue('Error during fetching the API response');
104
+ fetch.mockRejectedValue('Error during fetching the API response');
77
105
 
78
- const flg = flagsmith({
79
- environmentKey: 'key',
80
- });
106
+ const flg = flagsmith({
107
+ environmentKey: 'key'
108
+ });
81
109
 
82
- await expect(async () => {
83
- const flags = await flg.getEnvironmentFlags();
84
- const flag = flags.getFlag('some_feature');
85
- }).rejects.toThrow('getEnvironmentFlags failed and no default flag handler was provided');
110
+ await expect(async () => {
111
+ const flags = await flg.getEnvironmentFlags();
112
+ const flag = flags.getFlag('some_feature');
113
+ }).rejects.toThrow('getEnvironmentFlags failed and no default flag handler was provided');
86
114
  });
87
115
 
88
116
  test('test_non_200_response_raises_flagsmith_api_error', async () => {
89
- const errorResponse403 = new Response('403 Forbidden', {
90
- status: 403
91
- });
92
- fetch.mockResolvedValue(errorResponse403);
117
+ const errorResponse403 = new Response('403 Forbidden', {
118
+ status: 403
119
+ });
120
+ fetch.mockResolvedValue(errorResponse403);
93
121
 
94
- const flg = new Flagsmith({
95
- environmentKey: 'some'
96
- });
122
+ const flg = new Flagsmith({
123
+ environmentKey: 'some'
124
+ });
97
125
 
98
- await expect(flg.getEnvironmentFlags()).rejects.toThrow();
126
+ await expect(flg.getEnvironmentFlags()).rejects.toThrow();
99
127
  });
100
128
  test('test_default_flag_is_not_used_when_environment_flags_returned', async () => {
101
- const defaultFlag = new DefaultFlag('some-default-value', true);
129
+ const defaultFlag = new DefaultFlag('some-default-value', true);
102
130
 
103
- const defaultFlagHandler = (featureName: string) => defaultFlag;
131
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
104
132
 
105
- const flg = flagsmith({
106
- environmentKey: 'key',
107
- defaultFlagHandler: defaultFlagHandler
108
- });
133
+ const flg = flagsmith({
134
+ environmentKey: 'key',
135
+ defaultFlagHandler: defaultFlagHandler
136
+ });
109
137
 
110
- const flags = await flg.getEnvironmentFlags();
111
- const flag = flags.getFlag('some_feature');
138
+ const flags = await flg.getEnvironmentFlags();
139
+ const flag = flags.getFlag('some_feature');
112
140
 
113
- expect(flag.isDefault).toBe(false);
114
- expect(flag.value).not.toBe(defaultFlag.value);
115
- expect(flag.value).toBe('some-value');
141
+ expect(flag.isDefault).toBe(false);
142
+ expect(flag.value).not.toBe(defaultFlag.value);
143
+ expect(flag.value).toBe('some-value');
116
144
  });
117
145
 
118
146
  test('test_default_flag_is_used_when_bad_api_response_happens', async () => {
119
- fetch.mockResolvedValue(new Response('bad-data'));
147
+ fetch.mockResolvedValue(new Response('bad-data'));
120
148
 
121
- const defaultFlag = new DefaultFlag('some-default-value', true);
149
+ const defaultFlag = new DefaultFlag('some-default-value', true);
122
150
 
123
- const defaultFlagHandler = (featureName: string) => defaultFlag;
151
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
124
152
 
125
- const flg = new Flagsmith({
126
- environmentKey: 'key',
127
- defaultFlagHandler: defaultFlagHandler
128
- });
153
+ const flg = new Flagsmith({
154
+ environmentKey: 'key',
155
+ defaultFlagHandler: defaultFlagHandler
156
+ });
129
157
 
130
- const flags = await flg.getEnvironmentFlags();
131
- const flag = flags.getFlag('some_feature');
158
+ const flags = await flg.getEnvironmentFlags();
159
+ const flag = flags.getFlag('some_feature');
132
160
 
133
- expect(flag.isDefault).toBe(true);
134
- expect(flag.value).toBe(defaultFlag.value);
161
+ expect(flag.isDefault).toBe(true);
162
+ expect(flag.value).toBe(defaultFlag.value);
135
163
  });
136
164
 
137
165
  test('test_local_evaluation', async () => {
138
- const defaultFlag = new DefaultFlag('some-default-value', true);
166
+ const defaultFlag = new DefaultFlag('some-default-value', true);
139
167
 
140
- const defaultFlagHandler = (featureName: string) => defaultFlag;
168
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
141
169
 
142
- const flg = flagsmith({
143
- environmentKey: 'ser.key',
144
- enableLocalEvaluation: true,
145
- defaultFlagHandler: defaultFlagHandler
146
- });
170
+ const flg = flagsmith({
171
+ environmentKey: 'ser.key',
172
+ enableLocalEvaluation: true,
173
+ defaultFlagHandler: defaultFlagHandler
174
+ });
147
175
 
148
- const flags = await flg.getEnvironmentFlags();
149
- const flag = flags.getFlag('some_feature');
176
+ const flags = await flg.getEnvironmentFlags();
177
+ const flag = flags.getFlag('some_feature');
150
178
 
151
- expect(flag.isDefault).toBe(false);
152
- expect(flag.value).not.toBe(defaultFlag.value);
153
- expect(flag.value).toBe('some-value');
179
+ expect(flag.isDefault).toBe(false);
180
+ expect(flag.value).not.toBe(defaultFlag.value);
181
+ expect(flag.value).toBe('some-value');
154
182
  });
@@ -1,213 +1,219 @@
1
1
  import Flagsmith from '../../sdk/index.js';
2
2
  import {
3
- fetch,
4
- environmentJSON,
5
- flagsmith,
6
- identitiesJSON,
7
- identityWithTransientTraitsJSON,
8
- transientIdentityJSON,
9
- badFetch
3
+ fetch,
4
+ environmentJSON,
5
+ flagsmith,
6
+ identitiesJSON,
7
+ identityWithTransientTraitsJSON,
8
+ transientIdentityJSON,
9
+ badFetch
10
10
  } from './utils.js';
11
11
  import { DefaultFlag } from '../../sdk/models.js';
12
+ import { getUserAgent } from '../../sdk/utils.js';
12
13
 
13
14
  vi.mock('../../sdk/polling_manager');
14
15
 
15
16
  test('test_get_identity_flags_calls_api_when_no_local_environment_no_traits', async () => {
16
- const identifier = 'identifier';
17
+ const identifier = 'identifier';
17
18
 
18
- const flg = flagsmith();
19
+ const flg = flagsmith();
19
20
 
20
- const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
21
+ const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
21
22
 
22
- expect(identityFlags[0].enabled).toBe(true);
23
- expect(identityFlags[0].value).toBe('some-value');
24
- expect(identityFlags[0].featureName).toBe('some_feature');
23
+ expect(identityFlags[0].enabled).toBe(true);
24
+ expect(identityFlags[0].value).toBe('some-value');
25
+ expect(identityFlags[0].featureName).toBe('some_feature');
25
26
  });
26
27
 
27
28
  test('test_get_identity_flags_uses_environment_when_local_environment_no_traits', async () => {
28
- const identifier = 'identifier';
29
+ const identifier = 'identifier';
29
30
 
30
- const flg = flagsmith({
31
- environmentKey: 'ser.key',
32
- enableLocalEvaluation: true,
33
- });
31
+ const flg = flagsmith({
32
+ environmentKey: 'ser.key',
33
+ enableLocalEvaluation: true
34
+ });
34
35
 
36
+ const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
35
37
 
36
- const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
37
-
38
- expect(identityFlags[0].enabled).toBe(true);
39
- expect(identityFlags[0].value).toBe('some-value');
40
- expect(identityFlags[0].featureName).toBe('some_feature');
38
+ expect(identityFlags[0].enabled).toBe(true);
39
+ expect(identityFlags[0].value).toBe('some-value');
40
+ expect(identityFlags[0].featureName).toBe('some_feature');
41
41
  });
42
42
 
43
43
  test('test_get_identity_flags_calls_api_when_no_local_environment_with_traits', async () => {
44
- const identifier = 'identifier';
45
- const traits = { some_trait: 'some_value' };
46
- const flg = flagsmith();
44
+ const identifier = 'identifier';
45
+ const traits = { some_trait: 'some_value' };
46
+ const flg = flagsmith();
47
47
 
48
- const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
48
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
49
49
 
50
- expect(identityFlags[0].enabled).toBe(true);
51
- expect(identityFlags[0].value).toBe('some-value');
52
- expect(identityFlags[0].featureName).toBe('some_feature');
50
+ expect(identityFlags[0].enabled).toBe(true);
51
+ expect(identityFlags[0].value).toBe('some-value');
52
+ expect(identityFlags[0].featureName).toBe('some_feature');
53
53
  });
54
54
 
55
55
  test('test_default_flag_is_not_used_when_identity_flags_returned', async () => {
56
- const defaultFlag = new DefaultFlag('some-default-value', true);
56
+ const defaultFlag = new DefaultFlag('some-default-value', true);
57
57
 
58
- const defaultFlagHandler = (featureName: string) => defaultFlag;
58
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
59
59
 
60
- const flg = flagsmith({
61
- environmentKey: 'key',
62
- defaultFlagHandler: defaultFlagHandler
63
- });
60
+ const flg = flagsmith({
61
+ environmentKey: 'key',
62
+ defaultFlagHandler: defaultFlagHandler
63
+ });
64
64
 
65
- const flags = await flg.getIdentityFlags('identifier');
66
- const flag = flags.getFlag('some_feature');
65
+ const flags = await flg.getIdentityFlags('identifier');
66
+ const flag = flags.getFlag('some_feature');
67
67
 
68
- expect(flag.isDefault).toBe(false);
69
- expect(flag.value).not.toBe(defaultFlag.value);
70
- expect(flag.value).toBe('some-value');
68
+ expect(flag.isDefault).toBe(false);
69
+ expect(flag.value).not.toBe(defaultFlag.value);
70
+ expect(flag.value).toBe('some-value');
71
71
  });
72
72
 
73
73
  test('test_default_flag_is_used_when_no_identity_flags_returned', async () => {
74
- fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })));
74
+ fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })));
75
75
 
76
- const defaultFlag = new DefaultFlag('some-default-value', true);
77
- const defaultFlagHandler = (featureName: string) => defaultFlag;
76
+ const defaultFlag = new DefaultFlag('some-default-value', true);
77
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
78
78
 
79
- const flg = new Flagsmith({
80
- environmentKey: 'key',
81
- defaultFlagHandler: defaultFlagHandler
82
- });
79
+ const flg = new Flagsmith({
80
+ environmentKey: 'key',
81
+ defaultFlagHandler: defaultFlagHandler
82
+ });
83
83
 
84
- const flags = await flg.getIdentityFlags('identifier');
85
- const flag = flags.getFlag('some_feature');
84
+ const flags = await flg.getIdentityFlags('identifier');
85
+ const flag = flags.getFlag('some_feature');
86
86
 
87
- expect(flag.isDefault).toBe(true);
88
- expect(flag.value).toBe(defaultFlag.value);
89
- expect(flag.enabled).toBe(defaultFlag.enabled);
87
+ expect(flag.isDefault).toBe(true);
88
+ expect(flag.value).toBe(defaultFlag.value);
89
+ expect(flag.enabled).toBe(defaultFlag.enabled);
90
90
  });
91
91
 
92
92
  test('test_default_flag_is_used_when_no_identity_flags_returned_due_to_error', async () => {
93
- fetch.mockResolvedValue(new Response('bad data'))
93
+ fetch.mockResolvedValue(new Response('bad data'));
94
94
 
95
- const defaultFlag = new DefaultFlag('some-default-value', true);
96
- const defaultFlagHandler = (featureName: string) => defaultFlag;
95
+ const defaultFlag = new DefaultFlag('some-default-value', true);
96
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
97
97
 
98
- const flg = new Flagsmith({
99
- environmentKey: 'key',
100
- defaultFlagHandler: defaultFlagHandler
101
- });
98
+ const flg = new Flagsmith({
99
+ environmentKey: 'key',
100
+ defaultFlagHandler: defaultFlagHandler
101
+ });
102
102
 
103
- const flags = await flg.getIdentityFlags('identifier');
104
- const flag = flags.getFlag('some_feature');
103
+ const flags = await flg.getIdentityFlags('identifier');
104
+ const flag = flags.getFlag('some_feature');
105
105
 
106
- expect(flag.isDefault).toBe(true);
107
- expect(flag.value).toBe(defaultFlag.value);
108
- expect(flag.enabled).toBe(defaultFlag.enabled);
106
+ expect(flag.isDefault).toBe(true);
107
+ expect(flag.value).toBe(defaultFlag.value);
108
+ expect(flag.enabled).toBe(defaultFlag.enabled);
109
109
  });
110
110
 
111
111
  test('test_default_flag_is_used_when_no_identity_flags_returned_and_no_custom_default_flag_handler', async () => {
112
- fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })))
112
+ fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })));
113
113
 
114
- const flg = flagsmith({
115
- environmentKey: 'key',
116
- });
114
+ const flg = flagsmith({
115
+ environmentKey: 'key'
116
+ });
117
117
 
118
- const flags = await flg.getIdentityFlags('identifier');
119
- const flag = flags.getFlag('some_feature');
118
+ const flags = await flg.getIdentityFlags('identifier');
119
+ const flag = flags.getFlag('some_feature');
120
120
 
121
- expect(flag.isDefault).toBe(true);
122
- expect(flag.value).toBe(undefined);
123
- expect(flag.enabled).toBe(false);
121
+ expect(flag.isDefault).toBe(true);
122
+ expect(flag.value).toBe(undefined);
123
+ expect(flag.enabled).toBe(false);
124
124
  });
125
125
 
126
126
  test('test_get_identity_flags_multivariate_value_with_local_evaluation_enabled', async () => {
127
- fetch.mockResolvedValue(new Response(environmentJSON));
128
- const identifier = 'identifier';
127
+ fetch.mockResolvedValue(new Response(environmentJSON));
128
+ const identifier = 'identifier';
129
129
 
130
- const flg = flagsmith({
131
- environmentKey: 'ser.key',
132
- enableLocalEvaluation: true,
133
- });
130
+ const flg = flagsmith({
131
+ environmentKey: 'ser.key',
132
+ enableLocalEvaluation: true
133
+ });
134
134
 
135
- const identityFlags = (await flg.getIdentityFlags(identifier))
135
+ const identityFlags = await flg.getIdentityFlags(identifier);
136
136
 
137
- expect(identityFlags.getFeatureValue('mv_feature')).toBe('bar');
138
- expect(identityFlags.isFeatureEnabled('mv_feature')).toBe(false);
137
+ expect(identityFlags.getFeatureValue('mv_feature')).toBe('bar');
138
+ expect(identityFlags.isFeatureEnabled('mv_feature')).toBe(false);
139
139
  });
140
140
 
141
-
142
141
  test('test_transient_identity', async () => {
143
- fetch.mockResolvedValue(new Response(transientIdentityJSON));
144
- const identifier = 'transient_identifier';
145
- const traits = { some_trait: 'some_value' };
146
- const traitsInRequest = [{trait_key:Object.keys(traits)[0],trait_value:traits.some_trait}]
147
- const transient = true;
148
- const flg = flagsmith();
149
- const identityFlags = (await flg.getIdentityFlags(identifier, traits, transient)).allFlags();
150
-
151
- expect(fetch).toHaveBeenCalledWith(
152
- `https://edge.api.flagsmith.com/api/v1/identities/`,
153
- expect.objectContaining({
154
- method: 'POST',
155
- headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'sometestfakekey' },
156
- body: JSON.stringify({identifier, traits: traitsInRequest, transient })
157
- }
158
- ));
159
-
160
- expect(identityFlags[0].enabled).toBe(false);
161
- expect(identityFlags[0].value).toBe('some-transient-identity-value');
162
- expect(identityFlags[0].featureName).toBe('some_feature');
142
+ fetch.mockResolvedValue(new Response(transientIdentityJSON));
143
+ const identifier = 'transient_identifier';
144
+ const traits = { some_trait: 'some_value' };
145
+ const traitsInRequest = [{ trait_key: Object.keys(traits)[0], trait_value: traits.some_trait }];
146
+ const transient = true;
147
+ const flg = flagsmith();
148
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits, transient)).allFlags();
149
+
150
+ expect(fetch).toHaveBeenCalledWith(
151
+ `https://edge.api.flagsmith.com/api/v1/identities/`,
152
+ expect.objectContaining({
153
+ method: 'POST',
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ 'X-Environment-Key': 'sometestfakekey',
157
+ 'User-Agent': getUserAgent()
158
+ },
159
+ body: JSON.stringify({ identifier, traits: traitsInRequest, transient })
160
+ })
161
+ );
162
+
163
+ expect(identityFlags[0].enabled).toBe(false);
164
+ expect(identityFlags[0].value).toBe('some-transient-identity-value');
165
+ expect(identityFlags[0].featureName).toBe('some_feature');
163
166
  });
164
167
 
165
-
166
168
  test('test_identity_with_transient_traits', async () => {
167
- fetch.mockResolvedValue(new Response(identityWithTransientTraitsJSON));
168
- const identifier = 'transient_trait_identifier';
169
- const traits = {
170
- some_trait: 'some_value',
171
- another_trait: {value: 'another_value', transient: true},
172
- explicitly_non_transient_trait: {value: 'non_transient_value', transient: false}
173
- }
174
- const traitsInRequest = [
175
- {
176
- trait_key:Object.keys(traits)[0],
177
- trait_value:traits.some_trait,
178
- },
179
- {
180
- trait_key:Object.keys(traits)[1],
181
- trait_value:traits.another_trait.value,
182
- transient: true,
183
- },
184
- {
185
- trait_key:Object.keys(traits)[2],
186
- trait_value:traits.explicitly_non_transient_trait.value,
187
- transient: false,
188
- },
189
- ]
190
- const flg = flagsmith();
191
-
192
- const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
193
- expect(fetch).toHaveBeenCalledWith(
194
- `https://edge.api.flagsmith.com/api/v1/identities/`,
195
- expect.objectContaining({
196
- method: 'POST',
197
- headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'sometestfakekey' },
198
- body: JSON.stringify({identifier, traits: traitsInRequest})
199
- })
200
- );
201
- expect(identityFlags[0].enabled).toBe(true);
202
- expect(identityFlags[0].value).toBe('some-identity-with-transient-trait-value');
203
- expect(identityFlags[0].featureName).toBe('some_feature');
169
+ fetch.mockResolvedValue(new Response(identityWithTransientTraitsJSON));
170
+ const identifier = 'transient_trait_identifier';
171
+ const traits = {
172
+ some_trait: 'some_value',
173
+ another_trait: { value: 'another_value', transient: true },
174
+ explicitly_non_transient_trait: { value: 'non_transient_value', transient: false }
175
+ };
176
+ const traitsInRequest = [
177
+ {
178
+ trait_key: Object.keys(traits)[0],
179
+ trait_value: traits.some_trait
180
+ },
181
+ {
182
+ trait_key: Object.keys(traits)[1],
183
+ trait_value: traits.another_trait.value,
184
+ transient: true
185
+ },
186
+ {
187
+ trait_key: Object.keys(traits)[2],
188
+ trait_value: traits.explicitly_non_transient_trait.value,
189
+ transient: false
190
+ }
191
+ ];
192
+ const flg = flagsmith();
193
+
194
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
195
+ expect(fetch).toHaveBeenCalledWith(
196
+ `https://edge.api.flagsmith.com/api/v1/identities/`,
197
+ expect.objectContaining({
198
+ method: 'POST',
199
+ headers: {
200
+ 'Content-Type': 'application/json',
201
+ 'X-Environment-Key': 'sometestfakekey',
202
+ 'User-Agent': getUserAgent()
203
+ },
204
+ body: JSON.stringify({ identifier, traits: traitsInRequest })
205
+ })
206
+ );
207
+ expect(identityFlags[0].enabled).toBe(true);
208
+ expect(identityFlags[0].value).toBe('some-identity-with-transient-trait-value');
209
+ expect(identityFlags[0].featureName).toBe('some_feature');
204
210
  });
205
211
 
206
212
  test('getIdentityFlags fails if API call failed and no default flag handler was provided', async () => {
207
- const flg = flagsmith({
208
- fetch: badFetch,
209
- })
210
- await expect(flg.getIdentityFlags('user'))
211
- .rejects
212
- .toThrow('getIdentityFlags failed and no default flag handler was provided')
213
- })
213
+ const flg = flagsmith({
214
+ fetch: badFetch
215
+ });
216
+ await expect(flg.getIdentityFlags('user')).rejects.toThrow(
217
+ 'getIdentityFlags failed and no default flag handler was provided'
218
+ );
219
+ });