@splitsoftware/splitio 10.16.1 → 10.16.2-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGES.txt CHANGED
@@ -1,3 +1,7 @@
1
+ 10.17.0 (January XXX, 2022)
2
+ - Added Attribute binding feature to allow to optionally keep user attributes loaded within the SDK, along with the user ID, for easier usage when requesting flag.
3
+ - Bugfixing - Fixed issue returning dynamic configs if treatment name contains a dot (".")
4
+
1
5
  10.16.1 (October 25, 2021)
2
6
  - Updated some internal modules to optimize the time efficiency of split evaluations (i.e., `getTreatment(s)` method calls).
3
7
  - Updated some dependencies for vulnerability fixes (ioredis, @babel/cli, eslint, eslint-plugin-compat).
@@ -7,18 +7,19 @@ Split SDK is an open source project and we welcome feedback and contribution. Th
7
7
  ### Development process
8
8
 
9
9
  1. Fork the repository and create a topic branch from `development` branch. Please use a descriptive name for your branch.
10
- 2. While developing, use descriptive messages in your commits. Avoid short or meaningless sentences like: "fix bug".
11
- 3. Make sure to add tests for both positive and negative cases.
12
- 4. If your changes have any impact on the public API, make sure you update the TypeScript delcarations as well as it's related test file.
13
- 5. Run the linter script of the project and fix any issues you find.
14
- 6. Run the build script and make sure it runs with no errors.
15
- 7. Run all tests and make sure there are no failures.
16
- 8. Run the TypeScript declarations tests and make sure it compiles correctly.
17
- 9. `git push` your changes to GitHub within your topic branch.
18
- 10. Open a Pull Request(PR) from your forked repo and into the `development` branch of the original repository.
19
- 11. When creating your PR, please fill out all the fields of the PR template, as applicable, for the project.
20
- 12. Check for conflicts once the pull request is created to make sure your PR can be merged cleanly into `development`.
21
- 13. Keep an eye out for any feedback or comments from Split's SDK team.
10
+ 2. Run `nvm use` to ensure that you are using the right npm and node version, and `npm install` to have the dependencies up to date.
11
+ 3. While developing, use descriptive messages in your commits. Avoid short or meaningless sentences like: "fix bug".
12
+ 4. Make sure to add tests for both positive and negative cases.
13
+ 5. If your changes have any impact on the public API, make sure you update the TypeScript delcarations as well as it's related test file.
14
+ 6. Run the linter script of the project and fix any issues you find.
15
+ 7. Run the build script and make sure it runs with no errors.
16
+ 8. Run all tests and make sure there are no failures.
17
+ 9. Run the TypeScript declarations tests and make sure it compiles correctly.
18
+ 10. `git push` your changes to GitHub within your topic branch.
19
+ 11. Open a Pull Request(PR) from your forked repo and into the `development` branch of the original repository.
20
+ 12. When creating your PR, please fill out all the fields of the PR template, as applicable, for the project.
21
+ 13. Check for conflicts once the pull request is created to make sure your PR can be merged cleanly into `development`.
22
+ 14. Keep an eye out for any feedback or comments from Split's SDK team.
22
23
 
23
24
  ### Building the SDK
24
25
 
@@ -0,0 +1,116 @@
1
+ import ClientInputValidationLayer from './inputValidation';
2
+ import AttributesCacheInMemory from '../storage/AttributesCache/InMemory';
3
+ import { validateAttributesDeep } from '../utils/inputValidation/attributes';
4
+ import logFactory from '../utils/logger';
5
+ import objectAssign from 'object-assign';
6
+ var log = logFactory('splitio-client');
7
+ /**
8
+ * Add in memory attributes storage methods and combine them with any attribute received from the getTreatment/s call
9
+ */
10
+
11
+ export default function ClientAttributesDecorationLayer(context, isKeyBinded, isTTBinded) {
12
+ var client = ClientInputValidationLayer(context, isKeyBinded, isTTBinded);
13
+ var attributeStorage = new AttributesCacheInMemory(); // Keep a reference to the original methods
14
+
15
+ var clientGetTreatment = client.getTreatment;
16
+ var clientGetTreatmentWithConfig = client.getTreatmentWithConfig;
17
+ var clientGetTreatments = client.getTreatments;
18
+ var clientGetTreatmentsWithConfig = client.getTreatmentsWithConfig;
19
+ /**
20
+ * Add an attribute to client's in memory attributes storage
21
+ *
22
+ * @param {string} attributeName Attrinute name
23
+ * @param {string, number, boolean, list} attributeValue Attribute value
24
+ * @returns {boolean} true if the attribute was stored and false otherways
25
+ */
26
+
27
+ client.setAttribute = function (attributeName, attributeValue) {
28
+ var attribute = {};
29
+ attribute[attributeName] = attributeValue;
30
+ if (!validateAttributesDeep(attribute)) return false;
31
+ log.debug("stored " + attributeValue + " for attribute " + attributeName);
32
+ return attributeStorage.setAttribute(attributeName, attributeValue);
33
+ };
34
+ /**
35
+ * Returns the attribute with the given key
36
+ *
37
+ * @param {string} attributeName Attribute name
38
+ * @returns {Object} Attribute with the given key
39
+ */
40
+
41
+
42
+ client.getAttribute = function (attributeName) {
43
+ log.debug("retrieved attribute " + attributeName);
44
+ return attributeStorage.getAttribute(attributeName + '');
45
+ };
46
+ /**
47
+ * Add to client's in memory attributes storage the attributes in 'attributes'
48
+ *
49
+ * @param {Object} attributes Object with attributes to store
50
+ * @returns true if attributes were stored an false otherways
51
+ */
52
+
53
+
54
+ client.setAttributes = function (attributes) {
55
+ if (!validateAttributesDeep(attributes)) return false;
56
+ return attributeStorage.setAttributes(attributes);
57
+ };
58
+ /**
59
+ * Return all the attributes stored in client's in memory attributes storage
60
+ *
61
+ * @returns {Object} returns all the stored attributes
62
+ */
63
+
64
+
65
+ client.getAttributes = function () {
66
+ return attributeStorage.getAll();
67
+ };
68
+ /**
69
+ * Removes from client's in memory attributes storage the attribute with the given key
70
+ *
71
+ * @param {string} attributeName
72
+ * @returns {boolean} true if attribute was removed and false otherways
73
+ */
74
+
75
+
76
+ client.removeAttribute = function (attributeName) {
77
+ log.debug("removed attribute " + attributeName);
78
+ return attributeStorage.removeAttribute(attributeName + '');
79
+ };
80
+ /**
81
+ * Remove all the stored attributes in the client's in memory attribute storage
82
+ */
83
+
84
+
85
+ client.clearAttributes = function () {
86
+ return attributeStorage.clear();
87
+ };
88
+
89
+ client.getTreatment = function (maybeKey, maybeSplit, maybeAttributes) {
90
+ return clientGetTreatment(maybeKey, maybeSplit, combineAttributes(maybeAttributes));
91
+ };
92
+
93
+ client.getTreatmentWithConfig = function (maybeKey, maybeSplit, maybeAttributes) {
94
+ return clientGetTreatmentWithConfig(maybeKey, maybeSplit, combineAttributes(maybeAttributes));
95
+ };
96
+
97
+ client.getTreatments = function (maybeKey, maybeSplits, maybeAttributes) {
98
+ return clientGetTreatments(maybeKey, maybeSplits, combineAttributes(maybeAttributes));
99
+ };
100
+
101
+ client.getTreatmentsWithConfig = function (maybeKey, maybeSplits, maybeAttributes) {
102
+ return clientGetTreatmentsWithConfig(maybeKey, maybeSplits, combineAttributes(maybeAttributes));
103
+ };
104
+
105
+ function combineAttributes(maybeAttributes) {
106
+ var storedAttributes = attributeStorage.getAll();
107
+
108
+ if (Object.keys(storedAttributes).length > 0) {
109
+ return objectAssign({}, storedAttributes, maybeAttributes);
110
+ }
111
+
112
+ return maybeAttributes;
113
+ }
114
+
115
+ return client;
116
+ }
@@ -1,5 +1,5 @@
1
1
  import { get } from '../utils/lang';
2
- import ClientWithInputValidationLayer from './inputValidation';
2
+ import ClientAttributesDecorationLayer from './attributesDecoration';
3
3
  import { LOCALHOST_MODE } from '../utils/constants';
4
4
  import { validateKey, validateTrafficType } from '../utils/inputValidation';
5
5
 
@@ -25,7 +25,7 @@ function BrowserClientFactory(context) {
25
25
  trackBindings.push(tt);
26
26
  }
27
27
 
28
- var client = ClientWithInputValidationLayer(context, true, trackBindings.length > 1);
28
+ var client = ClientAttributesDecorationLayer(context, true, trackBindings.length > 1);
29
29
  client.isBrowserClient = true; // In the browser land, we can bind the key and the traffic type (if provided)
30
30
 
31
31
  client.getTreatment = client.getTreatment.bind(client, settings.core.key);
@@ -16,7 +16,6 @@ limitations under the License.
16
16
  import Engine from '../';
17
17
  import thenable from '../../utils/promise/thenable';
18
18
  import * as LabelsConstants from '../../utils/labels';
19
- import { get } from '../../utils/lang';
20
19
  import { CONTROL } from '../../utils/constants';
21
20
  var treatmentException = {
22
21
  treatment: CONTROL,
@@ -74,18 +73,18 @@ function getEvaluation(stringifiedSplit, key, attributes, storage) {
74
73
  if (stringifiedSplit) {
75
74
  var splitJSON = JSON.parse(stringifiedSplit);
76
75
  var split = Engine.parse(splitJSON, storage);
77
- evaluation = split.getTreatment(key, attributes, evaluateFeature); // If the storage is async, evaluation and changeNumber will return a thenable
76
+ evaluation = split.getTreatment(key, attributes, evaluateFeature); // If the storage is async and the evaluated split uses segment, evaluation is thenable
78
77
 
79
78
  if (thenable(evaluation)) {
80
79
  return evaluation.then(function (result) {
81
80
  result.changeNumber = split.getChangeNumber();
82
- result.config = get(splitJSON, "configurations." + result.treatment, null);
81
+ result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
83
82
  return result;
84
83
  });
85
84
  } else {
86
85
  evaluation.changeNumber = split.getChangeNumber(); // Always sync and optional
87
86
 
88
- evaluation.config = get(splitJSON, "configurations." + evaluation.treatment, null);
87
+ evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
89
88
  }
90
89
  }
91
90
 
@@ -0,0 +1,84 @@
1
+ import objectAssign from 'object-assign';
2
+
3
+ var AttributesCacheInMemory = /*#__PURE__*/function () {
4
+ function AttributesCacheInMemory() {
5
+ this.attributesCache = {};
6
+ }
7
+ /**
8
+ * Create or update the value for the given attribute
9
+ *
10
+ * @param {string} attributeName attribute name
11
+ * @param {Object} attributeValue attribute value
12
+ * @returns {boolean} the attribute was stored
13
+ */
14
+
15
+
16
+ var _proto = AttributesCacheInMemory.prototype;
17
+
18
+ _proto.setAttribute = function setAttribute(attributeName, attributeValue) {
19
+ this.attributesCache[attributeName] = attributeValue;
20
+ return true;
21
+ }
22
+ /**
23
+ * Retrieves the value of a given attribute
24
+ *
25
+ * @param {string} attributeName attribute name
26
+ * @returns {Object?} stored attribute value
27
+ */
28
+ ;
29
+
30
+ _proto.getAttribute = function getAttribute(attributeName) {
31
+ return this.attributesCache[attributeName];
32
+ }
33
+ /**
34
+ * Create or update all the given attributes
35
+ *
36
+ * @param {[string, Object]} attributes attributes to create or update
37
+ * @returns {boolean} attributes were stored
38
+ */
39
+ ;
40
+
41
+ _proto.setAttributes = function setAttributes(attributes) {
42
+ this.attributesCache = objectAssign(this.attributesCache, attributes);
43
+ return true;
44
+ }
45
+ /**
46
+ * Retrieve the full attributes map
47
+ *
48
+ * @returns {Map<string, Object>} stored attributes
49
+ */
50
+ ;
51
+
52
+ _proto.getAll = function getAll() {
53
+ return this.attributesCache;
54
+ }
55
+ /**
56
+ * Removes a given attribute from the map
57
+ *
58
+ * @param {string} attributeName attribute to remove
59
+ * @returns {boolean} attribute removed
60
+ */
61
+ ;
62
+
63
+ _proto.removeAttribute = function removeAttribute(attributeName) {
64
+ if (Object.keys(this.attributesCache).indexOf(attributeName) >= 0) {
65
+ delete this.attributesCache[attributeName];
66
+ return true;
67
+ }
68
+
69
+ return false;
70
+ }
71
+ /**
72
+ * Clears all attributes stored in the SDK
73
+ *
74
+ */
75
+ ;
76
+
77
+ _proto.clear = function clear() {
78
+ this.attributesCache = {};
79
+ };
80
+
81
+ return AttributesCacheInMemory;
82
+ }();
83
+
84
+ export default AttributesCacheInMemory;
@@ -0,0 +1,22 @@
1
+ import { isString, numberIsFinite, isBoolean } from '../lang';
2
+ import logFactory from '../logger';
3
+ var log = logFactory('');
4
+ export function validateAttribute(attributeKey, attributeValue, method) {
5
+ if (!isString(attributeKey) || attributeKey.length === 0) {
6
+ log.warn(method + ": you passed an invalid attribute name, attribute name must be a non-empty string.");
7
+ return false;
8
+ }
9
+
10
+ var isStringVal = isString(attributeValue);
11
+ var isFiniteVal = numberIsFinite(attributeValue);
12
+ var isBoolVal = isBoolean(attributeValue);
13
+ var isArrayVal = Array.isArray(attributeValue);
14
+
15
+ if (!(isStringVal || isFiniteVal || isBoolVal || isArrayVal)) {
16
+ // If it's not of valid type.
17
+ log.warn(method + ": you passed an invalid attribute value for " + attributeKey + ". Acceptable types are: string, number, boolean and array of strings.");
18
+ return false;
19
+ }
20
+
21
+ return true;
22
+ }
@@ -1,5 +1,6 @@
1
1
  import { isObject } from '../lang';
2
2
  import logFactory from '../logger';
3
+ import { validateAttribute } from './attribute';
3
4
  var log = logFactory('');
4
5
  export function validateAttributes(maybeAttrs, method) {
5
6
  // Attributes are optional
@@ -7,4 +8,12 @@ export function validateAttributes(maybeAttrs, method) {
7
8
  return maybeAttrs;
8
9
  log.error(method + ": attributes must be a plain object.");
9
10
  return false;
11
+ }
12
+ export function validateAttributesDeep(maybeAttributes, method) {
13
+ if (!validateAttributes(maybeAttributes, method)) return false;
14
+ var result = true;
15
+ Object.keys(maybeAttributes).forEach(function (attributeKey) {
16
+ if (!validateAttribute(attributeKey, maybeAttributes[attributeKey], method)) result = false;
17
+ });
18
+ return result;
10
19
  }
@@ -25,7 +25,7 @@ import validateSplitFilters from '../inputValidation/splitFilters';
25
25
  import { API } from '../../utils/logger';
26
26
  import { STANDALONE_MODE, STORAGE_MEMORY, CONSUMER_MODE, OPTIMIZED } from '../../utils/constants';
27
27
  import validImpressionsMode from './impressionsMode';
28
- var version = '10.16.1';
28
+ var version = '10.16.2-rc.0';
29
29
  var eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
30
30
  var authEndpointMatcher = /^\/v2\/auth/;
31
31
  var streamingEndpointMatcher = /^\/(sse|event-stream)/;
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.default = ClientAttributesDecorationLayer;
7
+
8
+ var _inputValidation = _interopRequireDefault(require("./inputValidation"));
9
+
10
+ var _InMemory = _interopRequireDefault(require("../storage/AttributesCache/InMemory"));
11
+
12
+ var _attributes = require("../utils/inputValidation/attributes");
13
+
14
+ var _logger = _interopRequireDefault(require("../utils/logger"));
15
+
16
+ var _objectAssign = _interopRequireDefault(require("object-assign"));
17
+
18
+ var log = (0, _logger.default)('splitio-client');
19
+ /**
20
+ * Add in memory attributes storage methods and combine them with any attribute received from the getTreatment/s call
21
+ */
22
+
23
+ function ClientAttributesDecorationLayer(context, isKeyBinded, isTTBinded) {
24
+ var client = (0, _inputValidation.default)(context, isKeyBinded, isTTBinded);
25
+ var attributeStorage = new _InMemory.default(); // Keep a reference to the original methods
26
+
27
+ var clientGetTreatment = client.getTreatment;
28
+ var clientGetTreatmentWithConfig = client.getTreatmentWithConfig;
29
+ var clientGetTreatments = client.getTreatments;
30
+ var clientGetTreatmentsWithConfig = client.getTreatmentsWithConfig;
31
+ /**
32
+ * Add an attribute to client's in memory attributes storage
33
+ *
34
+ * @param {string} attributeName Attrinute name
35
+ * @param {string, number, boolean, list} attributeValue Attribute value
36
+ * @returns {boolean} true if the attribute was stored and false otherways
37
+ */
38
+
39
+ client.setAttribute = function (attributeName, attributeValue) {
40
+ var attribute = {};
41
+ attribute[attributeName] = attributeValue;
42
+ if (!(0, _attributes.validateAttributesDeep)(attribute)) return false;
43
+ log.debug("stored " + attributeValue + " for attribute " + attributeName);
44
+ return attributeStorage.setAttribute(attributeName, attributeValue);
45
+ };
46
+ /**
47
+ * Returns the attribute with the given key
48
+ *
49
+ * @param {string} attributeName Attribute name
50
+ * @returns {Object} Attribute with the given key
51
+ */
52
+
53
+
54
+ client.getAttribute = function (attributeName) {
55
+ log.debug("retrieved attribute " + attributeName);
56
+ return attributeStorage.getAttribute(attributeName + '');
57
+ };
58
+ /**
59
+ * Add to client's in memory attributes storage the attributes in 'attributes'
60
+ *
61
+ * @param {Object} attributes Object with attributes to store
62
+ * @returns true if attributes were stored an false otherways
63
+ */
64
+
65
+
66
+ client.setAttributes = function (attributes) {
67
+ if (!(0, _attributes.validateAttributesDeep)(attributes)) return false;
68
+ return attributeStorage.setAttributes(attributes);
69
+ };
70
+ /**
71
+ * Return all the attributes stored in client's in memory attributes storage
72
+ *
73
+ * @returns {Object} returns all the stored attributes
74
+ */
75
+
76
+
77
+ client.getAttributes = function () {
78
+ return attributeStorage.getAll();
79
+ };
80
+ /**
81
+ * Removes from client's in memory attributes storage the attribute with the given key
82
+ *
83
+ * @param {string} attributeName
84
+ * @returns {boolean} true if attribute was removed and false otherways
85
+ */
86
+
87
+
88
+ client.removeAttribute = function (attributeName) {
89
+ log.debug("removed attribute " + attributeName);
90
+ return attributeStorage.removeAttribute(attributeName + '');
91
+ };
92
+ /**
93
+ * Remove all the stored attributes in the client's in memory attribute storage
94
+ */
95
+
96
+
97
+ client.clearAttributes = function () {
98
+ return attributeStorage.clear();
99
+ };
100
+
101
+ client.getTreatment = function (maybeKey, maybeSplit, maybeAttributes) {
102
+ return clientGetTreatment(maybeKey, maybeSplit, combineAttributes(maybeAttributes));
103
+ };
104
+
105
+ client.getTreatmentWithConfig = function (maybeKey, maybeSplit, maybeAttributes) {
106
+ return clientGetTreatmentWithConfig(maybeKey, maybeSplit, combineAttributes(maybeAttributes));
107
+ };
108
+
109
+ client.getTreatments = function (maybeKey, maybeSplits, maybeAttributes) {
110
+ return clientGetTreatments(maybeKey, maybeSplits, combineAttributes(maybeAttributes));
111
+ };
112
+
113
+ client.getTreatmentsWithConfig = function (maybeKey, maybeSplits, maybeAttributes) {
114
+ return clientGetTreatmentsWithConfig(maybeKey, maybeSplits, combineAttributes(maybeAttributes));
115
+ };
116
+
117
+ function combineAttributes(maybeAttributes) {
118
+ var storedAttributes = attributeStorage.getAll();
119
+
120
+ if (Object.keys(storedAttributes).length > 0) {
121
+ return (0, _objectAssign.default)({}, storedAttributes, maybeAttributes);
122
+ }
123
+
124
+ return maybeAttributes;
125
+ }
126
+
127
+ return client;
128
+ }
@@ -7,11 +7,11 @@ exports.default = void 0;
7
7
 
8
8
  var _lang = require("../utils/lang");
9
9
 
10
- var _inputValidation = _interopRequireDefault(require("./inputValidation"));
10
+ var _attributesDecoration = _interopRequireDefault(require("./attributesDecoration"));
11
11
 
12
12
  var _constants = require("../utils/constants");
13
13
 
14
- var _inputValidation2 = require("../utils/inputValidation");
14
+ var _inputValidation = require("../utils/inputValidation");
15
15
 
16
16
  function BrowserClientFactory(context) {
17
17
  var _client$track;
@@ -23,19 +23,19 @@ function BrowserClientFactory(context) {
23
23
  if (settings.mode === _constants.LOCALHOST_MODE && maybeKey === undefined) {
24
24
  settings.core.key = 'localhost_key';
25
25
  } else {
26
- settings.core.key = (0, _inputValidation2.validateKey)(maybeKey, 'Client instantiation');
26
+ settings.core.key = (0, _inputValidation.validateKey)(maybeKey, 'Client instantiation');
27
27
  } // Key is also binded to the .track method. Same thing happens with trafficType but only if present on configs. (not required)
28
28
 
29
29
 
30
30
  var trackBindings = [settings.core.key];
31
31
 
32
32
  if (maybeTT !== undefined) {
33
- var tt = (0, _inputValidation2.validateTrafficType)(maybeTT, 'Client instantiation');
33
+ var tt = (0, _inputValidation.validateTrafficType)(maybeTT, 'Client instantiation');
34
34
  settings.core.trafficType = tt;
35
35
  trackBindings.push(tt);
36
36
  }
37
37
 
38
- var client = (0, _inputValidation.default)(context, true, trackBindings.length > 1);
38
+ var client = (0, _attributesDecoration.default)(context, true, trackBindings.length > 1);
39
39
  client.isBrowserClient = true; // In the browser land, we can bind the key and the traffic type (if provided)
40
40
 
41
41
  client.getTreatment = client.getTreatment.bind(client, settings.core.key);
@@ -14,8 +14,6 @@ var _thenable = _interopRequireDefault(require("../../utils/promise/thenable"));
14
14
 
15
15
  var LabelsConstants = _interopRequireWildcard(require("../../utils/labels"));
16
16
 
17
- var _lang = require("../../utils/lang");
18
-
19
17
  var _constants = require("../../utils/constants");
20
18
 
21
19
  /**
@@ -93,18 +91,18 @@ function getEvaluation(stringifiedSplit, key, attributes, storage) {
93
91
 
94
92
  var split = _.default.parse(splitJSON, storage);
95
93
 
96
- evaluation = split.getTreatment(key, attributes, evaluateFeature); // If the storage is async, evaluation and changeNumber will return a thenable
94
+ evaluation = split.getTreatment(key, attributes, evaluateFeature); // If the storage is async and the evaluated split uses segment, evaluation is thenable
97
95
 
98
96
  if ((0, _thenable.default)(evaluation)) {
99
97
  return evaluation.then(function (result) {
100
98
  result.changeNumber = split.getChangeNumber();
101
- result.config = (0, _lang.get)(splitJSON, "configurations." + result.treatment, null);
99
+ result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
102
100
  return result;
103
101
  });
104
102
  } else {
105
103
  evaluation.changeNumber = split.getChangeNumber(); // Always sync and optional
106
104
 
107
- evaluation.config = (0, _lang.get)(splitJSON, "configurations." + evaluation.treatment, null);
105
+ evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
108
106
  }
109
107
  }
110
108
 
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.default = void 0;
7
+
8
+ var _objectAssign = _interopRequireDefault(require("object-assign"));
9
+
10
+ var AttributesCacheInMemory = /*#__PURE__*/function () {
11
+ function AttributesCacheInMemory() {
12
+ this.attributesCache = {};
13
+ }
14
+ /**
15
+ * Create or update the value for the given attribute
16
+ *
17
+ * @param {string} attributeName attribute name
18
+ * @param {Object} attributeValue attribute value
19
+ * @returns {boolean} the attribute was stored
20
+ */
21
+
22
+
23
+ var _proto = AttributesCacheInMemory.prototype;
24
+
25
+ _proto.setAttribute = function setAttribute(attributeName, attributeValue) {
26
+ this.attributesCache[attributeName] = attributeValue;
27
+ return true;
28
+ }
29
+ /**
30
+ * Retrieves the value of a given attribute
31
+ *
32
+ * @param {string} attributeName attribute name
33
+ * @returns {Object?} stored attribute value
34
+ */
35
+ ;
36
+
37
+ _proto.getAttribute = function getAttribute(attributeName) {
38
+ return this.attributesCache[attributeName];
39
+ }
40
+ /**
41
+ * Create or update all the given attributes
42
+ *
43
+ * @param {[string, Object]} attributes attributes to create or update
44
+ * @returns {boolean} attributes were stored
45
+ */
46
+ ;
47
+
48
+ _proto.setAttributes = function setAttributes(attributes) {
49
+ this.attributesCache = (0, _objectAssign.default)(this.attributesCache, attributes);
50
+ return true;
51
+ }
52
+ /**
53
+ * Retrieve the full attributes map
54
+ *
55
+ * @returns {Map<string, Object>} stored attributes
56
+ */
57
+ ;
58
+
59
+ _proto.getAll = function getAll() {
60
+ return this.attributesCache;
61
+ }
62
+ /**
63
+ * Removes a given attribute from the map
64
+ *
65
+ * @param {string} attributeName attribute to remove
66
+ * @returns {boolean} attribute removed
67
+ */
68
+ ;
69
+
70
+ _proto.removeAttribute = function removeAttribute(attributeName) {
71
+ if (Object.keys(this.attributesCache).indexOf(attributeName) >= 0) {
72
+ delete this.attributesCache[attributeName];
73
+ return true;
74
+ }
75
+
76
+ return false;
77
+ }
78
+ /**
79
+ * Clears all attributes stored in the SDK
80
+ *
81
+ */
82
+ ;
83
+
84
+ _proto.clear = function clear() {
85
+ this.attributesCache = {};
86
+ };
87
+
88
+ return AttributesCacheInMemory;
89
+ }();
90
+
91
+ var _default = AttributesCacheInMemory;
92
+ exports.default = _default;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ exports.__esModule = true;
6
+ exports.validateAttribute = validateAttribute;
7
+
8
+ var _lang = require("../lang");
9
+
10
+ var _logger = _interopRequireDefault(require("../logger"));
11
+
12
+ var log = (0, _logger.default)('');
13
+
14
+ function validateAttribute(attributeKey, attributeValue, method) {
15
+ if (!(0, _lang.isString)(attributeKey) || attributeKey.length === 0) {
16
+ log.warn(method + ": you passed an invalid attribute name, attribute name must be a non-empty string.");
17
+ return false;
18
+ }
19
+
20
+ var isStringVal = (0, _lang.isString)(attributeValue);
21
+ var isFiniteVal = (0, _lang.numberIsFinite)(attributeValue);
22
+ var isBoolVal = (0, _lang.isBoolean)(attributeValue);
23
+ var isArrayVal = Array.isArray(attributeValue);
24
+
25
+ if (!(isStringVal || isFiniteVal || isBoolVal || isArrayVal)) {
26
+ // If it's not of valid type.
27
+ log.warn(method + ": you passed an invalid attribute value for " + attributeKey + ". Acceptable types are: string, number, boolean and array of strings.");
28
+ return false;
29
+ }
30
+
31
+ return true;
32
+ }