From 174703e67016f7dd1c9d6b7fcf3b5c54d309c10e Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Wed, 9 Sep 2020 23:10:45 -0400 Subject: [PATCH 1/3] test: add lib/link.js tests - Added ELINKGLOBAL error code for when using --global - Added tests for lib/link.js - Do not reify, only load globals when linking a pkg to a local prefix - Fixes: #1777 --- lib/link.js | 45 +++-- tap-snapshots/test-lib-link.js-TAP.test.js | 19 ++ test/lib/link.js | 218 +++++++++++++++++++++ 3 files changed, 266 insertions(+), 16 deletions(-) create mode 100644 tap-snapshots/test-lib-link.js-TAP.test.js create mode 100644 test/lib/link.js diff --git a/lib/link.js b/lib/link.js index 0a1fbc52fb0e8..5318f9029eb46 100644 --- a/lib/link.js +++ b/lib/link.js @@ -1,14 +1,15 @@ -// link with no args: symlink the folder to the global location -// link with package arg: symlink the global to the local +'use strict' + +const { readdir } = require('fs') +const { resolve } = require('path') + +const Arborist = require('@npmcli/arborist') const npm = require('./npm.js') const usageUtil = require('./utils/usage.js') const reifyOutput = require('./utils/reify-output.js') -const { resolve } = require('path') -const Arborist = require('@npmcli/arborist') const completion = (opts, cb) => { - const { readdir } = require('fs') const dir = npm.globalDir readdir(dir, (er, files) => cb(er, files.filter(f => !/^[._-]/.test(f)))) } @@ -16,26 +17,33 @@ const completion = (opts, cb) => { const usage = usageUtil( 'link', 'npm link (in package dir)' + - '\nnpm link [<@scope>/][@]' + '\nnpm link [<@scope>/]' ) const cmd = (args, cb) => link(args).then(() => cb()).catch(cb) const link = async args => { if (npm.config.get('global')) { - throw new Error( - 'link should never be --global.\n' + - 'Please re-run this command with --local' + throw Object.assign( + new Error( + 'link should never be --global.\n' + + 'Please re-run this command with --local' + ), + { code: 'ELINKGLOBAL' } ) } + // link with no args: symlink the folder to the global location + // link with package arg: symlink the global to the local args = args.filter(a => resolve(a) !== npm.prefix) - return args.length ? linkInstall(args) : linkPkg() + return args.length + ? linkInstall(args) + : linkPkg() } const linkInstall = async args => { - // add all the args as global installs, and then add symlink installs locally - // to the packages in the global space. + // load current packages from the global space, + // and then add symlinks installs locally const globalTop = resolve(npm.globalDir, '..') const globalArb = new Arborist({ ...npm.flatOptions, @@ -43,24 +51,29 @@ const linkInstall = async args => { global: true }) - const globals = await globalArb.reify({ add: args }) + const globals = await globalArb.loadActual() + + const links = [ + ...globals.children.values() + ] + .filter(i => args.some(j => j === i.name)) - const links = globals.edgesOut.keys() const localArb = new Arborist({ ...npm.flatOptions, path: npm.prefix }) await localArb.reify({ - add: links.map(l => `file:${resolve(globalTop, 'node_modules', l)}`) + add: links.map(l => `file:${resolve(globalTop, 'node_modules', l.path)}`) }) reifyOutput(localArb) } const linkPkg = async () => { + const globalTop = resolve(npm.globalDir, '..') const arb = new Arborist({ ...npm.flatOptions, - path: resolve(npm.globalDir, '..'), + path: globalTop, global: true }) await arb.reify({ add: [`file:${npm.prefix}`] }) diff --git a/tap-snapshots/test-lib-link.js-TAP.test.js b/tap-snapshots/test-lib-link.js-TAP.test.js new file mode 100644 index 0000000000000..211417d3150ea --- /dev/null +++ b/tap-snapshots/test-lib-link.js-TAP.test.js @@ -0,0 +1,19 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/link.js TAP link global linked pkg to local nm when using args > should create a local symlink to global pkg 1`] = ` +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/@myscope/bar +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/scoped-linked + +` + +exports[`test/lib/link.js TAP link to globalDir when in current working dir of pkg and no args > should create a global link to current pkg 1`] = ` +{CWD}/test/lib/link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/test-pkg-link + +` diff --git a/test/lib/link.js b/test/lib/link.js new file mode 100644 index 0000000000000..056b0d3d6f446 --- /dev/null +++ b/test/lib/link.js @@ -0,0 +1,218 @@ +const { resolve } = require('path') + +const Arborist = require('@npmcli/arborist') +const t = require('tap') +const requireInject = require('require-inject') + +const redactCwd = (path) => { + const normalizePath = p => p + .replace(/\\+/g, '/') + .replace(/\r\n/g, '\n') + return normalizePath(path) + .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}') +} + +t.cleanSnapshot = (str) => redactCwd(str) + +let reifyOutput +const npm = { + globalDir: null, + prefix: null, + flatOptions: {}, + config: { + get () { return false } + } +} +const printLinks = async (opts) => { + let res = '' + const arb = new Arborist(opts) + const tree = await arb.loadActual() + const linkedItems = [...tree.inventory.values()] + for (const item of linkedItems) { + if (item.target) + res += `${item.path} -> ${item.target.path}\n` + } + return res +} + +const mocks = { + '../../lib/npm.js': npm, + '../../lib/utils/reify-output.js': () => reifyOutput() +} + +const link = requireInject('../../lib/link.js', mocks) + +t.test('link to globalDir when in current working dir of pkg and no args', (t) => { + t.plan(2) + + const testdir = t.testdir({ + 'global-prefix': { + lib: { + node_modules: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0' + }) + } + } + } + }, + 'test-pkg-link': { + 'package.json': JSON.stringify({ + name: 'test-pkg-link', + version: '1.0.0' + }) + } + }) + npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') + npm.prefix = resolve(testdir, 'test-pkg-link') + + reifyOutput = async () => { + reifyOutput = undefined + + const links = await printLinks({ + path: resolve(npm.globalDir, '..'), + global: true + }) + + t.matchSnapshot(links, 'should create a global link to current pkg') + } + + link([], (err) => { + t.ifError(err, 'should not error out') + }) +}) + +t.test('link global linked pkg to local nm when using args', (t) => { + t.plan(2) + + const testdir = t.testdir({ + 'global-prefix': { + lib: { + node_modules: { + '@myscope': { + foo: { + 'package.json': JSON.stringify({ + name: '@myscope/foo', + version: '1.0.0' + }) + }, + bar: { + 'package.json': JSON.stringify({ + name: '@myscope/bar', + version: '1.0.0' + }) + }, + linked: t.fixture('symlink', '../../../../scoped-linked') + }, + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0' + }) + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0' + }) + }, + 'test-pkg-link': t.fixture('symlink', '../../../test-pkg-link') + } + } + }, + 'test-pkg-link': { + 'package.json': JSON.stringify({ + name: 'test-pkg-link', + version: '1.0.0' + }) + }, + 'scoped-linked': { + 'package.json': JSON.stringify({ + name: '@myscope/linked', + version: '1.0.0' + }) + }, + 'my-project': { + 'package.json': JSON.stringify({ + name: 'my-project', + version: '1.0.0', + dependencies: { + foo: '^1.0.0' + } + }), + node_modules: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0' + }) + } + } + } + }) + npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') + npm.prefix = resolve(testdir, 'my-project') + + reifyOutput = async () => { + reifyOutput = undefined + + const links = await printLinks({ + path: npm.prefix + }) + + t.matchSnapshot(links, 'should create a local symlink to global pkg') + } + + // installs examples for: + // - test-pkg-link: pkg linked to globalDir from local fs + // - @myscope/linked: scoped pkg linked to globalDir from local fs + // - @myscope/bar: prev installed scoped package available in globalDir + // - a: prev installed package available in globalDir + link(['test-pkg-link', '@myscope/linked', '@myscope/bar', 'a'], (err) => { + t.ifError(err, 'should not error out') + }) +}) + +t.test('completion', (t) => { + const testdir = t.testdir({ + 'global-prefix': { + lib: { + node_modules: { + foo: {}, + bar: {}, + lorem: {}, + ipsum: {} + } + } + } + }) + npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') + + link.completion({}, (err, words) => { + t.ifError(err, 'should not error out') + t.deepEqual( + words, + ['bar', 'foo', 'ipsum', 'lorem'], + 'should list all package names available in globalDir' + ) + t.end() + }) +}) + +t.test('--global option', (t) => { + const _config = npm.config + npm.config = { get () { return true } } + link([], (err) => { + npm.config = _config + + t.match( + err.message, + /link should never be --global/, + 'should throw an useful error' + ) + + t.end() + }) +}) From 81772126f99ebe2b8f2f4c5d3a6bfa4c37acd274 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Thu, 10 Sep 2020 17:24:13 -0400 Subject: [PATCH 2/3] fix: reenable npm link from registry Being able to npm link a package that is not currently available in the global space should still be a supported feature, this change puts that functionality back in place but also improves it by avoiding reify any package that may already be found in the global directory. --- lib/link.js | 75 ++++++++++++++++++--- tap-snapshots/test-lib-link.js-TAP.test.js | 10 ++- test/lib/link.js | 77 +++++++++++++++++++++- 3 files changed, 149 insertions(+), 13 deletions(-) diff --git a/lib/link.js b/lib/link.js index 5318f9029eb46..56d50f98483eb 100644 --- a/lib/link.js +++ b/lib/link.js @@ -4,6 +4,9 @@ const { readdir } = require('fs') const { resolve } = require('path') const Arborist = require('@npmcli/arborist') +const npa = require('npm-package-arg') +const rpj = require('read-package-json-fast') +const semver = require('semver') const npm = require('./npm.js') const usageUtil = require('./utils/usage.js') @@ -17,7 +20,7 @@ const completion = (opts, cb) => { const usage = usageUtil( 'link', 'npm link (in package dir)' + - '\nnpm link [<@scope>/]' + '\nnpm link [<@scope>/][@]' ) const cmd = (args, cb) => link(args).then(() => cb()).catch(cb) @@ -41,29 +44,83 @@ const link = async args => { : linkPkg() } +// Returns a list of items that can't be fulfilled by +// things found in the current arborist inventory +const missingArgsFromTree = (tree, args) => { + const foundNodes = [] + const missing = args.filter(a => { + const arg = npa(a) + const nodes = tree.children.values() + const argFound = [...nodes].every(node => { + // TODO: write tests for unmatching version specs, this is hard to test + // atm but should be simple once we have a mocked registry again + if (arg.name !== node.name /* istanbul ignore next */ || ( + arg.version && + !semver.satisfies(node.version, arg.version) + )) { + foundNodes.push(node) + return true + } + }) + return argFound + }) + + // remote nodes from the loaded tree in order + // to avoid dropping them later when reifying + for (const node of foundNodes) { + node.parent = null + } + + return missing +} + const linkInstall = async args => { // load current packages from the global space, // and then add symlinks installs locally const globalTop = resolve(npm.globalDir, '..') - const globalArb = new Arborist({ + const globalOpts = { ...npm.flatOptions, path: globalTop, - global: true + global: true, + prune: false + } + const globalArb = new Arborist(globalOpts) + + // get only current top-level packages from the global space + const globals = await globalArb.loadActual({ + filter: (node, kid) => + !node.isRoot || args.some(a => npa(a).name === kid) }) - const globals = await globalArb.loadActual() + // any extra arg that is missing from the current + // global space should be reified there first + const missing = missingArgsFromTree(globals, args) + if (missing.length) { + await globalArb.reify({ + ...globalOpts, + add: missing + }) + } - const links = [ - ...globals.children.values() - ] - .filter(i => args.some(j => j === i.name)) + // get a list of module names that should be linked in the local prefix + const names = [] + for (const a of args) { + const arg = npa(a) + names.push( + arg.type === 'directory' + ? (await rpj(resolve(arg.fetchSpec, 'package.json'))).name + : arg.name + ) + } + // create a new arborist instance for the local prefix and + // reify all the pending names as symlinks there const localArb = new Arborist({ ...npm.flatOptions, path: npm.prefix }) await localArb.reify({ - add: links.map(l => `file:${resolve(globalTop, 'node_modules', l.path)}`) + add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`) }) reifyOutput(localArb) diff --git a/tap-snapshots/test-lib-link.js-TAP.test.js b/tap-snapshots/test-lib-link.js-TAP.test.js index 211417d3150ea..de7f483b60de8 100644 --- a/tap-snapshots/test-lib-link.js-TAP.test.js +++ b/tap-snapshots/test-lib-link.js-TAP.test.js @@ -6,10 +6,16 @@ */ 'use strict' exports[`test/lib/link.js TAP link global linked pkg to local nm when using args > should create a local symlink to global pkg 1`] = ` -{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/@myscope/bar -{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/scoped-linked +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/link-me-too -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/link-me-too +{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link + +` + +exports[`test/lib/link.js TAP link pkg already in global space > should create a local symlink to global pkg 1`] = ` +{CWD}/test/lib/link-link-pkg-already-in-global-space/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/link-link-pkg-already-in-global-space/scoped-linked ` diff --git a/test/lib/link.js b/test/lib/link.js index 056b0d3d6f446..aafdb8188e85c 100644 --- a/test/lib/link.js +++ b/test/lib/link.js @@ -28,9 +28,11 @@ const printLinks = async (opts) => { const arb = new Arborist(opts) const tree = await arb.loadActual() const linkedItems = [...tree.inventory.values()] + .sort((a, b) => a.pkgid.localeCompare(b.pkgid)) for (const item of linkedItems) { - if (item.target) + if (item.target) { res += `${item.path} -> ${item.target.path}\n` + } } return res } @@ -128,6 +130,12 @@ t.test('link global linked pkg to local nm when using args', (t) => { version: '1.0.0' }) }, + 'link-me-too': { + 'package.json': JSON.stringify({ + name: 'link-me-too', + version: '1.0.0' + }) + }, 'scoped-linked': { 'package.json': JSON.stringify({ name: '@myscope/linked', @@ -155,8 +163,72 @@ t.test('link global linked pkg to local nm when using args', (t) => { npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') npm.prefix = resolve(testdir, 'my-project') + const _cwd = process.cwd() + process.chdir(npm.prefix) + + reifyOutput = async () => { + reifyOutput = undefined + process.chdir(_cwd) + + const links = await printLinks({ + path: npm.prefix + }) + + t.matchSnapshot(links, 'should create a local symlink to global pkg') + } + + // installs examples for: + // - test-pkg-link: pkg linked to globalDir from local fs + // - @myscope/linked: scoped pkg linked to globalDir from local fs + // - @myscope/bar: prev installed scoped package available in globalDir + // - a: prev installed package available in globalDir + // - file:./link-me-too: pkg that needs to be reified in globalDir first + link([ + 'test-pkg-link', + '@myscope/linked', + '@myscope/bar', + 'a', + 'file:../link-me-too' + ], (err) => { + t.ifError(err, 'should not error out') + }) +}) + +t.test('link pkg already in global space', (t) => { + t.plan(2) + + const testdir = t.testdir({ + 'global-prefix': { + lib: { + node_modules: { + '@myscope': { + linked: t.fixture('symlink', '../../../../scoped-linked') + } + } + } + }, + 'scoped-linked': { + 'package.json': JSON.stringify({ + name: '@myscope/linked', + version: '1.0.0' + }) + }, + 'my-project': { + 'package.json': JSON.stringify({ + name: 'my-project', + version: '1.0.0' + }) + } + }) + npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') + npm.prefix = resolve(testdir, 'my-project') + + const _cwd = process.cwd() + process.chdir(npm.prefix) + reifyOutput = async () => { reifyOutput = undefined + process.chdir(_cwd) const links = await printLinks({ path: npm.prefix @@ -170,7 +242,8 @@ t.test('link global linked pkg to local nm when using args', (t) => { // - @myscope/linked: scoped pkg linked to globalDir from local fs // - @myscope/bar: prev installed scoped package available in globalDir // - a: prev installed package available in globalDir - link(['test-pkg-link', '@myscope/linked', '@myscope/bar', 'a'], (err) => { + // - file:./link-me-too: pkg that needs to be reified in globalDir first + link(['@myscope/linked'], (err) => { t.ifError(err, 'should not error out') }) }) From 402bd25fe9c4d28ac8ff778958bfbb2f6d546311 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Thu, 10 Sep 2020 17:26:15 -0400 Subject: [PATCH 3/3] @npmcli/arborist@0.0.23 --- .../@npmcli/arborist/lib/add-rm-pkg-deps.js | 3 ++- .../@npmcli/arborist/lib/arborist/rebuild.js | 18 +++++++++++++++--- node_modules/@npmcli/arborist/package.json | 2 +- package-lock.json | 14 +++++++------- package.json | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js b/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js index dad85c48c9320..4479328f94ae4 100644 --- a/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js +++ b/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js @@ -55,7 +55,8 @@ const addSingle = ({pkg, spec, saveBundle, saveType, path}) => { pkg[type] = pkg[type] || {} if (rawSpec !== '' || pkg[type][name] === undefined) { // if we're in global mode, file specs are based on cwd, not arb path - pkg[type][name] = specType === 'file' ? `file:${relpath(path, fetchSpec)}` + pkg[type][name] = specType === 'file' || specType === 'directory' + ? `file:${relpath(path, fetchSpec)}` : (rawSpec || '*') } diff --git a/node_modules/@npmcli/arborist/lib/arborist/rebuild.js b/node_modules/@npmcli/arborist/lib/arborist/rebuild.js index 2a0057887ccd7..26f841e7766e6 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/rebuild.js +++ b/node_modules/@npmcli/arborist/lib/arborist/rebuild.js @@ -184,13 +184,16 @@ module.exports = cls => class Builder extends cls { dev, devOptional, package: pkg, + location, } = node // skip any that we know we'll be deleting if (this[_trashList].has(path)) return - process.emit('time', `build:run:${event}:${node.location}`) + const timer = `build:run:${event}:${location}` + process.emit('time', timer) + this.log.info('run', pkg._id, event, location, pkg.scripts[event]) const p = runScript({ event, path, @@ -207,10 +210,19 @@ module.exports = cls => class Builder extends cls { boolEnv(devOptional && !dev && !optional), }, scriptShell: this[_scriptShell], + }).catch(er => { + const { code, signal } = er + this.log.info('run', pkg._id, event, {code, signal}) + throw er + }).then(({code, signal}) => { + this.log.info('run', pkg._id, event, {code, signal}) }) - return this[_doHandleOptionalFailure] - ? this[_handleOptionalFailure](node, p) : p + await (this[_doHandleOptionalFailure] + ? this[_handleOptionalFailure](node, p) + : p) + + process.emit('timeEnd', timer) })) process.emit('timeEnd', `build:run:${event}`) } diff --git a/node_modules/@npmcli/arborist/package.json b/node_modules/@npmcli/arborist/package.json index 75770b29cd276..fead51d1c6070 100644 --- a/node_modules/@npmcli/arborist/package.json +++ b/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "0.0.21", + "version": "0.0.23", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.5", diff --git a/package-lock.json b/package-lock.json index d54900b3727bc..68d871df12ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,7 +88,7 @@ ], "license": "Artistic-2.0", "dependencies": { - "@npmcli/arborist": "^0.0.21", + "@npmcli/arborist": "^0.0.23", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^1.1.7", "@npmcli/run-script": "^1.5.0", @@ -397,9 +397,9 @@ "dev": true }, "node_modules/@npmcli/arborist": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-0.0.21.tgz", - "integrity": "sha512-5yZ9xL4yDqqmjaJmql5HQ99lA/zMPZJL9DrmABiHAp22U5hR08e0E4DYBRlnLy/mdjjiopJ+aAm0hIgcD56vdg==", + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-0.0.23.tgz", + "integrity": "sha512-GP3QFAr5TWYzoG7JkfClc4XCwFGUk+R/pJpErpHzyiwf8TI9Ib1Psxjmdb+lVGYaX6QlO0iJeuvL5tvmOI4LlQ==", "inBundle": true, "dependencies": { "@npmcli/installed-package-contents": "^1.0.5", @@ -9460,9 +9460,9 @@ "dev": true }, "@npmcli/arborist": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-0.0.21.tgz", - "integrity": "sha512-5yZ9xL4yDqqmjaJmql5HQ99lA/zMPZJL9DrmABiHAp22U5hR08e0E4DYBRlnLy/mdjjiopJ+aAm0hIgcD56vdg==", + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-0.0.23.tgz", + "integrity": "sha512-GP3QFAr5TWYzoG7JkfClc4XCwFGUk+R/pJpErpHzyiwf8TI9Ib1Psxjmdb+lVGYaX6QlO0iJeuvL5tvmOI4LlQ==", "requires": { "@npmcli/installed-package-contents": "^1.0.5", "@npmcli/map-workspaces": "0.0.0-pre.1", diff --git a/package.json b/package.json index 1ed4cc905b549..17544784e3460 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^0.0.21", + "@npmcli/arborist": "^0.0.23", "@npmcli/ci-detect": "^1.2.0", "@npmcli/run-script": "^1.5.0", "abbrev": "~1.1.1",