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.
Files changed (50) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +82 -0
  3. package/dist/ast/expressions.d.ts +57 -0
  4. package/dist/ast/expressions.d.ts.map +1 -0
  5. package/dist/ast/expressions.js +300 -0
  6. package/dist/ast/stepnames.d.ts +9 -0
  7. package/dist/ast/stepnames.d.ts.map +1 -0
  8. package/dist/ast/stepnames.js +268 -0
  9. package/dist/ast/steps.d.ts +176 -0
  10. package/dist/ast/steps.d.ts.map +1 -0
  11. package/dist/ast/steps.js +534 -0
  12. package/dist/ast/validation.d.ts +20 -0
  13. package/dist/ast/validation.d.ts.map +1 -0
  14. package/dist/ast/validation.js +214 -0
  15. package/dist/ast/workflows.d.ts +28 -0
  16. package/dist/ast/workflows.d.ts.map +1 -0
  17. package/dist/ast/workflows.js +74 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +114 -0
  21. package/dist/errors.d.ts +18 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +12 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +2 -0
  27. package/dist/transpiler/asserts.d.ts +7 -0
  28. package/dist/transpiler/asserts.d.ts.map +1 -0
  29. package/dist/transpiler/asserts.js +11 -0
  30. package/dist/transpiler/expressions.d.ts +6 -0
  31. package/dist/transpiler/expressions.d.ts.map +1 -0
  32. package/dist/transpiler/expressions.js +223 -0
  33. package/dist/transpiler/generated/functionMetadata.d.ts +2 -0
  34. package/dist/transpiler/generated/functionMetadata.d.ts.map +1 -0
  35. package/dist/transpiler/generated/functionMetadata.js +324 -0
  36. package/dist/transpiler/index.d.ts +2 -0
  37. package/dist/transpiler/index.d.ts.map +1 -0
  38. package/dist/transpiler/index.js +74 -0
  39. package/dist/transpiler/statements.d.ts +7 -0
  40. package/dist/transpiler/statements.d.ts.map +1 -0
  41. package/dist/transpiler/statements.js +533 -0
  42. package/dist/transpiler/transformations.d.ts +28 -0
  43. package/dist/transpiler/transformations.d.ts.map +1 -0
  44. package/dist/transpiler/transformations.js +461 -0
  45. package/dist/utils.d.ts +2 -0
  46. package/dist/utils.d.ts.map +1 -0
  47. package/dist/utils.js +3 -0
  48. package/language_reference.md +771 -0
  49. package/package.json +62 -0
  50. package/types/workflowslib.d.ts +714 -0
@@ -0,0 +1,771 @@
1
+ # Language reference
2
+
3
+ ts2workflow converts Typescript source code to GCP Workflows YAML syntax. Only a subset of Typescript language features are supported. This page documents supported Typescript features and shows examples of the generted Workflows YAML output.
4
+
5
+ Functions provided by a Javascript runtime (`console.log`, `setInterval`, etc) are not available.
6
+
7
+ Type annotations are allowed. Type checking is done by the compiler but the types dont't affect the generated Workflows code.
8
+
9
+ Semicolon can be used as optional statement delimitter.
10
+
11
+ ⚠️ Semantics of certain operations are different from Typescript semantics. These differences are highlighted with the warning icon ⚠️ on this documentation.
12
+
13
+ ## Data types
14
+
15
+ - `number`: Integer (64 bit, signed) or double (64 bit, signed floating point number)
16
+ - `string`: `"my beautiful string"`, both single or double quotes are accepted
17
+ - `boolean`: `true`/`false`
18
+ - `bytes`
19
+ - `null`
20
+ - Array: `[1, 2, 3]`
21
+ - Map: `{temperature: -12, unit: "Celsius"}`
22
+
23
+ ### Array type
24
+
25
+ ⚠️ Arrays are not objects. In particular, methods like `array.map()` and `array.concat()` are not available.
26
+
27
+ ⚠️ Accessing out-of-bounds index will cause an IndexError at runtime unlike in Typescript where out-of-bounds access would return `undefined`.
28
+
29
+ ### Map type
30
+
31
+ Map keys can be identifiers or strings: `{temperature: -12}` or `{"temperature": -12}`. Trailing commas are allowed.
32
+
33
+ ⚠️ Trying to access a non-existing member of an object will throw a KeyError at runtime, unlike in Typescript where it would return `undefined`.
34
+
35
+ ### Bytes type
36
+
37
+ It is not possible to construct a bytes object expect by calling a function that returns bytes (e.g. base64.decode). It is not possible to do anything else with a bytes object than to assign it to a variable and to pass it one of the functions that take bytes type as input variable (e.g. base64.encode).
38
+
39
+ ### null type
40
+
41
+ In addition to the literal `null`, the Typescript `undefined` value is also treated as `null` in Workflows YAML.
42
+
43
+ ## Expressions
44
+
45
+ Most Typescript expressions work as expected.
46
+
47
+ Examples:
48
+
49
+ ```javascript
50
+ a + b
51
+
52
+ args.users[3].id
53
+
54
+ name === 'Bean'
55
+
56
+ sys.get_env('GOOGLE_CLOUD_PROJECT_ID')
57
+ ```
58
+
59
+ Operators:
60
+
61
+ | Operator | Description |
62
+ | ------------ | -------------------------------------------- |
63
+ | + | arithmetic addition and string concatenation |
64
+ | - | arithmetic subtraction or unary negation |
65
+ | \* | multiplication |
66
+ | / | float division |
67
+ | % | remainder division |
68
+ | ==, === | equal to (both mean strict equality) |
69
+ | !=, !== | not equal to (both mean strict equality) |
70
+ | <, >, <=, >= | inequality comparisons |
71
+ | &&, \|\|, ! | logical operators |
72
+ | in | check if a property is present in an object |
73
+ | ?? | nullish coalescing |
74
+
75
+ The [precendence order of operators](https://cloud.google.com/workflows/docs/reference/syntax/datatypes#order-operations) is the same as in GCP Workflows.
76
+
77
+ See [expression in GCP Workflows](https://cloud.google.com/workflows/docs/reference/syntax/expressions) for more information.
78
+
79
+ ## Template literals
80
+
81
+ Template literals are strings that support string interpolation. For example, `Hello ${name}`.
82
+
83
+ ⚠️ Interpolated values can (only) be numbers, strings or booleans. Other types will throw a TypeError at runtime.
84
+
85
+ ## Subworkflow definitions
86
+
87
+ Typescript `function`s are converted to subworkflow definitions.
88
+
89
+ The program code must be written inside workflow blocks. Only `function` and `import` declarations are allowed on the top level of a source code file. Functions can only be defined at the top level of a source file, not inside functions or in other nested scopes.
90
+
91
+ The workflow execution starts from the subworkflow called "main".
92
+
93
+ ```typescript
94
+ function main(): void {
95
+ const a = 1
96
+ }
97
+
98
+ function anotherWorkflow(): number {
99
+ const b = 10
100
+ return 2 * b
101
+ }
102
+ ```
103
+
104
+ Workflows can have parameters:
105
+
106
+ ```typescript
107
+ function multiply(firstFactor: number, secondFactor: number): number {
108
+ return firstFactor * secondFactor
109
+ }
110
+ ```
111
+
112
+ Parameters can be optional and have a default value that is used if a value is not provided in a subworkflow call:
113
+
114
+ ```typescript
115
+ function log(x, base = 10) {
116
+ return 'Should compute the logarithm of x'
117
+ }
118
+ ```
119
+
120
+ ### Returning value from a subworkflow
121
+
122
+ ```javascript
123
+ return 'Success'
124
+ ```
125
+
126
+ The returned value can be an expression:
127
+
128
+ ```javascript
129
+ return firstFactor * secondFactor
130
+ ```
131
+
132
+ ## Calling functions and subworkflows
133
+
134
+ The statement
135
+
136
+ ```typescript
137
+ const projectId = sys.get_env('GOOGLE_CLOUD_PROJECT_ID')
138
+ ```
139
+
140
+ is converted to an [assign step](https://cloud.google.com/workflows/docs/reference/syntax/variables#assign-step):
141
+
142
+ ```yaml
143
+ - assign1:
144
+ assign:
145
+ - projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
146
+ ```
147
+
148
+ This syntax can be used to call [standard library functions](https://cloud.google.com/workflows/docs/reference/stdlib/overview), subworkflows or connectors.
149
+
150
+ GCP Workflows language has two ways of calling functions and subworkflows: as expression in an [assign step](https://cloud.google.com/workflows/docs/reference/syntax/variables#assign-step) or as [call step](https://cloud.google.com/workflows/docs/reference/syntax/calls). They can mostly be used interchangeably. However, [blocking calls](https://cloud.google.com/workflows/docs/reference/syntax/expressions#blocking-calls) must be made as call steps. The transpiler tries to automatically output a call step when necessary.
151
+
152
+ It is also possible to force a function to be called as call step. This might be useful, if the transpiler fails to output call step when it should, or if you want to use named parameters. For example, the following Typescript program
153
+
154
+ ```typescript
155
+ import { call_step, sys } from 'ts2workflows/types/workflowslib'
156
+
157
+ function main() {
158
+ call_step(sys.log, {
159
+ json: { message: 'Hello log' },
160
+ severity: 'INFO',
161
+ })
162
+ }
163
+ ```
164
+
165
+ is converted to call step:
166
+
167
+ ```yaml
168
+ main:
169
+ steps:
170
+ - call1:
171
+ call: sys.log
172
+ args:
173
+ json:
174
+ message: Hello log
175
+ severity: INFO
176
+ ```
177
+
178
+ Some Workflows standard library functions have names that are reserved keywords in Typescript. Those functions must be called with alternative names in ts2workflows source code:
179
+
180
+ - To generate a call to `default()` in Workflows code, use the nullish coalescing operator `??`.
181
+ - To generete a call to `if()` in Workflows code, use the ternary operator `a ? b : c`.
182
+
183
+ ## Assignments
184
+
185
+ The statement
186
+
187
+ ```typescript
188
+ const name = 'Bean'
189
+ ```
190
+
191
+ is converted to an [assign step](https://cloud.google.com/workflows/docs/reference/syntax/variables#assign-step):
192
+
193
+ ```yaml
194
+ - assign1:
195
+ assign:
196
+ - name: Bean
197
+ ```
198
+
199
+ Compound assignments are also supported:
200
+
201
+ ```typescript
202
+ total += 1
203
+ ```
204
+
205
+ is converted to
206
+
207
+ ```yaml
208
+ - assign1:
209
+ assign:
210
+ - total: ${total + 1}
211
+ ```
212
+
213
+ ## Conditional statements
214
+
215
+ The statement
216
+
217
+ ```typescript
218
+ if (hour < 12) {
219
+ part_of_the_day = 'morning'
220
+ } else if (hour < 17) {
221
+ part_of_the_day = 'afternoon'
222
+ } else if (hour < 21) {
223
+ part_of_the_day = 'evening'
224
+ } else {
225
+ part_of_the_day = 'night'
226
+ }
227
+ ```
228
+
229
+ is converted to a [switch step](https://cloud.google.com/workflows/docs/reference/syntax/conditions)
230
+
231
+ ```yaml
232
+ - switch1:
233
+ switch:
234
+ - condition: ${hour < 12}
235
+ steps:
236
+ - assign1:
237
+ assign:
238
+ - part_of_the_day: morning
239
+ - condition: ${hour < 17}
240
+ steps:
241
+ - assign2:
242
+ assign:
243
+ - part_of_the_day: afternoon
244
+ - condition: ${hour < 21}
245
+ steps:
246
+ - assign3:
247
+ assign:
248
+ - part_of_the_day: evening
249
+ - condition: true
250
+ steps:
251
+ - assign4:
252
+ assign:
253
+ - part_of_the_day: night
254
+ ```
255
+
256
+ ## Switch statements
257
+
258
+ Typescript switch statements are transpiled to chains of conditions. For example, this statement
259
+
260
+ ```typescript
261
+ let b
262
+ switch (a) {
263
+ case 1:
264
+ b = 'first'
265
+ break
266
+
267
+ case 2:
268
+ b = 'second'
269
+ break
270
+
271
+ default:
272
+ b = 'other'
273
+ }
274
+
275
+ return b
276
+ ```
277
+
278
+ is converted to
279
+
280
+ ```yaml
281
+ steps:
282
+ - assign1:
283
+ assign:
284
+ - b: null
285
+ - switch1:
286
+ switch:
287
+ - condition: ${a == 1}
288
+ next: assign2
289
+ - condition: ${a == 2}
290
+ next: assign3
291
+ - condition: true
292
+ next: assign4
293
+ - assign2:
294
+ assign:
295
+ - b: first
296
+ - next1:
297
+ next: return1
298
+ - assign3:
299
+ assign:
300
+ - b: second
301
+ - next2:
302
+ next: return1
303
+ - assign4:
304
+ assign:
305
+ - b: other
306
+ - return1:
307
+ return: ${b}
308
+ ```
309
+
310
+ ## Conditional (ternary) operator
311
+
312
+ The expression
313
+
314
+ ```javascript
315
+ x > 0 ? 'positive' : 'not positive'
316
+ ```
317
+
318
+ is converted to an [if() expression](https://cloud.google.com/workflows/docs/reference/stdlib/expression-helpers#conditional_functions):
319
+
320
+ ```yaml
321
+ ${if(x > 0, "positive", "not positive")}
322
+ ```
323
+
324
+ ⚠️ Note that Workflows always evaluates both expression branches unlike Typescript which evaluates only the branch that gets executed.
325
+
326
+ ## Nullish coalescing operator
327
+
328
+ The expression
329
+
330
+ ```javascript
331
+ x ?? 'default value'
332
+ ```
333
+
334
+ is converted to an [default() expression](https://cloud.google.com/workflows/docs/reference/stdlib/expression-helpers#conditional_functions):
335
+
336
+ ```yaml
337
+ ${default(x, "default value")}
338
+ ```
339
+
340
+ ⚠️ Note that Workflows always evaluates the right-hand side expression unlike Typescript which evaluates the right-hand side only if the left-hand side is `null` or `undefined`.
341
+
342
+ ## Loops
343
+
344
+ The fragment
345
+
346
+ ```typescript
347
+ let total = 0
348
+ for (const i of [1, 2, 3]) {
349
+ total += i
350
+ }
351
+ ```
352
+
353
+ is converted to the following [for loop statement](https://cloud.google.com/workflows/docs/reference/syntax/iteration)
354
+
355
+ ```yaml
356
+ steps:
357
+ - assign1:
358
+ assign:
359
+ - total: 0
360
+ - for1:
361
+ for:
362
+ value: i
363
+ in:
364
+ - 1
365
+ - 2
366
+ - 3
367
+ steps:
368
+ - assign2:
369
+ assign:
370
+ - total: ${total + i}
371
+ ```
372
+
373
+ `while` and `do...while` loops are also supported:
374
+
375
+ ```typescript
376
+ const total = 0
377
+ let i = 5
378
+
379
+ while (i > 0) {
380
+ total += i
381
+ i -= 1
382
+ }
383
+
384
+ let k = 5
385
+ do {
386
+ total += k
387
+ k -= 1
388
+ } while (k > 0)
389
+ ```
390
+
391
+ `for...in` loops are not supported.
392
+
393
+ ### Break and continue in loops
394
+
395
+ Breaking out of a loop:
396
+
397
+ ```typescript
398
+ let total = 0
399
+ for (const i of [1, 2, 3, 4]) {
400
+ if (total > 5) {
401
+ break
402
+ }
403
+
404
+ total += i
405
+ }
406
+ ```
407
+
408
+ Continuing from the next iteration of a loop:
409
+
410
+ ```javascript
411
+ let total = 0
412
+ for (i of [1, 2, 3, 4]) {
413
+ if (i % 2 == 0) {
414
+ continue
415
+ }
416
+
417
+ total += i
418
+ }
419
+ ```
420
+
421
+ ## Parallel branches
422
+
423
+ The special function `parallel` can be used to execute several code branches in parallel. The code blocks to be executed in parallel are given as an array of `() => void` functions. For example, the following code
424
+
425
+ ```javascript
426
+ parallel([
427
+ () => {
428
+ http.post('https://forum.dreamland.test/register/bean')
429
+ },
430
+ () => {
431
+ http.post('https://forum.dreamland.test/register/elfo')
432
+ },
433
+ () => {
434
+ http.post('https://forum.dreamland.test/register/luci')
435
+ },
436
+ ])
437
+ ```
438
+
439
+ is converted to [parallel steps](https://cloud.google.com/workflows/docs/reference/syntax/parallel-steps)
440
+
441
+ ```yaml
442
+ - parallel1:
443
+ parallel:
444
+ branches:
445
+ - branch1:
446
+ steps:
447
+ - call1:
448
+ call: http.post
449
+ args:
450
+ url: https://forum.dreamland.test/register/bean
451
+ - branch2:
452
+ steps:
453
+ - call2:
454
+ call: http.post
455
+ args:
456
+ url: https://forum.dreamland.test/register/elfo
457
+ - branch3:
458
+ steps:
459
+ - call3:
460
+ call: http.post
461
+ args:
462
+ url: https://forum.dreamland.test/register/luci
463
+ ```
464
+
465
+ The branches can also be subworkflow names:
466
+
467
+ ```javascript
468
+ parallel([my_subworkflow1, my_subworkflow2, my_subworklfow3])
469
+ ```
470
+
471
+ An optional second parameter is an object that can define shared variables and concurrency limits:
472
+
473
+ ```javascript
474
+ let numPosts = 0
475
+
476
+ parallel(
477
+ [
478
+ () => {
479
+ n = http.get('https://forum.dreamland.test/numPosts/bean')
480
+ numPosts = numPosts + n
481
+ },
482
+ () => {
483
+ n = http.get('https://forum.dreamland.test/numPosts/elfo')
484
+ numPosts = numPosts + n
485
+ },
486
+ ],
487
+ {
488
+ shared: ['numPosts'],
489
+ concurrency_limit: 2,
490
+ },
491
+ )
492
+ ```
493
+
494
+ ## Parallel iteration
495
+
496
+ The following form of `parallel` can be called to execute iterations in parallel. The only statement in the function body must be a `for` loop.
497
+
498
+ ```typescript
499
+ parallel(() => {
500
+ for (const username of ['bean', 'elfo', 'luci']) {
501
+ http.post('https://forum.dreamland.test/register/' + username)
502
+ }
503
+ })
504
+ ```
505
+
506
+ is converted to [parallel iteration](https://cloud.google.com/workflows/docs/reference/syntax/parallel-steps#parallel-iteration):
507
+
508
+ ```yaml
509
+ - parallel1:
510
+ parallel:
511
+ for:
512
+ value: username
513
+ in:
514
+ - bean
515
+ - elfo
516
+ - luci
517
+ steps:
518
+ - call1:
519
+ call: http.post
520
+ args:
521
+ url: ${"https://forum.dreamland.test/register/" + username}
522
+ ```
523
+
524
+ The shared variables and concurrency limits can be set with the following syntax:
525
+
526
+ ```typescript
527
+ let total = 0
528
+
529
+ parallel(
530
+ () => {
531
+ for (const i of [1, 2, 3, 4]) {
532
+ total += i
533
+ }
534
+ },
535
+ {
536
+ shared: ['total'],
537
+ concurrency_limit: 2,
538
+ },
539
+ )
540
+ ```
541
+
542
+ ## Try/catch statements
543
+
544
+ The statement
545
+
546
+ ```javascript
547
+ try {
548
+ http.get('https://visit.dreamland.test/')
549
+ } catch (err) {
550
+ return 'Error!'
551
+ }
552
+ ```
553
+
554
+ is compiled to the following [try/except structure](https://cloud.google.com/workflows/docs/reference/syntax/catching-errors)
555
+
556
+ ```yaml
557
+ - try1:
558
+ try:
559
+ steps:
560
+ - call1:
561
+ call: http.get
562
+ args:
563
+ url: https://visit.dreamland.test/
564
+ except:
565
+ as: err
566
+ steps:
567
+ - return1:
568
+ return: Error!
569
+ ```
570
+
571
+ The error variable and other variables created inside the catch block are accessible only in that block's scope (similar to [the variable scoping in Workflows](https://cloud.google.com/workflows/docs/reference/syntax/catching-errors#variable-scope)).
572
+
573
+ ## Retrying on errors
574
+
575
+ 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` function. It must be called immediately after a try-catch block. A call to the `retry_policy` is ignored elsewhere.
576
+
577
+ The `retry_policy` function must be called with parameters defining a retry policy. It can be either a policy provided by GCP Workflows or a custom retry policy. See the GCP documentation for the [required parameters for the two policy types](https://cloud.google.com/workflows/docs/reference/syntax/retrying#try-retry).
578
+
579
+ A sample with a GCP-provided retry policy:
580
+
581
+ ```javascript
582
+ import { http, retry_policy } from 'ts2workflows/types/workflowslib'
583
+
584
+ function main() {
585
+ try {
586
+ http.get('https://visit.dreamland.test/')
587
+ } catch (err) {
588
+ return 'Error!'
589
+ }
590
+ retry_policy({ policy: http.default_retry })
591
+ }
592
+ ```
593
+
594
+ A sample with a custom retry policy:
595
+
596
+ ```javascript
597
+ import { http, retry_policy } from 'ts2workflows/types/workflowslib'
598
+
599
+ function main() {
600
+ try {
601
+ http.get('https://visit.dreamland.test/')
602
+ } catch (err) {
603
+ return 'Error!'
604
+ }
605
+ retry_policy({
606
+ predicate: http.default_retry_predicate,
607
+ max_retries: 3,
608
+ backoff: {
609
+ initial_delay: 0.5,
610
+ max_delay: 60,
611
+ multiplier: 2,
612
+ },
613
+ })
614
+ }
615
+ ```
616
+
617
+ The above is compiled to the following [try/except structure](https://cloud.google.com/workflows/docs/reference/syntax/catching-errors)
618
+
619
+ ```yaml
620
+ main:
621
+ steps:
622
+ - try1:
623
+ try:
624
+ steps:
625
+ - call1:
626
+ call: http.get
627
+ args:
628
+ url: https://visit.dreamland.test/
629
+ retry:
630
+ predicate: ${http.default_retry_predicate}
631
+ max_retries: 3
632
+ backoff:
633
+ initial_delay: 0.5
634
+ max_delay: 60
635
+ multiplier: 2
636
+ except:
637
+ as: err
638
+ steps:
639
+ - return1:
640
+ return: Error!
641
+ ```
642
+
643
+ ## Throwing errors
644
+
645
+ The statement
646
+
647
+ ```javascript
648
+ throw 'Error!'
649
+ ```
650
+
651
+ is compiled to the following [raise block](https://cloud.google.com/workflows/docs/reference/syntax/raising-errors)
652
+
653
+ ```yaml
654
+ - raise1:
655
+ raise: 'Error!'
656
+ ```
657
+
658
+ The error can be a string, a map or an expression that evaluates to string or map.
659
+
660
+ Thrown errors can be handled by a try statement.
661
+
662
+ ## Labeled steps
663
+
664
+ The transpiler labels output steps with the step type and sequential numbering by default: e.g. `assign1`, `assign2`, etc. The automatic labels can be overridden by using Typescript labeled statements.
665
+
666
+ ```typescript
667
+ setName: const name = 'Bean'
668
+ ```
669
+
670
+ is converted to a step with the label `setName`:
671
+
672
+ ```yaml
673
+ - setName:
674
+ assign:
675
+ - name: Bean
676
+ ```
677
+
678
+ ## Type annotations for standard library functions
679
+
680
+ Type annotations for GCP Workflows standard library functions and expression helpers are provided by importing "ts2workflows/types/workflowslib".
681
+
682
+ ```typescript
683
+ import { sys } from 'ts2workflows/types/workflowslib'
684
+
685
+ function read_from_env() {
686
+ return sys.get_env('GOOGLE_CLOUD_PROJECT_ID')
687
+ }
688
+ ```
689
+
690
+ At the moment, type annotations are provided for some [connectors](https://cloud.google.com/workflows/docs/reference/googleapis) but not for all of them.
691
+
692
+ ## Special run-time functions
693
+
694
+ ts2workflows provides some special functions for implementing features that are not directly supported by Typescript language features. The type annotations for these functions can be imported from ts2workflows/types/workflowslib:
695
+
696
+ ```typescript
697
+ import {
698
+ call_step,
699
+ parallel,
700
+ retry_policy,
701
+ } from 'ts2workflows/types/workflowslib'
702
+ ```
703
+
704
+ ### call_step
705
+
706
+ ```typescript
707
+ function call_step(func: Function, args: Record<string, unknown>): unknown
708
+ ```
709
+
710
+ The `call_step` function outputs a [call step](https://cloud.google.com/workflows/docs/reference/syntax/calls).
711
+
712
+ ### parallel
713
+
714
+ ```typescript
715
+ function parallel(
716
+ branches: (() => void)[] | (() => void),
717
+ options?: {
718
+ shared?: string[]
719
+ concurrency_limit?: number
720
+ exception_policy?: string
721
+ },
722
+ ): void
723
+ ```
724
+
725
+ The `parallel` function executes code blocks in parallel (using [parallel step](https://cloud.google.com/workflows/docs/reference/syntax/parallel-steps)). See the previous sections covering parallel branches and iteration.
726
+
727
+ ### retry_policy
728
+
729
+ ```typescript
730
+ function retry_policy(
731
+ params:
732
+ | {
733
+ policy: (exception: unknown) => void
734
+ }
735
+ | {
736
+ predicate: (exception: unknown) => boolean
737
+ max_retries: number
738
+ backoff: {
739
+ initial_delay: number
740
+ max_delay: number
741
+ multiplier: number
742
+ }
743
+ },
744
+ ): void
745
+ ```
746
+
747
+ The `retry_policy` function can called right after a `try`-`catch` block to specify a retry policy. See the section on retrying.
748
+
749
+ ## Source code comments
750
+
751
+ In-line comments start with `//`. The rest of the line starting from `//` is considered a comment. Multiline comments are defined with the `/* */` syntax.
752
+
753
+ Example:
754
+
755
+ ```typescript
756
+ const var1 = 1 // This is a comment
757
+ ```
758
+
759
+ ## Unsupported Typescript features
760
+
761
+ ts2workflows supports only a subset of all Typescript language features. Some examples that are not (yet) supported by ts2workflows:
762
+
763
+ - Functions provided by a Javascript runtime (`console.log`, `setInterval`, etc) are not available. Only the [GCP Workflows standard library functions](https://cloud.google.com/workflows/docs/reference/stdlib/overview) and [connectors](https://cloud.google.com/workflows/docs/reference/googleapis) are available.
764
+ - Classes (`class`) are not supported
765
+ - Arrays and maps are not objects. In particular, arrays don't have methods such as `array.push()`, `array.map()`, etc.
766
+ - Functions (subworkflows) are not first-class objects. Functions can not be assigned to a variable or passed to other functions
767
+ - Update expressions (`x++` and similar) are not supported
768
+ - Destructuring (`[a, b] = func()`) is not supported
769
+ - and many other Typescript language features are not supported
770
+
771
+ Some of these might be implemented later, but the goal of ts2workflows project is not to implement the full Typescript compatibility.