node-version-use 1.9.2 → 1.9.3

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.
@@ -0,0 +1,2 @@
1
+ export declare function homedir(): string;
2
+ export declare function stringEndsWith(str: string, search: string, position?: number): boolean;
@@ -0,0 +1,2 @@
1
+ export declare function homedir(): string;
2
+ export declare function stringEndsWith(str: string, search: string, position?: number): boolean;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Compatibility Layer for Node.js 0.8+
3
+ * Local to this package - contains only needed functions.
4
+ */ "use strict";
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ function _export(target, all) {
9
+ for(var name in all)Object.defineProperty(target, name, {
10
+ enumerable: true,
11
+ get: Object.getOwnPropertyDescriptor(all, name).get
12
+ });
13
+ }
14
+ _export(exports, {
15
+ get homedir () {
16
+ return homedir;
17
+ },
18
+ get stringEndsWith () {
19
+ return stringEndsWith;
20
+ }
21
+ });
22
+ var _os = /*#__PURE__*/ _interop_require_default(require("os"));
23
+ function _interop_require_default(obj) {
24
+ return obj && obj.__esModule ? obj : {
25
+ default: obj
26
+ };
27
+ }
28
+ var hasHomedir = typeof _os.default.homedir === 'function';
29
+ function homedir() {
30
+ if (hasHomedir) {
31
+ return _os.default.homedir();
32
+ }
33
+ var home = require('homedir-polyfill');
34
+ return home();
35
+ }
36
+ /**
37
+ * String.prototype.endsWith wrapper for Node.js 0.8+
38
+ * - Uses native endsWith on Node 4.0+ / ES2015+
39
+ * - Falls back to lastIndexOf on Node 0.8-3.x
40
+ */ var hasEndsWith = typeof String.prototype.endsWith === 'function';
41
+ function stringEndsWith(str, search, position) {
42
+ if (hasEndsWith) {
43
+ return str.endsWith(search, position);
44
+ }
45
+ var len = position === undefined ? str.length : position;
46
+ return str.lastIndexOf(search) === len - search.length;
47
+ }
48
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/compat.ts"],"sourcesContent":["/**\n * Compatibility Layer for Node.js 0.8+\n * Local to this package - contains only needed functions.\n */\nimport os from 'os';\n\nvar hasHomedir = typeof os.homedir === 'function';\n\nexport function homedir(): string {\n if (hasHomedir) {\n return os.homedir();\n }\n var home = require('homedir-polyfill');\n return home();\n}\n\n/**\n * String.prototype.endsWith wrapper for Node.js 0.8+\n * - Uses native endsWith on Node 4.0+ / ES2015+\n * - Falls back to lastIndexOf on Node 0.8-3.x\n */\nvar hasEndsWith = typeof String.prototype.endsWith === 'function';\n\nexport function stringEndsWith(str: string, search: string, position?: number): boolean {\n if (hasEndsWith) {\n return str.endsWith(search, position);\n }\n var len = position === undefined ? str.length : position;\n return str.lastIndexOf(search) === len - search.length;\n}\n"],"names":["homedir","stringEndsWith","hasHomedir","os","home","require","hasEndsWith","String","prototype","endsWith","str","search","position","len","undefined","length","lastIndexOf"],"mappings":"AAAA;;;CAGC;;;;;;;;;;;QAKeA;eAAAA;;QAeAC;eAAAA;;;yDAnBD;;;;;;AAEf,IAAIC,aAAa,OAAOC,WAAE,CAACH,OAAO,KAAK;AAEhC,SAASA;IACd,IAAIE,YAAY;QACd,OAAOC,WAAE,CAACH,OAAO;IACnB;IACA,IAAII,OAAOC,QAAQ;IACnB,OAAOD;AACT;AAEA;;;;CAIC,GACD,IAAIE,cAAc,OAAOC,OAAOC,SAAS,CAACC,QAAQ,KAAK;AAEhD,SAASR,eAAeS,GAAW,EAAEC,MAAc,EAAEC,QAAiB;IAC3E,IAAIN,aAAa;QACf,OAAOI,IAAID,QAAQ,CAACE,QAAQC;IAC9B;IACA,IAAIC,MAAMD,aAAaE,YAAYJ,IAAIK,MAAM,GAAGH;IAChD,OAAOF,IAAIM,WAAW,CAACL,YAAYE,MAAMF,OAAOI,MAAM;AACxD"}
@@ -8,13 +8,12 @@ Object.defineProperty(exports, "storagePath", {
8
8
  return storagePath;
9
9
  }
10
10
  });
11
- var _homedirpolyfill = /*#__PURE__*/ _interop_require_default(require("homedir-polyfill"));
12
11
  var _path = /*#__PURE__*/ _interop_require_default(require("path"));
12
+ var _compatts = require("./compat.js");
13
13
  function _interop_require_default(obj) {
14
14
  return obj && obj.__esModule ? obj : {
15
15
  default: obj
16
16
  };
17
17
  }
18
- var home = (0, _homedirpolyfill.default)();
19
- var storagePath = _path.default.join(home, '.nvu');
18
+ var storagePath = _path.default.join((0, _compatts.homedir)(), '.nvu');
20
19
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/constants.ts"],"sourcesContent":["import homedir from 'homedir-polyfill';\nimport path from 'path';\n\nconst home = homedir();\nexport const storagePath = path.join(home, '.nvu') as string;\n"],"names":["storagePath","home","homedir","path","join"],"mappings":";;;;+BAIaA;;;eAAAA;;;sEAJO;2DACH;;;;;;AAEjB,IAAMC,OAAOC,IAAAA,wBAAO;AACb,IAAMF,cAAcG,aAAI,CAACC,IAAI,CAACH,MAAM"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/constants.ts"],"sourcesContent":["import path from 'path';\nimport { homedir } from './compat.ts';\n\nexport const storagePath = path.join(homedir(), '.nvu') as string;\n"],"names":["storagePath","path","join","homedir"],"mappings":";;;;+BAGaA;;;eAAAA;;;2DAHI;wBACO;;;;;;AAEjB,IAAMA,cAAcC,aAAI,CAACC,IAAI,CAACC,IAAAA,iBAAO,KAAI"}
@@ -16,6 +16,7 @@ var _path = /*#__PURE__*/ _interop_require_default(require("path"));
16
16
  var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
17
17
  var _resolvebinsync = /*#__PURE__*/ _interop_require_default(require("resolve-bin-sync"));
18
18
  var _spawnstreaming = /*#__PURE__*/ _interop_require_default(require("spawn-streaming"));
19
+ var _compatts = require("./compat.js");
19
20
  var _constantsts = require("./constants.js");
20
21
  var _loadNodeVersionInstallts = /*#__PURE__*/ _interop_require_default(require("./lib/loadNodeVersionInstall.js"));
21
22
  var _loadSpawnTermts = /*#__PURE__*/ _interop_require_default(require("./lib/loadSpawnTerm.js"));
@@ -104,7 +105,7 @@ function resolveCommand(command, args) {
104
105
  args: args
105
106
  };
106
107
  // Case 1: Command is a .cmd file path
107
- if (command.toLowerCase().endsWith('.cmd')) {
108
+ if ((0, _compatts.stringEndsWith)(command.toLowerCase(), '.cmd')) {
108
109
  var scriptPath = parseNpmCmdWrapper(command);
109
110
  if (scriptPath) {
110
111
  return {
@@ -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 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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"}
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 { stringEndsWith } from './compat.ts';\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 (stringEndsWith(command.toLowerCase(), '.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","stringEndsWith","toLowerCase","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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"}
@@ -0,0 +1,2 @@
1
+ export declare function homedir(): string;
2
+ export declare function stringEndsWith(str: string, search: string, position?: number): boolean;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Compatibility Layer for Node.js 0.8+
3
+ * Local to this package - contains only needed functions.
4
+ */ import os from 'os';
5
+ var hasHomedir = typeof os.homedir === 'function';
6
+ export function homedir() {
7
+ if (hasHomedir) {
8
+ return os.homedir();
9
+ }
10
+ var home = require('homedir-polyfill');
11
+ return home();
12
+ }
13
+ /**
14
+ * String.prototype.endsWith wrapper for Node.js 0.8+
15
+ * - Uses native endsWith on Node 4.0+ / ES2015+
16
+ * - Falls back to lastIndexOf on Node 0.8-3.x
17
+ */ var hasEndsWith = typeof String.prototype.endsWith === 'function';
18
+ export function stringEndsWith(str, search, position) {
19
+ if (hasEndsWith) {
20
+ return str.endsWith(search, position);
21
+ }
22
+ var len = position === undefined ? str.length : position;
23
+ return str.lastIndexOf(search) === len - search.length;
24
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/compat.ts"],"sourcesContent":["/**\n * Compatibility Layer for Node.js 0.8+\n * Local to this package - contains only needed functions.\n */\nimport os from 'os';\n\nvar hasHomedir = typeof os.homedir === 'function';\n\nexport function homedir(): string {\n if (hasHomedir) {\n return os.homedir();\n }\n var home = require('homedir-polyfill');\n return home();\n}\n\n/**\n * String.prototype.endsWith wrapper for Node.js 0.8+\n * - Uses native endsWith on Node 4.0+ / ES2015+\n * - Falls back to lastIndexOf on Node 0.8-3.x\n */\nvar hasEndsWith = typeof String.prototype.endsWith === 'function';\n\nexport function stringEndsWith(str: string, search: string, position?: number): boolean {\n if (hasEndsWith) {\n return str.endsWith(search, position);\n }\n var len = position === undefined ? str.length : position;\n return str.lastIndexOf(search) === len - search.length;\n}\n"],"names":["os","hasHomedir","homedir","home","require","hasEndsWith","String","prototype","endsWith","stringEndsWith","str","search","position","len","undefined","length","lastIndexOf"],"mappings":"AAAA;;;CAGC,GACD,OAAOA,QAAQ,KAAK;AAEpB,IAAIC,aAAa,OAAOD,GAAGE,OAAO,KAAK;AAEvC,OAAO,SAASA;IACd,IAAID,YAAY;QACd,OAAOD,GAAGE,OAAO;IACnB;IACA,IAAIC,OAAOC,QAAQ;IACnB,OAAOD;AACT;AAEA;;;;CAIC,GACD,IAAIE,cAAc,OAAOC,OAAOC,SAAS,CAACC,QAAQ,KAAK;AAEvD,OAAO,SAASC,eAAeC,GAAW,EAAEC,MAAc,EAAEC,QAAiB;IAC3E,IAAIP,aAAa;QACf,OAAOK,IAAIF,QAAQ,CAACG,QAAQC;IAC9B;IACA,IAAIC,MAAMD,aAAaE,YAAYJ,IAAIK,MAAM,GAAGH;IAChD,OAAOF,IAAIM,WAAW,CAACL,YAAYE,MAAMF,OAAOI,MAAM;AACxD"}
@@ -1,4 +1,3 @@
1
- import homedir from 'homedir-polyfill';
2
1
  import path from 'path';
3
- const home = homedir();
4
- export const storagePath = path.join(home, '.nvu');
2
+ import { homedir } from './compat.js';
3
+ export const storagePath = path.join(homedir(), '.nvu');
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/constants.ts"],"sourcesContent":["import homedir from 'homedir-polyfill';\nimport path from 'path';\n\nconst home = homedir();\nexport const storagePath = path.join(home, '.nvu') as string;\n"],"names":["homedir","path","home","storagePath","join"],"mappings":"AAAA,OAAOA,aAAa,mBAAmB;AACvC,OAAOC,UAAU,OAAO;AAExB,MAAMC,OAAOF;AACb,OAAO,MAAMG,cAAcF,KAAKG,IAAI,CAACF,MAAM,QAAkB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-version-use/src/constants.ts"],"sourcesContent":["import path from 'path';\nimport { homedir } from './compat.ts';\n\nexport const storagePath = path.join(homedir(), '.nvu') as string;\n"],"names":["path","homedir","storagePath","join"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AACxB,SAASC,OAAO,QAAQ,cAAc;AAEtC,OAAO,MAAMC,cAAcF,KAAKG,IAAI,CAACF,WAAW,QAAkB"}
@@ -6,6 +6,7 @@ import path from 'path';
6
6
  import Queue from 'queue-cb';
7
7
  import resolveBin from 'resolve-bin-sync';
8
8
  import spawnStreaming from 'spawn-streaming';
9
+ import { stringEndsWith } from './compat.js';
9
10
  import { storagePath } from './constants.js';
10
11
  import loadNodeVersionInstall from './lib/loadNodeVersionInstall.js';
11
12
  import loadSpawnTerm from './lib/loadSpawnTerm.js';
@@ -36,7 +37,7 @@ function resolveCommand(command, args) {
36
37
  args
37
38
  };
38
39
  // Case 1: Command is a .cmd file path
39
- if (command.toLowerCase().endsWith('.cmd')) {
40
+ if (stringEndsWith(command.toLowerCase(), '.cmd')) {
40
41
  const scriptPath = parseNpmCmdWrapper(command);
41
42
  if (scriptPath) {
42
43
  return {
@@ -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 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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"}
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 { stringEndsWith } from './compat.ts';\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 (stringEndsWith(command.toLowerCase(), '.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","stringEndsWith","storagePath","loadNodeVersionInstall","loadSpawnTerm","isWindows","process","platform","test","env","OSTYPE","NODE","parseNpmCmdWrapper","cmdPath","content","readFileSync","match","relativePath","cmdDir","dirname","join","_e","resolveCommand","command","args","toLowerCase","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.9.2",
3
+ "version": "1.9.3",
4
4
  "description": "Cross-platform solution for using multiple versions of node. Useful for compatibility testing",
5
5
  "keywords": [
6
6
  "node",