@kameleoon/javascript-sdk-core 1.1.1 → 2.0.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 (138) hide show
  1. package/dist/campaignConfiguration/campaignConfiguration.d.ts +2 -1
  2. package/dist/campaignConfiguration/campaignConfiguration.js +239 -197
  3. package/dist/campaignConfiguration/campaignConfiguration.js.map +1 -1
  4. package/dist/campaignConfiguration/constants.js +20 -14
  5. package/dist/campaignConfiguration/constants.js.map +1 -1
  6. package/dist/campaignConfiguration/index.js +78 -6
  7. package/dist/campaignConfiguration/index.js.map +1 -1
  8. package/dist/campaignConfiguration/types.d.ts +3 -2
  9. package/dist/campaignConfiguration/types.js +53 -45
  10. package/dist/campaignConfiguration/types.js.map +1 -1
  11. package/dist/clientSettings/clientSettings.d.ts +1 -1
  12. package/dist/clientSettings/clientSettings.js +28 -21
  13. package/dist/clientSettings/clientSettings.js.map +1 -1
  14. package/dist/clientSettings/index.js +18 -4
  15. package/dist/clientSettings/index.js.map +1 -1
  16. package/dist/clientSettings/types.d.ts +1 -1
  17. package/dist/clientSettings/types.js +4 -1
  18. package/dist/clientSettings/types.js.map +1 -1
  19. package/dist/constants.js +22 -14
  20. package/dist/constants.js.map +1 -1
  21. package/dist/eventSource/constants.js +6 -2
  22. package/dist/eventSource/constants.js.map +1 -1
  23. package/dist/eventSource/externalEventSource.js +28 -20
  24. package/dist/eventSource/externalEventSource.js.map +1 -1
  25. package/dist/eventSource/index.js +49 -6
  26. package/dist/eventSource/index.js.map +1 -1
  27. package/dist/eventSource/types.d.ts +1 -1
  28. package/dist/eventSource/types.js +4 -1
  29. package/dist/eventSource/types.js.map +1 -1
  30. package/dist/hasher/constants.js +6 -2
  31. package/dist/hasher/constants.js.map +1 -1
  32. package/dist/hasher/hasher.js +35 -24
  33. package/dist/hasher/hasher.js.map +1 -1
  34. package/dist/hasher/index.js +11 -4
  35. package/dist/hasher/index.js.map +1 -1
  36. package/dist/hasher/types.js +4 -1
  37. package/dist/hasher/types.js.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +297 -28
  40. package/dist/index.js.map +1 -1
  41. package/dist/kameleoonClient.d.ts +16 -16
  42. package/dist/kameleoonClient.js +307 -236
  43. package/dist/kameleoonClient.js.map +1 -1
  44. package/dist/kameleoonData/browser.js +37 -32
  45. package/dist/kameleoonData/browser.js.map +1 -1
  46. package/dist/kameleoonData/constants.js +6 -2
  47. package/dist/kameleoonData/constants.js.map +1 -1
  48. package/dist/kameleoonData/conversion.js +47 -40
  49. package/dist/kameleoonData/conversion.js.map +1 -1
  50. package/dist/kameleoonData/customData.js +62 -58
  51. package/dist/kameleoonData/customData.js.map +1 -1
  52. package/dist/kameleoonData/device.js +37 -32
  53. package/dist/kameleoonData/device.js.map +1 -1
  54. package/dist/kameleoonData/index.js +101 -18
  55. package/dist/kameleoonData/index.js.map +1 -1
  56. package/dist/kameleoonData/nonce.js +25 -13
  57. package/dist/kameleoonData/nonce.js.map +1 -1
  58. package/dist/kameleoonData/pageView.js +52 -44
  59. package/dist/kameleoonData/pageView.js.map +1 -1
  60. package/dist/kameleoonData/types.js +41 -26
  61. package/dist/kameleoonData/types.js.map +1 -1
  62. package/dist/kameleoonData/userAgent.js +33 -24
  63. package/dist/kameleoonData/userAgent.js.map +1 -1
  64. package/dist/kameleoonError/constants.js +25 -21
  65. package/dist/kameleoonError/constants.js.map +1 -1
  66. package/dist/kameleoonError/helpers.js +6 -4
  67. package/dist/kameleoonError/helpers.js.map +1 -1
  68. package/dist/kameleoonError/index.js +25 -8
  69. package/dist/kameleoonError/index.js.map +1 -1
  70. package/dist/kameleoonError/kameleoonError.js +64 -53
  71. package/dist/kameleoonError/kameleoonError.js.map +1 -1
  72. package/dist/kameleoonError/types.js +26 -22
  73. package/dist/kameleoonError/types.js.map +1 -1
  74. package/dist/kameleoonUtils.js +34 -33
  75. package/dist/kameleoonUtils.js.map +1 -1
  76. package/dist/requester/constants.d.ts +6 -7
  77. package/dist/requester/constants.js +58 -45
  78. package/dist/requester/constants.js.map +1 -1
  79. package/dist/requester/index.d.ts +2 -2
  80. package/dist/requester/index.js +67 -8
  81. package/dist/requester/index.js.map +1 -1
  82. package/dist/requester/requester.d.ts +7 -7
  83. package/dist/requester/requester.js +100 -113
  84. package/dist/requester/requester.js.map +1 -1
  85. package/dist/requester/types.d.ts +38 -10
  86. package/dist/requester/types.js +14 -36
  87. package/dist/requester/types.js.map +1 -1
  88. package/dist/storage/constants.js +11 -7
  89. package/dist/storage/constants.js.map +1 -1
  90. package/dist/storage/externalStorage.js +33 -26
  91. package/dist/storage/externalStorage.js.map +1 -1
  92. package/dist/storage/index.js +55 -6
  93. package/dist/storage/index.js.map +1 -1
  94. package/dist/storage/types.js +4 -1
  95. package/dist/storage/types.js.map +1 -1
  96. package/dist/targeting/conditions/conditionFactory.js +24 -19
  97. package/dist/targeting/conditions/conditionFactory.js.map +1 -1
  98. package/dist/targeting/conditions/customDataCondition.js +99 -88
  99. package/dist/targeting/conditions/customDataCondition.js.map +1 -1
  100. package/dist/targeting/conditions/exclusiveExperimentCondition.js +27 -15
  101. package/dist/targeting/conditions/exclusiveExperimentCondition.js.map +1 -1
  102. package/dist/targeting/conditions/index.js +45 -10
  103. package/dist/targeting/conditions/index.js.map +1 -1
  104. package/dist/targeting/conditions/targetExperimentCondition.js +54 -32
  105. package/dist/targeting/conditions/targetExperimentCondition.js.map +1 -1
  106. package/dist/targeting/conditions/types.js +4 -1
  107. package/dist/targeting/conditions/types.js.map +1 -1
  108. package/dist/targeting/index.js +79 -13
  109. package/dist/targeting/index.js.map +1 -1
  110. package/dist/targeting/targetingNode.js +41 -33
  111. package/dist/targeting/targetingNode.js.map +1 -1
  112. package/dist/targeting/targetingTree.js +125 -104
  113. package/dist/targeting/targetingTree.js.map +1 -1
  114. package/dist/targeting/types.js +99 -91
  115. package/dist/targeting/types.js.map +1 -1
  116. package/dist/types.d.ts +17 -2
  117. package/dist/types.js +50 -21
  118. package/dist/types.js.map +1 -1
  119. package/dist/utilities/constants.js +6 -2
  120. package/dist/utilities/constants.js.map +1 -1
  121. package/dist/utilities/index.js +11 -4
  122. package/dist/utilities/index.js.map +1 -1
  123. package/dist/utilities/types.d.ts +1 -1
  124. package/dist/utilities/types.js +4 -1
  125. package/dist/utilities/types.js.map +1 -1
  126. package/dist/utilities/utilities.d.ts +2 -2
  127. package/dist/utilities/utilities.js +117 -105
  128. package/dist/utilities/utilities.js.map +1 -1
  129. package/dist/variationConfiguration/index.js +24 -4
  130. package/dist/variationConfiguration/index.js.map +1 -1
  131. package/dist/variationConfiguration/types.js +4 -1
  132. package/dist/variationConfiguration/types.js.map +1 -1
  133. package/dist/variationConfiguration/variation.js +35 -28
  134. package/dist/variationConfiguration/variation.js.map +1 -1
  135. package/dist/variationConfiguration/variationConfiguration.d.ts +5 -5
  136. package/dist/variationConfiguration/variationConfiguration.js +270 -228
  137. package/dist/variationConfiguration/variationConfiguration.js.map +1 -1
  138. package/package.json +6 -4
@@ -1,42 +1,64 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
3
6
  exports.TargetExperimentCondition = void 0;
4
- const ts_res_1 = require("ts-res");
5
- const types_1 = require("../types");
7
+ var _tsRes = require("ts-res");
8
+ var _types = require("../types");
9
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
10
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
11
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
12
  class TargetExperimentCondition {
7
- constructor({ variation, experiment, isInclude, variationMatchType, }) {
8
- this.inverseResult = !(isInclude !== null && isInclude !== void 0 ? isInclude : true);
9
- this.experimentId = experiment;
10
- this.variationId = variation;
11
- this.matchType = variationMatchType;
13
+ constructor({
14
+ variation,
15
+ experiment,
16
+ isInclude,
17
+ variationMatchType
18
+ }) {
19
+ _defineProperty(this, "inverseResult", void 0);
20
+ _defineProperty(this, "experimentId", void 0);
21
+ _defineProperty(this, "variationId", void 0);
22
+ _defineProperty(this, "matchType", void 0);
23
+ this.inverseResult = !(isInclude ?? true);
24
+ this.experimentId = experiment;
25
+ this.variationId = variation;
26
+ this.matchType = variationMatchType;
27
+ }
28
+ evaluate({
29
+ variationData
30
+ }) {
31
+ if (!this.experimentId) {
32
+ return (0, _tsRes.Ok)(false);
12
33
  }
13
- evaluate({ variationData, }) {
14
- if (!this.experimentId) {
15
- return (0, ts_res_1.Ok)(false);
16
- }
17
- if (this.matchType === types_1.MatchTypeVariation.EXACT && !this.variationId) {
18
- (0, ts_res_1.Ok)(false);
19
- }
20
- const result = this.checkCondition({
21
- variationId: this.variationId,
22
- experimentId: this.experimentId,
23
- variationData,
24
- });
25
- return (0, ts_res_1.Ok)(this.inverseResult ? !result : result);
34
+ if (this.matchType === _types.MatchTypeVariation.EXACT && !this.variationId) {
35
+ (0, _tsRes.Ok)(false);
26
36
  }
27
- checkCondition({ variationId, experimentId, variationData, }) {
28
- const experimentIdString = String(experimentId);
29
- const variation = variationData[experimentIdString];
30
- switch (this.matchType) {
31
- case types_1.MatchTypeVariation.EXACT: {
32
- return (variation === null || variation === void 0 ? void 0 : variation.variationId) === variationId;
33
- }
34
- case types_1.MatchTypeVariation.ANY:
35
- return Boolean(variation);
36
- default:
37
- return false;
37
+ const result = this.checkCondition({
38
+ variationId: this.variationId,
39
+ experimentId: this.experimentId,
40
+ variationData
41
+ });
42
+ return (0, _tsRes.Ok)(this.inverseResult ? !result : result);
43
+ }
44
+ checkCondition({
45
+ variationId,
46
+ experimentId,
47
+ variationData
48
+ }) {
49
+ const experimentIdString = String(experimentId);
50
+ const variation = variationData[experimentIdString];
51
+ switch (this.matchType) {
52
+ case _types.MatchTypeVariation.EXACT:
53
+ {
54
+ return variation?.variationId === variationId;
38
55
  }
56
+ case _types.MatchTypeVariation.ANY:
57
+ return Boolean(variation);
58
+ default:
59
+ return false;
39
60
  }
61
+ }
40
62
  }
41
63
  exports.TargetExperimentCondition = TargetExperimentCondition;
42
64
  //# sourceMappingURL=targetExperimentCondition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"targetExperimentCondition.js","sourceRoot":"","sources":["../../../src/targeting/conditions/targetExperimentCondition.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AAGpC,oCAAkE;AAGlE,MAAa,yBAAyB;IAMpC,YAAY,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,kBAAkB,GACA;QAClB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,kBAAkB,CAAC;IACtC,CAAC;IAED,QAAQ,CAAC,EACP,aAAa,GACM;QACnB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,OAAO,IAAA,WAAE,EAAC,KAAK,CAAC,CAAC;SAClB;QAED,IAAI,IAAI,CAAC,SAAS,KAAK,0BAAkB,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YACpE,IAAA,WAAE,EAAC,KAAK,CAAC,CAAC;SACX;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC;YACjC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,aAAa;SACd,CAAC,CAAC;QAEH,OAAO,IAAA,WAAE,EAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAEO,cAAc,CAAC,EACrB,WAAW,EACX,YAAY,EACZ,aAAa,GAKd;QACC,MAAM,kBAAkB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAEpD,QAAQ,IAAI,CAAC,SAAS,EAAE;YACtB,KAAK,0BAAkB,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,MAAK,WAAW,CAAC;aAC/C;YACD,KAAK,0BAAkB,CAAC,GAAG;gBACzB,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;YAC5B;gBACE,OAAO,KAAK,CAAC;SAChB;IACH,CAAC;CACF;AA5DD,8DA4DC"}
1
+ {"version":3,"file":"targetExperimentCondition.js","names":["_tsRes","require","_types","_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","arg","_toPrimitive","String","input","hint","prim","Symbol","toPrimitive","undefined","res","call","TypeError","Number","TargetExperimentCondition","constructor","variation","experiment","isInclude","variationMatchType","inverseResult","experimentId","variationId","matchType","evaluate","variationData","Ok","MatchTypeVariation","EXACT","result","checkCondition","experimentIdString","ANY","Boolean","exports"],"sources":["../../../src/targeting/conditions/targetExperimentCondition.ts"],"sourcesContent":["import { Ok, Result } from 'ts-res';\nimport { KameleoonError } from '../../kameleoonError';\nimport { ExperimentVariationsType } from '../../storage';\nimport { EvaluationDataType, MatchTypeVariation } from '../types';\nimport { ConditionDataType, ICondition } from './types';\n\nexport class TargetExperimentCondition implements ICondition {\n private inverseResult: boolean;\n private experimentId?: number | null;\n private variationId?: number | null;\n private matchType?: MatchTypeVariation | null;\n\n constructor({\n variation,\n experiment,\n isInclude,\n variationMatchType,\n }: ConditionDataType) {\n this.inverseResult = !(isInclude ?? true);\n this.experimentId = experiment;\n this.variationId = variation;\n this.matchType = variationMatchType;\n }\n\n evaluate({\n variationData,\n }: EvaluationDataType): Result<boolean, KameleoonError> {\n if (!this.experimentId) {\n return Ok(false);\n }\n\n if (this.matchType === MatchTypeVariation.EXACT && !this.variationId) {\n Ok(false);\n }\n\n const result = this.checkCondition({\n variationId: this.variationId,\n experimentId: this.experimentId,\n variationData,\n });\n\n return Ok(this.inverseResult ? !result : result);\n }\n\n private checkCondition({\n variationId,\n experimentId,\n variationData,\n }: {\n variationId?: number | null;\n experimentId: number;\n variationData: ExperimentVariationsType;\n }): boolean {\n const experimentIdString = String(experimentId);\n const variation = variationData[experimentIdString];\n\n switch (this.matchType) {\n case MatchTypeVariation.EXACT: {\n return variation?.variationId === variationId;\n }\n case MatchTypeVariation.ANY:\n return Boolean(variation);\n default:\n return false;\n }\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAGA,IAAAC,MAAA,GAAAD,OAAA;AAAkE,SAAAE,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,KAAA,IAAAD,GAAA,GAAAE,cAAA,CAAAF,GAAA,OAAAA,GAAA,IAAAD,GAAA,IAAAI,MAAA,CAAAC,cAAA,CAAAL,GAAA,EAAAC,GAAA,IAAAC,KAAA,EAAAA,KAAA,EAAAI,UAAA,QAAAC,YAAA,QAAAC,QAAA,oBAAAR,GAAA,CAAAC,GAAA,IAAAC,KAAA,WAAAF,GAAA;AAAA,SAAAG,eAAAM,GAAA,QAAAR,GAAA,GAAAS,YAAA,CAAAD,GAAA,2BAAAR,GAAA,gBAAAA,GAAA,GAAAU,MAAA,CAAAV,GAAA;AAAA,SAAAS,aAAAE,KAAA,EAAAC,IAAA,eAAAD,KAAA,iBAAAA,KAAA,kBAAAA,KAAA,MAAAE,IAAA,GAAAF,KAAA,CAAAG,MAAA,CAAAC,WAAA,OAAAF,IAAA,KAAAG,SAAA,QAAAC,GAAA,GAAAJ,IAAA,CAAAK,IAAA,CAAAP,KAAA,EAAAC,IAAA,2BAAAK,GAAA,sBAAAA,GAAA,YAAAE,SAAA,4DAAAP,IAAA,gBAAAF,MAAA,GAAAU,MAAA,EAAAT,KAAA;AAG3D,MAAMU,yBAAyB,CAAuB;EAM3DC,WAAWA,CAAC;IACVC,SAAS;IACTC,UAAU;IACVC,SAAS;IACTC;EACiB,CAAC,EAAE;IAAA5B,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IACpB,IAAI,CAAC6B,aAAa,GAAG,EAAEF,SAAS,IAAI,IAAI,CAAC;IACzC,IAAI,CAACG,YAAY,GAAGJ,UAAU;IAC9B,IAAI,CAACK,WAAW,GAAGN,SAAS;IAC5B,IAAI,CAACO,SAAS,GAAGJ,kBAAkB;EACrC;EAEAK,QAAQA,CAAC;IACPC;EACkB,CAAC,EAAmC;IACtD,IAAI,CAAC,IAAI,CAACJ,YAAY,EAAE;MACtB,OAAO,IAAAK,SAAE,EAAC,KAAK,CAAC;IAClB;IAEA,IAAI,IAAI,CAACH,SAAS,KAAKI,yBAAkB,CAACC,KAAK,IAAI,CAAC,IAAI,CAACN,WAAW,EAAE;MACpE,IAAAI,SAAE,EAAC,KAAK,CAAC;IACX;IAEA,MAAMG,MAAM,GAAG,IAAI,CAACC,cAAc,CAAC;MACjCR,WAAW,EAAE,IAAI,CAACA,WAAW;MAC7BD,YAAY,EAAE,IAAI,CAACA,YAAY;MAC/BI;IACF,CAAC,CAAC;IAEF,OAAO,IAAAC,SAAE,EAAC,IAAI,CAACN,aAAa,GAAG,CAACS,MAAM,GAAGA,MAAM,CAAC;EAClD;EAEQC,cAAcA,CAAC;IACrBR,WAAW;IACXD,YAAY;IACZI;EAKF,CAAC,EAAW;IACV,MAAMM,kBAAkB,GAAG5B,MAAM,CAACkB,YAAY,CAAC;IAC/C,MAAML,SAAS,GAAGS,aAAa,CAACM,kBAAkB,CAAC;IAEnD,QAAQ,IAAI,CAACR,SAAS;MACpB,KAAKI,yBAAkB,CAACC,KAAK;QAAE;UAC7B,OAAOZ,SAAS,EAAEM,WAAW,KAAKA,WAAW;QAC/C;MACA,KAAKK,yBAAkB,CAACK,GAAG;QACzB,OAAOC,OAAO,CAACjB,SAAS,CAAC;MAC3B;QACE,OAAO,KAAK;IAAC;EAEnB;AACF;AAACkB,OAAA,CAAApB,yBAAA,GAAAA,yBAAA"}
@@ -1,3 +1,6 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
3
6
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/targeting/conditions/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/targeting/conditions/types.ts"],"sourcesContent":["import { Result } from 'ts-res';\nimport { KameleoonError } from '../../kameleoonError';\nimport {\n EvaluationDataType,\n MatchTypeCustomData,\n MatchTypeTest,\n MatchTypeVariation,\n TargetingType,\n} from '../types';\nimport { CustomDataCondition } from './customDataCondition';\nimport { ExclusiveExperimentCondition } from './exclusiveExperimentCondition';\nimport { TargetExperimentCondition } from './targetExperimentCondition';\n\nexport interface ICondition {\n evaluate: (data: EvaluationDataType) => Result<boolean, KameleoonError>;\n}\n\nexport type ConditionType =\n | CustomDataCondition\n | ExclusiveExperimentCondition\n | TargetExperimentCondition;\n\nexport type ConditionDataType = {\n id: number;\n targetingType: TargetingType;\n isInclude: boolean | null;\n weight: number;\n customDataIndex: string | null;\n value: string | null;\n valueMatchType: MatchTypeCustomData | null;\n experiment?: number | null;\n variation?: number | null;\n variationMatchType?: MatchTypeVariation | null;\n testMatchType?: MatchTypeTest | null;\n};\n"],"mappings":""}
@@ -1,15 +1,81 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExclusiveExperimentCondition = exports.TargetExperimentCondition = exports.CustomDataCondition = exports.MatchTypeVariation = exports.MatchTypeCustomData = exports.TargetingType = exports.Operator = exports.TargetingTree = void 0;
4
- var targetingTree_1 = require("./targetingTree");
5
- Object.defineProperty(exports, "TargetingTree", { enumerable: true, get: function () { return targetingTree_1.TargetingTree; } });
6
- var types_1 = require("./types");
7
- Object.defineProperty(exports, "Operator", { enumerable: true, get: function () { return types_1.Operator; } });
8
- Object.defineProperty(exports, "TargetingType", { enumerable: true, get: function () { return types_1.TargetingType; } });
9
- Object.defineProperty(exports, "MatchTypeCustomData", { enumerable: true, get: function () { return types_1.MatchTypeCustomData; } });
10
- Object.defineProperty(exports, "MatchTypeVariation", { enumerable: true, get: function () { return types_1.MatchTypeVariation; } });
11
- var conditions_1 = require("./conditions");
12
- Object.defineProperty(exports, "CustomDataCondition", { enumerable: true, get: function () { return conditions_1.CustomDataCondition; } });
13
- Object.defineProperty(exports, "TargetExperimentCondition", { enumerable: true, get: function () { return conditions_1.TargetExperimentCondition; } });
14
- Object.defineProperty(exports, "ExclusiveExperimentCondition", { enumerable: true, get: function () { return conditions_1.ExclusiveExperimentCondition; } });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "CustomDataCondition", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _conditions.CustomDataCondition;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "EvaluationDataType", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _types.EvaluationDataType;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "ExclusiveExperimentCondition", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _conditions.ExclusiveExperimentCondition;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "MatchTypeCustomData", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _types.MatchTypeCustomData;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "MatchTypeVariation", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _types.MatchTypeVariation;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "Operator", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _types.Operator;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "SegmentType", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _types.SegmentType;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "TargetExperimentCondition", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _conditions.TargetExperimentCondition;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "TargetingDataItemType", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _types.TargetingDataItemType;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "TargetingDataType", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _types.TargetingDataType;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "TargetingTree", {
67
+ enumerable: true,
68
+ get: function () {
69
+ return _targetingTree.TargetingTree;
70
+ }
71
+ });
72
+ Object.defineProperty(exports, "TargetingType", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _types.TargetingType;
76
+ }
77
+ });
78
+ var _targetingTree = require("./targetingTree");
79
+ var _types = require("./types");
80
+ var _conditions = require("./conditions");
15
81
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/targeting/index.ts"],"names":[],"mappings":";;;AAAA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,iCASiB;AARf,iGAAA,QAAQ,OAAA;AACR,sGAAA,aAAa,OAAA;AAIb,4GAAA,mBAAmB,OAAA;AACnB,2GAAA,kBAAkB,OAAA;AAGpB,2CAIsB;AAHpB,iHAAA,mBAAmB,OAAA;AACnB,uHAAA,yBAAyB,OAAA;AACzB,0HAAA,4BAA4B,OAAA"}
1
+ {"version":3,"file":"index.js","names":["_targetingTree","require","_types","_conditions"],"sources":["../../src/targeting/index.ts"],"sourcesContent":["export { TargetingTree } from './targetingTree';\nexport {\n Operator,\n TargetingType,\n SegmentType,\n TargetingDataType,\n EvaluationDataType,\n MatchTypeCustomData,\n MatchTypeVariation,\n TargetingDataItemType,\n} from './types';\nexport {\n CustomDataCondition,\n TargetExperimentCondition,\n ExclusiveExperimentCondition,\n} from './conditions';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAUA,IAAAE,WAAA,GAAAF,OAAA"}
@@ -1,40 +1,48 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
3
6
  exports.TargetingNode = void 0;
4
- const conditions_1 = require("./conditions");
5
- const types_1 = require("./types");
7
+ var _conditions = require("./conditions");
8
+ var _types = require("./types");
9
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
10
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
11
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
12
  class TargetingNode {
7
- constructor(value, left, right) {
8
- if (this.isOperator(value)) {
9
- this.nodeValue = value;
10
- }
11
- else {
12
- const result = conditions_1.ConditionFactory.createCondition(value);
13
- if (result.ok) {
14
- this.nodeValue = result.data;
15
- }
16
- else {
17
- this.nodeError = result.error;
18
- }
19
- }
20
- this.leftChild = left;
21
- this.rightChild = right;
22
- }
23
- get value() {
24
- return this.nodeValue;
25
- }
26
- get error() {
27
- return this.nodeError;
28
- }
29
- get left() {
30
- return this.leftChild;
31
- }
32
- get right() {
33
- return this.rightChild;
34
- }
35
- isOperator(value) {
36
- return value === types_1.Operator.And || value === types_1.Operator.Or;
13
+ constructor(value, left, right) {
14
+ _defineProperty(this, "nodeValue", void 0);
15
+ _defineProperty(this, "nodeError", void 0);
16
+ _defineProperty(this, "leftChild", void 0);
17
+ _defineProperty(this, "rightChild", void 0);
18
+ if (this.isOperator(value)) {
19
+ this.nodeValue = value;
20
+ } else {
21
+ const result = _conditions.ConditionFactory.createCondition(value);
22
+ if (result.ok) {
23
+ this.nodeValue = result.data;
24
+ } else {
25
+ this.nodeError = result.error;
26
+ }
37
27
  }
28
+ this.leftChild = left;
29
+ this.rightChild = right;
30
+ }
31
+ get value() {
32
+ return this.nodeValue;
33
+ }
34
+ get error() {
35
+ return this.nodeError;
36
+ }
37
+ get left() {
38
+ return this.leftChild;
39
+ }
40
+ get right() {
41
+ return this.rightChild;
42
+ }
43
+ isOperator(value) {
44
+ return value === _types.Operator.And || value === _types.Operator.Or;
45
+ }
38
46
  }
39
47
  exports.TargetingNode = TargetingNode;
40
48
  //# sourceMappingURL=targetingNode.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"targetingNode.js","sourceRoot":"","sources":["../../src/targeting/targetingNode.ts"],"names":[],"mappings":";;;AACA,6CAAmE;AACnE,mCAAkD;AASlD,MAAa,aAAa;IAMxB,YACE,KAAmC,EACnC,IAAqB,EACrB,KAAsB;QAEtB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;YAC1B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;SACxB;aAAM;YACL,MAAM,MAAM,GAAG,6BAAgB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEvD,IAAI,MAAM,CAAC,EAAE,EAAE;gBACb,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;aAC9B;iBAAM;gBACL,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;aAC/B;SACF;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAEO,UAAU,CAAC,KAAmC;QACpD,OAAO,KAAK,KAAK,gBAAQ,CAAC,GAAG,IAAI,KAAK,KAAK,gBAAQ,CAAC,EAAE,CAAC;IACzD,CAAC;CACF;AA9CD,sCA8CC"}
1
+ {"version":3,"file":"targetingNode.js","names":["_conditions","require","_types","_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","arg","_toPrimitive","String","input","hint","prim","Symbol","toPrimitive","undefined","res","call","TypeError","Number","TargetingNode","constructor","left","right","isOperator","nodeValue","result","ConditionFactory","createCondition","ok","data","nodeError","error","leftChild","rightChild","Operator","And","Or","exports"],"sources":["../../src/targeting/targetingNode.ts"],"sourcesContent":["import { KameleoonError } from '../kameleoonError';\nimport { ConditionFactory, ConditionDataType } from './conditions';\nimport { NodeValueType, Operator } from './types';\n\nexport interface ITargetingNode {\n readonly value?: NodeValueType;\n readonly left?: ITargetingNode;\n readonly right?: ITargetingNode;\n readonly error?: KameleoonError;\n}\n\nexport class TargetingNode implements ITargetingNode {\n private nodeValue?: NodeValueType;\n private nodeError?: KameleoonError;\n private leftChild?: ITargetingNode;\n private rightChild?: ITargetingNode;\n\n constructor(\n value: ConditionDataType | Operator,\n left?: ITargetingNode,\n right?: ITargetingNode,\n ) {\n if (this.isOperator(value)) {\n this.nodeValue = value;\n } else {\n const result = ConditionFactory.createCondition(value);\n\n if (result.ok) {\n this.nodeValue = result.data;\n } else {\n this.nodeError = result.error;\n }\n }\n\n this.leftChild = left;\n this.rightChild = right;\n }\n\n get value(): NodeValueType | undefined {\n return this.nodeValue;\n }\n\n get error(): KameleoonError | undefined {\n return this.nodeError;\n }\n\n get left(): ITargetingNode | undefined {\n return this.leftChild;\n }\n\n get right(): ITargetingNode | undefined {\n return this.rightChild;\n }\n\n private isOperator(value: ConditionDataType | Operator): value is Operator {\n return value === Operator.And || value === Operator.Or;\n }\n}\n"],"mappings":";;;;;;AACA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAAkD,SAAAE,gBAAAC,GAAA,EAAAC,GAAA,EAAAC,KAAA,IAAAD,GAAA,GAAAE,cAAA,CAAAF,GAAA,OAAAA,GAAA,IAAAD,GAAA,IAAAI,MAAA,CAAAC,cAAA,CAAAL,GAAA,EAAAC,GAAA,IAAAC,KAAA,EAAAA,KAAA,EAAAI,UAAA,QAAAC,YAAA,QAAAC,QAAA,oBAAAR,GAAA,CAAAC,GAAA,IAAAC,KAAA,WAAAF,GAAA;AAAA,SAAAG,eAAAM,GAAA,QAAAR,GAAA,GAAAS,YAAA,CAAAD,GAAA,2BAAAR,GAAA,gBAAAA,GAAA,GAAAU,MAAA,CAAAV,GAAA;AAAA,SAAAS,aAAAE,KAAA,EAAAC,IAAA,eAAAD,KAAA,iBAAAA,KAAA,kBAAAA,KAAA,MAAAE,IAAA,GAAAF,KAAA,CAAAG,MAAA,CAAAC,WAAA,OAAAF,IAAA,KAAAG,SAAA,QAAAC,GAAA,GAAAJ,IAAA,CAAAK,IAAA,CAAAP,KAAA,EAAAC,IAAA,2BAAAK,GAAA,sBAAAA,GAAA,YAAAE,SAAA,4DAAAP,IAAA,gBAAAF,MAAA,GAAAU,MAAA,EAAAT,KAAA;AAS3C,MAAMU,aAAa,CAA2B;EAMnDC,WAAWA,CACTrB,KAAmC,EACnCsB,IAAqB,EACrBC,KAAsB,EACtB;IAAA1B,eAAA;IAAAA,eAAA;IAAAA,eAAA;IAAAA,eAAA;IACA,IAAI,IAAI,CAAC2B,UAAU,CAACxB,KAAK,CAAC,EAAE;MAC1B,IAAI,CAACyB,SAAS,GAAGzB,KAAK;IACxB,CAAC,MAAM;MACL,MAAM0B,MAAM,GAAGC,4BAAgB,CAACC,eAAe,CAAC5B,KAAK,CAAC;MAEtD,IAAI0B,MAAM,CAACG,EAAE,EAAE;QACb,IAAI,CAACJ,SAAS,GAAGC,MAAM,CAACI,IAAI;MAC9B,CAAC,MAAM;QACL,IAAI,CAACC,SAAS,GAAGL,MAAM,CAACM,KAAK;MAC/B;IACF;IAEA,IAAI,CAACC,SAAS,GAAGX,IAAI;IACrB,IAAI,CAACY,UAAU,GAAGX,KAAK;EACzB;EAEA,IAAIvB,KAAKA,CAAA,EAA8B;IACrC,OAAO,IAAI,CAACyB,SAAS;EACvB;EAEA,IAAIO,KAAKA,CAAA,EAA+B;IACtC,OAAO,IAAI,CAACD,SAAS;EACvB;EAEA,IAAIT,IAAIA,CAAA,EAA+B;IACrC,OAAO,IAAI,CAACW,SAAS;EACvB;EAEA,IAAIV,KAAKA,CAAA,EAA+B;IACtC,OAAO,IAAI,CAACW,UAAU;EACxB;EAEQV,UAAUA,CAACxB,KAAmC,EAAqB;IACzE,OAAOA,KAAK,KAAKmC,eAAQ,CAACC,GAAG,IAAIpC,KAAK,KAAKmC,eAAQ,CAACE,EAAE;EACxD;AACF;AAACC,OAAA,CAAAlB,aAAA,GAAAA,aAAA"}
@@ -1,115 +1,136 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
3
6
  exports.TargetingTree = void 0;
4
- const ts_res_1 = require("ts-res");
5
- const targetingNode_1 = require("./targetingNode");
6
- const types_1 = require("./types");
7
+ var _tsRes = require("ts-res");
8
+ var _targetingNode = require("./targetingNode");
9
+ var _types = require("./types");
10
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
12
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
7
13
  class TargetingTree {
8
- constructor(segment) {
9
- this.error = null;
10
- const { conditions, operators } = this.flattenSegment(segment);
11
- const nodes = conditions.map((condition) => new targetingNode_1.TargetingNode(condition));
12
- // --- Note ---
13
- // - Targeting tree is built bottom-up, it's the only way to both get the consistent logic
14
- // (grouping nested conditions) and have human readable tree representation.
15
- // - Here is an example of how tree is built (we use strict complete binary tree)
16
- // Let's say we have such a condition `value < 10 || value > 20 && value < 30`
17
- // Code-wise it looks as follows (this is not real code, real tree is more complicated and can have more
18
- // levels of deeply nested conditions):
19
- //
20
- // `const operators = [Operator.Or, Operator.And]`
21
- // `const conditions = [
22
- // {type: Condition.Less, value: 10},
23
- // {type: Condition.Greater, value: 20},
24
- // {type: Condition.Less, value: 30},
25
- // ]`
26
- //
27
- // After the first iteration we have node like this:
28
- // AND
29
- // / \
30
- // <30 >20
31
- //
32
- // After the second iteration tree looks as follows:
33
- // OR
34
- // / \
35
- // AND <10
36
- // / \
37
- // <30 >20
38
- // As you can see Leaf Nodes contain conditions and Non-Leaf Nodes contain logical operators
39
- for (const operator of operators) {
40
- const left = nodes.shift();
41
- const right = nodes.shift();
42
- nodes.unshift(new targetingNode_1.TargetingNode(operator, left, right));
43
- }
44
- // --- Note ---
45
- // It's guaranteed that only one root node will remain after iterations
46
- // (as soon as the backend `operators-conditions` relation doesn't change)
47
- this.tree = nodes[0];
14
+ constructor(segment) {
15
+ _defineProperty(this, "tree", void 0);
16
+ _defineProperty(this, "error", null);
17
+ const {
18
+ conditions,
19
+ operators
20
+ } = this.flattenSegment(segment);
21
+ const nodes = conditions.map(condition => new _targetingNode.TargetingNode(condition));
22
+
23
+ // --- Note ---
24
+ // - Targeting tree is built bottom-up, it's the only way to both get the consistent logic
25
+ // (grouping nested conditions) and have human readable tree representation.
26
+ // - Here is an example of how tree is built (we use strict complete binary tree)
27
+ // Let's say we have such a condition `value < 10 || value > 20 && value < 30`
28
+ // Code-wise it looks as follows (this is not real code, real tree is more complicated and can have more
29
+ // levels of deeply nested conditions):
30
+ //
31
+ // `const operators = [Operator.Or, Operator.And]`
32
+ // `const conditions = [
33
+ // {type: Condition.Less, value: 10},
34
+ // {type: Condition.Greater, value: 20},
35
+ // {type: Condition.Less, value: 30},
36
+ // ]`
37
+ //
38
+ // After the first iteration we have node like this:
39
+ // AND
40
+ // / \
41
+ // <30 >20
42
+ //
43
+ // After the second iteration tree looks as follows:
44
+ // OR
45
+ // / \
46
+ // AND <10
47
+ // / \
48
+ // <30 >20
49
+ // As you can see Leaf Nodes contain conditions and Non-Leaf Nodes contain logical operators
50
+ for (const operator of operators) {
51
+ const left = nodes.shift();
52
+ const right = nodes.shift();
53
+ nodes.unshift(new _targetingNode.TargetingNode(operator, left, right));
48
54
  }
49
- evaluate(data) {
50
- const result = this.evaluateNode(this.tree, data);
51
- if (this.error) {
52
- return (0, ts_res_1.Err)(this.error);
53
- }
54
- return (0, ts_res_1.Ok)(result);
55
+
56
+ // --- Note ---
57
+ // It's guaranteed that only one root node will remain after iterations
58
+ // (as soon as the backend `operators-conditions` relation doesn't change)
59
+ this.tree = nodes[0];
60
+ }
61
+ evaluate(data) {
62
+ const result = this.evaluateNode(this.tree, data);
63
+ if (this.error) {
64
+ return (0, _tsRes.Err)(this.error);
55
65
  }
56
- evaluateNode(node, data) {
57
- if (this.isLeafNode(node)) {
58
- if (node.error) {
59
- this.error = node.error;
60
- return false;
61
- }
62
- const result = node.value.evaluate(data);
63
- if (!result.ok) {
64
- this.error = result.error;
65
- return false;
66
- }
67
- return result.data;
68
- }
69
- if (this.isNonLeafNode(node)) {
70
- switch (node.value) {
71
- case types_1.Operator.And: {
72
- return (this.evaluateNode(node.left, data) &&
73
- this.evaluateNode(node.right, data));
74
- }
75
- case types_1.Operator.Or: {
76
- return (this.evaluateNode(node.left, data) ||
77
- this.evaluateNode(node.right, data));
78
- }
79
- default:
80
- break;
81
- }
82
- }
66
+ return (0, _tsRes.Ok)(result);
67
+ }
68
+ evaluateNode(node, data) {
69
+ if (this.isLeafNode(node)) {
70
+ if (node.error) {
71
+ // --- Note ---
72
+ // Non-existing condition should not break targeting tree
73
+ // instead it should be treated as `false` condition
83
74
  return false;
75
+ }
76
+ const result = node.value.evaluate(data);
77
+ if (!result.ok) {
78
+ this.error = result.error;
79
+ return false;
80
+ }
81
+ return result.data;
84
82
  }
85
- isLeafNode(node) {
86
- return !Boolean(node.left && node.right);
87
- }
88
- isNonLeafNode(node) {
89
- return Boolean(node.left &&
90
- node.right &&
91
- (node.value === types_1.Operator.Or || node.value === types_1.Operator.And));
92
- }
93
- flattenSegment(segment) {
94
- const { firstLevel: conditions, firstLevelOrOperators: operators } = segment.conditionsData;
95
- const resultOperators = [...operators];
96
- const resultConditions = [];
97
- conditions.forEach((condition) => {
98
- const { conditions: conditionList, orOperators } = condition;
99
- // --- Note ---
100
- // if `condition` has nested conditions and operators in it, they go to the
101
- // beginning of list, otherwise we just add it to the end
102
- if (orOperators.length) {
103
- orOperators.forEach((item) => resultOperators.unshift(item));
104
- conditionList.forEach((item) => resultConditions.unshift(item));
105
- }
106
- else {
107
- conditionList.forEach((item) => resultConditions.push(item));
108
- }
109
- });
110
- const convertedOperators = resultOperators.map((operator) => operator ? types_1.Operator.Or : types_1.Operator.And);
111
- return { conditions: resultConditions, operators: convertedOperators };
83
+ if (this.isNonLeafNode(node)) {
84
+ switch (node.value) {
85
+ case _types.Operator.And:
86
+ {
87
+ return this.evaluateNode(node.left, data) && this.evaluateNode(node.right, data);
88
+ }
89
+ case _types.Operator.Or:
90
+ {
91
+ return this.evaluateNode(node.left, data) || this.evaluateNode(node.right, data);
92
+ }
93
+ default:
94
+ break;
95
+ }
112
96
  }
97
+ return false;
98
+ }
99
+ isLeafNode(node) {
100
+ return !Boolean(node.left && node.right);
101
+ }
102
+ isNonLeafNode(node) {
103
+ return Boolean(node.left && node.right && (node.value === _types.Operator.Or || node.value === _types.Operator.And));
104
+ }
105
+ flattenSegment(segment) {
106
+ const {
107
+ firstLevel: conditions,
108
+ firstLevelOrOperators: operators
109
+ } = segment.conditionsData;
110
+ const resultOperators = [...operators];
111
+ const resultConditions = [];
112
+ conditions.forEach(condition => {
113
+ const {
114
+ conditions: conditionList,
115
+ orOperators
116
+ } = condition;
117
+
118
+ // --- Note ---
119
+ // if `condition` has nested conditions and operators in it, they go to the
120
+ // beginning of list, otherwise we just add it to the end
121
+ if (orOperators.length) {
122
+ orOperators.forEach(item => resultOperators.unshift(item));
123
+ conditionList.forEach(item => resultConditions.unshift(item));
124
+ } else {
125
+ conditionList.forEach(item => resultConditions.push(item));
126
+ }
127
+ });
128
+ const convertedOperators = resultOperators.map(operator => operator ? _types.Operator.Or : _types.Operator.And);
129
+ return {
130
+ conditions: resultConditions,
131
+ operators: convertedOperators
132
+ };
133
+ }
113
134
  }
114
135
  exports.TargetingTree = TargetingTree;
115
136
  //# sourceMappingURL=targetingTree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"targetingTree.js","sourceRoot":"","sources":["../../src/targeting/targetingTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"targetingTree.js","names":["_tsRes","require","_targetingNode","_types","_defineProperty","obj","key","value","_toPropertyKey","Object","defineProperty","enumerable","configurable","writable","arg","_toPrimitive","String","input","hint","prim","Symbol","toPrimitive","undefined","res","call","TypeError","Number","TargetingTree","constructor","segment","conditions","operators","flattenSegment","nodes","map","condition","TargetingNode","operator","left","shift","right","unshift","tree","evaluate","data","result","evaluateNode","error","Err","Ok","node","isLeafNode","ok","isNonLeafNode","Operator","And","Or","Boolean","firstLevel","firstLevelOrOperators","conditionsData","resultOperators","resultConditions","forEach","conditionList","orOperators","length","item","push","convertedOperators","exports"],"sources":["../../src/targeting/targetingTree.ts"],"sourcesContent":["import { Result, Ok, Err } from 'ts-res';\nimport { KameleoonError } from '../kameleoonError';\nimport { ConditionDataType } from './conditions';\nimport { ITargetingNode, TargetingNode } from './targetingNode';\nimport {\n EvaluationDataType,\n FlatSegmentType,\n LeafNodeType,\n NonLeafNodeType,\n Operator,\n SegmentType,\n} from './types';\n\ninterface ITargetingTree {\n evaluate: (data: EvaluationDataType) => Result<boolean, KameleoonError>;\n}\n\nexport class TargetingTree implements ITargetingTree {\n private tree: TargetingNode;\n private error: KameleoonError | null = null;\n\n constructor(segment: SegmentType) {\n const { conditions, operators } = this.flattenSegment(segment);\n const nodes = conditions.map((condition) => new TargetingNode(condition));\n\n // --- Note ---\n // - Targeting tree is built bottom-up, it's the only way to both get the consistent logic\n // (grouping nested conditions) and have human readable tree representation.\n // - Here is an example of how tree is built (we use strict complete binary tree)\n // Let's say we have such a condition `value < 10 || value > 20 && value < 30`\n // Code-wise it looks as follows (this is not real code, real tree is more complicated and can have more\n // levels of deeply nested conditions):\n //\n // `const operators = [Operator.Or, Operator.And]`\n // `const conditions = [\n // {type: Condition.Less, value: 10},\n // {type: Condition.Greater, value: 20},\n // {type: Condition.Less, value: 30},\n // ]`\n //\n // After the first iteration we have node like this:\n // AND\n // / \\\n // <30 >20\n //\n // After the second iteration tree looks as follows:\n // OR\n // / \\\n // AND <10\n // / \\\n // <30 >20\n // As you can see Leaf Nodes contain conditions and Non-Leaf Nodes contain logical operators\n for (const operator of operators) {\n const left = nodes.shift();\n const right = nodes.shift();\n\n nodes.unshift(new TargetingNode(operator, left, right));\n }\n\n // --- Note ---\n // It's guaranteed that only one root node will remain after iterations\n // (as soon as the backend `operators-conditions` relation doesn't change)\n this.tree = nodes[0];\n }\n\n public evaluate(data: EvaluationDataType): Result<boolean, KameleoonError> {\n const result = this.evaluateNode(this.tree, data);\n\n if (this.error) {\n return Err(this.error);\n }\n\n return Ok(result);\n }\n\n private evaluateNode(node: TargetingNode, data: EvaluationDataType): boolean {\n if (this.isLeafNode(node)) {\n if (node.error) {\n // --- Note ---\n // Non-existing condition should not break targeting tree\n // instead it should be treated as `false` condition\n return false;\n }\n\n const result = node.value.evaluate(data);\n\n if (!result.ok) {\n this.error = result.error;\n\n return false;\n }\n\n return result.data;\n }\n\n if (this.isNonLeafNode(node)) {\n switch (node.value) {\n case Operator.And: {\n return (\n this.evaluateNode(node.left, data) &&\n this.evaluateNode(node.right, data)\n );\n }\n case Operator.Or: {\n return (\n this.evaluateNode(node.left, data) ||\n this.evaluateNode(node.right, data)\n );\n }\n default:\n break;\n }\n }\n\n return false;\n }\n\n private isLeafNode(node: ITargetingNode): node is LeafNodeType {\n return !Boolean(node.left && node.right);\n }\n\n private isNonLeafNode(node: ITargetingNode): node is NonLeafNodeType {\n return Boolean(\n node.left &&\n node.right &&\n (node.value === Operator.Or || node.value === Operator.And),\n );\n }\n\n private flattenSegment(segment: SegmentType): FlatSegmentType {\n const { firstLevel: conditions, firstLevelOrOperators: operators } =\n segment.conditionsData;\n\n const resultOperators: boolean[] = [...operators];\n const resultConditions: ConditionDataType[] = [];\n\n conditions.forEach((condition) => {\n const { conditions: conditionList, orOperators } = condition;\n\n // --- Note ---\n // if `condition` has nested conditions and operators in it, they go to the\n // beginning of list, otherwise we just add it to the end\n if (orOperators.length) {\n orOperators.forEach((item) => resultOperators.unshift(item));\n conditionList.forEach((item) => resultConditions.unshift(item));\n } else {\n conditionList.forEach((item) => resultConditions.push(item));\n }\n });\n\n const convertedOperators = resultOperators.map((operator) =>\n operator ? Operator.Or : Operator.And,\n );\n\n return { conditions: resultConditions, operators: convertedOperators };\n }\n}\n"],"mappings":"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"}