fix(lifecycle): replace shell-quote with shlex (#9695)

* fix(lifecycle): replace shell-quote with shlex

close #9381

* fix: use shlex in @pnpm/worker

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
Junxiao Shi
2025-06-29 21:03:31 -04:00
committed by GitHub
parent 337a110dbc
commit 589ac1ffc7
10 changed files with 240 additions and 40 deletions

View File

@@ -0,0 +1,8 @@
---
"@pnpm/lifecycle": patch
"@pnpm/worker": patch
pnpm: patch
---
Replaced `shell-quote` with `shlex` for quoting command arguments [#9381](https://github.com/pnpm/pnpm/issues/9381).

View File

@@ -236,6 +236,7 @@
"semistrict",
"serverjs",
"sheetjs",
"shlex",
"sindresorhus",
"sirv",
"soporan",

View File

@@ -44,7 +44,7 @@
"is-windows": "catalog:",
"path-exists": "catalog:",
"run-groups": "catalog:",
"shell-quote": "catalog:"
"shlex": "catalog:"
},
"peerDependencies": {
"@pnpm/logger": "catalog:"
@@ -57,7 +57,6 @@
"@pnpm/test-ipc-server": "workspace:*",
"@types/is-windows": "catalog:",
"@types/rimraf": "catalog:",
"@types/shell-quote": "catalog:",
"@zkochan/rimraf": "catalog:",
"load-json-file": "catalog:"
},

View File

@@ -6,7 +6,7 @@ import { type DependencyManifest, type ProjectManifest, type PrepareExecutionEnv
import { PnpmError } from '@pnpm/error'
import { existsSync } from 'fs'
import isWindows from 'is-windows'
import { quote as shellQuote } from 'shell-quote'
import { join as shellQuote } from 'shlex'
function noop () {} // eslint-disable-line:no-empty

View File

@@ -55,11 +55,11 @@ test('runLifecycleHook() passes newline correctly', async () => {
rawConfig: {},
rootModulesDir,
unsafePerm: true,
args: ['a\nb'],
args: ['a\nb != \'A\\nB\''],
})
expect((await import(path.join(pkgRoot, 'output.json'))).default).toStrictEqual([
process.platform === 'win32' ? 'a\\nb' : 'a\nb',
process.platform === 'win32' ? 'a\\nb != \'A\\\\nB\'' : 'a\nb != \'A\\nB\'',
])
})

250
pnpm-lock.yaml generated
View File

@@ -150,9 +150,6 @@ catalogs:
'@types/semver':
specifier: 7.5.3
version: 7.5.3
'@types/shell-quote':
specifier: ^1.7.5
version: 1.7.5
'@types/signal-exit':
specifier: ^3.0.4
version: 3.0.4
@@ -570,9 +567,9 @@ catalogs:
semver-utils:
specifier: ^1.1.4
version: 1.1.4
shell-quote:
specifier: ^1.8.2
version: 1.8.2
shlex:
specifier: ^2.1.2
version: 2.1.2
signal-exit:
specifier: ^3.0.7
version: 3.0.7
@@ -804,7 +801,7 @@ importers:
version: link:../packages/logger
'@pnpm/meta-updater':
specifier: 'catalog:'
version: 2.0.6(@types/node@18.19.34)(typanion@3.14.0)
version: 2.0.6(@types/node@22.15.29)(typanion@3.14.0)
'@pnpm/object.key-sorting':
specifier: workspace:*
version: link:../object/key-sorting
@@ -2409,9 +2406,9 @@ importers:
run-groups:
specifier: 'catalog:'
version: 3.0.1
shell-quote:
shlex:
specifier: 'catalog:'
version: 1.8.2
version: 2.1.2
devDependencies:
'@pnpm/lifecycle':
specifier: workspace:*
@@ -2434,9 +2431,6 @@ importers:
'@types/rimraf':
specifier: 'catalog:'
version: 3.0.2
'@types/shell-quote':
specifier: 'catalog:'
version: 1.7.5
'@zkochan/rimraf':
specifier: 'catalog:'
version: 3.0.2
@@ -8096,9 +8090,9 @@ importers:
p-limit:
specifier: 'catalog:'
version: 3.1.0
shell-quote:
shlex:
specifier: 'catalog:'
version: 1.8.2
version: 2.1.2
devDependencies:
'@pnpm/logger':
specifier: workspace:*
@@ -8112,9 +8106,6 @@ importers:
'@types/is-windows':
specifier: 'catalog:'
version: 1.0.2
'@types/shell-quote':
specifier: 'catalog:'
version: 1.7.5
workspace/filter-packages-from-dir:
dependencies:
@@ -10226,9 +10217,6 @@ packages:
'@types/semver@7.7.0':
resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==}
'@types/shell-quote@1.7.5':
resolution: {integrity: sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==}
'@types/signal-exit@3.0.4':
resolution: {integrity: sha512-e7EUPfU9afHyWc5CXtlqbvVHEshrb05uPlDCenWIbMgtWoFrTuTDVYNLKk6o4X2/4oHTfNqrJX/vaJ3uBhtXTg==}
@@ -14426,10 +14414,6 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
shell-quote@1.8.2:
resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
engines: {node: '>= 0.4'}
shell-quote@1.8.3:
resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
engines: {node: '>= 0.4'}
@@ -14439,6 +14423,9 @@ packages:
engines: {node: '>=4'}
hasBin: true
shlex@2.1.2:
resolution: {integrity: sha512-Nz6gtibMVgYeMEhUjp2KuwAgqaJA1K155dU/HuDaEJUGgnmYfVtVZah+uerVWdH8UGnyahhDCgABbYTbs254+w==}
short-tree@1.0.0:
resolution: {integrity: sha512-SPhGxbdypMMjYlmdVL/dzBUCT/5FboztmleoS4WPgvCI7DqZXv8xrLSTuJqzmmuAtCTkgxkIKzfZ+jfJR6ODZg==}
engines: {node: '>=12'}
@@ -16640,6 +16627,28 @@ snapshots:
- supports-color
- typanion
'@pnpm/cli-utils@1000.1.5(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/cli-meta': 1000.0.8
'@pnpm/config': 1003.1.1(@pnpm/logger@1001.0.0)
'@pnpm/config.deps-installer': 1000.0.5(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))
'@pnpm/default-reporter': 1002.0.1(@pnpm/logger@1001.0.0)
'@pnpm/error': 1000.0.2
'@pnpm/logger': 1001.0.0
'@pnpm/manifest-utils': 1001.0.1(@pnpm/logger@1001.0.0)
'@pnpm/package-is-installable': 1000.0.10(@pnpm/logger@1001.0.0)
'@pnpm/pnpmfile': 1001.2.2(@pnpm/logger@1001.0.0)
'@pnpm/read-project-manifest': 1000.0.11
'@pnpm/store-connection-manager': 1002.0.3(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/types': 1000.6.0
chalk: 4.1.2
load-json-file: 6.2.0
transitivePeerDependencies:
- '@pnpm/worker'
- domexception
- supports-color
- typanion
'@pnpm/client@1000.0.19(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@18.19.34))(typanion@3.14.0)':
dependencies:
'@pnpm/default-resolver': 1002.0.2(@pnpm/logger@1001.0.0)
@@ -16659,6 +16668,25 @@ snapshots:
- supports-color
- typanion
'@pnpm/client@1000.0.19(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/default-resolver': 1002.0.2(@pnpm/logger@1001.0.0)
'@pnpm/directory-fetcher': 1000.1.7(@pnpm/logger@1001.0.0)
'@pnpm/fetch': 1000.2.2(@pnpm/logger@1001.0.0)
'@pnpm/fetching-types': 1000.1.0
'@pnpm/git-fetcher': 1001.0.8(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/network.auth-header': 1000.0.3
'@pnpm/resolver-base': 1003.0.1
'@pnpm/tarball-fetcher': 1001.0.8(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/types': 1000.6.0
ramda: '@pnpm/ramda@0.28.1'
transitivePeerDependencies:
- '@pnpm/logger'
- '@pnpm/worker'
- domexception
- supports-color
- typanion
'@pnpm/colorize-semver-diff@1.0.1':
dependencies:
chalk: 4.1.2
@@ -16692,6 +16720,28 @@ snapshots:
- domexception
- supports-color
'@pnpm/config.deps-installer@1000.0.5(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))':
dependencies:
'@pnpm/config.config-writer': 1000.0.5
'@pnpm/core-loggers': 1001.0.1(@pnpm/logger@1001.0.0)
'@pnpm/error': 1000.0.2
'@pnpm/fetch': 1000.2.2(@pnpm/logger@1001.0.0)
'@pnpm/logger': 1001.0.0
'@pnpm/network.auth-header': 1000.0.3
'@pnpm/npm-resolver': 1004.0.1(@pnpm/logger@1001.0.0)
'@pnpm/package-store': 1002.0.4(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))
'@pnpm/parse-wanted-dependency': 1001.0.0
'@pnpm/pick-registry-for-package': 1000.0.8
'@pnpm/read-modules-dir': 1000.0.0
'@pnpm/read-package-json': 1000.0.9
'@pnpm/types': 1000.6.0
'@zkochan/rimraf': 3.0.2
get-npm-tarball-url: 2.1.0
transitivePeerDependencies:
- '@pnpm/worker'
- domexception
- supports-color
'@pnpm/config.env-replace@1.1.0': {}
'@pnpm/config.env-replace@3.0.1': {}
@@ -17001,6 +17051,19 @@ snapshots:
- supports-color
- typanion
'@pnpm/git-fetcher@1001.0.8(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/fetcher-base': 1000.0.11
'@pnpm/fs.packlist': 2.0.0
'@pnpm/logger': 1001.0.0
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)
'@zkochan/rimraf': 3.0.2
execa: safe-execa@0.1.2
transitivePeerDependencies:
- supports-color
- typanion
'@pnpm/git-resolver@1001.0.2(@pnpm/logger@1001.0.0)':
dependencies:
'@pnpm/fetch': 1000.2.2(@pnpm/logger@1001.0.0)
@@ -17147,6 +17210,24 @@ snapshots:
- supports-color
- typanion
'@pnpm/meta-updater@2.0.6(@types/node@22.15.29)(typanion@3.14.0)':
dependencies:
'@pnpm/find-workspace-dir': 1000.1.0
'@pnpm/logger': 1001.0.0
'@pnpm/types': 1000.6.0
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)
'@pnpm/workspace.find-packages': 1000.0.25(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/workspace.read-manifest': 1000.1.5
load-json-file: 7.0.1
meow: 11.0.0
print-diff: 2.0.0
write-json-file: 5.0.0
transitivePeerDependencies:
- '@types/node'
- domexception
- supports-color
- typanion
'@pnpm/network.agent@2.0.3':
dependencies:
'@pnpm/network.config': 2.1.0
@@ -17327,6 +17408,30 @@ snapshots:
semver: 7.7.2
ssri: 10.0.5
'@pnpm/package-requester@1004.0.2(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))':
dependencies:
'@pnpm/core-loggers': 1001.0.1(@pnpm/logger@1001.0.0)
'@pnpm/dependency-path': 1000.0.9
'@pnpm/error': 1000.0.2
'@pnpm/fetcher-base': 1000.0.11
'@pnpm/graceful-fs': 1000.0.0
'@pnpm/logger': 1001.0.0
'@pnpm/package-is-installable': 1000.0.10(@pnpm/logger@1001.0.0)
'@pnpm/pick-fetcher': 1000.0.0
'@pnpm/read-package-json': 1000.0.9
'@pnpm/resolver-base': 1003.0.1
'@pnpm/store-controller-types': 1003.0.2
'@pnpm/store.cafs': 1000.0.13
'@pnpm/types': 1000.6.0
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)
p-defer: 3.0.0
p-limit: 3.1.0
p-queue: 6.6.2
promise-share: 1.0.0
ramda: '@pnpm/ramda@0.28.1'
semver: 7.7.2
ssri: 10.0.5
'@pnpm/package-store@1002.0.4(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@18.19.34))':
dependencies:
'@pnpm/create-cafs-store': 1000.0.14(@pnpm/logger@1001.0.0)
@@ -17343,6 +17448,22 @@ snapshots:
ramda: '@pnpm/ramda@0.28.1'
ssri: 10.0.5
'@pnpm/package-store@1002.0.4(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))':
dependencies:
'@pnpm/create-cafs-store': 1000.0.14(@pnpm/logger@1001.0.0)
'@pnpm/fetcher-base': 1000.0.11
'@pnpm/logger': 1001.0.0
'@pnpm/package-requester': 1004.0.2(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))
'@pnpm/resolver-base': 1003.0.1
'@pnpm/store-controller-types': 1003.0.2
'@pnpm/store.cafs': 1000.0.13
'@pnpm/types': 1000.6.0
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)
'@zkochan/rimraf': 3.0.2
load-json-file: 6.2.0
ramda: '@pnpm/ramda@0.28.1'
ssri: 10.0.5
'@pnpm/parse-overrides@1000.0.2':
dependencies:
'@pnpm/catalogs.resolver': 1000.0.2
@@ -17559,6 +17680,25 @@ snapshots:
- supports-color
- typanion
'@pnpm/store-connection-manager@1002.0.3(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/cli-meta': 1000.0.8
'@pnpm/client': 1000.0.19(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/config': 1003.1.1(@pnpm/logger@1001.0.0)
'@pnpm/error': 1000.0.2
'@pnpm/logger': 1001.0.0
'@pnpm/package-store': 1002.0.4(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))
'@pnpm/server': 1001.0.4(@pnpm/logger@1001.0.0)
'@pnpm/store-path': 1000.0.2
'@zkochan/diable': 1.0.2
delay: 5.0.0
dir-is-case-sensitive: 2.0.0
transitivePeerDependencies:
- '@pnpm/worker'
- domexception
- supports-color
- typanion
'@pnpm/store-controller-types@1001.0.3':
dependencies:
'@pnpm/fetcher-base': 1000.0.5
@@ -17632,6 +17772,28 @@ snapshots:
- supports-color
- typanion
'@pnpm/tarball-fetcher@1001.0.8(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/core-loggers': 1001.0.1(@pnpm/logger@1001.0.0)
'@pnpm/error': 1000.0.2
'@pnpm/fetcher-base': 1000.0.11
'@pnpm/fetching-types': 1000.1.0
'@pnpm/fs.packlist': 2.0.0
'@pnpm/graceful-fs': 1000.0.0
'@pnpm/logger': 1001.0.0
'@pnpm/prepare-package': 1000.0.16(@pnpm/logger@1001.0.0)(typanion@3.14.0)
'@pnpm/worker': 1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)
'@zkochan/retry': 0.2.0
lodash.throttle: 4.1.1
p-map-values: 1.0.0
path-temp: 2.1.0
ramda: '@pnpm/ramda@0.28.1'
rename-overwrite: 6.0.3
transitivePeerDependencies:
- domexception
- supports-color
- typanion
'@pnpm/tarball-resolver@1002.0.2':
dependencies:
'@pnpm/fetching-types': 1000.1.0
@@ -17679,6 +17841,26 @@ snapshots:
transitivePeerDependencies:
- '@types/node'
'@pnpm/worker@1000.1.7(@pnpm/logger@packages+logger)(@types/node@22.15.29)':
dependencies:
'@pnpm/cafs-types': 1000.0.0
'@pnpm/create-cafs-store': 1000.0.14(@pnpm/logger@1001.0.0)
'@pnpm/crypto.polyfill': 1000.1.0
'@pnpm/error': 1000.0.2
'@pnpm/exec.pkg-requires-build': 1000.0.8
'@pnpm/fs.hard-link-dir': 1000.0.1(@pnpm/logger@1001.0.0)
'@pnpm/graceful-fs': 1000.0.0
'@pnpm/logger': link:packages/logger
'@pnpm/store.cafs': 1000.0.13
'@pnpm/symlink-dependency': 1000.0.9(@pnpm/logger@1001.0.0)
'@rushstack/worker-pool': 0.4.9(@types/node@22.15.29)
is-windows: 1.0.2
load-json-file: 6.2.0
p-limit: 3.1.0
shell-quote: 1.8.3
transitivePeerDependencies:
- '@types/node'
'@pnpm/workspace.find-packages@1000.0.15(@pnpm/logger@1000.0.0)':
dependencies:
'@pnpm/cli-utils': 1000.0.15(@pnpm/logger@1000.0.0)
@@ -17702,6 +17884,20 @@ snapshots:
- supports-color
- typanion
'@pnpm/workspace.find-packages@1000.0.25(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)':
dependencies:
'@pnpm/cli-utils': 1000.1.5(@pnpm/logger@1001.0.0)(@pnpm/worker@1000.1.7(@pnpm/logger@1001.0.0)(@types/node@22.15.29))(typanion@3.14.0)
'@pnpm/constants': 1001.1.0
'@pnpm/fs.find-packages': 1000.0.11
'@pnpm/logger': 1001.0.0
'@pnpm/types': 1000.6.0
'@pnpm/util.lex-comparator': 3.0.2
transitivePeerDependencies:
- '@pnpm/worker'
- domexception
- supports-color
- typanion
'@pnpm/workspace.manifest-writer@1000.1.4':
dependencies:
'@pnpm/constants': 1001.1.0
@@ -17999,8 +18195,6 @@ snapshots:
'@types/semver@7.7.0': {}
'@types/shell-quote@1.7.5': {}
'@types/signal-exit@3.0.4': {}
'@types/sinon@10.0.20':
@@ -22898,8 +23092,6 @@ snapshots:
shebang-regex@3.0.0: {}
shell-quote@1.8.2: {}
shell-quote@1.8.3: {}
shelljs@0.8.5:
@@ -22908,6 +23100,8 @@ snapshots:
interpret: 1.4.0
rechoir: 0.6.2
shlex@2.1.2: {}
short-tree@1.0.0:
dependencies:
'@types/bintrees': 1.0.6

View File

@@ -93,7 +93,6 @@ catalog:
'@types/semver': 7.5.3
'@types/signal-exit': ^3.0.4
'@types/sinon': ^10.0.20
'@types/shell-quote': ^1.7.5
'@types/ssri': ^7.1.5
'@types/tar': ^6.1.13
'@types/tar-stream': ^2.2.3
@@ -233,7 +232,7 @@ catalog:
semver-range-intersect: ^0.3.1
semver-utils: ^1.1.4
semver: ^7.7.1
shell-quote: ^1.8.2
shlex: ^2.1.2
signal-exit: ^3.0.7
sinon: ^16.1.3
sort-keys: ^4.2.0

View File

@@ -97,7 +97,7 @@ test('recursive test: pass the args to the command that is specified in the buil
const result = execPnpmSync(['-r', 'test', 'arg', '--flag=true'])
expect((result.stdout as Buffer).toString('utf8')).toMatch(
process.platform === 'win32' ? /ts-node test "arg" "--flag=true"/ : /ts-node test arg --flag\\=true/
process.platform === 'win32' ? /ts-node test "arg" "--flag=true"/ : /ts-node test arg --flag=true/
)
})

View File

@@ -43,7 +43,7 @@
"is-windows": "catalog:",
"load-json-file": "catalog:",
"p-limit": "catalog:",
"shell-quote": "catalog:"
"shlex": "catalog:"
},
"peerDependencies": {
"@pnpm/logger": "catalog:"
@@ -52,8 +52,7 @@
"@pnpm/logger": "workspace:*",
"@pnpm/types": "workspace:*",
"@pnpm/worker": "workspace:*",
"@types/is-windows": "catalog:",
"@types/shell-quote": "catalog:"
"@types/is-windows": "catalog:"
},
"engines": {
"node": ">=18.12"

View File

@@ -8,7 +8,7 @@ import isWindows from 'is-windows'
import { type PackageFilesIndex } from '@pnpm/store.cafs'
import { type DependencyManifest } from '@pnpm/types'
import pLimit from 'p-limit'
import { quote as shellQuote } from 'shell-quote'
import { join as shellQuote } from 'shlex'
import {
type TarballExtractMessage,
type AddDirToStoreMessage,