node-install-release 1.16.0 → 1.16.1

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.
Files changed (31) hide show
  1. package/dist/cjs/installNPM/installLib.js +2 -2
  2. package/dist/cjs/installNPM/installLib.js.map +1 -1
  3. package/dist/cjs/installNode/installCompressed.js +15 -19
  4. package/dist/cjs/installNode/installCompressed.js.map +1 -1
  5. package/dist/cjs/installNode/installSource/index.js +13 -7
  6. package/dist/cjs/installNode/installSource/index.js.map +1 -1
  7. package/dist/cjs/lib/extract.d.cts +7 -0
  8. package/dist/cjs/lib/extract.d.ts +7 -0
  9. package/dist/cjs/lib/extract.js +62 -0
  10. package/dist/cjs/lib/extract.js.map +1 -0
  11. package/dist/cjs/workers/install.js +59 -30
  12. package/dist/cjs/workers/install.js.map +1 -1
  13. package/dist/esm/installNPM/installLib.js +2 -2
  14. package/dist/esm/installNPM/installLib.js.map +1 -1
  15. package/dist/esm/installNode/installCompressed.js +13 -17
  16. package/dist/esm/installNode/installCompressed.js.map +1 -1
  17. package/dist/esm/installNode/installSource/index.js +11 -7
  18. package/dist/esm/installNode/installSource/index.js.map +1 -1
  19. package/dist/esm/lib/extract.d.ts +7 -0
  20. package/dist/esm/lib/extract.js +19 -0
  21. package/dist/esm/lib/extract.js.map +1 -0
  22. package/dist/esm/workers/install.js +54 -27
  23. package/dist/esm/workers/install.js.map +1 -1
  24. package/package.json +8 -7
  25. package/dist/cjs/lib/conditionalExtract.d.cts +0 -2
  26. package/dist/cjs/lib/conditionalExtract.d.ts +0 -2
  27. package/dist/cjs/lib/conditionalExtract.js +0 -38
  28. package/dist/cjs/lib/conditionalExtract.js.map +0 -1
  29. package/dist/esm/lib/conditionalExtract.d.ts +0 -2
  30. package/dist/esm/lib/conditionalExtract.js +0 -22
  31. package/dist/esm/lib/conditionalExtract.js.map +0 -1
@@ -17,7 +17,7 @@ var _path = /*#__PURE__*/ _interop_require_default(require("path"));
17
17
  var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
18
18
  var _constantsts = require("../constants.js");
19
19
  var _conditionalCachets = /*#__PURE__*/ _interop_require_default(require("../lib/conditionalCache.js"));
20
- var _conditionalExtractts = /*#__PURE__*/ _interop_require_default(require("../lib/conditionalExtract.js"));
20
+ var _extractts = /*#__PURE__*/ _interop_require_default(require("../lib/extract.js"));
21
21
  function _interop_require_default(obj) {
22
22
  return obj && obj.__esModule ? obj : {
23
23
  default: obj
@@ -61,7 +61,7 @@ function installLib(version, dest, options, callback) {
61
61
  cb(err);
62
62
  });
63
63
  });
64
- queue.defer(_conditionalExtractts.default.bind(null, cachePath, installPath));
64
+ queue.defer(_extractts.default.bind(null, cachePath, installPath));
65
65
  queue.await(function(err) {
66
66
  err ? callback(err) : callback(null, npmVersion, checksum);
67
67
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNPM/installLib.ts"],"sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport get from 'get-remote';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport oo from 'on-one';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport { NPM_DIST_TAGS_URL, NPM_DIST_URL, NPM_MIN_VERSION } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport conditionalExtract from '../lib/conditionalExtract.ts';\n\ninterface DistRecord {\n latest: string;\n}\n\nimport type { InstallOptions } from '../types.ts';\n\nexport type Callback = (error?: Error, npmVersion?: string, checksum?: string) => undefined;\n\nfunction calculateChecksum(filePath: string, callback: (err?: Error, checksum?: string) => void): void {\n const hash = crypto.createHash('sha256');\n const stream = fs.createReadStream(filePath);\n stream.on('data', (data) => hash.update(data));\n oo(stream, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (err) return callback(err);\n callback(null, hash.digest('hex'));\n });\n}\n\nexport default function installLib(version: string, dest: string, options: InstallOptions, callback: Callback): undefined {\n const platform = options.platform;\n const libPath = platform === 'win32' ? dest : path.join(dest, 'lib');\n const installPath = path.join(libPath, 'node_modules', 'npm');\n\n const dist = getDist(version);\n const npmMajorPair = dist && dist.npm ? +dist.npm.split('.')[0] : NPM_MIN_VERSION;\n const npmMajor = Math.max(npmMajorPair, NPM_MIN_VERSION);\n\n get(NPM_DIST_TAGS_URL).json((err, res) => {\n if (err) return callback(err);\n const distTags = res.body as DistRecord;\n const npmVersion = distTags[`latest-${npmMajor}`] || distTags[`next-${npmMajor}`] || distTags.latest;\n const downloadPath = `${NPM_DIST_URL}/-/npm-${npmVersion}.tgz`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: string | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n calculateChecksum(cachePath, (err, hash) => {\n checksum = hash;\n cb(err);\n });\n });\n queue.defer(conditionalExtract.bind(null, cachePath, installPath));\n queue.await((err) => {\n err ? callback(err) : callback(null, npmVersion, checksum);\n });\n });\n}\n"],"names":["installLib","calculateChecksum","filePath","callback","hash","crypto","createHash","stream","fs","createReadStream","on","data","update","oo","err","digest","version","dest","options","platform","libPath","path","join","installPath","dist","getDist","npmMajorPair","npm","split","NPM_MIN_VERSION","npmMajor","Math","max","get","NPM_DIST_TAGS_URL","json","res","distTags","body","npmVersion","latest","downloadPath","NPM_DIST_URL","cachePath","basename","checksum","queue","Queue","defer","conditionalCache","bind","cb","conditionalExtract","await"],"mappings":";;;;+BA6BA;;;eAAwBA;;;6DA7BL;yDACJ;gEACC;uCACQ;4DACT;2DACE;8DACC;2BAC+C;yEACpC;2EACE;;;;;;AAU/B,SAASC,kBAAkBC,QAAgB,EAAEC,QAAkD;IAC7F,IAAMC,OAAOC,eAAM,CAACC,UAAU,CAAC;IAC/B,IAAMC,SAASC,WAAE,CAACC,gBAAgB,CAACP;IACnCK,OAAOG,EAAE,CAAC,QAAQ,SAACC;eAASP,KAAKQ,MAAM,CAACD;;IACxCE,IAAAA,cAAE,EAACN,QAAQ;QAAC;QAAS;QAAO;QAAS;KAAS,EAAE,SAACO;QAC/C,IAAIA,KAAK,OAAOX,SAASW;QACzBX,SAAS,MAAMC,KAAKW,MAAM,CAAC;IAC7B;AACF;AAEe,SAASf,WAAWgB,OAAe,EAAEC,IAAY,EAAEC,OAAuB,EAAEf,QAAkB;IAC3G,IAAMgB,WAAWD,QAAQC,QAAQ;IACjC,IAAMC,UAAUD,aAAa,UAAUF,OAAOI,aAAI,CAACC,IAAI,CAACL,MAAM;IAC9D,IAAMM,cAAcF,aAAI,CAACC,IAAI,CAACF,SAAS,gBAAgB;IAEvD,IAAMI,OAAOC,IAAAA,gCAAO,EAACT;IACrB,IAAMU,eAAeF,QAAQA,KAAKG,GAAG,GAAG,CAACH,KAAKG,GAAG,CAACC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAGC,4BAAe;IACjF,IAAMC,WAAWC,KAAKC,GAAG,CAACN,cAAcG,4BAAe;IAEvDI,IAAAA,kBAAG,EAACC,8BAAiB,EAAEC,IAAI,CAAC,SAACrB,KAAKsB;QAChC,IAAItB,KAAK,OAAOX,SAASW;QACzB,IAAMuB,WAAWD,IAAIE,IAAI;QACzB,IAAMC,aAAaF,QAAQ,CAAC,AAAC,UAAkB,OAATP,UAAW,IAAIO,QAAQ,CAAC,AAAC,QAAgB,OAATP,UAAW,IAAIO,SAASG,MAAM;QACpG,IAAMC,eAAe,AAAC,GAAwBF,OAAtBG,yBAAY,EAAC,WAAoB,OAAXH,YAAW;QACzD,IAAMI,YAAYtB,aAAI,CAACC,IAAI,CAACJ,QAAQyB,SAAS,EAAEtB,aAAI,CAACuB,QAAQ,CAACH;QAE7D,IAAII;QACJ,IAAMC,QAAQ,IAAIC,gBAAK,CAAC;QACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMT,cAAcE;QACtDG,MAAME,KAAK,CAAC,SAACG;YACXlD,kBAAkB0C,WAAW,SAAC7B,KAAKV;gBACjCyC,WAAWzC;gBACX+C,GAAGrC;YACL;QACF;QACAgC,MAAME,KAAK,CAACI,6BAAkB,CAACF,IAAI,CAAC,MAAMP,WAAWpB;QACrDuB,MAAMO,KAAK,CAAC,SAACvC;YACXA,MAAMX,SAASW,OAAOX,SAAS,MAAMoC,YAAYM;QACnD;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNPM/installLib.ts"],"sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport get from 'get-remote';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport oo from 'on-one';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport { NPM_DIST_TAGS_URL, NPM_DIST_URL, NPM_MIN_VERSION } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport extract from '../lib/extract.ts';\n\ninterface DistRecord {\n latest: string;\n}\n\nimport type { InstallOptions } from '../types.ts';\n\nexport type Callback = (error?: Error, npmVersion?: string, checksum?: string) => undefined;\n\nfunction calculateChecksum(filePath: string, callback: (err?: Error, checksum?: string) => void): void {\n const hash = crypto.createHash('sha256');\n const stream = fs.createReadStream(filePath);\n stream.on('data', (data) => hash.update(data));\n oo(stream, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (err) return callback(err);\n callback(null, hash.digest('hex'));\n });\n}\n\nexport default function installLib(version: string, dest: string, options: InstallOptions, callback: Callback): undefined {\n const platform = options.platform;\n const libPath = platform === 'win32' ? dest : path.join(dest, 'lib');\n const installPath = path.join(libPath, 'node_modules', 'npm');\n\n const dist = getDist(version);\n const npmMajorPair = dist && dist.npm ? +dist.npm.split('.')[0] : NPM_MIN_VERSION;\n const npmMajor = Math.max(npmMajorPair, NPM_MIN_VERSION);\n\n get(NPM_DIST_TAGS_URL).json((err, res) => {\n if (err) return callback(err);\n const distTags = res.body as DistRecord;\n const npmVersion = distTags[`latest-${npmMajor}`] || distTags[`next-${npmMajor}`] || distTags.latest;\n const downloadPath = `${NPM_DIST_URL}/-/npm-${npmVersion}.tgz`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: string | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n calculateChecksum(cachePath, (err, hash) => {\n checksum = hash;\n cb(err);\n });\n });\n queue.defer(extract.bind(null, cachePath, installPath));\n queue.await((err) => {\n err ? callback(err) : callback(null, npmVersion, checksum);\n });\n });\n}\n"],"names":["installLib","calculateChecksum","filePath","callback","hash","crypto","createHash","stream","fs","createReadStream","on","data","update","oo","err","digest","version","dest","options","platform","libPath","path","join","installPath","dist","getDist","npmMajorPair","npm","split","NPM_MIN_VERSION","npmMajor","Math","max","get","NPM_DIST_TAGS_URL","json","res","distTags","body","npmVersion","latest","downloadPath","NPM_DIST_URL","cachePath","basename","checksum","queue","Queue","defer","conditionalCache","bind","cb","extract","await"],"mappings":";;;;+BA6BA;;;eAAwBA;;;6DA7BL;yDACJ;gEACC;uCACQ;4DACT;2DACE;8DACC;2BAC+C;yEACpC;gEACT;;;;;;AAUpB,SAASC,kBAAkBC,QAAgB,EAAEC,QAAkD;IAC7F,IAAMC,OAAOC,eAAM,CAACC,UAAU,CAAC;IAC/B,IAAMC,SAASC,WAAE,CAACC,gBAAgB,CAACP;IACnCK,OAAOG,EAAE,CAAC,QAAQ,SAACC;eAASP,KAAKQ,MAAM,CAACD;;IACxCE,IAAAA,cAAE,EAACN,QAAQ;QAAC;QAAS;QAAO;QAAS;KAAS,EAAE,SAACO;QAC/C,IAAIA,KAAK,OAAOX,SAASW;QACzBX,SAAS,MAAMC,KAAKW,MAAM,CAAC;IAC7B;AACF;AAEe,SAASf,WAAWgB,OAAe,EAAEC,IAAY,EAAEC,OAAuB,EAAEf,QAAkB;IAC3G,IAAMgB,WAAWD,QAAQC,QAAQ;IACjC,IAAMC,UAAUD,aAAa,UAAUF,OAAOI,aAAI,CAACC,IAAI,CAACL,MAAM;IAC9D,IAAMM,cAAcF,aAAI,CAACC,IAAI,CAACF,SAAS,gBAAgB;IAEvD,IAAMI,OAAOC,IAAAA,gCAAO,EAACT;IACrB,IAAMU,eAAeF,QAAQA,KAAKG,GAAG,GAAG,CAACH,KAAKG,GAAG,CAACC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAGC,4BAAe;IACjF,IAAMC,WAAWC,KAAKC,GAAG,CAACN,cAAcG,4BAAe;IAEvDI,IAAAA,kBAAG,EAACC,8BAAiB,EAAEC,IAAI,CAAC,SAACrB,KAAKsB;QAChC,IAAItB,KAAK,OAAOX,SAASW;QACzB,IAAMuB,WAAWD,IAAIE,IAAI;QACzB,IAAMC,aAAaF,QAAQ,CAAC,AAAC,UAAkB,OAATP,UAAW,IAAIO,QAAQ,CAAC,AAAC,QAAgB,OAATP,UAAW,IAAIO,SAASG,MAAM;QACpG,IAAMC,eAAe,AAAC,GAAwBF,OAAtBG,yBAAY,EAAC,WAAoB,OAAXH,YAAW;QACzD,IAAMI,YAAYtB,aAAI,CAACC,IAAI,CAACJ,QAAQyB,SAAS,EAAEtB,aAAI,CAACuB,QAAQ,CAACH;QAE7D,IAAII;QACJ,IAAMC,QAAQ,IAAIC,gBAAK,CAAC;QACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMT,cAAcE;QACtDG,MAAME,KAAK,CAAC,SAACG;YACXlD,kBAAkB0C,WAAW,SAAC7B,KAAKV;gBACjCyC,WAAWzC;gBACX+C,GAAGrC;YACL;QACF;QACAgC,MAAME,KAAK,CAACI,kBAAO,CAACF,IAAI,CAAC,MAAMP,WAAWpB;QAC1CuB,MAAMO,KAAK,CAAC,SAACvC;YACXA,MAAMX,SAASW,OAAOX,SAAS,MAAMoC,YAAYM;QACnD;IACF;AACF"}
@@ -8,12 +8,11 @@ Object.defineProperty(exports, "default", {
8
8
  return installCompressed;
9
9
  }
10
10
  });
11
- var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
12
11
  var _path = /*#__PURE__*/ _interop_require_default(require("path"));
13
12
  var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
14
13
  var _constantsts = require("../constants.js");
15
14
  var _conditionalCachets = /*#__PURE__*/ _interop_require_default(require("../lib/conditionalCache.js"));
16
- var _conditionalExtractts = /*#__PURE__*/ _interop_require_default(require("../lib/conditionalExtract.js"));
15
+ var _extractts = /*#__PURE__*/ _interop_require_default(require("../lib/extract.js"));
17
16
  var _validateDownloadts = /*#__PURE__*/ _interop_require_default(require("./validateDownload.js"));
18
17
  function _interop_require_default(obj) {
19
18
  return obj && obj.__esModule ? obj : {
@@ -23,24 +22,21 @@ function _interop_require_default(obj) {
23
22
  function installCompressed(distPath, dest, options, callback) {
24
23
  var downloadPath = "".concat(_constantsts.NODE_DIST_BASE_URL, "/").concat(distPath);
25
24
  var cachePath = _path.default.join(options.cachePath, _path.default.basename(downloadPath));
26
- _fs.default.stat(dest, function(err) {
27
- if (!err) return callback(); // already exists
28
- var checksum;
29
- var queue = new _queuecb.default(1);
30
- queue.defer(_conditionalCachets.default.bind(null, downloadPath, cachePath));
31
- queue.defer(function(cb) {
32
- (0, _validateDownloadts.default)(distPath, cachePath, function(err, result) {
33
- checksum = result;
34
- cb(err);
35
- });
36
- });
37
- queue.defer(_conditionalExtractts.default.bind(null, cachePath, dest, {
38
- strip: 1,
39
- time: 1000
40
- }));
41
- queue.await(function(err) {
42
- return callback(err, checksum);
25
+ var checksum;
26
+ var queue = new _queuecb.default(1);
27
+ queue.defer(_conditionalCachets.default.bind(null, downloadPath, cachePath));
28
+ queue.defer(function(cb) {
29
+ (0, _validateDownloadts.default)(distPath, cachePath, function(err, result) {
30
+ checksum = result;
31
+ cb(err);
43
32
  });
44
33
  });
34
+ queue.defer(_extractts.default.bind(null, cachePath, dest, {
35
+ strip: 1,
36
+ time: 1000
37
+ }));
38
+ queue.await(function(err) {
39
+ return callback(err, checksum);
40
+ });
45
41
  }
46
42
  /* 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-install-release/src/installNode/installCompressed.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport conditionalExtract from '../lib/conditionalExtract.ts';\nimport type { ChecksumCallback, ChecksumResult, InstallOptions } from '../types.ts';\nimport validateDownload from './validateDownload.ts';\n\nexport default function installCompressed(distPath: string, dest: string, options: InstallOptions, callback: ChecksumCallback): undefined {\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n fs.stat(dest, (err) => {\n if (!err) return callback(); // already exists\n\n let checksum: ChecksumResult | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n validateDownload(distPath, cachePath, (err, result) => {\n checksum = result;\n cb(err);\n });\n });\n queue.defer(conditionalExtract.bind(null, cachePath, dest, { strip: 1, time: 1000 }));\n queue.await((err) => callback(err, checksum));\n });\n}\n"],"names":["installCompressed","distPath","dest","options","callback","downloadPath","NODE_DIST_BASE_URL","cachePath","path","join","basename","fs","stat","err","checksum","queue","Queue","defer","conditionalCache","bind","cb","validateDownload","result","conditionalExtract","strip","time","await"],"mappings":";;;;+BAUA;;;eAAwBA;;;yDAVT;2DACE;8DACC;2BAEiB;yEACN;2EACE;yEAEF;;;;;;AAEd,SAASA,kBAAkBC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAA0B;IAC3H,IAAMC,eAAe,AAAC,GAAwBJ,OAAtBK,+BAAkB,EAAC,KAAY,OAATL;IAC9C,IAAMM,YAAYC,aAAI,CAACC,IAAI,CAACN,QAAQI,SAAS,EAAEC,aAAI,CAACE,QAAQ,CAACL;IAE7DM,WAAE,CAACC,IAAI,CAACV,MAAM,SAACW;QACb,IAAI,CAACA,KAAK,OAAOT,YAAY,iBAAiB;QAE9C,IAAIU;QACJ,IAAMC,QAAQ,IAAIC,gBAAK,CAAC;QACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMd,cAAcE;QACtDQ,MAAME,KAAK,CAAC,SAACG;YACXC,IAAAA,2BAAgB,EAACpB,UAAUM,WAAW,SAACM,KAAKS;gBAC1CR,WAAWQ;gBACXF,GAAGP;YACL;QACF;QACAE,MAAME,KAAK,CAACM,6BAAkB,CAACJ,IAAI,CAAC,MAAMZ,WAAWL,MAAM;YAAEsB,OAAO;YAAGC,MAAM;QAAK;QAClFV,MAAMW,KAAK,CAAC,SAACb;mBAAQT,SAASS,KAAKC;;IACrC;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installCompressed.ts"],"sourcesContent":["import path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport extract from '../lib/extract.ts';\nimport type { ChecksumCallback, ChecksumResult, InstallOptions } from '../types.ts';\nimport validateDownload from './validateDownload.ts';\n\nexport default function installCompressed(distPath: string, dest: string, options: InstallOptions, callback: ChecksumCallback): undefined {\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: ChecksumResult | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n validateDownload(distPath, cachePath, (err, result) => {\n checksum = result;\n cb(err);\n });\n });\n queue.defer(extract.bind(null, cachePath, dest, { strip: 1, time: 1000 }));\n queue.await((err) => callback(err, checksum));\n}\n"],"names":["installCompressed","distPath","dest","options","callback","downloadPath","NODE_DIST_BASE_URL","cachePath","path","join","basename","checksum","queue","Queue","defer","conditionalCache","bind","cb","validateDownload","err","result","extract","strip","time","await"],"mappings":";;;;+BASA;;;eAAwBA;;;2DATP;8DACC;2BAEiB;yEACN;gEACT;yEAES;;;;;;AAEd,SAASA,kBAAkBC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAA0B;IAC3H,IAAMC,eAAe,AAAC,GAAwBJ,OAAtBK,+BAAkB,EAAC,KAAY,OAATL;IAC9C,IAAMM,YAAYC,aAAI,CAACC,IAAI,CAACN,QAAQI,SAAS,EAAEC,aAAI,CAACE,QAAQ,CAACL;IAE7D,IAAIM;IACJ,IAAMC,QAAQ,IAAIC,gBAAK,CAAC;IACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMX,cAAcE;IACtDK,MAAME,KAAK,CAAC,SAACG;QACXC,IAAAA,2BAAgB,EAACjB,UAAUM,WAAW,SAACY,KAAKC;YAC1CT,WAAWS;YACXH,GAAGE;QACL;IACF;IACAP,MAAME,KAAK,CAACO,kBAAO,CAACL,IAAI,CAAC,MAAMT,WAAWL,MAAM;QAAEoB,OAAO;QAAGC,MAAM;IAAK;IACvEX,MAAMY,KAAK,CAAC,SAACL;eAAQf,SAASe,KAAKR;;AACrC"}
@@ -8,11 +8,13 @@ Object.defineProperty(exports, "default", {
8
8
  return InstallSource;
9
9
  }
10
10
  });
11
+ var _fsremovecompat = require("fs-remove-compat");
11
12
  var _path = /*#__PURE__*/ _interop_require_default(require("path"));
12
13
  var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
14
+ var _tempsuffix = /*#__PURE__*/ _interop_require_default(require("temp-suffix"));
13
15
  var _constantsts = require("../../constants.js");
14
16
  var _conditionalCachets = /*#__PURE__*/ _interop_require_default(require("../../lib/conditionalCache.js"));
15
- var _conditionalExtractts = /*#__PURE__*/ _interop_require_default(require("../../lib/conditionalExtract.js"));
17
+ var _extractts = /*#__PURE__*/ _interop_require_default(require("../../lib/extract.js"));
16
18
  var _validateDownloadts = /*#__PURE__*/ _interop_require_default(require("../validateDownload.js"));
17
19
  var _buildPosixts = /*#__PURE__*/ _interop_require_default(require("./buildPosix.js"));
18
20
  var _buildWin32ts = /*#__PURE__*/ _interop_require_default(require("./buildWin32.js"));
@@ -25,15 +27,19 @@ function InstallSource(distPath, dest, options, callback) {
25
27
  var platform = options.platform;
26
28
  var build = platform === 'win32' ? _buildWin32ts.default : _buildPosixts.default;
27
29
  var downloadPath = "".concat(_constantsts.NODE_DIST_BASE_URL, "/").concat(distPath);
28
- var buildPath = _path.default.join(options.buildPath, _path.default.basename(distPath));
30
+ // Use temp build path to avoid race conditions with parallel builds
31
+ var tempBuildPath = (0, _tempsuffix.default)(_path.default.join(options.buildPath, _path.default.basename(distPath)));
29
32
  var cachePath = _path.default.join(options.cachePath, _path.default.basename(downloadPath));
30
33
  var queue = new _queuecb.default(1);
31
34
  queue.defer(_conditionalCachets.default.bind(null, downloadPath, cachePath));
32
35
  queue.defer(_validateDownloadts.default.bind(null, distPath, cachePath));
33
- queue.defer(_conditionalExtractts.default.bind(null, cachePath, buildPath, {
34
- strip: 1
35
- }));
36
- queue.defer(build.bind(null, buildPath, dest, options));
37
- queue.await(callback);
36
+ queue.defer(_extractts.default.bind(null, cachePath, tempBuildPath));
37
+ queue.defer(build.bind(null, tempBuildPath, dest, options));
38
+ queue.await(function(err) {
39
+ // Always clean up temp build directory
40
+ (0, _fsremovecompat.safeRm)(tempBuildPath, function() {
41
+ return callback(err);
42
+ });
43
+ });
38
44
  }
39
45
  /* 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-install-release/src/installNode/installSource/index.ts"],"sourcesContent":["import path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../../constants.ts';\nimport conditionalCache from '../../lib/conditionalCache.ts';\nimport conditionalExtract from '../../lib/conditionalExtract.ts';\nimport type { InstallOptions, NoParamCallback } from '../../types.ts';\nimport validateDownload from '../validateDownload.ts';\nimport buildPosix from './buildPosix.ts';\nimport buildWin32 from './buildWin32.ts';\n\nexport default function InstallSource(distPath: string, dest: string, options: InstallOptions, callback: NoParamCallback): undefined {\n const platform = options.platform;\n const build = platform === 'win32' ? buildWin32 : buildPosix;\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const buildPath = path.join(options.buildPath, path.basename(distPath));\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer(validateDownload.bind(null, distPath, cachePath));\n queue.defer(conditionalExtract.bind(null, cachePath, buildPath, { strip: 1 }));\n queue.defer(build.bind(null, buildPath, dest, options));\n queue.await(callback);\n}\n"],"names":["InstallSource","distPath","dest","options","callback","platform","build","buildWin32","buildPosix","downloadPath","NODE_DIST_BASE_URL","buildPath","path","join","basename","cachePath","queue","Queue","defer","conditionalCache","bind","validateDownload","conditionalExtract","strip","await"],"mappings":";;;;+BAWA;;;eAAwBA;;;2DAXP;8DACC;2BAEiB;yEACN;2EACE;yEAEF;mEACN;mEACA;;;;;;AAER,SAASA,cAAcC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAAyB;IACtH,IAAMC,WAAWF,QAAQE,QAAQ;IACjC,IAAMC,QAAQD,aAAa,UAAUE,qBAAU,GAAGC,qBAAU;IAC5D,IAAMC,eAAe,AAAC,GAAwBR,OAAtBS,+BAAkB,EAAC,KAAY,OAATT;IAC9C,IAAMU,YAAYC,aAAI,CAACC,IAAI,CAACV,QAAQQ,SAAS,EAAEC,aAAI,CAACE,QAAQ,CAACb;IAC7D,IAAMc,YAAYH,aAAI,CAACC,IAAI,CAACV,QAAQY,SAAS,EAAEH,aAAI,CAACE,QAAQ,CAACL;IAE7D,IAAMO,QAAQ,IAAIC,gBAAK,CAAC;IACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMX,cAAcM;IACtDC,MAAME,KAAK,CAACG,2BAAgB,CAACD,IAAI,CAAC,MAAMnB,UAAUc;IAClDC,MAAME,KAAK,CAACI,6BAAkB,CAACF,IAAI,CAAC,MAAML,WAAWJ,WAAW;QAAEY,OAAO;IAAE;IAC3EP,MAAME,KAAK,CAACZ,MAAMc,IAAI,CAAC,MAAMT,WAAWT,MAAMC;IAC9Ca,MAAMQ,KAAK,CAACpB;AACd"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installSource/index.ts"],"sourcesContent":["import { safeRm } from 'fs-remove-compat';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport tempSuffix from 'temp-suffix';\n\nimport { NODE_DIST_BASE_URL } from '../../constants.ts';\nimport conditionalCache from '../../lib/conditionalCache.ts';\nimport extract from '../../lib/extract.ts';\nimport type { InstallOptions, NoParamCallback } from '../../types.ts';\nimport validateDownload from '../validateDownload.ts';\nimport buildPosix from './buildPosix.ts';\nimport buildWin32 from './buildWin32.ts';\n\nexport default function InstallSource(distPath: string, dest: string, options: InstallOptions, callback: NoParamCallback): undefined {\n const platform = options.platform;\n const build = platform === 'win32' ? buildWin32 : buildPosix;\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n // Use temp build path to avoid race conditions with parallel builds\n const tempBuildPath = tempSuffix(path.join(options.buildPath, path.basename(distPath)));\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer(validateDownload.bind(null, distPath, cachePath));\n queue.defer(extract.bind(null, cachePath, tempBuildPath));\n queue.defer(build.bind(null, tempBuildPath, dest, options));\n queue.await((err) => {\n // Always clean up temp build directory\n safeRm(tempBuildPath, () => callback(err));\n });\n}\n"],"names":["InstallSource","distPath","dest","options","callback","platform","build","buildWin32","buildPosix","downloadPath","NODE_DIST_BASE_URL","tempBuildPath","tempSuffix","path","join","buildPath","basename","cachePath","queue","Queue","defer","conditionalCache","bind","validateDownload","extract","await","err","safeRm"],"mappings":";;;;+BAaA;;;eAAwBA;;;8BAbD;2DACN;8DACC;iEACK;2BAEY;yEACN;gEACT;yEAES;mEACN;mEACA;;;;;;AAER,SAASA,cAAcC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAAyB;IACtH,IAAMC,WAAWF,QAAQE,QAAQ;IACjC,IAAMC,QAAQD,aAAa,UAAUE,qBAAU,GAAGC,qBAAU;IAC5D,IAAMC,eAAe,AAAC,GAAwBR,OAAtBS,+BAAkB,EAAC,KAAY,OAATT;IAC9C,oEAAoE;IACpE,IAAMU,gBAAgBC,IAAAA,mBAAU,EAACC,aAAI,CAACC,IAAI,CAACX,QAAQY,SAAS,EAAEF,aAAI,CAACG,QAAQ,CAACf;IAC5E,IAAMgB,YAAYJ,aAAI,CAACC,IAAI,CAACX,QAAQc,SAAS,EAAEJ,aAAI,CAACG,QAAQ,CAACP;IAE7D,IAAMS,QAAQ,IAAIC,gBAAK,CAAC;IACxBD,MAAME,KAAK,CAACC,2BAAgB,CAACC,IAAI,CAAC,MAAMb,cAAcQ;IACtDC,MAAME,KAAK,CAACG,2BAAgB,CAACD,IAAI,CAAC,MAAMrB,UAAUgB;IAClDC,MAAME,KAAK,CAACI,kBAAO,CAACF,IAAI,CAAC,MAAML,WAAWN;IAC1CO,MAAME,KAAK,CAACd,MAAMgB,IAAI,CAAC,MAAMX,eAAeT,MAAMC;IAClDe,MAAMO,KAAK,CAAC,SAACC;QACX,uCAAuC;QACvCC,IAAAA,sBAAM,EAAChB,eAAe;mBAAMP,SAASsB;;IACvC;AACF"}
@@ -0,0 +1,7 @@
1
+ import type { NoParamCallback } from '../types.js';
2
+ interface ExtractOptions {
3
+ strip?: number;
4
+ time?: number;
5
+ }
6
+ export default function extract(src: string, dest: string, options: ExtractOptions | NoParamCallback, callback?: NoParamCallback): undefined;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { NoParamCallback } from '../types.js';
2
+ interface ExtractOptions {
3
+ strip?: number;
4
+ time?: number;
5
+ }
6
+ export default function extract(src: string, dest: string, options: ExtractOptions | NoParamCallback, callback?: NoParamCallback): undefined;
7
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return extract;
9
+ }
10
+ });
11
+ var _fastextract = /*#__PURE__*/ _interop_require_default(require("fast-extract"));
12
+ var _mkdirpclassic = /*#__PURE__*/ _interop_require_default(require("mkdirp-classic"));
13
+ var _path = /*#__PURE__*/ _interop_require_default(require("path"));
14
+ var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
15
+ function _define_property(obj, key, value) {
16
+ if (key in obj) {
17
+ Object.defineProperty(obj, key, {
18
+ value: value,
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true
22
+ });
23
+ } else {
24
+ obj[key] = value;
25
+ }
26
+ return obj;
27
+ }
28
+ function _interop_require_default(obj) {
29
+ return obj && obj.__esModule ? obj : {
30
+ default: obj
31
+ };
32
+ }
33
+ function _object_spread(target) {
34
+ for(var i = 1; i < arguments.length; i++){
35
+ var source = arguments[i] != null ? arguments[i] : {};
36
+ var ownKeys = Object.keys(source);
37
+ if (typeof Object.getOwnPropertySymbols === "function") {
38
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
39
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
40
+ }));
41
+ }
42
+ ownKeys.forEach(function(key) {
43
+ _define_property(target, key, source[key]);
44
+ });
45
+ }
46
+ return target;
47
+ }
48
+ function extract(src, dest, options, callback) {
49
+ if (typeof options === 'function') {
50
+ callback = options;
51
+ options = {};
52
+ }
53
+ var extractOptions = _object_spread({
54
+ strip: 1,
55
+ time: 1000
56
+ }, options);
57
+ var queue = new _queuecb.default(1);
58
+ queue.defer(_mkdirpclassic.default.bind(null, _path.default.dirname(dest)));
59
+ queue.defer(_fastextract.default.bind(null, src, dest, extractOptions));
60
+ queue.await(callback);
61
+ }
62
+ /* 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-install-release/src/lib/extract.ts"],"sourcesContent":["import fastExtract from 'fast-extract';\nimport mkdirp from 'mkdirp-classic';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport type { NoParamCallback } from '../types.ts';\n\ninterface ExtractOptions {\n strip?: number;\n time?: number;\n}\n\nexport default function extract(src: string, dest: string, options: ExtractOptions | NoParamCallback, callback?: NoParamCallback): undefined {\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n\n const extractOptions = { strip: 1, time: 1000, ...options };\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, path.dirname(dest)));\n queue.defer(fastExtract.bind(null, src, dest, extractOptions));\n queue.await(callback);\n}\n"],"names":["extract","src","dest","options","callback","extractOptions","strip","time","queue","Queue","defer","mkdirp","bind","path","dirname","fastExtract","await"],"mappings":";;;;+BAYA;;;eAAwBA;;;kEAZA;oEACL;2DACF;8DACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASH,SAASA,QAAQC,GAAW,EAAEC,IAAY,EAAEC,OAAyC,EAAEC,QAA0B;IAC9H,IAAI,OAAOD,YAAY,YAAY;QACjCC,WAAWD;QACXA,UAAU,CAAC;IACb;IAEA,IAAME,iBAAiB;QAAEC,OAAO;QAAGC,MAAM;OAASJ;IAElD,IAAMK,QAAQ,IAAIC,gBAAK,CAAC;IACxBD,MAAME,KAAK,CAACC,sBAAM,CAACC,IAAI,CAAC,MAAMC,aAAI,CAACC,OAAO,CAACZ;IAC3CM,MAAME,KAAK,CAACK,oBAAW,CAACH,IAAI,CAAC,MAAMX,KAAKC,MAAMG;IAC9CG,MAAMQ,KAAK,CAACZ;AACd"}
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "default", {
8
8
  return install;
9
9
  }
10
10
  });
11
+ var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
11
12
  var _fsremovecompat = require("fs-remove-compat");
12
13
  var _isversion = /*#__PURE__*/ _interop_require_default(require("is-version"));
13
14
  var _mkdirpclassic = /*#__PURE__*/ _interop_require_default(require("mkdirp-classic"));
@@ -15,6 +16,7 @@ var _nodefilenametodistpaths = require("node-filename-to-dist-paths");
15
16
  var _noderesolveversions = /*#__PURE__*/ _interop_require_default(require("node-resolve-versions"));
16
17
  var _path = /*#__PURE__*/ _interop_require_default(require("path"));
17
18
  var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
19
+ var _tempsuffix = /*#__PURE__*/ _interop_require_default(require("temp-suffix"));
18
20
  var _constantsts = require("../constants.js");
19
21
  var _createResultts = /*#__PURE__*/ _interop_require_default(require("../createResult.js"));
20
22
  var _createStoragePathsts = /*#__PURE__*/ _interop_require_default(require("../createStoragePaths.js"));
@@ -82,7 +84,7 @@ function install(versionExpression, options, callback) {
82
84
  }
83
85
  var version = versions[0];
84
86
  var result = (0, _createResultts.default)(options, version);
85
- // Check if node is missing first
87
+ // Fast path: check if installation is complete
86
88
  (0, _checkMissingts.default)(result.installPath, options, function(err, missing) {
87
89
  if (err) {
88
90
  callback(err);
@@ -93,42 +95,69 @@ function install(versionExpression, options, callback) {
93
95
  callback(null, result);
94
96
  return;
95
97
  }
96
- var queue = new _queuecb.default(1);
97
- queue.defer(_mkdirpclassic.default.bind(null, options.cachePath));
98
- queue.defer(_ensureDestinationParentts.default.bind(null, result.installPath));
99
- // Install node if missing
100
- !~missing.indexOf('node') || queue.defer(_indexts.default.bind(null, version, result.installPath, options));
101
- // Check and install npm AFTER node (so bundled npm is detected)
102
- // Skip npm download only if bundled npm is modern (6+); old npm (<6) was buggy
103
- queue.defer(function(cb) {
104
- (0, _checkMissingts.default)(result.installPath, options, function(err, npmMissing) {
105
- if (err) {
106
- cb(err);
107
- return;
108
- }
109
- if (!~npmMissing.indexOf('npm')) {
110
- // npm is present - check if it's modern enough to keep (npm >= 3 is stable)
111
- var dist = (0, _nodefilenametodistpaths.getDist)(version);
112
- var bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;
113
- if (bundledNpmMajor >= 3) {
114
- cb(); // npm >= 3 bundled, skip download
98
+ // Something is missing - use atomic pattern with temp folder
99
+ // First, remove any partial installation to avoid conflicts
100
+ (0, _fsremovecompat.safeRm)(result.installPath, function() {
101
+ var tempPath = (0, _tempsuffix.default)(result.installPath);
102
+ var queue = new _queuecb.default(1);
103
+ queue.defer(_mkdirpclassic.default.bind(null, options.cachePath));
104
+ queue.defer(_ensureDestinationParentts.default.bind(null, tempPath));
105
+ // Install node to temp folder
106
+ queue.defer(_indexts.default.bind(null, version, tempPath, options));
107
+ // Check and install npm to temp folder
108
+ // Skip npm download only if bundled npm is modern (>= 3)
109
+ queue.defer(function(cb) {
110
+ (0, _checkMissingts.default)(tempPath, options, function(err, npmMissing) {
111
+ if (err) {
112
+ cb(err);
115
113
  return;
116
114
  }
117
- // old npm (<3) is buggy - delete it so installNPM can override
118
- var platform = options.platform;
119
- var libPath = platform === 'win32' ? result.installPath : _path.default.join(result.installPath, 'lib');
120
- var npmPath = _path.default.join(libPath, 'node_modules', 'npm');
121
- (0, _fsremovecompat.safeRm)(npmPath, function() {
122
- return (0, _indexts1.default)(version, result.installPath, options, cb);
115
+ if (!~npmMissing.indexOf('npm')) {
116
+ // npm is present (bundled with node) - check if it's modern enough to keep
117
+ var dist = (0, _nodefilenametodistpaths.getDist)(version);
118
+ var bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;
119
+ if (bundledNpmMajor >= 3) {
120
+ cb(); // npm >= 3 bundled, skip download
121
+ return;
122
+ }
123
+ // old npm (<3) is buggy - delete it so installNPM can override
124
+ var platform = options.platform;
125
+ var libPath = platform === 'win32' ? tempPath : _path.default.join(tempPath, 'lib');
126
+ var npmPath = _path.default.join(libPath, 'node_modules', 'npm');
127
+ (0, _fsremovecompat.safeRm)(npmPath, function() {
128
+ return (0, _indexts1.default)(version, tempPath, options, cb);
129
+ });
130
+ return;
131
+ }
132
+ (0, _indexts1.default)(version, tempPath, options, cb);
133
+ });
134
+ });
135
+ // Atomic rename: move temp folder to final destination
136
+ queue.defer(function(cb) {
137
+ _fs.default.rename(tempPath, result.installPath, function(err) {
138
+ if (!err) return cb();
139
+ // Race condition: another process may have already created dest
140
+ if (err.code === 'EEXIST' || err.code === 'ENOTEMPTY' || err.code === 'EPERM') {
141
+ // Another process won the race - clean up temp and succeed
142
+ (0, _fsremovecompat.safeRm)(tempPath, function() {
143
+ return cb();
144
+ });
145
+ return;
146
+ }
147
+ cb(err);
148
+ });
149
+ });
150
+ queue.await(function(err) {
151
+ if (err) {
152
+ // Clean up temp folder on error
153
+ (0, _fsremovecompat.safeRm)(tempPath, function() {
154
+ return callback(err);
123
155
  });
124
156
  return;
125
157
  }
126
- (0, _indexts1.default)(version, result.installPath, options, cb);
158
+ callback(null, result);
127
159
  });
128
160
  });
129
- queue.await(function(err) {
130
- return err ? callback(err) : callback(null, result);
131
- });
132
161
  });
133
162
  });
134
163
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/workers/install.ts"],"sourcesContent":["import { safeRm } from 'fs-remove-compat';\nimport isVersion from 'is-version';\nimport mkdirp from 'mkdirp-classic';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport resolveVersions from 'node-resolve-versions';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport { DEFAULT_STORAGE_PATHS } from '../constants.ts';\n\nimport createResult from '../createResult.ts';\nimport createStoragePaths from '../createStoragePaths.ts';\nimport installNode from '../installNode/index.ts';\n\nimport installNPM from '../installNPM/index.ts';\nimport checkMissing from '../lib/checkMissing.ts';\nimport ensureDestinationParent from '../lib/ensureDestinationParent.ts';\nimport getTarget from '../lib/getTarget.ts';\n\nimport type { InstallCallback, InstallOptions } from '../types.ts';\n\ntype GetVersionsCallback = (error?: Error, results?: string[]) => undefined;\nfunction getVersions(versionExpression: string, options: InstallOptions, callback: GetVersionsCallback): undefined {\n // short circuit\n isVersion(versionExpression) ? callback(null, [versionExpression]) : resolveVersions(versionExpression, options, callback);\n}\n\nexport default function install(versionExpression: string, options: InstallOptions, callback: InstallCallback): undefined {\n const storagePaths = options.storagePath ? createStoragePaths(options.storagePath) : DEFAULT_STORAGE_PATHS;\n options = { ...storagePaths, ...options, ...getTarget(options) };\n getVersions(versionExpression, options, (err?: Error, versions?: string[]): undefined => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`Could not resolve versions for: ${versionExpression}`));\n return;\n }\n if (versions.length !== 1) {\n callback(new Error(`Version ${versionExpression} resolved to multiple versions: ${versions.map((x) => x)}. Expecting one.`));\n return;\n }\n\n const version = versions[0];\n const result = createResult(options, version);\n\n // Check if node is missing first\n checkMissing(result.installPath, options, (err, missing): undefined => {\n if (err) {\n callback(err);\n return;\n }\n\n // Early exit if both node and npm are already present\n if (!missing.length) {\n callback(null, result);\n return;\n }\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, options.cachePath));\n queue.defer(ensureDestinationParent.bind(null, result.installPath));\n\n // Install node if missing\n !~missing.indexOf('node') || queue.defer(installNode.bind(null, version, result.installPath, options));\n\n // Check and install npm AFTER node (so bundled npm is detected)\n // Skip npm download only if bundled npm is modern (6+); old npm (<6) was buggy\n queue.defer((cb) => {\n checkMissing(result.installPath, options, (err, npmMissing): undefined => {\n if (err) {\n cb(err);\n return;\n }\n if (!~npmMissing.indexOf('npm')) {\n // npm is present - check if it's modern enough to keep (npm >= 3 is stable)\n const dist = getDist(version);\n const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;\n if (bundledNpmMajor >= 3) {\n cb(); // npm >= 3 bundled, skip download\n return;\n }\n // old npm (<3) is buggy - delete it so installNPM can override\n const platform = options.platform;\n const libPath = platform === 'win32' ? result.installPath : path.join(result.installPath, 'lib');\n const npmPath = path.join(libPath, 'node_modules', 'npm');\n safeRm(npmPath, () => installNPM(version, result.installPath, options, cb));\n return;\n }\n installNPM(version, result.installPath, options, cb);\n });\n });\n\n queue.await((err) => (err ? callback(err) : callback(null, result)));\n });\n });\n}\n"],"names":["install","getVersions","versionExpression","options","callback","isVersion","resolveVersions","storagePaths","storagePath","createStoragePaths","DEFAULT_STORAGE_PATHS","getTarget","err","versions","length","Error","map","x","version","result","createResult","checkMissing","installPath","missing","queue","Queue","defer","mkdirp","bind","cachePath","ensureDestinationParent","indexOf","installNode","cb","npmMissing","dist","getDist","bundledNpmMajor","npm","split","platform","libPath","path","join","npmPath","safeRm","installNPM","await"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/workers/install.ts"],"sourcesContent":["import fs from 'fs';\nimport { safeRm } from 'fs-remove-compat';\nimport isVersion from 'is-version';\nimport mkdirp from 'mkdirp-classic';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport resolveVersions from 'node-resolve-versions';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport tempSuffix from 'temp-suffix';\n\nimport { DEFAULT_STORAGE_PATHS } from '../constants.ts';\n\nimport createResult from '../createResult.ts';\nimport createStoragePaths from '../createStoragePaths.ts';\nimport installNode from '../installNode/index.ts';\n\nimport installNPM from '../installNPM/index.ts';\nimport checkMissing from '../lib/checkMissing.ts';\nimport ensureDestinationParent from '../lib/ensureDestinationParent.ts';\nimport getTarget from '../lib/getTarget.ts';\n\nimport type { InstallCallback, InstallOptions } from '../types.ts';\n\ntype GetVersionsCallback = (error?: Error, results?: string[]) => undefined;\nfunction getVersions(versionExpression: string, options: InstallOptions, callback: GetVersionsCallback): undefined {\n // short circuit\n isVersion(versionExpression) ? callback(null, [versionExpression]) : resolveVersions(versionExpression, options, callback);\n}\n\nexport default function install(versionExpression: string, options: InstallOptions, callback: InstallCallback): undefined {\n const storagePaths = options.storagePath ? createStoragePaths(options.storagePath) : DEFAULT_STORAGE_PATHS;\n options = { ...storagePaths, ...options, ...getTarget(options) };\n getVersions(versionExpression, options, (err?: Error, versions?: string[]): undefined => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`Could not resolve versions for: ${versionExpression}`));\n return;\n }\n if (versions.length !== 1) {\n callback(new Error(`Version ${versionExpression} resolved to multiple versions: ${versions.map((x) => x)}. Expecting one.`));\n return;\n }\n\n const version = versions[0];\n const result = createResult(options, version);\n\n // Fast path: check if installation is complete\n checkMissing(result.installPath, options, (err, missing): undefined => {\n if (err) {\n callback(err);\n return;\n }\n\n // Early exit if both node and npm are already present\n if (!missing.length) {\n callback(null, result);\n return;\n }\n\n // Something is missing - use atomic pattern with temp folder\n // First, remove any partial installation to avoid conflicts\n safeRm(result.installPath, () => {\n const tempPath = tempSuffix(result.installPath);\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, options.cachePath));\n queue.defer(ensureDestinationParent.bind(null, tempPath));\n\n // Install node to temp folder\n queue.defer(installNode.bind(null, version, tempPath, options));\n\n // Check and install npm to temp folder\n // Skip npm download only if bundled npm is modern (>= 3)\n queue.defer((cb) => {\n checkMissing(tempPath, options, (err, npmMissing): undefined => {\n if (err) {\n cb(err);\n return;\n }\n if (!~npmMissing.indexOf('npm')) {\n // npm is present (bundled with node) - check if it's modern enough to keep\n const dist = getDist(version);\n const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;\n if (bundledNpmMajor >= 3) {\n cb(); // npm >= 3 bundled, skip download\n return;\n }\n // old npm (<3) is buggy - delete it so installNPM can override\n const platform = options.platform;\n const libPath = platform === 'win32' ? tempPath : path.join(tempPath, 'lib');\n const npmPath = path.join(libPath, 'node_modules', 'npm');\n safeRm(npmPath, () => installNPM(version, tempPath, options, cb));\n return;\n }\n installNPM(version, tempPath, options, cb);\n });\n });\n\n // Atomic rename: move temp folder to final destination\n queue.defer((cb) => {\n fs.rename(tempPath, result.installPath, (err) => {\n if (!err) return cb();\n // Race condition: another process may have already created dest\n if (err.code === 'EEXIST' || err.code === 'ENOTEMPTY' || err.code === 'EPERM') {\n // Another process won the race - clean up temp and succeed\n safeRm(tempPath, () => cb());\n return;\n }\n cb(err);\n });\n });\n\n queue.await((err) => {\n if (err) {\n // Clean up temp folder on error\n safeRm(tempPath, () => callback(err));\n return;\n }\n callback(null, result);\n });\n });\n });\n });\n}\n"],"names":["install","getVersions","versionExpression","options","callback","isVersion","resolveVersions","storagePaths","storagePath","createStoragePaths","DEFAULT_STORAGE_PATHS","getTarget","err","versions","length","Error","map","x","version","result","createResult","checkMissing","installPath","missing","safeRm","tempPath","tempSuffix","queue","Queue","defer","mkdirp","bind","cachePath","ensureDestinationParent","installNode","cb","npmMissing","indexOf","dist","getDist","bundledNpmMajor","npm","split","platform","libPath","path","join","npmPath","installNPM","fs","rename","code","await"],"mappings":"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"}
@@ -7,7 +7,7 @@ import path from 'path';
7
7
  import Queue from 'queue-cb';
8
8
  import { NPM_DIST_TAGS_URL, NPM_DIST_URL, NPM_MIN_VERSION } from '../constants.js';
9
9
  import conditionalCache from '../lib/conditionalCache.js';
10
- import conditionalExtract from '../lib/conditionalExtract.js';
10
+ import extract from '../lib/extract.js';
11
11
  function calculateChecksum(filePath, callback) {
12
12
  const hash = crypto.createHash('sha256');
13
13
  const stream = fs.createReadStream(filePath);
@@ -44,7 +44,7 @@ export default function installLib(version, dest, options, callback) {
44
44
  cb(err);
45
45
  });
46
46
  });
47
- queue.defer(conditionalExtract.bind(null, cachePath, installPath));
47
+ queue.defer(extract.bind(null, cachePath, installPath));
48
48
  queue.await((err)=>{
49
49
  err ? callback(err) : callback(null, npmVersion, checksum);
50
50
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNPM/installLib.ts"],"sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport get from 'get-remote';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport oo from 'on-one';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport { NPM_DIST_TAGS_URL, NPM_DIST_URL, NPM_MIN_VERSION } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport conditionalExtract from '../lib/conditionalExtract.ts';\n\ninterface DistRecord {\n latest: string;\n}\n\nimport type { InstallOptions } from '../types.ts';\n\nexport type Callback = (error?: Error, npmVersion?: string, checksum?: string) => undefined;\n\nfunction calculateChecksum(filePath: string, callback: (err?: Error, checksum?: string) => void): void {\n const hash = crypto.createHash('sha256');\n const stream = fs.createReadStream(filePath);\n stream.on('data', (data) => hash.update(data));\n oo(stream, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (err) return callback(err);\n callback(null, hash.digest('hex'));\n });\n}\n\nexport default function installLib(version: string, dest: string, options: InstallOptions, callback: Callback): undefined {\n const platform = options.platform;\n const libPath = platform === 'win32' ? dest : path.join(dest, 'lib');\n const installPath = path.join(libPath, 'node_modules', 'npm');\n\n const dist = getDist(version);\n const npmMajorPair = dist && dist.npm ? +dist.npm.split('.')[0] : NPM_MIN_VERSION;\n const npmMajor = Math.max(npmMajorPair, NPM_MIN_VERSION);\n\n get(NPM_DIST_TAGS_URL).json((err, res) => {\n if (err) return callback(err);\n const distTags = res.body as DistRecord;\n const npmVersion = distTags[`latest-${npmMajor}`] || distTags[`next-${npmMajor}`] || distTags.latest;\n const downloadPath = `${NPM_DIST_URL}/-/npm-${npmVersion}.tgz`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: string | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n calculateChecksum(cachePath, (err, hash) => {\n checksum = hash;\n cb(err);\n });\n });\n queue.defer(conditionalExtract.bind(null, cachePath, installPath));\n queue.await((err) => {\n err ? callback(err) : callback(null, npmVersion, checksum);\n });\n });\n}\n"],"names":["crypto","fs","get","getDist","oo","path","Queue","NPM_DIST_TAGS_URL","NPM_DIST_URL","NPM_MIN_VERSION","conditionalCache","conditionalExtract","calculateChecksum","filePath","callback","hash","createHash","stream","createReadStream","on","data","update","err","digest","installLib","version","dest","options","platform","libPath","join","installPath","dist","npmMajorPair","npm","split","npmMajor","Math","max","json","res","distTags","body","npmVersion","latest","downloadPath","cachePath","basename","checksum","queue","defer","bind","cb","await"],"mappings":"AAAA,OAAOA,YAAY,SAAS;AAC5B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,SAAS,aAAa;AAC7B,SAASC,OAAO,QAAQ,8BAA8B;AACtD,OAAOC,QAAQ,SAAS;AACxB,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAC7B,SAASC,iBAAiB,EAAEC,YAAY,EAAEC,eAAe,QAAQ,kBAAkB;AACnF,OAAOC,sBAAsB,6BAA6B;AAC1D,OAAOC,wBAAwB,+BAA+B;AAU9D,SAASC,kBAAkBC,QAAgB,EAAEC,QAAkD;IAC7F,MAAMC,OAAOf,OAAOgB,UAAU,CAAC;IAC/B,MAAMC,SAAShB,GAAGiB,gBAAgB,CAACL;IACnCI,OAAOE,EAAE,CAAC,QAAQ,CAACC,OAASL,KAAKM,MAAM,CAACD;IACxChB,GAAGa,QAAQ;QAAC;QAAS;QAAO;QAAS;KAAS,EAAE,CAACK;QAC/C,IAAIA,KAAK,OAAOR,SAASQ;QACzBR,SAAS,MAAMC,KAAKQ,MAAM,CAAC;IAC7B;AACF;AAEA,eAAe,SAASC,WAAWC,OAAe,EAAEC,IAAY,EAAEC,OAAuB,EAAEb,QAAkB;IAC3G,MAAMc,WAAWD,QAAQC,QAAQ;IACjC,MAAMC,UAAUD,aAAa,UAAUF,OAAOrB,KAAKyB,IAAI,CAACJ,MAAM;IAC9D,MAAMK,cAAc1B,KAAKyB,IAAI,CAACD,SAAS,gBAAgB;IAEvD,MAAMG,OAAO7B,QAAQsB;IACrB,MAAMQ,eAAeD,QAAQA,KAAKE,GAAG,GAAG,CAACF,KAAKE,GAAG,CAACC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG1B;IAClE,MAAM2B,WAAWC,KAAKC,GAAG,CAACL,cAAcxB;IAExCP,IAAIK,mBAAmBgC,IAAI,CAAC,CAACjB,KAAKkB;QAChC,IAAIlB,KAAK,OAAOR,SAASQ;QACzB,MAAMmB,WAAWD,IAAIE,IAAI;QACzB,MAAMC,aAAaF,QAAQ,CAAC,CAAC,OAAO,EAAEL,UAAU,CAAC,IAAIK,QAAQ,CAAC,CAAC,KAAK,EAAEL,UAAU,CAAC,IAAIK,SAASG,MAAM;QACpG,MAAMC,eAAe,GAAGrC,aAAa,OAAO,EAAEmC,WAAW,IAAI,CAAC;QAC9D,MAAMG,YAAYzC,KAAKyB,IAAI,CAACH,QAAQmB,SAAS,EAAEzC,KAAK0C,QAAQ,CAACF;QAE7D,IAAIG;QACJ,MAAMC,QAAQ,IAAI3C,MAAM;QACxB2C,MAAMC,KAAK,CAACxC,iBAAiByC,IAAI,CAAC,MAAMN,cAAcC;QACtDG,MAAMC,KAAK,CAAC,CAACE;YACXxC,kBAAkBkC,WAAW,CAACxB,KAAKP;gBACjCiC,WAAWjC;gBACXqC,GAAG9B;YACL;QACF;QACA2B,MAAMC,KAAK,CAACvC,mBAAmBwC,IAAI,CAAC,MAAML,WAAWf;QACrDkB,MAAMI,KAAK,CAAC,CAAC/B;YACXA,MAAMR,SAASQ,OAAOR,SAAS,MAAM6B,YAAYK;QACnD;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNPM/installLib.ts"],"sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport get from 'get-remote';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport oo from 'on-one';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport { NPM_DIST_TAGS_URL, NPM_DIST_URL, NPM_MIN_VERSION } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport extract from '../lib/extract.ts';\n\ninterface DistRecord {\n latest: string;\n}\n\nimport type { InstallOptions } from '../types.ts';\n\nexport type Callback = (error?: Error, npmVersion?: string, checksum?: string) => undefined;\n\nfunction calculateChecksum(filePath: string, callback: (err?: Error, checksum?: string) => void): void {\n const hash = crypto.createHash('sha256');\n const stream = fs.createReadStream(filePath);\n stream.on('data', (data) => hash.update(data));\n oo(stream, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (err) return callback(err);\n callback(null, hash.digest('hex'));\n });\n}\n\nexport default function installLib(version: string, dest: string, options: InstallOptions, callback: Callback): undefined {\n const platform = options.platform;\n const libPath = platform === 'win32' ? dest : path.join(dest, 'lib');\n const installPath = path.join(libPath, 'node_modules', 'npm');\n\n const dist = getDist(version);\n const npmMajorPair = dist && dist.npm ? +dist.npm.split('.')[0] : NPM_MIN_VERSION;\n const npmMajor = Math.max(npmMajorPair, NPM_MIN_VERSION);\n\n get(NPM_DIST_TAGS_URL).json((err, res) => {\n if (err) return callback(err);\n const distTags = res.body as DistRecord;\n const npmVersion = distTags[`latest-${npmMajor}`] || distTags[`next-${npmMajor}`] || distTags.latest;\n const downloadPath = `${NPM_DIST_URL}/-/npm-${npmVersion}.tgz`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: string | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n calculateChecksum(cachePath, (err, hash) => {\n checksum = hash;\n cb(err);\n });\n });\n queue.defer(extract.bind(null, cachePath, installPath));\n queue.await((err) => {\n err ? callback(err) : callback(null, npmVersion, checksum);\n });\n });\n}\n"],"names":["crypto","fs","get","getDist","oo","path","Queue","NPM_DIST_TAGS_URL","NPM_DIST_URL","NPM_MIN_VERSION","conditionalCache","extract","calculateChecksum","filePath","callback","hash","createHash","stream","createReadStream","on","data","update","err","digest","installLib","version","dest","options","platform","libPath","join","installPath","dist","npmMajorPair","npm","split","npmMajor","Math","max","json","res","distTags","body","npmVersion","latest","downloadPath","cachePath","basename","checksum","queue","defer","bind","cb","await"],"mappings":"AAAA,OAAOA,YAAY,SAAS;AAC5B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,SAAS,aAAa;AAC7B,SAASC,OAAO,QAAQ,8BAA8B;AACtD,OAAOC,QAAQ,SAAS;AACxB,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAC7B,SAASC,iBAAiB,EAAEC,YAAY,EAAEC,eAAe,QAAQ,kBAAkB;AACnF,OAAOC,sBAAsB,6BAA6B;AAC1D,OAAOC,aAAa,oBAAoB;AAUxC,SAASC,kBAAkBC,QAAgB,EAAEC,QAAkD;IAC7F,MAAMC,OAAOf,OAAOgB,UAAU,CAAC;IAC/B,MAAMC,SAAShB,GAAGiB,gBAAgB,CAACL;IACnCI,OAAOE,EAAE,CAAC,QAAQ,CAACC,OAASL,KAAKM,MAAM,CAACD;IACxChB,GAAGa,QAAQ;QAAC;QAAS;QAAO;QAAS;KAAS,EAAE,CAACK;QAC/C,IAAIA,KAAK,OAAOR,SAASQ;QACzBR,SAAS,MAAMC,KAAKQ,MAAM,CAAC;IAC7B;AACF;AAEA,eAAe,SAASC,WAAWC,OAAe,EAAEC,IAAY,EAAEC,OAAuB,EAAEb,QAAkB;IAC3G,MAAMc,WAAWD,QAAQC,QAAQ;IACjC,MAAMC,UAAUD,aAAa,UAAUF,OAAOrB,KAAKyB,IAAI,CAACJ,MAAM;IAC9D,MAAMK,cAAc1B,KAAKyB,IAAI,CAACD,SAAS,gBAAgB;IAEvD,MAAMG,OAAO7B,QAAQsB;IACrB,MAAMQ,eAAeD,QAAQA,KAAKE,GAAG,GAAG,CAACF,KAAKE,GAAG,CAACC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG1B;IAClE,MAAM2B,WAAWC,KAAKC,GAAG,CAACL,cAAcxB;IAExCP,IAAIK,mBAAmBgC,IAAI,CAAC,CAACjB,KAAKkB;QAChC,IAAIlB,KAAK,OAAOR,SAASQ;QACzB,MAAMmB,WAAWD,IAAIE,IAAI;QACzB,MAAMC,aAAaF,QAAQ,CAAC,CAAC,OAAO,EAAEL,UAAU,CAAC,IAAIK,QAAQ,CAAC,CAAC,KAAK,EAAEL,UAAU,CAAC,IAAIK,SAASG,MAAM;QACpG,MAAMC,eAAe,GAAGrC,aAAa,OAAO,EAAEmC,WAAW,IAAI,CAAC;QAC9D,MAAMG,YAAYzC,KAAKyB,IAAI,CAACH,QAAQmB,SAAS,EAAEzC,KAAK0C,QAAQ,CAACF;QAE7D,IAAIG;QACJ,MAAMC,QAAQ,IAAI3C,MAAM;QACxB2C,MAAMC,KAAK,CAACxC,iBAAiByC,IAAI,CAAC,MAAMN,cAAcC;QACtDG,MAAMC,KAAK,CAAC,CAACE;YACXxC,kBAAkBkC,WAAW,CAACxB,KAAKP;gBACjCiC,WAAWjC;gBACXqC,GAAG9B;YACL;QACF;QACA2B,MAAMC,KAAK,CAACvC,QAAQwC,IAAI,CAAC,MAAML,WAAWf;QAC1CkB,MAAMI,KAAK,CAAC,CAAC/B;YACXA,MAAMR,SAASQ,OAAOR,SAAS,MAAM6B,YAAYK;QACnD;IACF;AACF"}
@@ -1,28 +1,24 @@
1
- import fs from 'fs';
2
1
  import path from 'path';
3
2
  import Queue from 'queue-cb';
4
3
  import { NODE_DIST_BASE_URL } from '../constants.js';
5
4
  import conditionalCache from '../lib/conditionalCache.js';
6
- import conditionalExtract from '../lib/conditionalExtract.js';
5
+ import extract from '../lib/extract.js';
7
6
  import validateDownload from './validateDownload.js';
8
7
  export default function installCompressed(distPath, dest, options, callback) {
9
8
  const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;
10
9
  const cachePath = path.join(options.cachePath, path.basename(downloadPath));
11
- fs.stat(dest, (err)=>{
12
- if (!err) return callback(); // already exists
13
- let checksum;
14
- const queue = new Queue(1);
15
- queue.defer(conditionalCache.bind(null, downloadPath, cachePath));
16
- queue.defer((cb)=>{
17
- validateDownload(distPath, cachePath, (err, result)=>{
18
- checksum = result;
19
- cb(err);
20
- });
10
+ let checksum;
11
+ const queue = new Queue(1);
12
+ queue.defer(conditionalCache.bind(null, downloadPath, cachePath));
13
+ queue.defer((cb)=>{
14
+ validateDownload(distPath, cachePath, (err, result)=>{
15
+ checksum = result;
16
+ cb(err);
21
17
  });
22
- queue.defer(conditionalExtract.bind(null, cachePath, dest, {
23
- strip: 1,
24
- time: 1000
25
- }));
26
- queue.await((err)=>callback(err, checksum));
27
18
  });
19
+ queue.defer(extract.bind(null, cachePath, dest, {
20
+ strip: 1,
21
+ time: 1000
22
+ }));
23
+ queue.await((err)=>callback(err, checksum));
28
24
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installCompressed.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport conditionalExtract from '../lib/conditionalExtract.ts';\nimport type { ChecksumCallback, ChecksumResult, InstallOptions } from '../types.ts';\nimport validateDownload from './validateDownload.ts';\n\nexport default function installCompressed(distPath: string, dest: string, options: InstallOptions, callback: ChecksumCallback): undefined {\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n fs.stat(dest, (err) => {\n if (!err) return callback(); // already exists\n\n let checksum: ChecksumResult | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n validateDownload(distPath, cachePath, (err, result) => {\n checksum = result;\n cb(err);\n });\n });\n queue.defer(conditionalExtract.bind(null, cachePath, dest, { strip: 1, time: 1000 }));\n queue.await((err) => callback(err, checksum));\n });\n}\n"],"names":["fs","path","Queue","NODE_DIST_BASE_URL","conditionalCache","conditionalExtract","validateDownload","installCompressed","distPath","dest","options","callback","downloadPath","cachePath","join","basename","stat","err","checksum","queue","defer","bind","cb","result","strip","time","await"],"mappings":"AAAA,OAAOA,QAAQ,KAAK;AACpB,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAE7B,SAASC,kBAAkB,QAAQ,kBAAkB;AACrD,OAAOC,sBAAsB,6BAA6B;AAC1D,OAAOC,wBAAwB,+BAA+B;AAE9D,OAAOC,sBAAsB,wBAAwB;AAErD,eAAe,SAASC,kBAAkBC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAA0B;IAC3H,MAAMC,eAAe,GAAGT,mBAAmB,CAAC,EAAEK,UAAU;IACxD,MAAMK,YAAYZ,KAAKa,IAAI,CAACJ,QAAQG,SAAS,EAAEZ,KAAKc,QAAQ,CAACH;IAE7DZ,GAAGgB,IAAI,CAACP,MAAM,CAACQ;QACb,IAAI,CAACA,KAAK,OAAON,YAAY,iBAAiB;QAE9C,IAAIO;QACJ,MAAMC,QAAQ,IAAIjB,MAAM;QACxBiB,MAAMC,KAAK,CAAChB,iBAAiBiB,IAAI,CAAC,MAAMT,cAAcC;QACtDM,MAAMC,KAAK,CAAC,CAACE;YACXhB,iBAAiBE,UAAUK,WAAW,CAACI,KAAKM;gBAC1CL,WAAWK;gBACXD,GAAGL;YACL;QACF;QACAE,MAAMC,KAAK,CAACf,mBAAmBgB,IAAI,CAAC,MAAMR,WAAWJ,MAAM;YAAEe,OAAO;YAAGC,MAAM;QAAK;QAClFN,MAAMO,KAAK,CAAC,CAACT,MAAQN,SAASM,KAAKC;IACrC;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installCompressed.ts"],"sourcesContent":["import path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../constants.ts';\nimport conditionalCache from '../lib/conditionalCache.ts';\nimport extract from '../lib/extract.ts';\nimport type { ChecksumCallback, ChecksumResult, InstallOptions } from '../types.ts';\nimport validateDownload from './validateDownload.ts';\n\nexport default function installCompressed(distPath: string, dest: string, options: InstallOptions, callback: ChecksumCallback): undefined {\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n let checksum: ChecksumResult | undefined;\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer((cb) => {\n validateDownload(distPath, cachePath, (err, result) => {\n checksum = result;\n cb(err);\n });\n });\n queue.defer(extract.bind(null, cachePath, dest, { strip: 1, time: 1000 }));\n queue.await((err) => callback(err, checksum));\n}\n"],"names":["path","Queue","NODE_DIST_BASE_URL","conditionalCache","extract","validateDownload","installCompressed","distPath","dest","options","callback","downloadPath","cachePath","join","basename","checksum","queue","defer","bind","cb","err","result","strip","time","await"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAE7B,SAASC,kBAAkB,QAAQ,kBAAkB;AACrD,OAAOC,sBAAsB,6BAA6B;AAC1D,OAAOC,aAAa,oBAAoB;AAExC,OAAOC,sBAAsB,wBAAwB;AAErD,eAAe,SAASC,kBAAkBC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAA0B;IAC3H,MAAMC,eAAe,GAAGT,mBAAmB,CAAC,EAAEK,UAAU;IACxD,MAAMK,YAAYZ,KAAKa,IAAI,CAACJ,QAAQG,SAAS,EAAEZ,KAAKc,QAAQ,CAACH;IAE7D,IAAII;IACJ,MAAMC,QAAQ,IAAIf,MAAM;IACxBe,MAAMC,KAAK,CAACd,iBAAiBe,IAAI,CAAC,MAAMP,cAAcC;IACtDI,MAAMC,KAAK,CAAC,CAACE;QACXd,iBAAiBE,UAAUK,WAAW,CAACQ,KAAKC;YAC1CN,WAAWM;YACXF,GAAGC;QACL;IACF;IACAJ,MAAMC,KAAK,CAACb,QAAQc,IAAI,CAAC,MAAMN,WAAWJ,MAAM;QAAEc,OAAO;QAAGC,MAAM;IAAK;IACvEP,MAAMQ,KAAK,CAAC,CAACJ,MAAQV,SAASU,KAAKL;AACrC"}
@@ -1,8 +1,10 @@
1
+ import { safeRm } from 'fs-remove-compat';
1
2
  import path from 'path';
2
3
  import Queue from 'queue-cb';
4
+ import tempSuffix from 'temp-suffix';
3
5
  import { NODE_DIST_BASE_URL } from '../../constants.js';
4
6
  import conditionalCache from '../../lib/conditionalCache.js';
5
- import conditionalExtract from '../../lib/conditionalExtract.js';
7
+ import extract from '../../lib/extract.js';
6
8
  import validateDownload from '../validateDownload.js';
7
9
  import buildPosix from './buildPosix.js';
8
10
  import buildWin32 from './buildWin32.js';
@@ -10,14 +12,16 @@ export default function InstallSource(distPath, dest, options, callback) {
10
12
  const platform = options.platform;
11
13
  const build = platform === 'win32' ? buildWin32 : buildPosix;
12
14
  const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;
13
- const buildPath = path.join(options.buildPath, path.basename(distPath));
15
+ // Use temp build path to avoid race conditions with parallel builds
16
+ const tempBuildPath = tempSuffix(path.join(options.buildPath, path.basename(distPath)));
14
17
  const cachePath = path.join(options.cachePath, path.basename(downloadPath));
15
18
  const queue = new Queue(1);
16
19
  queue.defer(conditionalCache.bind(null, downloadPath, cachePath));
17
20
  queue.defer(validateDownload.bind(null, distPath, cachePath));
18
- queue.defer(conditionalExtract.bind(null, cachePath, buildPath, {
19
- strip: 1
20
- }));
21
- queue.defer(build.bind(null, buildPath, dest, options));
22
- queue.await(callback);
21
+ queue.defer(extract.bind(null, cachePath, tempBuildPath));
22
+ queue.defer(build.bind(null, tempBuildPath, dest, options));
23
+ queue.await((err)=>{
24
+ // Always clean up temp build directory
25
+ safeRm(tempBuildPath, ()=>callback(err));
26
+ });
23
27
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installSource/index.ts"],"sourcesContent":["import path from 'path';\nimport Queue from 'queue-cb';\n\nimport { NODE_DIST_BASE_URL } from '../../constants.ts';\nimport conditionalCache from '../../lib/conditionalCache.ts';\nimport conditionalExtract from '../../lib/conditionalExtract.ts';\nimport type { InstallOptions, NoParamCallback } from '../../types.ts';\nimport validateDownload from '../validateDownload.ts';\nimport buildPosix from './buildPosix.ts';\nimport buildWin32 from './buildWin32.ts';\n\nexport default function InstallSource(distPath: string, dest: string, options: InstallOptions, callback: NoParamCallback): undefined {\n const platform = options.platform;\n const build = platform === 'win32' ? buildWin32 : buildPosix;\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n const buildPath = path.join(options.buildPath, path.basename(distPath));\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer(validateDownload.bind(null, distPath, cachePath));\n queue.defer(conditionalExtract.bind(null, cachePath, buildPath, { strip: 1 }));\n queue.defer(build.bind(null, buildPath, dest, options));\n queue.await(callback);\n}\n"],"names":["path","Queue","NODE_DIST_BASE_URL","conditionalCache","conditionalExtract","validateDownload","buildPosix","buildWin32","InstallSource","distPath","dest","options","callback","platform","build","downloadPath","buildPath","join","basename","cachePath","queue","defer","bind","strip","await"],"mappings":"AAAA,OAAOA,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAE7B,SAASC,kBAAkB,QAAQ,qBAAqB;AACxD,OAAOC,sBAAsB,gCAAgC;AAC7D,OAAOC,wBAAwB,kCAAkC;AAEjE,OAAOC,sBAAsB,yBAAyB;AACtD,OAAOC,gBAAgB,kBAAkB;AACzC,OAAOC,gBAAgB,kBAAkB;AAEzC,eAAe,SAASC,cAAcC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAAyB;IACtH,MAAMC,WAAWF,QAAQE,QAAQ;IACjC,MAAMC,QAAQD,aAAa,UAAUN,aAAaD;IAClD,MAAMS,eAAe,GAAGb,mBAAmB,CAAC,EAAEO,UAAU;IACxD,MAAMO,YAAYhB,KAAKiB,IAAI,CAACN,QAAQK,SAAS,EAAEhB,KAAKkB,QAAQ,CAACT;IAC7D,MAAMU,YAAYnB,KAAKiB,IAAI,CAACN,QAAQQ,SAAS,EAAEnB,KAAKkB,QAAQ,CAACH;IAE7D,MAAMK,QAAQ,IAAInB,MAAM;IACxBmB,MAAMC,KAAK,CAAClB,iBAAiBmB,IAAI,CAAC,MAAMP,cAAcI;IACtDC,MAAMC,KAAK,CAAChB,iBAAiBiB,IAAI,CAAC,MAAMb,UAAUU;IAClDC,MAAMC,KAAK,CAACjB,mBAAmBkB,IAAI,CAAC,MAAMH,WAAWH,WAAW;QAAEO,OAAO;IAAE;IAC3EH,MAAMC,KAAK,CAACP,MAAMQ,IAAI,CAAC,MAAMN,WAAWN,MAAMC;IAC9CS,MAAMI,KAAK,CAACZ;AACd"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/installNode/installSource/index.ts"],"sourcesContent":["import { safeRm } from 'fs-remove-compat';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport tempSuffix from 'temp-suffix';\n\nimport { NODE_DIST_BASE_URL } from '../../constants.ts';\nimport conditionalCache from '../../lib/conditionalCache.ts';\nimport extract from '../../lib/extract.ts';\nimport type { InstallOptions, NoParamCallback } from '../../types.ts';\nimport validateDownload from '../validateDownload.ts';\nimport buildPosix from './buildPosix.ts';\nimport buildWin32 from './buildWin32.ts';\n\nexport default function InstallSource(distPath: string, dest: string, options: InstallOptions, callback: NoParamCallback): undefined {\n const platform = options.platform;\n const build = platform === 'win32' ? buildWin32 : buildPosix;\n const downloadPath = `${NODE_DIST_BASE_URL}/${distPath}`;\n // Use temp build path to avoid race conditions with parallel builds\n const tempBuildPath = tempSuffix(path.join(options.buildPath, path.basename(distPath)));\n const cachePath = path.join(options.cachePath, path.basename(downloadPath));\n\n const queue = new Queue(1);\n queue.defer(conditionalCache.bind(null, downloadPath, cachePath));\n queue.defer(validateDownload.bind(null, distPath, cachePath));\n queue.defer(extract.bind(null, cachePath, tempBuildPath));\n queue.defer(build.bind(null, tempBuildPath, dest, options));\n queue.await((err) => {\n // Always clean up temp build directory\n safeRm(tempBuildPath, () => callback(err));\n });\n}\n"],"names":["safeRm","path","Queue","tempSuffix","NODE_DIST_BASE_URL","conditionalCache","extract","validateDownload","buildPosix","buildWin32","InstallSource","distPath","dest","options","callback","platform","build","downloadPath","tempBuildPath","join","buildPath","basename","cachePath","queue","defer","bind","await","err"],"mappings":"AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAC7B,OAAOC,gBAAgB,cAAc;AAErC,SAASC,kBAAkB,QAAQ,qBAAqB;AACxD,OAAOC,sBAAsB,gCAAgC;AAC7D,OAAOC,aAAa,uBAAuB;AAE3C,OAAOC,sBAAsB,yBAAyB;AACtD,OAAOC,gBAAgB,kBAAkB;AACzC,OAAOC,gBAAgB,kBAAkB;AAEzC,eAAe,SAASC,cAAcC,QAAgB,EAAEC,IAAY,EAAEC,OAAuB,EAAEC,QAAyB;IACtH,MAAMC,WAAWF,QAAQE,QAAQ;IACjC,MAAMC,QAAQD,aAAa,UAAUN,aAAaD;IAClD,MAAMS,eAAe,GAAGb,mBAAmB,CAAC,EAAEO,UAAU;IACxD,oEAAoE;IACpE,MAAMO,gBAAgBf,WAAWF,KAAKkB,IAAI,CAACN,QAAQO,SAAS,EAAEnB,KAAKoB,QAAQ,CAACV;IAC5E,MAAMW,YAAYrB,KAAKkB,IAAI,CAACN,QAAQS,SAAS,EAAErB,KAAKoB,QAAQ,CAACJ;IAE7D,MAAMM,QAAQ,IAAIrB,MAAM;IACxBqB,MAAMC,KAAK,CAACnB,iBAAiBoB,IAAI,CAAC,MAAMR,cAAcK;IACtDC,MAAMC,KAAK,CAACjB,iBAAiBkB,IAAI,CAAC,MAAMd,UAAUW;IAClDC,MAAMC,KAAK,CAAClB,QAAQmB,IAAI,CAAC,MAAMH,WAAWJ;IAC1CK,MAAMC,KAAK,CAACR,MAAMS,IAAI,CAAC,MAAMP,eAAeN,MAAMC;IAClDU,MAAMG,KAAK,CAAC,CAACC;QACX,uCAAuC;QACvC3B,OAAOkB,eAAe,IAAMJ,SAASa;IACvC;AACF"}
@@ -0,0 +1,7 @@
1
+ import type { NoParamCallback } from '../types.js';
2
+ interface ExtractOptions {
3
+ strip?: number;
4
+ time?: number;
5
+ }
6
+ export default function extract(src: string, dest: string, options: ExtractOptions | NoParamCallback, callback?: NoParamCallback): undefined;
7
+ export {};
@@ -0,0 +1,19 @@
1
+ import fastExtract from 'fast-extract';
2
+ import mkdirp from 'mkdirp-classic';
3
+ import path from 'path';
4
+ import Queue from 'queue-cb';
5
+ export default function extract(src, dest, options, callback) {
6
+ if (typeof options === 'function') {
7
+ callback = options;
8
+ options = {};
9
+ }
10
+ const extractOptions = {
11
+ strip: 1,
12
+ time: 1000,
13
+ ...options
14
+ };
15
+ const queue = new Queue(1);
16
+ queue.defer(mkdirp.bind(null, path.dirname(dest)));
17
+ queue.defer(fastExtract.bind(null, src, dest, extractOptions));
18
+ queue.await(callback);
19
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/lib/extract.ts"],"sourcesContent":["import fastExtract from 'fast-extract';\nimport mkdirp from 'mkdirp-classic';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport type { NoParamCallback } from '../types.ts';\n\ninterface ExtractOptions {\n strip?: number;\n time?: number;\n}\n\nexport default function extract(src: string, dest: string, options: ExtractOptions | NoParamCallback, callback?: NoParamCallback): undefined {\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n\n const extractOptions = { strip: 1, time: 1000, ...options };\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, path.dirname(dest)));\n queue.defer(fastExtract.bind(null, src, dest, extractOptions));\n queue.await(callback);\n}\n"],"names":["fastExtract","mkdirp","path","Queue","extract","src","dest","options","callback","extractOptions","strip","time","queue","defer","bind","dirname","await"],"mappings":"AAAA,OAAOA,iBAAiB,eAAe;AACvC,OAAOC,YAAY,iBAAiB;AACpC,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAS7B,eAAe,SAASC,QAAQC,GAAW,EAAEC,IAAY,EAAEC,OAAyC,EAAEC,QAA0B;IAC9H,IAAI,OAAOD,YAAY,YAAY;QACjCC,WAAWD;QACXA,UAAU,CAAC;IACb;IAEA,MAAME,iBAAiB;QAAEC,OAAO;QAAGC,MAAM;QAAM,GAAGJ,OAAO;IAAC;IAE1D,MAAMK,QAAQ,IAAIT,MAAM;IACxBS,MAAMC,KAAK,CAACZ,OAAOa,IAAI,CAAC,MAAMZ,KAAKa,OAAO,CAACT;IAC3CM,MAAMC,KAAK,CAACb,YAAYc,IAAI,CAAC,MAAMT,KAAKC,MAAMG;IAC9CG,MAAMI,KAAK,CAACR;AACd"}
@@ -1,3 +1,4 @@
1
+ import fs from 'fs';
1
2
  import { safeRm } from 'fs-remove-compat';
2
3
  import isVersion from 'is-version';
3
4
  import mkdirp from 'mkdirp-classic';
@@ -5,6 +6,7 @@ import { getDist } from 'node-filename-to-dist-paths';
5
6
  import resolveVersions from 'node-resolve-versions';
6
7
  import path from 'path';
7
8
  import Queue from 'queue-cb';
9
+ import tempSuffix from 'temp-suffix';
8
10
  import { DEFAULT_STORAGE_PATHS } from '../constants.js';
9
11
  import createResult from '../createResult.js';
10
12
  import createStoragePaths from '../createStoragePaths.js';
@@ -41,7 +43,7 @@ export default function install(versionExpression, options, callback) {
41
43
  }
42
44
  const version = versions[0];
43
45
  const result = createResult(options, version);
44
- // Check if node is missing first
46
+ // Fast path: check if installation is complete
45
47
  checkMissing(result.installPath, options, (err, missing)=>{
46
48
  if (err) {
47
49
  callback(err);
@@ -52,38 +54,63 @@ export default function install(versionExpression, options, callback) {
52
54
  callback(null, result);
53
55
  return;
54
56
  }
55
- const queue = new Queue(1);
56
- queue.defer(mkdirp.bind(null, options.cachePath));
57
- queue.defer(ensureDestinationParent.bind(null, result.installPath));
58
- // Install node if missing
59
- !~missing.indexOf('node') || queue.defer(installNode.bind(null, version, result.installPath, options));
60
- // Check and install npm AFTER node (so bundled npm is detected)
61
- // Skip npm download only if bundled npm is modern (6+); old npm (<6) was buggy
62
- queue.defer((cb)=>{
63
- checkMissing(result.installPath, options, (err, npmMissing)=>{
64
- if (err) {
65
- cb(err);
66
- return;
67
- }
68
- if (!~npmMissing.indexOf('npm')) {
69
- // npm is present - check if it's modern enough to keep (npm >= 3 is stable)
70
- const dist = getDist(version);
71
- const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;
72
- if (bundledNpmMajor >= 3) {
73
- cb(); // npm >= 3 bundled, skip download
57
+ // Something is missing - use atomic pattern with temp folder
58
+ // First, remove any partial installation to avoid conflicts
59
+ safeRm(result.installPath, ()=>{
60
+ const tempPath = tempSuffix(result.installPath);
61
+ const queue = new Queue(1);
62
+ queue.defer(mkdirp.bind(null, options.cachePath));
63
+ queue.defer(ensureDestinationParent.bind(null, tempPath));
64
+ // Install node to temp folder
65
+ queue.defer(installNode.bind(null, version, tempPath, options));
66
+ // Check and install npm to temp folder
67
+ // Skip npm download only if bundled npm is modern (>= 3)
68
+ queue.defer((cb)=>{
69
+ checkMissing(tempPath, options, (err, npmMissing)=>{
70
+ if (err) {
71
+ cb(err);
72
+ return;
73
+ }
74
+ if (!~npmMissing.indexOf('npm')) {
75
+ // npm is present (bundled with node) - check if it's modern enough to keep
76
+ const dist = getDist(version);
77
+ const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;
78
+ if (bundledNpmMajor >= 3) {
79
+ cb(); // npm >= 3 bundled, skip download
80
+ return;
81
+ }
82
+ // old npm (<3) is buggy - delete it so installNPM can override
83
+ const platform = options.platform;
84
+ const libPath = platform === 'win32' ? tempPath : path.join(tempPath, 'lib');
85
+ const npmPath = path.join(libPath, 'node_modules', 'npm');
86
+ safeRm(npmPath, ()=>installNPM(version, tempPath, options, cb));
74
87
  return;
75
88
  }
76
- // old npm (<3) is buggy - delete it so installNPM can override
77
- const platform = options.platform;
78
- const libPath = platform === 'win32' ? result.installPath : path.join(result.installPath, 'lib');
79
- const npmPath = path.join(libPath, 'node_modules', 'npm');
80
- safeRm(npmPath, ()=>installNPM(version, result.installPath, options, cb));
89
+ installNPM(version, tempPath, options, cb);
90
+ });
91
+ });
92
+ // Atomic rename: move temp folder to final destination
93
+ queue.defer((cb)=>{
94
+ fs.rename(tempPath, result.installPath, (err)=>{
95
+ if (!err) return cb();
96
+ // Race condition: another process may have already created dest
97
+ if (err.code === 'EEXIST' || err.code === 'ENOTEMPTY' || err.code === 'EPERM') {
98
+ // Another process won the race - clean up temp and succeed
99
+ safeRm(tempPath, ()=>cb());
100
+ return;
101
+ }
102
+ cb(err);
103
+ });
104
+ });
105
+ queue.await((err)=>{
106
+ if (err) {
107
+ // Clean up temp folder on error
108
+ safeRm(tempPath, ()=>callback(err));
81
109
  return;
82
110
  }
83
- installNPM(version, result.installPath, options, cb);
111
+ callback(null, result);
84
112
  });
85
113
  });
86
- queue.await((err)=>err ? callback(err) : callback(null, result));
87
114
  });
88
115
  });
89
116
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/workers/install.ts"],"sourcesContent":["import { safeRm } from 'fs-remove-compat';\nimport isVersion from 'is-version';\nimport mkdirp from 'mkdirp-classic';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport resolveVersions from 'node-resolve-versions';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport { DEFAULT_STORAGE_PATHS } from '../constants.ts';\n\nimport createResult from '../createResult.ts';\nimport createStoragePaths from '../createStoragePaths.ts';\nimport installNode from '../installNode/index.ts';\n\nimport installNPM from '../installNPM/index.ts';\nimport checkMissing from '../lib/checkMissing.ts';\nimport ensureDestinationParent from '../lib/ensureDestinationParent.ts';\nimport getTarget from '../lib/getTarget.ts';\n\nimport type { InstallCallback, InstallOptions } from '../types.ts';\n\ntype GetVersionsCallback = (error?: Error, results?: string[]) => undefined;\nfunction getVersions(versionExpression: string, options: InstallOptions, callback: GetVersionsCallback): undefined {\n // short circuit\n isVersion(versionExpression) ? callback(null, [versionExpression]) : resolveVersions(versionExpression, options, callback);\n}\n\nexport default function install(versionExpression: string, options: InstallOptions, callback: InstallCallback): undefined {\n const storagePaths = options.storagePath ? createStoragePaths(options.storagePath) : DEFAULT_STORAGE_PATHS;\n options = { ...storagePaths, ...options, ...getTarget(options) };\n getVersions(versionExpression, options, (err?: Error, versions?: string[]): undefined => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`Could not resolve versions for: ${versionExpression}`));\n return;\n }\n if (versions.length !== 1) {\n callback(new Error(`Version ${versionExpression} resolved to multiple versions: ${versions.map((x) => x)}. Expecting one.`));\n return;\n }\n\n const version = versions[0];\n const result = createResult(options, version);\n\n // Check if node is missing first\n checkMissing(result.installPath, options, (err, missing): undefined => {\n if (err) {\n callback(err);\n return;\n }\n\n // Early exit if both node and npm are already present\n if (!missing.length) {\n callback(null, result);\n return;\n }\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, options.cachePath));\n queue.defer(ensureDestinationParent.bind(null, result.installPath));\n\n // Install node if missing\n !~missing.indexOf('node') || queue.defer(installNode.bind(null, version, result.installPath, options));\n\n // Check and install npm AFTER node (so bundled npm is detected)\n // Skip npm download only if bundled npm is modern (6+); old npm (<6) was buggy\n queue.defer((cb) => {\n checkMissing(result.installPath, options, (err, npmMissing): undefined => {\n if (err) {\n cb(err);\n return;\n }\n if (!~npmMissing.indexOf('npm')) {\n // npm is present - check if it's modern enough to keep (npm >= 3 is stable)\n const dist = getDist(version);\n const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;\n if (bundledNpmMajor >= 3) {\n cb(); // npm >= 3 bundled, skip download\n return;\n }\n // old npm (<3) is buggy - delete it so installNPM can override\n const platform = options.platform;\n const libPath = platform === 'win32' ? result.installPath : path.join(result.installPath, 'lib');\n const npmPath = path.join(libPath, 'node_modules', 'npm');\n safeRm(npmPath, () => installNPM(version, result.installPath, options, cb));\n return;\n }\n installNPM(version, result.installPath, options, cb);\n });\n });\n\n queue.await((err) => (err ? callback(err) : callback(null, result)));\n });\n });\n}\n"],"names":["safeRm","isVersion","mkdirp","getDist","resolveVersions","path","Queue","DEFAULT_STORAGE_PATHS","createResult","createStoragePaths","installNode","installNPM","checkMissing","ensureDestinationParent","getTarget","getVersions","versionExpression","options","callback","install","storagePaths","storagePath","err","versions","length","Error","map","x","version","result","installPath","missing","queue","defer","bind","cachePath","indexOf","cb","npmMissing","dist","bundledNpmMajor","npm","split","platform","libPath","join","npmPath","await"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/workers/install.ts"],"sourcesContent":["import fs from 'fs';\nimport { safeRm } from 'fs-remove-compat';\nimport isVersion from 'is-version';\nimport mkdirp from 'mkdirp-classic';\nimport { getDist } from 'node-filename-to-dist-paths';\nimport resolveVersions from 'node-resolve-versions';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport tempSuffix from 'temp-suffix';\n\nimport { DEFAULT_STORAGE_PATHS } from '../constants.ts';\n\nimport createResult from '../createResult.ts';\nimport createStoragePaths from '../createStoragePaths.ts';\nimport installNode from '../installNode/index.ts';\n\nimport installNPM from '../installNPM/index.ts';\nimport checkMissing from '../lib/checkMissing.ts';\nimport ensureDestinationParent from '../lib/ensureDestinationParent.ts';\nimport getTarget from '../lib/getTarget.ts';\n\nimport type { InstallCallback, InstallOptions } from '../types.ts';\n\ntype GetVersionsCallback = (error?: Error, results?: string[]) => undefined;\nfunction getVersions(versionExpression: string, options: InstallOptions, callback: GetVersionsCallback): undefined {\n // short circuit\n isVersion(versionExpression) ? callback(null, [versionExpression]) : resolveVersions(versionExpression, options, callback);\n}\n\nexport default function install(versionExpression: string, options: InstallOptions, callback: InstallCallback): undefined {\n const storagePaths = options.storagePath ? createStoragePaths(options.storagePath) : DEFAULT_STORAGE_PATHS;\n options = { ...storagePaths, ...options, ...getTarget(options) };\n getVersions(versionExpression, options, (err?: Error, versions?: string[]): undefined => {\n if (err) {\n callback(err);\n return;\n }\n if (!versions.length) {\n callback(new Error(`Could not resolve versions for: ${versionExpression}`));\n return;\n }\n if (versions.length !== 1) {\n callback(new Error(`Version ${versionExpression} resolved to multiple versions: ${versions.map((x) => x)}. Expecting one.`));\n return;\n }\n\n const version = versions[0];\n const result = createResult(options, version);\n\n // Fast path: check if installation is complete\n checkMissing(result.installPath, options, (err, missing): undefined => {\n if (err) {\n callback(err);\n return;\n }\n\n // Early exit if both node and npm are already present\n if (!missing.length) {\n callback(null, result);\n return;\n }\n\n // Something is missing - use atomic pattern with temp folder\n // First, remove any partial installation to avoid conflicts\n safeRm(result.installPath, () => {\n const tempPath = tempSuffix(result.installPath);\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, options.cachePath));\n queue.defer(ensureDestinationParent.bind(null, tempPath));\n\n // Install node to temp folder\n queue.defer(installNode.bind(null, version, tempPath, options));\n\n // Check and install npm to temp folder\n // Skip npm download only if bundled npm is modern (>= 3)\n queue.defer((cb) => {\n checkMissing(tempPath, options, (err, npmMissing): undefined => {\n if (err) {\n cb(err);\n return;\n }\n if (!~npmMissing.indexOf('npm')) {\n // npm is present (bundled with node) - check if it's modern enough to keep\n const dist = getDist(version);\n const bundledNpmMajor = dist && dist.npm ? +dist.npm.split('.')[0] : 0;\n if (bundledNpmMajor >= 3) {\n cb(); // npm >= 3 bundled, skip download\n return;\n }\n // old npm (<3) is buggy - delete it so installNPM can override\n const platform = options.platform;\n const libPath = platform === 'win32' ? tempPath : path.join(tempPath, 'lib');\n const npmPath = path.join(libPath, 'node_modules', 'npm');\n safeRm(npmPath, () => installNPM(version, tempPath, options, cb));\n return;\n }\n installNPM(version, tempPath, options, cb);\n });\n });\n\n // Atomic rename: move temp folder to final destination\n queue.defer((cb) => {\n fs.rename(tempPath, result.installPath, (err) => {\n if (!err) return cb();\n // Race condition: another process may have already created dest\n if (err.code === 'EEXIST' || err.code === 'ENOTEMPTY' || err.code === 'EPERM') {\n // Another process won the race - clean up temp and succeed\n safeRm(tempPath, () => cb());\n return;\n }\n cb(err);\n });\n });\n\n queue.await((err) => {\n if (err) {\n // Clean up temp folder on error\n safeRm(tempPath, () => callback(err));\n return;\n }\n callback(null, result);\n });\n });\n });\n });\n}\n"],"names":["fs","safeRm","isVersion","mkdirp","getDist","resolveVersions","path","Queue","tempSuffix","DEFAULT_STORAGE_PATHS","createResult","createStoragePaths","installNode","installNPM","checkMissing","ensureDestinationParent","getTarget","getVersions","versionExpression","options","callback","install","storagePaths","storagePath","err","versions","length","Error","map","x","version","result","installPath","missing","tempPath","queue","defer","bind","cachePath","cb","npmMissing","indexOf","dist","bundledNpmMajor","npm","split","platform","libPath","join","npmPath","rename","code","await"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-install-release",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
4
4
  "description": "Cross-platform solution for installing releases of Node.js",
5
5
  "keywords": [
6
6
  "node",
@@ -43,8 +43,8 @@
43
43
  "version": "tsds version"
44
44
  },
45
45
  "dependencies": {
46
- "cpu-arch": "^1.0.4",
47
- "cross-spawn-cb": "^2.4.10",
46
+ "cpu-arch": "^1.0.5",
47
+ "cross-spawn-cb": "^2.4.11",
48
48
  "exit-compat": "^1.0.0",
49
49
  "fast-extract": "^1.8.13",
50
50
  "fs-copy-compat": "^0.1.3",
@@ -55,19 +55,20 @@
55
55
  "is-version": "^1.0.7",
56
56
  "lodash.keys": "^4.2.0",
57
57
  "mkdirp-classic": "^0.5.3",
58
- "node-filename-to-dist-paths": "^1.3.11",
58
+ "node-filename-to-dist-paths": "^1.3.12",
59
59
  "node-resolve-versions": "^1.3.11",
60
60
  "on-one": "^1.0.8",
61
- "queue-cb": "^1.6.1"
61
+ "queue-cb": "^1.6.1",
62
+ "temp-suffix": "^1.0.8"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@types/mocha": "^10.0.10",
65
- "@types/node": "^25.0.0",
66
+ "@types/node": "^25.0.1",
66
67
  "cr": "^0.1.0",
67
68
  "lodash.find": "^4.6.0",
68
69
  "lodash.values": "^4.3.0",
69
70
  "node-version-compare": "^1.0.3",
70
- "node-version-use": "^2.1.1",
71
+ "node-version-use": "^2.1.4",
71
72
  "node-version-utils": "^1.3.15",
72
73
  "pinkie-promise": "^2.0.1",
73
74
  "ts-dev-stack": "^1.21.3",
@@ -1,2 +0,0 @@
1
- import type { InstallOptions, NoParamCallback } from '../types.js';
2
- export default function conditionalExtract(src: string, dest: string, options: InstallOptions | NoParamCallback, callback?: NoParamCallback): undefined;
@@ -1,2 +0,0 @@
1
- import type { InstallOptions, NoParamCallback } from '../types.js';
2
- export default function conditionalExtract(src: string, dest: string, options: InstallOptions | NoParamCallback, callback?: NoParamCallback): undefined;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "default", {
6
- enumerable: true,
7
- get: function() {
8
- return conditionalExtract;
9
- }
10
- });
11
- var _fastextract = /*#__PURE__*/ _interop_require_default(require("fast-extract"));
12
- var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
13
- var _mkdirpclassic = /*#__PURE__*/ _interop_require_default(require("mkdirp-classic"));
14
- var _path = /*#__PURE__*/ _interop_require_default(require("path"));
15
- var _queuecb = /*#__PURE__*/ _interop_require_default(require("queue-cb"));
16
- function _interop_require_default(obj) {
17
- return obj && obj.__esModule ? obj : {
18
- default: obj
19
- };
20
- }
21
- function conditionalExtract(src, dest, options, callback) {
22
- if (typeof options === 'function') {
23
- callback = options;
24
- options = null;
25
- }
26
- options = options || {};
27
- _fs.default.stat(dest, function(err) {
28
- if (!err) return callback(); // already exists
29
- var queue = new _queuecb.default(1);
30
- queue.defer(_mkdirpclassic.default.bind(null, _path.default.dirname(dest)));
31
- queue.defer(_fastextract.default.bind(null, src, dest, {
32
- strip: 1,
33
- time: 1000
34
- }));
35
- queue.await(callback);
36
- });
37
- }
38
- /* 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 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/lib/conditionalExtract.ts"],"sourcesContent":["import extract from 'fast-extract';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport type { InstallOptions, NoParamCallback } from '../types.ts';\n\nexport default function conditionalExtract(src: string, dest: string, options: InstallOptions | NoParamCallback, callback?: NoParamCallback): undefined {\n if (typeof options === 'function') {\n callback = options;\n options = null;\n }\n options = options || ({} as InstallOptions);\n\n fs.stat(dest, (err) => {\n if (!err) return callback(); // already exists\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, path.dirname(dest)));\n queue.defer(extract.bind(null, src, dest, { strip: 1, time: 1000 }));\n queue.await(callback);\n });\n}\n"],"names":["conditionalExtract","src","dest","options","callback","fs","stat","err","queue","Queue","defer","mkdirp","bind","path","dirname","extract","strip","time","await"],"mappings":";;;;+BAQA;;;eAAwBA;;;kEARJ;yDACL;oEACI;2DACF;8DACC;;;;;;AAIH,SAASA,mBAAmBC,GAAW,EAAEC,IAAY,EAAEC,OAAyC,EAAEC,QAA0B;IACzI,IAAI,OAAOD,YAAY,YAAY;QACjCC,WAAWD;QACXA,UAAU;IACZ;IACAA,UAAUA,WAAY,CAAC;IAEvBE,WAAE,CAACC,IAAI,CAACJ,MAAM,SAACK;QACb,IAAI,CAACA,KAAK,OAAOH,YAAY,iBAAiB;QAE9C,IAAMI,QAAQ,IAAIC,gBAAK,CAAC;QACxBD,MAAME,KAAK,CAACC,sBAAM,CAACC,IAAI,CAAC,MAAMC,aAAI,CAACC,OAAO,CAACZ;QAC3CM,MAAME,KAAK,CAACK,oBAAO,CAACH,IAAI,CAAC,MAAMX,KAAKC,MAAM;YAAEc,OAAO;YAAGC,MAAM;QAAK;QACjET,MAAMU,KAAK,CAACd;IACd;AACF"}
@@ -1,2 +0,0 @@
1
- import type { InstallOptions, NoParamCallback } from '../types.js';
2
- export default function conditionalExtract(src: string, dest: string, options: InstallOptions | NoParamCallback, callback?: NoParamCallback): undefined;
@@ -1,22 +0,0 @@
1
- import extract from 'fast-extract';
2
- import fs from 'fs';
3
- import mkdirp from 'mkdirp-classic';
4
- import path from 'path';
5
- import Queue from 'queue-cb';
6
- export default function conditionalExtract(src, dest, options, callback) {
7
- if (typeof options === 'function') {
8
- callback = options;
9
- options = null;
10
- }
11
- options = options || {};
12
- fs.stat(dest, (err)=>{
13
- if (!err) return callback(); // already exists
14
- const queue = new Queue(1);
15
- queue.defer(mkdirp.bind(null, path.dirname(dest)));
16
- queue.defer(extract.bind(null, src, dest, {
17
- strip: 1,
18
- time: 1000
19
- }));
20
- queue.await(callback);
21
- });
22
- }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node-version/node-install-release/src/lib/conditionalExtract.ts"],"sourcesContent":["import extract from 'fast-extract';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport path from 'path';\nimport Queue from 'queue-cb';\n\nimport type { InstallOptions, NoParamCallback } from '../types.ts';\n\nexport default function conditionalExtract(src: string, dest: string, options: InstallOptions | NoParamCallback, callback?: NoParamCallback): undefined {\n if (typeof options === 'function') {\n callback = options;\n options = null;\n }\n options = options || ({} as InstallOptions);\n\n fs.stat(dest, (err) => {\n if (!err) return callback(); // already exists\n\n const queue = new Queue(1);\n queue.defer(mkdirp.bind(null, path.dirname(dest)));\n queue.defer(extract.bind(null, src, dest, { strip: 1, time: 1000 }));\n queue.await(callback);\n });\n}\n"],"names":["extract","fs","mkdirp","path","Queue","conditionalExtract","src","dest","options","callback","stat","err","queue","defer","bind","dirname","strip","time","await"],"mappings":"AAAA,OAAOA,aAAa,eAAe;AACnC,OAAOC,QAAQ,KAAK;AACpB,OAAOC,YAAY,iBAAiB;AACpC,OAAOC,UAAU,OAAO;AACxB,OAAOC,WAAW,WAAW;AAI7B,eAAe,SAASC,mBAAmBC,GAAW,EAAEC,IAAY,EAAEC,OAAyC,EAAEC,QAA0B;IACzI,IAAI,OAAOD,YAAY,YAAY;QACjCC,WAAWD;QACXA,UAAU;IACZ;IACAA,UAAUA,WAAY,CAAC;IAEvBP,GAAGS,IAAI,CAACH,MAAM,CAACI;QACb,IAAI,CAACA,KAAK,OAAOF,YAAY,iBAAiB;QAE9C,MAAMG,QAAQ,IAAIR,MAAM;QACxBQ,MAAMC,KAAK,CAACX,OAAOY,IAAI,CAAC,MAAMX,KAAKY,OAAO,CAACR;QAC3CK,MAAMC,KAAK,CAACb,QAAQc,IAAI,CAAC,MAAMR,KAAKC,MAAM;YAAES,OAAO;YAAGC,MAAM;QAAK;QACjEL,MAAMM,KAAK,CAACT;IACd;AACF"}