UNPKG

@ivandt/json-rules

Version:

Rule parsing engine for JSON rules

104 lines (103 loc) 5.25 kB
"use strict"; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _RuleHelper_instances, _RuleHelper_objectDiscovery, _RuleHelper_asArray; Object.defineProperty(exports, "__esModule", { value: true }); exports.RuleHelper = void 0; const object_discovery_1 = require("./object-discovery"); class RuleHelper { constructor() { _RuleHelper_instances.add(this); _RuleHelper_objectDiscovery.set(this, new object_discovery_1.ObjectDiscovery()); } /** * Extracts all sub-rules from a condition. * @param condition The condition to extract sub-rules from. * @param results The sub-conditions result set * @param root The root condition which holds the condition to extract sub-rules from. */ extractSubRules(condition, results = [], root) { if (!root) root = condition; // Iterate each node in the condition const type = __classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").conditionType(condition); for (const node of condition[type]) { // If the node is a sub-rule we need to extract it, using the condition as it's parent if (__classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").isConditionWithResult(node)) { const subRule = this.removeAllSubRules(node); if (subRule) { results.push({ parent: this.removeAllSubRules(root), subRule }); } // Recursively find sub-rules in the sub-rule for (const element of __classPrivateFieldGet(this, _RuleHelper_instances, "m", _RuleHelper_asArray).call(this, node)) { // Ignore constraints if (!__classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").isCondition(element)) continue; results = this.extractSubRules(element, results, root); } // Do not re-process as a condition continue; } // If the node is a condition, recurse if (__classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").isCondition(node)) { results = this.extractSubRules(node, results, root); } } return results; } /** * Removes all subrules from the provided condition. * @param haystack The condition to search in and remove all sub-rules from. */ removeAllSubRules(haystack) { // Clone the condition so that we can modify it const clone = JSON.parse(JSON.stringify(haystack)); // Iterate over each node in the condition const type = __classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").conditionType(clone); for (let i = 0; i < clone[type].length; i++) { // Check if the current node is a sub-rule if (__classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").isConditionWithResult(clone[type][i])) { // Remove the node from the cloned object clone[type].splice(i, 1); // If the node is now empty, we can prune it if (Array.isArray(clone[type]) && !clone[type].length && !clone.result) return null; // Recurse to re-process updated clone return this.removeAllSubRules(clone); } // If the node is a condition, recurse if (__classPrivateFieldGet(this, _RuleHelper_objectDiscovery, "f").isCondition(clone[type][i])) { clone[type][i] = this.removeAllSubRules(clone[type][i]); } } return this.stripNullProps(clone); } /** * Removes all null properties from an object. * @param obj The object to remove null properties from. * @param defaults The default values to remove. */ stripNullProps(obj, defaults = [undefined, null, NaN, ""]) { if (defaults.includes(obj)) return; if (Array.isArray(obj)) return obj .map((v) => v && typeof v === "object" ? this.stripNullProps(v, defaults) : v) .filter((v) => !defaults.includes(v)); return Object.entries(obj).length ? Object.entries(obj) .map(([k, v]) => [ k, v && typeof v === "object" ? this.stripNullProps(v, defaults) : v, ]) .reduce((a, [k, v]) => (defaults.includes(v) ? a : Object.assign(Object.assign({}, a), { [k]: v })), {}) : obj; } } exports.RuleHelper = RuleHelper; _RuleHelper_objectDiscovery = new WeakMap(), _RuleHelper_instances = new WeakSet(), _RuleHelper_asArray = function _RuleHelper_asArray(value) { return Array.isArray(value) ? value : [value]; };