ts2workflows 0.1.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/LICENSE +22 -0
- package/README.md +82 -0
- package/dist/ast/expressions.d.ts +57 -0
- package/dist/ast/expressions.d.ts.map +1 -0
- package/dist/ast/expressions.js +300 -0
- package/dist/ast/stepnames.d.ts +9 -0
- package/dist/ast/stepnames.d.ts.map +1 -0
- package/dist/ast/stepnames.js +268 -0
- package/dist/ast/steps.d.ts +176 -0
- package/dist/ast/steps.d.ts.map +1 -0
- package/dist/ast/steps.js +534 -0
- package/dist/ast/validation.d.ts +20 -0
- package/dist/ast/validation.d.ts.map +1 -0
- package/dist/ast/validation.js +214 -0
- package/dist/ast/workflows.d.ts +28 -0
- package/dist/ast/workflows.d.ts.map +1 -0
- package/dist/ast/workflows.js +74 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +114 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +12 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/transpiler/asserts.d.ts +7 -0
- package/dist/transpiler/asserts.d.ts.map +1 -0
- package/dist/transpiler/asserts.js +11 -0
- package/dist/transpiler/expressions.d.ts +6 -0
- package/dist/transpiler/expressions.d.ts.map +1 -0
- package/dist/transpiler/expressions.js +223 -0
- package/dist/transpiler/generated/functionMetadata.d.ts +2 -0
- package/dist/transpiler/generated/functionMetadata.d.ts.map +1 -0
- package/dist/transpiler/generated/functionMetadata.js +324 -0
- package/dist/transpiler/index.d.ts +2 -0
- package/dist/transpiler/index.d.ts.map +1 -0
- package/dist/transpiler/index.js +74 -0
- package/dist/transpiler/statements.d.ts +7 -0
- package/dist/transpiler/statements.d.ts.map +1 -0
- package/dist/transpiler/statements.js +533 -0
- package/dist/transpiler/transformations.d.ts +28 -0
- package/dist/transpiler/transformations.d.ts.map +1 -0
- package/dist/transpiler/transformations.js +461 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +3 -0
- package/language_reference.md +771 -0
- package/package.json +62 -0
- package/types/workflowslib.d.ts +714 -0
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import { isRecord } from '../utils.js';
|
|
2
|
+
import { expressionToLiteralValueOrLiteralExpression, } from './expressions.js';
|
|
3
|
+
import { Subworkflow } from './workflows.js';
|
|
4
|
+
export class SubworkflowAST {
|
|
5
|
+
name;
|
|
6
|
+
steps;
|
|
7
|
+
params;
|
|
8
|
+
constructor(name, steps, params) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.steps = steps;
|
|
11
|
+
this.params = params;
|
|
12
|
+
}
|
|
13
|
+
withStepNames(generate) {
|
|
14
|
+
const steps = this.steps.map((step) => namedSteps(step, generate));
|
|
15
|
+
return new Subworkflow(this.name, steps, this.params);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/variables#assign-step
|
|
19
|
+
export class AssignStepAST {
|
|
20
|
+
tag = 'assign';
|
|
21
|
+
assignments;
|
|
22
|
+
label;
|
|
23
|
+
constructor(assignments, label) {
|
|
24
|
+
this.assignments = assignments;
|
|
25
|
+
this.label = label;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/calls
|
|
29
|
+
export class CallStepAST {
|
|
30
|
+
tag = 'call';
|
|
31
|
+
call;
|
|
32
|
+
args;
|
|
33
|
+
result;
|
|
34
|
+
label;
|
|
35
|
+
constructor(call, args, result, label) {
|
|
36
|
+
this.call = call;
|
|
37
|
+
this.args = args;
|
|
38
|
+
this.result = result;
|
|
39
|
+
this.label = label;
|
|
40
|
+
}
|
|
41
|
+
labelPrefix() {
|
|
42
|
+
return 'call_' + this.call.replaceAll(/[^a-zA-Z0-9]/g, '_') + '_';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/iteration
|
|
46
|
+
export class ForStepAST {
|
|
47
|
+
tag = 'for';
|
|
48
|
+
steps;
|
|
49
|
+
loopVariableName;
|
|
50
|
+
indexVariableName;
|
|
51
|
+
listExpression;
|
|
52
|
+
rangeStart;
|
|
53
|
+
rangeEnd;
|
|
54
|
+
label;
|
|
55
|
+
constructor(steps, loopVariableName, listExpression, indexVariable, rangeStart, rangeEnd, label) {
|
|
56
|
+
this.steps = steps;
|
|
57
|
+
this.loopVariableName = loopVariableName;
|
|
58
|
+
this.listExpression = listExpression;
|
|
59
|
+
this.indexVariableName = indexVariable;
|
|
60
|
+
this.rangeStart = rangeStart;
|
|
61
|
+
this.rangeEnd = rangeEnd;
|
|
62
|
+
this.label = label;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export class ForStepASTNamed {
|
|
66
|
+
tag = 'for';
|
|
67
|
+
steps;
|
|
68
|
+
loopVariableName;
|
|
69
|
+
indexVariableName;
|
|
70
|
+
listExpression;
|
|
71
|
+
rangeStart;
|
|
72
|
+
rangeEnd;
|
|
73
|
+
constructor(steps, loopVariableName, listExpression, indexVariable, rangeStart, rangeEnd) {
|
|
74
|
+
this.steps = steps;
|
|
75
|
+
this.loopVariableName = loopVariableName;
|
|
76
|
+
this.listExpression = listExpression;
|
|
77
|
+
this.indexVariableName = indexVariable;
|
|
78
|
+
this.rangeStart = rangeStart;
|
|
79
|
+
this.rangeEnd = rangeEnd;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export class NextStepAST {
|
|
83
|
+
tag = 'next';
|
|
84
|
+
target;
|
|
85
|
+
label;
|
|
86
|
+
constructor(target, label) {
|
|
87
|
+
this.target = target;
|
|
88
|
+
this.label = label;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/parallel-steps
|
|
92
|
+
export class ParallelStepAST {
|
|
93
|
+
tag = 'parallel';
|
|
94
|
+
steps;
|
|
95
|
+
shared;
|
|
96
|
+
concurrencyLimit;
|
|
97
|
+
exceptionPolicy;
|
|
98
|
+
label;
|
|
99
|
+
constructor(steps, shared, concurrencyLimit, exceptionPolicy, label) {
|
|
100
|
+
this.steps = steps;
|
|
101
|
+
this.shared = shared;
|
|
102
|
+
this.concurrencyLimit = concurrencyLimit;
|
|
103
|
+
this.exceptionPolicy = exceptionPolicy;
|
|
104
|
+
this.label = label;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export class ParallelStepASTNamed {
|
|
108
|
+
tag = 'parallel';
|
|
109
|
+
branches; // Either steps for each branch
|
|
110
|
+
forStep; // ... or a parallel for
|
|
111
|
+
shared;
|
|
112
|
+
concurrenceLimit;
|
|
113
|
+
exceptionPolicy;
|
|
114
|
+
constructor(steps, shared, concurrencyLimit, exceptionPolicy) {
|
|
115
|
+
this.shared = shared;
|
|
116
|
+
this.concurrenceLimit = concurrencyLimit;
|
|
117
|
+
this.exceptionPolicy = exceptionPolicy;
|
|
118
|
+
if (!isRecord(steps)) {
|
|
119
|
+
this.forStep = steps;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.branches = Object.entries(steps).map((x) => {
|
|
123
|
+
return { name: x[0], step: x[1] };
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/raising-errors
|
|
129
|
+
export class RaiseStepAST {
|
|
130
|
+
tag = 'raise';
|
|
131
|
+
value;
|
|
132
|
+
label;
|
|
133
|
+
constructor(value, label) {
|
|
134
|
+
this.value = value;
|
|
135
|
+
this.label = label;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/completing
|
|
139
|
+
export class ReturnStepAST {
|
|
140
|
+
tag = 'return';
|
|
141
|
+
value;
|
|
142
|
+
label;
|
|
143
|
+
constructor(value, label) {
|
|
144
|
+
this.value = value;
|
|
145
|
+
this.label = label;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/steps#embedded-steps
|
|
149
|
+
export class StepsStepAST {
|
|
150
|
+
tag = 'steps';
|
|
151
|
+
steps;
|
|
152
|
+
label;
|
|
153
|
+
constructor(steps, label) {
|
|
154
|
+
this.steps = steps;
|
|
155
|
+
this.label = label;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export class StepsStepASTNamed {
|
|
159
|
+
tag = 'steps';
|
|
160
|
+
steps;
|
|
161
|
+
constructor(steps) {
|
|
162
|
+
this.steps = steps;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/conditions
|
|
166
|
+
export class SwitchStepAST {
|
|
167
|
+
tag = 'switch';
|
|
168
|
+
branches;
|
|
169
|
+
label;
|
|
170
|
+
constructor(branches, label) {
|
|
171
|
+
this.branches = branches;
|
|
172
|
+
this.label = label;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export class SwitchStepASTNamed {
|
|
176
|
+
tag = 'switch';
|
|
177
|
+
conditions;
|
|
178
|
+
next;
|
|
179
|
+
constructor(conditions, next) {
|
|
180
|
+
this.conditions = conditions;
|
|
181
|
+
this.next = next;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// https://cloud.google.com/workflows/docs/reference/syntax/catching-errors
|
|
185
|
+
export class TryStepAST {
|
|
186
|
+
tag = 'try';
|
|
187
|
+
trySteps;
|
|
188
|
+
exceptSteps;
|
|
189
|
+
retryPolicy;
|
|
190
|
+
errorMap;
|
|
191
|
+
label;
|
|
192
|
+
constructor(trySteps, exceptSteps, retryPolicy, errorMap, label) {
|
|
193
|
+
this.trySteps = trySteps;
|
|
194
|
+
this.exceptSteps = exceptSteps;
|
|
195
|
+
this.retryPolicy = retryPolicy;
|
|
196
|
+
this.errorMap = errorMap;
|
|
197
|
+
this.label = label;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
export class TryStepASTNamed {
|
|
201
|
+
tag = 'try';
|
|
202
|
+
retryPolicy;
|
|
203
|
+
errorMap;
|
|
204
|
+
// Steps in the try block
|
|
205
|
+
trySteps;
|
|
206
|
+
// Steps in the except block
|
|
207
|
+
exceptSteps;
|
|
208
|
+
constructor(steps, exceptSteps, retryPolicy, errorMap) {
|
|
209
|
+
this.trySteps = steps;
|
|
210
|
+
this.retryPolicy = retryPolicy;
|
|
211
|
+
this.errorMap = errorMap;
|
|
212
|
+
this.exceptSteps = exceptSteps;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Internal step that represents a potential jump target.
|
|
216
|
+
// This can be ued as a placeholder when the actual target step is not yet known.
|
|
217
|
+
// JumpTargetAST is removed before transpiling to workflows YAML.
|
|
218
|
+
export class JumpTargetAST {
|
|
219
|
+
tag = 'jumptarget';
|
|
220
|
+
label;
|
|
221
|
+
constructor() {
|
|
222
|
+
this.label = `jumptarget_${Math.floor(Math.random() * 2 ** 32).toString(16)}`;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Assign a name for this step and its child steps.
|
|
227
|
+
*
|
|
228
|
+
* The name is generated by calling generateName with a prefix identifying the step type.
|
|
229
|
+
*/
|
|
230
|
+
export function namedSteps(step, generateName) {
|
|
231
|
+
switch (step.tag) {
|
|
232
|
+
case 'assign':
|
|
233
|
+
case 'next':
|
|
234
|
+
case 'raise':
|
|
235
|
+
case 'return':
|
|
236
|
+
return {
|
|
237
|
+
name: step.label ?? generateName(step.tag),
|
|
238
|
+
step,
|
|
239
|
+
};
|
|
240
|
+
case 'call':
|
|
241
|
+
return {
|
|
242
|
+
name: step.label ?? generateName(step.labelPrefix()),
|
|
243
|
+
step,
|
|
244
|
+
};
|
|
245
|
+
case 'for':
|
|
246
|
+
return namedStepsFor(step, generateName);
|
|
247
|
+
case 'parallel':
|
|
248
|
+
return namedStepsParallel(step, generateName);
|
|
249
|
+
case 'steps':
|
|
250
|
+
return namedStepsSteps(step, generateName);
|
|
251
|
+
case 'switch':
|
|
252
|
+
return namedStepsSwitch(step, generateName);
|
|
253
|
+
case 'try':
|
|
254
|
+
return namedStepsTry(step, generateName);
|
|
255
|
+
case 'jumptarget':
|
|
256
|
+
return {
|
|
257
|
+
name: step.label,
|
|
258
|
+
step: step,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function namedStepsFor(step, generateName) {
|
|
263
|
+
return {
|
|
264
|
+
name: step.label ?? generateName('for'),
|
|
265
|
+
step: new ForStepASTNamed(step.steps.map((nestedStep) => namedSteps(nestedStep, generateName)), step.loopVariableName, step.listExpression),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function namedStepsParallel(step, generateName) {
|
|
269
|
+
let steps;
|
|
270
|
+
if (!isRecord(step.steps)) {
|
|
271
|
+
const forStep = namedSteps(step.steps, generateName).step;
|
|
272
|
+
if (forStep.tag !== 'for') {
|
|
273
|
+
throw new Error(`Encountered a step of type ${forStep.tag} when a for step was expected`);
|
|
274
|
+
}
|
|
275
|
+
steps = forStep;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
steps = Object.fromEntries(Object.entries(step.steps).map(([name, nested]) => {
|
|
279
|
+
const named = nested.steps.map((x) => namedSteps(x, generateName));
|
|
280
|
+
return [name, new StepsStepASTNamed(named)];
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
name: step.label ?? generateName('parallel'),
|
|
285
|
+
step: new ParallelStepASTNamed(steps, step.shared, step.concurrencyLimit, step.exceptionPolicy),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function namedStepsSteps(step, generateName) {
|
|
289
|
+
return {
|
|
290
|
+
name: step.label ?? generateName('steps'),
|
|
291
|
+
step: new StepsStepASTNamed(step.steps.map((nested) => namedSteps(nested, generateName))),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function namedStepsSwitch(step, generateName) {
|
|
295
|
+
const namedBranches = step.branches.map((branch) => ({
|
|
296
|
+
condition: branch.condition,
|
|
297
|
+
steps: branch.steps.map((nested) => namedSteps(nested, generateName)),
|
|
298
|
+
next: branch.next,
|
|
299
|
+
}));
|
|
300
|
+
return {
|
|
301
|
+
name: step.label ?? generateName('switch'),
|
|
302
|
+
step: new SwitchStepASTNamed(namedBranches),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function namedStepsTry(step, generateName) {
|
|
306
|
+
const namedTrySteps = step.trySteps.map((nested) => namedSteps(nested, generateName));
|
|
307
|
+
const namedExceptSteps = step.exceptSteps.map((nested) => namedSteps(nested, generateName));
|
|
308
|
+
return {
|
|
309
|
+
name: step.label ?? generateName('try'),
|
|
310
|
+
step: new TryStepASTNamed(namedTrySteps, namedExceptSteps, step.retryPolicy, step.errorMap),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Returns the nested steps in contained in this step.
|
|
315
|
+
*
|
|
316
|
+
* Used in iterating the AST tree.
|
|
317
|
+
*/
|
|
318
|
+
export function nestedSteps(step) {
|
|
319
|
+
switch (step.tag) {
|
|
320
|
+
case 'assign':
|
|
321
|
+
case 'call':
|
|
322
|
+
case 'next':
|
|
323
|
+
case 'raise':
|
|
324
|
+
case 'return':
|
|
325
|
+
case 'jumptarget':
|
|
326
|
+
return [];
|
|
327
|
+
case 'for':
|
|
328
|
+
case 'steps':
|
|
329
|
+
return [step.steps];
|
|
330
|
+
case 'parallel':
|
|
331
|
+
return nestedStepsParallel(step);
|
|
332
|
+
case 'switch':
|
|
333
|
+
return step.conditions.map((x) => x.steps);
|
|
334
|
+
case 'try':
|
|
335
|
+
return nestedStepsTry(step);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function nestedStepsParallel(step) {
|
|
339
|
+
const nested = [];
|
|
340
|
+
if (step.branches && step.branches.length > 0) {
|
|
341
|
+
// return each branch as a separate child
|
|
342
|
+
nested.push(...step.branches.map((x) => [x]));
|
|
343
|
+
}
|
|
344
|
+
if (step.forStep?.steps && step.forStep.steps.length > 0) {
|
|
345
|
+
nested.push(step.forStep.steps);
|
|
346
|
+
}
|
|
347
|
+
return nested;
|
|
348
|
+
}
|
|
349
|
+
function nestedStepsTry(step) {
|
|
350
|
+
const nested = [];
|
|
351
|
+
if (step.trySteps.length > 0) {
|
|
352
|
+
nested.push(step.trySteps);
|
|
353
|
+
}
|
|
354
|
+
if (step.exceptSteps.length > 0) {
|
|
355
|
+
nested.push(step.exceptSteps);
|
|
356
|
+
}
|
|
357
|
+
return nested;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Returns an GCP Workflows object representation of a step.
|
|
361
|
+
*/
|
|
362
|
+
export function renderStep(step) {
|
|
363
|
+
switch (step.tag) {
|
|
364
|
+
case 'assign':
|
|
365
|
+
return {
|
|
366
|
+
assign: step.assignments.map(([key, val]) => {
|
|
367
|
+
return { [key]: expressionToLiteralValueOrLiteralExpression(val) };
|
|
368
|
+
}),
|
|
369
|
+
};
|
|
370
|
+
case 'call':
|
|
371
|
+
return renderCallStep(step);
|
|
372
|
+
case 'for':
|
|
373
|
+
return {
|
|
374
|
+
for: renderForBody(step),
|
|
375
|
+
};
|
|
376
|
+
case 'parallel':
|
|
377
|
+
return {
|
|
378
|
+
parallel: {
|
|
379
|
+
...(step.shared && { shared: step.shared }),
|
|
380
|
+
...(step.concurrenceLimit && {
|
|
381
|
+
concurrency_limit: step.concurrenceLimit,
|
|
382
|
+
}),
|
|
383
|
+
...(step.exceptionPolicy && {
|
|
384
|
+
exception_policy: step.exceptionPolicy,
|
|
385
|
+
}),
|
|
386
|
+
...(step.branches && { branches: renderSteps(step.branches) }),
|
|
387
|
+
...(step.forStep && { for: renderForBody(step.forStep) }),
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
case 'next':
|
|
391
|
+
return {
|
|
392
|
+
next: step.target,
|
|
393
|
+
};
|
|
394
|
+
case 'raise':
|
|
395
|
+
return {
|
|
396
|
+
raise: expressionToLiteralValueOrLiteralExpression(step.value),
|
|
397
|
+
};
|
|
398
|
+
case 'return':
|
|
399
|
+
return renderReturnStep(step);
|
|
400
|
+
case 'steps':
|
|
401
|
+
return {
|
|
402
|
+
steps: renderSteps(step.steps),
|
|
403
|
+
};
|
|
404
|
+
case 'switch':
|
|
405
|
+
return {
|
|
406
|
+
switch: step.conditions.map(renderSwitchCondition),
|
|
407
|
+
...(step.next && { next: step.next }),
|
|
408
|
+
};
|
|
409
|
+
case 'try':
|
|
410
|
+
return renderTryStep(step);
|
|
411
|
+
case 'jumptarget':
|
|
412
|
+
return {};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function renderSwitchCondition(cond) {
|
|
416
|
+
return {
|
|
417
|
+
condition: expressionToLiteralValueOrLiteralExpression(cond.condition),
|
|
418
|
+
...(cond.steps.length > 0 && { steps: renderSteps(cond.steps) }),
|
|
419
|
+
...(cond.next && { next: cond.next }),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function renderCallStep(step) {
|
|
423
|
+
let args = undefined;
|
|
424
|
+
if (step.args) {
|
|
425
|
+
args = Object.fromEntries(Object.entries(step.args).map(([k, v]) => {
|
|
426
|
+
return [k, expressionToLiteralValueOrLiteralExpression(v)];
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
call: step.call,
|
|
431
|
+
...(args && { args }),
|
|
432
|
+
...(step.result && { result: step.result }),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function renderForBody(step) {
|
|
436
|
+
let range;
|
|
437
|
+
let inValue;
|
|
438
|
+
if (typeof step.listExpression === 'undefined') {
|
|
439
|
+
range = [step.rangeStart, step.rangeEnd];
|
|
440
|
+
inValue = undefined;
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
inValue = expressionToLiteralValueOrLiteralExpression(step.listExpression);
|
|
444
|
+
range = undefined;
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
value: step.loopVariableName,
|
|
448
|
+
...(step.indexVariableName && { index: step.indexVariableName }),
|
|
449
|
+
...(inValue && { in: inValue }),
|
|
450
|
+
...(range && { range }),
|
|
451
|
+
steps: renderSteps(step.steps),
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
function renderReturnStep(step) {
|
|
455
|
+
if (step.value) {
|
|
456
|
+
return {
|
|
457
|
+
return: expressionToLiteralValueOrLiteralExpression(step.value),
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
return {
|
|
462
|
+
next: 'end',
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function renderTryStep(step) {
|
|
467
|
+
let retry;
|
|
468
|
+
if (typeof step.retryPolicy === 'undefined') {
|
|
469
|
+
retry = undefined;
|
|
470
|
+
}
|
|
471
|
+
else if (typeof step.retryPolicy === 'string') {
|
|
472
|
+
retry = `\${${step.retryPolicy}}`;
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
const predicateName = step.retryPolicy.predicate;
|
|
476
|
+
retry = {
|
|
477
|
+
predicate: `\${${predicateName}}`,
|
|
478
|
+
max_retries: step.retryPolicy.maxRetries,
|
|
479
|
+
backoff: {
|
|
480
|
+
initial_delay: step.retryPolicy.backoff.initialDelay,
|
|
481
|
+
max_delay: step.retryPolicy.backoff.maxDelay,
|
|
482
|
+
multiplier: step.retryPolicy.backoff.multiplier,
|
|
483
|
+
},
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
let except;
|
|
487
|
+
if (step.exceptSteps.length > 0) {
|
|
488
|
+
except = {
|
|
489
|
+
as: step.errorMap,
|
|
490
|
+
steps: renderSteps(step.exceptSteps),
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
except = undefined;
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
try: {
|
|
498
|
+
steps: renderSteps(step.trySteps),
|
|
499
|
+
},
|
|
500
|
+
...(retry && { retry }),
|
|
501
|
+
...(except && { except }),
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function renderSteps(steps) {
|
|
505
|
+
return steps.map((x) => {
|
|
506
|
+
return { [x.name]: renderStep(x.step) };
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
export function stepWithLabel(step, label) {
|
|
510
|
+
switch (step.tag) {
|
|
511
|
+
case 'assign':
|
|
512
|
+
return new AssignStepAST(step.assignments, label);
|
|
513
|
+
case 'call':
|
|
514
|
+
return new CallStepAST(step.call, step.args, step.result, label);
|
|
515
|
+
case 'for':
|
|
516
|
+
return new ForStepAST(step.steps, step.loopVariableName, step.listExpression, step.indexVariableName, step.rangeStart, step.rangeEnd, label);
|
|
517
|
+
case 'next':
|
|
518
|
+
return new NextStepAST(step.target, label);
|
|
519
|
+
case 'parallel':
|
|
520
|
+
return new ParallelStepAST(step.steps, step.shared, step.concurrencyLimit, step.exceptionPolicy, label);
|
|
521
|
+
case 'raise':
|
|
522
|
+
return new RaiseStepAST(step.value, label);
|
|
523
|
+
case 'return':
|
|
524
|
+
return new ReturnStepAST(step.value, label);
|
|
525
|
+
case 'steps':
|
|
526
|
+
return new StepsStepAST(step.steps, label);
|
|
527
|
+
case 'switch':
|
|
528
|
+
return new SwitchStepAST(step.branches, label);
|
|
529
|
+
case 'try':
|
|
530
|
+
return new TryStepAST(step.trySteps, step.exceptSteps, step.retryPolicy, step.errorMap, label);
|
|
531
|
+
case 'jumptarget':
|
|
532
|
+
return step;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { WorkflowApp } from './workflows.js';
|
|
2
|
+
export declare class WorkflowValidationError extends Error {
|
|
3
|
+
issues: WorkflowIssue[];
|
|
4
|
+
constructor(issues: WorkflowIssue[]);
|
|
5
|
+
}
|
|
6
|
+
export interface WorkflowIssue {
|
|
7
|
+
type: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Execute all syntax validators on a WorkflowApp app.
|
|
12
|
+
*
|
|
13
|
+
* Throws a WorkflowValidationError if there are errors.
|
|
14
|
+
*/
|
|
15
|
+
export declare function validate(app: WorkflowApp, disabled?: string[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* Returns all validator names.
|
|
18
|
+
*/
|
|
19
|
+
export declare function validatorNames(): string[];
|
|
20
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/ast/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEzD,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,MAAM,EAAE,aAAa,EAAE,CAAA;gBAEX,MAAM,EAAE,aAAa,EAAE;CAMpC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAWD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,IAAI,CAexE;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC"}
|