@veridid/workflow-parser 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,42 +1,27 @@
1
1
  {
2
2
  "name": "@veridid/workflow-parser",
3
- "version": "0.3.1",
4
- "description": "Workflow Parser is a TypeScript Node.js module for parsing and managing workflow definitions in a PostgreSQL database.",
5
- "main": "dist/index.js",
3
+ "version": "0.4.0",
4
+ "description": "FOr parsing JOSN data that represents data-driven state machines and delivering the display data for clients to render.",
5
+ "main": "index.js",
6
6
  "scripts": {
7
- "build": "mkdir -p dist && cp src/schema.sql dist/",
8
- "start": "node dist/index.js",
9
- "prepublishOnly": "npm run build",
10
- "test": "echo \"Error: no test specified\" && exit 1"
7
+ "test": " tsc --resolveJsonModule test/test.ts && node test/test.js"
11
8
  },
9
+ "keywords": ["workflow", "Parser", "Data-Driven State Machine"],
10
+ "author": "VeriDID Corp. Nas TIl and Dave McKay",
11
+ "license": "MIT",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "git+https://github.com/VeriDID/workflow-parser.git"
15
- },
16
- "keywords": [
17
- "workflow",
18
- "parser",
19
- "action-menu"
20
- ],
21
- "author": "Nas Til - VeriDID",
22
- "license": "Apache-2.0",
23
- "bugs": {
24
- "url": "https://github.com/VeriDID/workflow-parser/issues"
25
- },
26
- "homepage": "https://github.com/VeriDID/workflow-parser#readme",
27
- "dependencies": {
28
- "dotenv": "^16.4.5",
29
- "pg": "^8.12.0",
30
- "uuid": "^10.0.0"
14
+ "url": "git+https://github.com/DigiCred-Holdings/workflow-parser.git"
31
15
  },
16
+ "homepage": "https://github.com/DigiCred-Holdings/workflow-parser#readme",
32
17
  "devDependencies": {
33
- "@types/dotenv": "^8.2.0",
34
- "@types/node": "^20.14.2",
35
- "@types/pg": "^8.11.6",
36
- "@types/uuid": "^9.0.8",
37
- "typescript": "^5.4.5"
18
+ "typescript": "^5.8.2"
38
19
  },
39
- "files": [
40
- "dist"
41
- ]
20
+ "dependencies": {
21
+ "@types/pg": "^8.11.11",
22
+ "pg": "^8.14.1",
23
+ "reflect-metadata": "^0.2.2",
24
+ "typedi": "^0.10.0",
25
+ "uuid": "^11.1.0"
26
+ }
42
27
  }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DefaultAction = void 0;
40
+ var DefaultAction = /** @class */ (function () {
41
+ function DefaultAction(actionExtension) {
42
+ this.actionExtension = actionExtension;
43
+ }
44
+ DefaultAction.prototype.processAction = function (currentWorkflow, instance, actionInput) {
45
+ return __awaiter(this, void 0, void 0, function () {
46
+ var transition, state, action, findtransition;
47
+ return __generator(this, function (_a) {
48
+ switch (_a.label) {
49
+ case 0:
50
+ console.log("*** processAction action=", actionInput);
51
+ transition = {
52
+ type: "none",
53
+ workflow_id: instance.workflow_id,
54
+ state_id: instance.current_state
55
+ };
56
+ if (!(actionInput.actionID != "")) return [3 /*break*/, 4];
57
+ state = currentWorkflow.states.find(function (item) { return item.state_id == instance.current_state; });
58
+ if (!(state.actions.length > 0)) return [3 /*break*/, 3];
59
+ action = state.actions.find(function (item) { return item.action_id == actionInput.actionID; });
60
+ if (!this.actionExtension) return [3 /*break*/, 2];
61
+ return [4 /*yield*/, this.actionExtension.actions(actionInput, instance, action, transition)];
62
+ case 1:
63
+ transition = _a.sent();
64
+ _a.label = 2;
65
+ case 2:
66
+ // handle the types of actions
67
+ switch (action === null || action === void 0 ? void 0 : action.type) {
68
+ case "saveData":
69
+ // check condition
70
+ if (eval(action.condition)) {
71
+ // save the data from the workflow action to the instance data
72
+ instance.state_data = Object.assign(instance.state_data, action.value);
73
+ }
74
+ break;
75
+ case "stateData":
76
+ // check condition
77
+ if (eval(action.condition)) {
78
+ // save the data from the actionInput to the instance data
79
+ instance.state_data = Object.assign(instance.state_data, actionInput.data);
80
+ }
81
+ break;
82
+ case "stateTransition":
83
+ // check condition
84
+ if (eval(action.condition)) {
85
+ // set the transition condition for a new state
86
+ transition.type = "stateTransition";
87
+ transition.state_id = action.state_id;
88
+ }
89
+ break;
90
+ case "workflowTransition":
91
+ // check condition
92
+ if (eval(action.condition)) {
93
+ // set the transition condition for a new workflow
94
+ transition.type = "workflowTransition";
95
+ transition.workflow_id = action.workflow_id;
96
+ }
97
+ break;
98
+ default:
99
+ }
100
+ _a.label = 3;
101
+ case 3:
102
+ findtransition = state.transitions.find(function (item) { return eval(item.condition); });
103
+ if (findtransition) {
104
+ transition = findtransition;
105
+ }
106
+ _a.label = 4;
107
+ case 4: return [2 /*return*/, transition];
108
+ }
109
+ });
110
+ });
111
+ };
112
+ return DefaultAction;
113
+ }());
114
+ exports.DefaultAction = DefaultAction;
@@ -0,0 +1,74 @@
1
+ import { IActionExtension } from "../interfaces/actionextension";
2
+ import { IAction, Transition } from "../interfaces/actioninterface";
3
+ import { Instance, Workflow } from "../interfaces/workflowinterface";
4
+
5
+ export class DefaultAction implements IAction{
6
+ actionExtension: IActionExtension;
7
+
8
+ constructor(actionExtension: IActionExtension) {
9
+ this.actionExtension = actionExtension;
10
+ }
11
+
12
+ async processAction(currentWorkflow: Workflow, instance: Instance, actionInput: any): Promise<Transition>{
13
+ console.log("*** processAction action=", actionInput);
14
+ // start with a blank transition
15
+ let transition:Transition = {
16
+ type: "none",
17
+ workflow_id: instance.workflow_id,
18
+ state_id: instance.current_state
19
+ };
20
+
21
+ if(actionInput.actionID!="") {
22
+ // find the state
23
+ const state = currentWorkflow.states.find(item => { return item.state_id == instance.current_state });
24
+ // Only process actions if there are any
25
+ if(state.actions.length>0) {
26
+ const action = state.actions.find(item => { return item.action_id == actionInput.actionID })
27
+ // handle the types of actions from the extension first
28
+ if(this.actionExtension) {
29
+ transition = await this.actionExtension.actions(actionInput, instance, action, transition)
30
+ }
31
+ // handle the types of actions
32
+ switch(action?.type) {
33
+ case "saveData":
34
+ // check condition
35
+ if(eval(action.condition)) {
36
+ // save the data from the workflow action to the instance data
37
+ instance.state_data = Object.assign(instance.state_data, action.value);
38
+ }
39
+ break;
40
+ case "stateData":
41
+ // check condition
42
+ if(eval(action.condition)) {
43
+ // save the data from the actionInput to the instance data
44
+ instance.state_data = Object.assign(instance.state_data, actionInput.data);
45
+ }
46
+ break;
47
+ case "stateTransition":
48
+ // check condition
49
+ if(eval(action.condition)) {
50
+ // set the transition condition for a new state
51
+ transition.type = "stateTransition";
52
+ transition.state_id = action.state_id;
53
+ }
54
+ break;
55
+ case "workflowTransition":
56
+ // check condition
57
+ if(eval(action.condition)) {
58
+ // set the transition condition for a new workflow
59
+ transition.type = "workflowTransition";
60
+ transition.workflow_id = action.workflow_id;
61
+ }
62
+ break;
63
+ default:
64
+ }
65
+ }
66
+ // check the transitions until the first true condition
67
+ let findtransition = state.transitions.find(item => { return eval(item.condition) })
68
+ if(findtransition) {
69
+ transition = findtransition;
70
+ }
71
+ }
72
+ return transition;
73
+ }
74
+ }
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DefaultDisplay = void 0;
40
+ var DefaultDisplay = /** @class */ (function () {
41
+ function DefaultDisplay(displayExtension) {
42
+ this.displayExtension = displayExtension;
43
+ }
44
+ DefaultDisplay.prototype.processDisplay = function (clientID, curentWorkflow, instance, currentState) {
45
+ return __awaiter(this, void 0, void 0, function () {
46
+ var displayData, display, displayTemplate, i, newValue;
47
+ var _a;
48
+ return __generator(this, function (_b) {
49
+ switch (_b.label) {
50
+ case 0:
51
+ console.log("*** processDisplay");
52
+ displayData = { displayData: [] };
53
+ display = curentWorkflow.states.find(function (item) { return item.state_id == currentState; });
54
+ displayTemplate = display.display_data;
55
+ i = 0;
56
+ _b.label = 1;
57
+ case 1:
58
+ if (!(i < displayTemplate.length)) return [3 /*break*/, 5];
59
+ // condition can use instance.stateData
60
+ if ((_a = displayTemplate[i]) === null || _a === void 0 ? void 0 : _a.condition) {
61
+ if (!eval(displayTemplate[i].condition)) {
62
+ return [3 /*break*/, 4]; // don't process if condition not met
63
+ }
64
+ }
65
+ if (!this.displayExtension) return [3 /*break*/, 3];
66
+ return [4 /*yield*/, this.displayExtension.displays(instance, displayTemplate[i])];
67
+ case 2:
68
+ newValue = _b.sent();
69
+ if (newValue) {
70
+ displayTemplate[i] = newValue;
71
+ }
72
+ _b.label = 3;
73
+ case 3:
74
+ switch (displayTemplate[i].type) {
75
+ case "text":
76
+ displayTemplate[i].text = this.parseString(displayTemplate[i].text, instance.state_data);
77
+ break;
78
+ case "control":
79
+ displayTemplate[i].text = this.parseString(displayTemplate[i].text, instance.state_data);
80
+ break;
81
+ }
82
+ displayData.displayData[i] = displayTemplate[i];
83
+ _b.label = 4;
84
+ case 4:
85
+ i++;
86
+ return [3 /*break*/, 1];
87
+ case 5: return [2 /*return*/, displayData];
88
+ }
89
+ });
90
+ });
91
+ };
92
+ DefaultDisplay.prototype.parseString = function (text, data) {
93
+ // Split out the string
94
+ var parts = text.split(/[{,}]/);
95
+ // check every other string segment looking for a key in data
96
+ // Text for parsing should not start with a variable "{variable} hello!"
97
+ // *** repalce this code with a more comprehensive parser
98
+ for (var i = 1; i < parts.length; i += 2) {
99
+ // find this value in the data
100
+ var value = this.findNode(parts[i], data);
101
+ if (value) {
102
+ // if there is a value, replace the entry
103
+ parts[i] = value;
104
+ }
105
+ }
106
+ // put the string back together again
107
+ return parts.join("");
108
+ };
109
+ DefaultDisplay.prototype.findNode = function (id, currentNode) {
110
+ var currentChild, result;
111
+ if (id in currentNode) {
112
+ return currentNode[id];
113
+ }
114
+ else {
115
+ // use a for loop instead of forEach to avoid nested functions
116
+ // otherwise "return" will not work properly
117
+ for (var i = 0; currentNode.children !== undefined; i += 1) {
118
+ currentChild = currentNode.children[i];
119
+ // Search in the current child
120
+ result = this.findNode(id, currentChild);
121
+ // Return the result if the node has been found
122
+ if (result !== false) {
123
+ return result;
124
+ }
125
+ }
126
+ // the node has not been found and we have no more options
127
+ return false;
128
+ }
129
+ };
130
+ return DefaultDisplay;
131
+ }());
132
+ exports.DefaultDisplay = DefaultDisplay;
@@ -0,0 +1,98 @@
1
+ import { IDisplayExtension } from "../interfaces/displayextension";
2
+ import { DisplayData, IDisplay } from "../interfaces/displayinterface";
3
+ import { Instance, Workflow } from "../interfaces/workflowinterface";
4
+
5
+ export class DefaultDisplay implements IDisplay {
6
+ displayExtension: IDisplayExtension;
7
+
8
+ constructor(displayExtension: IDisplayExtension) {
9
+ this.displayExtension = displayExtension;
10
+ }
11
+
12
+ async processDisplay(
13
+ clientID: string,
14
+ curentWorkflow: Workflow,
15
+ instance: Instance,
16
+ currentState: string): Promise<DisplayData> {
17
+
18
+ console.log("*** processDisplay");
19
+ // build the display data to return
20
+ let displayData: DisplayData = {displayData: []};
21
+ // for each display entry check condition and process if required
22
+ const display = curentWorkflow.states.find(item => { return item.state_id == currentState});
23
+ const displayTemplate = display.display_data;
24
+ for(var i=0; i<displayTemplate.length; i++) {
25
+ // condition can use instance.stateData
26
+ if(displayTemplate[i]?.condition) {
27
+ if(!eval(displayTemplate[i].condition)) {
28
+ continue; // don't process if condition not met
29
+ }
30
+ }
31
+
32
+ // handle the types of displays from the extension first
33
+ if(this.displayExtension) {
34
+ let newValue = await this.displayExtension.displays(instance, displayTemplate[i]);
35
+ if(newValue) {
36
+ displayTemplate[i]=newValue;
37
+ }
38
+ }
39
+
40
+ switch(displayTemplate[i].type) {
41
+ case "text":
42
+ displayTemplate[i].text= this.parseString(displayTemplate[i].text, instance.state_data);
43
+ break;
44
+ case "control":
45
+ displayTemplate[i].text= this.parseString(displayTemplate[i].text, instance.state_data);
46
+ break;
47
+ }
48
+ displayData.displayData[i]=displayTemplate[i];
49
+ }
50
+
51
+ return displayData;
52
+ }
53
+
54
+ parseString(text: string, data: any) {
55
+ // Split out the string
56
+ const parts = text.split(/[{,}]/);
57
+ // check every other string segment looking for a key in data
58
+ // Text for parsing should not start with a variable "{variable} hello!"
59
+ // *** repalce this code with a more comprehensive parser
60
+
61
+ for(var i=1;i<parts.length; i+=2) {
62
+ // find this value in the data
63
+ let value = this.findNode(parts[i], data);
64
+ if(value) {
65
+ // if there is a value, replace the entry
66
+ parts[i]=value;
67
+ }
68
+ }
69
+ // put the string back together again
70
+ return parts.join("");
71
+ }
72
+
73
+
74
+ findNode(id: string, currentNode: any): any {
75
+ var currentChild: any, result: any;
76
+
77
+ if (id in currentNode) {
78
+ return currentNode[id];
79
+ } else {
80
+ // use a for loop instead of forEach to avoid nested functions
81
+ // otherwise "return" will not work properly
82
+ for (var i = 0; currentNode.children !== undefined ; i += 1) {
83
+ currentChild = currentNode.children[i];
84
+
85
+ // Search in the current child
86
+ result = this.findNode(id, currentChild);
87
+
88
+ // Return the result if the node has been found
89
+ if (result !== false) {
90
+ return result;
91
+ }
92
+ }
93
+
94
+ // the node has not been found and we have no more options
95
+ return false;
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DefaultWorkflow = void 0;
40
+ var uuid_1 = require("uuid");
41
+ var DefaultWorkflow = /** @class */ (function () {
42
+ function DefaultWorkflow(dbClient) {
43
+ this.dbClient = dbClient;
44
+ }
45
+ DefaultWorkflow.prototype.getWorkflowByID = function (workflowID) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var res;
48
+ var _a;
49
+ return __generator(this, function (_b) {
50
+ switch (_b.label) {
51
+ case 0:
52
+ console.log("*** getWorkflowByID");
53
+ return [4 /*yield*/, ((_a = this.dbClient) === null || _a === void 0 ? void 0 : _a.query('SELECT * FROM workflows WHERE "workflow_id" = $1', [workflowID]))];
54
+ case 1:
55
+ res = _b.sent();
56
+ //console.log("WorkflowID=", workflowID);
57
+ //console.log("Workflow=", res.rows[0]);
58
+ return [2 /*return*/, res.rows.length > 0 ? res.rows[0] : null];
59
+ }
60
+ });
61
+ });
62
+ };
63
+ DefaultWorkflow.prototype.getInstanceByID = function (clientID, workflowID) {
64
+ return __awaiter(this, void 0, void 0, function () {
65
+ var instance, query, res, workflow;
66
+ var _a;
67
+ return __generator(this, function (_b) {
68
+ switch (_b.label) {
69
+ case 0:
70
+ console.log("*** getInstanceByID");
71
+ instance = null;
72
+ query = 'SELECT * FROM instances WHERE "client_id" = $1 AND "workflow_id" = $2';
73
+ return [4 /*yield*/, ((_a = this.dbClient) === null || _a === void 0 ? void 0 : _a.query(query, [clientID, workflowID]))];
74
+ case 1:
75
+ res = _b.sent();
76
+ if (!(res.rows.length === 0)) return [3 /*break*/, 4];
77
+ return [4 /*yield*/, this.getWorkflowByID(workflowID)];
78
+ case 2:
79
+ workflow = _b.sent();
80
+ return [4 /*yield*/, this.newInstance(clientID, workflowID, workflow.initial_state)];
81
+ case 3:
82
+ // Create new instance with new instanceID, the initial state fromt he workflow, and empoty instance data
83
+ instance = _b.sent();
84
+ return [3 /*break*/, 5];
85
+ case 4:
86
+ instance = res.rows.length > 0 ? res.rows[0] : null;
87
+ _b.label = 5;
88
+ case 5:
89
+ //console.log("Instance=", instance);
90
+ return [2 /*return*/, instance];
91
+ }
92
+ });
93
+ });
94
+ };
95
+ DefaultWorkflow.prototype.newInstance = function (clientID, workflowID, stateID) {
96
+ return __awaiter(this, void 0, void 0, function () {
97
+ var query, result, res;
98
+ var _a;
99
+ return __generator(this, function (_b) {
100
+ switch (_b.label) {
101
+ case 0:
102
+ console.log("*** newInstance=", clientID, workflowID, stateID);
103
+ query = 'INSERT INTO instances (instance_id, workflow_id, client_id, current_state, state_data) VALUES ($1, $2, $3, $4, $5)';
104
+ return [4 /*yield*/, ((_a = this.dbClient) === null || _a === void 0 ? void 0 : _a.query(query, [(0, uuid_1.v4)(), workflowID, clientID, stateID, {}]))];
105
+ case 1:
106
+ result = _b.sent();
107
+ return [4 /*yield*/, this.getInstanceByID(clientID, workflowID)];
108
+ case 2:
109
+ res = _b.sent();
110
+ return [2 /*return*/, res];
111
+ }
112
+ });
113
+ });
114
+ };
115
+ DefaultWorkflow.prototype.updateInstanceByID = function (clientID, workflowID, stateID, data) {
116
+ return __awaiter(this, void 0, void 0, function () {
117
+ var instance, query;
118
+ var _a;
119
+ return __generator(this, function (_b) {
120
+ switch (_b.label) {
121
+ case 0:
122
+ console.log("*** updateInstance=", clientID, workflowID, stateID, data);
123
+ return [4 /*yield*/, this.getInstanceByID(clientID, workflowID)];
124
+ case 1:
125
+ instance = _b.sent();
126
+ query = "UPDATE instances SET current_state = $1, state_data = $2 WHERE workflow_id = $3 AND client_id = $4";
127
+ //console.log("query=", query);
128
+ //console.log("stateID=", stateID, " data=", data);
129
+ //console.log("workflowID=", stateID, " clientID=", clientID);
130
+ return [4 /*yield*/, ((_a = this.dbClient) === null || _a === void 0 ? void 0 : _a.query(query, [stateID, JSON.stringify(data), workflowID, clientID]))];
131
+ case 2:
132
+ //console.log("query=", query);
133
+ //console.log("stateID=", stateID, " data=", data);
134
+ //console.log("workflowID=", stateID, " clientID=", clientID);
135
+ _b.sent();
136
+ return [4 /*yield*/, this.getInstanceByID(clientID, workflowID)];
137
+ case 3:
138
+ instance = _b.sent();
139
+ return [2 /*return*/, instance];
140
+ }
141
+ });
142
+ });
143
+ };
144
+ return DefaultWorkflow;
145
+ }());
146
+ exports.DefaultWorkflow = DefaultWorkflow;