flagsmith-nodejs 3.3.3 → 4.0.0-beta.1

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 (190) hide show
  1. package/.github/workflows/publish.yml +2 -2
  2. package/.github/workflows/pull_request.yaml +3 -4
  3. package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/models.d.ts +3 -3
  4. package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/models.js +20 -13
  5. package/build/{flagsmith-engine → cjs/flagsmith-engine}/environments/util.d.ts +1 -1
  6. package/build/cjs/flagsmith-engine/environments/util.js +23 -0
  7. package/build/cjs/flagsmith-engine/features/models.js +118 -0
  8. package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/util.d.ts +1 -1
  9. package/build/cjs/flagsmith-engine/features/util.js +27 -0
  10. package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/models.d.ts +2 -2
  11. package/build/cjs/flagsmith-engine/identities/models.js +48 -0
  12. package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/traits/models.js +5 -4
  13. package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/util.d.ts +2 -2
  14. package/build/cjs/flagsmith-engine/identities/util.js +22 -0
  15. package/build/cjs/flagsmith-engine/index.d.ts +14 -0
  16. package/build/cjs/flagsmith-engine/index.js +75 -0
  17. package/build/cjs/flagsmith-engine/organisations/models.js +21 -0
  18. package/build/{flagsmith-engine → cjs/flagsmith-engine}/organisations/util.d.ts +1 -1
  19. package/build/cjs/flagsmith-engine/organisations/util.js +8 -0
  20. package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/models.d.ts +2 -2
  21. package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/models.js +8 -5
  22. package/build/{flagsmith-engine → cjs/flagsmith-engine}/projects/util.d.ts +1 -1
  23. package/build/cjs/flagsmith-engine/projects/util.js +15 -0
  24. package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/evaluators.d.ts +4 -4
  25. package/build/cjs/flagsmith-engine/segments/evaluators.js +37 -0
  26. package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/models.d.ts +1 -1
  27. package/build/cjs/flagsmith-engine/segments/models.js +114 -0
  28. package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/util.d.ts +1 -1
  29. package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/util.js +9 -11
  30. package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/collections.d.ts +1 -1
  31. package/build/cjs/flagsmith-engine/utils/collections.js +6 -0
  32. package/build/cjs/flagsmith-engine/utils/errors.js +6 -0
  33. package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/hashing/index.js +8 -11
  34. package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/index.js +5 -5
  35. package/build/{index.d.ts → cjs/index.d.ts} +3 -3
  36. package/build/{index.js → cjs/index.js} +17 -17
  37. package/build/cjs/package.json +1 -0
  38. package/build/{sdk → cjs/sdk}/analytics.d.ts +3 -0
  39. package/build/cjs/sdk/analytics.js +73 -0
  40. package/build/cjs/sdk/errors.js +9 -0
  41. package/build/{sdk → cjs/sdk}/index.d.ts +19 -18
  42. package/build/cjs/sdk/index.js +400 -0
  43. package/build/{sdk → cjs/sdk}/models.d.ts +2 -2
  44. package/build/cjs/sdk/models.js +101 -0
  45. package/build/{sdk → cjs/sdk}/offline_handlers.d.ts +1 -1
  46. package/build/cjs/sdk/offline_handlers.js +46 -0
  47. package/build/{sdk → cjs/sdk}/polling_manager.d.ts +1 -1
  48. package/build/cjs/sdk/polling_manager.js +29 -0
  49. package/build/{sdk → cjs/sdk}/types.d.ts +15 -7
  50. package/build/cjs/sdk/utils.d.ts +36 -0
  51. package/build/cjs/sdk/utils.js +63 -0
  52. package/build/esm/flagsmith-engine/environments/models.d.ts +22 -0
  53. package/build/esm/flagsmith-engine/environments/models.js +32 -0
  54. package/build/esm/flagsmith-engine/environments/util.d.ts +3 -0
  55. package/build/esm/flagsmith-engine/environments/util.js +18 -0
  56. package/build/esm/flagsmith-engine/features/constants.d.ts +4 -0
  57. package/build/esm/flagsmith-engine/features/constants.js +4 -0
  58. package/build/esm/flagsmith-engine/features/models.d.ts +37 -0
  59. package/build/esm/flagsmith-engine/features/models.js +110 -0
  60. package/build/esm/flagsmith-engine/features/util.d.ts +4 -0
  61. package/build/esm/flagsmith-engine/features/util.js +21 -0
  62. package/build/esm/flagsmith-engine/identities/models.d.ts +15 -0
  63. package/build/esm/flagsmith-engine/identities/models.js +44 -0
  64. package/build/esm/flagsmith-engine/identities/traits/models.d.ts +5 -0
  65. package/build/esm/flagsmith-engine/identities/traits/models.js +8 -0
  66. package/build/esm/flagsmith-engine/identities/util.d.ts +4 -0
  67. package/build/esm/flagsmith-engine/identities/util.js +17 -0
  68. package/build/esm/flagsmith-engine/index.d.ts +14 -0
  69. package/build/esm/flagsmith-engine/index.js +62 -0
  70. package/build/esm/flagsmith-engine/organisations/models.d.ts +9 -0
  71. package/build/esm/flagsmith-engine/organisations/models.js +17 -0
  72. package/build/esm/flagsmith-engine/organisations/util.d.ts +2 -0
  73. package/build/esm/flagsmith-engine/organisations/util.js +4 -0
  74. package/build/esm/flagsmith-engine/projects/models.d.ts +10 -0
  75. package/build/esm/flagsmith-engine/projects/models.js +13 -0
  76. package/build/esm/flagsmith-engine/projects/util.d.ts +2 -0
  77. package/build/esm/flagsmith-engine/projects/util.js +11 -0
  78. package/build/esm/flagsmith-engine/segments/constants.d.ts +34 -0
  79. package/build/esm/flagsmith-engine/segments/constants.js +36 -0
  80. package/build/esm/flagsmith-engine/segments/evaluators.d.ts +7 -0
  81. package/build/esm/flagsmith-engine/segments/evaluators.js +31 -0
  82. package/build/esm/flagsmith-engine/segments/models.d.ts +37 -0
  83. package/build/esm/flagsmith-engine/segments/models.js +102 -0
  84. package/build/esm/flagsmith-engine/segments/util.d.ts +6 -0
  85. package/build/esm/flagsmith-engine/segments/util.js +23 -0
  86. package/build/esm/flagsmith-engine/utils/collections.d.ts +3 -0
  87. package/build/esm/flagsmith-engine/utils/collections.js +2 -0
  88. package/build/esm/flagsmith-engine/utils/errors.d.ts +2 -0
  89. package/build/esm/flagsmith-engine/utils/errors.js +2 -0
  90. package/build/esm/flagsmith-engine/utils/hashing/index.d.ts +9 -0
  91. package/build/esm/flagsmith-engine/utils/hashing/index.js +50 -0
  92. package/build/esm/flagsmith-engine/utils/index.d.ts +1 -0
  93. package/build/esm/flagsmith-engine/utils/index.js +13 -0
  94. package/build/esm/index.d.ts +3 -0
  95. package/build/esm/index.js +4 -0
  96. package/build/esm/sdk/analytics.d.ts +35 -0
  97. package/build/esm/sdk/analytics.js +69 -0
  98. package/build/esm/sdk/errors.d.ts +4 -0
  99. package/build/esm/sdk/errors.js +4 -0
  100. package/build/esm/sdk/index.d.ts +131 -0
  101. package/build/esm/sdk/index.js +390 -0
  102. package/build/esm/sdk/models.d.ts +55 -0
  103. package/build/esm/sdk/models.js +94 -0
  104. package/build/esm/sdk/offline_handlers.d.ts +9 -0
  105. package/build/esm/sdk/offline_handlers.js +18 -0
  106. package/build/esm/sdk/polling_manager.d.ts +9 -0
  107. package/build/esm/sdk/polling_manager.js +25 -0
  108. package/build/esm/sdk/types.d.ts +38 -0
  109. package/build/esm/sdk/types.js +1 -0
  110. package/build/esm/sdk/utils.d.ts +36 -0
  111. package/build/esm/sdk/utils.js +56 -0
  112. package/flagsmith-engine/environments/models.ts +3 -3
  113. package/flagsmith-engine/environments/util.ts +4 -4
  114. package/flagsmith-engine/features/models.ts +1 -1
  115. package/flagsmith-engine/features/util.ts +1 -1
  116. package/flagsmith-engine/identities/models.ts +3 -4
  117. package/flagsmith-engine/identities/traits/models.ts +0 -1
  118. package/flagsmith-engine/identities/util.ts +4 -4
  119. package/flagsmith-engine/index.ts +13 -13
  120. package/flagsmith-engine/organisations/util.ts +1 -1
  121. package/flagsmith-engine/projects/models.ts +2 -2
  122. package/flagsmith-engine/projects/util.ts +4 -4
  123. package/flagsmith-engine/segments/evaluators.ts +6 -6
  124. package/flagsmith-engine/segments/models.ts +4 -4
  125. package/flagsmith-engine/segments/util.ts +3 -3
  126. package/flagsmith-engine/utils/collections.ts +1 -1
  127. package/flagsmith-engine/utils/index.ts +1 -1
  128. package/index.ts +4 -4
  129. package/package.json +21 -9
  130. package/sdk/analytics.ts +7 -5
  131. package/sdk/index.ts +55 -46
  132. package/sdk/models.ts +2 -3
  133. package/sdk/offline_handlers.ts +2 -2
  134. package/sdk/polling_manager.ts +2 -3
  135. package/sdk/types.ts +35 -24
  136. package/sdk/utils.ts +49 -37
  137. package/tests/engine/e2e/engine.test.ts +5 -5
  138. package/tests/engine/unit/engine.test.ts +5 -5
  139. package/tests/engine/unit/segments/segment_evaluators.test.ts +9 -9
  140. package/tests/engine/unit/utils/utils.test.ts +1 -1
  141. package/tests/sdk/analytics.test.ts +8 -13
  142. package/tests/sdk/data/identity-with-transient-traits.json +41 -0
  143. package/tests/sdk/data/transient-identity.json +29 -0
  144. package/tests/sdk/flagsmith-cache.test.ts +16 -32
  145. package/tests/sdk/flagsmith-environment-flags.test.ts +21 -36
  146. package/tests/sdk/flagsmith-identity-flags.test.ts +83 -32
  147. package/tests/sdk/flagsmith.test.ts +67 -99
  148. package/tests/sdk/offline-handlers.test.ts +4 -5
  149. package/tests/sdk/polling.test.ts +6 -8
  150. package/tests/sdk/utils.ts +19 -15
  151. package/tsconfig.cjs.json +7 -0
  152. package/tsconfig.esm.json +7 -0
  153. package/tsconfig.json +7 -3
  154. package/vitest.config.ts +17 -0
  155. package/build/flagsmith-engine/environments/util.js +0 -27
  156. package/build/flagsmith-engine/features/models.js +0 -132
  157. package/build/flagsmith-engine/features/util.js +0 -27
  158. package/build/flagsmith-engine/identities/models.js +0 -113
  159. package/build/flagsmith-engine/identities/util.js +0 -46
  160. package/build/flagsmith-engine/index.d.ts +0 -14
  161. package/build/flagsmith-engine/index.js +0 -127
  162. package/build/flagsmith-engine/organisations/models.js +0 -21
  163. package/build/flagsmith-engine/organisations/util.js +0 -8
  164. package/build/flagsmith-engine/projects/util.js +0 -15
  165. package/build/flagsmith-engine/segments/evaluators.js +0 -45
  166. package/build/flagsmith-engine/segments/models.js +0 -147
  167. package/build/flagsmith-engine/utils/collections.js +0 -26
  168. package/build/flagsmith-engine/utils/errors.js +0 -26
  169. package/build/sdk/analytics.js +0 -120
  170. package/build/sdk/errors.js +0 -34
  171. package/build/sdk/index.js +0 -594
  172. package/build/sdk/models.js +0 -149
  173. package/build/sdk/offline_handlers.js +0 -66
  174. package/build/sdk/polling_manager.js +0 -72
  175. package/build/sdk/utils.d.ts +0 -12
  176. package/build/sdk/utils.js +0 -107
  177. package/jest.config.js +0 -5
  178. package/tests/index.js +0 -0
  179. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/constants.d.ts +0 -0
  180. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/constants.js +0 -0
  181. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/features/models.d.ts +0 -0
  182. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/identities/traits/models.d.ts +0 -0
  183. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/organisations/models.d.ts +0 -0
  184. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/constants.d.ts +0 -0
  185. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/segments/constants.js +0 -0
  186. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/errors.d.ts +0 -0
  187. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/hashing/index.d.ts +0 -0
  188. /package/build/{flagsmith-engine → cjs/flagsmith-engine}/utils/index.d.ts +0 -0
  189. /package/build/{sdk → cjs/sdk}/errors.d.ts +0 -0
  190. /package/build/{sdk → cjs/sdk}/types.js +0 -0
@@ -14,9 +14,9 @@ jobs:
14
14
  - name: Cloning repo
15
15
  uses: actions/checkout@v3
16
16
 
17
- - uses: actions/setup-node@v3
17
+ - uses: actions/setup-node@v4
18
18
  with:
19
- node-version: '16.x'
19
+ node-version: '18.x'
20
20
  registry-url: 'https://registry.npmjs.org'
21
21
 
22
22
  - run: npm ci
@@ -23,9 +23,9 @@ jobs:
23
23
  auth_header="$(git config --local --get http.https://github.com/.extraheader)"
24
24
  git submodule sync --recursive
25
25
  git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
26
- - uses: actions/setup-node@v1
26
+ - uses: actions/setup-node@v4
27
27
  with:
28
- node-version: "15.x"
28
+ node-version: "18.x"
29
29
  - name: cache node modules
30
30
  uses: actions/cache@v1
31
31
  with:
@@ -34,8 +34,7 @@ jobs:
34
34
  restore-keys: |
35
35
  npm-${{ hashFiles('package-lock.json') }}
36
36
  npm-
37
- - run: npm i -g npm@7.0.2
38
- - run: npm install
37
+ - run: npm ci
39
38
  - run: npm test
40
39
  env:
41
40
  CI: true
@@ -1,6 +1,6 @@
1
- import { FeatureStateModel } from '../features/models';
2
- import { IdentityModel } from '../identities/models';
3
- import { ProjectModel } from '../projects/models';
1
+ import { FeatureStateModel } from '../features/models.js';
2
+ import { IdentityModel } from '../identities/models.js';
3
+ import { ProjectModel } from '../projects/models.js';
4
4
  export declare class EnvironmentAPIKeyModel {
5
5
  id: number;
6
6
  key: string;
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EnvironmentModel = exports.EnvironmentAPIKeyModel = void 0;
4
- var EnvironmentAPIKeyModel = /** @class */ (function () {
5
- function EnvironmentAPIKeyModel(id, key, createdAt, name, clientApiKey, expiresAt) {
6
- this.active = true;
4
+ class EnvironmentAPIKeyModel {
5
+ id;
6
+ key;
7
+ createdAt;
8
+ name;
9
+ clientApiKey;
10
+ expiresAt;
11
+ active = true;
12
+ constructor(id, key, createdAt, name, clientApiKey, expiresAt) {
7
13
  this.id = id;
8
14
  this.key = key;
9
15
  this.createdAt = createdAt;
@@ -11,20 +17,21 @@ var EnvironmentAPIKeyModel = /** @class */ (function () {
11
17
  this.clientApiKey = clientApiKey;
12
18
  this.expiresAt = expiresAt;
13
19
  }
14
- EnvironmentAPIKeyModel.prototype.isValid = function () {
20
+ isValid() {
15
21
  return !!this.active && (!this.expiresAt || this.expiresAt > Date.now());
16
- };
17
- return EnvironmentAPIKeyModel;
18
- }());
22
+ }
23
+ }
19
24
  exports.EnvironmentAPIKeyModel = EnvironmentAPIKeyModel;
20
- var EnvironmentModel = /** @class */ (function () {
21
- function EnvironmentModel(id, apiKey, project) {
22
- this.featureStates = [];
23
- this.identityOverrides = [];
25
+ class EnvironmentModel {
26
+ id;
27
+ apiKey;
28
+ project;
29
+ featureStates = [];
30
+ identityOverrides = [];
31
+ constructor(id, apiKey, project) {
24
32
  this.id = id;
25
33
  this.apiKey = apiKey;
26
34
  this.project = project;
27
35
  }
28
- return EnvironmentModel;
29
- }());
36
+ }
30
37
  exports.EnvironmentModel = EnvironmentModel;
@@ -1,3 +1,3 @@
1
- import { EnvironmentAPIKeyModel, EnvironmentModel } from './models';
1
+ import { EnvironmentAPIKeyModel, EnvironmentModel } from './models.js';
2
2
  export declare function buildEnvironmentModel(environmentJSON: any): EnvironmentModel;
3
3
  export declare function buildEnvironmentAPIKeyModel(apiKeyJSON: any): EnvironmentAPIKeyModel;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildEnvironmentAPIKeyModel = exports.buildEnvironmentModel = void 0;
4
+ const util_js_1 = require("../features/util.js");
5
+ const util_js_2 = require("../identities/util.js");
6
+ const util_js_3 = require("../projects/util.js");
7
+ const models_js_1 = require("./models.js");
8
+ function buildEnvironmentModel(environmentJSON) {
9
+ const project = (0, util_js_3.buildProjectModel)(environmentJSON.project);
10
+ const featureStates = environmentJSON.feature_states.map((fs) => (0, util_js_1.buildFeatureStateModel)(fs));
11
+ const environmentModel = new models_js_1.EnvironmentModel(environmentJSON.id, environmentJSON.api_key, project);
12
+ environmentModel.featureStates = featureStates;
13
+ if (!!environmentJSON.identity_overrides) {
14
+ environmentModel.identityOverrides = environmentJSON.identity_overrides.map((identityData) => (0, util_js_2.buildIdentityModel)(identityData));
15
+ }
16
+ return environmentModel;
17
+ }
18
+ exports.buildEnvironmentModel = buildEnvironmentModel;
19
+ function buildEnvironmentAPIKeyModel(apiKeyJSON) {
20
+ const model = new models_js_1.EnvironmentAPIKeyModel(apiKeyJSON.id, apiKeyJSON.key, Date.parse(apiKeyJSON.created_at), apiKeyJSON.name, apiKeyJSON.client_api_key);
21
+ return model;
22
+ }
23
+ exports.buildEnvironmentAPIKeyModel = buildEnvironmentAPIKeyModel;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeatureSegment = exports.FeatureStateModel = exports.MultivariateFeatureStateValueModel = exports.MultivariateFeatureOptionModel = exports.FeatureModel = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const index_js_1 = require("../utils/hashing/index.js");
6
+ class FeatureModel {
7
+ id;
8
+ name;
9
+ type;
10
+ constructor(id, name, type) {
11
+ this.id = id;
12
+ this.name = name;
13
+ this.type = type;
14
+ }
15
+ eq(other) {
16
+ return !!other && this.id === other.id;
17
+ }
18
+ }
19
+ exports.FeatureModel = FeatureModel;
20
+ class MultivariateFeatureOptionModel {
21
+ value;
22
+ id;
23
+ constructor(value, id) {
24
+ this.value = value;
25
+ this.id = id;
26
+ }
27
+ }
28
+ exports.MultivariateFeatureOptionModel = MultivariateFeatureOptionModel;
29
+ class MultivariateFeatureStateValueModel {
30
+ multivariateFeatureOption;
31
+ percentageAllocation;
32
+ id;
33
+ mvFsValueUuid = (0, uuid_1.v4)();
34
+ constructor(multivariate_feature_option, percentage_allocation, id, mvFsValueUuid) {
35
+ this.id = id;
36
+ this.percentageAllocation = percentage_allocation;
37
+ this.multivariateFeatureOption = multivariate_feature_option;
38
+ this.mvFsValueUuid = mvFsValueUuid || this.mvFsValueUuid;
39
+ }
40
+ }
41
+ exports.MultivariateFeatureStateValueModel = MultivariateFeatureStateValueModel;
42
+ class FeatureStateModel {
43
+ feature;
44
+ enabled;
45
+ djangoID;
46
+ featurestateUUID = (0, uuid_1.v4)();
47
+ featureSegment;
48
+ value;
49
+ multivariateFeatureStateValues = [];
50
+ constructor(feature, enabled, djangoID, value, featurestateUuid = (0, uuid_1.v4)()) {
51
+ this.feature = feature;
52
+ this.enabled = enabled;
53
+ this.djangoID = djangoID;
54
+ this.value = value;
55
+ this.featurestateUUID = featurestateUuid;
56
+ }
57
+ setValue(value) {
58
+ this.value = value;
59
+ }
60
+ getValue(identityId) {
61
+ if (!!identityId && this.multivariateFeatureStateValues.length > 0) {
62
+ return this.getMultivariateValue(identityId);
63
+ }
64
+ return this.value;
65
+ }
66
+ /*
67
+ Returns `True` if `this` is higher segment priority than `other`
68
+ (i.e. has lower value for featureSegment.priority)
69
+ NOTE:
70
+ A segment will be considered higher priority only if:
71
+ 1. `other` does not have a feature segment(i.e: it is an environment feature state or it's a
72
+ feature state with feature segment but from an old document that does not have `featureSegment.priority`)
73
+ but `this` does.
74
+ 2. `other` have a feature segment with high priority
75
+ */
76
+ isHigherSegmentPriority(other) {
77
+ if (!other.featureSegment || !this.featureSegment) {
78
+ return !!this.featureSegment && !other.featureSegment;
79
+ }
80
+ return this.featureSegment.priority < other.featureSegment.priority;
81
+ }
82
+ getMultivariateValue(identityID) {
83
+ let percentageValue;
84
+ let startPercentage = 0;
85
+ const sortedF = this.multivariateFeatureStateValues.sort((a, b) => {
86
+ return a.id - b.id;
87
+ });
88
+ for (const myValue of sortedF) {
89
+ switch (myValue.percentageAllocation) {
90
+ case 0:
91
+ continue;
92
+ case 100:
93
+ return myValue.multivariateFeatureOption.value;
94
+ default:
95
+ if (percentageValue === undefined) {
96
+ percentageValue = (0, index_js_1.getHashedPercentateForObjIds)([
97
+ this.djangoID || this.featurestateUUID,
98
+ identityID
99
+ ]);
100
+ }
101
+ }
102
+ const limit = myValue.percentageAllocation + startPercentage;
103
+ if (startPercentage <= percentageValue && percentageValue < limit) {
104
+ return myValue.multivariateFeatureOption.value;
105
+ }
106
+ startPercentage = limit;
107
+ }
108
+ return this.value;
109
+ }
110
+ }
111
+ exports.FeatureStateModel = FeatureStateModel;
112
+ class FeatureSegment {
113
+ priority;
114
+ constructor(priority) {
115
+ this.priority = priority;
116
+ }
117
+ }
118
+ exports.FeatureSegment = FeatureSegment;
@@ -1,4 +1,4 @@
1
- import { FeatureModel, FeatureSegment, FeatureStateModel } from './models';
1
+ import { FeatureModel, FeatureSegment, FeatureStateModel } from './models.js';
2
2
  export declare function buildFeatureModel(featuresModelJSON: any): FeatureModel;
3
3
  export declare function buildFeatureStateModel(featuresStateModelJSON: any): FeatureStateModel;
4
4
  export declare function buildFeatureSegment(featureSegmentJSON: any): FeatureSegment;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFeatureSegment = exports.buildFeatureStateModel = exports.buildFeatureModel = void 0;
4
+ const models_js_1 = require("./models.js");
5
+ function buildFeatureModel(featuresModelJSON) {
6
+ return new models_js_1.FeatureModel(featuresModelJSON.id, featuresModelJSON.name, featuresModelJSON.type);
7
+ }
8
+ exports.buildFeatureModel = buildFeatureModel;
9
+ function buildFeatureStateModel(featuresStateModelJSON) {
10
+ const featureStateModel = new models_js_1.FeatureStateModel(buildFeatureModel(featuresStateModelJSON.feature), featuresStateModelJSON.enabled, featuresStateModelJSON.django_id, featuresStateModelJSON.feature_state_value, featuresStateModelJSON.featurestate_uuid);
11
+ featureStateModel.featureSegment = featuresStateModelJSON.feature_segment ?
12
+ buildFeatureSegment(featuresStateModelJSON.feature_segment) :
13
+ undefined;
14
+ const multivariateFeatureStateValues = featuresStateModelJSON.multivariate_feature_state_values
15
+ ? featuresStateModelJSON.multivariate_feature_state_values.map((fsv) => {
16
+ const featureOption = new models_js_1.MultivariateFeatureOptionModel(fsv.multivariate_feature_option.value, fsv.multivariate_feature_option.id);
17
+ return new models_js_1.MultivariateFeatureStateValueModel(featureOption, fsv.percentage_allocation, fsv.id, fsv.mv_fs_value_uuid);
18
+ })
19
+ : [];
20
+ featureStateModel.multivariateFeatureStateValues = multivariateFeatureStateValues;
21
+ return featureStateModel;
22
+ }
23
+ exports.buildFeatureStateModel = buildFeatureStateModel;
24
+ function buildFeatureSegment(featureSegmentJSON) {
25
+ return new models_js_1.FeatureSegment(featureSegmentJSON.priority);
26
+ }
27
+ exports.buildFeatureSegment = buildFeatureSegment;
@@ -1,5 +1,5 @@
1
- import { IdentityFeaturesList } from '../utils/collections';
2
- import { TraitModel } from './traits/models';
1
+ import { IdentityFeaturesList } from '../utils/collections.js';
2
+ import { TraitModel } from './traits/models.js';
3
3
  export declare class IdentityModel {
4
4
  identifier: string;
5
5
  environmentApiKey: string;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdentityModel = void 0;
4
+ const collections_js_1 = require("../utils/collections.js");
5
+ const { v4: uuidv4 } = require('uuid');
6
+ class IdentityModel {
7
+ identifier;
8
+ environmentApiKey;
9
+ createdDate;
10
+ identityFeatures;
11
+ identityTraits;
12
+ identityUuid;
13
+ djangoID;
14
+ constructor(created_date, identityTraits, identityFeatures, environmentApiKey, identifier, identityUuid, djangoID) {
15
+ this.identityUuid = identityUuid || uuidv4();
16
+ this.createdDate = Date.parse(created_date) || Date.now();
17
+ this.identityTraits = identityTraits;
18
+ this.identityFeatures = new collections_js_1.IdentityFeaturesList(...identityFeatures);
19
+ this.environmentApiKey = environmentApiKey;
20
+ this.identifier = identifier;
21
+ this.djangoID = djangoID;
22
+ }
23
+ get compositeKey() {
24
+ return IdentityModel.generateCompositeKey(this.environmentApiKey, this.identifier);
25
+ }
26
+ static generateCompositeKey(env_key, identifier) {
27
+ return `${env_key}_${identifier}`;
28
+ }
29
+ updateTraits(traits) {
30
+ const existingTraits = new Map();
31
+ for (const trait of this.identityTraits) {
32
+ existingTraits.set(trait.traitKey, trait);
33
+ }
34
+ for (const trait of traits) {
35
+ if (!!trait.traitValue) {
36
+ existingTraits.set(trait.traitKey, trait);
37
+ }
38
+ else {
39
+ existingTraits.delete(trait.traitKey);
40
+ }
41
+ }
42
+ this.identityTraits = [];
43
+ for (const [k, v] of existingTraits.entries()) {
44
+ this.identityTraits.push(v);
45
+ }
46
+ }
47
+ }
48
+ exports.IdentityModel = IdentityModel;
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TraitModel = void 0;
4
- var TraitModel = /** @class */ (function () {
5
- function TraitModel(key, value) {
4
+ class TraitModel {
5
+ traitKey;
6
+ traitValue;
7
+ constructor(key, value) {
6
8
  this.traitKey = key;
7
9
  this.traitValue = value;
8
10
  }
9
- return TraitModel;
10
- }());
11
+ }
11
12
  exports.TraitModel = TraitModel;
@@ -1,4 +1,4 @@
1
- import { IdentityModel } from './models';
2
- import { TraitModel } from './traits/models';
1
+ import { IdentityModel } from './models.js';
2
+ import { TraitModel } from './traits/models.js';
3
3
  export declare function buildTraitModel(traitJSON: any): TraitModel;
4
4
  export declare function buildIdentityModel(identityJSON: any): IdentityModel;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildIdentityModel = exports.buildTraitModel = void 0;
4
+ const util_js_1 = require("../features/util.js");
5
+ const collections_js_1 = require("../utils/collections.js");
6
+ const models_js_1 = require("./models.js");
7
+ const models_js_2 = require("./traits/models.js");
8
+ function buildTraitModel(traitJSON) {
9
+ return new models_js_2.TraitModel(traitJSON.trait_key, traitJSON.trait_value);
10
+ }
11
+ exports.buildTraitModel = buildTraitModel;
12
+ function buildIdentityModel(identityJSON) {
13
+ const featureList = identityJSON.identity_features
14
+ ? new collections_js_1.IdentityFeaturesList(...identityJSON.identity_features.map((f) => (0, util_js_1.buildFeatureStateModel)(f)))
15
+ : [];
16
+ const model = new models_js_1.IdentityModel(identityJSON.created_date, identityJSON.identity_traits
17
+ ? identityJSON.identity_traits.map((trait) => buildTraitModel(trait))
18
+ : [], featureList, identityJSON.environment_api_key, identityJSON.identifier, identityJSON.identity_uuid);
19
+ model.djangoID = identityJSON.django_id;
20
+ return model;
21
+ }
22
+ exports.buildIdentityModel = buildIdentityModel;
@@ -0,0 +1,14 @@
1
+ import { EnvironmentModel } from './environments/models.js';
2
+ import { FeatureStateModel } from './features/models.js';
3
+ import { IdentityModel } from './identities/models.js';
4
+ import { TraitModel } from './identities/traits/models.js';
5
+ export { EnvironmentModel } from './environments/models.js';
6
+ export { FeatureStateModel } from './features/models.js';
7
+ export { IdentityModel } from './identities/models.js';
8
+ export { TraitModel } from './identities/traits/models.js';
9
+ export { SegmentModel } from './segments/models.js';
10
+ export { OrganisationModel } from './organisations/models.js';
11
+ export declare function getIdentityFeatureState(environment: EnvironmentModel, identity: IdentityModel, featureName: string, overrideTraits?: TraitModel[]): FeatureStateModel;
12
+ export declare function getIdentityFeatureStates(environment: EnvironmentModel, identity: IdentityModel, overrideTraits?: TraitModel[]): FeatureStateModel[];
13
+ export declare function getEnvironmentFeatureState(environment: EnvironmentModel, featureName: string): FeatureStateModel;
14
+ export declare function getEnvironmentFeatureStates(environment: EnvironmentModel): FeatureStateModel[];
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEnvironmentFeatureStates = exports.getEnvironmentFeatureState = exports.getIdentityFeatureStates = exports.getIdentityFeatureState = exports.OrganisationModel = exports.SegmentModel = exports.TraitModel = exports.IdentityModel = exports.FeatureStateModel = exports.EnvironmentModel = void 0;
4
+ const evaluators_js_1 = require("./segments/evaluators.js");
5
+ const errors_js_1 = require("./utils/errors.js");
6
+ var models_js_1 = require("./environments/models.js");
7
+ Object.defineProperty(exports, "EnvironmentModel", { enumerable: true, get: function () { return models_js_1.EnvironmentModel; } });
8
+ var models_js_2 = require("./features/models.js");
9
+ Object.defineProperty(exports, "FeatureStateModel", { enumerable: true, get: function () { return models_js_2.FeatureStateModel; } });
10
+ var models_js_3 = require("./identities/models.js");
11
+ Object.defineProperty(exports, "IdentityModel", { enumerable: true, get: function () { return models_js_3.IdentityModel; } });
12
+ var models_js_4 = require("./identities/traits/models.js");
13
+ Object.defineProperty(exports, "TraitModel", { enumerable: true, get: function () { return models_js_4.TraitModel; } });
14
+ var models_js_5 = require("./segments/models.js");
15
+ Object.defineProperty(exports, "SegmentModel", { enumerable: true, get: function () { return models_js_5.SegmentModel; } });
16
+ var models_js_6 = require("./organisations/models.js");
17
+ Object.defineProperty(exports, "OrganisationModel", { enumerable: true, get: function () { return models_js_6.OrganisationModel; } });
18
+ function getIdentityFeatureStatesDict(environment, identity, overrideTraits) {
19
+ // Get feature states from the environment
20
+ const featureStates = {};
21
+ for (const fs of environment.featureStates) {
22
+ featureStates[fs.feature.id] = fs;
23
+ }
24
+ // Override with any feature states defined by matching segments
25
+ const identitySegments = (0, evaluators_js_1.getIdentitySegments)(environment, identity, overrideTraits);
26
+ for (const matchingSegment of identitySegments) {
27
+ for (const featureState of matchingSegment.featureStates) {
28
+ if (featureStates[featureState.feature.id]) {
29
+ if (featureStates[featureState.feature.id].isHigherSegmentPriority(featureState)) {
30
+ continue;
31
+ }
32
+ }
33
+ featureStates[featureState.feature.id] = featureState;
34
+ }
35
+ }
36
+ // Override with any feature states defined directly the identity
37
+ for (const fs of identity.identityFeatures) {
38
+ if (featureStates[fs.feature.id]) {
39
+ featureStates[fs.feature.id] = fs;
40
+ }
41
+ }
42
+ return featureStates;
43
+ }
44
+ function getIdentityFeatureState(environment, identity, featureName, overrideTraits) {
45
+ const featureStates = getIdentityFeatureStatesDict(environment, identity, overrideTraits);
46
+ const matchingFeature = Object.values(featureStates).filter(f => f.feature.name === featureName);
47
+ if (matchingFeature.length === 0) {
48
+ throw new errors_js_1.FeatureStateNotFound('Feature State Not Found');
49
+ }
50
+ return matchingFeature[0];
51
+ }
52
+ exports.getIdentityFeatureState = getIdentityFeatureState;
53
+ function getIdentityFeatureStates(environment, identity, overrideTraits) {
54
+ const featureStates = Object.values(getIdentityFeatureStatesDict(environment, identity, overrideTraits));
55
+ if (environment.project.hideDisabledFlags) {
56
+ return featureStates.filter(fs => !!fs.enabled);
57
+ }
58
+ return featureStates;
59
+ }
60
+ exports.getIdentityFeatureStates = getIdentityFeatureStates;
61
+ function getEnvironmentFeatureState(environment, featureName) {
62
+ const featuresStates = environment.featureStates.filter(f => f.feature.name === featureName);
63
+ if (featuresStates.length === 0) {
64
+ throw new errors_js_1.FeatureStateNotFound('Feature State Not Found');
65
+ }
66
+ return featuresStates[0];
67
+ }
68
+ exports.getEnvironmentFeatureState = getEnvironmentFeatureState;
69
+ function getEnvironmentFeatureStates(environment) {
70
+ if (environment.project.hideDisabledFlags) {
71
+ return environment.featureStates.filter(fs => !!fs.enabled);
72
+ }
73
+ return environment.featureStates;
74
+ }
75
+ exports.getEnvironmentFeatureStates = getEnvironmentFeatureStates;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrganisationModel = void 0;
4
+ class OrganisationModel {
5
+ id;
6
+ name;
7
+ featureAnalytics;
8
+ stopServingFlags;
9
+ persistTraitData;
10
+ constructor(id, name, featureAnalytics, stopServingFlags, persistTraitData) {
11
+ this.id = id;
12
+ this.name = name;
13
+ this.featureAnalytics = featureAnalytics;
14
+ this.stopServingFlags = stopServingFlags;
15
+ this.persistTraitData = persistTraitData;
16
+ }
17
+ get uniqueSlug() {
18
+ return this.id.toString() + '-' + this.name;
19
+ }
20
+ }
21
+ exports.OrganisationModel = OrganisationModel;
@@ -1,2 +1,2 @@
1
- import { OrganisationModel } from './models';
1
+ import { OrganisationModel } from './models.js';
2
2
  export declare function buildOrganizationModel(organizationJSON: any): OrganisationModel;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildOrganizationModel = void 0;
4
+ const models_js_1 = require("./models.js");
5
+ function buildOrganizationModel(organizationJSON) {
6
+ return new models_js_1.OrganisationModel(organizationJSON.id, organizationJSON.name, organizationJSON.feature_analytics, organizationJSON.stop_serving_flags, organizationJSON.persist_trait_data);
7
+ }
8
+ exports.buildOrganizationModel = buildOrganizationModel;
@@ -1,5 +1,5 @@
1
- import { OrganisationModel } from '../organisations/models';
2
- import { SegmentModel } from '../segments/models';
1
+ import { OrganisationModel } from '../organisations/models.js';
2
+ import { SegmentModel } from '../segments/models.js';
3
3
  export declare class ProjectModel {
4
4
  id: number;
5
5
  name: string;
@@ -1,14 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProjectModel = void 0;
4
- var ProjectModel = /** @class */ (function () {
5
- function ProjectModel(id, name, hideDisabledFlags, organization) {
6
- this.segments = [];
4
+ class ProjectModel {
5
+ id;
6
+ name;
7
+ organisation;
8
+ hideDisabledFlags;
9
+ segments = [];
10
+ constructor(id, name, hideDisabledFlags, organization) {
7
11
  this.id = id;
8
12
  this.name = name;
9
13
  this.hideDisabledFlags = hideDisabledFlags;
10
14
  this.organisation = organization;
11
15
  }
12
- return ProjectModel;
13
- }());
16
+ }
14
17
  exports.ProjectModel = ProjectModel;
@@ -1,2 +1,2 @@
1
- import { ProjectModel } from './models';
1
+ import { ProjectModel } from './models.js';
2
2
  export declare function buildProjectModel(projectJSON: any): ProjectModel;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildProjectModel = void 0;
4
+ const util_js_1 = require("../organisations/util.js");
5
+ const util_js_2 = require("../segments/util.js");
6
+ const models_js_1 = require("./models.js");
7
+ function buildProjectModel(projectJSON) {
8
+ const segments = projectJSON['segments']
9
+ ? projectJSON['segments'].map((s) => (0, util_js_2.buildSegmentModel)(s))
10
+ : [];
11
+ const model = new models_js_1.ProjectModel(projectJSON.id, projectJSON.name, projectJSON.hide_disabled_flags, (0, util_js_1.buildOrganizationModel)(projectJSON.organisation));
12
+ model.segments = segments;
13
+ return model;
14
+ }
15
+ exports.buildProjectModel = buildProjectModel;
@@ -1,7 +1,7 @@
1
- import { EnvironmentModel } from '../environments/models';
2
- import { IdentityModel } from '../identities/models';
3
- import { TraitModel } from '../identities/traits/models';
4
- import { SegmentConditionModel, SegmentModel } from './models';
1
+ import { EnvironmentModel } from '../environments/models.js';
2
+ import { IdentityModel } from '../identities/models.js';
3
+ import { TraitModel } from '../identities/traits/models.js';
4
+ import { SegmentConditionModel, SegmentModel } from './models.js';
5
5
  export declare function getIdentitySegments(environment: EnvironmentModel, identity: IdentityModel, overrideTraits?: TraitModel[]): SegmentModel[];
6
6
  export declare function evaluateIdentityInSegment(identity: IdentityModel, segment: SegmentModel, overrideTraits?: TraitModel[]): boolean;
7
7
  export declare function traitsMatchSegmentCondition(identityTraits: TraitModel[], condition: SegmentConditionModel, segmentId: number | string, identityId: number | string): boolean;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.traitsMatchSegmentCondition = exports.evaluateIdentityInSegment = exports.getIdentitySegments = void 0;
4
+ const index_js_1 = require("../utils/hashing/index.js");
5
+ const constants_js_1 = require("./constants.js");
6
+ function getIdentitySegments(environment, identity, overrideTraits) {
7
+ return environment.project.segments.filter(segment => evaluateIdentityInSegment(identity, segment, overrideTraits));
8
+ }
9
+ exports.getIdentitySegments = getIdentitySegments;
10
+ function evaluateIdentityInSegment(identity, segment, overrideTraits) {
11
+ return (segment.rules.length > 0 &&
12
+ segment.rules.filter(rule => traitsMatchSegmentRule(overrideTraits || identity.identityTraits, rule, segment.id, identity.djangoID || identity.compositeKey)).length === segment.rules.length);
13
+ }
14
+ exports.evaluateIdentityInSegment = evaluateIdentityInSegment;
15
+ function traitsMatchSegmentRule(identityTraits, rule, segmentId, identityId) {
16
+ const matchesConditions = rule.conditions.length > 0
17
+ ? rule.matchingFunction()(rule.conditions.map(condition => traitsMatchSegmentCondition(identityTraits, condition, segmentId, identityId)))
18
+ : true;
19
+ return (matchesConditions &&
20
+ rule.rules.filter(rule => traitsMatchSegmentRule(identityTraits, rule, segmentId, identityId)).length === rule.rules.length);
21
+ }
22
+ function traitsMatchSegmentCondition(identityTraits, condition, segmentId, identityId) {
23
+ if (condition.operator == constants_js_1.PERCENTAGE_SPLIT) {
24
+ var hashedPercentage = (0, index_js_1.getHashedPercentateForObjIds)([segmentId, identityId]);
25
+ return hashedPercentage <= parseFloat(String(condition.value));
26
+ }
27
+ const traits = identityTraits.filter(t => t.traitKey === condition.property_);
28
+ const trait = traits.length > 0 ? traits[0] : undefined;
29
+ if (condition.operator === constants_js_1.IS_SET) {
30
+ return !!trait;
31
+ }
32
+ else if (condition.operator === constants_js_1.IS_NOT_SET) {
33
+ return trait == undefined;
34
+ }
35
+ return trait ? condition.matchesTraitValue(trait.traitValue) : false;
36
+ }
37
+ exports.traitsMatchSegmentCondition = traitsMatchSegmentCondition;
@@ -1,4 +1,4 @@
1
- import { FeatureStateModel } from '../features/models';
1
+ import { FeatureStateModel } from '../features/models.js';
2
2
  export declare const all: (iterable: Array<any>) => boolean;
3
3
  export declare const any: (iterable: Array<any>) => boolean;
4
4
  export declare const matchingFunctions: {