{"version":3,"file":"validation.mjs","names":[],"sources":["../../src/shield/validation.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n                       🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website:                  https://stormsoftware.com\n Repository:               https://github.com/storm-software/stryke\n Documentation:            https://docs.stormsoftware.com/projects/stryke\n Contact:                  https://stormsoftware.com/contact\n\n SPDX-License-Identifier:  Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n  IRules,\n  LogicRuleInterface,\n  RuleInterface,\n  ShieldRule\n} from \"./types\";\nimport { flattenObjectOf, isLogicRule, isRuleFunction } from \"./utils\";\n\n/**\n * Validates the rule tree declaration by checking references of rule\n * functions. We deem rule tree valid if no two rules with the same name point\n * to different rules.\n */\nexport function validateRuleTree<TContext extends Record<string, any>>(\n  ruleTree: IRules<TContext>\n): { status: \"ok\" } | { status: \"err\"; message: string } {\n  const rules = extractRules(ruleTree);\n\n  const valid = rules.reduce<{\n    map: Map<string, RuleInterface<TContext>>;\n    duplicates: string[];\n  }>(\n    ({ map, duplicates }, rule) => {\n      if (!map.has(rule.name)) {\n        return { map: map.set(rule.name, rule), duplicates };\n      } else if (\n        !map.get(rule.name)!.equals(rule) &&\n        !duplicates.includes(rule.name)\n      ) {\n        return {\n          map: map.set(rule.name, rule),\n          duplicates: [...duplicates, rule.name]\n        };\n      } else {\n        return { map, duplicates };\n      }\n    },\n    { map: new Map<string, RuleInterface<TContext>>(), duplicates: [] }\n  );\n\n  if (valid.duplicates.length === 0) {\n    return { status: \"ok\" };\n  } else {\n    const duplicates = valid.duplicates.join(\", \");\n\n    return {\n      status: \"err\",\n      message: `There seem to be multiple definitions of these rules: ${duplicates}`\n    };\n  }\n\n  /**\n   * Extracts rules from rule tree.\n   */\n  function extractRules<TContext extends Record<string, any>>(\n    ruleTree: IRules<TContext>\n  ): RuleInterface<TContext>[] {\n    const resolvers = flattenObjectOf<ShieldRule<TContext>>(\n      ruleTree,\n      isRuleFunction\n    );\n\n    const rules = resolvers.reduce<RuleInterface<TContext>[]>((rules, rule) => {\n      if (isLogicRule(rule)) {\n        return [\n          ...rules,\n          ...extractLogicRules(rule)\n        ] as RuleInterface<TContext>[];\n      } else {\n        return [...rules, rule] as RuleInterface<TContext>[];\n      }\n    }, []);\n\n    return rules;\n  }\n\n  /**\n   * Recursively extracts Rules from LogicRule\n   */\n  function extractLogicRules<TContext extends Record<string, any>>(\n    rule: LogicRuleInterface<TContext>\n  ): RuleInterface<TContext>[] {\n    return rule\n      .getRules()\n      .reduce<RuleInterface<TContext>[]>((acc, shieldRule) => {\n        if (isLogicRule(shieldRule)) {\n          return [\n            ...acc,\n            ...extractLogicRules(shieldRule)\n          ] as RuleInterface<TContext>[];\n        } else {\n          return [...acc, shieldRule] as RuleInterface<TContext>[];\n        }\n      }, []);\n  }\n}\n\nexport class ValidationError extends Error {\n  constructor(message: string) {\n    super(message);\n  }\n}\n"],"mappings":";;;;;;;;AA+BA,SAAgB,iBACd,UACuD;CAGvD,MAAM,QAFQ,aAAa,QAET,CAAC,CAAC,QAIjB,EAAE,KAAK,cAAc,SAAS;EAC7B,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,GACpB,OAAO;GAAE,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI;GAAG;EAAW;OAC9C,IACL,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,CAAE,OAAO,IAAI,KAChC,CAAC,WAAW,SAAS,KAAK,IAAI,GAE9B,OAAO;GACL,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI;GAC5B,YAAY,CAAC,GAAG,YAAY,KAAK,IAAI;EACvC;OAEA,OAAO;GAAE;GAAK;EAAW;CAE7B,GACA;EAAE,qBAAK,IAAI,IAAqC;EAAG,YAAY,CAAC;CAAE,CACpE;CAEA,IAAI,MAAM,WAAW,WAAW,GAC9B,OAAO,EAAE,QAAQ,KAAK;MAItB,OAAO;EACL,QAAQ;EACR,SAAS,yDAJQ,MAAM,WAAW,KAAK,IAIoC;CAC7E;;;;CAMF,SAAS,aACP,UAC2B;EAiB3B,OAhBkB,gBAChB,UACA,cAGoB,CAAC,CAAC,QAAmC,OAAO,SAAS;GACzE,IAAI,YAAY,IAAI,GAClB,OAAO,CACL,GAAG,OACH,GAAG,kBAAkB,IAAI,CAC3B;QAEA,OAAO,CAAC,GAAG,OAAO,IAAI;EAE1B,GAAG,CAAC,CAEO;CACb;;;;CAKA,SAAS,kBACP,MAC2B;EAC3B,OAAO,KACJ,SAAS,CAAC,CACV,QAAmC,KAAK,eAAe;GACtD,IAAI,YAAY,UAAU,GACxB,OAAO,CACL,GAAG,KACH,GAAG,kBAAkB,UAAU,CACjC;QAEA,OAAO,CAAC,GAAG,KAAK,UAAU;EAE9B,GAAG,CAAC,CAAC;CACT;AACF;AAEA,IAAa,kBAAb,cAAqC,MAAM;CACzC,YAAY,SAAiB;EAC3B,MAAM,OAAO;CACf;AACF"}