@xtr-dev/payload-automation 0.0.43 → 0.0.45
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/README.md +221 -49
- package/dist/collections/Steps.d.ts +6 -0
- package/dist/collections/Steps.js +166 -0
- package/dist/collections/Steps.js.map +1 -0
- package/dist/collections/Triggers.d.ts +7 -0
- package/dist/collections/Triggers.js +224 -0
- package/dist/collections/Triggers.js.map +1 -0
- package/dist/collections/Workflow.d.ts +5 -2
- package/dist/collections/Workflow.js +179 -39
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/collections/WorkflowRuns.d.ts +4 -0
- package/dist/collections/WorkflowRuns.js +219 -24
- package/dist/collections/WorkflowRuns.js.map +1 -1
- package/dist/components/WorkflowBuilder/WorkflowBuilder.js.map +1 -1
- package/dist/core/expression-engine.d.ts +58 -0
- package/dist/core/expression-engine.js +191 -0
- package/dist/core/expression-engine.js.map +1 -0
- package/dist/core/workflow-executor.d.ts +70 -56
- package/dist/core/workflow-executor.js +354 -677
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/exports/client.js +1 -3
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/views.js +2 -4
- package/dist/exports/views.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin/config-types.d.ts +43 -5
- package/dist/plugin/config-types.js +3 -1
- package/dist/plugin/config-types.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.js +82 -28
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/trigger-hook.d.ts +13 -0
- package/dist/plugin/trigger-hook.js +184 -0
- package/dist/plugin/trigger-hook.js.map +1 -0
- package/dist/steps/create-step.d.ts +66 -0
- package/dist/steps/create-step.js +59 -0
- package/dist/steps/create-step.js.map +1 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +3 -0
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/read-document-handler.js +1 -1
- package/dist/steps/read-document-handler.js.map +1 -1
- package/dist/steps/update-document-handler.js +1 -1
- package/dist/steps/update-document-handler.js.map +1 -1
- package/dist/triggers/hook-options.d.ts +34 -0
- package/dist/triggers/hook-options.js +158 -0
- package/dist/triggers/hook-options.js.map +1 -0
- package/dist/triggers/index.d.ts +2 -2
- package/dist/triggers/index.js +1 -2
- package/dist/triggers/index.js.map +1 -1
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +4 -5
- package/dist/types/index.js.map +1 -1
- package/dist/utils/validation.d.ts +64 -0
- package/dist/utils/validation.js +107 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +2 -1
- package/dist/plugin/collection-hook.d.ts +0 -1
- package/dist/plugin/collection-hook.js +0 -92
- package/dist/plugin/collection-hook.js.map +0 -1
- package/dist/plugin/global-hook.d.ts +0 -1
- package/dist/plugin/global-hook.js +0 -83
- package/dist/plugin/global-hook.js.map +0 -1
- package/dist/triggers/collection-trigger.d.ts +0 -2
- package/dist/triggers/collection-trigger.js +0 -36
- package/dist/triggers/collection-trigger.js.map +0 -1
- package/dist/triggers/global-trigger.d.ts +0 -2
- package/dist/triggers/global-trigger.js +0 -29
- package/dist/triggers/global-trigger.js.map +0 -1
- package/dist/triggers/types.d.ts +0 -5
- package/dist/triggers/types.js +0 -3
- package/dist/triggers/types.js.map +0 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import jsonata from 'jsonata';
|
|
2
|
+
// Cache compiled expressions for performance
|
|
3
|
+
const expressionCache = new Map();
|
|
4
|
+
const MAX_CACHE_SIZE = 1000;
|
|
5
|
+
/**
|
|
6
|
+
* Compile a JSONata expression with caching
|
|
7
|
+
*/ function compileExpression(expression) {
|
|
8
|
+
let compiled = expressionCache.get(expression);
|
|
9
|
+
if (!compiled) {
|
|
10
|
+
compiled = jsonata(expression);
|
|
11
|
+
// Register custom functions
|
|
12
|
+
registerCustomFunctions(compiled);
|
|
13
|
+
// Manage cache size
|
|
14
|
+
if (expressionCache.size >= MAX_CACHE_SIZE) {
|
|
15
|
+
const firstKey = expressionCache.keys().next().value;
|
|
16
|
+
if (firstKey) expressionCache.delete(firstKey);
|
|
17
|
+
}
|
|
18
|
+
expressionCache.set(expression, compiled);
|
|
19
|
+
}
|
|
20
|
+
return compiled;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register custom functions on a JSONata expression
|
|
24
|
+
*/ function registerCustomFunctions(expr) {
|
|
25
|
+
// $env(name) - Get environment variable (only non-sensitive ones)
|
|
26
|
+
expr.registerFunction('env', (name)=>{
|
|
27
|
+
// Only allow specific prefixes for security
|
|
28
|
+
if (typeof name === 'string' && name.startsWith('PUBLIC_')) {
|
|
29
|
+
return process.env[name];
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}, '<s:s>');
|
|
33
|
+
// $now() - Current ISO timestamp
|
|
34
|
+
expr.registerFunction('now', ()=>new Date().toISOString(), '<:s>');
|
|
35
|
+
// $timestamp() - Current Unix timestamp in milliseconds
|
|
36
|
+
expr.registerFunction('timestamp', ()=>Date.now(), '<:n>');
|
|
37
|
+
// $uuid() - Generate a UUID v4
|
|
38
|
+
expr.registerFunction('uuid', ()=>{
|
|
39
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c)=>{
|
|
40
|
+
const r = Math.random() * 16 | 0;
|
|
41
|
+
const v = c === 'x' ? r : r & 0x3 | 0x8;
|
|
42
|
+
return v.toString(16);
|
|
43
|
+
});
|
|
44
|
+
}, '<:s>');
|
|
45
|
+
// $default(value, defaultValue) - Return default if value is null/undefined
|
|
46
|
+
expr.registerFunction('default', (value, defaultValue)=>{
|
|
47
|
+
return value === null || value === undefined ? defaultValue : value;
|
|
48
|
+
}, '<xx:x>');
|
|
49
|
+
// $json(value) - Parse JSON string
|
|
50
|
+
expr.registerFunction('json', (value)=>{
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(value);
|
|
53
|
+
} catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}, '<s:x>');
|
|
57
|
+
// $stringify(value) - Convert to JSON string
|
|
58
|
+
expr.registerFunction('stringify', (value)=>{
|
|
59
|
+
try {
|
|
60
|
+
return JSON.stringify(value);
|
|
61
|
+
} catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}, '<x:s>');
|
|
65
|
+
// $keys(object) - Get object keys
|
|
66
|
+
expr.registerFunction('keys', (obj)=>{
|
|
67
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
68
|
+
return Object.keys(obj);
|
|
69
|
+
}
|
|
70
|
+
return [];
|
|
71
|
+
}, '<o:a>');
|
|
72
|
+
// $values(object) - Get object values
|
|
73
|
+
expr.registerFunction('values', (obj)=>{
|
|
74
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
75
|
+
return Object.values(obj);
|
|
76
|
+
}
|
|
77
|
+
return [];
|
|
78
|
+
}, '<o:a>');
|
|
79
|
+
// $has(object, key) - Check if object has key
|
|
80
|
+
expr.registerFunction('has', (obj, key)=>{
|
|
81
|
+
if (obj && typeof obj === 'object') {
|
|
82
|
+
return key in obj;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}, '<os:b>');
|
|
86
|
+
// $coalesce(values...) - Return first non-null value
|
|
87
|
+
expr.registerFunction('coalesce', (...values)=>{
|
|
88
|
+
for (const v of values){
|
|
89
|
+
if (v !== null && v !== undefined) {
|
|
90
|
+
return v;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}, '<x+:x>');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Evaluate a JSONata expression against a context
|
|
98
|
+
*/ export async function evaluate(expression, context, options = {}) {
|
|
99
|
+
const { timeout = 5000 } = options;
|
|
100
|
+
const compiled = compileExpression(expression);
|
|
101
|
+
// Create a promise that rejects on timeout
|
|
102
|
+
const timeoutPromise = new Promise((_, reject)=>{
|
|
103
|
+
setTimeout(()=>reject(new Error(`Expression evaluation timed out after ${timeout}ms`)), timeout);
|
|
104
|
+
});
|
|
105
|
+
// Race between evaluation and timeout
|
|
106
|
+
return Promise.race([
|
|
107
|
+
compiled.evaluate(context),
|
|
108
|
+
timeoutPromise
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Evaluate a condition expression and return a boolean
|
|
113
|
+
*/ export async function evaluateCondition(expression, context, options = {}) {
|
|
114
|
+
try {
|
|
115
|
+
const result = await evaluate(expression, context, options);
|
|
116
|
+
// Convert result to boolean
|
|
117
|
+
if (result === undefined || result === null) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (typeof result === 'boolean') {
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
if (typeof result === 'number') {
|
|
124
|
+
return result !== 0;
|
|
125
|
+
}
|
|
126
|
+
if (typeof result === 'string') {
|
|
127
|
+
return result.length > 0;
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(result)) {
|
|
130
|
+
return result.length > 0;
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
// Log error but return false for failed conditions
|
|
135
|
+
console.warn('Condition evaluation failed:', error instanceof Error ? error.message : error);
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Transform data using a JSONata expression
|
|
141
|
+
* The expression can be a JSONata query or a JSON object with embedded expressions
|
|
142
|
+
*/ export async function transform(template, context, options = {}) {
|
|
143
|
+
if (typeof template === 'string') {
|
|
144
|
+
// Check if it looks like a JSONata expression (starts with common patterns)
|
|
145
|
+
if (template.startsWith('{') || template.startsWith('[') || template.startsWith('$') || template.includes('.') || template.includes('(')) {
|
|
146
|
+
try {
|
|
147
|
+
return await evaluate(template, context, options);
|
|
148
|
+
} catch {
|
|
149
|
+
// If it fails to evaluate, return as literal string
|
|
150
|
+
return template;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return template;
|
|
154
|
+
}
|
|
155
|
+
if (Array.isArray(template)) {
|
|
156
|
+
return Promise.all(template.map((item)=>transform(item, context, options)));
|
|
157
|
+
}
|
|
158
|
+
if (template && typeof template === 'object') {
|
|
159
|
+
const result = {};
|
|
160
|
+
for (const [key, value] of Object.entries(template)){
|
|
161
|
+
result[key] = await transform(value, context, options);
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
return template;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Resolve a step input configuration using JSONata
|
|
169
|
+
* Handles both simple values and expressions
|
|
170
|
+
*/ export async function resolveStepInput(config, context, options = {}) {
|
|
171
|
+
const result = {};
|
|
172
|
+
for (const [key, value] of Object.entries(config)){
|
|
173
|
+
result[key] = await transform(value, context, options);
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Clear the expression cache
|
|
179
|
+
*/ export function clearCache() {
|
|
180
|
+
expressionCache.clear();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get cache statistics
|
|
184
|
+
*/ export function getCacheStats() {
|
|
185
|
+
return {
|
|
186
|
+
size: expressionCache.size,
|
|
187
|
+
maxSize: MAX_CACHE_SIZE
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=expression-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/expression-engine.ts"],"sourcesContent":["import jsonata from 'jsonata'\n\n/**\n * Expression engine using JSONata for safe, sandboxed expression evaluation.\n * Used for both conditions and data transformation in workflows.\n *\n * @example Conditions\n * ```\n * trigger.doc._status = \"published\"\n * trigger.doc.count > 10 and trigger.doc.enabled\n * $exists(steps.validate.output.error) = false\n * ```\n *\n * @example Data Transformation\n * ```\n * {\n * \"id\": trigger.doc.id,\n * \"title\": $uppercase(trigger.doc.title),\n * \"tags\": trigger.doc.tags[category = \"featured\"].name\n * }\n * ```\n */\n\nexport interface ExpressionContext {\n trigger: Record<string, unknown>\n steps: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface EvaluateOptions {\n /** Timeout in milliseconds (default: 5000) */\n timeout?: number\n}\n\n// Cache compiled expressions for performance\nconst expressionCache = new Map<string, jsonata.Expression>()\nconst MAX_CACHE_SIZE = 1000\n\n/**\n * Compile a JSONata expression with caching\n */\nfunction compileExpression(expression: string): jsonata.Expression {\n let compiled = expressionCache.get(expression)\n\n if (!compiled) {\n compiled = jsonata(expression)\n\n // Register custom functions\n registerCustomFunctions(compiled)\n\n // Manage cache size\n if (expressionCache.size >= MAX_CACHE_SIZE) {\n const firstKey = expressionCache.keys().next().value\n if (firstKey) expressionCache.delete(firstKey)\n }\n\n expressionCache.set(expression, compiled)\n }\n\n return compiled\n}\n\n/**\n * Register custom functions on a JSONata expression\n */\nfunction registerCustomFunctions(expr: jsonata.Expression): void {\n // $env(name) - Get environment variable (only non-sensitive ones)\n expr.registerFunction('env', (name: string) => {\n // Only allow specific prefixes for security\n if (typeof name === 'string' && name.startsWith('PUBLIC_')) {\n return process.env[name]\n }\n return undefined\n }, '<s:s>')\n\n // $now() - Current ISO timestamp\n expr.registerFunction('now', () => new Date().toISOString(), '<:s>')\n\n // $timestamp() - Current Unix timestamp in milliseconds\n expr.registerFunction('timestamp', () => Date.now(), '<:n>')\n\n // $uuid() - Generate a UUID v4\n expr.registerFunction('uuid', () => {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n }, '<:s>')\n\n // $default(value, defaultValue) - Return default if value is null/undefined\n expr.registerFunction('default', (value: unknown, defaultValue: unknown) => {\n return value === null || value === undefined ? defaultValue : value\n }, '<xx:x>')\n\n // $json(value) - Parse JSON string\n expr.registerFunction('json', (value: string) => {\n try {\n return JSON.parse(value)\n } catch {\n return undefined\n }\n }, '<s:x>')\n\n // $stringify(value) - Convert to JSON string\n expr.registerFunction('stringify', (value: unknown) => {\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n }, '<x:s>')\n\n // $keys(object) - Get object keys\n expr.registerFunction('keys', (obj: Record<string, unknown>) => {\n if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n return Object.keys(obj)\n }\n return []\n }, '<o:a>')\n\n // $values(object) - Get object values\n expr.registerFunction('values', (obj: Record<string, unknown>) => {\n if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n return Object.values(obj)\n }\n return []\n }, '<o:a>')\n\n // $has(object, key) - Check if object has key\n expr.registerFunction('has', (obj: Record<string, unknown>, key: string) => {\n if (obj && typeof obj === 'object') {\n return key in obj\n }\n return false\n }, '<os:b>')\n\n // $coalesce(values...) - Return first non-null value\n expr.registerFunction('coalesce', (...values: unknown[]) => {\n for (const v of values) {\n if (v !== null && v !== undefined) {\n return v\n }\n }\n return null\n }, '<x+:x>')\n}\n\n/**\n * Evaluate a JSONata expression against a context\n */\nexport async function evaluate(\n expression: string,\n context: ExpressionContext,\n options: EvaluateOptions = {}\n): Promise<unknown> {\n const { timeout = 5000 } = options\n\n const compiled = compileExpression(expression)\n\n // Create a promise that rejects on timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Expression evaluation timed out after ${timeout}ms`)), timeout)\n })\n\n // Race between evaluation and timeout\n return Promise.race([\n compiled.evaluate(context),\n timeoutPromise\n ])\n}\n\n/**\n * Evaluate a condition expression and return a boolean\n */\nexport async function evaluateCondition(\n expression: string,\n context: ExpressionContext,\n options: EvaluateOptions = {}\n): Promise<boolean> {\n try {\n const result = await evaluate(expression, context, options)\n\n // Convert result to boolean\n if (result === undefined || result === null) {\n return false\n }\n if (typeof result === 'boolean') {\n return result\n }\n if (typeof result === 'number') {\n return result !== 0\n }\n if (typeof result === 'string') {\n return result.length > 0\n }\n if (Array.isArray(result)) {\n return result.length > 0\n }\n return true\n } catch (error) {\n // Log error but return false for failed conditions\n console.warn('Condition evaluation failed:', error instanceof Error ? error.message : error)\n return false\n }\n}\n\n/**\n * Transform data using a JSONata expression\n * The expression can be a JSONata query or a JSON object with embedded expressions\n */\nexport async function transform(\n template: unknown,\n context: ExpressionContext,\n options: EvaluateOptions = {}\n): Promise<unknown> {\n if (typeof template === 'string') {\n // Check if it looks like a JSONata expression (starts with common patterns)\n if (\n template.startsWith('{') ||\n template.startsWith('[') ||\n template.startsWith('$') ||\n template.includes('.') ||\n template.includes('(')\n ) {\n try {\n return await evaluate(template, context, options)\n } catch {\n // If it fails to evaluate, return as literal string\n return template\n }\n }\n return template\n }\n\n if (Array.isArray(template)) {\n return Promise.all(template.map(item => transform(item, context, options)))\n }\n\n if (template && typeof template === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(template)) {\n result[key] = await transform(value, context, options)\n }\n return result\n }\n\n return template\n}\n\n/**\n * Resolve a step input configuration using JSONata\n * Handles both simple values and expressions\n */\nexport async function resolveStepInput(\n config: Record<string, unknown>,\n context: ExpressionContext,\n options: EvaluateOptions = {}\n): Promise<Record<string, unknown>> {\n const result: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(config)) {\n result[key] = await transform(value, context, options)\n }\n\n return result\n}\n\n/**\n * Clear the expression cache\n */\nexport function clearCache(): void {\n expressionCache.clear()\n}\n\n/**\n * Get cache statistics\n */\nexport function getCacheStats(): { size: number; maxSize: number } {\n return {\n size: expressionCache.size,\n maxSize: MAX_CACHE_SIZE\n }\n}\n"],"names":["jsonata","expressionCache","Map","MAX_CACHE_SIZE","compileExpression","expression","compiled","get","registerCustomFunctions","size","firstKey","keys","next","value","delete","set","expr","registerFunction","name","startsWith","process","env","undefined","Date","toISOString","now","replace","c","r","Math","random","v","toString","defaultValue","JSON","parse","stringify","obj","Array","isArray","Object","values","key","evaluate","context","options","timeout","timeoutPromise","Promise","_","reject","setTimeout","Error","race","evaluateCondition","result","length","error","console","warn","message","transform","template","includes","all","map","item","entries","resolveStepInput","config","clearCache","clear","getCacheStats","maxSize"],"mappings":"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"}
|
|
@@ -1,90 +1,104 @@
|
|
|
1
1
|
import type { Payload, PayloadRequest } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* Type for workflow data from the refactored collection
|
|
4
|
+
*/
|
|
2
5
|
export type PayloadWorkflow = {
|
|
3
|
-
id: number;
|
|
6
|
+
id: number | string;
|
|
4
7
|
name: string;
|
|
5
|
-
description?:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
condition?: null | string;
|
|
9
|
-
parameters?: {
|
|
10
|
-
collectionSlug?: null | string;
|
|
11
|
-
operation?: null | string;
|
|
12
|
-
global?: null | string;
|
|
13
|
-
globalOperation?: null | string;
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
} | null;
|
|
16
|
-
[key: string]: unknown;
|
|
17
|
-
}> | null;
|
|
8
|
+
description?: string | null;
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
triggers?: Array<any> | null;
|
|
18
11
|
steps?: Array<{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
condition?:
|
|
24
|
-
|
|
12
|
+
id?: string;
|
|
13
|
+
step: any;
|
|
14
|
+
stepName?: string | null;
|
|
15
|
+
inputOverrides?: Record<string, unknown> | null;
|
|
16
|
+
condition?: string | null;
|
|
17
|
+
dependencies?: Array<{
|
|
18
|
+
stepIndex: number;
|
|
19
|
+
}> | null;
|
|
20
|
+
position?: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
} | null;
|
|
25
24
|
}> | null;
|
|
25
|
+
errorHandling?: 'stop' | 'continue' | 'retry' | null;
|
|
26
|
+
maxRetries?: number | null;
|
|
27
|
+
retryDelay?: number | null;
|
|
28
|
+
timeout?: number | null;
|
|
26
29
|
[key: string]: unknown;
|
|
27
30
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export type
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Type for a resolved workflow step (with base step data merged)
|
|
33
|
+
*/
|
|
34
|
+
export type ResolvedStep = {
|
|
35
|
+
stepIndex: number;
|
|
36
|
+
stepId: string | number;
|
|
37
|
+
stepName: string;
|
|
38
|
+
stepType: string;
|
|
39
|
+
config: Record<string, unknown>;
|
|
40
|
+
condition?: string | null;
|
|
41
|
+
dependencies: number[];
|
|
42
|
+
retryOnFailure?: boolean;
|
|
43
|
+
maxRetries?: number;
|
|
44
|
+
retryDelay?: number;
|
|
45
|
+
};
|
|
34
46
|
export interface ExecutionContext {
|
|
35
47
|
steps: Record<string, any>;
|
|
36
48
|
trigger: Record<string, any>;
|
|
37
49
|
}
|
|
50
|
+
export interface StepResult {
|
|
51
|
+
step?: string | number;
|
|
52
|
+
stepName: string;
|
|
53
|
+
stepIndex: number;
|
|
54
|
+
status: 'pending' | 'running' | 'succeeded' | 'failed' | 'skipped';
|
|
55
|
+
startedAt?: string;
|
|
56
|
+
completedAt?: string;
|
|
57
|
+
duration?: number;
|
|
58
|
+
input?: Record<string, unknown>;
|
|
59
|
+
output?: Record<string, unknown>;
|
|
60
|
+
error?: string;
|
|
61
|
+
retryCount?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Workflow context stored on jobs created by workflow execution.
|
|
65
|
+
* Uses relationship IDs that link to the respective collections.
|
|
66
|
+
*/
|
|
67
|
+
export interface WorkflowJobMeta {
|
|
68
|
+
automationWorkflowId: string | number;
|
|
69
|
+
automationWorkflowRunId: string | number;
|
|
70
|
+
automationTriggerId?: string | number;
|
|
71
|
+
}
|
|
38
72
|
export declare class WorkflowExecutor {
|
|
39
73
|
private payload;
|
|
40
74
|
private logger;
|
|
41
75
|
constructor(payload: Payload, logger: Payload['logger']);
|
|
42
76
|
/**
|
|
43
|
-
*
|
|
44
|
-
*/
|
|
45
|
-
private convertValueType;
|
|
46
|
-
/**
|
|
47
|
-
* Classifies error types based on error messages
|
|
77
|
+
* Resolve workflow steps by loading base step configurations and merging with overrides
|
|
48
78
|
*/
|
|
49
|
-
private
|
|
79
|
+
private resolveWorkflowSteps;
|
|
50
80
|
/**
|
|
51
|
-
*
|
|
81
|
+
* Resolve step execution order based on dependencies
|
|
52
82
|
*/
|
|
53
|
-
private
|
|
83
|
+
private resolveExecutionOrder;
|
|
54
84
|
/**
|
|
55
85
|
* Execute a single workflow step
|
|
56
86
|
*/
|
|
57
87
|
private executeStep;
|
|
58
88
|
/**
|
|
59
|
-
*
|
|
60
|
-
*/
|
|
61
|
-
private extractErrorDetailsFromJob;
|
|
62
|
-
/**
|
|
63
|
-
* Resolve step execution order based on dependencies
|
|
64
|
-
*/
|
|
65
|
-
private resolveExecutionOrder;
|
|
66
|
-
/**
|
|
67
|
-
* Resolve step input using Handlebars templates with automatic type conversion
|
|
89
|
+
* Resolve step input using JSONata expressions
|
|
68
90
|
*/
|
|
69
91
|
private resolveStepInput;
|
|
70
92
|
/**
|
|
71
|
-
*
|
|
93
|
+
* Evaluate a condition using JSONata
|
|
72
94
|
*/
|
|
73
|
-
|
|
95
|
+
evaluateCondition(condition: string, context: ExecutionContext): Promise<boolean>;
|
|
74
96
|
/**
|
|
75
|
-
*
|
|
97
|
+
* Safely serialize an object for storage
|
|
76
98
|
*/
|
|
77
|
-
private
|
|
78
|
-
/**
|
|
79
|
-
* Evaluate a condition using Handlebars templates and comparison operators
|
|
80
|
-
*/
|
|
81
|
-
evaluateCondition(condition: string, context: ExecutionContext): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Resolve a condition value using Handlebars templates or JSONPath
|
|
84
|
-
*/
|
|
85
|
-
private resolveConditionValue;
|
|
99
|
+
private safeSerialize;
|
|
86
100
|
/**
|
|
87
101
|
* Execute a workflow with the given context
|
|
88
102
|
*/
|
|
89
|
-
execute(workflow: PayloadWorkflow, context: ExecutionContext, req: PayloadRequest): Promise<void>;
|
|
103
|
+
execute(workflow: PayloadWorkflow, context: ExecutionContext, req: PayloadRequest, firedTrigger?: any): Promise<void>;
|
|
90
104
|
}
|