@abyss-project/console 1.0.28 → 1.0.30
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/api/workflow.api.d.ts +2 -1
- package/dist/api/workflow.api.js +6 -1
- package/dist/expressions/functions/array.d.ts +2 -0
- package/dist/expressions/functions/array.js +252 -0
- package/dist/expressions/functions/crypto.d.ts +2 -0
- package/dist/expressions/functions/crypto.js +101 -0
- package/dist/expressions/functions/datetime.d.ts +2 -0
- package/dist/expressions/functions/datetime.js +256 -0
- package/dist/expressions/functions/index.d.ts +7 -0
- package/dist/expressions/functions/index.js +46 -0
- package/dist/expressions/functions/math.d.ts +2 -0
- package/dist/expressions/functions/math.js +174 -0
- package/dist/expressions/functions/string.d.ts +2 -0
- package/dist/expressions/functions/string.js +301 -0
- package/dist/expressions/functions/utility.d.ts +2 -0
- package/dist/expressions/functions/utility.js +230 -0
- package/dist/expressions/helpers.d.ts +26 -0
- package/dist/expressions/helpers.js +132 -0
- package/dist/expressions/index.d.ts +5 -0
- package/dist/expressions/index.js +16 -0
- package/dist/expressions/mapper.d.ts +9 -0
- package/dist/expressions/mapper.js +88 -0
- package/dist/expressions/parser.d.ts +3 -0
- package/dist/expressions/parser.js +97 -0
- package/dist/expressions/pipes/array-pipes.d.ts +2 -0
- package/dist/expressions/pipes/array-pipes.js +248 -0
- package/dist/expressions/pipes/index.d.ts +8 -0
- package/dist/expressions/pipes/index.js +40 -0
- package/dist/expressions/pipes/object-pipes.d.ts +2 -0
- package/dist/expressions/pipes/object-pipes.js +243 -0
- package/dist/expressions/pipes/string-pipes.d.ts +9 -0
- package/dist/expressions/pipes/string-pipes.js +178 -0
- package/dist/expressions/resolver.d.ts +12 -0
- package/dist/expressions/resolver.js +88 -0
- package/dist/expressions/types.d.ts +36 -0
- package/dist/expressions/types.js +2 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -1
- package/dist/types/interface/api/requests/workflow.request.d.ts +10 -0
- package/dist/types/interface/api/responses/workflow.response.d.ts +4 -0
- package/dist/utils/webhook-trigger.utils.js +10 -6
- package/dist/workflow-expressions/functions/array.d.ts +2 -0
- package/dist/workflow-expressions/functions/array.js +252 -0
- package/dist/workflow-expressions/functions/crypto.d.ts +2 -0
- package/dist/workflow-expressions/functions/crypto.js +101 -0
- package/dist/workflow-expressions/functions/datetime.d.ts +2 -0
- package/dist/workflow-expressions/functions/datetime.js +256 -0
- package/dist/workflow-expressions/functions/index.d.ts +7 -0
- package/dist/workflow-expressions/functions/index.js +46 -0
- package/dist/workflow-expressions/functions/math.d.ts +2 -0
- package/dist/workflow-expressions/functions/math.js +174 -0
- package/dist/workflow-expressions/functions/string.d.ts +2 -0
- package/dist/workflow-expressions/functions/string.js +301 -0
- package/dist/workflow-expressions/functions/utility.d.ts +2 -0
- package/dist/workflow-expressions/functions/utility.js +230 -0
- package/dist/workflow-expressions/helpers.d.ts +26 -0
- package/dist/workflow-expressions/helpers.js +130 -0
- package/dist/workflow-expressions/index.d.ts +15 -0
- package/dist/workflow-expressions/index.js +61 -0
- package/dist/workflow-expressions/parser.d.ts +8 -0
- package/dist/workflow-expressions/parser.js +456 -0
- package/dist/workflow-expressions/pipes/array-pipes.d.ts +2 -0
- package/dist/workflow-expressions/pipes/array-pipes.js +248 -0
- package/dist/workflow-expressions/pipes/index.d.ts +8 -0
- package/dist/workflow-expressions/pipes/index.js +40 -0
- package/dist/workflow-expressions/pipes/object-pipes.d.ts +2 -0
- package/dist/workflow-expressions/pipes/object-pipes.js +243 -0
- package/dist/workflow-expressions/pipes/string-pipes.d.ts +9 -0
- package/dist/workflow-expressions/pipes/string-pipes.js +178 -0
- package/dist/workflow-expressions/resolver.d.ts +8 -0
- package/dist/workflow-expressions/resolver.js +260 -0
- package/dist/workflow-expressions/types.d.ts +141 -0
- package/dist/workflow-expressions/types.js +33 -0
- package/package.json +2 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stringPipes = void 0;
|
|
4
|
+
exports.stringPipes = {
|
|
5
|
+
upper: {
|
|
6
|
+
name: 'upper',
|
|
7
|
+
description: 'Converts to uppercase',
|
|
8
|
+
category: 'string',
|
|
9
|
+
signature: 'upper',
|
|
10
|
+
examples: ['{{trigger.name | upper}}'],
|
|
11
|
+
execute: (value) => String(value).toUpperCase(),
|
|
12
|
+
},
|
|
13
|
+
lower: {
|
|
14
|
+
name: 'lower',
|
|
15
|
+
description: 'Converts to lowercase',
|
|
16
|
+
category: 'string',
|
|
17
|
+
signature: 'lower',
|
|
18
|
+
examples: ['{{trigger.email | lower}}'],
|
|
19
|
+
execute: (value) => String(value).toLowerCase(),
|
|
20
|
+
},
|
|
21
|
+
capitalize: {
|
|
22
|
+
name: 'capitalize',
|
|
23
|
+
description: 'Capitalizes the first letter',
|
|
24
|
+
category: 'string',
|
|
25
|
+
signature: 'capitalize',
|
|
26
|
+
examples: ['{{trigger.name | capitalize}}'],
|
|
27
|
+
execute: (value) => {
|
|
28
|
+
const str = String(value);
|
|
29
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
trim: {
|
|
33
|
+
name: 'trim',
|
|
34
|
+
description: 'Removes whitespace from both ends',
|
|
35
|
+
category: 'string',
|
|
36
|
+
signature: 'trim',
|
|
37
|
+
examples: ['{{trigger.input | trim}}'],
|
|
38
|
+
execute: (value) => String(value).trim(),
|
|
39
|
+
},
|
|
40
|
+
truncate: {
|
|
41
|
+
name: 'truncate',
|
|
42
|
+
description: 'Truncates a string to a specified length',
|
|
43
|
+
category: 'string',
|
|
44
|
+
signature: 'truncate(length)',
|
|
45
|
+
examples: ['{{trigger.description | truncate(100)}}'],
|
|
46
|
+
execute: (value, length) => {
|
|
47
|
+
const str = String(value);
|
|
48
|
+
const len = Number(length);
|
|
49
|
+
return str.length > len ? str.substring(0, len) + '...' : str;
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
replace: {
|
|
53
|
+
name: 'replace',
|
|
54
|
+
description: 'Replaces occurrences of a pattern',
|
|
55
|
+
category: 'string',
|
|
56
|
+
signature: 'replace(search, replacement)',
|
|
57
|
+
examples: ['{{trigger.text | replace("old", "new")}}'],
|
|
58
|
+
execute: (value, search, replacement) => {
|
|
59
|
+
const searchStr = String(search);
|
|
60
|
+
const replaceStr = String(replacement);
|
|
61
|
+
return String(value).replace(new RegExp(searchStr.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), replaceStr);
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
split: {
|
|
65
|
+
name: 'split',
|
|
66
|
+
description: 'Splits a string into an array',
|
|
67
|
+
category: 'string',
|
|
68
|
+
signature: 'split(separator)',
|
|
69
|
+
examples: ['{{trigger.tags | split(",")}}'],
|
|
70
|
+
execute: (value, separator) => {
|
|
71
|
+
return String(value).split(String(separator));
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
substring: {
|
|
75
|
+
name: 'substring',
|
|
76
|
+
description: 'Extracts a substring',
|
|
77
|
+
category: 'string',
|
|
78
|
+
signature: 'substring(start, end?)',
|
|
79
|
+
examples: ['{{trigger.id | substring(0, 8)}}'],
|
|
80
|
+
execute: (value, start, end) => {
|
|
81
|
+
return String(value).substring(Number(start), end !== undefined ? Number(end) : undefined);
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
padStart: {
|
|
85
|
+
name: 'padStart',
|
|
86
|
+
description: 'Pads a string from the start',
|
|
87
|
+
category: 'string',
|
|
88
|
+
signature: 'padStart(length, padString?)',
|
|
89
|
+
examples: ['{{trigger.id | padStart(10, "0")}}'],
|
|
90
|
+
execute: (value, length, padString) => {
|
|
91
|
+
return String(value).padStart(Number(length), padString !== undefined ? String(padString) : ' ');
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
padEnd: {
|
|
95
|
+
name: 'padEnd',
|
|
96
|
+
description: 'Pads a string from the end',
|
|
97
|
+
category: 'string',
|
|
98
|
+
signature: 'padEnd(length, padString?)',
|
|
99
|
+
examples: ['{{trigger.code | padEnd(5, "X")}}'],
|
|
100
|
+
execute: (value, length, padString) => {
|
|
101
|
+
return String(value).padEnd(Number(length), padString !== undefined ? String(padString) : ' ');
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
repeat: {
|
|
105
|
+
name: 'repeat',
|
|
106
|
+
description: 'Repeats a string n times',
|
|
107
|
+
category: 'string',
|
|
108
|
+
signature: 'repeat(count)',
|
|
109
|
+
examples: ['{{trigger.char | repeat(3)}}'],
|
|
110
|
+
execute: (value, count) => {
|
|
111
|
+
return String(value).repeat(Number(count));
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
reverse: {
|
|
115
|
+
name: 'reverse',
|
|
116
|
+
description: 'Reverses a string',
|
|
117
|
+
category: 'string',
|
|
118
|
+
signature: 'reverse',
|
|
119
|
+
examples: ['{{trigger.text | reverse}}'],
|
|
120
|
+
execute: (value) => {
|
|
121
|
+
return String(value).split('').reverse().join('');
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
slugify: {
|
|
125
|
+
name: 'slugify',
|
|
126
|
+
description: 'Converts to URL-friendly slug',
|
|
127
|
+
category: 'string',
|
|
128
|
+
signature: 'slugify',
|
|
129
|
+
examples: ['{{trigger.title | slugify}}'],
|
|
130
|
+
execute: (value) => {
|
|
131
|
+
return String(value)
|
|
132
|
+
.toLowerCase()
|
|
133
|
+
.trim()
|
|
134
|
+
.replace(/[^\w\s-]/g, '')
|
|
135
|
+
.replace(/[\s_-]+/g, '-')
|
|
136
|
+
.replace(/^-+|-+$/g, '');
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
camelCase: {
|
|
140
|
+
name: 'camelCase',
|
|
141
|
+
description: 'Converts to camelCase',
|
|
142
|
+
category: 'string',
|
|
143
|
+
signature: 'camelCase',
|
|
144
|
+
examples: ['{{trigger.text | camelCase}}'],
|
|
145
|
+
execute: (value) => {
|
|
146
|
+
return String(value)
|
|
147
|
+
.replace(/[^\w\s]/g, '')
|
|
148
|
+
.replace(/\s+(.)/g, (_, char) => char.toUpperCase())
|
|
149
|
+
.replace(/^\w/, (char) => char.toLowerCase());
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
kebabCase: {
|
|
153
|
+
name: 'kebabCase',
|
|
154
|
+
description: 'Converts to kebab-case',
|
|
155
|
+
category: 'string',
|
|
156
|
+
signature: 'kebabCase',
|
|
157
|
+
examples: ['{{trigger.text | kebabCase}}'],
|
|
158
|
+
execute: (value) => {
|
|
159
|
+
return String(value)
|
|
160
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
161
|
+
.replace(/[\s_]+/g, '-')
|
|
162
|
+
.toLowerCase();
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
snakeCase: {
|
|
166
|
+
name: 'snakeCase',
|
|
167
|
+
description: 'Converts to snake_case',
|
|
168
|
+
category: 'string',
|
|
169
|
+
signature: 'snakeCase',
|
|
170
|
+
examples: ['{{trigger.text | snakeCase}}'],
|
|
171
|
+
execute: (value) => {
|
|
172
|
+
return String(value)
|
|
173
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
174
|
+
.replace(/[\s-]+/g, '_')
|
|
175
|
+
.toLowerCase();
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParsedExpression, WorkflowContext } from './types';
|
|
2
|
+
export declare function buildResolverContext(workflowContext?: WorkflowContext): Record<string, unknown>;
|
|
3
|
+
export declare function resolvePathValue(path: string, context: Record<string, unknown>): unknown;
|
|
4
|
+
export declare function evaluateExpression(parsed: ParsedExpression, context: Record<string, unknown>, secretsMap?: Map<string, string>): unknown;
|
|
5
|
+
export declare function interpolateString(template: string, context: Record<string, unknown>, secretsMap?: Map<string, string>, options?: {
|
|
6
|
+
maskSecrets?: boolean;
|
|
7
|
+
}): string;
|
|
8
|
+
export declare function resolveExpression(expression: string, context: Record<string, unknown>, secretsMap?: Map<string, string>): unknown;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveExpression = exports.interpolateString = exports.evaluateExpression = exports.resolvePathValue = exports.buildResolverContext = void 0;
|
|
4
|
+
const parser_1 = require("./parser");
|
|
5
|
+
const functions_1 = require("./functions");
|
|
6
|
+
const pipes_1 = require("./pipes");
|
|
7
|
+
function buildResolverContext(workflowContext) {
|
|
8
|
+
var _a;
|
|
9
|
+
if (!workflowContext) {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
const context = {};
|
|
13
|
+
if (workflowContext.triggerData) {
|
|
14
|
+
context.trigger = workflowContext.triggerData;
|
|
15
|
+
context.triggerData = workflowContext.triggerData;
|
|
16
|
+
}
|
|
17
|
+
if (workflowContext.stepExecutions) {
|
|
18
|
+
const steps = {};
|
|
19
|
+
for (const [stepId, execution] of Object.entries(workflowContext.stepExecutions)) {
|
|
20
|
+
const step = (_a = workflowContext.steps) === null || _a === void 0 ? void 0 : _a.find((s) => s.id === stepId);
|
|
21
|
+
const stepKey = (step === null || step === void 0 ? void 0 : step.name) || stepId;
|
|
22
|
+
steps[stepKey] = execution.outputData;
|
|
23
|
+
}
|
|
24
|
+
context.steps = steps;
|
|
25
|
+
}
|
|
26
|
+
if (workflowContext.variables) {
|
|
27
|
+
context.variables = workflowContext.variables;
|
|
28
|
+
}
|
|
29
|
+
context.project = {
|
|
30
|
+
id: workflowContext.projectId,
|
|
31
|
+
...(workflowContext.projectName ? { name: workflowContext.projectName } : {}),
|
|
32
|
+
};
|
|
33
|
+
if (workflowContext.workflowId) {
|
|
34
|
+
context.workflow = {
|
|
35
|
+
id: workflowContext.workflowId,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return context;
|
|
39
|
+
}
|
|
40
|
+
exports.buildResolverContext = buildResolverContext;
|
|
41
|
+
function resolvePathValue(path, context) {
|
|
42
|
+
const segments = (0, parser_1.parsePathSegments)(path);
|
|
43
|
+
let current = context;
|
|
44
|
+
for (const segment of segments) {
|
|
45
|
+
if (current === null || current === undefined) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
if (/^\d+$/.test(segment) && Array.isArray(current)) {
|
|
49
|
+
current = current[Number(segment)];
|
|
50
|
+
}
|
|
51
|
+
else if (typeof current === 'object') {
|
|
52
|
+
current = current[segment];
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return current;
|
|
59
|
+
}
|
|
60
|
+
exports.resolvePathValue = resolvePathValue;
|
|
61
|
+
function evaluateExpression(parsed, context, secretsMap) {
|
|
62
|
+
switch (parsed.type) {
|
|
63
|
+
case 'literal':
|
|
64
|
+
return parsed.literalValue;
|
|
65
|
+
case 'path':
|
|
66
|
+
return evaluatePathExpression(parsed, context, secretsMap);
|
|
67
|
+
case 'function':
|
|
68
|
+
return evaluateFunctionExpression(parsed, context, secretsMap);
|
|
69
|
+
case 'binary':
|
|
70
|
+
return evaluateBinaryExpression(parsed, context, secretsMap);
|
|
71
|
+
case 'unary':
|
|
72
|
+
return evaluateUnaryExpression(parsed, context, secretsMap);
|
|
73
|
+
case 'ternary':
|
|
74
|
+
return evaluateTernaryExpression(parsed, context, secretsMap);
|
|
75
|
+
case 'group':
|
|
76
|
+
return evaluateExpression(parsed.expression, context, secretsMap);
|
|
77
|
+
default:
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.evaluateExpression = evaluateExpression;
|
|
82
|
+
function evaluatePathExpression(parsed, context, secretsMap) {
|
|
83
|
+
var _a;
|
|
84
|
+
if (parsed.source === 'secret' && secretsMap && parsed.path) {
|
|
85
|
+
const secretKey = parsed.path.replace('secret.', '');
|
|
86
|
+
let value = (_a = secretsMap.get(secretKey)) !== null && _a !== void 0 ? _a : `[Secret: ${secretKey}]`;
|
|
87
|
+
if (parsed.operations && parsed.operations.length > 0) {
|
|
88
|
+
for (const op of parsed.operations) {
|
|
89
|
+
try {
|
|
90
|
+
const resolvedArgs = op.args.map((arg) => {
|
|
91
|
+
if (typeof arg === 'string' && arg.includes('.')) {
|
|
92
|
+
const resolved = resolvePathValue(arg, context);
|
|
93
|
+
return resolved !== undefined ? resolved : arg;
|
|
94
|
+
}
|
|
95
|
+
return arg;
|
|
96
|
+
});
|
|
97
|
+
value = (0, pipes_1.executePipeOperation)(op.name, value, resolvedArgs);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return `[Error: ${error.message}]`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
let value = parsed.path ? resolvePathValue(parsed.path, context) : undefined;
|
|
107
|
+
if (parsed.operations && parsed.operations.length > 0) {
|
|
108
|
+
for (const op of parsed.operations) {
|
|
109
|
+
try {
|
|
110
|
+
const resolvedArgs = op.args.map((arg) => {
|
|
111
|
+
if (typeof arg === 'string' && arg.includes('.')) {
|
|
112
|
+
const resolved = resolvePathValue(arg, context);
|
|
113
|
+
return resolved !== undefined ? resolved : arg;
|
|
114
|
+
}
|
|
115
|
+
return arg;
|
|
116
|
+
});
|
|
117
|
+
value = (0, pipes_1.executePipeOperation)(op.name, value, resolvedArgs);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return `[Error: ${error.message}]`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
function evaluateFunctionExpression(parsed, context, secretsMap) {
|
|
127
|
+
if (!parsed.functionName) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
const resolvedArgs = (parsed.functionArgs || []).map((arg) => {
|
|
131
|
+
if (typeof arg === 'string' && arg.includes('.')) {
|
|
132
|
+
const resolved = resolvePathValue(arg, context);
|
|
133
|
+
return resolved !== undefined ? resolved : arg;
|
|
134
|
+
}
|
|
135
|
+
return arg;
|
|
136
|
+
});
|
|
137
|
+
try {
|
|
138
|
+
let value = (0, functions_1.executeFunction)(parsed.functionName, resolvedArgs);
|
|
139
|
+
if (parsed.operations && parsed.operations.length > 0) {
|
|
140
|
+
for (const op of parsed.operations) {
|
|
141
|
+
try {
|
|
142
|
+
const resolvedPipeArgs = op.args.map((arg) => {
|
|
143
|
+
if (typeof arg === 'string' && arg.includes('.')) {
|
|
144
|
+
const resolved = resolvePathValue(arg, context);
|
|
145
|
+
return resolved !== undefined ? resolved : arg;
|
|
146
|
+
}
|
|
147
|
+
return arg;
|
|
148
|
+
});
|
|
149
|
+
value = (0, pipes_1.executePipeOperation)(op.name, value, resolvedPipeArgs);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
return `[Error: ${error.message}]`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return `[Error: ${error.message}]`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function evaluateBinaryExpression(parsed, context, secretsMap) {
|
|
163
|
+
const left = evaluateExpression(parsed.left, context, secretsMap);
|
|
164
|
+
const right = evaluateExpression(parsed.right, context, secretsMap);
|
|
165
|
+
switch (parsed.operator) {
|
|
166
|
+
case '+':
|
|
167
|
+
return left + right;
|
|
168
|
+
case '-':
|
|
169
|
+
return left - right;
|
|
170
|
+
case '*':
|
|
171
|
+
return left * right;
|
|
172
|
+
case '/':
|
|
173
|
+
return left / right;
|
|
174
|
+
case '%':
|
|
175
|
+
return left % right;
|
|
176
|
+
case '**':
|
|
177
|
+
return Math.pow(left, right);
|
|
178
|
+
case '==':
|
|
179
|
+
case '===':
|
|
180
|
+
return left === right;
|
|
181
|
+
case '!=':
|
|
182
|
+
case '!==':
|
|
183
|
+
return left !== right;
|
|
184
|
+
case '<':
|
|
185
|
+
return left < right;
|
|
186
|
+
case '>':
|
|
187
|
+
return left > right;
|
|
188
|
+
case '<=':
|
|
189
|
+
return left <= right;
|
|
190
|
+
case '>=':
|
|
191
|
+
return left >= right;
|
|
192
|
+
case '&&':
|
|
193
|
+
return left && right;
|
|
194
|
+
case '||':
|
|
195
|
+
return left || right;
|
|
196
|
+
default:
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function evaluateUnaryExpression(parsed, context, secretsMap) {
|
|
201
|
+
const operand = evaluateExpression(parsed.operand, context, secretsMap);
|
|
202
|
+
switch (parsed.operator) {
|
|
203
|
+
case '!':
|
|
204
|
+
return !operand;
|
|
205
|
+
case '-':
|
|
206
|
+
return -operand;
|
|
207
|
+
default:
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function evaluateTernaryExpression(parsed, context, secretsMap) {
|
|
212
|
+
const condition = evaluateExpression(parsed.condition, context, secretsMap);
|
|
213
|
+
return condition
|
|
214
|
+
? evaluateExpression(parsed.consequent, context, secretsMap)
|
|
215
|
+
: evaluateExpression(parsed.alternate, context, secretsMap);
|
|
216
|
+
}
|
|
217
|
+
function interpolateString(template, context, secretsMap, options = {}) {
|
|
218
|
+
const tokens = (0, parser_1.tokenizeTemplate)(template);
|
|
219
|
+
let result = '';
|
|
220
|
+
for (const token of tokens) {
|
|
221
|
+
if (token.type === 'text') {
|
|
222
|
+
result += token.value;
|
|
223
|
+
}
|
|
224
|
+
else if (token.type === 'expression') {
|
|
225
|
+
try {
|
|
226
|
+
const parsed = (0, parser_1.parseExpression)(token.value);
|
|
227
|
+
const value = evaluateExpression(parsed, context, secretsMap);
|
|
228
|
+
if (parsed.type === 'path' &&
|
|
229
|
+
parsed.source === 'secret' &&
|
|
230
|
+
options.maskSecrets) {
|
|
231
|
+
result += '••••••••';
|
|
232
|
+
}
|
|
233
|
+
else if (value !== undefined && value !== null) {
|
|
234
|
+
result += typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
result += `{{${token.value}}}`;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
result += `[Error: ${error.message}]`;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
exports.interpolateString = interpolateString;
|
|
248
|
+
function resolveExpression(expression, context, secretsMap) {
|
|
249
|
+
if (expression.includes('{{') && expression.includes('}}')) {
|
|
250
|
+
const tokens = (0, parser_1.tokenizeTemplate)(expression);
|
|
251
|
+
if (tokens.length === 1 && tokens[0].type === 'expression') {
|
|
252
|
+
const parsed = (0, parser_1.parseExpression)(tokens[0].value);
|
|
253
|
+
return evaluateExpression(parsed, context, secretsMap);
|
|
254
|
+
}
|
|
255
|
+
return interpolateString(expression, context, secretsMap);
|
|
256
|
+
}
|
|
257
|
+
const parsed = (0, parser_1.parseExpression)(expression);
|
|
258
|
+
return evaluateExpression(parsed, context, secretsMap);
|
|
259
|
+
}
|
|
260
|
+
exports.resolveExpression = resolveExpression;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { ResourceMapping as GenericResourceMapping } from '../expressions/types';
|
|
2
|
+
export declare enum DataSourceType {
|
|
3
|
+
WORKFLOW_TRIGGER = "trigger",
|
|
4
|
+
WORKFLOW_STEPS = "steps",
|
|
5
|
+
WORKFLOW_VARIABLES = "variables",
|
|
6
|
+
IP_ADDRESSES = "ipAddress",
|
|
7
|
+
DOMAINS = "domain",
|
|
8
|
+
APPLICATIONS = "app",
|
|
9
|
+
SECRETS = "secret",
|
|
10
|
+
PROJECT = "project",
|
|
11
|
+
ENV = "env",
|
|
12
|
+
ABYSS_CONFIG = "abyss",
|
|
13
|
+
FUNCTIONS = "fn"
|
|
14
|
+
}
|
|
15
|
+
export declare const OPERATOR_PRECEDENCE: Record<string, number>;
|
|
16
|
+
export type ParsedExpression = PathExpression | FunctionExpression | BinaryExpression | UnaryExpression | TernaryExpression | LiteralExpression | GroupExpression;
|
|
17
|
+
export interface BaseExpression {
|
|
18
|
+
type: string;
|
|
19
|
+
isValid: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PathExpression extends BaseExpression {
|
|
23
|
+
type: 'path';
|
|
24
|
+
path: string;
|
|
25
|
+
source: DataSourceType | null;
|
|
26
|
+
operations?: PipeOperation[];
|
|
27
|
+
resolvedValue?: unknown;
|
|
28
|
+
}
|
|
29
|
+
export interface FunctionExpression extends BaseExpression {
|
|
30
|
+
type: 'function';
|
|
31
|
+
isFunction: true;
|
|
32
|
+
functionName: string;
|
|
33
|
+
functionArgs: unknown[];
|
|
34
|
+
operations?: PipeOperation[];
|
|
35
|
+
resolvedValue?: unknown;
|
|
36
|
+
}
|
|
37
|
+
export interface BinaryExpression extends BaseExpression {
|
|
38
|
+
type: 'binary';
|
|
39
|
+
operator: string;
|
|
40
|
+
left: ParsedExpression;
|
|
41
|
+
right: ParsedExpression;
|
|
42
|
+
}
|
|
43
|
+
export interface UnaryExpression extends BaseExpression {
|
|
44
|
+
type: 'unary';
|
|
45
|
+
operator: string;
|
|
46
|
+
operand: ParsedExpression;
|
|
47
|
+
}
|
|
48
|
+
export interface TernaryExpression extends BaseExpression {
|
|
49
|
+
type: 'ternary';
|
|
50
|
+
condition: ParsedExpression;
|
|
51
|
+
consequent: ParsedExpression;
|
|
52
|
+
alternate: ParsedExpression;
|
|
53
|
+
}
|
|
54
|
+
export interface LiteralExpression extends BaseExpression {
|
|
55
|
+
type: 'literal';
|
|
56
|
+
literalType: 'string' | 'number' | 'boolean' | 'null';
|
|
57
|
+
literalValue: unknown;
|
|
58
|
+
}
|
|
59
|
+
export interface GroupExpression extends BaseExpression {
|
|
60
|
+
type: 'group';
|
|
61
|
+
expression: ParsedExpression;
|
|
62
|
+
}
|
|
63
|
+
export interface PipeOperation {
|
|
64
|
+
name: string;
|
|
65
|
+
args: unknown[];
|
|
66
|
+
description?: string;
|
|
67
|
+
category?: OperationCategory;
|
|
68
|
+
}
|
|
69
|
+
export type OperationCategory = 'string' | 'array' | 'object' | 'number' | 'date' | 'encoding' | 'formatting';
|
|
70
|
+
export interface BuiltInFunction {
|
|
71
|
+
name: string;
|
|
72
|
+
description: string;
|
|
73
|
+
category: FunctionCategory;
|
|
74
|
+
signature: string;
|
|
75
|
+
args: FunctionArg[];
|
|
76
|
+
returnType: string;
|
|
77
|
+
examples: string[];
|
|
78
|
+
execute: (...args: unknown[]) => unknown;
|
|
79
|
+
}
|
|
80
|
+
export type FunctionCategory = 'datetime' | 'string' | 'math' | 'crypto' | 'array' | 'utility' | 'encoding';
|
|
81
|
+
export interface FunctionArg {
|
|
82
|
+
name: string;
|
|
83
|
+
type: string;
|
|
84
|
+
required: boolean;
|
|
85
|
+
description: string;
|
|
86
|
+
}
|
|
87
|
+
export interface WorkflowContext {
|
|
88
|
+
projectId: string;
|
|
89
|
+
projectName?: string;
|
|
90
|
+
workflowId?: string;
|
|
91
|
+
triggerData?: Record<string, unknown>;
|
|
92
|
+
stepExecutions?: Record<string, StepExecution>;
|
|
93
|
+
variables?: Record<string, unknown>;
|
|
94
|
+
steps?: WorkflowStep[];
|
|
95
|
+
}
|
|
96
|
+
export interface StepExecution {
|
|
97
|
+
stepId: string;
|
|
98
|
+
outputData: unknown;
|
|
99
|
+
status: 'success' | 'failed' | 'running' | 'pending';
|
|
100
|
+
startedAt?: Date;
|
|
101
|
+
completedAt?: Date;
|
|
102
|
+
error?: string;
|
|
103
|
+
}
|
|
104
|
+
export interface WorkflowStep {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
type: string;
|
|
108
|
+
config?: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
export interface ExpressionToken {
|
|
111
|
+
type: 'text' | 'expression' | 'reference' | 'function' | 'error';
|
|
112
|
+
value: string;
|
|
113
|
+
rawValue: string;
|
|
114
|
+
start: number;
|
|
115
|
+
end: number;
|
|
116
|
+
parsed?: ParsedExpression;
|
|
117
|
+
isSecret?: boolean;
|
|
118
|
+
}
|
|
119
|
+
export interface ValidationResult {
|
|
120
|
+
isValid: boolean;
|
|
121
|
+
errors: ValidationError[];
|
|
122
|
+
warnings: ValidationWarning[];
|
|
123
|
+
}
|
|
124
|
+
export interface ValidationError {
|
|
125
|
+
type: 'error';
|
|
126
|
+
message: string;
|
|
127
|
+
start: number;
|
|
128
|
+
end: number;
|
|
129
|
+
path?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface ValidationWarning {
|
|
132
|
+
type: 'warning';
|
|
133
|
+
message: string;
|
|
134
|
+
start: number;
|
|
135
|
+
end: number;
|
|
136
|
+
path?: string;
|
|
137
|
+
suggestion?: string;
|
|
138
|
+
}
|
|
139
|
+
export interface WorkflowResourceMapping extends Omit<GenericResourceMapping<DataSourceType>, 'source'> {
|
|
140
|
+
source: DataSourceType;
|
|
141
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OPERATOR_PRECEDENCE = exports.DataSourceType = void 0;
|
|
4
|
+
var DataSourceType;
|
|
5
|
+
(function (DataSourceType) {
|
|
6
|
+
DataSourceType["WORKFLOW_TRIGGER"] = "trigger";
|
|
7
|
+
DataSourceType["WORKFLOW_STEPS"] = "steps";
|
|
8
|
+
DataSourceType["WORKFLOW_VARIABLES"] = "variables";
|
|
9
|
+
DataSourceType["IP_ADDRESSES"] = "ipAddress";
|
|
10
|
+
DataSourceType["DOMAINS"] = "domain";
|
|
11
|
+
DataSourceType["APPLICATIONS"] = "app";
|
|
12
|
+
DataSourceType["SECRETS"] = "secret";
|
|
13
|
+
DataSourceType["PROJECT"] = "project";
|
|
14
|
+
DataSourceType["ENV"] = "env";
|
|
15
|
+
DataSourceType["ABYSS_CONFIG"] = "abyss";
|
|
16
|
+
DataSourceType["FUNCTIONS"] = "fn";
|
|
17
|
+
})(DataSourceType || (exports.DataSourceType = DataSourceType = {}));
|
|
18
|
+
exports.OPERATOR_PRECEDENCE = {
|
|
19
|
+
'||': 1,
|
|
20
|
+
'&&': 2,
|
|
21
|
+
'==': 3,
|
|
22
|
+
'!=': 3,
|
|
23
|
+
'<': 4,
|
|
24
|
+
'>': 4,
|
|
25
|
+
'<=': 4,
|
|
26
|
+
'>=': 4,
|
|
27
|
+
'+': 5,
|
|
28
|
+
'-': 5,
|
|
29
|
+
'*': 6,
|
|
30
|
+
'/': 6,
|
|
31
|
+
'%': 6,
|
|
32
|
+
'**': 7,
|
|
33
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abyss-project/console",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
4
4
|
"description": "Core package to interact with AbyssConsole",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"axios": "^1.2.2",
|
|
16
16
|
"axios-retry": "^3.4.0",
|
|
17
|
+
"date-fns": "^2.30.0",
|
|
17
18
|
"fs-extra": "^11.1.1",
|
|
18
19
|
"lodash": "^4.17.21",
|
|
19
20
|
"reflect-metadata": "^0.1.13",
|