ts2workflows 0.1.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transpiler/index.ts"],"names":[],"mappings":"AAyBA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transpiler/index.ts"],"names":[],"mappings":"AA0BA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAa9C"}
@@ -7,7 +7,7 @@ import { WorkflowSyntaxError } from '../errors.js';
7
7
  import { generateStepNames } from '../ast/stepnames.js';
8
8
  import { assertType } from './asserts.js';
9
9
  import { parseBlockStatement } from './statements.js';
10
- const { AssignmentPattern, ExportNamedDeclaration, FunctionDeclaration, Identifier, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, Literal, Program, TSTypeAliasDeclaration, TSInterfaceDeclaration, } = AST_NODE_TYPES;
10
+ const { AssignmentPattern, ExportNamedDeclaration, FunctionDeclaration, Identifier, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, Literal, Program, TSDeclareFunction, TSTypeAliasDeclaration, TSInterfaceDeclaration, } = AST_NODE_TYPES;
11
11
  export function transpile(code) {
12
12
  const parserOptions = {
13
13
  jsDocParsingMode: 'none',
@@ -40,10 +40,11 @@ function parseTopLevelStatement(node) {
40
40
  }
41
41
  case TSInterfaceDeclaration:
42
42
  case TSTypeAliasDeclaration:
43
- // Ignore "type" and "interface" declarations at the top-level
43
+ case TSDeclareFunction:
44
+ // Ignore "type", "interface" and "declare function" at the top-level
44
45
  return [];
45
46
  default:
46
- throw new WorkflowSyntaxError(`Only function declarations, imports and type aliases allowed at the top level, encountered ${node?.type}`, node?.loc);
47
+ throw new WorkflowSyntaxError(`Only function definitions, imports and type aliases allowed at the top level, encountered ${node?.type}`, node?.loc);
47
48
  }
48
49
  }
49
50
  function parseSubworkflows(node) {
@@ -1 +1 @@
1
- {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../src/transpiler/statements.ts"],"names":[],"mappings":"AAEA,OAAO,EASL,QAAQ,EAOR,eAAe,EAEhB,MAAM,iBAAiB,CAAA;AAwDxB,MAAM,WAAW,cAAc;IAE7B,WAAW,CAAC,EAAE,QAAQ,CAAA;IAEtB,cAAc,CAAC,EAAE,QAAQ,CAAA;CAC1B;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,EACT,GAAG,EAAE,cAAc,GAClB,eAAe,EAAE,CAKnB"}
1
+ {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../src/transpiler/statements.ts"],"names":[],"mappings":"AAEA,OAAO,EASL,QAAQ,EAMR,eAAe,EAEhB,MAAM,iBAAiB,CAAA;AAyDxB,MAAM,WAAW,cAAc;IAE7B,WAAW,CAAC,EAAE,QAAQ,CAAA;IAEtB,cAAc,CAAC,EAAE,QAAQ,CAAA;CAC1B;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,EACT,GAAG,EAAE,cAAc,GAClB,eAAe,EAAE,CAKnB"}
@@ -8,7 +8,7 @@ import { transformAST } from './transformations.js';
8
8
  import { assertType } from './asserts.js';
9
9
  import { convertExpression, convertMemberExpression, convertObjectExpression, convertObjectAsExpressionValues, } from './expressions.js';
10
10
  import { blockingFunctions } from './generated/functionMetadata.js';
11
- const { ArrayExpression, ArrowFunctionExpression, AssignmentExpression, BlockStatement, BreakStatement, CallExpression, ContinueStatement, DoWhileStatement, EmptyStatement, ExpressionStatement, ForInStatement, ForOfStatement, FunctionDeclaration, Identifier, IfStatement, LabeledStatement, MemberExpression, ObjectExpression, ReturnStatement, SwitchCase, SwitchStatement, ThrowStatement, TryStatement, TSTypeAliasDeclaration, TSInterfaceDeclaration, VariableDeclaration, VariableDeclarator, WhileStatement, } = AST_NODE_TYPES;
11
+ const { ArrayExpression, ArrowFunctionExpression, AssignmentExpression, BlockStatement, BreakStatement, CallExpression, ContinueStatement, DoWhileStatement, EmptyStatement, ExpressionStatement, ForInStatement, ForOfStatement, FunctionDeclaration, Identifier, IfStatement, LabeledStatement, MemberExpression, ObjectExpression, ReturnStatement, SwitchCase, SwitchStatement, ThrowStatement, TryStatement, TSDeclareFunction, TSTypeAliasDeclaration, TSInterfaceDeclaration, VariableDeclaration, VariableDeclarator, WhileStatement, } = AST_NODE_TYPES;
12
12
  export function parseBlockStatement(node, ctx) {
13
13
  assertType(node, BlockStatement);
14
14
  const body = node.body;
@@ -58,7 +58,8 @@ function parseStep(node, ctx) {
58
58
  throw new WorkflowSyntaxError('Functions must be defined at the top level of a source file', node.loc);
59
59
  case TSInterfaceDeclaration:
60
60
  case TSTypeAliasDeclaration:
61
- // Ignore "type" and "interface" declarations
61
+ case TSDeclareFunction:
62
+ // Ignore "type", "interface" and "declare function"
62
63
  return [];
63
64
  default:
64
65
  throw new WorkflowSyntaxError(`TODO: encountered unsupported type: ${node.type}`, node.loc);
@@ -178,10 +179,12 @@ function callExpressionToStep(node, ctx) {
178
179
  }
179
180
  function callExpressionAssignStep(functionName, argumentsNode) {
180
181
  const argumentExpressions = argumentsNode.map(convertExpression);
181
- const assignments = [
182
- ['', new FunctionInvocationExpression(functionName, argumentExpressions)],
183
- ];
184
- return new AssignStepAST(assignments);
182
+ return new AssignStepAST([
183
+ [
184
+ '__temp',
185
+ new FunctionInvocationExpression(functionName, argumentExpressions),
186
+ ],
187
+ ]);
185
188
  }
186
189
  function callExpressionToCallStep(functionName, argumentsNode) {
187
190
  if (argumentsNode.length < 1 || argumentsNode[0].type !== ObjectExpression) {
@@ -324,7 +327,7 @@ function parseParallelOptions(node) {
324
327
  };
325
328
  }
326
329
  function generalExpressionToAssignStep(node) {
327
- return new AssignStepAST([['', convertExpression(node)]]);
330
+ return new AssignStepAST([['__temp', convertExpression(node)]]);
328
331
  }
329
332
  function returnStatementToReturnStep(node) {
330
333
  assertType(node, ReturnStatement);
@@ -7,7 +7,7 @@ import { WorkflowStepAST } from '../ast/steps.js';
7
7
  */
8
8
  export declare function transformAST(steps: WorkflowStepAST[]): WorkflowStepAST[];
9
9
  /**
10
- * Flatten switch conditions that contain a single next step.
10
+ * Merge a next step to the previous step.
11
11
  *
12
12
  * For example, transforms this:
13
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"transformations.d.ts","sourceRoot":"","sources":["../../src/transpiler/transformations.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAoBxB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAQxE;AA0JD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAEnB"}
1
+ {"version":3,"file":"transformations.d.ts","sourceRoot":"","sources":["../../src/transpiler/transformations.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAuBxB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAUxE;AA0JD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAoBnB"}
@@ -3,6 +3,7 @@ import { InternalTranspilingError } from '../errors.js';
3
3
  import { isRecord } 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
+ const Unmodified = Symbol();
6
7
  /**
7
8
  * Performs various transformations on the AST.
8
9
  *
@@ -10,7 +11,7 @@ import { blockingFunctions } from './generated/functionMetadata.js';
10
11
  * called on each nesting level separately.
11
12
  */
12
13
  export function transformAST(steps) {
13
- return blockingCallsAsCallSteps(flattenPlainNextConditions(combineRetryBlocksToTry(mergeAssignSteps(mapLiteralsAsAssignSteps(steps)))));
14
+ return blockingCallsAsCallSteps(runtimeFunctionImplementation(flattenPlainNextConditions(combineRetryBlocksToTry(mergeAssignSteps(mapLiteralsAsAssignSteps(steps))))));
14
15
  }
15
16
  /**
16
17
  * Merge consecutive assign steps into one assign step
@@ -123,7 +124,7 @@ function parseRetryPolicyNumber(record, keyName) {
123
124
  return primitiveValue;
124
125
  }
125
126
  /**
126
- * Flatten switch conditions that contain a single next step.
127
+ * Merge a next step to the previous step.
127
128
  *
128
129
  * For example, transforms this:
129
130
  *
@@ -141,6 +142,23 @@ function parseRetryPolicyNumber(record, keyName) {
141
142
  * next: target1
142
143
  */
143
144
  export function flattenPlainNextConditions(steps) {
145
+ /*
146
+ const res = steps.reduce((acc: WorkflowStepAST[], step: WorkflowStepAST) => {
147
+ if (acc.length > 0) {
148
+ if (step.tag === 'next') {
149
+ const prev = acc[-1]
150
+
151
+ if (prev.tag === 'assign') {
152
+
153
+ }
154
+
155
+ }
156
+ }
157
+
158
+ return acc
159
+ }, [])
160
+
161
+ */
144
162
  return steps.map((step) => (step.tag === 'switch' ? flattenNext(step) : step));
145
163
  }
146
164
  function flattenNext(step) {
@@ -196,7 +214,6 @@ function createTempVariableGenerator() {
196
214
  const generator = () => `__temp${i++}`;
197
215
  return generator;
198
216
  }
199
- const Unmodified = Symbol();
200
217
  function replaceBlockingCalls(expression, generateName) {
201
218
  function replaceBlockingFunctionInvocations(ex) {
202
219
  if (ex.expressionType === 'functionInvocation') {
@@ -406,13 +423,14 @@ function mapLiteralsAsAssignSteps(steps) {
406
423
  return value.expressionType === 'primitive';
407
424
  });
408
425
  }
409
- else if (current.tag === 'raise') {
426
+ else if (current.tag === 'raise' || current.tag === 'return') {
410
427
  needsTransformation =
411
- !isLiteral(current.value) && includesMapLiteral(current.value);
428
+ current.value !== undefined &&
429
+ includesExtractableMapLiteral(current.value, true);
412
430
  }
413
431
  else if (current.tag === 'call') {
414
432
  if (current.args) {
415
- needsTransformation = Object.values(current.args).some((ex) => !isLiteral(ex) && includesMapLiteral(ex));
433
+ needsTransformation = Object.values(current.args).some((ex) => includesExtractableMapLiteral(ex, true));
416
434
  }
417
435
  }
418
436
  if (needsTransformation) {
@@ -425,20 +443,34 @@ function mapLiteralsAsAssignSteps(steps) {
425
443
  return acc;
426
444
  }, []);
427
445
  }
428
- function includesMapLiteral(ex) {
446
+ // Return true if the string representation of ex would include {}
447
+ function includesExtractableMapLiteral(ex, parentAllowsMaps) {
429
448
  switch (ex.expressionType) {
430
449
  case 'primitive':
431
- return isRecord(ex.value);
450
+ if (isRecord(ex.value)) {
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
+ }
432
462
  case 'binary':
433
- return includesMapLiteral(ex.left) || includesMapLiteral(ex.right);
463
+ return (includesExtractableMapLiteral(ex.left, parentAllowsMaps) ||
464
+ includesExtractableMapLiteral(ex.right, parentAllowsMaps));
434
465
  case 'variableReference':
435
466
  return false;
436
467
  case 'unary':
437
- return includesMapLiteral(ex.value);
468
+ return includesExtractableMapLiteral(ex.value, parentAllowsMaps);
438
469
  case 'functionInvocation':
439
- return ex.arguments.some(includesMapLiteral);
470
+ return ex.arguments.some((x) => includesExtractableMapLiteral(x, false));
440
471
  case 'member':
441
- return includesMapLiteral(ex.object) || includesMapLiteral(ex.property);
472
+ return (includesExtractableMapLiteral(ex.object, false) ||
473
+ includesExtractableMapLiteral(ex.property, false));
442
474
  }
443
475
  }
444
476
  function replaceMapLiterals(expression, generateName) {
@@ -459,3 +491,25 @@ function replaceMapLiterals(expression, generateName) {
459
491
  assignSteps,
460
492
  };
461
493
  }
494
+ /**
495
+ * Replace `Array.isArray(x)` with `get_type(x) == "list"`
496
+ */
497
+ function runtimeFunctionImplementation(steps) {
498
+ return steps.reduce((acc, current) => {
499
+ const transformedSteps = transformStepExpressions(current, (ex) => [
500
+ [],
501
+ transformExpression(ex, replaceIsArray),
502
+ ]);
503
+ acc.push(...transformedSteps);
504
+ return acc;
505
+ }, []);
506
+ }
507
+ function replaceIsArray(ex) {
508
+ if (ex.expressionType === 'functionInvocation' &&
509
+ ex.functionName === 'Array.isArray') {
510
+ return new BinaryExpression(new FunctionInvocationExpression('get_type', ex.arguments), '==', new PrimitiveExpression('list'));
511
+ }
512
+ else {
513
+ return Unmodified;
514
+ }
515
+ }
@@ -2,7 +2,7 @@
2
2
 
3
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
4
 
5
- Functions provided by a Javascript runtime (`console.log`, `setInterval`, etc) are not available.
5
+ Most functions provided by a Javascript runtime (`console.log()`, `setInterval()`, etc) are not available.
6
6
 
7
7
  Type annotations are allowed. Type checking is done by the compiler but the types dont't affect the generated Workflows code.
8
8
 
@@ -22,7 +22,7 @@ Semicolon can be used as optional statement delimitter.
22
22
 
23
23
  ### Array type
24
24
 
25
- ⚠️ Arrays are not objects. In particular, methods like `array.map()` and `array.concat()` are not available.
25
+ ⚠️ Arrays are not objects. In particular, methods like `[].map()` and `[].concat()` are not available.
26
26
 
27
27
  ⚠️ Accessing out-of-bounds index will cause an IndexError at runtime unlike in Typescript where out-of-bounds access would return `undefined`.
28
28
 
@@ -145,7 +145,7 @@ is converted to an [assign step](https://cloud.google.com/workflows/docs/referen
145
145
  - projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
146
146
  ```
147
147
 
148
- This syntax can be used to call [standard library functions](https://cloud.google.com/workflows/docs/reference/stdlib/overview), subworkflows or connectors.
148
+ 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
149
 
150
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
151
 
@@ -175,7 +175,7 @@ main:
175
175
  severity: INFO
176
176
  ```
177
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:
178
+ 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
179
 
180
180
  - To generate a call to `default()` in Workflows code, use the nullish coalescing operator `??`.
181
181
  - To generete a call to `if()` in Workflows code, use the ternary operator `a ? b : c`.
@@ -689,7 +689,19 @@ function read_from_env() {
689
689
 
690
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
691
 
692
- ## Special run-time functions
692
+ ### Runtime functions
693
+
694
+ This section describes the few standard Javascript runtime functions that are available. Most are not.
695
+
696
+ ### Array.isArray()
697
+
698
+ ```typescript
699
+ Array.isArray(arg: any): arg is any[]
700
+ ```
701
+
702
+ Gets converted to the comparison `get_type(arg) == "list"`. Unlike a direct call to `get_type()`, `Array.isArray()` allows the type inference to learn if `arg` is array or not.
703
+
704
+ ## Language extension functions
693
705
 
694
706
  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
707
 
@@ -701,15 +713,18 @@ import {
701
713
  } from 'ts2workflows/types/workflowslib'
702
714
  ```
703
715
 
704
- ### call_step
716
+ ### call_step()
705
717
 
706
718
  ```typescript
707
- function call_step(func: Function, args: Record<string, unknown>): unknown
719
+ function call_step<T, A extends any[]>(
720
+ func: (...args: A) => T,
721
+ arguments: Record<string, unknown>,
722
+ ): T
708
723
  ```
709
724
 
710
725
  The `call_step` function outputs a [call step](https://cloud.google.com/workflows/docs/reference/syntax/calls).
711
726
 
712
- ### parallel
727
+ ### parallel()
713
728
 
714
729
  ```typescript
715
730
  function parallel(
@@ -724,7 +739,7 @@ function parallel(
724
739
 
725
740
  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
741
 
727
- ### retry_policy
742
+ ### retry_policy()
728
743
 
729
744
  ```typescript
730
745
  function retry_policy(
@@ -760,9 +775,9 @@ const var1 = 1 // This is a comment
760
775
 
761
776
  ts2workflows supports only a subset of all Typescript language features. Some examples that are not (yet) supported by ts2workflows:
762
777
 
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.
778
+ - Most 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
779
  - 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.
780
+ - Arrays and maps are not objects. In particular, arrays don't have methods such as `[].push()`, `[].map()`, etc.
766
781
  - Functions (subworkflows) are not first-class objects. Functions can not be assigned to a variable or passed to other functions
767
782
  - Update expressions (`x++` and similar) are not supported
768
783
  - Destructuring (`[a, b] = func()`) is not supported
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts2workflows",
3
- "version": "0.1.0",
3
+ "version": "0.3.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,17 @@
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
+ "*.ts": [
27
+ "prettier --write",
28
+ "eslint"
29
+ ],
30
+ "*.md": [
31
+ "prettier --write"
32
+ ]
23
33
  },
24
34
  "bin": "./dist/cli.js",
25
35
  "files": [
@@ -46,6 +56,8 @@
46
56
  "@typescript-eslint/parser": "^8.0.0",
47
57
  "chai": "^5.1.1",
48
58
  "eslint": "^9.10.0",
59
+ "husky": "^9.1.6",
60
+ "lint-staged": "^15.2.10",
49
61
  "mocha": "^10.4.0",
50
62
  "prettier": "^3.2.5",
51
63
  "rimraf": "^5.0.10",
@@ -161,9 +161,15 @@ export declare namespace http {
161
161
  }
162
162
 
163
163
  export declare namespace json {
164
- function decode(data: bytes | string): object
164
+ function decode(data: bytes | string): unknown
165
165
  function encode(
166
- data: string | number | boolean | unknown[] | Record<string, unknown>,
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: string | number | boolean | unknown[] | Record<string, unknown>,
181
+ data:
182
+ | string
183
+ | number
184
+ | boolean
185
+ | unknown[]
186
+ | Record<string, unknown>
187
+ | null,
176
188
  indent?:
177
189
  | boolean
178
190
  | {
@@ -188,16 +200,19 @@ export declare namespace list {
188
200
  }
189
201
 
190
202
  export declare namespace map {
191
- function _delete<T1>(map: Record<string, T1>, key: string): Record<string, T1>
192
- export function get<T2>(map: Record<string, T2>, keys: string | string[]): T2
193
- export function merge<S1, S2>(
194
- first: Record<string, S1>,
195
- second: Record<string, S2>,
196
- ): Record<string, S1 | S2>
197
- export function merge_nested<S3, S4>(
198
- first: Record<string, S3>,
199
- second: Record<string, S4>,
200
- ): Record<string, S3 | S4>
203
+ function _delete<T>(map: Record<string, T>, key: string): Record<string, T>
204
+ export function get<T, K extends string | string[]>(
205
+ map: Record<string, T>,
206
+ keys: K,
207
+ ): K extends string ? T | null : unknown
208
+ export function merge<T, U>(
209
+ first: Record<string, T>,
210
+ second: Record<string, U>,
211
+ ): Record<string, T | U>
212
+ export function merge_nested<T, U>(
213
+ first: Record<string, T>,
214
+ second: Record<string, U>,
215
+ ): Record<string, T | U>
201
216
  export { _delete as delete }
202
217
  }
203
218
 
@@ -242,7 +257,7 @@ export declare namespace text {
242
257
  index: number
243
258
  match: string
244
259
  }[]
245
- function match_regexp(source: string, regexp: string): boolean
260
+ function match_regex(source: string, regexp: string): boolean
246
261
  function replace_all(source: string, substr: string, repl: string): string
247
262
  function replace_all_regex(
248
263
  source: string,
@@ -708,7 +723,7 @@ export declare function retry_policy(
708
723
  },
709
724
  ): void
710
725
 
711
- export declare function call_step(
712
- func: Function,
726
+ export declare function call_step<T, A extends any[]>(
727
+ func: (...args: A) => T,
713
728
  arguments: Record<string, unknown>,
714
- ): unknown
729
+ ): T