forked from CacheControl/json-rules-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path08-fact-comparison.js
More file actions
138 lines (124 loc) · 3.38 KB
/
08-fact-comparison.js
File metadata and controls
138 lines (124 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
'use strict'
/*
* This is a basic example demonstrating a condition that compares two facts
*
* Usage:
* node ./examples/08-fact-comparison.js
*
* For detailed output:
* DEBUG=json-rules-engine node ./examples/08-fact-comparison.js
*/
require('colors')
let Engine = require('../dist').Engine
/**
* Setup a new engine
*/
let engine = new Engine()
/**
* Rule for determining if account has enough money to purchase a $50 gift card product
*
* customer-account-balance >= $50 gift card
*/
let rule = {
conditions: {
all: [{
// extract 'balance' from the 'customer' account type
fact: 'account',
path: '.balance',
params: {
accountType: 'customer'
},
operator: 'greaterThanInclusive', // >=
// "value" in this instance is an object containing a fact definition
// fact helpers "path" and "params" are supported here as well
value: {
fact: 'product',
path: '.price',
params: {
productId: 'giftCard'
}
}
}]
},
event: { type: 'customer-can-afford-gift-card' }
}
engine.addRule(rule)
engine.addFact('account', (params, almanac) => {
// get account list
return almanac.factValue('accounts')
.then(accounts => {
// use "params" to filter down to the type specified, in this case the "customer" account
let customerAccount = accounts.filter(account => account.type === params.accountType)
// return the customerAccount object, which "path" will use to pull the "balance" property
return customerAccount[0]
})
})
engine.addFact('product', (params, almanac) => {
// get product list
return almanac.factValue('products')
.then(products => {
// use "params" to filter down to the product specified, in this case the "giftCard" product
let product = products.filter(product => product.productId === params.productId)
// return the product object, which "path" will use to pull the "price" property
return product[0]
})
})
/**
* Register listeners with the engine for rule success and failure
*/
let facts
engine
.on('success', (event, almanac) => {
console.log(facts.userId + ' DID '.green + 'meet conditions for the ' + event.type.underline + ' rule.')
})
.on('failure', event => {
console.log(facts.userId + ' did ' + 'NOT'.red + ' meet conditions for the ' + event.type.underline + ' rule.')
})
// define fact(s) known at runtime
let productList = {
products: [
{
productId: 'giftCard',
price: 50
}, {
productId: 'widget',
price: 45
}, {
productId: 'widget-plus',
price: 800
}
]
}
let userFacts = {
userId: 'washington',
accounts: [{
type: 'customer',
balance: 500
}, {
type: 'partner',
balance: 0
}]
}
// compile facts to be fed to the engine
facts = Object.assign({}, userFacts, productList)
engine
.run(facts) // first run, user can afford a gift card
.then(() => {
// second run; a user that cannot afford a gift card
userFacts = {
userId: 'jefferson',
accounts: [{
type: 'customer',
balance: 30
}]
}
facts = Object.assign({}, userFacts, productList)
return engine.run(facts)
})
.catch(console.log)
/*
* OUTPUT:
*
* washington DID meet conditions for the customer-can-afford-gift-card rule.
* jefferson did NOT meet conditions for the customer-can-afford-gift-card rule.
*/