Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added: Chaining support in lazy enforcement (#495)
- Loading branch information
Showing
13 changed files
with
133 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,4 +67,4 @@ | |
"build": "rollup -c ./config/rollup/rollup.config.js", | ||
"test": "jest" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,21 @@ | ||
import asArray from 'asArray'; | ||
import { RUN_RULE } from 'enforceKeywords'; | ||
import { isNull } from 'isNull'; | ||
import { isUndefined } from 'isUndefined'; | ||
|
||
/** | ||
* @param {Array} ObjectEntry Object and key leading to current value | ||
* @param {Function[]} rules Rules to validate the value with | ||
*/ | ||
export default function optional([obj, key], ...rules) { | ||
export default function optional([obj, key], ...ruleGroups) { | ||
if ( | ||
!Object.prototype.hasOwnProperty.call(obj, key) || | ||
isUndefined(obj[key] || isNull(obj[key])) | ||
) { | ||
return true; | ||
} | ||
|
||
return rules.every(fn => fn(obj[key])); | ||
return asArray(ruleGroups).every(ruleGroup => { | ||
return ruleGroup[RUN_RULE].every(fn => fn(obj[key])); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,85 @@ | ||
import compounds from 'compounds'; | ||
import { RUN_RULE } from 'enforceKeywords'; | ||
import runner from 'enforceRunner'; | ||
import isRule from 'isRule'; | ||
import proxySupported from 'proxySupported'; | ||
import rules from 'rules'; | ||
|
||
const rulesObject = Object.assign(rules(), compounds); | ||
|
||
let enforce, rulesList; | ||
let rulesList = proxySupported() ? null : Object.keys(rulesObject); | ||
|
||
const bindLazyRule = ruleName => (...args) => { | ||
return Object.defineProperty( | ||
value => rulesObject[ruleName](value, ...args), | ||
'name', | ||
{ value: ruleName } | ||
); | ||
}; | ||
|
||
const bindLazyRules = rules => | ||
rules.reduce( | ||
(enforce, ruleName) => | ||
Object.assign(enforce, { | ||
[ruleName]: bindLazyRule(ruleName), | ||
}), | ||
enforce | ||
); | ||
|
||
if (proxySupported()) { | ||
const enforceMain = value => { | ||
const proxy = new Proxy(rulesObject, { | ||
get: (rules, fnName) => { | ||
if (!isRule(rules, fnName)) { | ||
return enforce[fnName]; | ||
} | ||
|
||
return (...args) => { | ||
runner(rules[fnName], value, ...args); | ||
return proxy; | ||
}; | ||
}, | ||
}); | ||
const Enforce = value => { | ||
const target = proxySupported() ? enforce : {}; | ||
const proxy = genRuleProxy(target, ruleName => (...args) => { | ||
runner(rulesObject[ruleName], value, args); | ||
return proxy; | ||
}; | ||
|
||
// This is for lazy enforcement: enforce.isArray()([]) // true | ||
enforce = new Proxy(enforceMain, { | ||
get: (enforce, fnName) => { | ||
if (!isRule(rulesObject, fnName)) { | ||
return enforce[fnName]; | ||
} | ||
|
||
return bindLazyRule(fnName); | ||
}, | ||
}); | ||
} else { | ||
rulesList = Object.keys(rulesObject); | ||
|
||
// This is for lazy enforcement: enforce.isArray()([]) // true | ||
enforce = value => | ||
rulesList.reduce((allRules, fnName) => { | ||
if (!isRule(rulesObject, fnName)) { | ||
return enforce[fnName]; | ||
} | ||
return Object.assign(allRules, { | ||
[fnName]: (...args) => { | ||
runner(rulesObject[fnName], value, ...args); | ||
return allRules; | ||
}, | ||
}); | ||
}, {}); | ||
return proxy; | ||
}; | ||
|
||
bindLazyRules(rulesList); | ||
} | ||
const enforce = genRuleProxy(Enforce, bindLazyRule); | ||
|
||
enforce.extend = customRules => { | ||
Object.assign(rulesObject, customRules); | ||
|
||
if (!proxySupported()) { | ||
rulesList = Object.keys(rulesObject); | ||
bindLazyRules(Object.keys(customRules)); | ||
genRuleProxy(Enforce, bindLazyRule); | ||
} | ||
|
||
return enforce; | ||
}; | ||
|
||
export default enforce; | ||
|
||
// Creates a proxy object that has access to all the rules | ||
function genRuleProxy(target, output) { | ||
if (proxySupported()) { | ||
return new Proxy(target, { | ||
get: (target, fnName) => { | ||
if (!isRule(rulesObject, fnName)) { | ||
return target[fnName]; | ||
} | ||
|
||
return output(fnName); | ||
}, | ||
}); | ||
} else { | ||
/** | ||
* This method is REALLY not recommended as it is slow and iterates over | ||
* all the rules for each direct enforce reference. We only use it as a | ||
* lightweight alternative for the much faster proxy interface | ||
*/ | ||
return rulesList.reduce((target, fnName) => { | ||
return Object.defineProperties(target, { | ||
[fnName]: { get: () => output(fnName), configurable: true }, | ||
}); | ||
}, target); | ||
} | ||
} | ||
|
||
// Initiates a chain of functions directly from the `enforce` | ||
// function - that's even though we do not have any closure | ||
// there to store that data. | ||
function bindLazyRule(ruleName) { | ||
const registeredRules = []; | ||
|
||
const addFn = fnName => (...args) => { | ||
registeredRules.push( | ||
Object.defineProperty( | ||
value => rulesObject[fnName](value, ...args), | ||
'name', | ||
{ value: fnName } | ||
) | ||
); | ||
|
||
const returnvalue = genRuleProxy({}, addFn); | ||
|
||
return Object.assign(returnvalue, { | ||
[RUN_RULE]: registeredRules, | ||
}); | ||
}; | ||
|
||
return addFn(ruleName); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const RUN_RULE = 'test'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,4 +48,4 @@ | |
"context": "^1.1.0", | ||
"n4s": "^2.1.1" | ||
} | ||
} | ||
} |
Oops, something went wrong.