Skip to content

Commit b707ffe

Browse files
author
Dylan Stewart
authored
Merge pull request #25 from NASA-AMMOS/feat/support-promise-async-user-code
[FEAT] Support async user code and automatically await it
2 parents 967f468 + dc0211b commit b707ffe

File tree

2 files changed

+314
-26
lines changed

2 files changed

+314
-26
lines changed

src/UserCodeRunner.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ export class UserCodeRunner {
5656
5757
declare global {
5858
const __args: [${argsTypes.join(', ')}];
59-
let __result: ${outputType};
59+
let __result: ${outputType} | Promise<${outputType}>;
6060
}
6161
__result = defaultExport(...__args);
62+
63+
if ((__result as any) instanceof Promise) {
64+
__result = await __result;
65+
}
6266
`;
6367

6468
const executionSourceFile = ts.createSourceFile(
@@ -442,11 +446,10 @@ export class ExecutionHarnessTypeError extends UserCodeTypeError {
442446
this.diagnostic.messageText = `Default export is not a valid function. Expected a default export function with the signature: "(...args: ${this.argumentTypeNode.getText()}) => ${this.outputTypeNode.getText()}".`;
443447
return;
444448
}
445-
446-
447449
// Errors in the return type of the user code default export
448450
if (
449451
diagnosticNode === this.executionHarnessResultNode
452+
|| diagnosticNode === this.executionHarnessAsyncResultNode
450453
) {
451454
const returnType = callSignature.getReturnType();
452455
const defaultExportedFunctionNodeReturnTypeNode = this.defaultExportedFunctionReturnNode;
@@ -576,17 +579,30 @@ export class ExecutionHarnessTypeError extends UserCodeTypeError {
576579
return binaryExpression.left as ts.Identifier;
577580
}
578581

582+
protected get executionHarnessAsyncResultNode(): ts.Identifier {
583+
const binaryExpression = this.executionHarnessAsyncExpressionStatementNode;
584+
return binaryExpression.left as ts.Identifier;
585+
}
586+
579587
protected get executionHarnessDefaultFunctionCallNode(): ts.CallExpression {
580588
const binaryExpression = this.executionHarnessExpressionStatementNode;
581589
return binaryExpression.right as ts.CallExpression;
582590
}
583591

584592
protected get executionHarnessExpressionStatementNode() {
585593
const executionHarness = this.sources.get(EXECUTION_HARNESS_FILENAME)!;
586-
const expressionStatement = executionHarness.statements.find(
587-
s =>
588-
s.kind === ts.SyntaxKind.ExpressionStatement,
589-
)! as ts.ExpressionStatement;
594+
const expressionStatement = executionHarness.statements.find(ts.isExpressionStatement)!;
595+
return expressionStatement.expression as ts.BinaryExpression;
596+
}
597+
598+
protected get executionHarnessAsyncExpressionStatementNode() {
599+
const executionHarness = this.sources.get(EXECUTION_HARNESS_FILENAME)!;
600+
const ifStatement = executionHarness.statements.find(ts.isIfStatement)!;
601+
602+
const thenStatement = ifStatement.thenStatement as ts.Block;
603+
604+
const expressionStatement = thenStatement.statements.find(ts.isExpressionStatement)!;
605+
590606
return expressionStatement.expression as ts.BinaryExpression;
591607
}
592608

@@ -605,10 +621,7 @@ export class ExecutionHarnessTypeError extends UserCodeTypeError {
605621

606622
protected get globalModuleDeclarationBlock(): ts.ModuleBlock {
607623
const executionHarness = this.sources.get(EXECUTION_HARNESS_FILENAME)!;
608-
const moduleDeclaration = executionHarness.statements.find(
609-
s =>
610-
s.kind === ts.SyntaxKind.ModuleDeclaration,
611-
)! as ts.ModuleDeclaration;
624+
const moduleDeclaration = executionHarness.statements.find(ts.isModuleDeclaration)!;
612625
return moduleDeclaration.body! as ts.ModuleBlock;
613626
}
614627

0 commit comments

Comments
 (0)