Skip to content

Commit b7039c5

Browse files
committed
Migrate examples to typescript
1 parent 454f679 commit b7039c5

15 files changed

+145
-149
lines changed

examples/01-hello-world.js renamed to examples/01-hello-world.mts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This is the hello-world example from the README.
43
*
@@ -9,8 +8,8 @@
98
* DEBUG=json-rules-engine node ./examples/01-hello-world.js
109
*/
1110

12-
require("colors");
13-
const { Engine } = require("json-rules-engine");
11+
import "colors";
12+
import { Engine } from "json-rules-engine";
1413

1514
async function start() {
1615
/**
@@ -51,7 +50,7 @@ async function start() {
5150
// engine.run() evaluates the rule using the facts provided
5251
const { events } = await engine.run(facts);
5352

54-
events.map((event) => console.log(event.params.data.green));
53+
events.map((event) => console.log(event.params!.data.green));
5554
}
5655

5756
start();

examples/02-nested-boolean-logic.js renamed to examples/02-nested-boolean-logic.mts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This example demonstates nested boolean logic - e.g. (x OR y) AND (a OR b).
43
*
@@ -9,8 +8,8 @@
98
* DEBUG=json-rules-engine node ./examples/02-nested-boolean-logic.js
109
*/
1110

12-
require("colors");
13-
const { Engine } = require("json-rules-engine");
11+
import "colors";
12+
import { Engine } from "json-rules-engine";
1413

1514
async function start() {
1615
/**
@@ -77,7 +76,7 @@ async function start() {
7776

7877
const { events } = await engine.run(facts);
7978

80-
events.map((event) => console.log(event.params.message.red));
79+
events.map((event) => console.log(event.params!.message.red));
8180
}
8281
start();
8382
/*

examples/03-dynamic-facts.js renamed to examples/03-dynamic-facts.mts

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This example demonstrates computing fact values at runtime, and leveraging the 'path' feature
43
* to select object properties returned by facts
@@ -10,11 +9,11 @@
109
* DEBUG=json-rules-engine node ./examples/03-dynamic-facts.js
1110
*/
1211

13-
require("colors");
14-
const { Engine } = require("json-rules-engine");
12+
import "colors";
13+
import { Engine } from "json-rules-engine";
1514

1615
// example client for making asynchronous requests to an api, database, etc
17-
const apiClient = require("./support/account-api-client");
16+
import apiClient from "./support/account-api-client.mjs";
1817

1918
async function start() {
2019
/**
@@ -65,18 +64,17 @@ async function start() {
6564
* into the engine. The major advantage of this technique is that although there are THREE conditions
6665
* requiring this data, only ONE api call is made. This results in much more efficient runtime performance.
6766
*/
68-
engine.addFact("account-information", function (params, almanac) {
69-
return almanac.factValue("accountId").then((accountId) => {
70-
return apiClient.getAccountInformation(accountId);
71-
});
67+
engine.addFact("account-information", async function (_params, almanac) {
68+
const accountId = await almanac.factValue<string>("accountId");
69+
return apiClient.getAccountInformation(accountId);
7270
});
7371

7472
// define fact(s) known at runtime
7573
const facts = { accountId: "lincoln" };
7674
const { events } = await engine.run(facts);
7775

7876
console.log(
79-
facts.accountId + " is a " + events.map((event) => event.params.message),
77+
facts.accountId + " is a " + events.map((event) => event.params!.message),
8078
);
8179
}
8280
start();

examples/04-fact-dependency.js renamed to examples/04-fact-dependency.mts

+25-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This is an advanced example that demonstrates facts with dependencies
43
* on other facts. In addition, it demonstrates facts that load data asynchronously
@@ -11,9 +10,9 @@
1110
* DEBUG=json-rules-engine node ./examples/04-fact-dependency.js
1211
*/
1312

14-
require("colors");
15-
const { Engine } = require("json-rules-engine");
16-
const accountClient = require("./support/account-api-client");
13+
import "colors";
14+
import { Engine } from "json-rules-engine";
15+
import accountClient from "./support/account-api-client.mjs";
1716

1817
async function start() {
1918
/**
@@ -72,7 +71,7 @@ async function start() {
7271
/**
7372
* Register listeners with the engine for rule success and failure
7473
*/
75-
let facts;
74+
let facts: Record<string, unknown>;
7675
engine
7776
.on("success", (event) => {
7877
console.log(
@@ -98,31 +97,33 @@ async function start() {
9897
* 'account-information' fact executes an api call and retrieves account data
9998
* - Demonstrates facts called only by other facts and never mentioned directly in a rule
10099
*/
101-
engine.addFact("account-information", (params, almanac) => {
102-
return almanac.factValue("accountId").then((accountId) => {
103-
return accountClient.getAccountInformation(accountId);
104-
});
100+
engine.addFact("account-information", async (_params, almanac) => {
101+
const accountId = await almanac.factValue<string>("accountId");
102+
return accountClient.getAccountInformation(accountId);
105103
});
106104

107105
/**
108106
* 'employee-tenure' fact retrieves account-information, and computes the duration of employment
109107
* since the account was created using 'accountInformation.createdAt'
110108
*/
111-
engine.addFact("employee-tenure", (params, almanac) => {
112-
return almanac
113-
.factValue("account-information")
114-
.then((accountInformation) => {
115-
const created = new Date(accountInformation.createdAt);
116-
const now = new Date();
117-
switch (params.unit) {
118-
case "years":
119-
return now.getFullYear() - created.getFullYear();
120-
case "milliseconds":
121-
default:
122-
return now.getTime() - created.getTime();
123-
}
124-
})
125-
.catch(console.log);
109+
engine.addFact("employee-tenure", async (params, almanac) => {
110+
try {
111+
const accountInformation = await almanac.factValue<{ createdAt: string }>(
112+
"account-information",
113+
);
114+
const created = new Date(accountInformation.createdAt);
115+
const now = new Date();
116+
switch (params.unit) {
117+
case "years":
118+
return now.getFullYear() - created.getFullYear();
119+
case "milliseconds":
120+
default:
121+
return now.getTime() - created.getTime();
122+
}
123+
} catch (err) {
124+
console.log(err);
125+
return undefined;
126+
}
126127
});
127128

128129
// first run, using washington's facts

examples/05-optimizing-runtime-with-fact-priorities.js renamed to examples/05-optimizing-runtime-with-fact-priorities.mts

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This is an advanced example that demonstrates using fact priorities to optimize the rules engine.
43
*
@@ -9,9 +8,9 @@
98
* DEBUG=json-rules-engine node ./examples/05-optimizing-runtime-with-fact-priorities.js
109
*/
1110

12-
require("colors");
13-
const { Engine } = require("json-rules-engine");
14-
const accountClient = require("./support/account-api-client");
11+
import "colors";
12+
import { Engine } from "json-rules-engine";
13+
import accountClient from "./support/account-api-client.mjs";
1514

1615
async function start() {
1716
/**
@@ -81,12 +80,11 @@ async function start() {
8180
*/
8281
engine.addFact(
8382
"account-information",
84-
(params, almanac) => {
83+
async (_params, almanac) => {
8584
// this fact will not be evaluated, because the "date" fact will fail first
8685
console.log('Checking the "account-information" fact...'); // this message will not appear
87-
return almanac.factValue("accountId").then((accountId) => {
88-
return accountClient.getAccountInformation(accountId);
89-
});
86+
const accountId = await almanac.factValue<string>("accountId");
87+
return accountClient.getAccountInformation(accountId);
9088
},
9189
{ priority: LOW },
9290
);
@@ -97,7 +95,7 @@ async function start() {
9795
*/
9896
engine.addFact(
9997
"date",
100-
(params, almanac) => {
98+
() => {
10199
console.log('Checking the "date" fact...');
102100
return Date.now();
103101
},

examples/06-custom-operators.js renamed to examples/06-custom-operators.mts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This example demonstrates using custom operators.
43
*
@@ -15,8 +14,8 @@
1514
* DEBUG=json-rules-engine node ./examples/06-custom-operators.js
1615
*/
1716

18-
require("colors");
19-
const { Engine } = require("json-rules-engine");
17+
import "colors";
18+
import { Engine } from "json-rules-engine";
2019

2120
async function start() {
2221
/**
@@ -27,7 +26,7 @@ async function start() {
2726
/**
2827
* Define a 'startsWith' custom operator, for use in later rules
2928
*/
30-
engine.addOperator("startsWith", (factValue, jsonValue) => {
29+
engine.addOperator("startsWith", (factValue: string, jsonValue: string) => {
3130
if (!factValue.length) return false;
3231
return factValue[0].toLowerCase() === jsonValue.toLowerCase();
3332
});
@@ -71,15 +70,15 @@ async function start() {
7170
engine.addRule(ruleB);
7271

7372
// utility for printing output
74-
const printEventType = {
73+
const printEventType: Record<string, string> = {
7574
"start-with-a": 'start with "a"',
7675
"start-with-b": 'start with "b"',
7776
};
7877

7978
/**
8079
* Register listeners with the engine for rule success and failure
8180
*/
82-
let facts;
81+
let facts: Record<string, unknown>;
8382
engine
8483
.on("success", (event) => {
8584
console.log(facts.word + " DID ".green + printEventType[event.type]);

examples/07-rule-chaining.js renamed to examples/07-rule-chaining.mts

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This is an advanced example demonstrating rules that passed based off the
43
* results of other rules by adding runtime facts. It also demonstrates
@@ -11,9 +10,9 @@
1110
* DEBUG=json-rules-engine node ./examples/07-rule-chaining.js
1211
*/
1312

14-
require("colors");
15-
const { Engine } = require("json-rules-engine");
16-
const { getAccountInformation } = require("./support/account-api-client");
13+
import "colors";
14+
import { Almanac, Engine } from "json-rules-engine";
15+
import apiClient from "./support/account-api-client.mjs";
1716

1817
async function start() {
1918
/**
@@ -41,16 +40,16 @@ async function start() {
4140
},
4241
event: { type: "drinks-screwdrivers" },
4342
priority: 10, // IMPORTANT! Set a higher priority for the drinkRule, so it runs first
44-
onSuccess: async function (event, almanac) {
43+
onSuccess: async function (_event: unknown, almanac: Almanac) {
4544
almanac.addFact("screwdriverAficionado", true);
4645

4746
// asychronous operations can be performed within callbacks
4847
// engine execution will not proceed until the returned promises is resolved
49-
const accountId = await almanac.factValue("accountId");
50-
const accountInfo = await getAccountInformation(accountId);
48+
const accountId = await almanac.factValue<string>("accountId");
49+
const accountInfo = await apiClient.getAccountInformation(accountId);
5150
almanac.addFact("accountInfo", accountInfo);
5251
},
53-
onFailure: function (event, almanac) {
52+
onFailure: function (_event: unknown, almanac: Almanac) {
5453
almanac.addFact("screwdriverAficionado", false);
5554
},
5655
};
@@ -92,7 +91,9 @@ async function start() {
9291
*/
9392
engine
9493
.on("success", async (event, almanac) => {
95-
const accountInfo = await almanac.factValue("accountInfo");
94+
const accountInfo = await almanac.factValue<{ company: string }>(
95+
"accountInfo",
96+
);
9697
const accountId = await almanac.factValue("accountId");
9798
console.log(
9899
`${accountId}(${accountInfo.company}) ` +
@@ -122,7 +123,7 @@ async function start() {
122123
let results = await engine.run(facts);
123124

124125
// isScrewdriverAficionado was a fact set by engine.run()
125-
let isScrewdriverAficionado = results.almanac.factValue(
126+
let isScrewdriverAficionado = await results.almanac.factValue<boolean>(
126127
"screwdriverAficionado",
127128
);
128129
console.log(

examples/08-fact-comparison.js renamed to examples/08-fact-comparison.mts

+21-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
"use strict";
21
/*
32
* This is a basic example demonstrating a condition that compares two facts
43
*
@@ -9,8 +8,8 @@
98
* DEBUG=json-rules-engine node ./examples/08-fact-comparison.js
109
*/
1110

12-
require("colors");
13-
const { Engine } = require("json-rules-engine");
11+
import "colors";
12+
import { Engine } from "json-rules-engine";
1413

1514
async function start() {
1615
/**
@@ -52,36 +51,35 @@ async function start() {
5251
};
5352
engine.addRule(rule);
5453

55-
engine.addFact("account", (params, almanac) => {
54+
engine.addFact("account", async (params, almanac) => {
5655
// get account list
57-
return almanac.factValue("accounts").then((accounts) => {
58-
// use "params" to filter down to the type specified, in this case the "customer" account
59-
const customerAccount = accounts.filter(
60-
(account) => account.type === params.accountType,
61-
);
62-
// return the customerAccount object, which "path" will use to pull the "balance" property
63-
return customerAccount[0];
64-
});
56+
const accounts = await almanac.factValue<{ type: string }[]>("accounts");
57+
// use "params" to filter down to the type specified, in this case the "customer" account
58+
const customerAccount = accounts.filter(
59+
(account) => account.type === params.accountType,
60+
);
61+
// return the customerAccount object, which "path" will use to pull the "balance" property
62+
return customerAccount[0];
6563
});
6664

67-
engine.addFact("product", (params, almanac) => {
65+
engine.addFact("product", async (params, almanac) => {
6866
// get product list
69-
return almanac.factValue("products").then((products) => {
70-
// use "params" to filter down to the product specified, in this case the "giftCard" product
71-
const product = products.filter(
72-
(product) => product.productId === params.productId,
73-
);
74-
// return the product object, which "path" will use to pull the "price" property
75-
return product[0];
76-
});
67+
const products =
68+
await almanac.factValue<{ productId: string }[]>("products");
69+
// use "params" to filter down to the product specified, in this case the "giftCard" product
70+
const product = products.filter(
71+
(product) => product.productId === params.productId,
72+
);
73+
// return the product object, which "path" will use to pull the "price" property
74+
return product[0];
7775
});
7876

7977
/**
8078
* Register listeners with the engine for rule success and failure
8179
*/
82-
let facts;
80+
let facts: Record<string, unknown>;
8381
engine
84-
.on("success", (event, almanac) => {
82+
.on("success", (event) => {
8583
console.log(
8684
facts.userId +
8785
" DID ".green +

0 commit comments

Comments
 (0)