Skip to content

Commit a9632d5

Browse files
committed
Fix node modules not being detected
Closes #1071
1 parent bec1819 commit a9632d5

3 files changed

Lines changed: 63 additions & 5 deletions

File tree

RuriLib.Tests/Functions/Interop/NodeJSTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Jering.Javascript.NodeJS;
22
using System;
33
using System.Collections.Generic;
4+
using System.IO;
45
using System.Linq;
56
using System.Text.Json;
67
using System.Text.RegularExpressions;
@@ -115,4 +116,51 @@ public async Task InvokeNode_NoOutputs_ReturnNothing()
115116
var result = await StaticNodeJSService.InvokeFromStringAsync<JsonElement>(script, null, null, [3, 5], TestCancellationToken);
116117
Assert.Throws<KeyNotFoundException>(() => result.GetProperty("result"));
117118
}
119+
120+
[Fact]
121+
public async Task InvokeNode_WithCreateRequire_ResolvesDependencyFromScriptsNodeModules()
122+
{
123+
var tempRoot = Path.Combine(Path.GetTempPath(), $"{nameof(NodeJsTests)}-{Guid.NewGuid():N}");
124+
var scriptsPath = Path.Combine(tempRoot, "Scripts");
125+
var dependencyPath = Path.Combine(scriptsPath, "node_modules", "ob2-test-dependency");
126+
127+
Directory.CreateDirectory(dependencyPath);
128+
await File.WriteAllTextAsync(
129+
Path.Combine(dependencyPath, "index.js"),
130+
"module.exports = { getValue: () => 'resolved from Scripts/node_modules' };",
131+
TestCancellationToken);
132+
133+
var virtualScriptPath = Path.Combine(scriptsPath, "__ob2_virtual__.js");
134+
var escapedVirtualScriptPath = JsonSerializer.Serialize(virtualScriptPath);
135+
var script = $$"""
136+
module.exports = async () => {
137+
const { createRequire } = require('module');
138+
const obRequire = createRequire({{escapedVirtualScriptPath}});
139+
return await (async (require) => {
140+
const dependency = require('ob2-test-dependency');
141+
var result = dependency.getValue();
142+
var noderesult = {
143+
'result': result,
144+
};
145+
return noderesult;
146+
})(obRequire);
147+
}
148+
""";
149+
150+
try
151+
{
152+
var result = await StaticNodeJSService.InvokeFromStringAsync<JsonElement>(
153+
script,
154+
null,
155+
null,
156+
[],
157+
TestCancellationToken);
158+
159+
Assert.Equal("resolved from Scripts/node_modules", result.GetProperty("result").GetString());
160+
}
161+
finally
162+
{
163+
Directory.Delete(tempRoot, recursive: true);
164+
}
165+
}
118166
}

RuriLib.Tests/Models/Blocks/Custom/ScriptBlockInstanceTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public void ToSyntax_NodeJs_DeclaresOutputsAndSanitizesInputs()
6868
var output = RenderSyntax(block, definedVariables);
6969

7070
Assert.Contains("module.exports = async (DATA,x) => {", output);
71+
Assert.Contains("const { createRequire } = require('module');", output);
72+
Assert.Contains("__ob2_virtual__.js", output);
7173
Assert.Contains("new object[] { input.DATA, x }", output);
7274
Assert.Contains("string result = ", output);
7375
Assert.Contains("result = tmp_", output);
@@ -103,6 +105,8 @@ public void ToSyntax_NodeJs_UsesStableGeneratedShape()
103105
RenderSyntax(block, []));
104106

105107
Assert.Contains("var tmp_TEMP = await InvokeNode<dynamic>(data,", syntax);
108+
Assert.Contains("createRequire", syntax);
109+
Assert.Contains("__ob2_virtual__.js", syntax);
106110
Assert.Contains("new object[] { input.DATA, x }", syntax);
107111
Assert.Contains("string result = tmp_TEMP.GetProperty(\"result\").ToString();", syntax);
108112
}

RuriLib/Models/Blocks/Custom/ScriptBlockInstance.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,19 @@ public override IEnumerable<StatementSyntax> ToSyntax(BlockSyntaxGenerationConte
228228
break;
229229

230230
case Interpreter.NodeJS:
231+
var nodeRequireBasePath = JsonConvert.ToString(
232+
Path.GetFullPath(Path.Combine("Scripts", "__ob2_virtual__.js")));
231233
var nodeScript = $$"""
232234
module.exports = async ({{MakeInputs()}}) => {
233-
{{Script}}
234-
var noderesult = {
235-
{{MakeNodeObject()}}
236-
};
237-
return noderesult;
235+
const { createRequire } = require('module');
236+
const obRequire = createRequire({{nodeRequireBasePath}});
237+
return await (async (require) => {
238+
{{Script}}
239+
var noderesult = {
240+
{{MakeNodeObject()}}
241+
};
242+
return noderesult;
243+
})(obRequire);
238244
}
239245
""";
240246

0 commit comments

Comments
 (0)