@ivandt/json-rules
Version:
Rule parsing engine for JSON rules
104 lines (103 loc) • 5.25 kB
JavaScript
;
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];
};