ts2workflows 0.2.0 → 0.4.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/dist/ast/stepnames.d.ts.map +1 -1
- package/dist/ast/stepnames.js +11 -1
- package/dist/ast/steps.d.ts +24 -13
- package/dist/ast/steps.d.ts.map +1 -1
- package/dist/ast/steps.js +42 -27
- package/dist/transpiler/expressions.d.ts +7 -4
- package/dist/transpiler/expressions.d.ts.map +1 -1
- package/dist/transpiler/expressions.js +156 -37
- package/dist/transpiler/index.d.ts.map +1 -1
- package/dist/transpiler/index.js +29 -28
- package/dist/transpiler/statements.d.ts +2 -1
- package/dist/transpiler/statements.d.ts.map +1 -1
- package/dist/transpiler/statements.js +135 -158
- package/dist/transpiler/transformations.d.ts +1 -1
- package/dist/transpiler/transformations.d.ts.map +1 -1
- package/dist/transpiler/transformations.js +27 -6
- package/language_reference.md +57 -35
- package/package.json +22 -3
- package/types/global.d.ts +116 -0
- package/types/workflowslib.d.ts +17 -5
- package/dist/transpiler/asserts.d.ts +0 -7
- package/dist/transpiler/asserts.d.ts.map +0 -1
- package/dist/transpiler/asserts.js +0 -11
package/language_reference.md
CHANGED
|
@@ -40,6 +40,12 @@ It is not possible to construct a bytes object expect by calling a function that
|
|
|
40
40
|
|
|
41
41
|
In addition to the literal `null`, the Typescript `undefined` value is also treated as `null` in Workflows YAML.
|
|
42
42
|
|
|
43
|
+
### Implicit type conversions
|
|
44
|
+
|
|
45
|
+
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.
|
|
46
|
+
|
|
47
|
+
⚠️ Checking if a variable is null or not must be done by an explicit comparison: `if (var != null) {...}`. Relying in an implicit conversion, such as `if (var) {...}`, results in a TypeError at runtime.
|
|
48
|
+
|
|
43
49
|
## Expressions
|
|
44
50
|
|
|
45
51
|
Most Typescript expressions work as expected.
|
|
@@ -56,7 +62,7 @@ name === 'Bean'
|
|
|
56
62
|
sys.get_env('GOOGLE_CLOUD_PROJECT_ID')
|
|
57
63
|
```
|
|
58
64
|
|
|
59
|
-
Operators
|
|
65
|
+
## Operators
|
|
60
66
|
|
|
61
67
|
| Operator | Description |
|
|
62
68
|
| ------------ | -------------------------------------------- |
|
|
@@ -71,11 +77,59 @@ Operators:
|
|
|
71
77
|
| &&, \|\|, ! | logical operators |
|
|
72
78
|
| in | check if a property is present in an object |
|
|
73
79
|
| ?? | nullish coalescing |
|
|
80
|
+
| ?. | optional chaining |
|
|
81
|
+
| ? : | conditional operator |
|
|
74
82
|
|
|
75
83
|
The [precendence order of operators](https://cloud.google.com/workflows/docs/reference/syntax/datatypes#order-operations) is the same as in GCP Workflows.
|
|
76
84
|
|
|
77
85
|
See [expression in GCP Workflows](https://cloud.google.com/workflows/docs/reference/syntax/expressions) for more information.
|
|
78
86
|
|
|
87
|
+
### Conditional (ternary) operator
|
|
88
|
+
|
|
89
|
+
The expression
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
x > 0 ? 'positive' : 'not positive'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
is converted to an [if() expression](https://cloud.google.com/workflows/docs/reference/stdlib/expression-helpers#conditional_functions):
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
${if(x > 0, "positive", "not positive")}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
⚠️ Note that Workflows always evaluates both expression branches unlike Typescript which evaluates only the branch that gets executed.
|
|
102
|
+
|
|
103
|
+
### Nullish coalescing operator
|
|
104
|
+
|
|
105
|
+
The expression
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
x ?? 'default value'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
is converted to a [default() expression](https://cloud.google.com/workflows/docs/reference/stdlib/expression-helpers#conditional_functions):
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
${default(x, "default value")}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
⚠️ 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`.
|
|
118
|
+
|
|
119
|
+
### Optional chaining
|
|
120
|
+
|
|
121
|
+
The optional chaining expression
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
data.user?.name
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
is converted to a [map.get() expression](https://cloud.google.com/workflows/docs/reference/stdlib/map/get):
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
${map.get(data, ["user", "name"])}
|
|
131
|
+
```
|
|
132
|
+
|
|
79
133
|
## Template literals
|
|
80
134
|
|
|
81
135
|
Template literals are strings that support string interpolation. For example, `Hello ${name}`.
|
|
@@ -145,7 +199,7 @@ is converted to an [assign step](https://cloud.google.com/workflows/docs/referen
|
|
|
145
199
|
- projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
|
|
146
200
|
```
|
|
147
201
|
|
|
148
|
-
This syntax can be used to call [standard library functions](https://cloud.google.com/workflows/docs/reference/stdlib/overview), subworkflows or connectors.
|
|
202
|
+
This syntax can be used to call [standard library functions](https://cloud.google.com/workflows/docs/reference/stdlib/overview), subworkflows or connectors. Note that Javascript runtime functions (such as `fetch()`, `console.error()` or `new XMLHttpRequest()`) are not available on Workflows.
|
|
149
203
|
|
|
150
204
|
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
205
|
|
|
@@ -175,7 +229,7 @@ main:
|
|
|
175
229
|
severity: INFO
|
|
176
230
|
```
|
|
177
231
|
|
|
178
|
-
Some Workflows standard library functions have names that are reserved keywords in Typescript. Those functions must be called with alternative
|
|
232
|
+
Some Workflows standard library functions have names that are reserved keywords in Typescript. Those functions must be called with alternative syntax in ts2workflows source code:
|
|
179
233
|
|
|
180
234
|
- To generate a call to `default()` in Workflows code, use the nullish coalescing operator `??`.
|
|
181
235
|
- To generete a call to `if()` in Workflows code, use the ternary operator `a ? b : c`.
|
|
@@ -307,38 +361,6 @@ steps:
|
|
|
307
361
|
return: ${b}
|
|
308
362
|
```
|
|
309
363
|
|
|
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
364
|
## Loops
|
|
343
365
|
|
|
344
366
|
The fragment
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts2workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Transpile Typescript code to GCP Workflows programs",
|
|
5
5
|
"homepage": "https://github.com/aajanki/ts2workflows",
|
|
6
6
|
"repository": {
|
|
@@ -19,7 +19,25 @@
|
|
|
19
19
|
"build:functionmetadata": "tsx scripts/generateBlockingFunctionMetadata.ts",
|
|
20
20
|
"lint": "eslint src test scripts",
|
|
21
21
|
"format": "prettier . --write",
|
|
22
|
-
"test": "mocha"
|
|
22
|
+
"test": "mocha",
|
|
23
|
+
"prepare": "husky"
|
|
24
|
+
},
|
|
25
|
+
"lint-staged": {
|
|
26
|
+
"src/**/*.ts": [
|
|
27
|
+
"prettier --write",
|
|
28
|
+
"eslint"
|
|
29
|
+
],
|
|
30
|
+
"test/**/*.ts": [
|
|
31
|
+
"prettier --write",
|
|
32
|
+
"eslint"
|
|
33
|
+
],
|
|
34
|
+
"scripts/**/*.ts": [
|
|
35
|
+
"prettier --write",
|
|
36
|
+
"eslint"
|
|
37
|
+
],
|
|
38
|
+
"*.md": [
|
|
39
|
+
"prettier --write"
|
|
40
|
+
]
|
|
23
41
|
},
|
|
24
42
|
"bin": "./dist/cli.js",
|
|
25
43
|
"files": [
|
|
@@ -46,6 +64,8 @@
|
|
|
46
64
|
"@typescript-eslint/parser": "^8.0.0",
|
|
47
65
|
"chai": "^5.1.1",
|
|
48
66
|
"eslint": "^9.10.0",
|
|
67
|
+
"husky": "^9.1.6",
|
|
68
|
+
"lint-staged": "^15.2.10",
|
|
49
69
|
"mocha": "^10.4.0",
|
|
50
70
|
"prettier": "^3.2.5",
|
|
51
71
|
"rimraf": "^5.0.10",
|
|
@@ -54,7 +74,6 @@
|
|
|
54
74
|
},
|
|
55
75
|
"dependencies": {
|
|
56
76
|
"@typescript-eslint/typescript-estree": "^8.0.0",
|
|
57
|
-
"@typescript-eslint/utils": "^8.0.0",
|
|
58
77
|
"commander": "^12.1.0",
|
|
59
78
|
"typescript": "^5.0.0",
|
|
60
79
|
"yaml": "^2.4.2"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export {}
|
|
2
|
+
|
|
3
|
+
/// <reference no-default-lib="true"/>
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
// Minimal definition of Symbol.iterator required by the for-of statement
|
|
7
|
+
interface SymbolConstructor {
|
|
8
|
+
readonly iterator: unique symbol
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
var Symbol: SymbolConstructor
|
|
12
|
+
|
|
13
|
+
interface Iterator<T> {}
|
|
14
|
+
|
|
15
|
+
interface Iterable<T> {
|
|
16
|
+
[Symbol.iterator](): Iterator<T>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface IterableIterator<T> extends Iterator<T> {
|
|
20
|
+
[Symbol.iterator](): IterableIterator<T>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Array<T> {
|
|
24
|
+
// Array member access
|
|
25
|
+
[n: number]: T
|
|
26
|
+
|
|
27
|
+
// Arrays can be iterated by the for-of statement
|
|
28
|
+
[Symbol.iterator](): IterableIterator<T>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface ArrayConstructor {
|
|
32
|
+
isArray(arg: any): arg is any[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var Array: ArrayConstructor
|
|
36
|
+
|
|
37
|
+
interface Boolean {}
|
|
38
|
+
interface CallableFunction {}
|
|
39
|
+
interface Function {}
|
|
40
|
+
interface IArguments {}
|
|
41
|
+
interface NewableFunction {}
|
|
42
|
+
interface Number {}
|
|
43
|
+
interface Object {}
|
|
44
|
+
interface RegExp {}
|
|
45
|
+
interface String {}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Utility types
|
|
49
|
+
* Copied from lib.es5.d.ts
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Make all properties in T optional
|
|
54
|
+
*/
|
|
55
|
+
type Partial<T> = {
|
|
56
|
+
[P in keyof T]?: T[P]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Make all properties in T required
|
|
61
|
+
*/
|
|
62
|
+
type Required<T> = {
|
|
63
|
+
[P in keyof T]-?: T[P]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Make all properties in T readonly
|
|
68
|
+
*/
|
|
69
|
+
type Readonly<T> = {
|
|
70
|
+
readonly [P in keyof T]: T[P]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* From T, pick a set of properties whose keys are in the union K
|
|
75
|
+
*/
|
|
76
|
+
type Pick<T, K extends keyof T> = {
|
|
77
|
+
[P in K]: T[P]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Construct a type with a set of properties K of type T
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
type Record<K extends keyof any, T> = {
|
|
85
|
+
[P in K]: T
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Obtain the return type of a function type
|
|
90
|
+
*/
|
|
91
|
+
type ReturnType<T extends (...args: any) => any> = T extends (
|
|
92
|
+
...args: any
|
|
93
|
+
) => infer R
|
|
94
|
+
? R
|
|
95
|
+
: any
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Exclude from T those types that are assignable to U
|
|
99
|
+
*/
|
|
100
|
+
type Exclude<T, U> = T extends U ? never : T
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Extract from T those types that are assignable to U
|
|
104
|
+
*/
|
|
105
|
+
type Extract<T, U> = T extends U ? T : never
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Construct a type with the properties of T except for those in type K.
|
|
109
|
+
*/
|
|
110
|
+
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Exclude null and undefined from T
|
|
114
|
+
*/
|
|
115
|
+
type NonNullable<T> = T & {}
|
|
116
|
+
}
|
package/types/workflowslib.d.ts
CHANGED
|
@@ -161,9 +161,15 @@ export declare namespace http {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
export declare namespace json {
|
|
164
|
-
function decode(data: bytes | string):
|
|
164
|
+
function decode(data: bytes | string): unknown
|
|
165
165
|
function encode(
|
|
166
|
-
data:
|
|
166
|
+
data:
|
|
167
|
+
| string
|
|
168
|
+
| number
|
|
169
|
+
| boolean
|
|
170
|
+
| unknown[]
|
|
171
|
+
| Record<string, unknown>
|
|
172
|
+
| null,
|
|
167
173
|
indent?:
|
|
168
174
|
| boolean
|
|
169
175
|
| {
|
|
@@ -172,7 +178,13 @@ export declare namespace json {
|
|
|
172
178
|
},
|
|
173
179
|
): bytes
|
|
174
180
|
function encode_to_string(
|
|
175
|
-
data:
|
|
181
|
+
data:
|
|
182
|
+
| string
|
|
183
|
+
| number
|
|
184
|
+
| boolean
|
|
185
|
+
| unknown[]
|
|
186
|
+
| Record<string, unknown>
|
|
187
|
+
| null,
|
|
176
188
|
indent?:
|
|
177
189
|
| boolean
|
|
178
190
|
| {
|
|
@@ -192,7 +204,7 @@ export declare namespace map {
|
|
|
192
204
|
export function get<T, K extends string | string[]>(
|
|
193
205
|
map: Record<string, T>,
|
|
194
206
|
keys: K,
|
|
195
|
-
): K extends string ? T : unknown
|
|
207
|
+
): K extends string ? T | null : unknown
|
|
196
208
|
export function merge<T, U>(
|
|
197
209
|
first: Record<string, T>,
|
|
198
210
|
second: Record<string, U>,
|
|
@@ -245,7 +257,7 @@ export declare namespace text {
|
|
|
245
257
|
index: number
|
|
246
258
|
match: string
|
|
247
259
|
}[]
|
|
248
|
-
function
|
|
260
|
+
function match_regex(source: string, regexp: string): boolean
|
|
249
261
|
function replace_all(source: string, substr: string, repl: string): string
|
|
250
262
|
function replace_all_regex(
|
|
251
263
|
source: string,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asserts.d.ts","sourceRoot":"","sources":["../../src/transpiler/asserts.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAM7E;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACtB,qBAAqB,EAAE,MAAM,EAAE,GAC9B,IAAI,CAMN"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { InternalTranspilingError } from '../errors.js';
|
|
2
|
-
export function assertType(node, expectedType) {
|
|
3
|
-
if (node?.type !== expectedType) {
|
|
4
|
-
throw new InternalTranspilingError(`Expected ${expectedType}, got ${node?.type}`);
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
export function assertOneOfManyTypes(node, expectAnyOfTheseTypes) {
|
|
8
|
-
if (!expectAnyOfTheseTypes.includes(node?.type)) {
|
|
9
|
-
throw new InternalTranspilingError(`Expected ${expectAnyOfTheseTypes.join(' or ')}, got ${node?.type}`);
|
|
10
|
-
}
|
|
11
|
-
}
|