ts2workflows 0.3.0 → 0.5.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/README.md +6 -2
- package/dist/ast/expressions.d.ts.map +1 -1
- package/dist/ast/expressions.js +7 -10
- 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 +54 -38
- package/dist/transpiler/expressions.d.ts +8 -4
- package/dist/transpiler/expressions.d.ts.map +1 -1
- package/dist/transpiler/expressions.js +162 -42
- 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 +137 -155
- package/dist/transpiler/transformations.d.ts.map +1 -1
- package/dist/transpiler/transformations.js +216 -110
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +6 -0
- package/language_reference.md +55 -33
- package/package.json +11 -4
- package/types/global.d.ts +124 -0
- package/dist/transpiler/asserts.d.ts +0 -7
- package/dist/transpiler/asserts.d.ts.map +0 -1
- package/dist/transpiler/asserts.js +0 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssignStepAST, CallStepAST, ForStepAST, RaiseStepAST, ReturnStepAST, SwitchStepAST, TryStepAST, } from '../ast/steps.js';
|
|
2
2
|
import { InternalTranspilingError } from '../errors.js';
|
|
3
|
-
import { isRecord } from '../utils.js';
|
|
3
|
+
import { isRecord, mapRecordValues } from '../utils.js';
|
|
4
4
|
import { BinaryExpression, FunctionInvocationExpression, MemberExpression, PrimitiveExpression, UnaryExpression, VariableReferenceExpression, expressionToLiteralValueOrLiteralExpression, isExpression, isFullyQualifiedName, isLiteral, } from '../ast/expressions.js';
|
|
5
5
|
import { blockingFunctions } from './generated/functionMetadata.js';
|
|
6
6
|
const Unmodified = Symbol();
|
|
@@ -23,8 +23,9 @@ function mergeAssignSteps(steps) {
|
|
|
23
23
|
const prev = acc.length > 0 ? acc[acc.length - 1] : null;
|
|
24
24
|
if (current.tag === 'assign' &&
|
|
25
25
|
prev?.tag === 'assign' &&
|
|
26
|
-
prev.assignments.length < 50
|
|
27
|
-
|
|
26
|
+
prev.assignments.length < 50 &&
|
|
27
|
+
!prev.next) {
|
|
28
|
+
const merged = new AssignStepAST(prev.assignments.concat(current.assignments), current.next, prev.label ?? current.label);
|
|
28
29
|
acc.pop();
|
|
29
30
|
acc.push(merged);
|
|
30
31
|
}
|
|
@@ -142,26 +143,29 @@ function parseRetryPolicyNumber(record, keyName) {
|
|
|
142
143
|
* next: target1
|
|
143
144
|
*/
|
|
144
145
|
export function flattenPlainNextConditions(steps) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
146
|
+
return steps.reduce((acc, step) => {
|
|
147
|
+
if (acc.length > 0 && step.tag === 'next') {
|
|
148
|
+
// Merge a "next" to the previous "assign" step
|
|
149
|
+
const prev = acc[acc.length - 1];
|
|
150
|
+
if (prev.tag === 'assign' && !prev.next) {
|
|
151
|
+
acc.pop();
|
|
152
|
+
acc.push(prev.withNext(step.target));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
acc.push(step);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else if (step.tag === 'switch') {
|
|
159
|
+
// If the condition steps consists of a single "next", merge it with the condition
|
|
160
|
+
acc.push(flattenNextToCondition(step));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
acc.push(step);
|
|
155
164
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
*/
|
|
162
|
-
return steps.map((step) => (step.tag === 'switch' ? flattenNext(step) : step));
|
|
163
|
-
}
|
|
164
|
-
function flattenNext(step) {
|
|
165
|
+
return acc;
|
|
166
|
+
}, []);
|
|
167
|
+
}
|
|
168
|
+
function flattenNextToCondition(step) {
|
|
165
169
|
const transformedBranches = step.branches.map((cond) => {
|
|
166
170
|
if (!cond.next && cond.steps.length === 1 && cond.steps[0].tag === 'next') {
|
|
167
171
|
const nextStep = cond.steps[0];
|
|
@@ -287,7 +291,7 @@ function transformExpressionsAssign(step, transform) {
|
|
|
287
291
|
newSteps.push(...steps2);
|
|
288
292
|
return [name, ex2];
|
|
289
293
|
});
|
|
290
|
-
newSteps.push(new AssignStepAST(newAssignments, step.label));
|
|
294
|
+
newSteps.push(new AssignStepAST(newAssignments, step.next, step.label));
|
|
291
295
|
return newSteps;
|
|
292
296
|
}
|
|
293
297
|
else {
|
|
@@ -297,11 +301,11 @@ function transformExpressionsAssign(step, transform) {
|
|
|
297
301
|
function transformExpressionsCall(step, transform) {
|
|
298
302
|
if (step.args) {
|
|
299
303
|
const newSteps = [];
|
|
300
|
-
const newArgs =
|
|
304
|
+
const newArgs = mapRecordValues(step.args, (ex) => {
|
|
301
305
|
const [steps2, ex2] = transform(ex);
|
|
302
306
|
newSteps.push(...steps2);
|
|
303
|
-
return
|
|
304
|
-
})
|
|
307
|
+
return ex2;
|
|
308
|
+
});
|
|
305
309
|
newSteps.push(new CallStepAST(step.call, newArgs, step.result, step.label));
|
|
306
310
|
return newSteps;
|
|
307
311
|
}
|
|
@@ -353,8 +357,8 @@ function transformExpressionsSwitch(step, transform) {
|
|
|
353
357
|
newSteps.push(new SwitchStepAST(newBranches, step.label));
|
|
354
358
|
return newSteps;
|
|
355
359
|
}
|
|
356
|
-
function transformExpression(ex,
|
|
357
|
-
const transformed =
|
|
360
|
+
function transformExpression(ex, transform) {
|
|
361
|
+
const transformed = transform(ex);
|
|
358
362
|
if (transformed !== Unmodified) {
|
|
359
363
|
// Use the transformed version of this term
|
|
360
364
|
return transformed;
|
|
@@ -363,28 +367,76 @@ function transformExpression(ex, transformer) {
|
|
|
363
367
|
// Otherwise, recurse into the nested expression
|
|
364
368
|
switch (ex.expressionType) {
|
|
365
369
|
case 'primitive':
|
|
366
|
-
|
|
367
|
-
|
|
370
|
+
if (isLiteral(ex)) {
|
|
371
|
+
return ex;
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
const newPrimitive = transformPrimitive(ex.value, transform);
|
|
375
|
+
return newPrimitive === ex.value
|
|
376
|
+
? ex
|
|
377
|
+
: new PrimitiveExpression(newPrimitive);
|
|
378
|
+
}
|
|
368
379
|
case 'binary':
|
|
369
|
-
return transformBinaryExpression(ex,
|
|
380
|
+
return transformBinaryExpression(ex, transform);
|
|
370
381
|
case 'functionInvocation':
|
|
371
|
-
return transformFunctionInvocationExpression(ex,
|
|
382
|
+
return transformFunctionInvocationExpression(ex, transform);
|
|
372
383
|
case 'member':
|
|
373
|
-
return
|
|
384
|
+
return transformMemberExpression(ex, transform);
|
|
374
385
|
case 'unary':
|
|
375
|
-
return
|
|
386
|
+
return transformUnaryExpression(ex, transform);
|
|
387
|
+
case 'variableReference':
|
|
388
|
+
return ex;
|
|
376
389
|
}
|
|
377
390
|
}
|
|
378
391
|
}
|
|
379
|
-
function
|
|
392
|
+
function transformPrimitive(val, transform) {
|
|
393
|
+
if (Array.isArray(val)) {
|
|
394
|
+
return val.map((x) => isExpression(x)
|
|
395
|
+
? transformExpression(x, transform)
|
|
396
|
+
: transformPrimitive(x, transform));
|
|
397
|
+
}
|
|
398
|
+
else if (isRecord(val)) {
|
|
399
|
+
return mapRecordValues(val, (x) => isExpression(x)
|
|
400
|
+
? transformExpression(x, transform)
|
|
401
|
+
: transformPrimitive(x, transform));
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
return val;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
function transformBinaryExpression(ex, transform) {
|
|
380
408
|
// Transform left first to keep the correct order of execution of sub-expressions
|
|
381
|
-
const newLeft = transformExpression(ex.left,
|
|
382
|
-
const newRight = transformExpression(ex.right,
|
|
383
|
-
|
|
409
|
+
const newLeft = transformExpression(ex.left, transform);
|
|
410
|
+
const newRight = transformExpression(ex.right, transform);
|
|
411
|
+
if (newLeft === ex.left && newRight === ex.right) {
|
|
412
|
+
return ex;
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
return new BinaryExpression(newLeft, ex.binaryOperator, newRight);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function transformFunctionInvocationExpression(ex, transform) {
|
|
419
|
+
const newArguments = ex.arguments.map((x) => transformExpression(x, transform));
|
|
420
|
+
if (newArguments.every((x, i) => x === ex.arguments[i])) {
|
|
421
|
+
return ex;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
return new FunctionInvocationExpression(ex.functionName, newArguments);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function transformMemberExpression(ex, transform) {
|
|
428
|
+
const newObject = transformExpression(ex.object, transform);
|
|
429
|
+
const newProperty = transformExpression(ex.property, transform);
|
|
430
|
+
if (newObject === ex.object && newProperty === ex.property) {
|
|
431
|
+
return ex;
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
return new MemberExpression(newObject, newProperty, ex.computed);
|
|
435
|
+
}
|
|
384
436
|
}
|
|
385
|
-
function
|
|
386
|
-
const
|
|
387
|
-
return new
|
|
437
|
+
function transformUnaryExpression(ex, transform) {
|
|
438
|
+
const newValue = transformExpression(ex.value, transform);
|
|
439
|
+
return newValue === ex.value ? ex : new UnaryExpression(ex.operator, newValue);
|
|
388
440
|
}
|
|
389
441
|
/**
|
|
390
442
|
* Search for map literals in expressions and replace them with assign step + variable.
|
|
@@ -406,89 +458,143 @@ function transformFunctionInvocationExpression(ex, transformer) {
|
|
|
406
458
|
* return: ${__temp0.value}
|
|
407
459
|
*/
|
|
408
460
|
function mapLiteralsAsAssignSteps(steps) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
// These steps are allowed to contain map literals if the map is the
|
|
417
|
-
// main expression
|
|
418
|
-
if (current.tag === 'assign') {
|
|
419
|
-
// This does the transformation a bit too eagerly: If any of the
|
|
420
|
-
// assignments need the map literal extraction, it is done on all of
|
|
421
|
-
// the variables.
|
|
422
|
-
needsTransformation = !current.assignments.every(([, value]) => {
|
|
423
|
-
return value.expressionType === 'primitive';
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
else if (current.tag === 'raise' || current.tag === 'return') {
|
|
427
|
-
needsTransformation =
|
|
428
|
-
current.value !== undefined &&
|
|
429
|
-
includesExtractableMapLiteral(current.value, true);
|
|
430
|
-
}
|
|
431
|
-
else if (current.tag === 'call') {
|
|
432
|
-
if (current.args) {
|
|
433
|
-
needsTransformation = Object.values(current.args).some((ex) => includesExtractableMapLiteral(ex, true));
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
if (needsTransformation) {
|
|
437
|
-
const transformedSteps = transformStepExpressions(current, transformer);
|
|
438
|
-
acc.push(...transformedSteps);
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
acc.push(current);
|
|
442
|
-
}
|
|
443
|
-
return acc;
|
|
444
|
-
}, []);
|
|
461
|
+
return steps.flatMap((step) => transformStepExpressions(step, transformNestedMaps));
|
|
462
|
+
}
|
|
463
|
+
function transformNestedMaps(ex) {
|
|
464
|
+
const generateTemporaryVariableName = createTempVariableGenerator();
|
|
465
|
+
const { transformedExpression, tempVariables } = extractNestedMaps(ex, generateTemporaryVariableName, 0);
|
|
466
|
+
const assignments = tempVariables.length > 0 ? [new AssignStepAST(tempVariables)] : [];
|
|
467
|
+
return [assignments, transformedExpression];
|
|
445
468
|
}
|
|
446
|
-
|
|
447
|
-
function includesExtractableMapLiteral(ex, parentAllowsMaps) {
|
|
469
|
+
function extractNestedMaps(ex, generateName, nestingLevel) {
|
|
448
470
|
switch (ex.expressionType) {
|
|
449
471
|
case 'primitive':
|
|
450
|
-
|
|
451
|
-
return (!parentAllowsMaps ||
|
|
452
|
-
Object.values(ex.value).some((x) => isExpression(x) &&
|
|
453
|
-
includesExtractableMapLiteral(x, parentAllowsMaps)));
|
|
454
|
-
}
|
|
455
|
-
else if (Array.isArray(ex.value)) {
|
|
456
|
-
return ex.value.some((x) => isExpression(x) &&
|
|
457
|
-
includesExtractableMapLiteral(x, parentAllowsMaps));
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
return false;
|
|
461
|
-
}
|
|
472
|
+
return extractNestedMapPrimitive(ex.value, generateName, nestingLevel);
|
|
462
473
|
case 'binary':
|
|
463
|
-
return (
|
|
464
|
-
includesExtractableMapLiteral(ex.right, parentAllowsMaps));
|
|
474
|
+
return extractNestedMapBinary(ex, generateName, nestingLevel);
|
|
465
475
|
case 'variableReference':
|
|
466
|
-
return
|
|
467
|
-
case 'unary':
|
|
468
|
-
return includesExtractableMapLiteral(ex.value, parentAllowsMaps);
|
|
476
|
+
return { transformedExpression: ex, tempVariables: [] };
|
|
469
477
|
case 'functionInvocation':
|
|
470
|
-
return ex
|
|
478
|
+
return extractNestedMapFunctionInvocation(ex, generateName, nestingLevel);
|
|
471
479
|
case 'member':
|
|
472
|
-
return (
|
|
473
|
-
|
|
480
|
+
return extractNestedMapMember(ex, generateName, nestingLevel);
|
|
481
|
+
case 'unary':
|
|
482
|
+
return extractNestedMapUnary(ex, generateName, nestingLevel);
|
|
474
483
|
}
|
|
475
484
|
}
|
|
476
|
-
function
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
485
|
+
function extractNestedMapPrimitive(primitiveEx, generateName, nestingLevel) {
|
|
486
|
+
const { transformed, tempVariables } = extractNestedMapPrimitiveRecursive(primitiveEx, generateName, nestingLevel);
|
|
487
|
+
const ex = isExpression(transformed)
|
|
488
|
+
? transformed
|
|
489
|
+
: new PrimitiveExpression(transformed);
|
|
490
|
+
return {
|
|
491
|
+
transformedExpression: ex,
|
|
492
|
+
tempVariables,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
function extractNestedMapPrimitiveRecursive(primitiveEx, generateName, nestingLevel) {
|
|
496
|
+
if (typeof primitiveEx === 'string' ||
|
|
497
|
+
typeof primitiveEx === 'number' ||
|
|
498
|
+
typeof primitiveEx === 'boolean' ||
|
|
499
|
+
primitiveEx === null) {
|
|
500
|
+
return {
|
|
501
|
+
transformed: primitiveEx,
|
|
502
|
+
tempVariables: [],
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
else if (Array.isArray(primitiveEx)) {
|
|
506
|
+
return extractMapsInList(primitiveEx, generateName, nestingLevel);
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
return extractMapsInMap(primitiveEx, generateName, nestingLevel);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function extractMapsInList(primitiveEx, generateName, nestingLevel) {
|
|
513
|
+
const { tempVariables, elements } = primitiveEx.reduce((acc, val) => {
|
|
514
|
+
if (isExpression(val)) {
|
|
515
|
+
const { transformedExpression, tempVariables: temps } = extractNestedMaps(val, generateName, nestingLevel);
|
|
516
|
+
acc.tempVariables.push(...temps);
|
|
517
|
+
acc.elements.push(transformedExpression);
|
|
483
518
|
}
|
|
484
519
|
else {
|
|
485
|
-
|
|
520
|
+
const { transformed, tempVariables: temps } = extractNestedMapPrimitiveRecursive(val, generateName, nestingLevel);
|
|
521
|
+
acc.tempVariables.push(...temps);
|
|
522
|
+
acc.elements.push(transformed);
|
|
486
523
|
}
|
|
524
|
+
return acc;
|
|
525
|
+
}, {
|
|
526
|
+
tempVariables: [],
|
|
527
|
+
elements: [],
|
|
528
|
+
});
|
|
529
|
+
return {
|
|
530
|
+
tempVariables,
|
|
531
|
+
transformed: elements,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function extractMapsInMap(primitiveEx, generateName, nestingLevel) {
|
|
535
|
+
const { tempVariables, properties } = Object.entries(primitiveEx).reduce((acc, [key, val]) => {
|
|
536
|
+
if (isExpression(val)) {
|
|
537
|
+
const { transformedExpression, tempVariables: temps } = extractNestedMaps(val, generateName, 0);
|
|
538
|
+
acc.tempVariables.push(...temps);
|
|
539
|
+
acc.properties[key] = transformedExpression;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
const { transformed, tempVariables: temps } = extractNestedMapPrimitiveRecursive(val, generateName, 0);
|
|
543
|
+
acc.tempVariables.push(...temps);
|
|
544
|
+
acc.properties[key] = transformed;
|
|
545
|
+
}
|
|
546
|
+
return acc;
|
|
547
|
+
}, {
|
|
548
|
+
tempVariables: [],
|
|
549
|
+
properties: {},
|
|
550
|
+
});
|
|
551
|
+
let newValue;
|
|
552
|
+
if (nestingLevel === 0) {
|
|
553
|
+
newValue = properties;
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
const name = generateName();
|
|
557
|
+
tempVariables.push([name, new PrimitiveExpression(properties)]);
|
|
558
|
+
newValue = new VariableReferenceExpression(name);
|
|
487
559
|
}
|
|
488
|
-
const assignSteps = [];
|
|
489
560
|
return {
|
|
490
|
-
|
|
491
|
-
|
|
561
|
+
transformed: newValue,
|
|
562
|
+
tempVariables,
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function extractNestedMapFunctionInvocation(ex, generateName, nestingLevel) {
|
|
566
|
+
const { expressions, temps } = ex.arguments.reduce((acc, arg) => {
|
|
567
|
+
const { transformedExpression, tempVariables } = extractNestedMaps(arg, generateName, nestingLevel + 1);
|
|
568
|
+
acc.expressions.push(transformedExpression);
|
|
569
|
+
acc.temps.push(...tempVariables);
|
|
570
|
+
return acc;
|
|
571
|
+
}, { expressions: [], temps: [] });
|
|
572
|
+
return {
|
|
573
|
+
transformedExpression: new FunctionInvocationExpression(ex.functionName, expressions),
|
|
574
|
+
tempVariables: temps,
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function extractNestedMapBinary(ex, generateName, nestingLevel) {
|
|
578
|
+
const left = extractNestedMaps(ex.left, generateName, nestingLevel + 1);
|
|
579
|
+
const right = extractNestedMaps(ex.right, generateName, nestingLevel + 1);
|
|
580
|
+
return {
|
|
581
|
+
transformedExpression: new BinaryExpression(left.transformedExpression, ex.binaryOperator, right.transformedExpression),
|
|
582
|
+
tempVariables: left.tempVariables.concat(right.tempVariables),
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
function extractNestedMapMember(ex, generateName, nestingLevel) {
|
|
586
|
+
const obj = extractNestedMaps(ex.object, generateName, nestingLevel + 1);
|
|
587
|
+
const pr = extractNestedMaps(ex.property, generateName, nestingLevel + 1);
|
|
588
|
+
return {
|
|
589
|
+
transformedExpression: new MemberExpression(obj.transformedExpression, pr.transformedExpression, ex.computed),
|
|
590
|
+
tempVariables: obj.tempVariables.concat(pr.tempVariables),
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function extractNestedMapUnary(ex, generateName, nestingLevel) {
|
|
594
|
+
const { transformedExpression, tempVariables } = extractNestedMaps(ex.value, generateName, nestingLevel);
|
|
595
|
+
return {
|
|
596
|
+
transformedExpression: new UnaryExpression(ex.operator, transformedExpression),
|
|
597
|
+
tempVariables,
|
|
492
598
|
};
|
|
493
599
|
}
|
|
494
600
|
/**
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export declare function isRecord(object: unknown): object is Record<keyof never, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Apply f to values of obj and return the result
|
|
4
|
+
*/
|
|
5
|
+
export declare function mapRecordValues<T, U>(obj: Record<string, T>, f: (t: T) => U): Record<string, U>;
|
|
2
6
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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"}
|
|
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;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EACtB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GACb,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAEnB"}
|
package/dist/utils.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export function isRecord(object) {
|
|
2
2
|
return object instanceof Object && object.constructor === Object;
|
|
3
3
|
}
|
|
4
|
+
/**
|
|
5
|
+
* Apply f to values of obj and return the result
|
|
6
|
+
*/
|
|
7
|
+
export function mapRecordValues(obj, f) {
|
|
8
|
+
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, f(v)]));
|
|
9
|
+
}
|
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}`.
|
|
@@ -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.5.0",
|
|
4
4
|
"description": "Transpile Typescript code to GCP Workflows programs",
|
|
5
5
|
"homepage": "https://github.com/aajanki/ts2workflows",
|
|
6
6
|
"repository": {
|
|
@@ -23,7 +23,15 @@
|
|
|
23
23
|
"prepare": "husky"
|
|
24
24
|
},
|
|
25
25
|
"lint-staged": {
|
|
26
|
-
"
|
|
26
|
+
"src/**/*.ts": [
|
|
27
|
+
"prettier --write",
|
|
28
|
+
"eslint"
|
|
29
|
+
],
|
|
30
|
+
"test/**/*.ts": [
|
|
31
|
+
"prettier --write",
|
|
32
|
+
"eslint"
|
|
33
|
+
],
|
|
34
|
+
"scripts/**/*.ts": [
|
|
27
35
|
"prettier --write",
|
|
28
36
|
"eslint"
|
|
29
37
|
],
|
|
@@ -49,7 +57,7 @@
|
|
|
49
57
|
],
|
|
50
58
|
"devDependencies": {
|
|
51
59
|
"@eslint/js": "^9.10.0",
|
|
52
|
-
"@types/chai": "^
|
|
60
|
+
"@types/chai": "^5.0.1",
|
|
53
61
|
"@types/mocha": "^10.0.6",
|
|
54
62
|
"@types/node": "^18",
|
|
55
63
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
@@ -66,7 +74,6 @@
|
|
|
66
74
|
},
|
|
67
75
|
"dependencies": {
|
|
68
76
|
"@typescript-eslint/typescript-estree": "^8.0.0",
|
|
69
|
-
"@typescript-eslint/utils": "^8.0.0",
|
|
70
77
|
"commander": "^12.1.0",
|
|
71
78
|
"typescript": "^5.0.0",
|
|
72
79
|
"yaml": "^2.4.2"
|