ts2workflows 0.10.0 → 0.11.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright © 2024 Antti Ajanki, <antti.ajanki@iki.fi>
3
+ Copyright © 2024-2025 Antti Ajanki, <antti.ajanki@iki.fi>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -2,13 +2,22 @@
2
2
 
3
3
  ts2workflows converts Typescript code to a [GCP Workflows](https://cloud.google.com/workflows/docs/apis) program.
4
4
 
5
+ ![NPM Version](https://img.shields.io/npm/v/ts2workflows)
6
+ ![Node LTS](https://img.shields.io/node/v-lts/ts2workflows)
7
+
5
8
  Only a subset of Typescript features are supported. The [language reference](language_reference.md) describes the supported Typescript features.
6
9
 
7
10
  See the [samples](samples) directory for code examples.
8
11
 
9
12
  Project status: It's possible to write Workflows programs, but the transpiler has not been extensively tested. Expect some rough edges!
10
13
 
11
- ## Command for transpiling a Typescript file to Workflows syntax
14
+ ## Installation
15
+
16
+ ```
17
+ npm install ts2workflows
18
+ ```
19
+
20
+ ## Usage
12
21
 
13
22
  Converting Typescript code in a file samples/sample1.ts into GCP Workflows YAML syntax on stdout:
14
23
 
@@ -28,7 +37,7 @@ When developing ts2workflows, you can run the transpiler directly from the sourc
28
37
  npx tsx src/cli.ts samples/sample1.ts
29
38
  ```
30
39
 
31
- ## Type checking
40
+ ## Type checking workflow sources
32
41
 
33
42
  One benefit of writing the workflow programs in Typescript is that the sources can be type checked.
34
43
 
@@ -48,20 +57,28 @@ import { http, retry_policy } from 'ts2workflows/types/workflowslib'
48
57
 
49
58
  Type checking step is completely separate from the transpiling. The ts2workflows command ignores type annotations.
50
59
 
51
- ## Build
60
+ ## Development
61
+
62
+ ### Build
52
63
 
53
64
  ```
54
65
  npm install
55
66
  npm run build
56
67
  ```
57
68
 
58
- ## Run unit tests
69
+ ### Run unit tests
59
70
 
60
71
  ```
61
72
  npm run test
62
73
  ```
63
74
 
64
- ## Architecture
75
+ Run tests and print the test coverage:
76
+
77
+ ```
78
+ npm run test-coverage
79
+ ```
80
+
81
+ ### Architecture
65
82
 
66
83
  A transpilation using ts2workflows consists of five phases:
67
84
 
@@ -12,9 +12,9 @@ export class StepNameGenerator {
12
12
  }
13
13
  }
14
14
  export function generateStepNames(ast) {
15
- const stepNameGenerator = new StepNameGenerator();
16
15
  const subworkflows = ast.subworkflows
17
16
  .map((subworkflow) => {
17
+ const stepNameGenerator = new StepNameGenerator();
18
18
  return subworkflow.withStepNames((x) => stepNameGenerator.generate(x));
19
19
  })
20
20
  .map(fixJumpLabels);
@@ -150,7 +150,7 @@ function removeJumpTargetsParallel(step) {
150
150
  return new ParallelStepASTNamed(transformedSteps, step.shared, step.concurrenceLimit, step.exceptionPolicy);
151
151
  }
152
152
  function removeJumpTargetsSwitch(step) {
153
- const transformedConditions = step.conditions.map((cond) => {
153
+ const transformedConditions = step.branches.map((cond) => {
154
154
  return {
155
155
  condition: cond.condition,
156
156
  steps: removeJumpTargetSteps(cond.steps),
@@ -250,7 +250,7 @@ function renameJumpTargetsSwitch(step, replaceLabels) {
250
250
  if (step.next) {
251
251
  updatedNext = replaceLabels.get(step.next) ?? step.next;
252
252
  }
253
- const updatedConditions = step.conditions.map((cond) => {
253
+ const updatedConditions = step.branches.map((cond) => {
254
254
  let updatedCondNext = undefined;
255
255
  if (cond.next) {
256
256
  updatedCondNext = replaceLabels.get(cond.next) ?? cond.next;
@@ -157,9 +157,9 @@ export declare class SwitchStepAST {
157
157
  }
158
158
  export declare class SwitchStepASTNamed {
159
159
  readonly tag = "switch";
160
- readonly conditions: SwitchConditionAST<NamedWorkflowStep>[];
160
+ readonly branches: SwitchConditionAST<NamedWorkflowStep>[];
161
161
  readonly next?: StepName;
162
- constructor(conditions: SwitchConditionAST<NamedWorkflowStep>[], next?: StepName);
162
+ constructor(branches: SwitchConditionAST<NamedWorkflowStep>[], next?: StepName);
163
163
  }
164
164
  export interface SwitchConditionAST<T extends WorkflowStepAST | NamedWorkflowStep> {
165
165
  readonly condition: Expression;
@@ -179,11 +179,11 @@ export declare class TryStepAST {
179
179
  }
180
180
  export declare class TryStepASTNamed {
181
181
  readonly tag = "try";
182
- readonly retryPolicy?: string | CustomRetryPolicy;
183
- readonly errorMap?: VariableName;
184
182
  readonly trySteps: NamedWorkflowStep[];
185
183
  readonly exceptSteps?: NamedWorkflowStep[];
186
- constructor(steps: NamedWorkflowStep[], exceptSteps?: NamedWorkflowStep[], retryPolicy?: string | CustomRetryPolicy, errorMap?: VariableName);
184
+ readonly retryPolicy?: string | CustomRetryPolicy;
185
+ readonly errorMap?: VariableName;
186
+ constructor(trySteps: NamedWorkflowStep[], exceptSteps?: NamedWorkflowStep[], retryPolicy?: string | CustomRetryPolicy, errorMap?: VariableName);
187
187
  }
188
188
  export declare class JumpTargetAST {
189
189
  readonly tag = "jumptarget";
@@ -1 +1 @@
1
- {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/ast/steps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/ast/steps.ts"],"names":[],"mappings":"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"}
package/dist/ast/steps.js CHANGED
@@ -267,17 +267,19 @@ export class SwitchStepAST {
267
267
  }
268
268
  export class SwitchStepASTNamed {
269
269
  tag = 'switch';
270
- conditions;
270
+ branches;
271
271
  next;
272
- constructor(conditions, next) {
273
- this.conditions = conditions;
272
+ constructor(branches, next) {
273
+ this.branches = branches;
274
274
  this.next = next;
275
275
  }
276
276
  }
277
277
  // https://cloud.google.com/workflows/docs/reference/syntax/catching-errors
278
278
  export class TryStepAST {
279
279
  tag = 'try';
280
+ // Steps in the try block
280
281
  trySteps;
282
+ // Steps in the except block
281
283
  exceptSteps;
282
284
  retryPolicy;
283
285
  errorMap;
@@ -298,14 +300,14 @@ export class TryStepAST {
298
300
  }
299
301
  export class TryStepASTNamed {
300
302
  tag = 'try';
301
- retryPolicy;
302
- errorMap;
303
303
  // Steps in the try block
304
304
  trySteps;
305
305
  // Steps in the except block
306
306
  exceptSteps;
307
- constructor(steps, exceptSteps, retryPolicy, errorMap) {
308
- this.trySteps = steps;
307
+ retryPolicy;
308
+ errorMap;
309
+ constructor(trySteps, exceptSteps, retryPolicy, errorMap) {
310
+ this.trySteps = trySteps;
309
311
  this.retryPolicy = retryPolicy;
310
312
  this.errorMap = errorMap;
311
313
  this.exceptSteps = exceptSteps;
@@ -443,7 +445,7 @@ export function nestedSteps(step) {
443
445
  case 'parallel':
444
446
  return nestedStepsParallel(step);
445
447
  case 'switch':
446
- return step.conditions.map((x) => x.steps);
448
+ return step.branches.map((x) => x.steps);
447
449
  case 'try':
448
450
  return nestedStepsTry(step);
449
451
  }
@@ -519,7 +521,7 @@ export function renderStep(step) {
519
521
  };
520
522
  case 'switch':
521
523
  return {
522
- switch: step.conditions.map(renderSwitchCondition),
524
+ switch: step.branches.map(renderSwitchCondition),
523
525
  ...(step.next && { next: step.next }),
524
526
  };
525
527
  case 'try':
@@ -19,10 +19,5 @@ export declare class Subworkflow {
19
19
  constructor(name: string, steps: NamedWorkflowStep[], params?: WorkflowParameter[]);
20
20
  render(): Record<string, unknown>;
21
21
  renderBody(): Record<string, unknown>;
22
- iterateStepsDepthFirst(): IterableIterator<NamedWorkflowStep>;
23
22
  }
24
- /**
25
- * Print the workflow as a YAML string.
26
- */
27
- export declare function toYAMLString(workflow: WorkflowApp): string;
28
23
  //# sourceMappingURL=workflows.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/ast/workflows.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAA2B,MAAM,YAAY,CAAA;AAEvE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE,+BAA+B,CAAA;CAC1C;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,YAAY,EAAE,WAAW,EAAE,CAAA;gBAExB,YAAY,GAAE,WAAW,EAAO;IAI5C,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAKlC;AAGD,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;gBAGnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,iBAAiB,EAAE,EAC1B,MAAM,CAAC,EAAE,iBAAiB,EAAE;IAO9B,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMjC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAuBpC,sBAAsB,IAAI,gBAAgB,CAAC,iBAAiB,CAAC;CAqB/D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAI1D"}
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/ast/workflows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAc,MAAM,YAAY,CAAA;AAE1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,CAAC,EAAE,+BAA+B,CAAA;CAC1C;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,YAAY,EAAE,WAAW,EAAE,CAAA;gBAExB,YAAY,GAAE,WAAW,EAAO;IAI5C,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAKlC;AAGD,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAAE,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAA;gBAGnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,iBAAiB,EAAE,EAC1B,MAAM,CAAC,EAAE,iBAAiB,EAAE;IAO9B,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMjC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAsBtC"}
@@ -1,5 +1,4 @@
1
- import * as YAML from 'yaml';
2
- import { nestedSteps, renderStep } from './steps.js';
1
+ import { renderStep } from './steps.js';
3
2
  /**
4
3
  * This is the main container class that brings together all subworkflows in a program
5
4
  */
@@ -48,27 +47,4 @@ export class Subworkflow {
48
47
  });
49
48
  return body;
50
49
  }
51
- *iterateStepsDepthFirst() {
52
- const visited = new Set();
53
- function* visitPreOrder(step) {
54
- if (!visited.has(step)) {
55
- visited.add(step);
56
- yield step;
57
- for (const x of nestedSteps(step.step).flat()) {
58
- yield* visitPreOrder(x);
59
- }
60
- }
61
- }
62
- for (const step of this.steps) {
63
- yield* visitPreOrder(step);
64
- }
65
- }
66
- }
67
- /**
68
- * Print the workflow as a YAML string.
69
- */
70
- export function toYAMLString(workflow) {
71
- return YAML.stringify(workflow.render(), {
72
- lineWidth: 100,
73
- });
74
50
  }
@@ -1,2 +1,7 @@
1
+ import { WorkflowApp } from '../ast/workflows.js';
1
2
  export declare function transpile(code: string, inputFile?: string, tsconfigPath?: string): string;
3
+ /**
4
+ * Print the workflow as a YAML string.
5
+ */
6
+ export declare function toYAMLString(workflow: WorkflowApp): string;
2
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transpiler/index.ts"],"names":[],"mappings":"AAcA,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAkBR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transpiler/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAA;AAKpE,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAkBR;AAuID;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAI1D"}
@@ -20,7 +20,7 @@ export function transpile(code, inputFile, tsconfigPath) {
20
20
  const { ast } = parseAndGenerateServices(code, parserOptions);
21
21
  const workflowAst = { subworkflows: ast.body.flatMap(parseTopLevelStatement) };
22
22
  const workflow = generateStepNames(workflowAst);
23
- return YAML.stringify(workflow.render(), { lineWidth: 100 });
23
+ return toYAMLString(workflow);
24
24
  }
25
25
  function parseTopLevelStatement(node) {
26
26
  switch (node.type) {
@@ -104,3 +104,11 @@ function parseSubworkflowDefaultArgument(param) {
104
104
  default: defaultValue,
105
105
  };
106
106
  }
107
+ /**
108
+ * Print the workflow as a YAML string.
109
+ */
110
+ export function toYAMLString(workflow) {
111
+ return YAML.stringify(workflow.render(), {
112
+ lineWidth: 100,
113
+ });
114
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../src/transpiler/statements.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,QAAQ,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EAWL,QAAQ,EAOR,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAkCxB,MAAM,WAAW,cAAc;IAE7B,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAA;IAE/B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAA;IAGlC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAKtC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAA;CAC9B;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,SAAS,EACxB,GAAG,EAAE,cAAc,GAClB,eAAe,EAAE,CAEnB"}
1
+ {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../src/transpiler/statements.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,QAAQ,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EAWL,QAAQ,EAOR,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAkCxB,MAAM,WAAW,cAAc;IAE7B,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAA;IAE/B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAA;IAGlC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAKtC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAA;CAC9B;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,SAAS,EACxB,GAAG,EAAE,cAAc,GAClB,eAAe,EAAE,CA6EnB"}
@@ -3,18 +3,15 @@ import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree';
3
3
  import { AssignStepAST, CallStepAST, ForRangeStepAST, ForStepAST, JumpTargetAST, NextStepAST, ParallelStepAST, RaiseStepAST, ReturnStepAST, StepsStepAST, SwitchStepAST, TryStepAST, } from '../ast/steps.js';
4
4
  import { BinaryExpression, FunctionInvocationExpression, MemberExpression, PrimitiveExpression, VariableReferenceExpression, asExpression, isExpression, isFullyQualifiedName, isLiteral, isPure, nullEx, safeAsExpression, trueEx, } from '../ast/expressions.js';
5
5
  import { InternalTranspilingError, WorkflowSyntaxError } from '../errors.js';
6
- import { chainPairs, isRecord } from '../utils.js';
6
+ import { isRecord } from '../utils.js';
7
7
  import { convertExpression, convertMemberExpression, convertObjectExpression, convertObjectAsExpressionValues, isIntrinsic, throwIfSpread, isIntrinsicStatment as isIntrinsicStatement, convertVariableNameExpression, } from './expressions.js';
8
8
  import { blockingFunctions } from './generated/functionMetadata.js';
9
9
  export function parseStatement(node, ctx) {
10
- return parseStatementRecursively(node, undefined, ctx);
11
- }
12
- function parseStatementRecursively(node, nextNode, ctx) {
13
10
  switch (node.type) {
14
11
  case AST_NODE_TYPES.BlockStatement:
15
- return chainPairs(R.partialRight(parseStatementRecursively, [ctx]), node.body);
12
+ return node.body.flatMap((node) => parseStatement(node, ctx));
16
13
  case AST_NODE_TYPES.VariableDeclaration:
17
- return convertVariableDeclarations(node.declarations, ctx);
14
+ return convertVariableDeclarations(node, ctx);
18
15
  case AST_NODE_TYPES.ExpressionStatement:
19
16
  if (node.expression.type === AST_NODE_TYPES.AssignmentExpression) {
20
17
  return assignmentExpressionToSteps(node.expression, ctx);
@@ -45,14 +42,8 @@ function parseStatementRecursively(node, nextNode, ctx) {
45
42
  return [breakStatementToNextStep(node, ctx)];
46
43
  case AST_NODE_TYPES.ContinueStatement:
47
44
  return [continueStatementToNextStep(node, ctx)];
48
- case AST_NODE_TYPES.TryStatement: {
49
- let retryPolicy = undefined;
50
- if (nextNode?.type === AST_NODE_TYPES.ExpressionStatement &&
51
- nextNode.expression.type === AST_NODE_TYPES.CallExpression) {
52
- retryPolicy = parseRetryPolicy(nextNode.expression);
53
- }
54
- return tryStatementToTrySteps(node, retryPolicy, ctx);
55
- }
45
+ case AST_NODE_TYPES.TryStatement:
46
+ return tryStatementToTrySteps(node, ctx);
56
47
  case AST_NODE_TYPES.LabeledStatement:
57
48
  return labeledStep(node, ctx);
58
49
  case AST_NODE_TYPES.EmptyStatement:
@@ -68,8 +59,11 @@ function parseStatementRecursively(node, nextNode, ctx) {
68
59
  throw new WorkflowSyntaxError(`TODO: encountered unsupported type: ${node.type}`, node.loc);
69
60
  }
70
61
  }
71
- function convertVariableDeclarations(declarations, ctx) {
72
- return declarations.flatMap((decl) => {
62
+ function convertVariableDeclarations(node, ctx) {
63
+ if (node.kind !== 'const' && node.kind !== 'let') {
64
+ throw new WorkflowSyntaxError('Only const and let variable declarations are supported', node.loc);
65
+ }
66
+ return node.declarations.flatMap((decl) => {
73
67
  if (decl.id.type === AST_NODE_TYPES.Identifier) {
74
68
  return convertInitializer(decl.id.name, decl.init, ctx);
75
69
  }
@@ -885,7 +879,8 @@ function continueStatementToNextStep(node, ctx) {
885
879
  }
886
880
  return new NextStepAST(target);
887
881
  }
888
- function tryStatementToTrySteps(node, retryPolicy, ctx) {
882
+ function tryStatementToTrySteps(node, ctx) {
883
+ const retryPolicy = extractRetryPolicy(node.block);
889
884
  if (!node.finalizer) {
890
885
  // Basic try-catch without a finally block
891
886
  const baseTryStep = parseTryCatchRetry(node, ctx, retryPolicy);
@@ -1033,27 +1028,30 @@ function labeledStep(node, ctx) {
1033
1028
  }
1034
1029
  return steps;
1035
1030
  }
1036
- function parseRetryPolicy(node) {
1037
- const callee = node.callee;
1038
- if (callee.type !== AST_NODE_TYPES.Identifier ||
1039
- callee.name !== 'retry_policy') {
1040
- // Ignore everything else besides retry_policy()
1041
- return undefined;
1042
- }
1043
- if (node.arguments.length < 1) {
1044
- throw new WorkflowSyntaxError('Required argument missing', node.loc);
1045
- }
1046
- const arg0 = throwIfSpread(node.arguments).map(convertExpression)[0];
1047
- const argsLoc = node.arguments[0].loc;
1048
- if (isFullyQualifiedName(arg0)) {
1049
- return arg0.toString();
1050
- }
1051
- else if (arg0.expressionType === 'primitive' && isRecord(arg0.value)) {
1052
- return retryPolicyFromParams(arg0.value, argsLoc);
1053
- }
1054
- else {
1055
- throw new WorkflowSyntaxError('Unexpected type', argsLoc);
1031
+ function extractRetryPolicy(tryBlock) {
1032
+ // Find and parse the first retry_policy() in tryBlock
1033
+ for (const statement of tryBlock.body) {
1034
+ if (statement.type === AST_NODE_TYPES.ExpressionStatement &&
1035
+ statement.expression.type === AST_NODE_TYPES.CallExpression &&
1036
+ statement.expression.callee.type === AST_NODE_TYPES.Identifier &&
1037
+ statement.expression.callee.name === 'retry_policy') {
1038
+ if (statement.expression.arguments.length < 1) {
1039
+ throw new WorkflowSyntaxError('Required argument missing', statement.expression.loc);
1040
+ }
1041
+ const arg0 = throwIfSpread(statement.expression.arguments).map(convertExpression)[0];
1042
+ const argsLoc = statement.expression.arguments[0].loc;
1043
+ if (isFullyQualifiedName(arg0)) {
1044
+ return arg0.toString();
1045
+ }
1046
+ else if (arg0.expressionType === 'primitive' && isRecord(arg0.value)) {
1047
+ return retryPolicyFromParams(arg0.value, argsLoc);
1048
+ }
1049
+ else {
1050
+ throw new WorkflowSyntaxError('Unexpected type', argsLoc);
1051
+ }
1052
+ }
1056
1053
  }
1054
+ return undefined;
1057
1055
  }
1058
1056
  function retryPolicyFromParams(paramsObject, argsLoc) {
1059
1057
  const params = R.map(asExpression, paramsObject);
package/dist/utils.d.ts CHANGED
@@ -1,9 +1,2 @@
1
1
  export declare function isRecord(object: unknown): object is Record<keyof never, unknown>;
2
- /**
3
- * Like arr.flatMap() but the callback takes two consecutive array elements.
4
- *
5
- * During the last execution of the callback, the second argument (which would
6
- * be element after the last array element) will be undefined.
7
- */
8
- export declare function chainPairs<T, U>(callback: (val: T, next: T | undefined) => U[], arr: readonly T[]): U[];
9
2
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CACtB,MAAM,EAAE,OAAO,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAExC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,EAC9C,GAAG,EAAE,SAAS,CAAC,EAAE,GAChB,CAAC,EAAE,CAKL"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CACtB,MAAM,EAAE,OAAO,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,OAAO,CAAC,CAExC"}
package/dist/utils.js CHANGED
@@ -1,13 +1,3 @@
1
- import * as R from 'ramda';
2
1
  export function isRecord(object) {
3
2
  return object instanceof Object && object.constructor === Object;
4
3
  }
5
- /**
6
- * Like arr.flatMap() but the callback takes two consecutive array elements.
7
- *
8
- * During the last execution of the callback, the second argument (which would
9
- * be element after the last array element) will be undefined.
10
- */
11
- export function chainPairs(callback, arr) {
12
- return R.chain(R.apply(callback), R.zip(arr, R.append(undefined, R.tail(arr))));
13
- }
@@ -20,6 +20,14 @@ Semicolon can be used as optional statement delimitter.
20
20
  - Array: `[1, 2, 3]`
21
21
  - Map: `{temperature: -12, unit: "Celsius"}`
22
22
 
23
+ The Typescript type alias `WorkflowsValue` (provided by `ts2workflows/types/workflowslib`) represents any valid Workflows value. Sample usage:
24
+
25
+ ```typescript
26
+ import { WorkflowsValue } from 'ts2workflows/types/workflowslib'
27
+
28
+ const x: WorkflowsValue = [1, 2]
29
+ ```
30
+
23
31
  ### Array type
24
32
 
25
33
  ⚠️ Arrays are not objects in GCP Workflows. In particular, methods like `[].map()` and `[].concat()` are not available.
@@ -46,7 +54,7 @@ Note that `null` and `undefined` still are distinct types on the type checking s
46
54
 
47
55
  Expressions that combine variables with operators such as `+`, `>`, `==` perform implict type conversions according to the [rules listed on GCP Workflows documentation](https://cloud.google.com/workflows/docs/reference/syntax/datatypes#implicit-conversions). For example, applying `+` to a string and a number concatenates the values into a string.
48
56
 
49
- ⚠️ Checking if a variable is null or not must be done by an explicit comparison: `if (var != null) {...}`. Relying on an implicit conversion (`if (var) {...}` where `var` is not a boolean) results in a TypeError at runtime.
57
+ ⚠️ Checking if a variable is null or not must be done by an explicit comparison: `if (myVar != null) {...}`. Relying on an implicit conversion (`if (myVvar) {...}` where `myVar` is not a boolean) results in a TypeError at runtime.
50
58
 
51
59
  ## Expressions
52
60
 
@@ -156,6 +164,25 @@ String literals can include interpolated variables. The syntax is same as in Typ
156
164
 
157
165
  ⚠️ Interpolated values can (only) be numbers, strings, booleans or nulls. Other types will throw a TypeError at runtime.
158
166
 
167
+ ## Variable scopes
168
+
169
+ Variable scopes are determined by the [GCP Workflows scoping rules](https://cloud.google.com/workflows/docs/reference/syntax/variables#variable-scope).
170
+
171
+ Variables have function scope, that is they are available in the function where they are defined. Variables defined in `for` and `except` blocks are exceptions; they belong to a local scope of the block in which they are declared.
172
+
173
+ ⚠️ TypeScript has more strict scoping rules. In Typescript, variables declared with `let` or `const` are accessible only on the block in which they are declared (i.e. variable declared inside an if branch cannot be accessed after the if block ends). Programs written according to TypeScript scoping rules always produce valid GCP Workflows programs, too.
174
+
175
+ Trying to read a variable before it is assigned causes a runtime error.
176
+
177
+ ⚠️ If variable is not initialized at declaration, its value is implicitly set to `null`. For example, the following program will return `null`. (Note that the sample is not valid as a TypeScript program. TypeScript compiler consideres variable `x` to be used before it is assigned.)
178
+
179
+ ```typescript
180
+ function main(): void {
181
+ let x: number | null
182
+ return x
183
+ }
184
+ ```
185
+
159
186
  ## Subworkflow definitions
160
187
 
161
188
  ts2workflows converts Typescript `function`s to subworkflow definitions.
@@ -694,24 +721,25 @@ If an exception gets thrown inside a try block, the stack trace in Workflows log
694
721
 
695
722
  ## Retrying on errors
696
723
 
697
- It is possible to set a retry policy for a try-catch statement. Because Typescript does not have `retry` keyword, the retry is implemented by a special `retry_policy` intrinsic function. It must be called immediately after a try-catch block. `retry_policy` is ignored elsewhere.
724
+ It is possible to set a retry policy for a try-catch statement. Because Typescript does not have `retry` keyword, the retry is implemented by a `retry_policy` intrinsic function. It must be called inside a try block. `retry_policy` is ignored elsewhere. Only the first `retry_policy` in a try block has any effect.
698
725
 
699
726
  The arguments of `retry_policy` specify which errors are retried and how many times. The arguments can be either a policy provided by GCP Workflows or a custom retry policy as explained in the next sections.
700
727
 
701
- If an exception gets thrown in a try block and the retry policy covers the exception, the try block is executed again. Finally and catch blocks are run after possible retry attempts. The following sample retries `http.get()` if it throws an HTTP error and executes `sys.log('Error!')` and `closeConnection()` after retry attempts.
728
+ If an exception gets thrown in a try block and the retry policy covers the exception, the try block is executed again. Finally and catch blocks are run if the try block keeps failing after all retry attempts have been used up. The following sample retries `http.get()` if it throws an HTTP error covered by `http.default_retry`. It logs `sys.log('Error!')` if the number of retry attempts exceed retry policy's maximum retry attempt count. `closeConnection()` is run always regardless of whether the HTTP request succeeded or failed.
702
729
 
703
730
  ```javascript
704
731
  import { http, retry_policy, sys } from 'ts2workflows/types/workflowslib'
705
732
 
706
733
  function main() {
707
734
  try {
735
+ retry_policy(http.default_retry)
736
+
708
737
  http.get('https://visit.dreamland.test/')
709
738
  } catch (err) {
710
739
  sys.log('Error!')
711
740
  } finally {
712
741
  closeConnection()
713
742
  }
714
- retry_policy(http.default_retry)
715
743
  }
716
744
  ```
717
745
 
@@ -724,11 +752,12 @@ import { http, retry_policy } from 'ts2workflows/types/workflowslib'
724
752
 
725
753
  function main() {
726
754
  try {
755
+ retry_policy(http.default_retry)
756
+
727
757
  http.get('https://visit.dreamland.test/')
728
758
  } catch (err) {
729
759
  return 'Error!'
730
760
  }
731
- retry_policy(http.default_retry)
732
761
  }
733
762
  ```
734
763
 
@@ -743,19 +772,20 @@ import { http, retry_policy } from 'ts2workflows/types/workflowslib'
743
772
 
744
773
  function main() {
745
774
  try {
775
+ retry_policy({
776
+ predicate: http.default_retry_predicate,
777
+ max_retries: 3,
778
+ backoff: {
779
+ initial_delay: 0.5,
780
+ max_delay: 60,
781
+ multiplier: 2,
782
+ },
783
+ })
784
+
746
785
  http.get('https://visit.dreamland.test/')
747
786
  } catch (err) {
748
787
  return 'Error!'
749
788
  }
750
- retry_policy({
751
- predicate: http.default_retry_predicate,
752
- max_retries: 3,
753
- backoff: {
754
- initial_delay: 0.5,
755
- max_delay: 60,
756
- multiplier: 2,
757
- },
758
- })
759
789
  }
760
790
  ```
761
791
 
@@ -904,7 +934,7 @@ function retry_policy(
904
934
  ): void
905
935
  ```
906
936
 
907
- A retry policy can be attached to a `try`-`catch` block be calling `retry_policy` as the next statement after the `try`-`catch`. ts2workflows ignores `retry_policy` everywhere else except after a `try`-`catch`.
937
+ A retry policy can be attached to a `try`-`catch` block by calling `retry_policy` inside the `try` block. ts2workflows ignores `retry_policy` everywhere else.
908
938
 
909
939
  See the section on [retrying errors](#retrying-on-errors).
910
940
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts2workflows",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Transpile Typescript code to GCP Workflows programs",
5
5
  "homepage": "https://github.com/aajanki/ts2workflows",
6
6
  "repository": {
@@ -12,7 +12,7 @@
12
12
  "types": "dist/index.d.ts",
13
13
  "type": "module",
14
14
  "engines": {
15
- "node": ">=18"
15
+ "node": ">=20"
16
16
  },
17
17
  "scripts": {
18
18
  "build": "rimraf dist && npm run build:functionmetadata && tsc",
@@ -20,6 +20,7 @@
20
20
  "lint": "eslint src test scripts",
21
21
  "format": "prettier . --write",
22
22
  "test": "mocha",
23
+ "test-coverage": "nyc mocha",
23
24
  "prepare": "husky && npm run build"
24
25
  },
25
26
  "lint-staged": {
@@ -61,25 +62,26 @@
61
62
  "@eslint/js": "^9.10.0",
62
63
  "@types/chai": "^5.0.1",
63
64
  "@types/mocha": "^10.0.6",
64
- "@types/node": "^18",
65
+ "@types/node": "^20",
65
66
  "@types/ramda": "^0.30.2",
66
67
  "@typescript-eslint/eslint-plugin": "^8.0.0",
67
68
  "@typescript-eslint/parser": "^8.0.0",
68
69
  "chai": "^5.1.1",
69
70
  "eslint": "^9.10.0",
70
71
  "husky": "^9.1.6",
71
- "lint-staged": "^15.2.10",
72
+ "lint-staged": "^16.1.2",
72
73
  "mocha": "^11.1.0",
74
+ "nyc": "^17.1.0",
73
75
  "prettier": "^3.2.5",
74
- "rimraf": "^5.0.10",
75
- "tsx": "^4.10.2",
76
+ "rimraf": "^6.0.1",
77
+ "tsx": "~4.19.4",
76
78
  "typescript-eslint": "^8.0.0"
77
79
  },
78
80
  "dependencies": {
79
81
  "@typescript-eslint/typescript-estree": "^8.0.0",
80
- "commander": "^13.1.0",
81
- "ramda": "^0.30.1",
82
- "typescript": "^5.0.0",
82
+ "commander": "^14.0.0",
83
+ "ramda": "^0.31.3",
84
+ "typescript": "^5.4.0",
83
85
  "yaml": "^2.4.2"
84
86
  }
85
87
  }
@@ -10,6 +10,28 @@ export interface bytes {
10
10
  readonly [__bytes_tag]: 'bytes'
11
11
  }
12
12
 
13
+ // GCP Workflows data types
14
+ export type WorkflowsValue =
15
+ | boolean
16
+ | number
17
+ | string
18
+ | bytes
19
+ | WorkflowsValue[]
20
+ | { [key: string]: WorkflowsValue }
21
+ | null
22
+
23
+ type BooleanNumberStringListOrDict =
24
+ | boolean
25
+ | number
26
+ | string
27
+ | BooleanNumberStringListOrDict[]
28
+ | { [key: string]: BooleanNumberStringListOrDict }
29
+
30
+ type HTTPQuery = Record<
31
+ string,
32
+ string | number | boolean | (string | number | boolean)[]
33
+ >
34
+
13
35
  // GCP Workflows expression helpers
14
36
 
15
37
  export declare function double(x: string | number): number
@@ -19,19 +41,10 @@ export declare function keys(map: Record<string, unknown>): string[]
19
41
  export declare function len(
20
42
  value: unknown[] | Record<string, unknown> | string,
21
43
  ): number
22
- export declare function get_type(
23
- value:
24
- | boolean
25
- | number
26
- | string
27
- | unknown[]
28
- | Record<string, unknown>
29
- | null
30
- | bytes
31
- | undefined,
32
- ): string
44
+ export declare function get_type(value: unknown): string
33
45
 
34
46
  // GCP Workflows standard library functions
47
+ // https://cloud.google.com/workflows/docs/reference/stdlib/overview
35
48
 
36
49
  export declare namespace base64 {
37
50
  function decode(data: bytes, padding?: boolean): string
@@ -39,7 +52,7 @@ export declare namespace base64 {
39
52
  }
40
53
 
41
54
  export declare namespace events {
42
- function await_callback<ResponseType = unknown>(
55
+ function await_callback<ResponseType = WorkflowsValue>(
43
56
  callback: {
44
57
  url: string
45
58
  },
@@ -80,15 +93,12 @@ export declare namespace http {
80
93
  export function default_retry_predicate_non_idempotent(
81
94
  errormap: Record<string, any>,
82
95
  ): boolean
83
- function _delete<ResponseType = unknown>(
96
+ function _delete<ResponseType = WorkflowsValue>(
84
97
  url: string,
85
98
  timeout?: number,
86
- body?: unknown,
99
+ body?: any,
87
100
  headers?: Record<string, string>,
88
- query?: Record<
89
- string,
90
- string | number | boolean | (string | number | boolean)[]
91
- >,
101
+ query?: HTTPQuery,
92
102
  auth?: Record<string, string>,
93
103
  private_service_name?: string,
94
104
  ca_certificate?: string,
@@ -97,14 +107,11 @@ export declare namespace http {
97
107
  code: number
98
108
  headers: Record<string, string>
99
109
  }
100
- export function get<ResponseType = unknown>(
110
+ export function get<ResponseType = WorkflowsValue>(
101
111
  url: string,
102
112
  timeout?: number,
103
113
  headers?: Record<string, string>,
104
- query?: Record<
105
- string,
106
- string | number | boolean | (string | number | boolean)[]
107
- >,
114
+ query?: HTTPQuery,
108
115
  auth?: Record<string, string>,
109
116
  private_service_name?: string,
110
117
  ca_certificate?: string,
@@ -113,10 +120,10 @@ export declare namespace http {
113
120
  code: number
114
121
  headers: Record<string, string>
115
122
  }
116
- export function patch<ResponseType = unknown>(
123
+ export function patch<ResponseType = WorkflowsValue>(
117
124
  url: string,
118
125
  timeout?: number,
119
- body?: unknown,
126
+ body?: any,
120
127
  headers?: Record<string, string>,
121
128
  query?: Record<
122
129
  string,
@@ -130,15 +137,12 @@ export declare namespace http {
130
137
  code: number
131
138
  headers: Record<string, string>
132
139
  }
133
- export function post<ResponseType = unknown>(
140
+ export function post<ResponseType = WorkflowsValue>(
134
141
  url: string,
135
142
  timeout?: number,
136
- body?: unknown,
143
+ body?: any,
137
144
  headers?: Record<string, string>,
138
- query?: Record<
139
- string,
140
- string | number | boolean | (string | number | boolean)[]
141
- >,
145
+ query?: HTTPQuery,
142
146
  auth?: Record<string, string>,
143
147
  private_service_name?: string,
144
148
  ca_certificate?: string,
@@ -147,15 +151,12 @@ export declare namespace http {
147
151
  code: number
148
152
  headers: Record<string, string>
149
153
  }
150
- export function put<ResponseType = unknown>(
154
+ export function put<ResponseType = WorkflowsValue>(
151
155
  url: string,
152
156
  timeout?: number,
153
- body?: unknown,
157
+ body?: any,
154
158
  headers?: Record<string, string>,
155
- query?: Record<
156
- string,
157
- string | number | boolean | (string | number | boolean)[]
158
- >,
159
+ query?: HTTPQuery,
159
160
  auth?: Record<string, string>,
160
161
  private_service_name?: string,
161
162
  ca_certificate?: string,
@@ -164,16 +165,13 @@ export declare namespace http {
164
165
  code: number
165
166
  headers: Record<string, string>
166
167
  }
167
- export function request<ResponseType = unknown>(
168
+ export function request<ResponseType = WorkflowsValue>(
168
169
  method: string,
169
170
  url: string,
170
171
  timeout?: number,
171
- body?: unknown,
172
+ body?: any,
172
173
  headers?: Record<string, string>,
173
- query?: Record<
174
- string,
175
- string | number | boolean | (string | number | boolean)[]
176
- >,
174
+ query?: HTTPQuery,
177
175
  auth?: Record<string, string>,
178
176
  private_service_name?: string,
179
177
  ca_certificate?: string,
@@ -186,16 +184,9 @@ export declare namespace http {
186
184
  }
187
185
 
188
186
  export declare namespace json {
189
- function decode(data: bytes | string): unknown
187
+ function decode(data: bytes | string): WorkflowsValue
190
188
  function encode(
191
- data:
192
- | string
193
- | number
194
- | boolean
195
- | unknown[]
196
- | Record<string, unknown>
197
- | null
198
- | undefined,
189
+ data: unknown,
199
190
  indent?:
200
191
  | boolean
201
192
  | {
@@ -204,14 +195,7 @@ export declare namespace json {
204
195
  },
205
196
  ): bytes
206
197
  function encode_to_string(
207
- data:
208
- | string
209
- | number
210
- | boolean
211
- | unknown[]
212
- | Record<string, unknown>
213
- | null
214
- | undefined,
198
+ data: unknown,
215
199
  indent?:
216
200
  | boolean
217
201
  | {
@@ -228,10 +212,10 @@ export declare namespace list {
228
212
 
229
213
  export declare namespace map {
230
214
  function _delete<T>(map: Record<string, T>, key: string): Record<string, T>
231
- export function get<T, K extends string | string[]>(
232
- map: Record<string, T>,
233
- keys: K,
234
- ): K extends string ? T | null : unknown
215
+ // map.get() with a string key, returns a property value or null
216
+ export function get<T>(map: Record<string, T>, keys: string): T | null
217
+ // map.get() with string[] key or non-object lookup, the return type is unknown
218
+ export function get(map: any, keys: string | string[]): WorkflowsValue
235
219
  export function merge<T, U>(
236
220
  first: Record<string, T>,
237
221
  second: Record<string, U>,
@@ -250,23 +234,23 @@ export declare namespace math {
250
234
  }
251
235
 
252
236
  export declare namespace retry {
253
- function always(exception: unknown): void
237
+ function always(exception: any): void
254
238
  const default_backoff: {
255
239
  initial_delay: number
256
240
  max_delay: number
257
241
  multiplier: number
258
242
  }
259
- function never(exception: unknown): void
243
+ function never(exception: any): void
260
244
  }
261
245
 
262
246
  export declare namespace sys {
263
247
  function get_env(name: string): string | null
264
248
  function get_env(name: string, default_value: string): string
265
249
  function log(
266
- data?: number | boolean | string | unknown[] | object,
250
+ data?: BooleanNumberStringListOrDict,
267
251
  severity?: string,
268
- text?: number | boolean | string | unknown[] | object,
269
- json?: object,
252
+ text?: BooleanNumberStringListOrDict,
253
+ json?: Record<string, any>,
270
254
  timeout?: number,
271
255
  ): void
272
256
  function now(): number
@@ -456,9 +440,9 @@ export declare namespace googleapis {
456
440
  interface GoogleLongrunningOperation {
457
441
  done: boolean
458
442
  error?: Status
459
- metadata?: Record<string, unknown>
443
+ metadata?: Record<string, any>
460
444
  name: string
461
- response: Record<string, unknown>
445
+ response: Record<string, any>
462
446
  }
463
447
  interface GoogleLongrunningListOperationsResponse {
464
448
  nextPageToken?: string
@@ -476,7 +460,7 @@ export declare namespace googleapis {
476
460
  displayName: string
477
461
  labels: Record<string, string>
478
462
  locationId: string
479
- metadata?: Record<string, unknown>
463
+ metadata?: Record<string, any>
480
464
  name: string
481
465
  }
482
466
  interface ListCollectionIdsRequest {
@@ -538,7 +522,7 @@ export declare namespace googleapis {
538
522
  }
539
523
  interface Status {
540
524
  code: number
541
- details: Record<string, unknown>[]
525
+ details: Record<string, any>[]
542
526
  message: string
543
527
  }
544
528
  interface StructuredQuery {
@@ -751,5 +735,5 @@ export declare function retry_policy(
751
735
 
752
736
  export declare function call_step<T, A extends any[]>(
753
737
  func: (...args: A) => T,
754
- arguments: Record<string, unknown>,
738
+ arguments: Record<string, any>,
755
739
  ): T
@@ -1,20 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,214 +0,0 @@
1
- export class WorkflowValidationError extends Error {
2
- issues;
3
- constructor(issues) {
4
- const issueTypes = Array.from(new Set(issues.map((x) => x.type))).join(', ');
5
- super(`Workflow validation error: ${issueTypes}`);
6
- this.name = this.constructor.name;
7
- this.issues = issues;
8
- }
9
- }
10
- const validators = new Map([
11
- ['invalidWorkflowName', validateWorkflowNames],
12
- ['duplicatedStepName', validateNoDuplicateStepNames],
13
- ['duplicatedSubworkflowName', validateNoDuplicateSubworkflowNames],
14
- ['missingJumpTarget', validateJumpTargets],
15
- ['wrongNumberOfCallArguments', validateSubworkflowArguments],
16
- ]);
17
- /**
18
- * Execute all syntax validators on a WorkflowApp app.
19
- *
20
- * Throws a WorkflowValidationError if there are errors.
21
- */
22
- export function validate(app, disabled = []) {
23
- const selectedValidators = Array.from(validators.entries()).filter(([name]) => {
24
- return !disabled.includes(name);
25
- });
26
- const issues = [];
27
- for (const [, validator] of selectedValidators) {
28
- issues.push(...validator(app));
29
- }
30
- if (issues.length > 0) {
31
- throw new WorkflowValidationError(issues);
32
- }
33
- }
34
- /**
35
- * Returns all validator names.
36
- */
37
- export function validatorNames() {
38
- return Array.from(validators.keys());
39
- }
40
- /**
41
- * Check that workflow does not contain duplicated step names.
42
- */
43
- function validateNoDuplicateStepNames(app) {
44
- function collectDuplicateStepName(wf) {
45
- const seen = new Set();
46
- const duplicates = new Set();
47
- for (const { name } of wf.iterateStepsDepthFirst()) {
48
- if (seen.has(name)) {
49
- duplicates.add(name);
50
- }
51
- else {
52
- seen.add(name);
53
- }
54
- }
55
- return Array.from(duplicates.values());
56
- }
57
- const issues = [];
58
- for (const subworkflow of app.subworkflows) {
59
- const duplicatesInSub = collectDuplicateStepName(subworkflow);
60
- if (duplicatesInSub.length > 0) {
61
- const message = `Duplicated step names in the subworkflow ${subworkflow.name}: ${duplicatesInSub.join(', ')}`;
62
- issues.push({ type: 'duplicatedStepName', message: message });
63
- }
64
- }
65
- return issues;
66
- }
67
- /**
68
- * Check that there are no two subworkflows sharing a name.
69
- */
70
- function validateNoDuplicateSubworkflowNames(app) {
71
- const seen = new Set();
72
- const duplicates = new Set();
73
- const names = app.subworkflows.map((w) => w.name);
74
- for (const name of names) {
75
- if (seen.has(name)) {
76
- duplicates.add(name);
77
- }
78
- else {
79
- seen.add(name);
80
- }
81
- }
82
- if (duplicates.size > 0) {
83
- const dup = Array.from(duplicates);
84
- return [
85
- {
86
- type: 'duplicatedSubworkflowName',
87
- message: `Duplicated subworkflow names: ${dup.join(', ')}`,
88
- },
89
- ];
90
- }
91
- else {
92
- return [];
93
- }
94
- }
95
- /**
96
- * Check that the subworkflow names are valid.
97
- */
98
- function validateWorkflowNames(app) {
99
- const issues = [];
100
- const names = app.subworkflows.map((w) => w.name);
101
- if (names.some((x) => x === '')) {
102
- issues.push({
103
- type: 'invalidWorkflowName',
104
- message: 'Subworkflow must have a non-empty name',
105
- });
106
- }
107
- return issues;
108
- }
109
- /**
110
- * Check that there are no jumps (calls, nexts) to non-existing steps or subworkflows
111
- */
112
- function validateJumpTargets(app) {
113
- const subworkflowNames = app.subworkflows.map((w) => w.name);
114
- return app.subworkflows.flatMap((subworkflow) => {
115
- return validateJumpTargetsInWorkflow(subworkflow, subworkflowNames);
116
- });
117
- }
118
- function validateJumpTargetsInWorkflow(workflow, subworkflowNames) {
119
- const issues = [];
120
- const stepNames = [];
121
- for (const { name } of workflow.iterateStepsDepthFirst()) {
122
- stepNames.push(name);
123
- }
124
- function validCallTarget(name) {
125
- return (isRuntimeFunction(name) ||
126
- stepNames.includes(name) ||
127
- subworkflowNames.includes(name));
128
- }
129
- function validNextTarget(name) {
130
- return stepNames.includes(name) || name === 'end'; // accepts "next: end"
131
- }
132
- for (const { name, step } of workflow.iterateStepsDepthFirst()) {
133
- if (step.tag === 'call') {
134
- if (!validCallTarget(step.call))
135
- issues.push({
136
- type: 'missingJumpTarget',
137
- message: `Call target "${step.call}" in step "${name}" not found`,
138
- });
139
- }
140
- else if (step.tag === 'switch') {
141
- if (step.next && !validNextTarget(step.next)) {
142
- issues.push({
143
- type: 'missingJumpTarget',
144
- message: `Next target "${step.next}" in step "${name}" not found`,
145
- });
146
- }
147
- step.conditions.forEach((cond) => {
148
- if (cond.next && !validNextTarget(cond.next)) {
149
- issues.push({
150
- type: 'missingJumpTarget',
151
- message: `Next target "${cond.next}" in step "${name}" not found`,
152
- });
153
- }
154
- });
155
- }
156
- }
157
- return issues;
158
- }
159
- /**
160
- * Check that call steps provide a correct number of argument in subworkflow calls
161
- */
162
- function validateSubworkflowArguments(app) {
163
- const issues = [];
164
- const paramsBySubworkflow = new Map(app.subworkflows.map((x) => [
165
- x.name,
166
- {
167
- required: x.params
168
- ?.filter((x) => typeof x.default === 'undefined')
169
- .map((x) => x.name) ?? [],
170
- optional: x.params
171
- ?.filter((x) => typeof x.default !== 'undefined')
172
- .map((x) => x.name) ?? [],
173
- },
174
- ]));
175
- app.subworkflows.forEach((subw) => {
176
- issues.push(...findIssuesInCallArguments(subw, paramsBySubworkflow));
177
- });
178
- return issues;
179
- }
180
- function findIssuesInCallArguments(wf, argumentBySubworkflowName) {
181
- const issues = [];
182
- for (const { name, step } of wf.iterateStepsDepthFirst()) {
183
- if (step.tag === 'call' && argumentBySubworkflowName.has(step.call)) {
184
- const requiredArgs = argumentBySubworkflowName.get(step.call)?.required ?? [];
185
- const optionalArgs = argumentBySubworkflowName.get(step.call)?.optional ?? [];
186
- const requiredAndOptionalArgs = requiredArgs.concat(optionalArgs);
187
- const providedArgs = Object.keys(step.args ?? {});
188
- const requiredButNotProvided = requiredArgs.filter((x) => !providedArgs.includes(x));
189
- const providedButNotRequired = providedArgs.filter((x) => !requiredAndOptionalArgs.includes(x));
190
- if (requiredButNotProvided.length > 0) {
191
- issues.push({
192
- type: 'wrongNumberOfCallArguments',
193
- message: `Required parameters not provided on call step "${name}": ${JSON.stringify(requiredButNotProvided)}`,
194
- });
195
- }
196
- if (providedButNotRequired.length > 0) {
197
- issues.push({
198
- type: 'wrongNumberOfCallArguments',
199
- message: `Extra arguments provided on call step "${name}": ${JSON.stringify(providedButNotRequired)}`,
200
- });
201
- }
202
- }
203
- }
204
- return issues;
205
- }
206
- /**
207
- * Returns true if functionName is a standard library or connector function.
208
- *
209
- * Current version does a minimalistic checking and assumes that a name is a
210
- * standard library function if it contains a dot.
211
- */
212
- function isRuntimeFunction(functionName) {
213
- return functionName.includes('.');
214
- }