@frontegg/entitlements-javascript-commons 1.1.3 → 1.2.0-alpha.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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { FeatureFlagEvaluationResult, FeatureFlag, evaluateFeatureFlag } from './feature-flags';
2
2
  export { PlanEvaluationResult, Plan, evaluatePlan } from './plans';
3
- export { TreatmentEnum, Rule } from './rules';
3
+ export { TreatmentEnum, Rule, ConditionGroup, isConditionGroup } from './rules';
4
4
  export { Condition } from './conditions';
5
5
  export { OperationEnum, ConditionValue } from './operations/types';
6
6
  export { evaluateIsEntitledToFeature, evaluateIsEntitledToPermissions, prepareAttributes, checkPermission, createPermissionCheckRegex, Permissions, JwtAttributes, CustomAttributes, FronteggAttributes, NotEntitledJustification, UserEntitlementsContext, EntitlementResult, Attributes, } from './user-entitlements';
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NotEntitledJustification = exports.createPermissionCheckRegex = exports.checkPermission = exports.prepareAttributes = exports.evaluateIsEntitledToPermissions = exports.evaluateIsEntitledToFeature = exports.OperationEnum = exports.TreatmentEnum = exports.evaluatePlan = exports.evaluateFeatureFlag = void 0;
3
+ exports.NotEntitledJustification = exports.createPermissionCheckRegex = exports.checkPermission = exports.prepareAttributes = exports.evaluateIsEntitledToPermissions = exports.evaluateIsEntitledToFeature = exports.OperationEnum = exports.isConditionGroup = exports.TreatmentEnum = exports.evaluatePlan = exports.evaluateFeatureFlag = void 0;
4
4
  var feature_flags_1 = require("./feature-flags");
5
5
  Object.defineProperty(exports, "evaluateFeatureFlag", { enumerable: true, get: function () { return feature_flags_1.evaluateFeatureFlag; } });
6
6
  var plans_1 = require("./plans");
7
7
  Object.defineProperty(exports, "evaluatePlan", { enumerable: true, get: function () { return plans_1.evaluatePlan; } });
8
8
  var rules_1 = require("./rules");
9
9
  Object.defineProperty(exports, "TreatmentEnum", { enumerable: true, get: function () { return rules_1.TreatmentEnum; } });
10
+ Object.defineProperty(exports, "isConditionGroup", { enumerable: true, get: function () { return rules_1.isConditionGroup; } });
10
11
  var types_1 = require("./operations/types");
11
12
  Object.defineProperty(exports, "OperationEnum", { enumerable: true, get: function () { return types_1.OperationEnum; } });
12
13
  var user_entitlements_1 = require("./user-entitlements");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAgG;AAA7C,oHAAA,mBAAmB,OAAA;AACtE,iCAAmE;AAA9B,qGAAA,YAAY,OAAA;AACjD,iCAA8C;AAArC,sGAAA,aAAa,OAAA;AAEtB,4CAAmE;AAA1D,sGAAA,aAAa,OAAA;AACtB,yDAc6B;AAb3B,gIAAA,2BAA2B,OAAA;AAC3B,oIAAA,+BAA+B,OAAA;AAC/B,sHAAA,iBAAiB,OAAA;AACjB,oHAAA,eAAe,OAAA;AACf,+HAAA,0BAA0B,OAAA;AAK1B,6HAAA,wBAAwB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAgG;AAA7C,oHAAA,mBAAmB,OAAA;AACtE,iCAAmE;AAA9B,qGAAA,YAAY,OAAA;AACjD,iCAAgF;AAAvE,sGAAA,aAAa,OAAA;AAAwB,yGAAA,gBAAgB,OAAA;AAE9D,4CAAmE;AAA1D,sGAAA,aAAa,OAAA;AACtB,yDAc6B;AAb3B,gIAAA,2BAA2B,OAAA;AAC3B,oIAAA,+BAA+B,OAAA;AAC/B,sHAAA,iBAAiB,OAAA;AACjB,oHAAA,eAAe,OAAA;AACf,+HAAA,0BAA0B,OAAA;AAK1B,6HAAA,wBAAwB,OAAA"}
@@ -14,7 +14,12 @@ function useContainsOperation(payload) {
14
14
  }
15
15
  exports.useContainsOperation = useContainsOperation;
16
16
  function useInListOperation(payload) {
17
- return (attribute) => ({ isValid: payload.list.includes(attribute) });
17
+ return (attribute) => {
18
+ if (Array.isArray(attribute)) {
19
+ return { isValid: attribute.some((item) => payload.list.includes(item)) };
20
+ }
21
+ return { isValid: payload.list.includes(attribute) };
22
+ };
18
23
  }
19
24
  exports.useInListOperation = useInListOperation;
20
25
  function useMatchesOperation(payload) {
@@ -1 +1 @@
1
- {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/operations/string/operations.ts"],"names":[],"mappings":";;;AAGA,SAAgB,sBAAsB,CAAC,OAAmC;IACxE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACzG,CAAC;AAFD,wDAEC;AAED,SAAgB,oBAAoB,CAAC,OAAmC;IACtE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvG,CAAC;AAFD,oDAEC;AAED,SAAgB,oBAAoB,CAAC,OAAmC;IACtE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvG,CAAC;AAFD,oDAEC;AAED,SAAgB,kBAAkB,CAAC,OAAmC;IACpE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAChF,CAAC;AAFD,gDAEC;AAED,SAAgB,mBAAmB,CAAC,OAAqC;IACvE,OAAO,CAAC,SAAiB,EAAE,EAAE;QAC3B,IAAI,UAAkB,CAAC;QAEvB,IAAI;YACF,UAAU,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACzC;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;SAC3B;QAED,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAZD,kDAYC"}
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/operations/string/operations.ts"],"names":[],"mappings":";;;AAGA,SAAgB,sBAAsB,CAAC,OAAmC;IACxE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACzG,CAAC;AAFD,wDAEC;AAED,SAAgB,oBAAoB,CAAC,OAAmC;IACtE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvG,CAAC;AAFD,oDAEC;AAED,SAAgB,oBAAoB,CAAC,OAAmC;IACtE,OAAO,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvG,CAAC;AAFD,oDAEC;AAED,SAAgB,kBAAkB,CAAC,OAAmC;IACpE,OAAO,CAAC,SAA4B,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC5B,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;SAC3E;QACD,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAPD,gDAOC;AAED,SAAgB,mBAAmB,CAAC,OAAqC;IACvE,OAAO,CAAC,SAAiB,EAAE,EAAE;QAC3B,IAAI,UAAkB,CAAC;QAEvB,IAAI;YACF,UAAU,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SACzC;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;SAC3B;QAED,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAZD,kDAYC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizers.js","sourceRoot":"","sources":["../../../src/operations/string/sanitizers.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAGtE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAEzE,MAAM,oBAAoB,GAA4C,CAAC,KAAK,EAAE,EAAE;IACrF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnH,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,oBAAoB,wBAO/B;AAEK,MAAM,kBAAkB,GAA0C,CAAC,KAAK,EAAE,EAAE;IACjF,MAAM,cAAc,GAClB,KAAK,CAAC,IAAI,KAAK,SAAS,IAAgB,KAAK,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/E,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAgB,EAAE;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B;AAEW,QAAA,sBAAsB,GAA6C;IAC9E,CAAC,qBAAa,CAAC,OAAO,CAAC,EAAE,4BAAoB;IAC7C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,UAAU,CAAC,EAAE,0BAAkB;IAC9C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,MAAM,CAAC,EAAE,0BAAkB;CAC3C,CAAC"}
1
+ {"version":3,"file":"sanitizers.js","sourceRoot":"","sources":["../../../src/operations/string/sanitizers.ts"],"names":[],"mappings":";;;AAAA,oCAAsE;AAGtE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAEzE,MAAM,oBAAoB,GAA4C,CAAC,KAAK,EAAE,EAAE;IACrF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnH,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,oBAAoB,wBAO/B;AAEK,MAAM,kBAAkB,GAA0C,CAAC,KAAK,EAAE,EAAE;IACjF,MAAM,cAAc,GAClB,KAAK,CAAC,IAAI,KAAK,SAAS,IAAgB,KAAK,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/E,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAgB,EAAE;QAClC,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,cAAc;QAC7B,cAAc;KACf,CAAC;AACJ,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B;AAGW,QAAA,sBAAsB,GAA6C;IAC9E,CAAC,qBAAa,CAAC,OAAO,CAAC,EAAE,4BAAoB;IAC7C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,UAAU,CAAC,EAAE,0BAAkB;IAC9C,CAAC,qBAAa,CAAC,QAAQ,CAAC,EAAE,0BAAkB;IAC5C,CAAC,qBAAa,CAAC,MAAM,CAAC,EAAE,0BAAkB;CAC3C,CAAC"}
@@ -3,12 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRuleEvaluator = void 0;
4
4
  const types_1 = require("./types");
5
5
  const conditions_1 = require("../conditions");
6
+ function evaluateGroup(group, attributes) {
7
+ const evaluateItem = (item) => {
8
+ if ((0, types_1.isConditionGroup)(item)) {
9
+ return evaluateGroup(item, attributes);
10
+ }
11
+ const evaluator = (0, conditions_1.createConditionEvaluator)({ condition: item });
12
+ return evaluator(attributes);
13
+ };
14
+ const arrayMethod = group.conditionLogic === types_1.ConditionLogicEnum.Or ? 'some' : 'every';
15
+ return group.conditions[arrayMethod](evaluateItem);
16
+ }
6
17
  function createRuleEvaluator(payload) {
7
18
  return (attributes) => {
8
- const isRuleTreatable = payload.rule.conditions.every((condition) => {
9
- const evaluator = (0, conditions_1.createConditionEvaluator)({ condition });
10
- return evaluator(attributes);
11
- });
19
+ const isRuleTreatable = evaluateGroup(payload.rule, attributes);
12
20
  return isRuleTreatable ? types_1.RuleEvaluationResultEnum.Treatable : types_1.RuleEvaluationResultEnum.Insufficient;
13
21
  };
14
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rule.evaluator.js","sourceRoot":"","sources":["../../src/rules/rule.evaluator.ts"],"names":[],"mappings":";;;AAAA,mCAA8F;AAC9F,8CAAyD;AAEzD,SAAgB,mBAAmB,CAAC,OAAmC;IACrE,OAAO,CAAC,UAAmC,EAA4B,EAAE;QACvE,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE;YAClE,MAAM,SAAS,GAAG,IAAA,qCAAwB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;YAE1D,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,eAAe,CAAC,CAAC,CAAC,gCAAwB,CAAC,SAAS,CAAC,CAAC,CAAC,gCAAwB,CAAC,YAAY,CAAC;IACtG,CAAC,CAAC;AACJ,CAAC;AAVD,kDAUC"}
1
+ {"version":3,"file":"rule.evaluator.js","sourceRoot":"","sources":["../../src/rules/rule.evaluator.ts"],"names":[],"mappings":";;;AAAA,mCAOiB;AACjB,8CAAoE;AAEpE,SAAS,aAAa,CAAC,KAAqB,EAAE,UAAmC;IAC/E,MAAM,YAAY,GAAG,CAAC,IAAgC,EAAW,EAAE;QACjE,IAAI,IAAA,wBAAgB,EAAC,IAAI,CAAC,EAAE;YAC1B,OAAO,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;SACxC;QACD,MAAM,SAAS,GAAG,IAAA,qCAAwB,EAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,KAAK,0BAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACtF,OAAO,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAAmC;IACrE,OAAO,CAAC,UAAmC,EAA4B,EAAE;QACvE,MAAM,eAAe,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAChE,OAAO,eAAe,CAAC,CAAC,CAAC,gCAAwB,CAAC,SAAS,CAAC,CAAC,CAAC,gCAAwB,CAAC,YAAY,CAAC;IACtG,CAAC,CAAC;AACJ,CAAC;AALD,kDAKC"}
@@ -1,11 +1,17 @@
1
1
  import { Condition } from '../conditions';
2
+ export interface ConditionGroup {
3
+ conditionLogic: ConditionLogicEnum;
4
+ conditions: (Condition | ConditionGroup)[];
5
+ }
6
+ export declare function isConditionGroup(item: Condition | ConditionGroup): item is ConditionGroup;
2
7
  export interface Rule {
3
- conditionLogic: ConditionLogicEnum.And;
4
- conditions: Condition[];
8
+ conditionLogic: ConditionLogicEnum;
9
+ conditions: (Condition | ConditionGroup)[];
5
10
  treatment: TreatmentEnum;
6
11
  }
7
12
  export declare enum ConditionLogicEnum {
8
- And = "and"
13
+ And = "and",
14
+ Or = "or"
9
15
  }
10
16
  export declare enum TreatmentEnum {
11
17
  True = "true",
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RuleEvaluationResultEnum = exports.TreatmentEnum = exports.ConditionLogicEnum = void 0;
3
+ exports.RuleEvaluationResultEnum = exports.TreatmentEnum = exports.ConditionLogicEnum = exports.isConditionGroup = void 0;
4
+ function isConditionGroup(item) {
5
+ return 'conditionLogic' in item && !('op' in item);
6
+ }
7
+ exports.isConditionGroup = isConditionGroup;
4
8
  var ConditionLogicEnum;
5
9
  (function (ConditionLogicEnum) {
6
10
  ConditionLogicEnum["And"] = "and";
11
+ ConditionLogicEnum["Or"] = "or";
7
12
  })(ConditionLogicEnum = exports.ConditionLogicEnum || (exports.ConditionLogicEnum = {}));
8
13
  var TreatmentEnum;
9
14
  (function (TreatmentEnum) {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":";;;AAQA,IAAY,kBAEX;AAFD,WAAY,kBAAkB;IAC5B,iCAAW,CAAA;AACb,CAAC,EAFW,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QAE7B;AAED,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,8BAAa,CAAA;IACb,gCAAe,CAAA;AACjB,CAAC,EAHW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAGxB;AAED,IAAY,wBAGX;AAHD,WAAY,wBAAwB;IAClC,mDAAuB,CAAA;IACvB,yDAA6B,CAAA;AAC/B,CAAC,EAHW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAGnC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":";;;AAOA,SAAgB,gBAAgB,CAAC,IAAgC;IAC/D,OAAO,gBAAgB,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AACrD,CAAC;AAFD,4CAEC;AAQD,IAAY,kBAGX;AAHD,WAAY,kBAAkB;IAC5B,iCAAW,CAAA;IACX,+BAAS,CAAA;AACX,CAAC,EAHW,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QAG7B;AAED,IAAY,aAGX;AAHD,WAAY,aAAa;IACvB,8BAAa,CAAA;IACb,gCAAe,CAAA;AACjB,CAAC,EAHW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAGxB;AAED,IAAY,wBAGX;AAHD,WAAY,wBAAwB;IAClC,mDAAuB,CAAA;IACvB,yDAA6B,CAAA;AAC/B,CAAC,EAHW,wBAAwB,GAAxB,gCAAwB,KAAxB,gCAAwB,QAGnC"}
package/docs/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [1.2.0-alpha.1](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.1.5...v-1.2.0-alpha.1) (2026-02-19)
2
+
3
+
4
+ ### Features
5
+
6
+ * **or:** support or ([4ec8cc2](https://github.com/frontegg/entitlements-javascript-commons/commit/4ec8cc2e7669528c8418560c173e8dc9c237ff5b))
7
+
8
+ ## [1.1.5](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.1.4...v-1.1.5) (2026-02-15)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **release:** fix release ([51407ee](https://github.com/frontegg/entitlements-javascript-commons/commit/51407ee17cbb3c91f29cd23475bd062fd71515b1))
14
+
15
+ ## [1.1.4](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.1.3...v-1.1.4) (2026-02-15)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **attribute:** array attributes in inList ([17b6218](https://github.com/frontegg/entitlements-javascript-commons/commit/17b6218f704f9b1dd19992f501ee3fc3facebe17))
21
+
1
22
  ## [1.1.3](https://github.com/frontegg/entitlements-javascript-commons/compare/v-1.1.2...v-1.1.3) (2025-02-24)
2
23
 
3
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontegg/entitlements-javascript-commons",
3
- "version": "1.1.3",
3
+ "version": "1.2.0-alpha.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { FeatureFlagEvaluationResult, FeatureFlag, evaluateFeatureFlag } from './feature-flags';
2
2
  export { PlanEvaluationResult, Plan, evaluatePlan } from './plans';
3
- export { TreatmentEnum, Rule } from './rules';
3
+ export { TreatmentEnum, Rule, ConditionGroup, isConditionGroup } from './rules';
4
4
  export { Condition } from './conditions';
5
5
  export { OperationEnum, ConditionValue } from './operations/types';
6
6
  export {
@@ -14,7 +14,12 @@ export function useContainsOperation(payload: ListStringOperationPayload): Opera
14
14
  }
15
15
 
16
16
  export function useInListOperation(payload: ListStringOperationPayload): OperationHandler {
17
- return (attribute: string) => ({ isValid: payload.list.includes(attribute) });
17
+ return (attribute: string | string[]) => {
18
+ if (Array.isArray(attribute)) {
19
+ return { isValid: attribute.some((item) => payload.list.includes(item)) };
20
+ }
21
+ return { isValid: payload.list.includes(attribute) };
22
+ };
18
23
  }
19
24
 
20
25
  export function useMatchesOperation(payload: SingleStringOperationPayload): OperationHandler {
@@ -24,6 +24,7 @@ export const sanitizeListString: Sanitizer<ListStringOperationPayload> = (value)
24
24
  };
25
25
  };
26
26
 
27
+
27
28
  export const StringSanitizersMapper: SanitizersMapper<StringOperationPayload> = {
28
29
  [OperationEnum.Matches]: sanitizeSingleString,
29
30
  [OperationEnum.Contains]: sanitizeListString,
@@ -1,14 +1,29 @@
1
- import { CreateRuleEvaluatorPayload, RuleEvaluationResultEnum, RuleEvaluator } from './types';
2
- import { createConditionEvaluator } from '../conditions';
1
+ import {
2
+ ConditionGroup,
3
+ ConditionLogicEnum,
4
+ CreateRuleEvaluatorPayload,
5
+ isConditionGroup,
6
+ RuleEvaluationResultEnum,
7
+ RuleEvaluator,
8
+ } from './types';
9
+ import { Condition, createConditionEvaluator } from '../conditions';
3
10
 
4
- export function createRuleEvaluator(payload: CreateRuleEvaluatorPayload): RuleEvaluator {
5
- return (attributes: Record<string, unknown>): RuleEvaluationResultEnum => {
6
- const isRuleTreatable = payload.rule.conditions.every((condition) => {
7
- const evaluator = createConditionEvaluator({ condition });
11
+ function evaluateGroup(group: ConditionGroup, attributes: Record<string, unknown>): boolean {
12
+ const evaluateItem = (item: Condition | ConditionGroup): boolean => {
13
+ if (isConditionGroup(item)) {
14
+ return evaluateGroup(item, attributes);
15
+ }
16
+ const evaluator = createConditionEvaluator({ condition: item });
17
+ return evaluator(attributes);
18
+ };
8
19
 
9
- return evaluator(attributes);
10
- });
20
+ const arrayMethod = group.conditionLogic === ConditionLogicEnum.Or ? 'some' : 'every';
21
+ return group.conditions[arrayMethod](evaluateItem);
22
+ }
11
23
 
24
+ export function createRuleEvaluator(payload: CreateRuleEvaluatorPayload): RuleEvaluator {
25
+ return (attributes: Record<string, unknown>): RuleEvaluationResultEnum => {
26
+ const isRuleTreatable = evaluateGroup(payload.rule, attributes);
12
27
  return isRuleTreatable ? RuleEvaluationResultEnum.Treatable : RuleEvaluationResultEnum.Insufficient;
13
28
  };
14
29
  }
@@ -1,4 +1,4 @@
1
- import { ConditionLogicEnum, Rule, RuleEvaluationResultEnum, TreatmentEnum } from '../types';
1
+ import { ConditionGroup, ConditionLogicEnum, Rule, RuleEvaluationResultEnum, TreatmentEnum } from '../types';
2
2
  import { createRuleEvaluator } from '../rule.evaluator';
3
3
  import { OperationEnum } from '../../operations/types';
4
4
 
@@ -132,4 +132,257 @@ describe('RuleEvaluator', () => {
132
132
 
133
133
  expect(result).toEqual(RuleEvaluationResultEnum.Treatable);
134
134
  });
135
+
136
+ it('should return RuleEvaluationResultEnum.Treatable with "or" logic when at least one condition passes', () => {
137
+ const rule: Rule = {
138
+ treatment: TreatmentEnum.True,
139
+ conditions: [
140
+ {
141
+ attribute: 'attribute',
142
+ op: OperationEnum.StartsWith,
143
+ value: { list: ['no-match'] },
144
+ negate: false,
145
+ },
146
+ {
147
+ attribute: 'attribute',
148
+ op: OperationEnum.Contains,
149
+ value: { list: ['test'] },
150
+ negate: false,
151
+ },
152
+ ],
153
+ conditionLogic: ConditionLogicEnum.Or,
154
+ };
155
+
156
+ const ruleEvaluator = createRuleEvaluator({ rule });
157
+ const result = ruleEvaluator({ attribute: 'test' });
158
+
159
+ expect(result).toEqual(RuleEvaluationResultEnum.Treatable);
160
+ });
161
+
162
+ it('should return RuleEvaluationResultEnum.Insufficient with "or" logic when no conditions pass', () => {
163
+ const rule: Rule = {
164
+ treatment: TreatmentEnum.True,
165
+ conditions: [
166
+ {
167
+ attribute: 'attribute',
168
+ op: OperationEnum.StartsWith,
169
+ value: { list: ['no-match'] },
170
+ negate: false,
171
+ },
172
+ {
173
+ attribute: 'attribute',
174
+ op: OperationEnum.Contains,
175
+ value: { list: ['no-match'] },
176
+ negate: false,
177
+ },
178
+ ],
179
+ conditionLogic: ConditionLogicEnum.Or,
180
+ };
181
+
182
+ const ruleEvaluator = createRuleEvaluator({ rule });
183
+ const result = ruleEvaluator({ attribute: 'test' });
184
+
185
+ expect(result).toEqual(RuleEvaluationResultEnum.Insufficient);
186
+ });
187
+
188
+ it('should return RuleEvaluationResultEnum.Treatable with "or" logic when all conditions pass', () => {
189
+ const rule: Rule = {
190
+ treatment: TreatmentEnum.True,
191
+ conditions: [
192
+ {
193
+ attribute: 'attribute',
194
+ op: OperationEnum.InList,
195
+ value: { list: ['test'] },
196
+ negate: false,
197
+ },
198
+ {
199
+ attribute: 'attribute',
200
+ op: OperationEnum.Contains,
201
+ value: { list: ['test'] },
202
+ negate: false,
203
+ },
204
+ ],
205
+ conditionLogic: ConditionLogicEnum.Or,
206
+ };
207
+
208
+ const ruleEvaluator = createRuleEvaluator({ rule });
209
+ const result = ruleEvaluator({ attribute: 'test' });
210
+
211
+ expect(result).toEqual(RuleEvaluationResultEnum.Treatable);
212
+ });
213
+
214
+ describe('nested condition groups', () => {
215
+ it('should return Treatable for x | (y & z) when x passes but y & z do not', () => {
216
+ const rule: Rule = {
217
+ treatment: TreatmentEnum.True,
218
+ conditionLogic: ConditionLogicEnum.Or,
219
+ conditions: [
220
+ {
221
+ attribute: 'x',
222
+ op: OperationEnum.Equal,
223
+ value: { number: 1 },
224
+ negate: false,
225
+ },
226
+ {
227
+ conditionLogic: ConditionLogicEnum.And,
228
+ conditions: [
229
+ {
230
+ attribute: 'y',
231
+ op: OperationEnum.Equal,
232
+ value: { number: 1 },
233
+ negate: false,
234
+ },
235
+ {
236
+ attribute: 'z',
237
+ op: OperationEnum.Equal,
238
+ value: { number: 1 },
239
+ negate: false,
240
+ },
241
+ ],
242
+ } as ConditionGroup,
243
+ ],
244
+ };
245
+
246
+ const ruleEvaluator = createRuleEvaluator({ rule });
247
+ const result = ruleEvaluator({ x: 1, y: 0, z: 0 });
248
+
249
+ expect(result).toEqual(RuleEvaluationResultEnum.Treatable);
250
+ });
251
+
252
+ it('should return Insufficient for x | (y & z) when none pass', () => {
253
+ const rule: Rule = {
254
+ treatment: TreatmentEnum.True,
255
+ conditionLogic: ConditionLogicEnum.Or,
256
+ conditions: [
257
+ {
258
+ attribute: 'x',
259
+ op: OperationEnum.Equal,
260
+ value: { number: 1 },
261
+ negate: false,
262
+ },
263
+ {
264
+ conditionLogic: ConditionLogicEnum.And,
265
+ conditions: [
266
+ {
267
+ attribute: 'y',
268
+ op: OperationEnum.Equal,
269
+ value: { number: 1 },
270
+ negate: false,
271
+ },
272
+ {
273
+ attribute: 'z',
274
+ op: OperationEnum.Equal,
275
+ value: { number: 1 },
276
+ negate: false,
277
+ },
278
+ ],
279
+ } as ConditionGroup,
280
+ ],
281
+ };
282
+
283
+ const ruleEvaluator = createRuleEvaluator({ rule });
284
+ const result = ruleEvaluator({ x: 0, y: 0, z: 0 });
285
+
286
+ expect(result).toEqual(RuleEvaluationResultEnum.Insufficient);
287
+ });
288
+
289
+ it('should return Treatable for (a & b) | (c & d) when second group passes', () => {
290
+ const rule: Rule = {
291
+ treatment: TreatmentEnum.True,
292
+ conditionLogic: ConditionLogicEnum.Or,
293
+ conditions: [
294
+ {
295
+ conditionLogic: ConditionLogicEnum.And,
296
+ conditions: [
297
+ {
298
+ attribute: 'a',
299
+ op: OperationEnum.Equal,
300
+ value: { number: 1 },
301
+ negate: false,
302
+ },
303
+ {
304
+ attribute: 'b',
305
+ op: OperationEnum.Equal,
306
+ value: { number: 1 },
307
+ negate: false,
308
+ },
309
+ ],
310
+ } as ConditionGroup,
311
+ {
312
+ conditionLogic: ConditionLogicEnum.And,
313
+ conditions: [
314
+ {
315
+ attribute: 'c',
316
+ op: OperationEnum.Equal,
317
+ value: { number: 1 },
318
+ negate: false,
319
+ },
320
+ {
321
+ attribute: 'd',
322
+ op: OperationEnum.Equal,
323
+ value: { number: 1 },
324
+ negate: false,
325
+ },
326
+ ],
327
+ } as ConditionGroup,
328
+ ],
329
+ };
330
+
331
+ const ruleEvaluator = createRuleEvaluator({ rule });
332
+ const result = ruleEvaluator({ a: 0, b: 0, c: 1, d: 1 });
333
+
334
+ expect(result).toEqual(RuleEvaluationResultEnum.Treatable);
335
+ });
336
+
337
+ it('should handle deeply nested groups', () => {
338
+ const rule: Rule = {
339
+ treatment: TreatmentEnum.True,
340
+ conditionLogic: ConditionLogicEnum.And,
341
+ conditions: [
342
+ {
343
+ attribute: 'a',
344
+ op: OperationEnum.Equal,
345
+ value: { number: 1 },
346
+ negate: false,
347
+ },
348
+ {
349
+ conditionLogic: ConditionLogicEnum.Or,
350
+ conditions: [
351
+ {
352
+ attribute: 'b',
353
+ op: OperationEnum.Equal,
354
+ value: { number: 1 },
355
+ negate: false,
356
+ },
357
+ {
358
+ conditionLogic: ConditionLogicEnum.And,
359
+ conditions: [
360
+ {
361
+ attribute: 'c',
362
+ op: OperationEnum.Equal,
363
+ value: { number: 1 },
364
+ negate: false,
365
+ },
366
+ {
367
+ attribute: 'd',
368
+ op: OperationEnum.Equal,
369
+ value: { number: 1 },
370
+ negate: false,
371
+ },
372
+ ],
373
+ } as ConditionGroup,
374
+ ],
375
+ } as ConditionGroup,
376
+ ],
377
+ };
378
+
379
+ const ruleEvaluator = createRuleEvaluator({ rule });
380
+
381
+ // a=1 AND (b=0 OR (c=1 AND d=1)) -> 1 AND (0 OR 1) -> 1 AND 1 -> Treatable
382
+ expect(ruleEvaluator({ a: 1, b: 0, c: 1, d: 1 })).toEqual(RuleEvaluationResultEnum.Treatable);
383
+
384
+ // a=1 AND (b=0 OR (c=1 AND d=0)) -> 1 AND (0 OR 0) -> 1 AND 0 -> Insufficient
385
+ expect(ruleEvaluator({ a: 1, b: 0, c: 1, d: 0 })).toEqual(RuleEvaluationResultEnum.Insufficient);
386
+ });
387
+ });
135
388
  });
@@ -1,13 +1,23 @@
1
1
  import { Condition } from '../conditions';
2
2
 
3
+ export interface ConditionGroup {
4
+ conditionLogic: ConditionLogicEnum;
5
+ conditions: (Condition | ConditionGroup)[];
6
+ }
7
+
8
+ export function isConditionGroup(item: Condition | ConditionGroup): item is ConditionGroup {
9
+ return 'conditionLogic' in item && !('op' in item);
10
+ }
11
+
3
12
  export interface Rule {
4
- conditionLogic: ConditionLogicEnum.And;
5
- conditions: Condition[];
13
+ conditionLogic: ConditionLogicEnum;
14
+ conditions: (Condition | ConditionGroup)[];
6
15
  treatment: TreatmentEnum;
7
16
  }
8
17
 
9
18
  export enum ConditionLogicEnum {
10
19
  And = 'and',
20
+ Or = 'or',
11
21
  }
12
22
 
13
23
  export enum TreatmentEnum {