Skip to content

Commit 652cd54

Browse files
authoredDec 24, 2024··
Merge pull request #1215 from carolinetew/collapsible-treeview-visualisation
Collapsible Treeview: Initial Visualisation
2 parents 106edf6 + bc9b89c commit 652cd54

20 files changed

+2648
-44
lines changed
 

‎cli/package-lock.json

+1,172
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎cli/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"webpack-cli": "^5.0.1"
88
},
99
"dependencies": {
10+
"@types/d3": "^7.4.3",
11+
"d3": "^7.9.0",
1012
"morphir-elm": "2.86.0"
1113
}
1214
}

‎cli/treeview/src/index.ts

+284-20
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { toDistribution, Morphir } from "morphir-elm";
22
import { TreeNode } from "./treeNode";
3+
import * as d3 from "d3";
34

45
const treeviewTitle: string = "Treeview Display";
5-
document.body.innerHTML = `<h2>${treeviewTitle}</h2>`;
66

77
window.onload = Home;
88

@@ -15,9 +15,9 @@ interface RawDistribution {
1515
fornatVersion: Number;
1616
}
1717

18-
async function getIR() {
18+
export async function getIR(): Promise<TreeNode | string> {
1919
try {
20-
const response = await fetch("/server/morphir-ir.json", {
20+
let response = await fetch("/server/morphir-ir.json", {
2121
method: "GET",
2222
});
2323

@@ -33,10 +33,11 @@ async function getIR() {
3333
JSON.stringify(result)
3434
);
3535
console.log("DIST: ", distribution);
36-
const treeview: TreeNode = createTree(distribution);
36+
let treeview: TreeNode = createTree(distribution);
37+
treeview.children = nestedTree(treeview);
3738
console.log("CREATED TREE: ", treeview);
38-
document.body.innerHTML = `<h2>${treeview.name}</h2>`;
3939

40+
d3.select("div").append(() => createChart(treeview));
4041
return treeview;
4142
} catch (error) {
4243
return error instanceof Error
@@ -45,6 +46,241 @@ async function getIR() {
4546
}
4647
}
4748

49+
function createChart(data: TreeNode): SVGSVGElement | null {
50+
// Chart from: https://observablehq.com/@d3/collapsible-tree with modifications to support our implementation.
51+
// Specify the charts’ dimensions. The height is variable, depending on the layout.
52+
const marginTop = 10;
53+
const marginRight = 200;
54+
const marginBottom = 10;
55+
const marginLeft = 200;
56+
57+
// Rows are separated by dx pixels, columns by dy pixels. These names can be counter-intuitive
58+
// (dx is a height, and dy a width). This because the tree must be viewed with the root at the
59+
// “bottom”, in the data domain. The width of a column is based on the tree’s height.
60+
const root = d3.hierarchy<TreeNode>(data as TreeNode);
61+
const dx = 30; //10
62+
// const dy = ((width - marginRight - marginLeft) / (1 + root.height))+30;// NEed mor space
63+
const dy = 150;
64+
65+
// Define the tree layout and the shape for links.
66+
const tree = d3.tree<TreeNode>().nodeSize([dx, dy]);
67+
const diagonal = d3
68+
.linkHorizontal()
69+
.x((d: any) => d.y)
70+
.y((d: any) => d.x);
71+
// const diagonal = d3.linkHorizontal().x(d => d.x).y(d => d.y);
72+
73+
// Create the SVG container, a layer for the links and a layer for the nodes.
74+
const svg = d3
75+
.create("svg")
76+
.attr("width", dy)
77+
.attr("height", dx)
78+
.attr("viewBox", [-marginLeft, -marginTop, dy, dx])
79+
.attr(
80+
"style",
81+
"width: auto; height: auto; font: 10px sans-serif; user-select: none;"
82+
);
83+
84+
const gLink = svg
85+
.append("g")
86+
.attr("fill", "none")
87+
.attr("stroke", "#555")
88+
.attr("stroke-opacity", 0.4)
89+
.attr("stroke-width", 1.5);
90+
91+
const gNode = svg
92+
.append("g")
93+
.attr("cursor", "pointer")
94+
.attr("pointer-events", "all");
95+
96+
function update(event: any, source: any) {
97+
const duration = event?.altKey ? 2500 : 250; // hold the alt key to slow down the transition
98+
const nodes = (
99+
root.descendants() as d3.HierarchyPointNode<TreeNode>[]
100+
).reverse();
101+
const links = root.links();
102+
103+
// Compute the new tree layout.
104+
tree(root);
105+
106+
let left = root;
107+
let right = root;
108+
let up = root;
109+
let down = root;
110+
root.eachBefore((node) => {
111+
if (
112+
node.x === undefined ||
113+
node.y == undefined ||
114+
left.x === undefined ||
115+
right.x === undefined ||
116+
up.y === undefined ||
117+
down.y === undefined
118+
)
119+
return;
120+
if (node.x < left.x) left = node;
121+
if (node.x > right.x) right = node;
122+
if (node.y < up.y) up = node;
123+
if (node.y > down.y) down = node;
124+
});
125+
if (
126+
left.x === undefined ||
127+
right.x === undefined ||
128+
down.y == undefined ||
129+
up.y == undefined
130+
)
131+
return;
132+
133+
const height = right.x - left.x + marginTop + marginBottom;
134+
const width = down.y - up.y + marginRight + marginLeft;
135+
136+
const transition = svg
137+
.transition()
138+
.duration(duration)
139+
.attr("width", width)
140+
.attr("height", height)
141+
.attr("viewBox", [-marginLeft, left.x - marginTop, width, height].join());
142+
143+
if (!window.ResizeObserver) {
144+
transition.tween("resize", function () {
145+
return function () {
146+
svg.dispatch("toggle");
147+
};
148+
});
149+
}
150+
151+
// Update the nodes…
152+
const node = gNode
153+
.selectAll<SVGGElement, d3.HierarchyNode<TreeNode>>("g")
154+
.data(nodes, (d) => d.id as string);
155+
156+
// Enter any new nodes at the parent's previous position.
157+
const nodeEnter = node
158+
.enter()
159+
.append("g")
160+
.attr("transform", (d) => `translate(${source.y0},${source.x0})`)
161+
.attr("fill-opacity", 0)
162+
.attr("stroke-opacity", 0)
163+
.on("click", (event, d: any) => {
164+
d.children = d.children ? null : d._children;
165+
update(event, d);
166+
});
167+
168+
const types = ["Enum", "CustomType", "Record", "Alias"];
169+
nodeEnter
170+
.append("circle")
171+
.attr("r", 2.5)
172+
.attr("fill", (d: any) => {
173+
//blue node if it is a type, less bright when terminating node
174+
if (types.includes(d.data.type))
175+
return d._children ? "#0000ff" : "#5a86ad";
176+
return d._children ? "#555" : "#999";
177+
})
178+
.attr("stroke-width", 10);
179+
180+
nodeEnter
181+
.append("text")
182+
.attr("dy", "0.31em")
183+
.attr("x", (d: any) => (d._children ? -6 : 6))
184+
.attr("text-anchor", (d: any) => (d._children ? "end" : "start"))
185+
.text((d: any) => d.data.name)
186+
.attr("stroke-linejoin", "round")
187+
.attr("stroke-width", 3)
188+
.attr("stroke", "white")
189+
.attr("paint-order", "stroke");
190+
191+
// Transition nodes to their new position.
192+
const nodeUpdate = node
193+
.merge(nodeEnter)
194+
.transition(transition as any)
195+
.attr("transform", (d) => `translate(${d.y},${d.x})`)
196+
.attr("fill-opacity", 1)
197+
.attr("stroke-opacity", 1);
198+
199+
// Transition exiting nodes to the parent's new position.
200+
const nodeExit = node
201+
.exit()
202+
.transition(transition as any)
203+
.remove()
204+
.attr("transform", (d) => `translate(${source.y},${source.x})`)
205+
.attr("fill-opacity", 0)
206+
.attr("stroke-opacity", 0);
207+
208+
// Update the links…
209+
const link = gLink
210+
.selectAll<SVGGElement, d3.HierarchyPointLink<TreeNode>>("path")
211+
.data(links, (d) => d.target.id as string);
212+
213+
// Enter any new links at the parent's previous position.
214+
const linkEnter = link
215+
.enter()
216+
.append("path")
217+
.attr("d", (d) => {
218+
const o: any = { x: source.x0, y: source.y0 };
219+
return diagonal({ source: o, target: o });
220+
});
221+
222+
// Transition links to their new position.
223+
link
224+
.merge(linkEnter as any)
225+
.transition(transition as any)
226+
.attr("d", diagonal as any);
227+
228+
// Transition exiting nodes to the parent's new position.
229+
link
230+
.exit()
231+
.transition(transition as any)
232+
.remove()
233+
.attr("d", (d) => {
234+
const o: any = { x: source.x0, y: source.y0 };
235+
return diagonal({ source: o, target: o });
236+
});
237+
238+
// Stash the old positions for transition.
239+
root.eachBefore((d: any) => {
240+
d.x0 = d.x;
241+
d.y0 = d.y;
242+
});
243+
}
244+
245+
// Do the first update to the initial configuration of the tree — where a number of nodes
246+
// are open (arbitrarily selected as the root, plus nodes with 7 letters).
247+
(root as any).x0 = dy / 2;
248+
(root as any).y0 = 0;
249+
root.descendants().forEach((d: any, i) => {
250+
d.id = i;
251+
d._children = d.children;
252+
if (d.depth && d.data.name.length !== 7) d.children = null;
253+
});
254+
255+
update(null, root);
256+
257+
return svg.node();
258+
}
259+
260+
function nestedTree(flatTree: TreeNode): TreeNode[] {
261+
const root = new TreeNode("root", "placeholder");
262+
flatTree.children.forEach((node) => {
263+
const modules = node.name.split(".");
264+
let currentNode = root;
265+
266+
modules.forEach((module, idx) => {
267+
let child = currentNode.children.find((child) => child.name === module);
268+
if (!child) {
269+
currentNode.children = currentNode.children.filter(
270+
(child) => child.type == "module"
271+
);
272+
child = new TreeNode(module, "module");
273+
currentNode.children.push(child);
274+
}
275+
276+
currentNode = child;
277+
});
278+
279+
currentNode.children = node.children;
280+
});
281+
return root.children;
282+
}
283+
48284
function createTree(ir: Morphir.IR.Distribution.Distribution) {
49285
let packageName = ir.arg1.map((p) => p.map(capitalize).join(".")).join(".");
50286
let tree: TreeNode = new TreeNode(packageName, "package");
@@ -146,13 +382,21 @@ function recursiveTypeFunction(
146382

147383
switch (distNode.kind) {
148384
case "Reference":
149-
treeNodes.push(
150-
new TreeNode(toCamelCase(distNode.arg2[2]), distNode.kind)
151-
);
385+
if (!isMorphirSDK(distNode)) {
386+
treeNodes.push(
387+
new TreeNode(toCamelCase(distNode.arg2[2]), distNode.kind)
388+
);
389+
}
152390
distNode.arg3.forEach((node) =>
153391
treeNodes.push(...recursiveTypeFunction(node))
154392
);
155393
break;
394+
case "Tuple":
395+
treeNodes.push(
396+
...recursiveTypeFunction(distNode.arg2[0]),
397+
...recursiveTypeFunction(distNode.arg2[1])
398+
);
399+
break;
156400
case "Record":
157401
distNode.arg2.forEach((node) => {
158402
let parentNode = new TreeNode(toCamelCase(node.name), node.tpe.kind);
@@ -166,7 +410,8 @@ function recursiveTypeFunction(
166410
treeNodes.push(...parentNode);
167411
break;
168412
default:
169-
console.log("Not yet covered: ", distNode.kind);
413+
console.log("Unsupported type found: ", distNode.kind);
414+
treeNodes.push(new TreeNode("Unknown Type", distNode.kind));
170415
break;
171416
}
172417

@@ -218,22 +463,13 @@ function recursiveValueFunction(
218463
treeNodes.push(...arg2IfDrilldown);
219464
break;
220465
case "PatternMatch":
221-
if (distNode.arg2.kind == "Tuple") {
222-
treeNodes.push(...recursiveValueFunction(distNode.arg2.arg2[0]));
223-
treeNodes.push(...recursiveValueFunction(distNode.arg2.arg2[1]));
224-
}
466+
treeNodes.push(...recursiveValueFunction(distNode.arg2));
225467
break;
226468
case "Variable":
227469
treeNodes.push(new TreeNode(toCamelCase(distNode.arg2), "Variable"));
228470
break;
229471
case "Reference":
230-
if (
231-
!(
232-
toCamelCase(distNode.arg2[1][0]) == "basics" &&
233-
toCamelCase(distNode.arg2[0][1]) == "sDK" &&
234-
toCamelCase(distNode.arg2[0][0]) == "morphir"
235-
)
236-
) {
472+
if (!isMorphirSDK(distNode)) {
237473
//Stop normal operations from appearing in tree
238474
treeNodes.push(
239475
new TreeNode(toCamelCase(distNode.arg2[2]), "Reference")
@@ -245,7 +481,24 @@ function recursiveValueFunction(
245481
break;
246482
case "Literal":
247483
break;
484+
case "Constructor":
485+
treeNodes.push(new TreeNode(toCamelCase(distNode.arg2[2]), "Reference"));
486+
break;
487+
case "List":
488+
distNode.arg2.forEach((node) =>
489+
treeNodes.push(...recursiveValueFunction(node))
490+
);
491+
break;
492+
case "Tuple":
493+
treeNodes.push(...recursiveValueFunction(distNode.arg2[0]));
494+
treeNodes.push(...recursiveValueFunction(distNode.arg2[1]));
495+
break;
496+
case "Lambda":
497+
break;
498+
case "FieldFunction":
499+
break;
248500
default:
501+
console.log("Unsupported type found:", distNode);
249502
treeNodes.push(new TreeNode("Unknown Value", distNode.kind));
250503
break;
251504
}
@@ -272,3 +525,14 @@ function toCamelCase(array: string[]) {
272525
function capitalize(str: string): string {
273526
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
274527
}
528+
529+
function isMorphirSDK(
530+
distNode: Morphir.IR.Type.Reference<{}> | Morphir.IR.Value.Reference<{}>
531+
): boolean {
532+
return (
533+
distNode.arg2[0][1] &&
534+
distNode.arg2[0][0] &&
535+
toCamelCase(distNode.arg2[0][1]) == "sDK" &&
536+
toCamelCase(distNode.arg2[0][0]) == "morphir"
537+
);
538+
}

‎jest.config.cjs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ module.exports = {
66
'ts-jest': {
77
tsconfig: 'tsconfig.json'
88
}
9-
}
9+
},
10+
transform: {
11+
'^.+\\.(ts|tsx)?$': 'ts-jest',
12+
},
13+
moduleNameMapper: { //Fixes import/export of d3 module by pointing to bundled version of d3
14+
'^d3$': '<rootDir>/cli/node_modules/d3/dist/d3.js',
15+
},
16+
verbose: true,
17+
silent: false
1018
};

‎package-lock.json

+635-22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"hpagent": "^1.2.0",
8989
"isomorphic-git": "^1.25.7",
9090
"jest": "^29.7.0",
91+
"jest-environment-jsdom": "^29.7.0",
9192
"json-schema": "^0.4.0",
9293
"mocha": "^10.1.0",
9394
"node-elm-compiler": "^5.0.6",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules": []}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "name": "Morphir.Example.App", "type": "package", "children": [] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules":[[[["forecast"]],{"access":"Public","value":{"types":[[["wind","direction"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["east"],[]],[["north"],[]],[["south"],[]],[["west"],[]]]}]}}]],"values":[[["list","example"],{"access":"Public","value":{"doc":"","value":{"inputTypes":[],"outputType":["Reference",{},[[["morphir"],["s","d","k"]],[["list"]],["list"]],[["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["wind","direction"]],[]]]],"body":["List",["Reference",{},[[["morphir"],["s","d","k"]],[["list"]],["list"]],[["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["wind","direction"]],[]]]],[["Constructor",["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["wind","direction"]],[]],[[["morphir"],["example"],["app"]],[["forecast"]],["north"]]],["Constructor",["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["wind","direction"]],[]],[[["morphir"],["example"],["app"]],[["forecast"]],["west"]]],["Constructor",["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["wind","direction"]],[]],[[["morphir"],["example"],["app"]],[["forecast"]],["east"]]]]]}}}]],"doc":null}}]]}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"name": "Morphir.Example.App",
3+
"type": "package",
4+
"children": [
5+
{
6+
"name": "Forecast",
7+
"type": "module",
8+
"children": [
9+
{
10+
"name": "windDirection",
11+
"type": "Enum",
12+
"children": [
13+
{
14+
"name": "east",
15+
"type": "CustomType",
16+
"children": []
17+
},
18+
{
19+
"name": "north",
20+
"type": "CustomType",
21+
"children": []
22+
},
23+
{
24+
"name": "south",
25+
"type": "CustomType",
26+
"children": []
27+
},
28+
{
29+
"name": "west",
30+
"type": "CustomType",
31+
"children": []
32+
}
33+
]
34+
},
35+
{
36+
"name": "listExample",
37+
"type": "value",
38+
"children": [
39+
{
40+
"name": "north",
41+
"type": "Reference",
42+
"children": []
43+
},
44+
{
45+
"name": "west",
46+
"type": "Reference",
47+
"children": []
48+
},
49+
{
50+
"name": "east",
51+
"type": "Reference",
52+
"children": []
53+
}
54+
]
55+
}
56+
]
57+
}
58+
]
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules": [[[["u","s"],["f","r","2052","a"]],{"access": "Public", "value": {"doc": "", "types": [], "values":[]}}], [[["u","s"],["f","r","2052","a"], ["data","tables"]],{"access": "Public", "value": {"doc": "", "types": [], "values":[]}}]]}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "Morphir.Example.App",
3+
"type": "package",
4+
"children": [
5+
{
6+
"name": "US",
7+
"type": "module",
8+
"children": [
9+
{
10+
"name": "FR2052A",
11+
"type": "module",
12+
"children": [
13+
{
14+
"name": "DataTables",
15+
"type": "module",
16+
"children": []
17+
}
18+
]
19+
}
20+
]
21+
}
22+
]
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules":[[[["forecast"]],{"access":"Public","value":{"types":[[["celcius"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["custom","report"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["temp"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["celcius"]],[]]]]],[["weather"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["forecast","percent"]],[]]],[["arg","2"],["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["celcius"]],[]]]]]]}]}}],[["forecast"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Record",{},[{"name":["temp"],"tpe":["Record",{},[{"name":["low"],"tpe":["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["celcius"]],[]]},{"name":["high"],"tpe":["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["celcius"]],[]]}]]},{"name":["forecast","percent"],"tpe":["Reference",{},[[["morphir"],["example"],["app"]],[["forecast"]],["forecast","percent"]],[]]}]]]}}],[["forecast","detail"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["showers"],[]],[["thunderstorms"],[]]]}]}}],[["forecast","percent"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]]}}]],"values":[],"doc":null}}]]}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"name": "Morphir.Example.App",
3+
"type": "package",
4+
"children": [
5+
{
6+
"name": "Forecast",
7+
"type": "module",
8+
"children": [
9+
{
10+
"name": "celcius",
11+
"type": "Alias",
12+
"children": []
13+
},
14+
{
15+
"name": "customReport",
16+
"type": "CustomType",
17+
"children": [
18+
{
19+
"name": "temp",
20+
"type": "CustomType",
21+
"children": [
22+
{
23+
"name": "celcius",
24+
"type": "Reference",
25+
"children": []
26+
}
27+
]
28+
},
29+
{
30+
"name": "weather",
31+
"type": "CustomType",
32+
"children": [
33+
{
34+
"name": "forecastPercent",
35+
"type": "Reference",
36+
"children": []
37+
},
38+
{
39+
"name": "celcius",
40+
"type": "Reference",
41+
"children": []
42+
}
43+
]
44+
}
45+
]
46+
},
47+
{
48+
"name": "forecast",
49+
"type": "Record",
50+
"children": [
51+
{
52+
"name": "temp",
53+
"type": "Record",
54+
"children": [
55+
{
56+
"name": "low",
57+
"type": "Reference",
58+
"children": [
59+
{
60+
"name": "celcius",
61+
"type": "Reference",
62+
"children": []
63+
}
64+
]
65+
},
66+
{
67+
"name": "high",
68+
"type": "Reference",
69+
"children": [
70+
{
71+
"name": "celcius",
72+
"type": "Reference",
73+
"children": []
74+
}
75+
]
76+
}
77+
]
78+
},
79+
{
80+
"name": "forecastPercent",
81+
"type": "Reference",
82+
"children": [
83+
{
84+
"name": "forecastPercent",
85+
"type": "Reference",
86+
"children": []
87+
}
88+
]
89+
}
90+
]
91+
},
92+
{
93+
"name": "forecastDetail",
94+
"type": "Enum",
95+
"children": [
96+
{
97+
"name": "showers",
98+
"type": "CustomType",
99+
"children": []
100+
},
101+
{
102+
"name": "thunderstorms",
103+
"type": "CustomType",
104+
"children": []
105+
}
106+
]
107+
},
108+
{
109+
"name": "forecastPercent",
110+
"type": "Alias",
111+
"children": []
112+
}
113+
]
114+
}
115+
]
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules":[[[["analytics"]],{"access":"Public","value":{"types":[],"values":[[["safe","ratio"],{"access":"Public","value":{"doc":"","value":{"inputTypes":[[["numerator"],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]],[["denominator"],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],"outputType":["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],"body":["LetDefinition",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["result"],{"inputTypes":[],"outputType":["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],"body":["IfThenElse",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["or"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["less","than"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["numerator"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["WholeNumberLiteral",0]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["less","than"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["denominator"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["WholeNumberLiteral",0]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["err"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["StringLiteral","Only natural numbers allowed"]]],["IfThenElse",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["greater","than"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["numerator"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["denominator"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["err"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["StringLiteral","The numerator must be less than or equal to the denominator"]]],["IfThenElse",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["equal"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["denominator"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["WholeNumberLiteral",0]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["ok"]]],["Literal",["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]],["FloatLiteral",0]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["ok"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["divide"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]],[[["morphir"],["s","d","k"]],[["basics"]],["to","float"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["numerator"]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]],[[["morphir"],["s","d","k"]],[["basics"]],["to","float"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["denominator"]]]]]]]]},["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["cancelation","ratio"]],[]]]],["result"]]]}}}]],"doc":null}}]]}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "Morphir.Example.App",
3+
"type": "package",
4+
"children": [
5+
{
6+
"name": "Analytics",
7+
"type": "module",
8+
"children": [
9+
{
10+
"name": "safeRatio",
11+
"type": "value",
12+
"children": [
13+
{
14+
"name": "result",
15+
"type": "Variable",
16+
"children": [
17+
{
18+
"name": "numerator",
19+
"type": "Variable",
20+
"children": []
21+
},
22+
{
23+
"name": "denominator",
24+
"type": "Variable",
25+
"children": []
26+
}
27+
]
28+
}
29+
]
30+
}
31+
]
32+
}
33+
]
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"formatVersion":3,"distribution":["Library",[["morphir"],["example"],["app"]],[],{"modules":[[[["app"]],{"access":"Public","value":{"types":[[["a","p","i"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Record",{},[{"name":["receive","locate","list"],"tpe":["Function",{},["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["rental","i","d"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["list"]],["list"]],[["Tuple",{},[["Reference",{},[[["morphir"],["example"],["app"]],[["rentals"]],["reason"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]]]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["reserved","quantity"]],[]],["Reference",{},[[["morphir"],["example"],["app"]],[["app"]],["event"]],[]]]]]]}]]]}}],[["event"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["pickup","completed"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["rental","i","d"]],[]]]]],[["request","accepted"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["rental","i","d"]],[]]],[["arg","2"],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["reserved","quantity"]],[]]]]],[["request","rejected"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["rental","i","d"]],[]]],[["arg","2"],["Reference",{},[[["morphir"],["example"],["app"]],[["rentals"]],["reason"]],[]]]]],[["return","completed"],[[["arg","1"],["Reference",{},[[["morphir"],["example"],["app"]],[["business","terms"]],["rental","i","d"]],[]]]]]]}]}}]],"values":[],"doc":null}}],[[["business","terms"]],{"access":"Public","value":{"types":[[["allow","partials"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]}}],[["availability"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["cancelation","ratio"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["float"]],[]]]}}],[["canceled","quantity"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["current","inventory"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["existing","reservations"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["expertise","level"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["expert"],[]],[["intermediate"],[]],[["novice"],[]]]}]}}],[["pending","returns"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["probable","reservations"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["rental","i","d"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]]]}}],[["requested","quantity"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}],[["reserved","quantity"],{"access":"Public","value":{"doc":"","value":["TypeAliasDefinition",[],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]}}]],"values":[],"doc":null}}],[[["rentals"]],{"access":"Public","value":{"types":[[["reason"],{"access":"Public","value":{"doc":"","value":["CustomTypeDefinition",[],{"access":"Public","value":[[["closed","due","to","conditions"],[]],[["insufficient","availability"],[]]]}]}}]],"values":[[["request"],{"access":"Public","value":{"doc":"","value":{"inputTypes":[[["availability"],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]],[["requested","quantity"],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],"outputType":["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],"body":["IfThenElse",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]],["Apply",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]],["Reference",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["bool"]],[]]]],[[["morphir"],["s","d","k"]],[["basics"]],["less","than","or","equal"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["requested","quantity"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["availability"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["ok"]]],["Variable",["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]],["requested","quantity"]]],["Apply",["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]],["Constructor",["Function",{},["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["result"]],["result"]],[["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["Reference",{},[[["morphir"],["s","d","k"]],[["basics"]],["int"]],[]]]]],[[["morphir"],["s","d","k"]],[["result"]],["err"]]],["Literal",["Reference",{},[[["morphir"],["s","d","k"]],[["string"]],["string"]],[]],["StringLiteral","Insufficient availability"]]]]}}}]],"doc":null}}]]}]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
{
2+
"name": "Morphir.Example.App",
3+
"type": "package",
4+
"children": [
5+
{
6+
"name": "App",
7+
"type": "module",
8+
"children": [
9+
{
10+
"name": "aPI",
11+
"type": "Record",
12+
"children": [
13+
{
14+
"name": "receiveLocateList",
15+
"type": "Function",
16+
"children": [
17+
{
18+
"name": "rentalID",
19+
"type": "Reference",
20+
"children": [
21+
{
22+
"name": "reason",
23+
"type": "Reference",
24+
"children": [
25+
{
26+
"name": "reservedQuantity",
27+
"type": "Reference",
28+
"children": []
29+
},
30+
{
31+
"name": "event",
32+
"type": "Reference",
33+
"children": []
34+
}
35+
]
36+
}
37+
]
38+
}
39+
]
40+
}
41+
]
42+
},
43+
{
44+
"name": "event",
45+
"type": "CustomType",
46+
"children": [
47+
{
48+
"name": "pickupCompleted",
49+
"type": "CustomType",
50+
"children": [
51+
{
52+
"name": "rentalID",
53+
"type": "Reference",
54+
"children": []
55+
}
56+
]
57+
},
58+
{
59+
"name": "requestAccepted",
60+
"type": "CustomType",
61+
"children": [
62+
{
63+
"name": "rentalID",
64+
"type": "Reference",
65+
"children": []
66+
},
67+
{
68+
"name": "reservedQuantity",
69+
"type": "Reference",
70+
"children": []
71+
}
72+
]
73+
},
74+
{
75+
"name": "requestRejected",
76+
"type": "CustomType",
77+
"children": [
78+
{
79+
"name": "rentalID",
80+
"type": "Reference",
81+
"children": []
82+
},
83+
{
84+
"name": "reason",
85+
"type": "Reference",
86+
"children": []
87+
}
88+
]
89+
},
90+
{
91+
"name": "returnCompleted",
92+
"type": "CustomType",
93+
"children": [
94+
{
95+
"name": "rentalID",
96+
"type": "Reference",
97+
"children": []
98+
}
99+
]
100+
}
101+
]
102+
}
103+
]
104+
},
105+
{
106+
"name": "BusinessTerms",
107+
"type": "module",
108+
"children": [
109+
{
110+
"name": "allowPartials",
111+
"type": "Alias",
112+
"children": []
113+
},
114+
{
115+
"name": "availability",
116+
"type": "Alias",
117+
"children": []
118+
},
119+
{
120+
"name": "cancelationRatio",
121+
"type": "Alias",
122+
"children": []
123+
},
124+
{
125+
"name": "canceledQuantity",
126+
"type": "Alias",
127+
"children": []
128+
},
129+
{
130+
"name": "currentInventory",
131+
"type": "Alias",
132+
"children": []
133+
},
134+
{
135+
"name": "existingReservations",
136+
"type": "Alias",
137+
"children": []
138+
},
139+
{
140+
"name": "expertiseLevel",
141+
"type": "Enum",
142+
"children": [
143+
{
144+
"name": "expert",
145+
"type": "CustomType",
146+
"children": []
147+
},
148+
{
149+
"name": "intermediate",
150+
"type": "CustomType",
151+
"children": []
152+
},
153+
{
154+
"name": "novice",
155+
"type": "CustomType",
156+
"children": []
157+
}
158+
]
159+
},
160+
{
161+
"name": "pendingReturns",
162+
"type": "Alias",
163+
"children": []
164+
},
165+
{
166+
"name": "probableReservations",
167+
"type": "Alias",
168+
"children": []
169+
},
170+
{
171+
"name": "rentalID",
172+
"type": "Alias",
173+
"children": []
174+
},
175+
{
176+
"name": "requestedQuantity",
177+
"type": "Alias",
178+
"children": []
179+
},
180+
{
181+
"name": "reservedQuantity",
182+
"type": "Alias",
183+
"children": []
184+
}
185+
]
186+
},
187+
{
188+
"name": "Rentals",
189+
"type": "module",
190+
"children": [
191+
{
192+
"name": "reason",
193+
"type": "Enum",
194+
"children": [
195+
{
196+
"name": "closedDueToConditions",
197+
"type": "CustomType",
198+
"children": []
199+
},
200+
{
201+
"name": "insufficientAvailability",
202+
"type": "CustomType",
203+
"children": []
204+
}
205+
]
206+
},
207+
{
208+
"name": "request",
209+
"type": "value",
210+
"children": [
211+
{
212+
"name": "requestedQuantity",
213+
"type": "Variable",
214+
"children": [
215+
{
216+
"name": "availability",
217+
"type": "Variable",
218+
"children": []
219+
}
220+
]
221+
}
222+
]
223+
}
224+
]
225+
}
226+
]
227+
}
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
import { TextEncoder, TextDecoder } from "util";
5+
6+
Object.assign(global, { TextDecoder, TextEncoder });
7+
import { JSDOM } from "jsdom";
8+
import { getIR } from "../../cli/treeview/src/index";
9+
10+
const { window } = new JSDOM(`<!DOCTYPE html><body><div></div></body>`);
11+
jest.mock("node-fetch", () => jest.fn());
12+
13+
describe("test getIR", () => {
14+
beforeEach(() => {
15+
global.fetch = jest.fn();
16+
(fetch as jest.Mock).mockClear();
17+
});
18+
19+
test("test IR with no modules", async () => {
20+
const expectedTree = require("./test-ir-files/base-result.json");
21+
22+
expect(await mockIR("./test-ir-files/base-ir.json")).toEqual(expectedTree);
23+
});
24+
25+
test("test multilevel modules", async () => {
26+
const expectedTree = require("./test-ir-files/multilevelModules-result.json");
27+
28+
expect(await mockIR("./test-ir-files/multilevelModules-ir.json")).toEqual(
29+
expectedTree
30+
);
31+
});
32+
33+
test("test simple value tree", async () => {
34+
//Tests node types LetDefinition, Apply, Reference, Variable, IfThenElse, and Literal
35+
const expectedTree = require("./test-ir-files/simpleValueTree-result.json");
36+
37+
expect(await mockIR("./test-ir-files/simpleValueTree-ir.json")).toEqual(
38+
expectedTree
39+
);
40+
});
41+
42+
test("test simple type tree", async () => {
43+
//Tests node types Record, Enum, Custom Type, and Alias
44+
const expectedTree = require("./test-ir-files/simpleTypeTree-result.json");
45+
46+
expect(await mockIR("./test-ir-files/simpleTypeTree-ir.json")).toEqual(
47+
expectedTree
48+
);
49+
});
50+
51+
test("test List and Constructor nodes", async () => {
52+
const expectedTree = require("./test-ir-files/listType-result.json");
53+
54+
expect(await mockIR("./test-ir-files/listType-ir.json")).toEqual(
55+
expectedTree
56+
);
57+
});
58+
59+
test("test Tuple nodes", async () => {
60+
const expectedTree = require("./test-ir-files/tupleType-result.json");
61+
62+
expect(await mockIR("./test-ir-files/tupleType-ir.json")).toEqual(
63+
expectedTree
64+
);
65+
});
66+
});
67+
68+
async function mockIR(path: string) {
69+
(fetch as jest.Mock).mockResolvedValueOnce({
70+
ok: true,
71+
json: jest.fn().mockResolvedValueOnce(require(path)),
72+
});
73+
return await getIR();
74+
}

‎tsconfig.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
"compilerOptions": {
33
"types": ["node", "mocha", "jest"],
44
"lib": ["ES2019"],
5-
"target": "es2019"
5+
"target": "es2019",
6+
"module": "nodenext",
7+
"moduleResolution": "nodenext",
8+
"resolveJsonModule": true,
69
}
10+
711
}

0 commit comments

Comments
 (0)
Please sign in to comment.