sift-rule
v0.1.4
Published
Define rules using MongoDB/sift queries
Downloads
5
Readme
sift-rule
Define rules using sift (=~ MongoDB) queries
Terminology
- Rules have a
head
and atail
. - Rules are applied to values. If the value matches the
head
, thetail
is implied. - Rules can have an optional name.
- Rulesets are list of rules.
- Rules are applied to values. Depending on the logic (which method is used, see RuleSet API below):
- Return all matching rules
- Return all an array of the
tail
of all matching rules - Return whether ever rule in the set matched
- Return whether some rules in the set matched
Example
const {RuleSet} = require('sift-rule')
colorRules = new RuleSet()
colorRules.add({filename: {$regex: '\.js$'}}, 'red')
colorRules.add({filename: {$regex: '^foo'}}, 'green')
colorRules.filterApply({filename: 'foo.js'})
// => ['red', 'green']
colorRules.filterApply({filename: 'foo.css'})
// => ['green']
String notation
head
andtail
are separated by-->
- Rule and rule name are separated by
#==
head
andtail
are parsed as HJSON, JSON with some extensions:- Object keys can be unquoted
- Escaped backslashes are doubled, to make it easier to write regexes
- Unquoted values of the form
YYYY-MM-DD
are parsed asDate
- Unquoted values of the form
0x...
are parsed as hexadecimal numbers
{topic: "Universe"} --> 42 #== answer to everything
parses as
{
head: { topic: "Universe" },
tail: 42,
name: 'answer to everything',
}
Debugging
To get debug output:
- Set
process.env.SIFT_RULE_DEBUG='true'
in Node.js - Set
window.SIFT_RULE_DEBUG='true'
in the browser
NOTE: 'true'
must be the string true
not the boolean value true
.
Extensions
References
You can add clauses to a rule head that reference data in the object to sift
using an object with a single $ref
key and a JSON Pointer as the value.
For example, to define a rule that users may only edit their own posts:
var rule = new Rule({"post.user": {$ref: '/user/id'}}, true)
rule.apply({post: {title: 'title', user: 'john'}, user: {id: 'john'}})
// => true
rule.apply({post: {title: 'title', user: 'john'}, user: {id: 'mike'}}) // true
// => false
NOTE: references to non-existing values are set to NaN
(not-a-number)
because NaN !== NaN
so this clause will always fail.
API
Rule
Rule.new()
new Rule(stringRule)
new Rule(head[, tail][, name])
Constructor takes either a rule in String notation or head
, tail
(optional) and name (optional)
Rule.match()
rule.match(value)
Return true
if the head
matches val
, false
otherwise.
Rule.apply()
rule.match(value)
Return the tail
if the head
matches val
, undefined
otherwise.
RuleSet
RuleSet.new()
new RuleSet{[rule1, rule2...]}
new RuleSet({name: 'ruleset1', rules: [rule1, rule2...]})
Create a new Ruleset.
Managing rules
RuleSet.size
Return the number of rules in the RuleSet.
RuleSet.add()
ruleset.add(rule)
ruleset.add(ruleString)
ruleset.add(head, tail, name)
Adds a single rule to the RuleSet. If rule is not an instance of a Rule
, passes arguments to the Rule.new
.
Returns the rule.
RuleSet.addAll()
ruleset.addAll(otherRuleset)
ruleset.addAll(arrayOfRules)
RuleSet.delete()
RuleSet.deleteAll()
RuleSet.clear()
Delete all rules in this RuleSet.
Processing rules
RuleSet.every()
ruleset.every(value)
Return true
if the head
of every rule matches value
, false
otherwise.
RuleSet.some()
ruleset.some(value)
Return true
if the head
of any rule matches value
, false
if none match.
RuleSet.filter()
ruleset.filter(value)
Return the rules whose head
matches value
.
RuleSet.filterApply()
ruleset.filter(value)
Return the tail
of any rule whose head
matches value
.
RuleSet.first()
ruleset.first(value)
Return the first rule whose head
matches value
.
RuleSet.firstApply()
ruleset.firstApply(value)
Return the tail
of the first rule whose head
matches value
.