Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Update nswag.js
prevent passing through the /runtime arguments to the executable of nswag, because that causes errors in the actual tool.
  • Loading branch information
KaterSchnurz authored Jul 31, 2025
commit f1880b2c12d51094376cba1e9ff688e32a9da4eb
176 changes: 130 additions & 46 deletions src/NSwag.Npm/bin/nswag.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,149 @@ var supportedCoreVersions = [
{ ver: '9.0', dir: "Net90", },
];

const path = require('path');
var c = require('child_process');

// Initialize
process.title = 'nswag';
console.log("NSwag NPM CLI");
var args = process.argv.splice(2, process.argv.length - 2).map(function (a) { return a.indexOf(" ") === -1 ? a : '"' + a + '"' }).join(" ");

let args = process.argv.slice(2);

// Legacy support
args = args.replace("--x86", "/runtime:WinX86");
args = args.replace("/runtime:x86", "/runtime:WinX86");
args = args.replace("--core 8.0", "/runtime:Net80");
args = args.replace("--core 9.0", "/runtime:Net90");
args = args.replace("--core", "/runtime:" + defaultCoreVersion);
args = args.map(arg => arg === '--x86' ? '/runtime:WinX86' : arg);
args = args.map(arg => arg === '--core' ? '/runtime:' + defaultCoreVersion : arg);
args = args.map(arg => arg === '--core 8.0' ? '/runtime:Net80' : arg);
args = args.map(arg => arg === '--core 9.0' ? '/runtime:Net90' : arg);

// Search for full .NET installation
var hasFullDotNet = false;
var fs = require('fs');
if (process.env["windir"]) {
try {
var stats = fs.lstatSync(process.env["windir"] + '/Microsoft.NET');
if (stats.isDirectory())
hasFullDotNet = true;
// Remove /runtime:* parameter from args, but remember its value
let runtimeIndices = [];
let runtimeValue = null;
args.forEach((arg, idx) => {
const match = arg.match(/^\/runtime:(.+)$/i);
if (match) {
runtimeIndices.push(idx);
runtimeValue = match[1];
}
catch (e) {
console.log(e);
});

if (runtimeIndices.length > 1) {
console.error("Error: Multiple /runtime:* arguments detected. Please specify only one. Maybe remove the legacy --core argument?");
process.exit(1);
} else if (runtimeIndices.length === 1) {
args.splice(runtimeIndices[0], 1);
}

if (runtimeValue) {
if (runtimeValue.toLowerCase() === "netcore") {

// detect latest installed NetCore Version
console.log("Trying to detect latest installed NetCore Version.");
var infoCmd = "dotnet";
var infoArgs = ["--version"];

try {
var result = c.spawnSync(infoCmd, infoArgs, { encoding: 'utf8' });
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
throw new Error(result.stderr ? result.stderr.toString() : "Unknown error");
}
var coreVersion = result.stdout.trim();
const version = supportedCoreVersions.find(v => coreVersion.startsWith(v.ver));
if (!version) {
console.error("Error: Detected .NET Core version '" + coreVersion + "' is not supported.");
process.exit(1);
}
console.log("Using supported .NET Core version: " + version.dir);
runtimeValue = version.dir;
} catch (error) {
console.error("Error: Could not detect .NET Core version.");
console.debug(error);
process.exit(1);
}
}

if(!runtimeValue.toLowerCase().startsWith("win")) {
const isSupported = supportedCoreVersions.some(v => v.dir.toLowerCase() === runtimeValue.toLowerCase());
if (!isSupported) {
console.error("Error: Unsupported /runtime: argument '" + runtimeValue + "'.");
process.exit(1);
}
}
}

var c = require('child_process');
if (hasFullDotNet && args.toLowerCase().indexOf("/runtime:win") != -1) {
var hasFullDotNet = false;
if (runtimeValue && runtimeValue.toLowerCase().startsWith("win")) {
// Search for full .NET installation
var fs = require('fs');

if (process.env["windir"]) {

try {
var stats = fs.lstatSync(process.env["windir"] + '/Microsoft.NET');
if (stats.isDirectory())
{
hasFullDotNet = true;
}
}
catch (e) {
console.warn("Could not verify the presence of the full .NET Framework installation.");
}
}
}

let childResult = null;

if (hasFullDotNet && runtimeValue && runtimeValue.toLowerCase().startsWith("win")) {

// Run full .NET version
if (args.toLowerCase().indexOf("/runtime:winx86") != -1) {
var cmd = '"' + __dirname + '/binaries/Win/nswag.x86.exe" ' + args;
var code = c.execSync(cmd, { stdio: [0, 1, 2] });
if (runtimeValue.toLowerCase() === "winx86") {
var exePath = path.join(__dirname, 'binaries', 'Win', 'nswag.x86.exe');
} else {
var cmd = '"' + __dirname + '/binaries/Win/nswag.exe" ' + args;
var code = c.execSync(cmd, { stdio: [0, 1, 2] });
var exePath = path.join(__dirname, 'binaries', 'Win', 'nswag.exe');
}

try {
childResult = c.spawnSync(exePath, args, { stdio: 'inherit' });
} catch (error) {
if (error.status !== undefined) {
process.exit(error.status);
} else {
console.error(error);
process.exit(1);
}
}
} else {
// Run .NET Core version
var defaultCmd = 'dotnet "' + __dirname + '/binaries/' + defaultCoreVersion + '/dotnet-nswag.dll" ' + args;
var infoCmd = "dotnet --version";
c.exec(infoCmd, (error, stdout, _stderr) => {
for (let version of supportedCoreVersions) {
var coreCmd = 'dotnet "' + __dirname + '/binaries/' + version.dir + '/dotnet-nswag.dll" ' + args;

if (args.toLowerCase().indexOf("/runtime:" + version.dir.toLocaleLowerCase()) != -1) {
c.execSync(coreCmd, { stdio: [0, 1, 2] });
return;
} else {
if (!error) {
var coreVersion = stdout;

if (coreVersion.startsWith(version.ver)) {
c.execSync(coreCmd, { stdio: [0, 1, 2] });
return;
}
}
}

// No Runtime specified or full .Net Installation not found, run default command
if (!runtimeValue || runtimeValue.toLowerCase().startsWith("win")) {
runtimeValue = defaultCoreVersion;
}

console.log("Using runtime: " + runtimeValue);

var dllPath = path.join(__dirname, 'binaries', runtimeValue, 'dotnet-nswag.dll');
var spawnArgs = [dllPath].concat(args);

try {
childResult = c.spawnSync('dotnet', spawnArgs, { stdio: 'inherit' });
} catch (error) {
if (typeof error.status === 'number') {
process.exit(error.status);
} else {
console.error(error);
process.exit(1);
}
c.execSync(defaultCmd, { stdio: [0, 1, 2] });
return;
});
}
}

// Exit with the same exit code as the child process
if (childResult && typeof childResult.status === 'number') {
process.exit(childResult.status);
} else if (childResult) {
// If status is undefined, exit with code 1 to indicate an error
process.exit(1);
}
// End of script
Loading