'use strict' /* * This example demonstrates computing fact values at runtime, and leveraging the 'path' feature * to select object properties returned by facts * * Usage: * node ./examples/03-dynamic-facts.js * * For detailed output: * DEBUG=json-rules-engine node ./examples/03-dynamic-facts.js */ require('colors') const { Engine } = require('json-rules-engine') // example client for making asynchronous requests to an api, database, etc const apiClient = require('./support/account-api-client') async function start () { /** * Setup a new engine */ const engine = new Engine() /** * Rule for identifying microsoft employees taking pto on christmas * * the account-information fact returns: * { company: 'XYZ', status: 'ABC', ptoDaysTaken: ['YYYY-MM-DD', 'YYYY-MM-DD'] } */ const microsoftRule = { conditions: { all: [{ fact: 'account-information', operator: 'equal', value: 'microsoft', path: '$.company' // access the 'company' property of "account-information" }, { fact: 'account-information', operator: 'in', value: ['active', 'paid-leave'], // 'status'' can be active or paid-leave path: '$.status' // access the 'status' property of "account-information" }, { fact: 'account-information', operator: 'contains', value: '2016-12-25', path: '$.ptoDaysTaken' // access the 'ptoDaysTaken' property of "account-information" }] }, event: { type: 'microsoft-christmas-pto', params: { message: 'current microsoft employee taking christmas day off' } } } engine.addRule(microsoftRule) /** * 'account-information' fact executes an api call and retrieves account data, feeding the results * into the engine. The major advantage of this technique is that although there are THREE conditions * requiring this data, only ONE api call is made. This results in much more efficient runtime performance. */ engine.addFact('account-information', function (params, almanac) { return almanac.factValue('accountId') .then(accountId => { return apiClient.getAccountInformation(accountId) }) }) // define fact(s) known at runtime const facts = { accountId: 'lincoln' } const { events } = await engine.run(facts) console.log(facts.accountId + ' is a ' + events.map(event => event.params.message)) } start() /* * OUTPUT: * * loading account information for "lincoln" * lincoln is a current microsoft employee taking christmas day off * * NOTES: * * - Notice that although all 3 conditions required data from the "account-information" fact, * the account-information api call is executed only ONCE. This is because fact results are * cached by default, increasing performance and lowering network requests. * * - See the 'fact' docs on how to disable fact caching */