otomato-sdk 1.2.0 → 1.3.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/dist/examples/create-action.js +2 -2
- package/dist/examples/create-automation.js +2 -8
- package/dist/examples/create-trigger.js +2 -2
- package/dist/examples/create-workflow.js +44 -0
- package/dist/examples/load-workflow.js +16 -0
- package/dist/examples/sandbox.js +18 -0
- package/dist/src/constants/Blocks.js +422 -293
- package/dist/src/index.js +1 -1
- package/dist/src/models/Edge.js +6 -1
- package/dist/src/models/Node.js +79 -6
- package/dist/src/models/Trigger.js +6 -3
- package/dist/src/models/Workflow.js +67 -0
- package/dist/src/services/ApiService.js +24 -18
- package/dist/src/utils/typeValidator.js +2 -1
- package/dist/test/action.spec.js +20 -17
- package/dist/test/automation.spec.js +26 -25
- package/dist/test/node.spec.js +34 -30
- package/dist/test/trigger.spec.js +8 -3
- package/dist/test/typeValidator.spec.js +2 -1
- package/dist/types/examples/create-workflow.d.ts +1 -0
- package/dist/types/examples/load-workflow.d.ts +1 -0
- package/dist/types/examples/sandbox.d.ts +1 -0
- package/dist/types/src/constants/Blocks.d.ts +101 -29
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/models/Action.d.ts +2 -1
- package/dist/types/src/models/Edge.d.ts +3 -0
- package/dist/types/src/models/Node.d.ts +9 -2
- package/dist/types/src/models/Parameter.d.ts +1 -1
- package/dist/types/src/models/Trigger.d.ts +3 -1
- package/dist/types/src/models/Workflow.d.ts +26 -0
- package/dist/types/src/services/ApiService.d.ts +8 -3
- package/examples/create-action.ts +2 -2
- package/examples/create-trigger.ts +2 -2
- package/examples/create-workflow.ts +44 -0
- package/examples/load-workflow.ts +10 -0
- package/package.json +2 -3
- package/src/constants/Blocks.ts +422 -292
- package/src/index.ts +1 -1
- package/src/models/Action.ts +1 -1
- package/src/models/Condition.ts +5 -5
- package/src/models/Edge.ts +8 -2
- package/src/models/Node.ts +90 -10
- package/src/models/Parameter.ts +5 -5
- package/src/models/Trigger.ts +9 -5
- package/src/models/Workflow.ts +69 -0
- package/src/services/ApiService.ts +26 -19
- package/src/utils/typeValidator.ts +2 -1
- package/test/action.spec.ts +11 -9
- package/test/automation.spec.ts +27 -26
- package/test/node.spec.ts +34 -30
- package/test/trigger.spec.ts +8 -3
- package/test/typeValidator.spec.ts +2 -1
- package/examples/create-automation.ts +0 -41
- package/src/constants/json.json +0 -16
- package/src/models/Automation.ts +0 -47
package/dist/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@ export * from './constants/chains.js';
|
|
|
4
4
|
export * from './constants/tokens.js';
|
|
5
5
|
// Exporting models
|
|
6
6
|
export * from './models/Action.js';
|
|
7
|
-
export * from './models/
|
|
7
|
+
export * from './models/Workflow.js';
|
|
8
8
|
export * from './models/Condition.js';
|
|
9
9
|
export * from './models/Parameter.js';
|
|
10
10
|
export * from './models/Trigger.js';
|
package/dist/src/models/Edge.js
CHANGED
|
@@ -17,9 +17,14 @@ export class Edge {
|
|
|
17
17
|
}
|
|
18
18
|
toJSON() {
|
|
19
19
|
return {
|
|
20
|
-
id: this.id,
|
|
21
20
|
source: this.source.getRef(),
|
|
22
21
|
target: this.target.getRef(),
|
|
23
22
|
};
|
|
24
23
|
}
|
|
24
|
+
static fromJSON(json) {
|
|
25
|
+
return new Edge({
|
|
26
|
+
source: json.source,
|
|
27
|
+
target: json.target,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
25
30
|
}
|
package/dist/src/models/Node.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
// Assuming you have the ACTIONS constant defined as you provided
|
|
1
2
|
import { validateType } from '../utils/typeValidator.js';
|
|
3
|
+
import { ACTIONS, TRIGGERS } from '../constants/Blocks.js';
|
|
2
4
|
let nodeCounter = 0;
|
|
3
5
|
const generatedRefs = new Set();
|
|
4
6
|
export class Node {
|
|
5
7
|
constructor(node) {
|
|
6
|
-
this.id =
|
|
8
|
+
this.id = null;
|
|
9
|
+
this.id = null;
|
|
10
|
+
this.blockId = node.blockId;
|
|
7
11
|
this.name = node.name;
|
|
8
12
|
this.description = node.description;
|
|
13
|
+
this.image = node.image;
|
|
9
14
|
this.parameters = {};
|
|
10
15
|
this.keyMap = {};
|
|
11
|
-
this.class = node.class;
|
|
16
|
+
this.class = node.class;
|
|
12
17
|
if (node.ref) {
|
|
13
18
|
this.ref = node.ref;
|
|
14
19
|
}
|
|
@@ -28,6 +33,9 @@ export class Node {
|
|
|
28
33
|
this.position = node.position;
|
|
29
34
|
}
|
|
30
35
|
}
|
|
36
|
+
setId(id) {
|
|
37
|
+
this.id = id;
|
|
38
|
+
}
|
|
31
39
|
setChainId(value) {
|
|
32
40
|
this.setParameter('chainId', value);
|
|
33
41
|
}
|
|
@@ -68,7 +76,16 @@ export class Node {
|
|
|
68
76
|
}
|
|
69
77
|
getParameters() {
|
|
70
78
|
return Object.keys(this.parameters).reduce((acc, key) => {
|
|
71
|
-
|
|
79
|
+
if (key.startsWith('abiParams.')) {
|
|
80
|
+
const abiKey = key.replace('abiParams.', '');
|
|
81
|
+
if (!acc.abi) {
|
|
82
|
+
acc.abi = { parameters: {} };
|
|
83
|
+
}
|
|
84
|
+
acc.abi.parameters[abiKey] = this.parameters[key].value;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
acc[key] = this.parameters[key].value;
|
|
88
|
+
}
|
|
72
89
|
return acc;
|
|
73
90
|
}, {});
|
|
74
91
|
}
|
|
@@ -76,10 +93,9 @@ export class Node {
|
|
|
76
93
|
const json = {
|
|
77
94
|
id: this.id,
|
|
78
95
|
ref: this.ref,
|
|
96
|
+
blockId: this.blockId,
|
|
79
97
|
type: this.class,
|
|
80
|
-
|
|
81
|
-
parameters: this.getParameters(),
|
|
82
|
-
}
|
|
98
|
+
parameters: this.getParameters(),
|
|
83
99
|
};
|
|
84
100
|
if (this.position) {
|
|
85
101
|
json.position = this.position;
|
|
@@ -89,4 +105,61 @@ export class Node {
|
|
|
89
105
|
getSimplifiedKey(key) {
|
|
90
106
|
return key.replace(/[.\[\]]/g, '_');
|
|
91
107
|
}
|
|
108
|
+
static fromJSON(json) {
|
|
109
|
+
let enriched = findActionByBlockId(json.blockId);
|
|
110
|
+
if (!enriched)
|
|
111
|
+
enriched = findTriggerByBlockId(json.blockId);
|
|
112
|
+
if (!enriched)
|
|
113
|
+
enriched = { name: "Unknown", description: "Unknown", image: "Unknown" };
|
|
114
|
+
const parameters = Object.keys(json.parameters).map(key => ({
|
|
115
|
+
key,
|
|
116
|
+
type: typeof json.parameters[key], // Assuming type can be derived from the value's type
|
|
117
|
+
description: '', // Add appropriate description if needed
|
|
118
|
+
value: json.parameters[key]
|
|
119
|
+
}));
|
|
120
|
+
const node = new Node({
|
|
121
|
+
blockId: json.blockId,
|
|
122
|
+
name: enriched.name,
|
|
123
|
+
description: enriched.description,
|
|
124
|
+
image: enriched.image,
|
|
125
|
+
parameters,
|
|
126
|
+
ref: json.ref,
|
|
127
|
+
position: json.position,
|
|
128
|
+
class: json.type
|
|
129
|
+
});
|
|
130
|
+
node.setId(json.id);
|
|
131
|
+
return node;
|
|
132
|
+
}
|
|
92
133
|
}
|
|
134
|
+
const findActionByBlockId = (blockId) => {
|
|
135
|
+
for (const category in ACTIONS) {
|
|
136
|
+
for (const service in ACTIONS[category]) {
|
|
137
|
+
for (const actionKey in ACTIONS[category][service]) {
|
|
138
|
+
if (ACTIONS[category][service][actionKey].blockId === blockId) {
|
|
139
|
+
return {
|
|
140
|
+
name: ACTIONS[category][service][actionKey].name,
|
|
141
|
+
description: ACTIONS[category][service][actionKey].description,
|
|
142
|
+
image: ACTIONS[category][service][actionKey].image,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
};
|
|
150
|
+
const findTriggerByBlockId = (blockId) => {
|
|
151
|
+
for (const category in TRIGGERS) {
|
|
152
|
+
for (const service in TRIGGERS[category]) {
|
|
153
|
+
for (const triggerKey in TRIGGERS[category][service]) {
|
|
154
|
+
if (TRIGGERS[category][service][triggerKey].blockId === blockId) {
|
|
155
|
+
return {
|
|
156
|
+
name: TRIGGERS[category][service][triggerKey].name,
|
|
157
|
+
description: TRIGGERS[category][service][triggerKey].description,
|
|
158
|
+
image: TRIGGERS[category][service][triggerKey].image,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
};
|
|
@@ -4,20 +4,23 @@ export class Trigger extends Node {
|
|
|
4
4
|
super(Object.assign(Object.assign({}, trigger), { class: 'trigger' }));
|
|
5
5
|
this.type = trigger.type;
|
|
6
6
|
}
|
|
7
|
+
notAPollingTrigger() {
|
|
8
|
+
return this.type === 0;
|
|
9
|
+
}
|
|
7
10
|
setCondition(value) {
|
|
8
|
-
if (this.
|
|
11
|
+
if (this.notAPollingTrigger()) {
|
|
9
12
|
throw new Error('Condition setting is not applicable for subscription based triggers.');
|
|
10
13
|
}
|
|
11
14
|
this.setParameter('condition', value);
|
|
12
15
|
}
|
|
13
16
|
setComparisonValue(value) {
|
|
14
|
-
if (this.
|
|
17
|
+
if (this.notAPollingTrigger()) {
|
|
15
18
|
throw new Error('Comparison value setting is not applicable for subscription based triggers.');
|
|
16
19
|
}
|
|
17
20
|
this.setParameter('comparisonValue', value);
|
|
18
21
|
}
|
|
19
22
|
setInterval(value) {
|
|
20
|
-
if (this.
|
|
23
|
+
if (this.notAPollingTrigger()) {
|
|
21
24
|
throw new Error('Interval setting is not applicable for subscription based triggers.');
|
|
22
25
|
}
|
|
23
26
|
this.setParameter('interval', value);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Node } from './Node.js';
|
|
11
|
+
import { Edge } from './Edge.js';
|
|
12
|
+
import { apiServices } from '../services/ApiService.js';
|
|
13
|
+
export class Workflow {
|
|
14
|
+
constructor(name = '', nodes = [], edges = []) {
|
|
15
|
+
this.id = null;
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.nodes = nodes;
|
|
18
|
+
this.edges = edges;
|
|
19
|
+
}
|
|
20
|
+
setName(name) {
|
|
21
|
+
this.name = name;
|
|
22
|
+
}
|
|
23
|
+
addNode(node) {
|
|
24
|
+
this.nodes.push(node);
|
|
25
|
+
}
|
|
26
|
+
addNodes(nodes) {
|
|
27
|
+
this.nodes.push(...nodes);
|
|
28
|
+
}
|
|
29
|
+
addEdge(edge) {
|
|
30
|
+
this.edges.push(edge);
|
|
31
|
+
}
|
|
32
|
+
addEdges(edges) {
|
|
33
|
+
this.edges.push(...edges);
|
|
34
|
+
}
|
|
35
|
+
toJSON() {
|
|
36
|
+
return {
|
|
37
|
+
id: this.id,
|
|
38
|
+
name: this.name,
|
|
39
|
+
nodes: this.nodes.map(node => node.toJSON()),
|
|
40
|
+
edges: this.edges.map(edge => edge.toJSON()),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
create() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const response = yield apiServices.post('/workflows', this.toJSON());
|
|
46
|
+
this.id = response.id; // Assign the returned ID to the workflow instance
|
|
47
|
+
// Assign IDs to the nodes based on the response
|
|
48
|
+
response.nodes.forEach((nodeResponse) => {
|
|
49
|
+
const node = this.nodes.find(n => n.getRef() === nodeResponse.ref);
|
|
50
|
+
if (node) {
|
|
51
|
+
node.setId(nodeResponse.id);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return response;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
load(workflowId) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const response = yield apiServices.get(`/workflows/${workflowId}`);
|
|
60
|
+
this.id = response.id;
|
|
61
|
+
this.name = response.name;
|
|
62
|
+
this.nodes = response.nodes.map((nodeData) => Node.fromJSON(nodeData));
|
|
63
|
+
this.edges = response.edges.map((edgeData) => Edge.fromJSON(edgeData));
|
|
64
|
+
return this;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -10,30 +10,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
// networkService.ts
|
|
11
11
|
import axios from 'axios';
|
|
12
12
|
const API_CONFIG = {
|
|
13
|
-
BASE_URL: '
|
|
13
|
+
BASE_URL: 'https://staging-api.otomato.xyz/api',
|
|
14
14
|
HEADERS: {
|
|
15
|
-
'Content-Type': 'application/json'
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
const axiosInstance = axios.create({
|
|
19
19
|
baseURL: API_CONFIG.BASE_URL,
|
|
20
20
|
headers: API_CONFIG.HEADERS
|
|
21
21
|
});
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
class ApiServices {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.cookie = null;
|
|
25
|
+
// You can add other methods (get, put, delete) similarly
|
|
26
|
+
}
|
|
27
|
+
setCookie(cookie) {
|
|
28
|
+
this.cookie = `token=${cookie}`;
|
|
29
|
+
}
|
|
30
|
+
post(url, data) {
|
|
24
31
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
console.error('Network request failed', error);
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
32
|
+
const headers = this.cookie ? { 'Cookie': this.cookie } : {};
|
|
33
|
+
const response = yield axiosInstance.post(url, data, { headers });
|
|
34
|
+
return response.data;
|
|
33
35
|
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
}
|
|
37
|
+
get(url) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const headers = this.cookie ? { 'Cookie': this.cookie } : {};
|
|
40
|
+
const response = yield axiosInstance.get(url, { headers });
|
|
41
|
+
return response.data;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export const apiServices = new ApiServices();
|
|
@@ -33,10 +33,11 @@ export function validateType(expectedType, value) {
|
|
|
33
33
|
return typeof value === 'string' && isValidUrl(value);
|
|
34
34
|
case 'phone_number':
|
|
35
35
|
return typeof value === 'string' && isValidPhoneNumber(value);
|
|
36
|
+
case 'string':
|
|
36
37
|
case 'paragraph':
|
|
37
38
|
return typeof value === 'string';
|
|
38
39
|
case 'logic_operator':
|
|
39
|
-
const validOperators = new Set(['
|
|
40
|
+
const validOperators = new Set(['gte', 'gt', 'lte', 'lt', 'eq', 'neq']);
|
|
40
41
|
return typeof value === 'string' && validOperators.has(value);
|
|
41
42
|
case 'any':
|
|
42
43
|
return true;
|
package/dist/test/action.spec.js
CHANGED
|
@@ -30,7 +30,9 @@ describe('Action Class', () => {
|
|
|
30
30
|
transferAction.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
31
31
|
const json = transferAction.toJSON();
|
|
32
32
|
expect(json).to.deep.equal({
|
|
33
|
-
|
|
33
|
+
blockId: ACTIONS.TOKENS.ERC20.TRANSFER.blockId,
|
|
34
|
+
ref: transferAction.getRef(),
|
|
35
|
+
type: 'action',
|
|
34
36
|
parameters: {
|
|
35
37
|
chainId: CHAINS.ETHEREUM,
|
|
36
38
|
'abiParams.value': 1000,
|
|
@@ -39,21 +41,22 @@ describe('Action Class', () => {
|
|
|
39
41
|
}
|
|
40
42
|
});
|
|
41
43
|
});
|
|
42
|
-
it('should create an SMS action and set parameters correctly', () => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
/*it('should create an SMS action and set parameters correctly', () => {
|
|
45
|
+
const smsAction = new Action(ACTIONS.NOTIFICATIONS.SMS);
|
|
46
|
+
smsAction.setParams("phoneNumber", "+1234567890");
|
|
47
|
+
smsAction.setParams("text", "Hello, this is a test message!");
|
|
48
|
+
|
|
49
|
+
const params = smsAction.getParameters();
|
|
50
|
+
expect(params.phoneNumber).to.equal("+1234567890");
|
|
51
|
+
expect(params.text).to.equal("Hello, this is a test message!");
|
|
52
|
+
});*/
|
|
50
53
|
it('should create a Slack action and set parameters correctly', () => {
|
|
51
|
-
const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK);
|
|
54
|
+
const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
|
|
52
55
|
slackAction.setParams("webhook", "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX");
|
|
53
|
-
slackAction.setParams("
|
|
56
|
+
slackAction.setParams("message", "This is a test message!");
|
|
54
57
|
const params = slackAction.getParameters();
|
|
55
58
|
expect(params.webhook).to.equal("https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX");
|
|
56
|
-
expect(params.
|
|
59
|
+
expect(params.message).to.equal("This is a test message!");
|
|
57
60
|
});
|
|
58
61
|
it('should throw an error for invalid parameter type', () => {
|
|
59
62
|
const transferAction = new Action(ACTIONS.TOKENS.ERC20.TRANSFER);
|
|
@@ -64,11 +67,11 @@ describe('Action Class', () => {
|
|
|
64
67
|
expect(() => transferAction.setParams("to", "invalid_address")).to.throw('Invalid type for parameter abiParams.to. Expected address.');
|
|
65
68
|
});
|
|
66
69
|
it('should throw an error for invalid URL', () => {
|
|
67
|
-
const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK);
|
|
70
|
+
const slackAction = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
|
|
68
71
|
expect(() => slackAction.setParams("webhook", "invalid_url")).to.throw('Invalid type for parameter webhook. Expected url.');
|
|
69
72
|
});
|
|
70
|
-
it('should throw an error for invalid phone number', () => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
})
|
|
73
|
+
/*it('should throw an error for invalid phone number', () => {
|
|
74
|
+
const smsAction = new Action(ACTIONS.NOTIFICATIONS.SMS);
|
|
75
|
+
expect(() => smsAction.setParams("phoneNumber", "invalid_phone_number")).to.throw('Invalid type for parameter phoneNumber. Expected phone_number.');
|
|
76
|
+
});*/
|
|
74
77
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { expect } from 'chai';
|
|
2
|
-
import {
|
|
2
|
+
import { Workflow } from '../src/models/Workflow.js';
|
|
3
3
|
import { Trigger } from '../src/models/Trigger.js';
|
|
4
4
|
import { Action } from '../src/models/Action.js';
|
|
5
5
|
import { TRIGGERS, ACTIONS, getToken, CHAINS } from '../src/index.js';
|
|
6
|
-
describe('
|
|
7
|
-
it('should create
|
|
6
|
+
describe('Workflow Class', () => {
|
|
7
|
+
it('should create a workflow with a trigger and actions', () => {
|
|
8
8
|
const trigger = new Trigger(TRIGGERS.TOKENS.ERC20.TRANSFER);
|
|
9
9
|
trigger.setChainId(CHAINS.ETHEREUM);
|
|
10
10
|
trigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
@@ -15,27 +15,28 @@ describe('Automation Class', () => {
|
|
|
15
15
|
action1.setParams("to", "0xe1432599B51d9BE1b5A27E2A2FB8e5dF684749C6");
|
|
16
16
|
action1.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
17
17
|
action1.setPosition(1, 0);
|
|
18
|
-
const action2 = new Action(ACTIONS.NOTIFICATIONS.
|
|
19
|
-
action2.setParams("
|
|
20
|
-
action2.setParams("
|
|
18
|
+
const action2 = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
|
|
19
|
+
action2.setParams("webhook", "https://webhook.url");
|
|
20
|
+
action2.setParams("message", "This is a test message");
|
|
21
21
|
action2.setPosition(2, 0);
|
|
22
|
-
const
|
|
23
|
-
const json =
|
|
22
|
+
const workflow = new Workflow("Test Workflow", [trigger, action1, action2]);
|
|
23
|
+
const json = workflow.toJSON();
|
|
24
24
|
expect(json).to.deep.equal({
|
|
25
|
-
name: "Test
|
|
25
|
+
name: "Test Workflow",
|
|
26
26
|
nodes: [trigger.toJSON(), action1.toJSON(), action2.toJSON()],
|
|
27
|
+
edges: []
|
|
27
28
|
});
|
|
28
29
|
});
|
|
29
|
-
it('should set the name of the
|
|
30
|
+
it('should set the name of the workflow', () => {
|
|
30
31
|
const trigger = new Trigger(TRIGGERS.TOKENS.ERC20.TRANSFER);
|
|
31
32
|
trigger.setChainId(CHAINS.ETHEREUM);
|
|
32
33
|
trigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
33
34
|
trigger.setPosition(0, 0);
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
expect(
|
|
35
|
+
const workflow = new Workflow("Initial Name", [trigger]);
|
|
36
|
+
workflow.setName("Updated Name");
|
|
37
|
+
expect(workflow.name).to.equal("Updated Name");
|
|
37
38
|
});
|
|
38
|
-
it('should add a trigger to the
|
|
39
|
+
it('should add a trigger to the workflow', () => {
|
|
39
40
|
const initialTrigger = new Trigger(TRIGGERS.TOKENS.ERC20.TRANSFER);
|
|
40
41
|
initialTrigger.setChainId(CHAINS.ETHEREUM);
|
|
41
42
|
initialTrigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
@@ -44,11 +45,11 @@ describe('Automation Class', () => {
|
|
|
44
45
|
newTrigger.setChainId(CHAINS.ETHEREUM);
|
|
45
46
|
newTrigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
46
47
|
newTrigger.setPosition(1, 0);
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
expect(
|
|
48
|
+
const workflow = new Workflow("Test Workflow", [initialTrigger]);
|
|
49
|
+
workflow.addNode(newTrigger);
|
|
50
|
+
expect(workflow.nodes).to.deep.equal([initialTrigger, newTrigger]);
|
|
50
51
|
});
|
|
51
|
-
it('should add actions to the
|
|
52
|
+
it('should add actions to the workflow', () => {
|
|
52
53
|
const trigger = new Trigger(TRIGGERS.TOKENS.ERC20.TRANSFER);
|
|
53
54
|
trigger.setChainId(CHAINS.ETHEREUM);
|
|
54
55
|
trigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
@@ -59,13 +60,13 @@ describe('Automation Class', () => {
|
|
|
59
60
|
action1.setParams("to", "0xe1432599B51d9BE1b5A27E2A2FB8e5dF684749C6");
|
|
60
61
|
action1.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
61
62
|
action1.setPosition(1, 0);
|
|
62
|
-
const action2 = new Action(ACTIONS.NOTIFICATIONS.
|
|
63
|
-
action2.setParams("
|
|
64
|
-
action2.setParams("
|
|
63
|
+
const action2 = new Action(ACTIONS.NOTIFICATIONS.SLACK.SEND_MESSAGE);
|
|
64
|
+
action2.setParams("webhook", "https://webhook.url");
|
|
65
|
+
action2.setParams("message", "This is a test message");
|
|
65
66
|
action2.setPosition(2, 0);
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
expect(
|
|
67
|
+
const workflow = new Workflow("Test Workflow", [trigger]);
|
|
68
|
+
workflow.addNode(action1);
|
|
69
|
+
workflow.addNode(action2);
|
|
70
|
+
expect(workflow.nodes).to.deep.equal([trigger, action1, action2]);
|
|
70
71
|
});
|
|
71
72
|
});
|
package/dist/test/node.spec.js
CHANGED
|
@@ -7,23 +7,25 @@ const DEFAULT_PARAMETERS = [
|
|
|
7
7
|
describe('Node Class', () => {
|
|
8
8
|
it('should create a node without coordinates', () => {
|
|
9
9
|
const node = new Node({
|
|
10
|
-
|
|
10
|
+
blockId: 1,
|
|
11
11
|
name: 'Test Node',
|
|
12
12
|
description: 'A node for testing',
|
|
13
13
|
parameters: DEFAULT_PARAMETERS,
|
|
14
|
-
class: 'testClass'
|
|
14
|
+
class: 'testClass',
|
|
15
|
+
image: 'a',
|
|
15
16
|
});
|
|
16
17
|
expect(node.position).to.be.undefined;
|
|
17
18
|
});
|
|
18
19
|
it('should create a node with coordinates', () => {
|
|
19
20
|
var _a, _b;
|
|
20
21
|
const node = new Node({
|
|
21
|
-
|
|
22
|
+
blockId: 2,
|
|
22
23
|
name: 'Test Node with Coordinates',
|
|
23
24
|
description: 'A node for testing with coordinates',
|
|
24
25
|
parameters: DEFAULT_PARAMETERS,
|
|
25
26
|
class: 'testClass',
|
|
26
|
-
position: { x: 100, y: 200 }
|
|
27
|
+
position: { x: 100, y: 200 },
|
|
28
|
+
image: 'a',
|
|
27
29
|
});
|
|
28
30
|
expect((_a = node.position) === null || _a === void 0 ? void 0 : _a.x).to.equal(100);
|
|
29
31
|
expect((_b = node.position) === null || _b === void 0 ? void 0 : _b.y).to.equal(200);
|
|
@@ -31,11 +33,12 @@ describe('Node Class', () => {
|
|
|
31
33
|
it('should set and get coordinates correctly', () => {
|
|
32
34
|
var _a, _b;
|
|
33
35
|
const node = new Node({
|
|
34
|
-
|
|
36
|
+
blockId: 3,
|
|
35
37
|
name: 'Test Node for Coordinates',
|
|
36
38
|
description: 'A node for testing coordinate setting',
|
|
37
39
|
parameters: DEFAULT_PARAMETERS,
|
|
38
|
-
class: 'testClass'
|
|
40
|
+
class: 'testClass',
|
|
41
|
+
image: 'a',
|
|
39
42
|
});
|
|
40
43
|
node.setPosition(300, 400);
|
|
41
44
|
expect((_a = node.position) === null || _a === void 0 ? void 0 : _a.x).to.equal(300);
|
|
@@ -43,11 +46,12 @@ describe('Node Class', () => {
|
|
|
43
46
|
});
|
|
44
47
|
it('should create a node and set parameters correctly', () => {
|
|
45
48
|
const node = new Node({
|
|
46
|
-
|
|
49
|
+
blockId: 4,
|
|
47
50
|
name: 'Test Node for Parameters',
|
|
48
51
|
description: 'A node for testing parameter setting',
|
|
49
52
|
parameters: DEFAULT_PARAMETERS,
|
|
50
|
-
class: 'testClass'
|
|
53
|
+
class: 'testClass',
|
|
54
|
+
image: 'a',
|
|
51
55
|
});
|
|
52
56
|
node.setChainId(1);
|
|
53
57
|
node.setContractAddress("0x0000000000000000000000000000000000000000");
|
|
@@ -57,69 +61,69 @@ describe('Node Class', () => {
|
|
|
57
61
|
});
|
|
58
62
|
it('should be able to export a node as json without coordinates', () => {
|
|
59
63
|
const node = new Node({
|
|
60
|
-
|
|
64
|
+
blockId: 5,
|
|
61
65
|
name: 'Test Node for JSON',
|
|
62
66
|
description: 'A node for testing JSON export',
|
|
63
67
|
parameters: DEFAULT_PARAMETERS,
|
|
64
|
-
class: 'testClass'
|
|
68
|
+
class: 'testClass',
|
|
69
|
+
image: 'a',
|
|
65
70
|
});
|
|
66
71
|
node.setChainId(1);
|
|
67
72
|
node.setContractAddress("0x0000000000000000000000000000000000000000");
|
|
68
73
|
const json = node.toJSON();
|
|
69
74
|
expect(json).to.deep.equal({
|
|
70
|
-
|
|
75
|
+
blockId: 5,
|
|
71
76
|
ref: node.getRef(),
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
contractAddress: "0x0000000000000000000000000000000000000000"
|
|
77
|
-
}
|
|
77
|
+
type: 'testClass',
|
|
78
|
+
parameters: {
|
|
79
|
+
chainId: 1,
|
|
80
|
+
contractAddress: "0x0000000000000000000000000000000000000000"
|
|
78
81
|
}
|
|
79
82
|
});
|
|
80
83
|
});
|
|
81
84
|
it('should be able to export a node as json with coordinates', () => {
|
|
82
85
|
const node = new Node({
|
|
83
|
-
|
|
86
|
+
blockId: 6,
|
|
84
87
|
name: 'Test Node for JSON with Coordinates',
|
|
85
88
|
description: 'A node for testing JSON export with coordinates',
|
|
86
89
|
parameters: DEFAULT_PARAMETERS,
|
|
87
90
|
class: 'testClass',
|
|
88
|
-
position: { x: 1, y: 2 }
|
|
91
|
+
position: { x: 1, y: 2 },
|
|
92
|
+
image: 'a',
|
|
89
93
|
});
|
|
90
94
|
node.setChainId(1);
|
|
91
95
|
node.setContractAddress("0x0000000000000000000000000000000000000000");
|
|
92
96
|
const json = node.toJSON();
|
|
93
97
|
expect(json).to.deep.equal({
|
|
94
|
-
|
|
98
|
+
type: 'testClass',
|
|
99
|
+
blockId: 6,
|
|
95
100
|
ref: node.getRef(),
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
chainId: 1,
|
|
100
|
-
contractAddress: "0x0000000000000000000000000000000000000000"
|
|
101
|
-
}
|
|
101
|
+
parameters: {
|
|
102
|
+
chainId: 1,
|
|
103
|
+
contractAddress: "0x0000000000000000000000000000000000000000"
|
|
102
104
|
},
|
|
103
105
|
position: { x: 1, y: 2 }
|
|
104
106
|
});
|
|
105
107
|
});
|
|
106
108
|
it('should throw an error for invalid parameter type', () => {
|
|
107
109
|
const node = new Node({
|
|
108
|
-
|
|
110
|
+
blockId: 7,
|
|
109
111
|
name: 'Test Node for Invalid Parameter Type',
|
|
110
112
|
description: 'A node for testing invalid parameter type',
|
|
111
113
|
parameters: DEFAULT_PARAMETERS,
|
|
112
|
-
class: 'testClass'
|
|
114
|
+
class: 'testClass',
|
|
115
|
+
image: 'a',
|
|
113
116
|
});
|
|
114
117
|
expect(() => node.setParams("chainId", "invalid")).to.throw('Invalid type for parameter chainId. Expected integer.');
|
|
115
118
|
});
|
|
116
119
|
it('should throw an error for invalid address', () => {
|
|
117
120
|
const node = new Node({
|
|
118
|
-
|
|
121
|
+
blockId: 8,
|
|
119
122
|
name: 'Test Node for Invalid Address',
|
|
120
123
|
description: 'A node for testing invalid address',
|
|
121
124
|
parameters: DEFAULT_PARAMETERS,
|
|
122
|
-
class: 'testClass'
|
|
125
|
+
class: 'testClass',
|
|
126
|
+
image: 'a',
|
|
123
127
|
});
|
|
124
128
|
expect(() => node.setParams("contractAddress", "invalid_address")).to.throw('Invalid type for parameter contractAddress. Expected address.');
|
|
125
129
|
});
|
|
@@ -29,12 +29,16 @@ describe('Trigger Class', () => {
|
|
|
29
29
|
transferTrigger.setParams("to", DEFAULT_ADDRESS);
|
|
30
30
|
transferTrigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
31
31
|
const json = transferTrigger.toJSON();
|
|
32
|
+
console.log(json);
|
|
32
33
|
expect(json).to.deep.equal({
|
|
33
|
-
|
|
34
|
+
blockId: TRIGGERS.TOKENS.ERC20.TRANSFER.blockId,
|
|
35
|
+
ref: transferTrigger.getRef(),
|
|
36
|
+
type: 'trigger',
|
|
34
37
|
parameters: {
|
|
35
38
|
chainId: CHAINS.ETHEREUM,
|
|
36
39
|
'abiParams.value': 1000,
|
|
37
40
|
'abiParams.to': DEFAULT_ADDRESS,
|
|
41
|
+
'abiParams.from': null,
|
|
38
42
|
contractAddress: getToken(CHAINS.ETHEREUM, 'USDC').contractAddress
|
|
39
43
|
}
|
|
40
44
|
});
|
|
@@ -44,14 +48,15 @@ describe('Trigger Class', () => {
|
|
|
44
48
|
balanceTrigger.setChainId(CHAINS.ETHEREUM);
|
|
45
49
|
balanceTrigger.setParams("account", DEFAULT_ADDRESS);
|
|
46
50
|
balanceTrigger.setContractAddress(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
47
|
-
balanceTrigger.setCondition("
|
|
51
|
+
balanceTrigger.setCondition("gte");
|
|
48
52
|
balanceTrigger.setComparisonValue(45000);
|
|
49
53
|
balanceTrigger.setInterval(5000);
|
|
50
54
|
const params = balanceTrigger.getParameters();
|
|
51
55
|
expect(params.chainId).to.equal(CHAINS.ETHEREUM);
|
|
52
56
|
expect(params['abiParams.account']).to.equal(DEFAULT_ADDRESS);
|
|
53
57
|
expect(params.contractAddress).to.equal(getToken(CHAINS.ETHEREUM, 'USDC').contractAddress);
|
|
54
|
-
|
|
58
|
+
console.log(balanceTrigger.toJSON());
|
|
59
|
+
expect(balanceTrigger.toJSON().parameters.condition).to.equal("gte");
|
|
55
60
|
expect(balanceTrigger.toJSON().parameters.comparisonValue).to.equal(45000);
|
|
56
61
|
expect(balanceTrigger.toJSON().parameters.interval).to.equal(5000);
|
|
57
62
|
});
|