node-version-use 1.8.5 → 1.9.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.
- package/dist/cjs/worker.js +88 -3
- package/dist/cjs/worker.js.map +1 -1
- package/dist/esm/worker.js +65 -3
- package/dist/esm/worker.js.map +1 -1
- package/package.json +7 -3
package/dist/cjs/worker.js
CHANGED
|
@@ -9,13 +9,24 @@ Object.defineProperty(exports, "default", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
var _crossspawncb = /*#__PURE__*/ _interop_require_default(require("cross-spawn-cb"));
|
|
12
|
+
var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
12
13
|
var _noderesolveversions = /*#__PURE__*/ _interop_require_default(require("node-resolve-versions"));
|
|
13
14
|
var _nodeversionutils = require("node-version-utils");
|
|
15
|
+
var _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
14
16
|
var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
|
|
17
|
+
var _resolvebinsync = /*#__PURE__*/ _interop_require_default(require("resolve-bin-sync"));
|
|
15
18
|
var _spawnstreaming = /*#__PURE__*/ _interop_require_default(require("spawn-streaming"));
|
|
16
19
|
var _constantsts = require("./constants.js");
|
|
17
20
|
var _loadNodeVersionInstallts = /*#__PURE__*/ _interop_require_default(require("./lib/loadNodeVersionInstall.js"));
|
|
18
21
|
var _loadSpawnTermts = /*#__PURE__*/ _interop_require_default(require("./lib/loadSpawnTerm.js"));
|
|
22
|
+
function _array_like_to_array(arr, len) {
|
|
23
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
24
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
25
|
+
return arr2;
|
|
26
|
+
}
|
|
27
|
+
function _array_without_holes(arr) {
|
|
28
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
29
|
+
}
|
|
19
30
|
function _define_property(obj, key, value) {
|
|
20
31
|
if (key in obj) {
|
|
21
32
|
Object.defineProperty(obj, key, {
|
|
@@ -34,6 +45,12 @@ function _interop_require_default(obj) {
|
|
|
34
45
|
default: obj
|
|
35
46
|
};
|
|
36
47
|
}
|
|
48
|
+
function _iterable_to_array(iter) {
|
|
49
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
50
|
+
}
|
|
51
|
+
function _non_iterable_spread() {
|
|
52
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
53
|
+
}
|
|
37
54
|
function _object_spread(target) {
|
|
38
55
|
for(var i = 1; i < arguments.length; i++){
|
|
39
56
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
@@ -49,6 +66,72 @@ function _object_spread(target) {
|
|
|
49
66
|
}
|
|
50
67
|
return target;
|
|
51
68
|
}
|
|
69
|
+
function _to_consumable_array(arr) {
|
|
70
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
71
|
+
}
|
|
72
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
73
|
+
if (!o) return;
|
|
74
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
75
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
76
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
77
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
78
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
79
|
+
}
|
|
80
|
+
var isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);
|
|
81
|
+
var NODE = isWindows ? 'node.exe' : 'node';
|
|
82
|
+
// Parse npm-generated .cmd wrapper to extract the JS script path
|
|
83
|
+
function parseNpmCmdWrapper(cmdPath) {
|
|
84
|
+
try {
|
|
85
|
+
var content = _fs.default.readFileSync(cmdPath, 'utf8');
|
|
86
|
+
// Match: "%_prog%" "%dp0%\node_modules\...\cli.js" %*
|
|
87
|
+
// or: "%_prog%" "%dp0%\path\to\script.js" %*
|
|
88
|
+
var match = content.match(/"%_prog%"\s+"?%dp0%\\([^"]+)"?\s+%\*/);
|
|
89
|
+
if (match) {
|
|
90
|
+
var relativePath = match[1];
|
|
91
|
+
var cmdDir = _path.default.dirname(cmdPath);
|
|
92
|
+
return _path.default.join(cmdDir, relativePath);
|
|
93
|
+
}
|
|
94
|
+
} catch (_e) {
|
|
95
|
+
// ignore
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
// On Windows, resolve npm bin commands to their JS entry points to bypass .cmd wrappers
|
|
100
|
+
// This fixes issues with nvm-windows where .cmd wrappers use symlinked node.exe directly
|
|
101
|
+
function resolveCommand(command, args) {
|
|
102
|
+
if (!isWindows) return {
|
|
103
|
+
command: command,
|
|
104
|
+
args: args
|
|
105
|
+
};
|
|
106
|
+
// Case 1: Command is a .cmd file path
|
|
107
|
+
if (command.toLowerCase().endsWith('.cmd')) {
|
|
108
|
+
var scriptPath = parseNpmCmdWrapper(command);
|
|
109
|
+
if (scriptPath) {
|
|
110
|
+
return {
|
|
111
|
+
command: NODE,
|
|
112
|
+
args: [
|
|
113
|
+
scriptPath
|
|
114
|
+
].concat(_to_consumable_array(args))
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Case 2: Try to resolve the command as an npm package bin from node_modules
|
|
119
|
+
try {
|
|
120
|
+
var binPath = (0, _resolvebinsync.default)(command);
|
|
121
|
+
return {
|
|
122
|
+
command: NODE,
|
|
123
|
+
args: [
|
|
124
|
+
binPath
|
|
125
|
+
].concat(_to_consumable_array(args))
|
|
126
|
+
};
|
|
127
|
+
} catch (_e) {
|
|
128
|
+
// Not an npm package bin, use original command
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
command: command,
|
|
132
|
+
args: args
|
|
133
|
+
};
|
|
134
|
+
}
|
|
52
135
|
function worker(versionExpression, command, args, options, callback) {
|
|
53
136
|
// Load lazy dependencies in parallel
|
|
54
137
|
var loaderQueue = new _queuecb.default();
|
|
@@ -120,12 +203,14 @@ function worker(versionExpression, command, args, options, callback) {
|
|
|
120
203
|
}
|
|
121
204
|
var spawnOptions = (0, _nodeversionutils.spawnOptions)(install.installPath, options);
|
|
122
205
|
var prefix = install.version;
|
|
123
|
-
|
|
124
|
-
|
|
206
|
+
// On Windows, resolve npm bin commands to bypass .cmd wrappers
|
|
207
|
+
var resolved = resolveCommand(command, args);
|
|
208
|
+
if (versions.length < 2) return (0, _crossspawncb.default)(resolved.command, resolved.args, spawnOptions, next);
|
|
209
|
+
if (session) session.spawn(resolved.command, resolved.args, spawnOptions, {
|
|
125
210
|
group: prefix,
|
|
126
211
|
expanded: streamingOptions.expanded
|
|
127
212
|
}, next);
|
|
128
|
-
else (0, _spawnstreaming.default)(command, args, spawnOptions, {
|
|
213
|
+
else (0, _spawnstreaming.default)(resolved.command, resolved.args, spawnOptions, {
|
|
129
214
|
prefix: prefix
|
|
130
215
|
}, next);
|
|
131
216
|
});
|
package/dist/cjs/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/worker.ts"],"sourcesContent":["import spawn, { type SpawnOptions } from 'cross-spawn-cb';\nimport resolveVersions, { type VersionOptions } from 'node-resolve-versions';\nimport type { InstallOptions, InstallResult } from 'node-version-install';\nimport { spawnOptions as createSpawnOptions } from 'node-version-utils';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { storagePath } from './constants.ts';\nimport loadNodeVersionInstall from './lib/loadNodeVersionInstall.ts';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\n\nimport type { Options, UseCallback, UseOptions, UseResult } from './types.ts';\n\nexport default function worker(versionExpression: string, command: string, args: string[], options: UseOptions, callback: UseCallback): undefined {\n // Load lazy dependencies in parallel\n const loaderQueue = new Queue();\n let installVersion: (version: string, opts: InstallOptions, cb: (err?: Error, results?: InstallResult[]) => void) => void;\n let createSession:\n | ((options?: { header?: string; showStatusBar?: boolean; interactive?: boolean }) => {\n spawn: (command: string, args: string[], options: unknown, termOptions: unknown, callback: (err?: Error, res?: unknown) => void) => void;\n close: () => void;\n waitAndClose: (callback?: () => void) => void;\n })\n | undefined;\n\n loaderQueue.defer((cb) =>\n loadNodeVersionInstall((err, fn) => {\n installVersion = fn;\n cb(err);\n })\n );\n loaderQueue.defer((cb) =>\n loadSpawnTerm((err, mod) => {\n createSession = mod?.createSession;\n cb(err);\n })\n );\n\n loaderQueue.await((loadErr) => {\n if (loadErr) return callback(loadErr);\n\n resolveVersions(versionExpression, options as VersionOptions, (err?: Error, versions?: string[]) => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`No versions found from expression: ${versionExpression}`));\n return;\n }\n\n const installOptions = { storagePath, ...options } as InstallOptions;\n const streamingOptions = options as Options;\n const results: UseResult[] = [];\n const queue = new Queue(1);\n\n // Create session once for all processes (only if multiple versions)\n const interactive = options.interactive !== false;\n const session = versions.length >= 2 && createSession && !streamingOptions.streaming ? createSession({ header: `${command} ${args.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n versions.forEach((version: string) => {\n queue.defer((cb) => {\n installVersion(version, installOptions, (_err, installs) => {\n const install = installs && installs.length === 1 ? installs[0] : null;\n if (!install) {\n results.push({ install, command, version, error: new Error(`Unexpected version results for version ${version}. Install ${JSON.stringify(installs)}`), result: null });\n return callback();\n }\n const spawnOptions = createSpawnOptions(install.installPath, options as SpawnOptions);\n const prefix = install.version;\n\n function next(err?, res?): undefined {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err;\n err = null;\n }\n results.push({ install, command, version, error: err, result: res });\n cb();\n }\n\n if (versions.length < 2) return spawn(command, args, spawnOptions, next);\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: streamingOptions.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n });\n queue.await((err) => {\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n });\n });\n });\n}\n"],"names":["worker","versionExpression","command","args","options","callback","loaderQueue","Queue","installVersion","createSession","defer","cb","loadNodeVersionInstall","err","fn","loadSpawnTerm","mod","await","loadErr","resolveVersions","versions","length","Error","installOptions","storagePath","streamingOptions","results","queue","interactive","session","streaming","header","join","showStatusBar","forEach","version","_err","installs","next","res","message","indexOf","push","install","error","result","JSON","stringify","spawnOptions","createSpawnOptions","installPath","prefix","spawn","group","expanded","spawnStreaming","waitAndClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/worker.ts"],"sourcesContent":["import spawn, { type SpawnOptions } from 'cross-spawn-cb';\nimport fs from 'fs';\nimport resolveVersions, { type VersionOptions } from 'node-resolve-versions';\nimport type { InstallOptions, InstallResult } from 'node-version-install';\nimport { spawnOptions as createSpawnOptions } from 'node-version-utils';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport resolveBin from 'resolve-bin-sync';\nimport spawnStreaming from 'spawn-streaming';\nimport { storagePath } from './constants.ts';\nimport loadNodeVersionInstall from './lib/loadNodeVersionInstall.ts';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\n\nimport type { Options, UseCallback, UseOptions, UseResult } from './types.ts';\n\nconst isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\nconst NODE = isWindows ? 'node.exe' : 'node';\n\n// Parse npm-generated .cmd wrapper to extract the JS script path\nfunction parseNpmCmdWrapper(cmdPath: string): string | null {\n try {\n const content = fs.readFileSync(cmdPath, 'utf8');\n // Match: \"%_prog%\" \"%dp0%\\node_modules\\...\\cli.js\" %*\n // or: \"%_prog%\" \"%dp0%\\path\\to\\script.js\" %*\n const match = content.match(/\"%_prog%\"\\s+\"?%dp0%\\\\([^\"]+)\"?\\s+%\\*/);\n if (match) {\n const relativePath = match[1];\n const cmdDir = path.dirname(cmdPath);\n return path.join(cmdDir, relativePath);\n }\n } catch (_e) {\n // ignore\n }\n return null;\n}\n\n// On Windows, resolve npm bin commands to their JS entry points to bypass .cmd wrappers\n// This fixes issues with nvm-windows where .cmd wrappers use symlinked node.exe directly\nfunction resolveCommand(command: string, args: string[]): { command: string; args: string[] } {\n if (!isWindows) return { command, args };\n\n // Case 1: Command is a .cmd file path\n if (command.toLowerCase().endsWith('.cmd')) {\n const scriptPath = parseNpmCmdWrapper(command);\n if (scriptPath) {\n return { command: NODE, args: [scriptPath, ...args] };\n }\n }\n\n // Case 2: Try to resolve the command as an npm package bin from node_modules\n try {\n const binPath = resolveBin(command);\n return { command: NODE, args: [binPath, ...args] };\n } catch (_e) {\n // Not an npm package bin, use original command\n }\n\n return { command, args };\n}\n\nexport default function worker(versionExpression: string, command: string, args: string[], options: UseOptions, callback: UseCallback): undefined {\n // Load lazy dependencies in parallel\n const loaderQueue = new Queue();\n let installVersion: (version: string, opts: InstallOptions, cb: (err?: Error, results?: InstallResult[]) => void) => void;\n let createSession:\n | ((options?: { header?: string; showStatusBar?: boolean; interactive?: boolean }) => {\n spawn: (command: string, args: string[], options: unknown, termOptions: unknown, callback: (err?: Error, res?: unknown) => void) => void;\n close: () => void;\n waitAndClose: (callback?: () => void) => void;\n })\n | undefined;\n\n loaderQueue.defer((cb) =>\n loadNodeVersionInstall((err, fn) => {\n installVersion = fn;\n cb(err);\n })\n );\n loaderQueue.defer((cb) =>\n loadSpawnTerm((err, mod) => {\n createSession = mod?.createSession;\n cb(err);\n })\n );\n\n loaderQueue.await((loadErr) => {\n if (loadErr) return callback(loadErr);\n\n resolveVersions(versionExpression, options as VersionOptions, (err?: Error, versions?: string[]) => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`No versions found from expression: ${versionExpression}`));\n return;\n }\n\n const installOptions = { storagePath, ...options } as InstallOptions;\n const streamingOptions = options as Options;\n const results: UseResult[] = [];\n const queue = new Queue(1);\n\n // Create session once for all processes (only if multiple versions)\n const interactive = options.interactive !== false;\n const session = versions.length >= 2 && createSession && !streamingOptions.streaming ? createSession({ header: `${command} ${args.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n versions.forEach((version: string) => {\n queue.defer((cb) => {\n installVersion(version, installOptions, (_err, installs) => {\n const install = installs && installs.length === 1 ? installs[0] : null;\n if (!install) {\n results.push({ install, command, version, error: new Error(`Unexpected version results for version ${version}. Install ${JSON.stringify(installs)}`), result: null });\n return callback();\n }\n const spawnOptions = createSpawnOptions(install.installPath, options as SpawnOptions);\n const prefix = install.version;\n\n function next(err?, res?): undefined {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err;\n err = null;\n }\n results.push({ install, command, version, error: err, result: res });\n cb();\n }\n\n // On Windows, resolve npm bin commands to bypass .cmd wrappers\n const resolved = resolveCommand(command, args);\n\n if (versions.length < 2) return spawn(resolved.command, resolved.args, spawnOptions, next);\n if (session) session.spawn(resolved.command, resolved.args, spawnOptions, { group: prefix, expanded: streamingOptions.expanded }, next);\n else spawnStreaming(resolved.command, resolved.args, spawnOptions, { prefix }, next);\n });\n });\n });\n queue.await((err) => {\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n });\n });\n });\n}\n"],"names":["worker","isWindows","process","platform","test","env","OSTYPE","NODE","parseNpmCmdWrapper","cmdPath","content","fs","readFileSync","match","relativePath","cmdDir","path","dirname","join","_e","resolveCommand","command","args","toLowerCase","endsWith","scriptPath","binPath","resolveBin","versionExpression","options","callback","loaderQueue","Queue","installVersion","createSession","defer","cb","loadNodeVersionInstall","err","fn","loadSpawnTerm","mod","await","loadErr","resolveVersions","versions","length","Error","installOptions","storagePath","streamingOptions","results","queue","interactive","session","streaming","header","showStatusBar","forEach","version","_err","installs","next","res","message","indexOf","push","install","error","result","JSON","stringify","spawnOptions","createSpawnOptions","installPath","prefix","resolved","spawn","group","expanded","spawnStreaming","waitAndClose"],"mappings":"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"}
|
package/dist/esm/worker.js
CHANGED
|
@@ -1,11 +1,71 @@
|
|
|
1
1
|
import spawn from 'cross-spawn-cb';
|
|
2
|
+
import fs from 'fs';
|
|
2
3
|
import resolveVersions from 'node-resolve-versions';
|
|
3
4
|
import { spawnOptions as createSpawnOptions } from 'node-version-utils';
|
|
5
|
+
import path from 'path';
|
|
4
6
|
import Queue from 'queue-cb';
|
|
7
|
+
import resolveBin from 'resolve-bin-sync';
|
|
5
8
|
import spawnStreaming from 'spawn-streaming';
|
|
6
9
|
import { storagePath } from './constants.js';
|
|
7
10
|
import loadNodeVersionInstall from './lib/loadNodeVersionInstall.js';
|
|
8
11
|
import loadSpawnTerm from './lib/loadSpawnTerm.js';
|
|
12
|
+
const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);
|
|
13
|
+
const NODE = isWindows ? 'node.exe' : 'node';
|
|
14
|
+
// Parse npm-generated .cmd wrapper to extract the JS script path
|
|
15
|
+
function parseNpmCmdWrapper(cmdPath) {
|
|
16
|
+
try {
|
|
17
|
+
const content = fs.readFileSync(cmdPath, 'utf8');
|
|
18
|
+
// Match: "%_prog%" "%dp0%\node_modules\...\cli.js" %*
|
|
19
|
+
// or: "%_prog%" "%dp0%\path\to\script.js" %*
|
|
20
|
+
const match = content.match(/"%_prog%"\s+"?%dp0%\\([^"]+)"?\s+%\*/);
|
|
21
|
+
if (match) {
|
|
22
|
+
const relativePath = match[1];
|
|
23
|
+
const cmdDir = path.dirname(cmdPath);
|
|
24
|
+
return path.join(cmdDir, relativePath);
|
|
25
|
+
}
|
|
26
|
+
} catch (_e) {
|
|
27
|
+
// ignore
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
// On Windows, resolve npm bin commands to their JS entry points to bypass .cmd wrappers
|
|
32
|
+
// This fixes issues with nvm-windows where .cmd wrappers use symlinked node.exe directly
|
|
33
|
+
function resolveCommand(command, args) {
|
|
34
|
+
if (!isWindows) return {
|
|
35
|
+
command,
|
|
36
|
+
args
|
|
37
|
+
};
|
|
38
|
+
// Case 1: Command is a .cmd file path
|
|
39
|
+
if (command.toLowerCase().endsWith('.cmd')) {
|
|
40
|
+
const scriptPath = parseNpmCmdWrapper(command);
|
|
41
|
+
if (scriptPath) {
|
|
42
|
+
return {
|
|
43
|
+
command: NODE,
|
|
44
|
+
args: [
|
|
45
|
+
scriptPath,
|
|
46
|
+
...args
|
|
47
|
+
]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Case 2: Try to resolve the command as an npm package bin from node_modules
|
|
52
|
+
try {
|
|
53
|
+
const binPath = resolveBin(command);
|
|
54
|
+
return {
|
|
55
|
+
command: NODE,
|
|
56
|
+
args: [
|
|
57
|
+
binPath,
|
|
58
|
+
...args
|
|
59
|
+
]
|
|
60
|
+
};
|
|
61
|
+
} catch (_e) {
|
|
62
|
+
// Not an npm package bin, use original command
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
command,
|
|
66
|
+
args
|
|
67
|
+
};
|
|
68
|
+
}
|
|
9
69
|
export default function worker(versionExpression, command, args, options, callback) {
|
|
10
70
|
// Load lazy dependencies in parallel
|
|
11
71
|
const loaderQueue = new Queue();
|
|
@@ -74,12 +134,14 @@ export default function worker(versionExpression, command, args, options, callba
|
|
|
74
134
|
});
|
|
75
135
|
cb();
|
|
76
136
|
}
|
|
77
|
-
|
|
78
|
-
|
|
137
|
+
// On Windows, resolve npm bin commands to bypass .cmd wrappers
|
|
138
|
+
const resolved = resolveCommand(command, args);
|
|
139
|
+
if (versions.length < 2) return spawn(resolved.command, resolved.args, spawnOptions, next);
|
|
140
|
+
if (session) session.spawn(resolved.command, resolved.args, spawnOptions, {
|
|
79
141
|
group: prefix,
|
|
80
142
|
expanded: streamingOptions.expanded
|
|
81
143
|
}, next);
|
|
82
|
-
else spawnStreaming(command, args, spawnOptions, {
|
|
144
|
+
else spawnStreaming(resolved.command, resolved.args, spawnOptions, {
|
|
83
145
|
prefix
|
|
84
146
|
}, next);
|
|
85
147
|
});
|
package/dist/esm/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/worker.ts"],"sourcesContent":["import spawn, { type SpawnOptions } from 'cross-spawn-cb';\nimport resolveVersions, { type VersionOptions } from 'node-resolve-versions';\nimport type { InstallOptions, InstallResult } from 'node-version-install';\nimport { spawnOptions as createSpawnOptions } from 'node-version-utils';\nimport Queue from 'queue-cb';\nimport spawnStreaming from 'spawn-streaming';\nimport { storagePath } from './constants.ts';\nimport loadNodeVersionInstall from './lib/loadNodeVersionInstall.ts';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\n\nimport type { Options, UseCallback, UseOptions, UseResult } from './types.ts';\n\nexport default function worker(versionExpression: string, command: string, args: string[], options: UseOptions, callback: UseCallback): undefined {\n // Load lazy dependencies in parallel\n const loaderQueue = new Queue();\n let installVersion: (version: string, opts: InstallOptions, cb: (err?: Error, results?: InstallResult[]) => void) => void;\n let createSession:\n | ((options?: { header?: string; showStatusBar?: boolean; interactive?: boolean }) => {\n spawn: (command: string, args: string[], options: unknown, termOptions: unknown, callback: (err?: Error, res?: unknown) => void) => void;\n close: () => void;\n waitAndClose: (callback?: () => void) => void;\n })\n | undefined;\n\n loaderQueue.defer((cb) =>\n loadNodeVersionInstall((err, fn) => {\n installVersion = fn;\n cb(err);\n })\n );\n loaderQueue.defer((cb) =>\n loadSpawnTerm((err, mod) => {\n createSession = mod?.createSession;\n cb(err);\n })\n );\n\n loaderQueue.await((loadErr) => {\n if (loadErr) return callback(loadErr);\n\n resolveVersions(versionExpression, options as VersionOptions, (err?: Error, versions?: string[]) => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`No versions found from expression: ${versionExpression}`));\n return;\n }\n\n const installOptions = { storagePath, ...options } as InstallOptions;\n const streamingOptions = options as Options;\n const results: UseResult[] = [];\n const queue = new Queue(1);\n\n // Create session once for all processes (only if multiple versions)\n const interactive = options.interactive !== false;\n const session = versions.length >= 2 && createSession && !streamingOptions.streaming ? createSession({ header: `${command} ${args.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n versions.forEach((version: string) => {\n queue.defer((cb) => {\n installVersion(version, installOptions, (_err, installs) => {\n const install = installs && installs.length === 1 ? installs[0] : null;\n if (!install) {\n results.push({ install, command, version, error: new Error(`Unexpected version results for version ${version}. Install ${JSON.stringify(installs)}`), result: null });\n return callback();\n }\n const spawnOptions = createSpawnOptions(install.installPath, options as SpawnOptions);\n const prefix = install.version;\n\n function next(err?, res?): undefined {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err;\n err = null;\n }\n results.push({ install, command, version, error: err, result: res });\n cb();\n }\n\n if (versions.length < 2) return spawn(command, args, spawnOptions, next);\n if (session) session.spawn(command, args, spawnOptions, { group: prefix, expanded: streamingOptions.expanded }, next);\n else spawnStreaming(command, args, spawnOptions, { prefix }, next);\n });\n });\n });\n queue.await((err) => {\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n });\n });\n });\n}\n"],"names":["spawn","resolveVersions","spawnOptions","createSpawnOptions","Queue","spawnStreaming","storagePath","loadNodeVersionInstall","loadSpawnTerm","worker","versionExpression","command","args","options","callback","loaderQueue","installVersion","createSession","defer","cb","err","fn","mod","await","loadErr","versions","length","Error","installOptions","streamingOptions","results","queue","interactive","session","streaming","header","join","showStatusBar","forEach","version","_err","installs","install","push","error","JSON","stringify","result","installPath","prefix","next","res","message","indexOf","group","expanded","waitAndClose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/worker.ts"],"sourcesContent":["import spawn, { type SpawnOptions } from 'cross-spawn-cb';\nimport fs from 'fs';\nimport resolveVersions, { type VersionOptions } from 'node-resolve-versions';\nimport type { InstallOptions, InstallResult } from 'node-version-install';\nimport { spawnOptions as createSpawnOptions } from 'node-version-utils';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport resolveBin from 'resolve-bin-sync';\nimport spawnStreaming from 'spawn-streaming';\nimport { storagePath } from './constants.ts';\nimport loadNodeVersionInstall from './lib/loadNodeVersionInstall.ts';\nimport loadSpawnTerm from './lib/loadSpawnTerm.ts';\n\nimport type { Options, UseCallback, UseOptions, UseResult } from './types.ts';\n\nconst isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE);\nconst NODE = isWindows ? 'node.exe' : 'node';\n\n// Parse npm-generated .cmd wrapper to extract the JS script path\nfunction parseNpmCmdWrapper(cmdPath: string): string | null {\n try {\n const content = fs.readFileSync(cmdPath, 'utf8');\n // Match: \"%_prog%\" \"%dp0%\\node_modules\\...\\cli.js\" %*\n // or: \"%_prog%\" \"%dp0%\\path\\to\\script.js\" %*\n const match = content.match(/\"%_prog%\"\\s+\"?%dp0%\\\\([^\"]+)\"?\\s+%\\*/);\n if (match) {\n const relativePath = match[1];\n const cmdDir = path.dirname(cmdPath);\n return path.join(cmdDir, relativePath);\n }\n } catch (_e) {\n // ignore\n }\n return null;\n}\n\n// On Windows, resolve npm bin commands to their JS entry points to bypass .cmd wrappers\n// This fixes issues with nvm-windows where .cmd wrappers use symlinked node.exe directly\nfunction resolveCommand(command: string, args: string[]): { command: string; args: string[] } {\n if (!isWindows) return { command, args };\n\n // Case 1: Command is a .cmd file path\n if (command.toLowerCase().endsWith('.cmd')) {\n const scriptPath = parseNpmCmdWrapper(command);\n if (scriptPath) {\n return { command: NODE, args: [scriptPath, ...args] };\n }\n }\n\n // Case 2: Try to resolve the command as an npm package bin from node_modules\n try {\n const binPath = resolveBin(command);\n return { command: NODE, args: [binPath, ...args] };\n } catch (_e) {\n // Not an npm package bin, use original command\n }\n\n return { command, args };\n}\n\nexport default function worker(versionExpression: string, command: string, args: string[], options: UseOptions, callback: UseCallback): undefined {\n // Load lazy dependencies in parallel\n const loaderQueue = new Queue();\n let installVersion: (version: string, opts: InstallOptions, cb: (err?: Error, results?: InstallResult[]) => void) => void;\n let createSession:\n | ((options?: { header?: string; showStatusBar?: boolean; interactive?: boolean }) => {\n spawn: (command: string, args: string[], options: unknown, termOptions: unknown, callback: (err?: Error, res?: unknown) => void) => void;\n close: () => void;\n waitAndClose: (callback?: () => void) => void;\n })\n | undefined;\n\n loaderQueue.defer((cb) =>\n loadNodeVersionInstall((err, fn) => {\n installVersion = fn;\n cb(err);\n })\n );\n loaderQueue.defer((cb) =>\n loadSpawnTerm((err, mod) => {\n createSession = mod?.createSession;\n cb(err);\n })\n );\n\n loaderQueue.await((loadErr) => {\n if (loadErr) return callback(loadErr);\n\n resolveVersions(versionExpression, options as VersionOptions, (err?: Error, versions?: string[]) => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`No versions found from expression: ${versionExpression}`));\n return;\n }\n\n const installOptions = { storagePath, ...options } as InstallOptions;\n const streamingOptions = options as Options;\n const results: UseResult[] = [];\n const queue = new Queue(1);\n\n // Create session once for all processes (only if multiple versions)\n const interactive = options.interactive !== false;\n const session = versions.length >= 2 && createSession && !streamingOptions.streaming ? createSession({ header: `${command} ${args.join(' ')}`, showStatusBar: true, interactive }) : null;\n\n versions.forEach((version: string) => {\n queue.defer((cb) => {\n installVersion(version, installOptions, (_err, installs) => {\n const install = installs && installs.length === 1 ? installs[0] : null;\n if (!install) {\n results.push({ install, command, version, error: new Error(`Unexpected version results for version ${version}. Install ${JSON.stringify(installs)}`), result: null });\n return callback();\n }\n const spawnOptions = createSpawnOptions(install.installPath, options as SpawnOptions);\n const prefix = install.version;\n\n function next(err?, res?): undefined {\n if (err && err.message.indexOf('ExperimentalWarning') >= 0) {\n res = err;\n err = null;\n }\n results.push({ install, command, version, error: err, result: res });\n cb();\n }\n\n // On Windows, resolve npm bin commands to bypass .cmd wrappers\n const resolved = resolveCommand(command, args);\n\n if (versions.length < 2) return spawn(resolved.command, resolved.args, spawnOptions, next);\n if (session) session.spawn(resolved.command, resolved.args, spawnOptions, { group: prefix, expanded: streamingOptions.expanded }, next);\n else spawnStreaming(resolved.command, resolved.args, spawnOptions, { prefix }, next);\n });\n });\n });\n queue.await((err) => {\n if (session) {\n session.waitAndClose(() => {\n err ? callback(err) : callback(null, results);\n });\n } else {\n err ? callback(err) : callback(null, results);\n }\n });\n });\n });\n}\n"],"names":["spawn","fs","resolveVersions","spawnOptions","createSpawnOptions","path","Queue","resolveBin","spawnStreaming","storagePath","loadNodeVersionInstall","loadSpawnTerm","isWindows","process","platform","test","env","OSTYPE","NODE","parseNpmCmdWrapper","cmdPath","content","readFileSync","match","relativePath","cmdDir","dirname","join","_e","resolveCommand","command","args","toLowerCase","endsWith","scriptPath","binPath","worker","versionExpression","options","callback","loaderQueue","installVersion","createSession","defer","cb","err","fn","mod","await","loadErr","versions","length","Error","installOptions","streamingOptions","results","queue","interactive","session","streaming","header","showStatusBar","forEach","version","_err","installs","install","push","error","JSON","stringify","result","installPath","prefix","next","res","message","indexOf","resolved","group","expanded","waitAndClose"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-version-use",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Cross-platform solution for using multiple versions of node. Useful for compatibility testing",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"build": "tsds build",
|
|
38
38
|
"format": "biome check --write --unsafe",
|
|
39
39
|
"prepublishOnly": "tsds validate",
|
|
40
|
-
"test": "
|
|
40
|
+
"test": "tsds test:node --no-timeouts",
|
|
41
41
|
"test:engines": "nvu engines tsds test:node --no-timeouts",
|
|
42
42
|
"version": "tsds version"
|
|
43
43
|
},
|
|
@@ -50,16 +50,20 @@
|
|
|
50
50
|
"node-resolve-versions": "*",
|
|
51
51
|
"node-version-utils": "*",
|
|
52
52
|
"queue-cb": "*",
|
|
53
|
+
"resolve-bin-sync": "^1.0.7",
|
|
53
54
|
"spawn-streaming": "*"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
57
|
+
"@biomejs/biome": "*",
|
|
56
58
|
"@types/mocha": "*",
|
|
57
59
|
"@types/node": "*",
|
|
58
60
|
"cr": "*",
|
|
59
61
|
"is-version": "*",
|
|
60
62
|
"node-version-install": "*",
|
|
63
|
+
"node-version-use": "*",
|
|
61
64
|
"pinkie-promise": "*",
|
|
62
|
-
"rimraf2": "*"
|
|
65
|
+
"rimraf2": "*",
|
|
66
|
+
"ts-dev-stack": "*"
|
|
63
67
|
},
|
|
64
68
|
"engines": {
|
|
65
69
|
"node": ">=0.8"
|