From 1639a2997e9df0298b4bdb7e9dcb8e23a6df4f24 Mon Sep 17 00:00:00 2001 From: JeremyTCD Date: Wed, 18 Jan 2023 22:11:31 +0800 Subject: [PATCH] Add support for mjs. --- package-lock.json | 6 + .../Servers/OutOfProcess/Http/Http11Server.ts | 17 +- .../Servers/OutOfProcess/Http/Http20Server.ts | 17 +- .../Servers/OutOfProcess/Http/Shared.ts | 2 +- src/NodeJS/Javascript/tsconfig.json | 5 +- src/NodeJS/Jering.Javascript.NodeJS.csproj | 2 +- src/NodeJS/packages.lock.json | 181 ++++++++++++++++++ ...MultipleFunctionExportECMAScriptModule.mjs | 11 ++ ...mySingleFunctionExportECMAScriptModule.mjs | 6 + .../Http/HttpNodeJSServiceIntegrationTests.cs | 35 +++- 10 files changed, 263 insertions(+), 19 deletions(-) create mode 100644 package-lock.json create mode 100644 test/NodeJS/Javascript/dummyMultipleFunctionExportECMAScriptModule.mjs create mode 100644 test/NodeJS/Javascript/dummySingleFunctionExportECMAScriptModule.mjs diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..82dfa61 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Javascript.NodeJS", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http11Server.ts b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http11Server.ts index b151afd..5bc1ccb 100644 --- a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http11Server.ts +++ b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http11Server.ts @@ -118,7 +118,11 @@ function serverOnRequestListener(req: http.IncomingMessage, res: http.ServerResp } } else if (invocationRequest.moduleSourceType === ModuleSourceType.File) { const resolvedPath = path.resolve(projectDir, invocationRequest.moduleSource); - exports = __non_webpack_require__(resolvedPath); + if (resolvedPath.endsWith('.mjs')) { + exports = await import(/* webpackIgnore: true */ 'file:///' + resolvedPath.replaceAll('\\', '/')); + } else { + exports = __non_webpack_require__(resolvedPath); + } } else { respondWithError(res, `Invalid module source type: ${invocationRequest.moduleSourceType}.`); return; @@ -140,12 +144,13 @@ function serverOnRequestListener(req: http.IncomingMessage, res: http.ServerResp respondWithError(res, `The export named ${invocationRequest.exportName} from module ${getTempIdentifier(invocationRequest)} is not a function.`); return; } - } else { - if (!(typeof exports === 'function')) { - respondWithError(res, `The module ${getTempIdentifier(invocationRequest)} does not export a function.`); - return; - } + } else if (typeof exports === 'function') { functionToInvoke = exports; + } else if (typeof exports.default === 'function') { // .mjs default export + functionToInvoke = exports.default; + } else { + respondWithError(res, `The module ${getTempIdentifier(invocationRequest)} does not export a function.`); + return; } let callbackCalled = false; diff --git a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http20Server.ts b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http20Server.ts index 02baf60..e0a30f4 100644 --- a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http20Server.ts +++ b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Http20Server.ts @@ -104,7 +104,11 @@ function serverOnRequestListener(req: http2.Http2ServerRequest, res: http2.Http2 } } else if (invocationRequest.moduleSourceType === ModuleSourceType.File) { const resolvedPath = path.resolve(projectDir, invocationRequest.moduleSource); - exports = __non_webpack_require__(resolvedPath); + if (resolvedPath.endsWith('.mjs')) { + exports = await import(/* webpackIgnore: true */ 'file:///' + resolvedPath.replaceAll('\\', '/')); + } else { + exports = __non_webpack_require__(resolvedPath); + } } else { respondWithError(res, `Invalid module source type: ${invocationRequest.moduleSourceType}.`); return; @@ -126,12 +130,13 @@ function serverOnRequestListener(req: http2.Http2ServerRequest, res: http2.Http2 respondWithError(res, `The export named ${invocationRequest.exportName} from module ${getTempIdentifier(invocationRequest)} is not a function.`); return; } - } else { - if (!(typeof exports === 'function')) { - respondWithError(res, `The module ${getTempIdentifier(invocationRequest)} does not export a function.`); - return; - } + } else if (typeof exports === 'function') { functionToInvoke = exports; + } else if (typeof exports.default === 'function') { // .mjs default export + functionToInvoke = exports.default; + } else { + respondWithError(res, `The module ${getTempIdentifier(invocationRequest)} does not export a function.`); + return; } let callbackCalled = false; diff --git a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Shared.ts b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Shared.ts index 44daca1..87489a1 100644 --- a/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Shared.ts +++ b/src/NodeJS/Javascript/Servers/OutOfProcess/Http/Shared.ts @@ -1,4 +1,4 @@ -import path = require("path"); +const path = require("path"); import * as http from 'http'; import * as http2 from 'http2'; import InvocationRequest from "../../../InvocationData/InvocationRequest"; diff --git a/src/NodeJS/Javascript/tsconfig.json b/src/NodeJS/Javascript/tsconfig.json index 66b8433..8a4813f 100644 --- a/src/NodeJS/Javascript/tsconfig.json +++ b/src/NodeJS/Javascript/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { - "target": "es6", - "module": "commonjs", + "target": "es2022", + "module": "es2022", + "esModuleInterop": true, "moduleResolution": "node", "typeRoots": [ "node_modules/@types" ], "types": [ "node" ] diff --git a/src/NodeJS/Jering.Javascript.NodeJS.csproj b/src/NodeJS/Jering.Javascript.NodeJS.csproj index 97b18f3..061ba96 100644 --- a/src/NodeJS/Jering.Javascript.NodeJS.csproj +++ b/src/NodeJS/Jering.Javascript.NodeJS.csproj @@ -67,7 +67,7 @@ - + diff --git a/src/NodeJS/packages.lock.json b/src/NodeJS/packages.lock.json index b7d17e7..723e230 100644 --- a/src/NodeJS/packages.lock.json +++ b/src/NodeJS/packages.lock.json @@ -179,6 +179,16 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.1.1", @@ -189,6 +199,16 @@ "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -203,10 +223,25 @@ "resolved": "4.5.4", "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } }, ".NETFramework,Version=v4.6.1": { @@ -422,6 +457,11 @@ "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==" + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -463,6 +503,12 @@ "type": "Transitive", "resolved": "4.5.0", "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } }, ".NETStandard,Version=v2.0": { @@ -681,6 +727,11 @@ "resolved": "1.1.0", "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.1.1", @@ -691,6 +742,16 @@ "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.ComponentModel.Annotations": { "type": "Transitive", "resolved": "5.0.0", @@ -720,6 +781,15 @@ "resolved": "4.5.0", "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", @@ -732,6 +802,12 @@ "dependencies": { "System.Runtime.CompilerServices.Unsafe": "4.5.3" } + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } }, ".NETCoreApp,Version=v5.0": { @@ -912,6 +988,16 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.1.1", @@ -922,6 +1008,16 @@ "resolved": "4.5.1", "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -935,10 +1031,25 @@ "resolved": "4.5.4", "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } }, "net6.0": { @@ -1115,11 +1226,31 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.1.1", "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -1128,10 +1259,25 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } }, "net7.0": { @@ -1308,11 +1454,31 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, "Microsoft.SourceLink.Common": { "type": "Transitive", "resolved": "1.1.1", "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, "System.Diagnostics.DiagnosticSource": { "type": "Transitive", "resolved": "6.0.0", @@ -1321,10 +1487,25 @@ "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", "resolved": "6.0.0", "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "jering.javascript.nodejs.generators": { + "type": "Project", + "dependencies": { + "System.Collections": "[4.3.0, )" + } } } } diff --git a/test/NodeJS/Javascript/dummyMultipleFunctionExportECMAScriptModule.mjs b/test/NodeJS/Javascript/dummyMultipleFunctionExportECMAScriptModule.mjs new file mode 100644 index 0000000..a1ae31c --- /dev/null +++ b/test/NodeJS/Javascript/dummyMultipleFunctionExportECMAScriptModule.mjs @@ -0,0 +1,11 @@ +function add(callback, x, y) { + var result = x + y; + callback(null, result); +} + +function subtract(callback, x, y) { + var result = x - y; + callback(null, result); +} + +export { add, subtract }; \ No newline at end of file diff --git a/test/NodeJS/Javascript/dummySingleFunctionExportECMAScriptModule.mjs b/test/NodeJS/Javascript/dummySingleFunctionExportECMAScriptModule.mjs new file mode 100644 index 0000000..ba2640a --- /dev/null +++ b/test/NodeJS/Javascript/dummySingleFunctionExportECMAScriptModule.mjs @@ -0,0 +1,6 @@ +function dummyFunction(callback, x, y) { + var result = x + y; + callback(null, result); +} + +export default dummyFunction; \ No newline at end of file diff --git a/test/NodeJS/NodeJSServiceImplementations/OutOfProcess/Http/HttpNodeJSServiceIntegrationTests.cs b/test/NodeJS/NodeJSServiceImplementations/OutOfProcess/Http/HttpNodeJSServiceIntegrationTests.cs index efb5780..53692d5 100644 --- a/test/NodeJS/NodeJSServiceImplementations/OutOfProcess/Http/HttpNodeJSServiceIntegrationTests.cs +++ b/test/NodeJS/NodeJSServiceImplementations/OutOfProcess/Http/HttpNodeJSServiceIntegrationTests.cs @@ -23,12 +23,13 @@ namespace Jering.Javascript.NodeJS.Tests public sealed class HttpNodeJSServiceIntegrationTests : IDisposable { // Set to true to break in NodeJS (see CreateHttpNodeJSService) - private const bool DEBUG_NODEJS = false; - // Set to -1 when debugging in NodeJS - private const int TIMEOUT_MS = 60000; + private const bool DEBUG_NODEJS = true; + private const int TIMEOUT_MS = DEBUG_NODEJS ? - 1 : 60000; // Modules private const string DUMMY_RETURNS_ARG_MODULE_FILE = "dummyReturnsArgModule.js"; + private const string DUMMY_SINGLE_FUNCTION_EXPORT_ECMA_SCRIPT_MODULE_FILE = "dummySingleFunctionExportECMAScriptModule.mjs"; + private const string DUMMY_MULTIPLE_FUNCTION_EXPORT_ECMA_SCRIPT_MODULE_FILE = "dummyMultipleFunctionExportECMAScriptModule.mjs"; private const string DUMMY_EXPORTS_MULTIPLE_FUNCTIONS_MODULE_FILE = "dummyExportsMultipleFunctionsModule.js"; private const string DUMMY_CACHE_IDENTIFIER = "dummyCacheIdentifier"; private static readonly string _projectPath = Path.Combine(Directory.GetCurrentDirectory(), "../../../Javascript"); // Current directory is /bin/debug/ @@ -184,6 +185,34 @@ public async void InvokeFromFileAsync_WithoutTypeParameter_IsThreadSafe() Assert.Equal(numThreads, result); } + [Fact(Timeout = TIMEOUT_MS)] + public async void InvokeFromFileAsync_WorksForSingleFunctionExportEcmaScriptModule() + { + // Arrange + HttpNodeJSService testSubject = CreateHttpNodeJSService(projectPath: _projectPath); + + // Act + int result = await testSubject.InvokeFromFileAsync(DUMMY_SINGLE_FUNCTION_EXPORT_ECMA_SCRIPT_MODULE_FILE, args: new object[] {1, 2}).ConfigureAwait(false); + + // Assert + Assert.Equal(3, result); + } + + [Fact(Timeout = TIMEOUT_MS)] + public async void InvokeFromFileAsync_WorksForMultipleFunctionExportEcmaScriptModule() + { + // Arrange + HttpNodeJSService testSubject = CreateHttpNodeJSService(projectPath: _projectPath); + + // Act + int result1 = await testSubject.InvokeFromFileAsync(DUMMY_MULTIPLE_FUNCTION_EXPORT_ECMA_SCRIPT_MODULE_FILE, "subtract", new object[] { 1, 2 }).ConfigureAwait(false); + int result2 = await testSubject.InvokeFromFileAsync(DUMMY_MULTIPLE_FUNCTION_EXPORT_ECMA_SCRIPT_MODULE_FILE, "add", new object[] { 1, 2 }).ConfigureAwait(false); + + // Assert + Assert.Equal(-1, result1); + Assert.Equal(3, result2); + } + [Fact(Timeout = TIMEOUT_MS)] public async void InvokeFromStringAsync_WithTypeParameter_WithRawStringModule_InvokesFromString() {