diff --git a/deps/npm/docs/content/commands/npm-approve-scripts.md b/deps/npm/docs/content/commands/npm-approve-scripts.md index e3445447c79..c4d3c15a814 100644 --- a/deps/npm/docs/content/commands/npm-approve-scripts.md +++ b/deps/npm/docs/content/commands/npm-approve-scripts.md @@ -25,6 +25,14 @@ In the current release, this field is advisory: install scripts still run by default, but installs print a list of packages whose scripts have not been reviewed. A future release will block unreviewed install scripts. +This command only works inside a project that has a `package.json`. Running +it with `--global` (`-g`) fails with an `EGLOBAL` error, since global +installs (`npm install -g`) and one-off executions (`npm exec` / `npx`) have +no project `package.json` to write to. To allow install scripts in those +contexts, use the `--allow-scripts` flag at install time (for example +`npm install -g --allow-scripts=canvas,sharp`) or persist the setting with +`npm config set allow-scripts=canvas,sharp --location=user`. + There are three modes: ```bash @@ -51,6 +59,14 @@ the command cannot infer. Existing `false` entries always win; `approve-scripts` will not silently re-allow a package you previously denied. +If a registry dependency has no `resolved` URL in your `package-lock.json` +(for example, an older lockfile or one written with +`omit-lockfile-registry-resolved`), npm cannot verify a trusted version for +it and cannot pin it: a `pkg@1.2.3` entry never matches, so the package +keeps appearing under `--allow-scripts-pending`. `approve-scripts` approves +these by name (`pkg: true`) and warns when it does. To restore pinning, +refresh the lockfile with `npm install`. + ### Examples ```bash @@ -74,9 +90,10 @@ npm approve-scripts --allow-scripts-pending * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. diff --git a/deps/npm/docs/content/commands/npm-ci.md b/deps/npm/docs/content/commands/npm-ci.md index bc460070459..741caf5eae7 100644 --- a/deps/npm/docs/content/commands/npm-ci.md +++ b/deps/npm/docs/content/commands/npm-ci.md @@ -74,8 +74,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -298,6 +306,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` diff --git a/deps/npm/docs/content/commands/npm-dedupe.md b/deps/npm/docs/content/commands/npm-dedupe.md index 8186ee2c1f3..a48bf1bd622 100644 --- a/deps/npm/docs/content/commands/npm-dedupe.md +++ b/deps/npm/docs/content/commands/npm-dedupe.md @@ -74,8 +74,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). diff --git a/deps/npm/docs/content/commands/npm-deny-scripts.md b/deps/npm/docs/content/commands/npm-deny-scripts.md index 51915b09fe1..fdefca28957 100644 --- a/deps/npm/docs/content/commands/npm-deny-scripts.md +++ b/deps/npm/docs/content/commands/npm-deny-scripts.md @@ -59,9 +59,10 @@ npm deny-scripts --all * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. diff --git a/deps/npm/docs/content/commands/npm-exec.md b/deps/npm/docs/content/commands/npm-exec.md index 13a0939209a..ff08d07786a 100644 --- a/deps/npm/docs/content/commands/npm-exec.md +++ b/deps/npm/docs/content/commands/npm-exec.md @@ -194,6 +194,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` diff --git a/deps/npm/docs/content/commands/npm-find-dupes.md b/deps/npm/docs/content/commands/npm-find-dupes.md index 52bb59b9f81..2d72186fe5a 100644 --- a/deps/npm/docs/content/commands/npm-find-dupes.md +++ b/deps/npm/docs/content/commands/npm-find-dupes.md @@ -25,8 +25,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). diff --git a/deps/npm/docs/content/commands/npm-install-ci-test.md b/deps/npm/docs/content/commands/npm-install-ci-test.md index 4528f63dfe2..2194a4df84a 100644 --- a/deps/npm/docs/content/commands/npm-install-ci-test.md +++ b/deps/npm/docs/content/commands/npm-install-ci-test.md @@ -27,8 +27,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -251,6 +259,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` diff --git a/deps/npm/docs/content/commands/npm-install-scripts.md b/deps/npm/docs/content/commands/npm-install-scripts.md new file mode 100644 index 00000000000..4182392c9a3 --- /dev/null +++ b/deps/npm/docs/content/commands/npm-install-scripts.md @@ -0,0 +1,166 @@ +--- +title: npm-install-scripts +section: 1 +description: Manage install-script approvals for dependencies +--- + +### Synopsis + +```bash +npm install-scripts approve [ ...] +npm install-scripts approve --all +npm install-scripts deny [ ...] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune +``` + +Note: This command is unaware of workspaces. + +### Description + +Manages the `allowScripts` field in your project's `package.json`, which +records which of your dependencies are permitted to run install scripts +(`preinstall`, `install`, `postinstall`, and `prepare` for non-registry +sources). This is the recommended way to maintain that field. + +Dependency install scripts are blocked by default. Install commands +silently skip lifecycle scripts for any dependency that does not have a +matching entry in `allowScripts`, and end with a list of the packages +whose scripts were skipped so you can review them here. + +This command only works inside a project that has a `package.json`. Running +it with `--global` (`-g`) fails with an `EGLOBAL` error, since global +installs (`npm install -g`) and one-off executions (`npm exec` / `npx`) have +no project `package.json` to write to. To allow install scripts in those +contexts, use the `--allow-scripts` flag at install time (for example +`npm install -g --allow-scripts=canvas,sharp`) or persist the setting with +`npm config set allow-scripts=canvas,sharp --location=user`. + +There are four subcommands: + +```bash +npm install-scripts approve [ ...] +npm install-scripts approve --all +npm install-scripts deny [ ...] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune +``` + +`approve` allows install scripts for the named packages. `` matches +every installed version of that package. By default it writes pinned entries +(`pkg@1.2.3`), which keep their approval narrowed to the specific version you +reviewed. Pass `--no-allow-scripts-pin` to write name-only entries that allow +any future version. `--all` approves every package with unreviewed install +scripts in one go. + +`deny` records an explicit denial for the named packages (a name-only `false` +entry), which survives `npm install-scripts approve --all` and excludes the +package from any future blanket approval. `--all` denies every package with +unreviewed install scripts. + +`ls` is read-only: it lists every package whose install scripts are not yet +covered by `allowScripts`, without modifying `package.json`. + +`prune` removes `allowScripts` entries that no longer match an installed +package with an install script, either because the package is no longer +installed (a transitive dependency changed, or a pinned `pkg@1.2.3` was +upgraded) or because it no longer has an install script. Both approvals +(`true`) and denials (`false`) are removed. It edits only the `allowScripts` +field in `package.json`, never `.npmrc` or `--allow-scripts`. Pass `--dry-run` +to preview without writing. Unparseable keys are left alone. + +`approve` honours the asymmetric pin rule: if you re-approve a package whose +installed version has changed, the existing pin is rewritten to track the new +installed version. Multi-version statements (`pkg@1 || 2`) are left alone, +since they likely capture intent that the command cannot infer. Existing +`false` entries always win; `approve` will not silently re-allow a package you +previously denied. + +The standalone commands [`npm approve-scripts`](/commands/npm-approve-scripts) +and [`npm deny-scripts`](/commands/npm-deny-scripts) are aliases for +`npm install-scripts approve` and `npm install-scripts deny`. + +### Examples + +```bash +# Approve all currently-installed install scripts after reviewing them +npm install-scripts approve --all + +# Approve specific packages, pinned to their installed version +npm install-scripts approve canvas sharp + +# Deny a package so it stays blocked +npm install-scripts deny telemetry-pkg + +# Preview which packages still need review +npm install-scripts ls + +# Preview stale allowScripts entries, then remove them +npm install-scripts prune --dry-run +npm install-scripts prune +``` + +### Configuration + +#### `all` + +* Default: false +* Type: Boolean + +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. + + + +#### `allow-scripts-pin` + +* Default: true +* Type: Boolean + +Write pinned (`pkg@version`) entries when approving install scripts. Set to +`false` to write name-only entries that allow any version. Has no effect on +`npm deny-scripts`, which always writes name-only entries regardless of this +setting. + + + +#### `dry-run` + +* Default: false +* Type: Boolean + +Indicates that you don't want npm to make any changes and that it should +only report what it would have done. This can be passed into any of the +commands that modify your local installation, eg, `install`, `update`, +`dedupe`, `uninstall`, as well as `pack` and `publish`. + +Note: This is NOT honored by other network related commands, eg `dist-tags`, +`owner`, etc. + + + +#### `json` + +* Default: false +* Type: Boolean + +Whether or not to output JSON data, rather than the normal output. + +* In `npm pkg set` it enables parsing set values with JSON.parse() before + saving them to your `package.json`. + +Not supported by all npm commands. + + + +### See Also + +* [npm approve-scripts](/commands/npm-approve-scripts) +* [npm deny-scripts](/commands/npm-deny-scripts) +* [npm install](/commands/npm-install) +* [npm rebuild](/commands/npm-rebuild) +* [package.json](/configuring-npm/package-json) diff --git a/deps/npm/docs/content/commands/npm-install-test.md b/deps/npm/docs/content/commands/npm-install-test.md index 5a2f33a84ca..e13f79a51e6 100644 --- a/deps/npm/docs/content/commands/npm-install-test.md +++ b/deps/npm/docs/content/commands/npm-install-test.md @@ -68,8 +68,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -328,6 +336,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` @@ -375,6 +387,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + #### `min-release-age` @@ -394,6 +413,43 @@ your `.npmrc` is preserved when npm internally spawns a sub-process with apply, `before` wins within a single source and across sources the standard precedence rules apply. +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. #### `bin-links` diff --git a/deps/npm/docs/content/commands/npm-install.md b/deps/npm/docs/content/commands/npm-install.md index 7bc00701e7b..98d69d5e842 100644 --- a/deps/npm/docs/content/commands/npm-install.md +++ b/deps/npm/docs/content/commands/npm-install.md @@ -410,8 +410,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -670,6 +678,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` @@ -717,6 +729,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + #### `min-release-age` @@ -736,6 +755,43 @@ your `.npmrc` is preserved when npm internally spawns a sub-process with apply, `before` wins within a single source and across sources the standard precedence rules apply. +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. #### `bin-links` diff --git a/deps/npm/docs/content/commands/npm-link.md b/deps/npm/docs/content/commands/npm-link.md index 37efda66408..fa9626c4edd 100644 --- a/deps/npm/docs/content/commands/npm-link.md +++ b/deps/npm/docs/content/commands/npm-link.md @@ -138,8 +138,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). diff --git a/deps/npm/docs/content/commands/npm-ll.md b/deps/npm/docs/content/commands/npm-ll.md index 2114c263d4b..dacac2f5a26 100644 --- a/deps/npm/docs/content/commands/npm-ll.md +++ b/deps/npm/docs/content/commands/npm-ll.md @@ -23,9 +23,10 @@ List installed packages * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md index c0a341e46fd..fba77fd01cf 100644 --- a/deps/npm/docs/content/commands/npm-ls.md +++ b/deps/npm/docs/content/commands/npm-ls.md @@ -23,7 +23,7 @@ Note that nested packages will *also* show the paths to the specified packages. For example, running `npm ls promzard` in npm's source tree will show: ```bash -npm@11.16.0 /path/to/npm +npm@11.18.0 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 ``` @@ -43,9 +43,10 @@ When run as `ll` or `la`, it shows extended information by default. * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. diff --git a/deps/npm/docs/content/commands/npm-outdated.md b/deps/npm/docs/content/commands/npm-outdated.md index 92e15e96020..40f7e835a68 100644 --- a/deps/npm/docs/content/commands/npm-outdated.md +++ b/deps/npm/docs/content/commands/npm-outdated.md @@ -20,7 +20,7 @@ Use `--all` to find all outdated meta-dependencies as well. In the output: * `wanted` is the maximum version of the package that satisfies the semver range specified in `package.json`. - If there's no available semver range (i.e. you're running `npm outdated --global`, or the package isn't included in `package.json`), then `wanted` shows the currently-installed version. + If there's no available semver range (i.e. you're running `npm outdated --global`, or the package isn't included in `package.json`), then `wanted` shows the latest version. * `latest` is the version of the package tagged as latest in the registry. Running `npm publish` with no special configuration will publish the package with a dist-tag of `latest`. This may or may not be the maximum version of the package, or the most-recently published version of the package, depending on how the package's developer manages the latest [dist-tag](/commands/npm-dist-tag). @@ -73,9 +73,10 @@ A few things to note: * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. @@ -171,6 +172,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + #### `min-release-age` @@ -190,6 +198,43 @@ your `.npmrc` is preserved when npm internally spawns a sub-process with apply, `before` wins within a single source and across sources the standard precedence rules apply. +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. ### See Also diff --git a/deps/npm/docs/content/commands/npm-query.md b/deps/npm/docs/content/commands/npm-query.md index f80dfdcf58b..4349e47ad23 100644 --- a/deps/npm/docs/content/commands/npm-query.md +++ b/deps/npm/docs/content/commands/npm-query.md @@ -262,6 +262,92 @@ This config cannot be used with: `expect-result-count` Tells to expect a specific number of results from the command. This config cannot be used with: `expect-results` + +#### `before` + +* Default: null +* Type: null or Date + +If passed to `npm install`, will rebuild the npm tree such that only +versions that were available **on or before** the given date are installed. +If there are no versions available for the current set of dependencies, the +command will error. + +If the requested version is a `dist-tag` and the given tag does not pass the +`--before` filter, the most recent version less than or equal to that tag +will be used. For example, `foo@latest` might install `foo@1.2` even though +`latest` is `2.0`. + +If `before` and `min-release-age` are both set in the same source, `before` +wins (an explicit absolute date overrides a relative window). Across +sources, the standard precedence applies (cli > env > project > user > +global), so a higher-priority source can always relax or override a +lower-priority one. + +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + + + +#### `min-release-age` + +* Default: null +* Type: null or Number + +If set, npm will build the npm tree such that only versions that were +available more than the given number of days ago will be installed. If there +are no versions available for the current set of dependencies, the command +will error. + +This flag is a complement to `before`, which accepts an exact date instead +of a relative number of days. The two may coexist (e.g. `min-release-age` in +your `.npmrc` is preserved when npm internally spawns a sub-process with +`--before` while preparing a `git:` or `github:` dependency); when both +apply, `before` wins within a single source and across sources the standard +precedence rules apply. + +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + +This value is not exported to the environment for child processes. ## See Also * [dependency selectors](/using-npm/dependency-selectors) diff --git a/deps/npm/docs/content/commands/npm-rebuild.md b/deps/npm/docs/content/commands/npm-rebuild.md index 18b1d37c779..c70307a2a7f 100644 --- a/deps/npm/docs/content/commands/npm-rebuild.md +++ b/deps/npm/docs/content/commands/npm-rebuild.md @@ -136,6 +136,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` diff --git a/deps/npm/docs/content/commands/npm-stage.md b/deps/npm/docs/content/commands/npm-stage.md index cda1b493f9a..798d6c2d953 100644 --- a/deps/npm/docs/content/commands/npm-stage.md +++ b/deps/npm/docs/content/commands/npm-stage.md @@ -151,7 +151,7 @@ npm stage publish | Flag | Default | Type | Description | | --- | --- | --- | --- | -| `--tag` | "latest" | String | If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag. It is the tag added to the package@version specified in the `npm dist-tag add` command, if no explicit tag is given. When used by the `npm diff` command, this is the tag used to fetch the tarball that will be compared with the local files by default. If used in the `npm publish` command, this is the tag that will be added to the package submitted to the registry. | +| `--tag` | "latest" | String | If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag. It is the tag added to the package@version specified in the `npm dist-tag add` command, if no explicit tag is given. When used by the `npm diff` command, this is the tag used to fetch the tarball that will be compared with the local files by default. If used in the `npm publish` command, this is the tag that will be added to the package submitted to the registry. | | `--access` | 'public' for new packages, existing packages it will not change the current level | null, "restricted", "public", or "private" | If you do not want your scoped package to be publicly viewable (and installable) set `--access=restricted`. Unscoped packages cannot be set to `restricted`. Note: This defaults to not changing the current access level for existing packages. Specifying a value of `restricted` or `public` during publish will change the access for an existing package the same way that `npm access set status` would. The value `private` is an alias for `restricted`. | | `--dry-run` | false | Boolean | Indicates that you don't want npm to make any changes and that it should only report what it would have done. This can be passed into any of the commands that modify your local installation, eg, `install`, `update`, `dedupe`, `uninstall`, as well as `pack` and `publish`. Note: This is NOT honored by other network related commands, eg `dist-tags`, `owner`, etc. | | `--otp` | null | null or String | This is a one-time password from a two-factor authenticator. It's needed when publishing or changing package permissions with `npm access`. If not set, and a registry response fails with a challenge for a one-time password, npm will prompt on the command line for one. | diff --git a/deps/npm/docs/content/commands/npm-trust.md b/deps/npm/docs/content/commands/npm-trust.md index 5aac2035b38..bebbd1efa31 100644 --- a/deps/npm/docs/content/commands/npm-trust.md +++ b/deps/npm/docs/content/commands/npm-trust.md @@ -12,7 +12,7 @@ Note: This command is unaware of workspaces. Before using npm trust commands, ensure the following requirements are met: -* **npm version**: `npm@11.10.0` or above is required. Use `npm install -g npm@^11.10.0` to update if needed. +* **npm version**: `npm@11.15.0` or above is required. Use `npm install -g npm@^11.15.0` to update if needed. * **Write permissions on the package**: You must have write access to the package you're configuring. * **2FA enabled on account**: Two-factor authentication must be enabled at the account level. Even if it's not currently enabled, you must enable it to use trust commands. * **Supported authentication methods**: Granular Access Tokens (GAT) with the bypass 2FA option are not supported. Legacy basic auth (username and password) credentials will not work for trust commands or endpoints. diff --git a/deps/npm/docs/content/commands/npm-update.md b/deps/npm/docs/content/commands/npm-update.md index 86b54eed070..317f85f7d0d 100644 --- a/deps/npm/docs/content/commands/npm-update.md +++ b/deps/npm/docs/content/commands/npm-update.md @@ -132,8 +132,7 @@ In this case if you really did need your package to use a newer version you woul `npm update -g` will apply the `update` action to each globally installed package that is `outdated` -- that is, has a version that is different from `wanted`. -Note: Globally installed packages are treated as if they are installed with a caret semver range specified. -So if you require to update to `latest` you may need to run `npm install -g [...]` +Note: Globally installed packages do not have a `package.json` semver range available, so their `wanted` version is `latest`. NOTE: If a package has been upgraded to a version newer than `latest`, it will be _downgraded_. @@ -178,8 +177,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -339,6 +346,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `dangerously-allow-all-scripts` @@ -386,6 +397,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + #### `min-release-age` @@ -405,6 +423,43 @@ your `.npmrc` is preserved when npm internally spawns a sub-process with apply, `before` wins within a single source and across sources the standard precedence rules apply. +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. #### `bin-links` diff --git a/deps/npm/docs/content/commands/npm.md b/deps/npm/docs/content/commands/npm.md index ba1890149fc..088553c6ffc 100644 --- a/deps/npm/docs/content/commands/npm.md +++ b/deps/npm/docs/content/commands/npm.md @@ -14,7 +14,7 @@ Note: This command is unaware of workspaces. ### Version -11.16.0 +11.18.0 ### Description diff --git a/deps/npm/docs/content/configuring-npm/package-json.md b/deps/npm/docs/content/configuring-npm/package-json.md index 972845cd3c1..12b87cb7a84 100644 --- a/deps/npm/docs/content/configuring-npm/package-json.md +++ b/deps/npm/docs/content/configuring-npm/package-json.md @@ -884,6 +884,21 @@ To make sure the package `@npm/foo` is always installed as version `1.0.0` no ma } ``` +Override values can use any specifier that npm accepts for dependencies, including +an exact version, a semver range, a dist-tag, or a replacement specifier such as +`npm:`, `file:`, or a Git URL. + +For example, if you only need to enforce a minimum patched release instead of one +exact version, you can use a semver range: + +```json +{ + "overrides": { + "@npm/foo": "^1.0.0" + } +} +``` + The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. This will cause `@npm/foo` to always be `1.0.0` while also making `@npm/bar` at any depth beyond `@npm/foo` also `1.0.0`: diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md index d1167e0d148..5d951493e8a 100644 --- a/deps/npm/docs/content/using-npm/config.md +++ b/deps/npm/docs/content/using-npm/config.md @@ -161,9 +161,10 @@ The value `private` is an alias for `restricted`. * Default: false * Type: Boolean -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For `npm outdated` and `npm ls` this lists every outdated or installed +package. For `npm approve-scripts` and `npm deny-scripts` it selects every +package with pending install scripts. @@ -348,6 +349,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with `min-release-age`, when this cutoff blocks a fix that `npm audit +fix` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + #### `bin-links` @@ -1025,8 +1033,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use `--install-strategy=linked` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +`import` of a package that was never added to `package.json` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -1220,6 +1236,43 @@ your `.npmrc` is preserved when npm internally spawns a sub-process with apply, `before` wins within a single source and across sources the standard precedence rules apply. +When this window stops `npm audit fix` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +`min-release-age-exclude`, or relax `min-release-age` or `before`. + +Packages whose names match `min-release-age-exclude` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### `min-release-age-exclude` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or `minimatch` glob patterns that are exempt from +the `min-release-age` (and `before`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +``` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +``` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so `@myorg/*` matches `@myorg/shared-utils`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. #### `name` @@ -1585,7 +1638,14 @@ registry (https://registry.npmjs.org) to the configured registry. If set to "never", then use the registry value. If set to "always", then replace the registry host with the configured host every time. -You may also specify a bare hostname (e.g., "registry.npmjs.org"). +You may also specify a bare hostname (e.g., "registry.npmjs.org") to only +replace URLs coming from that host. + +You may also specify a full URL including a path (e.g., +"https://old-registry.example.com/npm/path"). In that case, resolved URLs +whose host and path begin with that prefix will have the entire prefix +replaced with the configured registry URL (host and path), without +duplicating path segments. @@ -1842,6 +1902,10 @@ silently skipped; this setting only affects unreviewed entries. `--ignore-scripts` and `--dangerously-allow-all-scripts` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching `os`, `cpu`, or `libc`) are not flagged, because +their install scripts never run. + #### `strict-peer-deps` diff --git a/deps/npm/docs/content/using-npm/developers.md b/deps/npm/docs/content/using-npm/developers.md index de0cb848c59..b1fff0e3894 100644 --- a/deps/npm/docs/content/using-npm/developers.md +++ b/deps/npm/docs/content/using-npm/developers.md @@ -171,6 +171,24 @@ to install it locally into the node_modules folder in that other place. Then go into the node-repl, and try using require("my-thing") to bring in your module's main module. +#### Catching undeclared ("phantom") dependencies + +Under the default hoisted `node_modules` layout, your package can `import` a dependency it never declared and still resolve it. +A transitive dependency hoisted alongside it, or your workspace root's `node_modules`, happens to satisfy the `import`. +That undeclared ("phantom") dependency passes your own build silently, then fails for anyone who installs your package on its own. + +We recommend developing your package under [`install-strategy=linked`](/using-npm/config#install-strategy). +The isolated layout only exposes a package's *declared* dependencies, so an `import` of an undeclared package fails for you during development instead of resolving by accident, shipping broken, and failing for your users: + +```bash +npm install --install-strategy=linked +npm test +``` + +> **Note:** This doesn't catch every case. +> A dependency that's still satisfied at your build by a `devDependency` or by your workspace root's `node_modules` can resolve fine for you and still be missing for whoever installs your package. +> So treat it as one check, not a guarantee, alongside auditing the dependencies your published package actually uses. + ### Create a User Account Create a user with the adduser command. diff --git a/deps/npm/docs/output/commands/npm-access.html b/deps/npm/docs/output/commands/npm-access.html index 983b44e86a6..13475a5d16f 100644 --- a/deps/npm/docs/output/commands/npm-access.html +++ b/deps/npm/docs/output/commands/npm-access.html @@ -186,9 +186,9 @@
-

+

npm-access - @11.16.0 + @11.18.0

Set access level on published packages
diff --git a/deps/npm/docs/output/commands/npm-adduser.html b/deps/npm/docs/output/commands/npm-adduser.html index 8945c6ef6cb..e43659736fe 100644 --- a/deps/npm/docs/output/commands/npm-adduser.html +++ b/deps/npm/docs/output/commands/npm-adduser.html @@ -186,9 +186,9 @@
-

+

npm-adduser - @11.16.0 + @11.18.0

Add a registry user account
diff --git a/deps/npm/docs/output/commands/npm-approve-scripts.html b/deps/npm/docs/output/commands/npm-approve-scripts.html index 1849ae8c501..c3bc0172b5a 100644 --- a/deps/npm/docs/output/commands/npm-approve-scripts.html +++ b/deps/npm/docs/output/commands/npm-approve-scripts.html @@ -186,9 +186,9 @@
-

+

npm-approve-scripts - @11.16.0 + @11.18.0

Approve install scripts for specific dependencies
@@ -212,6 +212,13 @@

Description

In the current release, this field is advisory: install scripts still run by default, but installs print a list of packages whose scripts have not been reviewed. A future release will block unreviewed install scripts.

+

This command only works inside a project that has a package.json. Running +it with --global (-g) fails with an EGLOBAL error, since global +installs (npm install -g) and one-off executions (npm exec / npx) have +no project package.json to write to. To allow install scripts in those +contexts, use the --allow-scripts flag at install time (for example +npm install -g --allow-scripts=canvas,sharp) or persist the setting with +npm config set allow-scripts=canvas,sharp --location=user.

There are three modes:

npm approve-scripts <pkg> [<pkg> ...]
 npm approve-scripts --all
@@ -231,6 +238,13 @@ 

Description

the command cannot infer. Existing false entries always win; approve-scripts will not silently re-allow a package you previously denied.

+

If a registry dependency has no resolved URL in your package-lock.json +(for example, an older lockfile or one written with +omit-lockfile-registry-resolved), npm cannot verify a trusted version for +it and cannot pin it: a pkg@1.2.3 entry never matches, so the package +keeps appearing under --allow-scripts-pending. approve-scripts approves +these by name (pkg: true) and warns when it does. To restore pinning, +refresh the lockfile with npm install.

Examples

# Approve all currently-installed install scripts after reviewing them
 npm approve-scripts --all
@@ -250,9 +264,10 @@ 

all

  • Default: false
  • Type: Boolean
  • -

    When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

    +

    Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

    allow-scripts-pending

    • Default: false
    • diff --git a/deps/npm/docs/output/commands/npm-audit.html b/deps/npm/docs/output/commands/npm-audit.html index f018a7ae7f1..61042b6fbb0 100644 --- a/deps/npm/docs/output/commands/npm-audit.html +++ b/deps/npm/docs/output/commands/npm-audit.html @@ -186,9 +186,9 @@
      -

      +

      npm-audit - @11.16.0 + @11.18.0

      Run a security audit
      diff --git a/deps/npm/docs/output/commands/npm-bugs.html b/deps/npm/docs/output/commands/npm-bugs.html index 45ca5bec8ef..660f011d1a0 100644 --- a/deps/npm/docs/output/commands/npm-bugs.html +++ b/deps/npm/docs/output/commands/npm-bugs.html @@ -186,9 +186,9 @@
      -

      +

      npm-bugs - @11.16.0 + @11.18.0

      Report bugs for a package in a web browser
      diff --git a/deps/npm/docs/output/commands/npm-cache.html b/deps/npm/docs/output/commands/npm-cache.html index 0e561b39dab..553a38d06f4 100644 --- a/deps/npm/docs/output/commands/npm-cache.html +++ b/deps/npm/docs/output/commands/npm-cache.html @@ -186,9 +186,9 @@
      -

      +

      npm-cache - @11.16.0 + @11.18.0

      Manipulates packages cache
      diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html index 745a22ea53c..3e61cba31be 100644 --- a/deps/npm/docs/output/commands/npm-ci.html +++ b/deps/npm/docs/output/commands/npm-ci.html @@ -186,9 +186,9 @@
      -

      +

      npm-ci - @11.16.0 + @11.18.0

      Clean install a project
      @@ -251,8 +251,15 @@

      install-strategy

      (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

      +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

      +

      We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

      legacy-bundling

      • Default: false
      • @@ -419,6 +426,9 @@

        strict-allow-scripts

        silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

        +

        Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

        dangerously-allow-all-scripts

        • Default: false
        • diff --git a/deps/npm/docs/output/commands/npm-completion.html b/deps/npm/docs/output/commands/npm-completion.html index 866085f4235..d24da48ebb0 100644 --- a/deps/npm/docs/output/commands/npm-completion.html +++ b/deps/npm/docs/output/commands/npm-completion.html @@ -186,9 +186,9 @@
          -

          +

          npm-completion - @11.16.0 + @11.18.0

          Tab Completion for npm
          diff --git a/deps/npm/docs/output/commands/npm-config.html b/deps/npm/docs/output/commands/npm-config.html index 3f9be6dedfb..a3c0dab2dee 100644 --- a/deps/npm/docs/output/commands/npm-config.html +++ b/deps/npm/docs/output/commands/npm-config.html @@ -186,9 +186,9 @@
          -

          +

          npm-config - @11.16.0 + @11.18.0

          Manage the npm configuration files
          diff --git a/deps/npm/docs/output/commands/npm-dedupe.html b/deps/npm/docs/output/commands/npm-dedupe.html index e15165a5d00..fa8d4b70843 100644 --- a/deps/npm/docs/output/commands/npm-dedupe.html +++ b/deps/npm/docs/output/commands/npm-dedupe.html @@ -186,9 +186,9 @@
          -

          +

          npm-dedupe - @11.16.0 + @11.18.0

          Reduce duplication in the package tree
          @@ -245,8 +245,15 @@

          install-strategy

          (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

          +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

          +

          We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

          legacy-bundling

          • Default: false
          • diff --git a/deps/npm/docs/output/commands/npm-deny-scripts.html b/deps/npm/docs/output/commands/npm-deny-scripts.html index e9b18afb88b..4f7653c4017 100644 --- a/deps/npm/docs/output/commands/npm-deny-scripts.html +++ b/deps/npm/docs/output/commands/npm-deny-scripts.html @@ -186,9 +186,9 @@
            -

            +

            npm-deny-scripts - @11.16.0 + @11.18.0

            Deny install scripts for specific dependencies
            @@ -237,9 +237,10 @@

            all

          • Default: false
          • Type: Boolean
          -

          When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

          +

          Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

          allow-scripts-pending

          • Default: false
          • diff --git a/deps/npm/docs/output/commands/npm-deprecate.html b/deps/npm/docs/output/commands/npm-deprecate.html index 9bda62f1a89..30c4c912238 100644 --- a/deps/npm/docs/output/commands/npm-deprecate.html +++ b/deps/npm/docs/output/commands/npm-deprecate.html @@ -186,9 +186,9 @@
            -

            +

            npm-deprecate - @11.16.0 + @11.18.0

            Deprecate a version of a package
            diff --git a/deps/npm/docs/output/commands/npm-diff.html b/deps/npm/docs/output/commands/npm-diff.html index 7b72340cb35..6cf770360c1 100644 --- a/deps/npm/docs/output/commands/npm-diff.html +++ b/deps/npm/docs/output/commands/npm-diff.html @@ -186,9 +186,9 @@
            -

            +

            npm-diff - @11.16.0 + @11.18.0

            The registry diff command
            diff --git a/deps/npm/docs/output/commands/npm-dist-tag.html b/deps/npm/docs/output/commands/npm-dist-tag.html index 3b95fe2e3eb..59985e4a43f 100644 --- a/deps/npm/docs/output/commands/npm-dist-tag.html +++ b/deps/npm/docs/output/commands/npm-dist-tag.html @@ -186,9 +186,9 @@
            -

            +

            npm-dist-tag - @11.16.0 + @11.18.0

            Modify package distribution tags
            diff --git a/deps/npm/docs/output/commands/npm-docs.html b/deps/npm/docs/output/commands/npm-docs.html index a12dd65697c..884f20d70d2 100644 --- a/deps/npm/docs/output/commands/npm-docs.html +++ b/deps/npm/docs/output/commands/npm-docs.html @@ -186,9 +186,9 @@
            -

            +

            npm-docs - @11.16.0 + @11.18.0

            Open documentation for a package in a web browser
            diff --git a/deps/npm/docs/output/commands/npm-doctor.html b/deps/npm/docs/output/commands/npm-doctor.html index d9094606fa2..13bb25228dd 100644 --- a/deps/npm/docs/output/commands/npm-doctor.html +++ b/deps/npm/docs/output/commands/npm-doctor.html @@ -186,9 +186,9 @@
            -

            +

            npm-doctor - @11.16.0 + @11.18.0

            Check the health of your npm environment
            diff --git a/deps/npm/docs/output/commands/npm-edit.html b/deps/npm/docs/output/commands/npm-edit.html index a5f7d958498..6d1215ebfe1 100644 --- a/deps/npm/docs/output/commands/npm-edit.html +++ b/deps/npm/docs/output/commands/npm-edit.html @@ -186,9 +186,9 @@
            -

            +

            npm-edit - @11.16.0 + @11.18.0

            Edit an installed package
            diff --git a/deps/npm/docs/output/commands/npm-exec.html b/deps/npm/docs/output/commands/npm-exec.html index 333fd7312a6..3f57293a17f 100644 --- a/deps/npm/docs/output/commands/npm-exec.html +++ b/deps/npm/docs/output/commands/npm-exec.html @@ -186,9 +186,9 @@
            -

            +

            npm-exec - @11.16.0 + @11.18.0

            Run a command from a local or remote npm package
            @@ -336,6 +336,9 @@

            strict-allow-scripts

            silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

            +

            Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

            dangerously-allow-all-scripts

            • Default: false
            • diff --git a/deps/npm/docs/output/commands/npm-explain.html b/deps/npm/docs/output/commands/npm-explain.html index feef6d1cf95..5d5f6cea5ce 100644 --- a/deps/npm/docs/output/commands/npm-explain.html +++ b/deps/npm/docs/output/commands/npm-explain.html @@ -186,9 +186,9 @@
              -

              +

              npm-explain - @11.16.0 + @11.18.0

              Explain installed packages
              diff --git a/deps/npm/docs/output/commands/npm-explore.html b/deps/npm/docs/output/commands/npm-explore.html index 0985c9bb2e8..d1ecb4e8188 100644 --- a/deps/npm/docs/output/commands/npm-explore.html +++ b/deps/npm/docs/output/commands/npm-explore.html @@ -186,9 +186,9 @@
              -

              +

              npm-explore - @11.16.0 + @11.18.0

              Browse an installed package
              diff --git a/deps/npm/docs/output/commands/npm-find-dupes.html b/deps/npm/docs/output/commands/npm-find-dupes.html index c013dd0db41..28a90663987 100644 --- a/deps/npm/docs/output/commands/npm-find-dupes.html +++ b/deps/npm/docs/output/commands/npm-find-dupes.html @@ -186,9 +186,9 @@
              -

              +

              npm-find-dupes - @11.16.0 + @11.18.0

              Find duplication in the package tree
              @@ -213,8 +213,15 @@

              install-strategy

              (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

              +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

              +

              We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

              legacy-bundling

              • Default: false
              • diff --git a/deps/npm/docs/output/commands/npm-fund.html b/deps/npm/docs/output/commands/npm-fund.html index 927ce09fa8c..26761cc9019 100644 --- a/deps/npm/docs/output/commands/npm-fund.html +++ b/deps/npm/docs/output/commands/npm-fund.html @@ -186,9 +186,9 @@
                -

                +

                npm-fund - @11.16.0 + @11.18.0

                Retrieve funding information
                diff --git a/deps/npm/docs/output/commands/npm-get.html b/deps/npm/docs/output/commands/npm-get.html index 675a4fcecb9..e8fe5dfc037 100644 --- a/deps/npm/docs/output/commands/npm-get.html +++ b/deps/npm/docs/output/commands/npm-get.html @@ -186,9 +186,9 @@
                -

                +

                npm-get - @11.16.0 + @11.18.0

                Get a value from the npm configuration
                diff --git a/deps/npm/docs/output/commands/npm-help-search.html b/deps/npm/docs/output/commands/npm-help-search.html index ba77fc89ae5..24f4ddafaea 100644 --- a/deps/npm/docs/output/commands/npm-help-search.html +++ b/deps/npm/docs/output/commands/npm-help-search.html @@ -186,9 +186,9 @@
                -

                +

                npm-help-search - @11.16.0 + @11.18.0

                Search npm help documentation
                diff --git a/deps/npm/docs/output/commands/npm-help.html b/deps/npm/docs/output/commands/npm-help.html index 5c83c72e328..4fb2ef4be76 100644 --- a/deps/npm/docs/output/commands/npm-help.html +++ b/deps/npm/docs/output/commands/npm-help.html @@ -186,9 +186,9 @@
                -

                +

                npm-help - @11.16.0 + @11.18.0

                Get help on npm
                diff --git a/deps/npm/docs/output/commands/npm-init.html b/deps/npm/docs/output/commands/npm-init.html index 321a462a5f0..deeaf25a234 100644 --- a/deps/npm/docs/output/commands/npm-init.html +++ b/deps/npm/docs/output/commands/npm-init.html @@ -186,9 +186,9 @@
                -

                +

                npm-init - @11.16.0 + @11.18.0

                Create a package.json file
                diff --git a/deps/npm/docs/output/commands/npm-install-ci-test.html b/deps/npm/docs/output/commands/npm-install-ci-test.html index 2658ecedd0e..2227da94885 100644 --- a/deps/npm/docs/output/commands/npm-install-ci-test.html +++ b/deps/npm/docs/output/commands/npm-install-ci-test.html @@ -186,9 +186,9 @@
                -

                +

                npm-install-ci-test - @11.16.0 + @11.18.0

                Install a project with a clean slate and run tests
                @@ -215,8 +215,15 @@

                install-strategy

                (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

                +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

                +

                We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

                legacy-bundling

                • Default: false
                • @@ -383,6 +390,9 @@

                  strict-allow-scripts

                  silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

                  +

                  Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

                  dangerously-allow-all-scripts

                  • Default: false
                  • diff --git a/deps/npm/docs/output/commands/npm-install-scripts.html b/deps/npm/docs/output/commands/npm-install-scripts.html new file mode 100644 index 00000000000..1b036581f6a --- /dev/null +++ b/deps/npm/docs/output/commands/npm-install-scripts.html @@ -0,0 +1,341 @@ + + +npm-install-scripts + + + + + +
                    +
                    +

                    + npm-install-scripts + @11.18.0 +

                    +Manage install-script approvals for dependencies +
                    + +
                    +

                    Table of contents

                    + +
                    + +

                    Synopsis

                    +
                    npm install-scripts approve <pkg> [<pkg> ...]
                    +npm install-scripts approve --all
                    +npm install-scripts deny <pkg> [<pkg> ...]
                    +npm install-scripts deny --all
                    +npm install-scripts ls
                    +npm install-scripts prune
                    +
                    +

                    Note: This command is unaware of workspaces.

                    +

                    Description

                    +

                    Manages the allowScripts field in your project's package.json, which +records which of your dependencies are permitted to run install scripts +(preinstall, install, postinstall, and prepare for non-registry +sources). This is the recommended way to maintain that field.

                    +

                    Dependency install scripts are blocked by default. Install commands +silently skip lifecycle scripts for any dependency that does not have a +matching entry in allowScripts, and end with a list of the packages +whose scripts were skipped so you can review them here.

                    +

                    This command only works inside a project that has a package.json. Running +it with --global (-g) fails with an EGLOBAL error, since global +installs (npm install -g) and one-off executions (npm exec / npx) have +no project package.json to write to. To allow install scripts in those +contexts, use the --allow-scripts flag at install time (for example +npm install -g --allow-scripts=canvas,sharp) or persist the setting with +npm config set allow-scripts=canvas,sharp --location=user.

                    +

                    There are four subcommands:

                    +
                    npm install-scripts approve <pkg> [<pkg> ...]
                    +npm install-scripts approve --all
                    +npm install-scripts deny <pkg> [<pkg> ...]
                    +npm install-scripts deny --all
                    +npm install-scripts ls
                    +npm install-scripts prune
                    +
                    +

                    approve allows install scripts for the named packages. <pkg> matches +every installed version of that package. By default it writes pinned entries +(pkg@1.2.3), which keep their approval narrowed to the specific version you +reviewed. Pass --no-allow-scripts-pin to write name-only entries that allow +any future version. --all approves every package with unreviewed install +scripts in one go.

                    +

                    deny records an explicit denial for the named packages (a name-only false +entry), which survives npm install-scripts approve --all and excludes the +package from any future blanket approval. --all denies every package with +unreviewed install scripts.

                    +

                    ls is read-only: it lists every package whose install scripts are not yet +covered by allowScripts, without modifying package.json.

                    +

                    prune removes allowScripts entries that no longer match an installed +package with an install script, either because the package is no longer +installed (a transitive dependency changed, or a pinned pkg@1.2.3 was +upgraded) or because it no longer has an install script. Both approvals +(true) and denials (false) are removed. It edits only the allowScripts +field in package.json, never .npmrc or --allow-scripts. Pass --dry-run +to preview without writing. Unparseable keys are left alone.

                    +

                    approve honours the asymmetric pin rule: if you re-approve a package whose +installed version has changed, the existing pin is rewritten to track the new +installed version. Multi-version statements (pkg@1 || 2) are left alone, +since they likely capture intent that the command cannot infer. Existing +false entries always win; approve will not silently re-allow a package you +previously denied.

                    +

                    The standalone commands npm approve-scripts +and npm deny-scripts are aliases for +npm install-scripts approve and npm install-scripts deny.

                    +

                    Examples

                    +
                    # Approve all currently-installed install scripts after reviewing them
                    +npm install-scripts approve --all
                    +
                    +# Approve specific packages, pinned to their installed version
                    +npm install-scripts approve canvas sharp
                    +
                    +# Deny a package so it stays blocked
                    +npm install-scripts deny telemetry-pkg
                    +
                    +# Preview which packages still need review
                    +npm install-scripts ls
                    +
                    +# Preview stale allowScripts entries, then remove them
                    +npm install-scripts prune --dry-run
                    +npm install-scripts prune
                    +
                    +

                    Configuration

                    +

                    all

                    +
                      +
                    • Default: false
                    • +
                    • Type: Boolean
                    • +
                    +

                    Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

                    +

                    allow-scripts-pin

                    +
                      +
                    • Default: true
                    • +
                    • Type: Boolean
                    • +
                    +

                    Write pinned (pkg@version) entries when approving install scripts. Set to +false to write name-only entries that allow any version. Has no effect on +npm deny-scripts, which always writes name-only entries regardless of this +setting.

                    +

                    dry-run

                    +
                      +
                    • Default: false
                    • +
                    • Type: Boolean
                    • +
                    +

                    Indicates that you don't want npm to make any changes and that it should +only report what it would have done. This can be passed into any of the +commands that modify your local installation, eg, install, update, +dedupe, uninstall, as well as pack and publish.

                    +

                    Note: This is NOT honored by other network related commands, eg dist-tags, +owner, etc.

                    +

                    json

                    +
                      +
                    • Default: false
                    • +
                    • Type: Boolean
                    • +
                    +

                    Whether or not to output JSON data, rather than the normal output.

                    +
                      +
                    • In npm pkg set it enables parsing set values with JSON.parse() before +saving them to your package.json.
                    • +
                    +

                    Not supported by all npm commands.

                    +

                    See Also

                    +
                    + + +
                    + + + + \ No newline at end of file diff --git a/deps/npm/docs/output/commands/npm-install-test.html b/deps/npm/docs/output/commands/npm-install-test.html index cda0bf383f0..94231076345 100644 --- a/deps/npm/docs/output/commands/npm-install-test.html +++ b/deps/npm/docs/output/commands/npm-install-test.html @@ -186,16 +186,16 @@
                    -

                    +

                    npm-install-test - @11.16.0 + @11.18.0

                    Install package(s) and run tests

                    Table of contents

                    - +

                    Synopsis

                    @@ -246,8 +246,15 @@

                    install-strategy

                    (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

                    +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

                    +

                    We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

                    legacy-bundling

                    • Default: false
                    • @@ -439,6 +446,9 @@

                      strict-allow-scripts

                      silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

                      +

                      Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

                      dangerously-allow-all-scripts

                      • Default: false
                      • @@ -475,6 +485,10 @@

                        before

                        sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one.

                        +

                        As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

                        +

                        Packages whose names match min-release-age-exclude are exempt from this +filter.

                        min-release-age

                        • Default: null
                        • @@ -490,6 +504,34 @@

                          min-release-age

                          --before while preparing a git: or github: dependency); when both apply, before wins within a single source and across sources the standard precedence rules apply.

                          +

                          When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

                          +

                          Packages whose names match min-release-age-exclude are exempt from this +filter.

                          +

                          This value is not exported to the environment for child processes.

                          +

                          min-release-age-exclude

                          +
                            +
                          • Default:
                          • +
                          • Type: String (can be set multiple times)
                          • +
                          +

                          A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

                          +

                          For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

                          +
                          min-release-age=7
                          +min-release-age-exclude[]=@myorg/*
                          +min-release-age-exclude[]=my-internal-pkg
                          +
                          +

                          Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

                          +

                          Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

                          This value is not exported to the environment for child processes.

                            diff --git a/deps/npm/docs/output/commands/npm-install.html b/deps/npm/docs/output/commands/npm-install.html index c9ae37e3932..fd6fe12eb8c 100644 --- a/deps/npm/docs/output/commands/npm-install.html +++ b/deps/npm/docs/output/commands/npm-install.html @@ -186,16 +186,16 @@
                            -

                            +

                            npm-install - @11.16.0 + @11.18.0

                            Install a package

                            Table of contents

                            - +

                            Synopsis

                            @@ -521,8 +521,15 @@

                            install-strategy

                            (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

                            +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

                            +

                            We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

                            legacy-bundling

                            • Default: false
                            • @@ -714,6 +721,9 @@

                              strict-allow-scripts

                              silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

                              +

                              Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

                              dangerously-allow-all-scripts

                              • Default: false
                              • @@ -750,6 +760,10 @@

                                before

                                sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one.

                                +

                                As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

                                +

                                Packages whose names match min-release-age-exclude are exempt from this +filter.

                                min-release-age

                                • Default: null
                                • @@ -765,6 +779,34 @@

                                  min-release-age

                                  --before while preparing a git: or github: dependency); when both apply, before wins within a single source and across sources the standard precedence rules apply.

                                  +

                                  When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

                                  +

                                  Packages whose names match min-release-age-exclude are exempt from this +filter.

                                  +

                                  This value is not exported to the environment for child processes.

                                  +

                                  min-release-age-exclude

                                  +
                                    +
                                  • Default:
                                  • +
                                  • Type: String (can be set multiple times)
                                  • +
                                  +

                                  A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

                                  +

                                  For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

                                  +
                                  min-release-age=7
                                  +min-release-age-exclude[]=@myorg/*
                                  +min-release-age-exclude[]=my-internal-pkg
                                  +
                                  +

                                  Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

                                  +

                                  Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

                                  This value is not exported to the environment for child processes.

                                    diff --git a/deps/npm/docs/output/commands/npm-link.html b/deps/npm/docs/output/commands/npm-link.html index dcc559329df..e4c9f092f37 100644 --- a/deps/npm/docs/output/commands/npm-link.html +++ b/deps/npm/docs/output/commands/npm-link.html @@ -186,9 +186,9 @@
                                    -

                                    +

                                    npm-link - @11.16.0 + @11.18.0

                                    Symlink a package folder
                                    @@ -288,8 +288,15 @@

                                    install-strategy

                                    (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

                                    +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

                                    +

                                    We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

                                    legacy-bundling

                                    • Default: false
                                    • diff --git a/deps/npm/docs/output/commands/npm-ll.html b/deps/npm/docs/output/commands/npm-ll.html index 52f363b8b17..a7e3061ddf9 100644 --- a/deps/npm/docs/output/commands/npm-ll.html +++ b/deps/npm/docs/output/commands/npm-ll.html @@ -186,9 +186,9 @@
                                      -

                                      +

                                      npm-ll - @11.16.0 + @11.18.0

                                      List installed packages
                                      @@ -211,9 +211,10 @@

                                      all

                                    • Default: false
                                    • Type: Boolean
                                    -

                                    When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

                                    +

                                    Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

                                    json

                                    • Default: false
                                    • diff --git a/deps/npm/docs/output/commands/npm-login.html b/deps/npm/docs/output/commands/npm-login.html index eac37fc5a66..b08ac7b3357 100644 --- a/deps/npm/docs/output/commands/npm-login.html +++ b/deps/npm/docs/output/commands/npm-login.html @@ -186,9 +186,9 @@
                                      -

                                      +

                                      npm-login - @11.16.0 + @11.18.0

                                      Login to a registry user account
                                      diff --git a/deps/npm/docs/output/commands/npm-logout.html b/deps/npm/docs/output/commands/npm-logout.html index 0930332b862..dfc1b256538 100644 --- a/deps/npm/docs/output/commands/npm-logout.html +++ b/deps/npm/docs/output/commands/npm-logout.html @@ -186,9 +186,9 @@
                                      -

                                      +

                                      npm-logout - @11.16.0 + @11.18.0

                                      Log out of the registry
                                      diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index cbf7f4e8208..a3de66d0323 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -186,9 +186,9 @@
                                      -

                                      +

                                      npm-ls - @11.16.0 + @11.18.0

                                      List installed packages
                                      @@ -209,7 +209,7 @@

                                      Description

                                      Positional arguments are name@version-range identifiers, which will limit the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm's source tree will show:

                                      -
                                      npm@11.16.0 /path/to/npm
                                      +
                                      npm@11.18.0 /path/to/npm
                                       └─┬ init-package-json@0.0.4
                                         └── promzard@0.1.5
                                       
                                      @@ -223,9 +223,10 @@

                                      all

                                    • Default: false
                                    • Type: Boolean
                                    -

                                    When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

                                    +

                                    Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

                                    json

                                    • Default: false
                                    • diff --git a/deps/npm/docs/output/commands/npm-org.html b/deps/npm/docs/output/commands/npm-org.html index 99e8c472dc5..7c0526d750c 100644 --- a/deps/npm/docs/output/commands/npm-org.html +++ b/deps/npm/docs/output/commands/npm-org.html @@ -186,9 +186,9 @@
                                      -

                                      +

                                      npm-org - @11.16.0 + @11.18.0

                                      Manage orgs
                                      diff --git a/deps/npm/docs/output/commands/npm-outdated.html b/deps/npm/docs/output/commands/npm-outdated.html index cb154b4a234..5bf8ee630c2 100644 --- a/deps/npm/docs/output/commands/npm-outdated.html +++ b/deps/npm/docs/output/commands/npm-outdated.html @@ -186,16 +186,16 @@
                                      -

                                      +

                                      npm-outdated - @11.16.0 + @11.18.0

                                      Check for outdated packages

                                      Table of contents

                                      - +

                                      Synopsis

                                      @@ -208,7 +208,7 @@

                                      Description

                                      In the output:

                                      • wanted is the maximum version of the package that satisfies the semver range specified in package.json. -If there's no available semver range (i.e. you're running npm outdated --global, or the package isn't included in package.json), then wanted shows the currently-installed version.
                                      • +If there's no available semver range (i.e. you're running npm outdated --global, or the package isn't included in package.json), then wanted shows the latest version.
                                      • latest is the version of the package tagged as latest in the registry. Running npm publish with no special configuration will publish the package with a dist-tag of latest. This may or may not be the maximum version of the package, or the most-recently published version of the package, depending on how the package's developer manages the latest dist-tag.
                                      • @@ -255,9 +255,10 @@

                                        all

                                      • Default: false
                                      • Type: Boolean
                                      -

                                      When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

                                      +

                                      Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

                                      json

                                      • Default: false
                                      • @@ -333,6 +334,10 @@

                                        before

                                        sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one.

                                        +

                                        As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

                                        +

                                        Packages whose names match min-release-age-exclude are exempt from this +filter.

                                        min-release-age

                                        • Default: null
                                        • @@ -348,6 +353,34 @@

                                          min-release-age

                                          --before while preparing a git: or github: dependency); when both apply, before wins within a single source and across sources the standard precedence rules apply.

                                          +

                                          When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

                                          +

                                          Packages whose names match min-release-age-exclude are exempt from this +filter.

                                          +

                                          This value is not exported to the environment for child processes.

                                          +

                                          min-release-age-exclude

                                          +
                                            +
                                          • Default:
                                          • +
                                          • Type: String (can be set multiple times)
                                          • +
                                          +

                                          A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

                                          +

                                          For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

                                          +
                                          min-release-age=7
                                          +min-release-age-exclude[]=@myorg/*
                                          +min-release-age-exclude[]=my-internal-pkg
                                          +
                                          +

                                          Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

                                          +

                                          Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

                                          This value is not exported to the environment for child processes.

                                          See Also

                                            diff --git a/deps/npm/docs/output/commands/npm-owner.html b/deps/npm/docs/output/commands/npm-owner.html index fa568741602..c4947a01ae9 100644 --- a/deps/npm/docs/output/commands/npm-owner.html +++ b/deps/npm/docs/output/commands/npm-owner.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-owner - @11.16.0 + @11.18.0

                                            Manage package owners
                                            diff --git a/deps/npm/docs/output/commands/npm-pack.html b/deps/npm/docs/output/commands/npm-pack.html index a99ae2dba99..a875a527f81 100644 --- a/deps/npm/docs/output/commands/npm-pack.html +++ b/deps/npm/docs/output/commands/npm-pack.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-pack - @11.16.0 + @11.18.0

                                            Create a tarball from a package
                                            diff --git a/deps/npm/docs/output/commands/npm-ping.html b/deps/npm/docs/output/commands/npm-ping.html index bd867fbd3ef..74a7e2adc92 100644 --- a/deps/npm/docs/output/commands/npm-ping.html +++ b/deps/npm/docs/output/commands/npm-ping.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-ping - @11.16.0 + @11.18.0

                                            Ping npm registry
                                            diff --git a/deps/npm/docs/output/commands/npm-pkg.html b/deps/npm/docs/output/commands/npm-pkg.html index 145b47fde4e..9aec2f5f560 100644 --- a/deps/npm/docs/output/commands/npm-pkg.html +++ b/deps/npm/docs/output/commands/npm-pkg.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-pkg - @11.16.0 + @11.18.0

                                            Manages your package.json
                                            diff --git a/deps/npm/docs/output/commands/npm-prefix.html b/deps/npm/docs/output/commands/npm-prefix.html index 2bccd93bb26..887a4f26432 100644 --- a/deps/npm/docs/output/commands/npm-prefix.html +++ b/deps/npm/docs/output/commands/npm-prefix.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-prefix - @11.16.0 + @11.18.0

                                            Display prefix
                                            diff --git a/deps/npm/docs/output/commands/npm-profile.html b/deps/npm/docs/output/commands/npm-profile.html index 9e3d975aa3c..c45be8a6052 100644 --- a/deps/npm/docs/output/commands/npm-profile.html +++ b/deps/npm/docs/output/commands/npm-profile.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-profile - @11.16.0 + @11.18.0

                                            Change settings on your registry profile
                                            diff --git a/deps/npm/docs/output/commands/npm-prune.html b/deps/npm/docs/output/commands/npm-prune.html index f6a356f53cc..bfb3914265b 100644 --- a/deps/npm/docs/output/commands/npm-prune.html +++ b/deps/npm/docs/output/commands/npm-prune.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-prune - @11.16.0 + @11.18.0

                                            Remove extraneous packages
                                            diff --git a/deps/npm/docs/output/commands/npm-publish.html b/deps/npm/docs/output/commands/npm-publish.html index b9c7824c845..f2a7ba05905 100644 --- a/deps/npm/docs/output/commands/npm-publish.html +++ b/deps/npm/docs/output/commands/npm-publish.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-publish - @11.16.0 + @11.18.0

                                            Publish a package
                                            diff --git a/deps/npm/docs/output/commands/npm-query.html b/deps/npm/docs/output/commands/npm-query.html index efa6bd81f13..7d9bf80b88d 100644 --- a/deps/npm/docs/output/commands/npm-query.html +++ b/deps/npm/docs/output/commands/npm-query.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-query - @11.16.0 + @11.18.0

                                            Dependency selector query
                                            @@ -414,6 +414,72 @@

                                            expect-result-count

                                          Tells to expect a specific number of results from the command.

                                          This config cannot be used with: expect-results

                                          +

                                          before

                                          +
                                            +
                                          • Default: null
                                          • +
                                          • Type: null or Date
                                          • +
                                          +

                                          If passed to npm install, will rebuild the npm tree such that only +versions that were available on or before the given date are installed. +If there are no versions available for the current set of dependencies, the +command will error.

                                          +

                                          If the requested version is a dist-tag and the given tag does not pass the +--before filter, the most recent version less than or equal to that tag +will be used. For example, foo@latest might install foo@1.2 even though +latest is 2.0.

                                          +

                                          If before and min-release-age are both set in the same source, before +wins (an explicit absolute date overrides a relative window). Across +sources, the standard precedence applies (cli > env > project > user > +global), so a higher-priority source can always relax or override a +lower-priority one.

                                          +

                                          As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

                                          +

                                          Packages whose names match min-release-age-exclude are exempt from this +filter.

                                          +

                                          min-release-age

                                          +
                                            +
                                          • Default: null
                                          • +
                                          • Type: null or Number
                                          • +
                                          +

                                          If set, npm will build the npm tree such that only versions that were +available more than the given number of days ago will be installed. If there +are no versions available for the current set of dependencies, the command +will error.

                                          +

                                          This flag is a complement to before, which accepts an exact date instead +of a relative number of days. The two may coexist (e.g. min-release-age in +your .npmrc is preserved when npm internally spawns a sub-process with +--before while preparing a git: or github: dependency); when both +apply, before wins within a single source and across sources the standard +precedence rules apply.

                                          +

                                          When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

                                          +

                                          Packages whose names match min-release-age-exclude are exempt from this +filter.

                                          +

                                          This value is not exported to the environment for child processes.

                                          +

                                          min-release-age-exclude

                                          +
                                            +
                                          • Default:
                                          • +
                                          • Type: String (can be set multiple times)
                                          • +
                                          +

                                          A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

                                          +

                                          For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

                                          +
                                          min-release-age=7
                                          +min-release-age-exclude[]=@myorg/*
                                          +min-release-age-exclude[]=my-internal-pkg
                                          +
                                          +

                                          Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

                                          +

                                          Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

                                          +

                                          This value is not exported to the environment for child processes.

                                          See Also

                                          • dependency selectors
                                          • diff --git a/deps/npm/docs/output/commands/npm-rebuild.html b/deps/npm/docs/output/commands/npm-rebuild.html index 0aff44579c5..5245b156b68 100644 --- a/deps/npm/docs/output/commands/npm-rebuild.html +++ b/deps/npm/docs/output/commands/npm-rebuild.html @@ -186,9 +186,9 @@
                                            -

                                            +

                                            npm-rebuild - @11.16.0 + @11.18.0

                                            Rebuild a package
                                            @@ -298,6 +298,9 @@

                                            strict-allow-scripts

                                            silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

                                            +

                                            Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

                                            dangerously-allow-all-scripts

                                            • Default: false
                                            • diff --git a/deps/npm/docs/output/commands/npm-repo.html b/deps/npm/docs/output/commands/npm-repo.html index 0efe01e3239..c210a4efd30 100644 --- a/deps/npm/docs/output/commands/npm-repo.html +++ b/deps/npm/docs/output/commands/npm-repo.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-repo - @11.16.0 + @11.18.0

                                              Open package repository page in the browser
                                              diff --git a/deps/npm/docs/output/commands/npm-restart.html b/deps/npm/docs/output/commands/npm-restart.html index d58d9d362a0..cc0ee51c458 100644 --- a/deps/npm/docs/output/commands/npm-restart.html +++ b/deps/npm/docs/output/commands/npm-restart.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-restart - @11.16.0 + @11.18.0

                                              Restart a package
                                              diff --git a/deps/npm/docs/output/commands/npm-root.html b/deps/npm/docs/output/commands/npm-root.html index 8f1a7319765..6f0af858537 100644 --- a/deps/npm/docs/output/commands/npm-root.html +++ b/deps/npm/docs/output/commands/npm-root.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-root - @11.16.0 + @11.18.0

                                              Display npm root
                                              diff --git a/deps/npm/docs/output/commands/npm-run.html b/deps/npm/docs/output/commands/npm-run.html index c234db61b93..c7119fea964 100644 --- a/deps/npm/docs/output/commands/npm-run.html +++ b/deps/npm/docs/output/commands/npm-run.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-run - @11.16.0 + @11.18.0

                                              Run arbitrary package scripts
                                              diff --git a/deps/npm/docs/output/commands/npm-sbom.html b/deps/npm/docs/output/commands/npm-sbom.html index df30ae75770..70eb4780c5c 100644 --- a/deps/npm/docs/output/commands/npm-sbom.html +++ b/deps/npm/docs/output/commands/npm-sbom.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-sbom - @11.16.0 + @11.18.0

                                              Generate a Software Bill of Materials (SBOM)
                                              diff --git a/deps/npm/docs/output/commands/npm-search.html b/deps/npm/docs/output/commands/npm-search.html index 63efdaad281..b417f9ba815 100644 --- a/deps/npm/docs/output/commands/npm-search.html +++ b/deps/npm/docs/output/commands/npm-search.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-search - @11.16.0 + @11.18.0

                                              Search for packages
                                              diff --git a/deps/npm/docs/output/commands/npm-set.html b/deps/npm/docs/output/commands/npm-set.html index 988c341f8fe..dfd53bcf72f 100644 --- a/deps/npm/docs/output/commands/npm-set.html +++ b/deps/npm/docs/output/commands/npm-set.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-set - @11.16.0 + @11.18.0

                                              Set a value in the npm configuration
                                              diff --git a/deps/npm/docs/output/commands/npm-shrinkwrap.html b/deps/npm/docs/output/commands/npm-shrinkwrap.html index 46c96bdef91..8989040dd9f 100644 --- a/deps/npm/docs/output/commands/npm-shrinkwrap.html +++ b/deps/npm/docs/output/commands/npm-shrinkwrap.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-shrinkwrap - @11.16.0 + @11.18.0

                                              Lock down dependency versions for publication
                                              diff --git a/deps/npm/docs/output/commands/npm-stage.html b/deps/npm/docs/output/commands/npm-stage.html index e98b5e5aca1..de76caf167e 100644 --- a/deps/npm/docs/output/commands/npm-stage.html +++ b/deps/npm/docs/output/commands/npm-stage.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-stage - @11.16.0 + @11.18.0

                                              Stage packages for publishing
                                              @@ -391,7 +391,7 @@

                                              Flags

                                              --tag "latest" String -If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag. It is the tag added to the package@version specified in the npm dist-tag add command, if no explicit tag is given. When used by the npm diff command, this is the tag used to fetch the tarball that will be compared with the local files by default. If used in the npm publish command, this is the tag that will be added to the package submitted to the registry. +If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag. It is the tag added to the package@version specified in the npm dist-tag add command, if no explicit tag is given. When used by the npm diff command, this is the tag used to fetch the tarball that will be compared with the local files by default. If used in the npm publish command, this is the tag that will be added to the package submitted to the registry. --access diff --git a/deps/npm/docs/output/commands/npm-star.html b/deps/npm/docs/output/commands/npm-star.html index 5ecd1df01d0..0642cfefb4b 100644 --- a/deps/npm/docs/output/commands/npm-star.html +++ b/deps/npm/docs/output/commands/npm-star.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-star - @11.16.0 + @11.18.0

                                              Mark your favorite packages
                                              diff --git a/deps/npm/docs/output/commands/npm-stars.html b/deps/npm/docs/output/commands/npm-stars.html index d4e8bb1ae97..3f586b4fb0a 100644 --- a/deps/npm/docs/output/commands/npm-stars.html +++ b/deps/npm/docs/output/commands/npm-stars.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-stars - @11.16.0 + @11.18.0

                                              View packages marked as favorites
                                              diff --git a/deps/npm/docs/output/commands/npm-start.html b/deps/npm/docs/output/commands/npm-start.html index bcc5463e6dd..35a7c7798f8 100644 --- a/deps/npm/docs/output/commands/npm-start.html +++ b/deps/npm/docs/output/commands/npm-start.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-start - @11.16.0 + @11.18.0

                                              Start a package
                                              diff --git a/deps/npm/docs/output/commands/npm-stop.html b/deps/npm/docs/output/commands/npm-stop.html index abbb05aa873..37c8d91d4ba 100644 --- a/deps/npm/docs/output/commands/npm-stop.html +++ b/deps/npm/docs/output/commands/npm-stop.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-stop - @11.16.0 + @11.18.0

                                              Stop a package
                                              diff --git a/deps/npm/docs/output/commands/npm-team.html b/deps/npm/docs/output/commands/npm-team.html index a1d0941e2e5..66263e4f1f5 100644 --- a/deps/npm/docs/output/commands/npm-team.html +++ b/deps/npm/docs/output/commands/npm-team.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-team - @11.16.0 + @11.18.0

                                              Manage organization teams and team memberships
                                              diff --git a/deps/npm/docs/output/commands/npm-test.html b/deps/npm/docs/output/commands/npm-test.html index d5fb0a1ded1..b9e84c47671 100644 --- a/deps/npm/docs/output/commands/npm-test.html +++ b/deps/npm/docs/output/commands/npm-test.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-test - @11.16.0 + @11.18.0

                                              Test a package
                                              diff --git a/deps/npm/docs/output/commands/npm-token.html b/deps/npm/docs/output/commands/npm-token.html index 10163668153..c3c59a86cab 100644 --- a/deps/npm/docs/output/commands/npm-token.html +++ b/deps/npm/docs/output/commands/npm-token.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-token - @11.16.0 + @11.18.0

                                              Manage your authentication tokens
                                              diff --git a/deps/npm/docs/output/commands/npm-trust.html b/deps/npm/docs/output/commands/npm-trust.html index e269490efdf..00d389d044c 100644 --- a/deps/npm/docs/output/commands/npm-trust.html +++ b/deps/npm/docs/output/commands/npm-trust.html @@ -186,9 +186,9 @@
                                              -

                                              +

                                              npm-trust - @11.16.0 + @11.18.0

                                              Manage trusted publishing relationships between packages and CI/CD providers
                                              @@ -203,7 +203,7 @@

                                              Table of contents

                                              Prerequisites

                                              Before using npm trust commands, ensure the following requirements are met:

                                                -
                                              • npm version: npm@11.10.0 or above is required. Use npm install -g npm@^11.10.0 to update if needed.
                                              • +
                                              • npm version: npm@11.15.0 or above is required. Use npm install -g npm@^11.15.0 to update if needed.
                                              • Write permissions on the package: You must have write access to the package you're configuring.
                                              • 2FA enabled on account: Two-factor authentication must be enabled at the account level. Even if it's not currently enabled, you must enable it to use trust commands.
                                              • Supported authentication methods: Granular Access Tokens (GAT) with the bypass 2FA option are not supported. Legacy basic auth (username and password) credentials will not work for trust commands or endpoints.
                                              • diff --git a/deps/npm/docs/output/commands/npm-undeprecate.html b/deps/npm/docs/output/commands/npm-undeprecate.html index 45fcb65deed..06ca5b07fbb 100644 --- a/deps/npm/docs/output/commands/npm-undeprecate.html +++ b/deps/npm/docs/output/commands/npm-undeprecate.html @@ -186,9 +186,9 @@
                                                -

                                                +

                                                npm-undeprecate - @11.16.0 + @11.18.0

                                                Undeprecate a version of a package
                                                diff --git a/deps/npm/docs/output/commands/npm-uninstall.html b/deps/npm/docs/output/commands/npm-uninstall.html index bdeb05ee1b3..f82cbbc1dce 100644 --- a/deps/npm/docs/output/commands/npm-uninstall.html +++ b/deps/npm/docs/output/commands/npm-uninstall.html @@ -186,9 +186,9 @@
                                                -

                                                +

                                                npm-uninstall - @11.16.0 + @11.18.0

                                                Remove a package
                                                diff --git a/deps/npm/docs/output/commands/npm-unpublish.html b/deps/npm/docs/output/commands/npm-unpublish.html index eec4aee8c60..f6557a7a40a 100644 --- a/deps/npm/docs/output/commands/npm-unpublish.html +++ b/deps/npm/docs/output/commands/npm-unpublish.html @@ -186,9 +186,9 @@
                                                -

                                                +

                                                npm-unpublish - @11.16.0 + @11.18.0

                                                Remove a package from the registry
                                                diff --git a/deps/npm/docs/output/commands/npm-unstar.html b/deps/npm/docs/output/commands/npm-unstar.html index 7d3d40d2992..d91decf5f96 100644 --- a/deps/npm/docs/output/commands/npm-unstar.html +++ b/deps/npm/docs/output/commands/npm-unstar.html @@ -186,9 +186,9 @@
                                                -

                                                +

                                                npm-unstar - @11.16.0 + @11.18.0

                                                Remove an item from your favorite packages
                                                diff --git a/deps/npm/docs/output/commands/npm-update.html b/deps/npm/docs/output/commands/npm-update.html index 1558e84ce06..9b395086246 100644 --- a/deps/npm/docs/output/commands/npm-update.html +++ b/deps/npm/docs/output/commands/npm-update.html @@ -186,16 +186,16 @@
                                                -

                                                +

                                                npm-update - @11.16.0 + @11.18.0

                                                Update packages

                                                Table of contents

                                                - +

                                                Synopsis

                                                @@ -282,8 +282,7 @@

                                                Subdependencies

                                                In this case if you really did need your package to use a newer version you would need to use npm install.

                                                Updating Globally-Installed Packages

                                                npm update -g will apply the update action to each globally installed package that is outdated -- that is, has a version that is different from wanted.

                                                -

                                                Note: Globally installed packages are treated as if they are installed with a caret semver range specified. -So if you require to update to latest you may need to run npm install -g [<pkg>...]

                                                +

                                                Note: Globally installed packages do not have a package.json semver range available, so their wanted version is latest.

                                                NOTE: If a package has been upgraded to a version newer than latest, it will be downgraded.

                                                Configuration

                                                save

                                                @@ -318,8 +317,15 @@

                                                install-strategy

                                                (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

                                                +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

                                                +

                                                We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

                                                legacy-bundling

                                                • Default: false
                                                • @@ -436,6 +442,9 @@

                                                  strict-allow-scripts

                                                  silently skipped; this setting only affects unreviewed entries. --ignore-scripts and --dangerously-allow-all-scripts both override this setting.

                                                  +

                                                  Optional dependencies that cannot be installed on the current platform or +engine (a non-matching os, cpu, or libc) are not flagged, because +their install scripts never run.

                                                  dangerously-allow-all-scripts

                                                  • Default: false
                                                  • @@ -472,6 +481,10 @@

                                                    before

                                                    sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one.

                                                    +

                                                    As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

                                                    +

                                                    Packages whose names match min-release-age-exclude are exempt from this +filter.

                                                    min-release-age

                                                    • Default: null
                                                    • @@ -487,6 +500,34 @@

                                                      min-release-age

                                                      --before while preparing a git: or github: dependency); when both apply, before wins within a single source and across sources the standard precedence rules apply.

                                                      +

                                                      When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

                                                      +

                                                      Packages whose names match min-release-age-exclude are exempt from this +filter.

                                                      +

                                                      This value is not exported to the environment for child processes.

                                                      +

                                                      min-release-age-exclude

                                                      +
                                                        +
                                                      • Default:
                                                      • +
                                                      • Type: String (can be set multiple times)
                                                      • +
                                                      +

                                                      A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

                                                      +

                                                      For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

                                                      +
                                                      min-release-age=7
                                                      +min-release-age-exclude[]=@myorg/*
                                                      +min-release-age-exclude[]=my-internal-pkg
                                                      +
                                                      +

                                                      Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

                                                      +

                                                      Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

                                                      This value is not exported to the environment for child processes.

                                                        diff --git a/deps/npm/docs/output/commands/npm-version.html b/deps/npm/docs/output/commands/npm-version.html index 4deac0758f8..17e504dd49e 100644 --- a/deps/npm/docs/output/commands/npm-version.html +++ b/deps/npm/docs/output/commands/npm-version.html @@ -186,9 +186,9 @@
                                                        -

                                                        +

                                                        npm-version - @11.16.0 + @11.18.0

                                                        Bump a package version
                                                        diff --git a/deps/npm/docs/output/commands/npm-view.html b/deps/npm/docs/output/commands/npm-view.html index 71fac734e58..6424eed09df 100644 --- a/deps/npm/docs/output/commands/npm-view.html +++ b/deps/npm/docs/output/commands/npm-view.html @@ -186,9 +186,9 @@
                                                        -

                                                        +

                                                        npm-view - @11.16.0 + @11.18.0

                                                        View registry info
                                                        diff --git a/deps/npm/docs/output/commands/npm-whoami.html b/deps/npm/docs/output/commands/npm-whoami.html index f92bd67d1f5..9830a8c3c8d 100644 --- a/deps/npm/docs/output/commands/npm-whoami.html +++ b/deps/npm/docs/output/commands/npm-whoami.html @@ -186,9 +186,9 @@
                                                        -

                                                        +

                                                        npm-whoami - @11.16.0 + @11.18.0

                                                        Display npm username
                                                        diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index 52befd07604..cef7c6a5f2c 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -186,9 +186,9 @@
                                                        -

                                                        +

                                                        npm - @11.16.0 + @11.18.0

                                                        javascript package manager
                                                        @@ -203,7 +203,7 @@

                                                        Table of contents

    Note: This command is unaware of workspaces.

    Version

    -

    11.16.0

    +

    11.18.0

    Description

    npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently.

    diff --git a/deps/npm/docs/output/commands/npx.html b/deps/npm/docs/output/commands/npx.html index 5786f4332f3..f06143a5c2c 100644 --- a/deps/npm/docs/output/commands/npx.html +++ b/deps/npm/docs/output/commands/npx.html @@ -186,9 +186,9 @@
    -

    +

    npx - @11.16.0 + @11.18.0

    Run a command from a local or remote npm package
    diff --git a/deps/npm/docs/output/configuring-npm/folders.html b/deps/npm/docs/output/configuring-npm/folders.html index c88270a3799..78f9f0f1ebd 100644 --- a/deps/npm/docs/output/configuring-npm/folders.html +++ b/deps/npm/docs/output/configuring-npm/folders.html @@ -186,9 +186,9 @@
    -

    +

    Folders - @11.16.0 + @11.18.0

    Folder structures used by npm
    diff --git a/deps/npm/docs/output/configuring-npm/install.html b/deps/npm/docs/output/configuring-npm/install.html index cb308af4d96..9ae64ab1d40 100644 --- a/deps/npm/docs/output/configuring-npm/install.html +++ b/deps/npm/docs/output/configuring-npm/install.html @@ -186,9 +186,9 @@
    -

    +

    Install - @11.16.0 + @11.18.0

    Download and install node and npm
    diff --git a/deps/npm/docs/output/configuring-npm/npm-global.html b/deps/npm/docs/output/configuring-npm/npm-global.html index c88270a3799..78f9f0f1ebd 100644 --- a/deps/npm/docs/output/configuring-npm/npm-global.html +++ b/deps/npm/docs/output/configuring-npm/npm-global.html @@ -186,9 +186,9 @@
    -

    +

    Folders - @11.16.0 + @11.18.0

    Folder structures used by npm
    diff --git a/deps/npm/docs/output/configuring-npm/npm-json.html b/deps/npm/docs/output/configuring-npm/npm-json.html index 057c1190422..cb9a3626a0c 100644 --- a/deps/npm/docs/output/configuring-npm/npm-json.html +++ b/deps/npm/docs/output/configuring-npm/npm-json.html @@ -186,9 +186,9 @@
    -

    +

    package.json - @11.16.0 + @11.18.0

    Specifics of npm's package.json handling
    @@ -838,6 +838,17 @@

    overrides

    } }
    +

    Override values can use any specifier that npm accepts for dependencies, including +an exact version, a semver range, a dist-tag, or a replacement specifier such as +npm:, file:, or a Git URL.

    +

    For example, if you only need to enforce a minimum patched release instead of one +exact version, you can use a semver range:

    +
    {
    +  "overrides": {
    +    "@npm/foo": "^1.0.0"
    +  }
    +}
    +

    The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. This will cause @npm/foo to always be 1.0.0 while also making @npm/bar at any depth beyond @npm/foo also 1.0.0:

    {
    diff --git a/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html b/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html
    index 2c585ff171c..ecbc9d9e150 100644
    --- a/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html
    +++ b/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html
    @@ -186,9 +186,9 @@
     
     
    -

    +

    npm-shrinkwrap.json - @11.16.0 + @11.18.0

    A publishable lockfile
    diff --git a/deps/npm/docs/output/configuring-npm/npmrc.html b/deps/npm/docs/output/configuring-npm/npmrc.html index c90a8b19c6b..bad73af8064 100644 --- a/deps/npm/docs/output/configuring-npm/npmrc.html +++ b/deps/npm/docs/output/configuring-npm/npmrc.html @@ -186,9 +186,9 @@
    -

    +

    .npmrc - @11.16.0 + @11.18.0

    The npm config files
    diff --git a/deps/npm/docs/output/configuring-npm/package-json.html b/deps/npm/docs/output/configuring-npm/package-json.html index 057c1190422..cb9a3626a0c 100644 --- a/deps/npm/docs/output/configuring-npm/package-json.html +++ b/deps/npm/docs/output/configuring-npm/package-json.html @@ -186,9 +186,9 @@
    -

    +

    package.json - @11.16.0 + @11.18.0

    Specifics of npm's package.json handling
    @@ -838,6 +838,17 @@

    overrides

    } }
    +

    Override values can use any specifier that npm accepts for dependencies, including +an exact version, a semver range, a dist-tag, or a replacement specifier such as +npm:, file:, or a Git URL.

    +

    For example, if you only need to enforce a minimum patched release instead of one +exact version, you can use a semver range:

    +
    {
    +  "overrides": {
    +    "@npm/foo": "^1.0.0"
    +  }
    +}
    +

    The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. This will cause @npm/foo to always be 1.0.0 while also making @npm/bar at any depth beyond @npm/foo also 1.0.0:

    {
    diff --git a/deps/npm/docs/output/configuring-npm/package-lock-json.html b/deps/npm/docs/output/configuring-npm/package-lock-json.html
    index 64a2dbb1360..834e14f6263 100644
    --- a/deps/npm/docs/output/configuring-npm/package-lock-json.html
    +++ b/deps/npm/docs/output/configuring-npm/package-lock-json.html
    @@ -186,9 +186,9 @@
     
     
    -

    +

    package-lock.json - @11.16.0 + @11.18.0

    A manifestation of the manifest
    diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html index 687d077639e..f52caeefd18 100644 --- a/deps/npm/docs/output/using-npm/config.html +++ b/deps/npm/docs/output/using-npm/config.html @@ -186,16 +186,16 @@
    -

    +

    Config - @11.16.0 + @11.18.0

    About npm configuration

    Table of contents

    -
    +

    Description

    @@ -321,9 +321,10 @@

    all

  • Default: false
  • Type: Boolean
  • -

    When running npm outdated and npm ls, setting --all will show all -outdated or installed packages, rather than only those directly depended -upon by the current project.

    +

    Show or act on all packages, not just the ones your project directly depends +on. For npm outdated and npm ls this lists every outdated or installed +package. For npm approve-scripts and npm deny-scripts it selects every +package with pending install scripts.

    allow-directory

    • Default: "all"
    • @@ -463,6 +464,10 @@

      before

      sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one.

      +

      As with min-release-age, when this cutoff blocks a fix that npm audit fix would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code.

      +

      Packages whose names match min-release-age-exclude are exempt from this +filter.

      • Default: true
      • @@ -945,8 +950,15 @@

        install-strategy

        (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted.

        +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted.

        +

        We recommend that package authors use --install-strategy=linked during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +import of a package that was never added to package.json can fail +instead of resolving by accident and shipping broken. See Catching +undeclared ("phantom") +dependencies.

        json

        • Default: false
        • @@ -1086,6 +1098,34 @@

          min-release-age

          --before while preparing a git: or github: dependency); when both apply, before wins within a single source and across sources the standard precedence rules apply.

          +

          When this window stops npm audit fix from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +min-release-age-exclude, or relax min-release-age or before.

          +

          Packages whose names match min-release-age-exclude are exempt from this +filter.

          +

          This value is not exported to the environment for child processes.

          +

          min-release-age-exclude

          +
            +
          • Default:
          • +
          • Type: String (can be set multiple times)
          • +
          +

          A list of package names or minimatch glob patterns that are exempt from +the min-release-age (and before) filter. A matching package can always +resolve to its newest version, even when a release-age window is set.

          +

          For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately:

          +
          min-release-age=7
          +min-release-age-exclude[]=@myorg/*
          +min-release-age-exclude[]=my-internal-pkg
          +
          +

          Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so @myorg/* matches @myorg/shared-utils.

          +

          Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name.

          This value is not exported to the environment for child processes.

          name

    to install it locally into the node_modules folder in that other place.

    Then go into the node-repl, and try using require("my-thing") to bring in your module's main module.

    +

    Catching undeclared ("phantom") dependencies

    +

    Under the default hoisted node_modules layout, your package can import a dependency it never declared and still resolve it. +A transitive dependency hoisted alongside it, or your workspace root's node_modules, happens to satisfy the import. +That undeclared ("phantom") dependency passes your own build silently, then fails for anyone who installs your package on its own.

    +

    We recommend developing your package under install-strategy=linked. +The isolated layout only exposes a package's declared dependencies, so an import of an undeclared package fails for you during development instead of resolving by accident, shipping broken, and failing for your users:

    +
    npm install --install-strategy=linked
    +npm test
    +
    +
    +

    Note: This doesn't catch every case. +A dependency that's still satisfied at your build by a devDependency or by your workspace root's node_modules can resolve fine for you and still be missing for whoever installs your package. +So treat it as one check, not a guarantee, alongside auditing the dependencies your published package actually uses.

    +

    Create a User Account

    Create a user with the adduser command. It works like this:

    diff --git a/deps/npm/docs/output/using-npm/logging.html b/deps/npm/docs/output/using-npm/logging.html index 675c116ed70..19c47d4adc3 100644 --- a/deps/npm/docs/output/using-npm/logging.html +++ b/deps/npm/docs/output/using-npm/logging.html @@ -186,9 +186,9 @@
    -

    +

    Logging - @11.16.0 + @11.18.0

    Why, What & How we Log
    diff --git a/deps/npm/docs/output/using-npm/orgs.html b/deps/npm/docs/output/using-npm/orgs.html index 4da8761b61f..3444f3bf1c4 100644 --- a/deps/npm/docs/output/using-npm/orgs.html +++ b/deps/npm/docs/output/using-npm/orgs.html @@ -186,9 +186,9 @@
    -

    +

    Organizations - @11.16.0 + @11.18.0

    Working with teams & organizations
    diff --git a/deps/npm/docs/output/using-npm/package-spec.html b/deps/npm/docs/output/using-npm/package-spec.html index b682f188968..92cd9d2af61 100644 --- a/deps/npm/docs/output/using-npm/package-spec.html +++ b/deps/npm/docs/output/using-npm/package-spec.html @@ -186,9 +186,9 @@
    -

    +

    Package spec - @11.16.0 + @11.18.0

    Package name specifier
    diff --git a/deps/npm/docs/output/using-npm/registry.html b/deps/npm/docs/output/using-npm/registry.html index e6efaed669f..ed47e3a6ed7 100644 --- a/deps/npm/docs/output/using-npm/registry.html +++ b/deps/npm/docs/output/using-npm/registry.html @@ -186,9 +186,9 @@
    -

    +

    Registry - @11.16.0 + @11.18.0

    The JavaScript Package Registry
    diff --git a/deps/npm/docs/output/using-npm/removal.html b/deps/npm/docs/output/using-npm/removal.html index 0d58d278fa6..57f02ed1ee2 100644 --- a/deps/npm/docs/output/using-npm/removal.html +++ b/deps/npm/docs/output/using-npm/removal.html @@ -186,9 +186,9 @@
    -

    +

    Removal - @11.16.0 + @11.18.0

    Cleaning the slate
    diff --git a/deps/npm/docs/output/using-npm/scope.html b/deps/npm/docs/output/using-npm/scope.html index 4004c513323..11861347920 100644 --- a/deps/npm/docs/output/using-npm/scope.html +++ b/deps/npm/docs/output/using-npm/scope.html @@ -186,9 +186,9 @@
    -

    +

    Scope - @11.16.0 + @11.18.0

    Scoped packages
    diff --git a/deps/npm/docs/output/using-npm/scripts.html b/deps/npm/docs/output/using-npm/scripts.html index 15ca8072c34..65ff19a4673 100644 --- a/deps/npm/docs/output/using-npm/scripts.html +++ b/deps/npm/docs/output/using-npm/scripts.html @@ -186,9 +186,9 @@
    -

    +

    Scripts - @11.16.0 + @11.18.0

    How npm handles the "scripts" field
    diff --git a/deps/npm/docs/output/using-npm/workspaces.html b/deps/npm/docs/output/using-npm/workspaces.html index a544b68ce46..fd75a0ad62a 100644 --- a/deps/npm/docs/output/using-npm/workspaces.html +++ b/deps/npm/docs/output/using-npm/workspaces.html @@ -186,9 +186,9 @@
    -

    +

    Workspaces - @11.16.0 + @11.18.0

    Working with workspaces
    diff --git a/deps/npm/lib/base-cmd.js b/deps/npm/lib/base-cmd.js index 089ec680c74..85b1f5ac8f3 100644 --- a/deps/npm/lib/base-cmd.js +++ b/deps/npm/lib/base-cmd.js @@ -129,7 +129,8 @@ class BaseCommand { } fullUsage.push('') - fullUsage.push(`Run "npm help ${name}" for more info`) + const helpName = parentName ? parentName.split(' ')[0] : name + fullUsage.push(`Run "npm help ${helpName}" for more info`) return fullUsage.join('\n') } @@ -137,6 +138,7 @@ class BaseCommand { constructor (npm) { this.npm = npm this.commandArgs = null + this.parentName = null const { config } = this @@ -167,7 +169,7 @@ class BaseCommand { } get usage () { - return this.constructor.describeUsage + return this.constructor.getUsage(this.parentName) } usageError (prefix = '') { diff --git a/deps/npm/lib/commands/audit.js b/deps/npm/lib/commands/audit.js index 39e3a599fc3..6a55af43135 100644 --- a/deps/npm/lib/commands/audit.js +++ b/deps/npm/lib/commands/audit.js @@ -3,6 +3,7 @@ const ArboristWorkspaceCmd = require('../arborist-cmd.js') const auditError = require('../utils/audit-error.js') const { log, output } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') +const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') const VerifySignatures = require('../utils/verify-signatures.js') class Audit extends ArboristWorkspaceCmd { @@ -58,18 +59,33 @@ class Audit extends ArboristWorkspaceCmd { } const reporter = this.npm.config.get('json') ? 'json' : 'detail' const Arborist = require('@npmcli/arborist') + const { policy: allowScriptsPolicy } = await resolveAllowScripts(this.npm) const opts = { ...this.npm.flatOptions, audit: true, path: this.npm.prefix, reporter, workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, } const arb = new Arborist(opts) await arb.audit({ fix }) if (fix) { await reifyFinish(this.npm, arb) + // Report any fix that a `min-release-age`/`before` window blocked from + // installing, and exit non-zero so a blocked fix is not missed. + const report = arb.auditReport + const blocked = report instanceof Map + ? [...report.values()].filter(v => v.fixBlockedByReleaseAge).map(v => v.name) + : [] + if (blocked.length) { + log.warn('audit', `${blocked.length} package(s) left at a vulnerable version because ` + + `a fix is newer than the release-age cutoff: ${blocked.join(', ')}.\n` + + 'Add the package to min-release-age-exclude, or relax min-release-age or before, ' + + 'to install the fix.') + process.exitCode = 1 + } } else { // will throw if there's an error, because this is an audit command auditError(this.npm, arb.auditReport) diff --git a/deps/npm/lib/commands/dedupe.js b/deps/npm/lib/commands/dedupe.js index 347031b60a7..e703e9fb374 100644 --- a/deps/npm/lib/commands/dedupe.js +++ b/deps/npm/lib/commands/dedupe.js @@ -1,4 +1,5 @@ const reifyFinish = require('../utils/reify-finish.js') +const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') // dedupe duplicated packages, or find them in the tree @@ -35,6 +36,7 @@ class Dedupe extends ArboristWorkspaceCmd { const dryRun = this.npm.config.get('dry-run') const where = this.npm.prefix const Arborist = require('@npmcli/arborist') + const { policy: allowScriptsPolicy } = await resolveAllowScripts(this.npm) const opts = { ...this.npm.flatOptions, path: where, @@ -44,6 +46,7 @@ class Dedupe extends ArboristWorkspaceCmd { // In order to reduce potential confusion we set this to false. save: false, workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, } const arb = new Arborist(opts) await arb.dedupe(opts) diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js index 23c47a0cc1a..7b7d8ad30fc 100644 --- a/deps/npm/lib/commands/exec.js +++ b/deps/npm/lib/commands/exec.js @@ -42,7 +42,7 @@ class Exec extends BaseCommand { } } - async callExec (args, { name, locationMsg, runPath } = {}) { + async callExec (args, { locationMsg, runPath } = {}) { let localBin = this.npm.localBin let pkgPath = this.npm.localPrefix @@ -50,8 +50,8 @@ class Exec extends BaseCommand { if (!runPath) { runPath = process.cwd() } else { - // We have to consider if the workspace has its own separate versions libnpmexec will walk up to localDir after looking here - localBin = resolve(this.npm.localDir, name, 'node_modules', '.bin') + // Use the workspace's own node_modules/.bin, not localDir/, since the linked strategy does not symlink workspaces into the root node_modules. + localBin = resolve(runPath, 'node_modules', '.bin') // We also need to look for `bin` entries in the workspace package.json // libnpmexec will NOT look in the project root for the bin entry pkgPath = runPath diff --git a/deps/npm/lib/commands/install-scripts.js b/deps/npm/lib/commands/install-scripts.js new file mode 100644 index 00000000000..c6f91f87b08 --- /dev/null +++ b/deps/npm/lib/commands/install-scripts.js @@ -0,0 +1,53 @@ +const AllowScriptsCmd = require('../utils/allow-scripts-cmd.js') + +// Namespaced front-end for install-script approvals. +// `approve`/`deny` write the `allowScripts` policy, `ls` lists unreviewed packages, +// `prune` drops entries that no longer match an installed package with an install script. +// `npm approve-scripts` / `npm deny-scripts` are aliases for `approve` / `deny`. +class InstallScripts extends AllowScriptsCmd { + static description = 'Manage install-script approvals for dependencies' + static name = 'install-scripts' + static usage = [ + 'approve [ ...]', + 'approve --all', + 'deny [ ...]', + 'deny --all', + 'ls', + 'prune', + ] + + static params = ['all', 'allow-scripts-pin', 'dry-run', 'json'] + + static async completion (opts) { + const argv = opts.conf.argv.remain + const subcommands = ['approve', 'deny', 'ls', 'prune'] + if (argv.length === 2) { + return subcommands + } + if (subcommands.includes(argv[2])) { + return [] + } + throw new Error(`${argv[2]} not recognized`) + } + + async exec (args) { + const [sub, ...rest] = args + switch (sub) { + case 'approve': + return this.runMode('approve', rest) + case 'deny': + return this.runMode('deny', rest) + case 'ls': + case 'list': + return this.runMode('list', rest) + case 'prune': + return this.runMode('prune', rest) + default: + throw this.usageError( + sub ? `\`${sub}\` is not a recognized subcommand.` : undefined + ) + } + } +} + +module.exports = InstallScripts diff --git a/deps/npm/lib/commands/install.js b/deps/npm/lib/commands/install.js index 0bc3591d4af..11bdb1b76c2 100644 --- a/deps/npm/lib/commands/install.js +++ b/deps/npm/lib/commands/install.js @@ -39,6 +39,7 @@ class Install extends ArboristWorkspaceCmd { 'audit', 'before', 'min-release-age', + 'min-release-age-exclude', 'bin-links', 'fund', 'dry-run', diff --git a/deps/npm/lib/commands/link.js b/deps/npm/lib/commands/link.js index ca656ad18f5..cad499b2df8 100644 --- a/deps/npm/lib/commands/link.js +++ b/deps/npm/lib/commands/link.js @@ -4,6 +4,8 @@ const npa = require('npm-package-arg') const pkgJson = require('@npmcli/package-json') const semver = require('semver') const reifyFinish = require('../utils/reify-finish.js') +const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') +const strictAllowScriptsPreflight = require('../utils/strict-allow-scripts-preflight.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Link extends ArboristWorkspaceCmd { @@ -67,12 +69,16 @@ class Link extends ArboristWorkspaceCmd { // load current packages from the global space, and then add symlinks installs locally const globalTop = resolve(this.npm.globalDir, '..') const Arborist = require('@npmcli/arborist') + // Resolve the policy up front so it also gates the global install of + // missing packages, not just the local link. + const { policy: allowScriptsPolicy } = await resolveAllowScripts(this.npm) const globalOpts = { ...this.npm.flatOptions, Arborist, path: globalTop, global: true, prune: false, + allowScripts: allowScriptsPolicy, } const globalArb = new Arborist(globalOpts) @@ -85,10 +91,17 @@ class Link extends ArboristWorkspaceCmd { // any extra arg that is missing from the current global space should be reified there first const missing = this.missingArgsFromTree(globals, args) if (missing.length) { - await globalArb.reify({ + const globalReifyOpts = { ...globalOpts, add: missing, + } + // Gate the global install with the same preflight as `npm install`. + await strictAllowScriptsPreflight({ + arb: globalArb, + npm: this.npm, + idealTreeOpts: globalReifyOpts, }) + await globalArb.reify(globalReifyOpts) } // get a list of module names that should be linked in the local prefix @@ -120,6 +133,9 @@ class Link extends ArboristWorkspaceCmd { prune: false, path: this.npm.prefix, save, + // Arborist reads this.options.workspaces (set at construction) to decide which node receives the add, so it must be set here, not only at reify time. + workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, }) await localArb.reify({ ...this.npm.flatOptions, @@ -128,6 +144,7 @@ class Link extends ArboristWorkspaceCmd { add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`), save, workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, }) await reifyFinish(this.npm, localArb) diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js index 5dacd391988..8b9b4f3f5d2 100644 --- a/deps/npm/lib/commands/ls.js +++ b/deps/npm/lib/commands/ls.js @@ -135,7 +135,7 @@ class LS extends ArboristWorkspaceCmd { omit, }) : () => true) .filter(installStrategy === 'linked' - ? filterLinkedStrategyEdges({ node, currentDepth }) + ? filterLinkedStrategyEdges({ currentDepth }) : () => true) .map(mapEdgesToNodes({ seenPaths })) .concat(appendExtraneousChildren({ node, seenPaths })) @@ -400,32 +400,16 @@ const getJsonOutputItem = (node, { global, long }) => { return augmentItemWithIncludeMetadata(node, item) } -// In linked strategy, two types of edges produce false UNMET DEPENDENCYs: -// 1. Workspace edges for undeclared workspaces: the lockfile records edges from root to ALL workspaces, but only declared workspaces are hoisted to root/node_modules in linked mode. Undeclared ones are intentionally absent. -// 2. Dev edges on non-root packages: store package link targets have no parent in the node tree, so they are treated as "top" nodes and their devDependencies are loaded as edges. Those devDeps are never installed. -const filterLinkedStrategyEdges = ({ node, currentDepth }) => { - const declaredDeps = new Set(Object.keys(Object.assign({}, - node.target.package.dependencies, - node.target.package.devDependencies, - node.target.package.optionalDependencies, - node.target.package.peerDependencies - ))) - - return (edge) => { - // Skip workspace edges for undeclared workspaces at root level - if (currentDepth === 0 && edge.type === 'workspace' && edge.missing) { - if (!declaredDeps.has(edge.name)) { - return false - } - } - - // Skip dev edges for non-root packages (store packages) - if (currentDepth > 0 && edge.dev) { - return false - } - - return true +// In linked strategy, dev edges on non-root packages produce false UNMET DEPENDENCYs: store package link targets have no parent in the node tree, so they are treated as "top" nodes and their devDependencies are loaded as edges. Those devDeps are never installed. +// Undeclared workspaces no longer need filtering here: loadActual synthesizes their root links so their edges resolve instead of reporting missing. +const filterLinkedStrategyEdges = ({ currentDepth }) => (edge) => { + // Skip dev edges for non-root packages (store packages) + /* istanbul ignore next: store packages no longer carry dev edges, so this guard is not exercised by tests */ + if (currentDepth > 0 && edge.dev) { + return false } + + return true } const filterByEdgesTypes = ({ link, omit }) => (edge) => { diff --git a/deps/npm/lib/commands/outdated.js b/deps/npm/lib/commands/outdated.js index 882ad2cc9d2..714b3ab64da 100644 --- a/deps/npm/lib/commands/outdated.js +++ b/deps/npm/lib/commands/outdated.js @@ -4,6 +4,7 @@ const pacote = require('pacote') const table = require('text-table') const npa = require('npm-package-arg') const pickManifest = require('npm-pick-manifest') +const { isReleaseAgeExcluded } = require('@npmcli/arborist/lib/release-age-exclude.js') const { output } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const ArboristWorkspaceCmd = require('../arborist-cmd.js') @@ -32,6 +33,7 @@ class Outdated extends ArboristWorkspaceCmd { 'workspace', 'before', 'min-release-age', + 'min-release-age-exclude', ] #tree @@ -183,8 +185,14 @@ class Outdated extends ArboristWorkspaceCmd { try { const packument = await this.#getPackument(spec) const expected = alias ? alias.fetchSpec : edge.spec - const wanted = pickManifest(packument, expected, this.npm.flatOptions) - const latest = pickManifest(packument, '*', this.npm.flatOptions) + const { minReleaseAgeExclude } = this.npm.flatOptions + // Packages matching `min-release-age-exclude` resolve to their newest + // version, so drop the `before` constraint for them. + const pickOpts = isReleaseAgeExcluded(packument.name, minReleaseAgeExclude) + ? { ...this.npm.flatOptions, before: null } + : this.npm.flatOptions + const wanted = pickManifest(packument, expected, pickOpts) + const latest = pickManifest(packument, '*', pickOpts) if (!current || current !== wanted.version || wanted.version !== latest.version) { this.#list.push({ name: alias ? edge.spec.replace('npm', edge.name) : edge.name, diff --git a/deps/npm/lib/commands/prune.js b/deps/npm/lib/commands/prune.js index d91b0030524..bc88a4e20de 100644 --- a/deps/npm/lib/commands/prune.js +++ b/deps/npm/lib/commands/prune.js @@ -1,4 +1,5 @@ const reifyFinish = require('../utils/reify-finish.js') +const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Prune extends ArboristWorkspaceCmd { @@ -19,10 +20,12 @@ class Prune extends ArboristWorkspaceCmd { async exec () { const where = this.npm.prefix const Arborist = require('@npmcli/arborist') + const { policy: allowScriptsPolicy } = await resolveAllowScripts(this.npm) const opts = { ...this.npm.flatOptions, path: where, workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, } const arb = new Arborist(opts) await arb.prune(opts) diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js index 450c51858ba..aea01cc10e7 100644 --- a/deps/npm/lib/commands/publish.js +++ b/deps/npm/lib/commands/publish.js @@ -83,6 +83,7 @@ class Publish extends BaseCommand { const json = this.npm.config.get('json') const defaultTag = this.npm.config.get('tag') const ignoreScripts = this.npm.config.get('ignore-scripts') + const scriptShell = this.npm.config.get('script-shell') || undefined const { silent } = this.npm if (semver.validRange(defaultTag)) { @@ -102,6 +103,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) } @@ -218,6 +220,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) await runScript({ @@ -225,6 +228,7 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, + scriptShell, }) } diff --git a/deps/npm/lib/commands/query.js b/deps/npm/lib/commands/query.js index 5e70e25f32e..f826cdc5265 100644 --- a/deps/npm/lib/commands/query.js +++ b/deps/npm/lib/commands/query.js @@ -2,6 +2,15 @@ const { resolve } = require('node:path') const BaseCommand = require('../base-cmd.js') const { log, output } = require('proc-log') +// Ranks competing representations of the same physical package so the most logical one is reported. +// A top-level placement (e.g. node_modules/) beats the canonical store node, which beats an internal store symlink. +const locationRank = (node) => { + if (!node.location.includes('node_modules/.store/')) { + return 2 + } + return node.isLink ? 0 : 1 +} + class QuerySelectorItem { constructor (node) { // all enumerable properties from the target @@ -9,8 +18,11 @@ class QuerySelectorItem { // append extra info this.pkgid = node.target.pkgid - this.location = node.target.location - this.path = node.target.path + // For a dep symlinked into the isolated store, report the logical link location (node_modules/) rather than the .store backing path. + // Workspaces and regular nodes keep the target location (e.g. packages/). + const logical = node.target.isInStore ? node : node.target + this.location = logical.location + this.path = logical.path this.realpath = node.target.realpath this.resolved = node.target.resolved this.from = [] @@ -33,7 +45,7 @@ class QuerySelectorItem { class Query extends BaseCommand { #response = [] // response is the query response - #seen = new Set() // paths we've seen so we can keep response deduped + #seen = new Map() // physical location -> index in #response, to keep response deduped static description = 'Retrieve a filtered list of packages' static name = 'query' @@ -49,6 +61,9 @@ class Query extends BaseCommand { 'include-workspace-root', 'package-lock-only', 'expect-results', + 'before', + 'min-release-age', + 'min-release-age-exclude', ] constructor (...args) { @@ -124,12 +139,22 @@ class Query extends BaseCommand { async #queryTree (tree, arg) { const items = await tree.querySelectorAll(arg, this.npm.flatOptions) for (const node of items) { + // Dedup by the target's physical location so multiple logical links to the same store node collapse to one result. const { location } = node.target - if (!location || !this.#seen.has(location)) { - const item = new QuerySelectorItem(node) - this.#response.push(item) - if (location) { - this.#seen.add(item.location) + if (!location) { + this.#response.push(new QuerySelectorItem(node)) + continue + } + const seen = this.#seen.get(location) + if (seen === undefined) { + this.#seen.set(location, { index: this.#response.length, rank: locationRank(node) }) + this.#response.push(new QuerySelectorItem(node)) + } else { + // Replace the stored representation only with a more logical one for the same physical package. + const rank = locationRank(node) + if (rank > seen.rank) { + this.#response[seen.index] = new QuerySelectorItem(node) + seen.rank = rank } } } diff --git a/deps/npm/lib/commands/rebuild.js b/deps/npm/lib/commands/rebuild.js index 333a879026c..17595aa4eb7 100644 --- a/deps/npm/lib/commands/rebuild.js +++ b/deps/npm/lib/commands/rebuild.js @@ -2,10 +2,12 @@ const { resolve } = require('node:path') const { log, output } = require('proc-log') const npa = require('npm-package-arg') const semver = require('semver') +const { trustedDisplay } = require('@npmcli/arborist/lib/script-allowed.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') const checkAllowScripts = require('../utils/check-allow-scripts.js') const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') const strictAllowScriptsPreflight = require('../utils/strict-allow-scripts-preflight.js') +const { configSetAllowScripts } = require('../utils/allow-scripts-remediation.js') class Rebuild extends ArboristWorkspaceCmd { static description = 'Rebuild a package' @@ -56,7 +58,7 @@ class Rebuild extends ArboristWorkspaceCmd { return spec }) - const nodes = tree.inventory.filter(node => this.isNode(specs, node)) + const nodes = [...tree.inventory.filter(node => this.isNode(specs, node))] await strictAllowScriptsPreflight({ arb, npm: this.npm }) await arb.rebuild({ nodes }) @@ -73,10 +75,17 @@ class Rebuild extends ArboristWorkspaceCmd { if (unreviewed.length > 0) { const count = unreviewed.length const noun = count === 1 ? 'package has' : 'packages have' + // `npm install-scripts` writes to a project package.json, which doesn't + // exist for global rebuilds. Point global users at `npm config set`, + // which writes the `allow-scripts` setting to their user .npmrc. + const names = unreviewed.map(({ node }) => trustedDisplay(node).name) + const remediation = this.npm.global + ? `Run \`${configSetAllowScripts(names)}\` to allow their scripts.` + : 'Run `npm install-scripts ls` to review.' log.warn( 'rebuild', `${count} ${noun} install scripts not yet covered by allowScripts. ` + - 'Run `npm approve-scripts --allow-scripts-pending` to review.' + remediation ) } @@ -84,6 +93,13 @@ class Rebuild extends ArboristWorkspaceCmd { } isNode (specs, node) { + // Bundled dependencies are never selected by name. Their identity comes + // from the bundling parent's tarball (a bundled folder can call itself + // anything), so `npm rebuild bcrypt` must never target a bundled + // `node_modules/bcrypt`. Their install scripts never run regardless. + if (node.inBundle) { + return false + } return specs.some(spec => { if (spec.type === 'directory') { return node.path === spec.fetchSpec diff --git a/deps/npm/lib/commands/token.js b/deps/npm/lib/commands/token.js index b248d6a789a..8f54e9d8725 100644 --- a/deps/npm/lib/commands/token.js +++ b/deps/npm/lib/commands/token.js @@ -73,17 +73,22 @@ class Token extends BaseCommand { const parseable = this.npm.config.get('parseable') log.info('token', 'getting list') const tokens = await paginate('/-/npm/v1/tokens', this.npm.flatOptions) + + this.generateTokenIds(tokens, 6) + if (json) { output.buffer(tokens) return } if (parseable) { - output.standard(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) + output.standard(['key', 'token', 'id', 'name', 'created', 'readonly', 'CIDR whitelist'].join('\t')) tokens.forEach(token => { output.standard( [ token.key, token.token, + token.id, + token.name, token.created, token.readonly ? 'true' : 'false', token.cidr_whitelist ? token.cidr_whitelist.join(',') : '', @@ -92,11 +97,10 @@ class Token extends BaseCommand { }) return } - this.generateTokenIds(tokens, 6) const chalk = this.npm.chalk for (const token of tokens) { const created = String(token.created).slice(0, 10) - output.standard(`${chalk.blue('Token')} ${token.token}… with id ${chalk.cyan(token.id)} created ${created}`) + output.standard(`${chalk.blue('Token')} ${token.token}… with id ${chalk.cyan(token.id)} name ${chalk.magenta(token.name)} created ${created}`) if (token.cidr_whitelist) { output.standard(`with IP whitelist: ${chalk.green(token.cidr_whitelist.join(','))}`) } diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js index a369158d99c..60c5eb8e791 100644 --- a/deps/npm/lib/commands/uninstall.js +++ b/deps/npm/lib/commands/uninstall.js @@ -1,6 +1,7 @@ const { resolve } = require('node:path') const pkgJson = require('@npmcli/package-json') const reifyFinish = require('../utils/reify-finish.js') +const resolveAllowScripts = require('../utils/resolve-allow-scripts.js') const completion = require('../utils/installed-shallow.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') @@ -39,11 +40,13 @@ class Uninstall extends ArboristWorkspaceCmd { : this.npm.localPrefix const Arborist = require('@npmcli/arborist') + const { policy: allowScriptsPolicy } = await resolveAllowScripts(this.npm) const opts = { ...this.npm.flatOptions, path, rm: args, workspaces: this.workspaceNames, + allowScripts: allowScriptsPolicy, } const arb = new Arborist(opts) await arb.reify(opts) diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js index 22f77390b25..38f87c4a3e2 100644 --- a/deps/npm/lib/commands/update.js +++ b/deps/npm/lib/commands/update.js @@ -27,6 +27,7 @@ class Update extends ArboristWorkspaceCmd { 'audit', 'before', 'min-release-age', + 'min-release-age-exclude', 'bin-links', 'fund', 'dry-run', diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index b2ab377e95d..340d872a176 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -252,12 +252,13 @@ class Npm { // Check if help is requested for the subcommand if (this.config.get('usage')) { - const parentName = commandPath[0] + const parentName = commandPath.join(' ') return output.standard(SubCommand.getUsage(parentName)) } // Create subcommand instance and recurse const subcommandInstance = new SubCommand(this) + subcommandInstance.parentName = commandPath.join(' ') const subcommandArgs = args.slice(1) // Remove subcommand name from args const subcommandPath = [...commandPath, subcommandName] diff --git a/deps/npm/lib/utils/allow-scripts-cmd.js b/deps/npm/lib/utils/allow-scripts-cmd.js index c1ff242abea..315b7b0b4fb 100644 --- a/deps/npm/lib/utils/allow-scripts-cmd.js +++ b/deps/npm/lib/utils/allow-scripts-cmd.js @@ -1,6 +1,9 @@ const { log, output } = require('proc-log') +const npa = require('npm-package-arg') +const semver = require('semver') const pkgJson = require('@npmcli/package-json') const { trustedDisplay } = require('@npmcli/arborist/lib/script-allowed.js') +const getInstallScripts = require('@npmcli/arborist/lib/install-scripts.js') const checkAllowScripts = require('./check-allow-scripts.js') const resolveAllowScripts = require('./resolve-allow-scripts.js') const { @@ -8,10 +11,34 @@ const { applyDenyForPackage, nameKeyFor, } = require('./allow-scripts-writer.js') +const { classifyUnusedEntries } = require('./allow-scripts-prune.js') const BaseCommand = require('../base-cmd.js') -// Shared implementation for `npm approve-scripts` and `npm deny-scripts`. -// Subclasses set `verb` to `'approve'` or `'deny'`. +// Parse a positional arg into a name and an optional version range. A bare +// name matches every installed version; `pkg@1.2.3` or `pkg@^1` narrows by +// semver. npm-package-arg handles dotted and scoped names; fall back to the +// raw string as the name if it can't be parsed. +const parsePositional = (arg) => { + let parsed + try { + parsed = npa(arg) + } catch { + return { name: arg, range: null } + } + const name = parsed.name || arg + if (parsed.type === 'version' || parsed.type === 'range') { + const spec = parsed.fetchSpec + const range = (!spec || spec === '*' || parsed.rawSpec === '' || parsed.rawSpec === '*') + ? null + : spec + return { name, range } + } + return { name, range: null } +} + +// Shared implementation for `npm approve-scripts`, `npm deny-scripts`, and the `npm install-scripts` namespace. +// `npm install-scripts` dispatches to `runMode('approve' | 'deny' | 'list', ...)`. +// The standalone commands set `static verb` and run through the default `exec`. // // Extends `BaseCommand` rather than `ArboristCmd` on purpose. Per RFC, // `allowScripts` is read from the workspace root's `package.json` only; @@ -24,13 +51,23 @@ class AllowScriptsCmd extends BaseCommand { static params = ['all', 'allow-scripts-pending', 'allow-scripts-pin', 'json'] static ignoreImplicitWorkspace = false - // Subclasses set `static verb = 'approve' | 'deny'`. + // Mode of the current run, set by runMode. + // One of 'approve', 'deny', 'list', or 'prune'. + #mode = null + + // verb drives the writers and summaries, which only run in the two write modes, so it is never read while listing. get verb () { - /* istanbul ignore next: every concrete subclass declares static verb */ - return this.constructor.verb + return this.#mode } + // Standalone `npm approve-scripts` / `npm deny-scripts` pick their mode from `static verb`. async exec (args) { + return this.runMode(this.constructor.verb, args) + } + + async runMode (mode, args) { + this.#mode = mode + if (this.npm.global) { throw Object.assign( new Error(`\`npm ${this.constructor.name}\` does not work for global installs`), @@ -38,19 +75,33 @@ class AllowScriptsCmd extends BaseCommand { ) } - const pending = !!this.npm.config.get('allow-scripts-pending') + // `prune` has its own flow: it reads the literal package.json#allowScripts + // map, not the resolved policy. + if (mode === 'prune') { + return this.runPrune(args) + } + + // `--allow-scripts-pending` is only honored by commands that declare it; the namespace lists via `ls` instead. + const pending = this.constructor.params.includes('allow-scripts-pending') && + !!this.npm.config.get('allow-scripts-pending') const all = !!this.npm.config.get('all') + // The `ls` subcommand lists, and so does `--allow-scripts-pending` on the write commands. + const list = mode === 'list' || pending - if (pending && (args.length > 0 || all)) { + if (list && (args.length > 0 || all)) { + const what = mode === 'list' ? '`npm install-scripts ls`' : '`--allow-scripts-pending`' throw this.usageError( - '`--allow-scripts-pending` cannot be combined with positional arguments or `--all`.' + `${what} cannot be combined with positional arguments or \`--all\`.` ) } - if (!pending && !all && args.length === 0) { + if (!list && !all && args.length === 0) { throw this.usageError() } - if (this.verb === 'deny' && pending) { - throw this.usageError('`npm deny-scripts --allow-scripts-pending` is not supported.') + if (mode === 'deny' && pending) { + throw this.usageError( + '`npm deny-scripts --allow-scripts-pending` is not supported; ' + + 'run `npm install-scripts ls` to list unreviewed packages.' + ) } const Arborist = require('@npmcli/arborist') @@ -62,9 +113,12 @@ class AllowScriptsCmd extends BaseCommand { }) await arb.loadActual() - const unreviewed = await checkAllowScripts({ arb, npm: this.npm }) + // Keep listing unreviewed packages even with ignore-scripts set, so + // you can move from a blanket ignore-scripts to an allowlist. This + // only lists; nothing runs. + const unreviewed = await checkAllowScripts({ arb, npm: this.npm, includeWhenIgnored: true }) - if (pending) { + if (list) { return this.runPending(unreviewed) } @@ -76,6 +130,10 @@ class AllowScriptsCmd extends BaseCommand { } runPending (unreviewed) { + if (this.npm.flatOptions.json) { + output.buffer({ allowScripts: this.pendingSummary(unreviewed) }) + return + } if (unreviewed.length === 0) { output.standard('No packages with unreviewed install scripts.') return @@ -98,42 +156,56 @@ class AllowScriptsCmd extends BaseCommand { } output.standard('') output.standard( - 'Run `npm approve-scripts ` to allow, or `npm deny-scripts ` to deny.' + 'Run `npm install-scripts approve ` to allow, ' + + 'or `npm install-scripts deny ` to deny.' ) } + // Build the same `{ name, changes }` shape printSummary uses for writes, + // but tag every entry as `pending` since nothing is written. Names and + // versions are derived exactly like the text listing above. + pendingSummary (unreviewed) { + const groups = new Map() + for (const { node } of unreviewed) { + const { name, version } = trustedDisplay(node) + /* istanbul ignore next: every test node has a name */ + const display = name || '' + const key = version ? `${display}@${version}` : display + if (!groups.has(display)) { + groups.set(display, []) + } + groups.get(display).push({ key, change: 'pending' }) + } + return [...groups].map(([name, changes]) => ({ name, changes })) + } + async runAll (unreviewed) { if (unreviewed.length === 0) { + if (this.npm.flatOptions.json) { + output.buffer({ allowScripts: [] }) + return + } output.standard('No packages with unreviewed install scripts.') return } - // Bundled dependencies cannot be allowlisted in Phase 1 (RFC defers - // this to a follow-up because matching by name@version from the - // bundled tarball would reintroduce manifest confusion). Exclude - // them from `--all` so we don't silently write a policy entry under - // attacker-controlled identity. - const candidates = unreviewed.filter(({ node }) => !node.inBundle) - const skipped = unreviewed.length - candidates.length - if (skipped > 0) { - /* istanbul ignore next: plural variant covered separately */ - const noun = skipped === 1 ? 'dependency' : 'dependencies' - log.warn( - this.logTitle, - `Skipping ${skipped} bundled ${noun}; bundled deps with install ` + - 'scripts cannot be allowlisted in this release.' - ) - } - if (candidates.length === 0) { - output.standard('No packages eligible for approval.') - return - } - const groups = this.groupByPackage(candidates.map(({ node }) => node)) + // Bundled dependencies never appear in `unreviewed` (checkAllowScripts + // skips them because they never run their install scripts and cannot + // be allowlisted), so there is nothing extra to filter here. + const groups = this.groupByPackage(unreviewed.map(({ node }) => node)) await this.writePolicyChanges(groups) } async runPositional (args, arb) { - const matched = this.findNodesForArgs(args, arb) + const { matched, unmatched } = this.findNodesForArgs(args, arb) + if (unmatched.length > 0) { + throw Object.assign( + new Error(`No installed packages match: ${unmatched.join(', ')}`), + { code: 'ENOMATCH' } + ) + } const groups = this.groupByPackage(matched) + /* istanbul ignore if: matched is non-empty here; groups only empties when a + matched node has no trusted key, which groupByPackage already warns on */ if (Object.keys(groups).length === 0) { throw Object.assign( new Error(`No installed packages match: ${args.join(', ')}`), @@ -144,22 +216,36 @@ class AllowScriptsCmd extends BaseCommand { } findNodesForArgs (args, arb) { - // Match positional args against each node's trusted name. Registry - // deps use the URL-derived name; non-registry deps fall back to the - // dependency edge name. Bundled deps are excluded for the same reason - // as --all. - const wanted = new Set(args) + // Match positional args against each node's trusted name. Registry deps + // use the URL-derived name; non-registry deps fall back to the dependency + // edge name. A version or range on the arg narrows the match to installed + // versions that satisfy it. Bundled deps are excluded for the same reason + // as --all. Args that match nothing are returned in `unmatched`. const matched = [] - for (const node of arb.actualTree.inventory.values()) { - if (node.isProjectRoot || node.isWorkspace || node.inBundle) { - continue + const unmatched = [] + for (const arg of args) { + const { name: wantName, range } = parsePositional(arg) + const found = [] + for (const node of arb.actualTree.inventory.values()) { + if (node.isProjectRoot || node.isWorkspace || node.inBundle) { + continue + } + const { name, version } = trustedDisplay(node) + if (!name || name !== wantName) { + continue + } + if (range && (!version || !semver.satisfies(version, range, { loose: true }))) { + continue + } + found.push(node) } - const { name } = trustedDisplay(node) - if (name && wanted.has(name)) { - matched.push(node) + if (found.length === 0) { + unmatched.push(arg) + } else { + matched.push(...found) } } - return matched + return { matched, unmatched } } get logTitle () { @@ -240,6 +326,78 @@ class AllowScriptsCmd extends BaseCommand { output.standard(`Nothing to ${this.verb}; allowScripts unchanged.`) } } + + // `npm install-scripts prune`: drop package.json#allowScripts entries that no + // longer match an installed package with an install script. Edits only + // package.json (never `.npmrc`/CLI policy); `--dry-run` reports without writing. + async runPrune (args) { + const all = !!this.npm.config.get('all') + if (args.length > 0 || all) { + throw this.usageError( + '`npm install-scripts prune` cannot be combined with positional arguments or `--all`.' + ) + } + + const dryRun = !!this.npm.config.get('dry-run') + const pkg = await pkgJson.load(this.npm.prefix) + const existing = pkg.content.allowScripts && typeof pkg.content.allowScripts === 'object' + ? pkg.content.allowScripts + : {} + + let removed = [] + if (Object.keys(existing).length > 0) { + const Arborist = require('@npmcli/arborist') + const arb = new Arborist({ + ...this.npm.flatOptions, + path: this.npm.prefix, + }) + await arb.loadActual() + + // Candidate install nodes (mirrors collectUnreviewedScripts), tagged with + // whether each has install scripts so the classifier can tell "gone" from + // "no longer has scripts". + const nodes = [] + for (const node of arb.actualTree.inventory.values()) { + if (node.isProjectRoot || node.isWorkspace || node.isLink || node.inBundle || node.inert) { + continue + } + const scripts = await getInstallScripts(node) + nodes.push({ node, hasScripts: Object.keys(scripts).length > 0 }) + } + + const { remaining, removed: unused } = classifyUnusedEntries(existing, nodes) + removed = unused + + if (removed.length > 0 && !dryRun) { + // Drop the field entirely when nothing is left rather than leaving `{}`. + pkg.update({ + allowScripts: Object.keys(remaining).length > 0 ? remaining : undefined, + }) + await pkg.save() + } + } + + this.printPruneSummary({ removed, dryRun }) + } + + printPruneSummary ({ removed, dryRun }) { + if (this.npm.flatOptions.json) { + output.buffer({ allowScripts: { removed, dryRun } }) + return + } + if (removed.length === 0) { + output.standard('No unused allowScripts entries.') + return + } + const entry = removed.length === 1 ? 'entry' : 'entries' + output.standard( + `${dryRun ? 'Would remove' : 'Removed'} ${removed.length} unused allowScripts ${entry}:` + ) + for (const { key, reason } of removed) { + const text = reason === 'not-installed' ? 'package not installed' : 'no install scripts' + output.standard(` ${key} (${text})`) + } + } } module.exports = AllowScriptsCmd diff --git a/deps/npm/lib/utils/allow-scripts-prune.js b/deps/npm/lib/utils/allow-scripts-prune.js new file mode 100644 index 00000000000..1111b45d9ca --- /dev/null +++ b/deps/npm/lib/utils/allow-scripts-prune.js @@ -0,0 +1,47 @@ +const npa = require('npm-package-arg') +const { matches } = require('@npmcli/arborist/lib/script-allowed.js') + +// Pure classifier behind `npm install-scripts prune`. +// +// Splits the `package.json#allowScripts` map into entries to keep (`remaining`) +// and unused ones to drop (`removed`). `nodes` is the install candidates as +// `{ node, hasScripts }`; the caller gathers them so this stays sync. +// +// An entry is unused (version-aware, by trusted identity) when: +// - no installed node matches the key -> reason 'not-installed' +// - it matches but none have scripts -> reason 'no-scripts' +// +// Unparseable keys are kept (prune never drops what it can't parse). Both +// `true` (approve) and `false` (deny) entries are pruned. +const classifyUnusedEntries = (allowScripts, nodes) => { + const remaining = {} + const removed = [] + + for (const [key, value] of Object.entries(allowScripts || {})) { + let parseable = true + try { + npa(key) + } catch { + parseable = false + } + if (!parseable) { + remaining[key] = value + continue + } + + const matching = nodes.filter(({ node }) => matches(node, key)) + if (matching.length === 0) { + removed.push({ key, value, reason: 'not-installed' }) + continue + } + if (!matching.some(({ hasScripts }) => hasScripts)) { + removed.push({ key, value, reason: 'no-scripts' }) + continue + } + remaining[key] = value + } + + return { remaining, removed } +} + +module.exports = { classifyUnusedEntries } diff --git a/deps/npm/lib/utils/allow-scripts-remediation.js b/deps/npm/lib/utils/allow-scripts-remediation.js new file mode 100644 index 00000000000..ff8c9b75a81 --- /dev/null +++ b/deps/npm/lib/utils/allow-scripts-remediation.js @@ -0,0 +1,9 @@ +// Builds the `npm config set allow-scripts` command suggested to global +// users, who have no project package.json for `npm approve-scripts` to +// write to. `--location=user` keeps the setting in the user .npmrc instead +// of trying (and, for global installs, failing) to write it to the local +// project config. +const configSetAllowScripts = (names) => + `npm config set allow-scripts=${names.join(',')} --location=user` + +module.exports = { configSetAllowScripts } diff --git a/deps/npm/lib/utils/allow-scripts-writer.js b/deps/npm/lib/utils/allow-scripts-writer.js index 5f43bbebeed..b9476905d42 100644 --- a/deps/npm/lib/utils/allow-scripts-writer.js +++ b/deps/npm/lib/utils/allow-scripts-writer.js @@ -1,6 +1,9 @@ const npa = require('npm-package-arg') const { log } = require('proc-log') -const { getTrustedRegistryIdentity } = require('@npmcli/arborist/lib/script-allowed.js') +const { + getTrustedRegistryIdentity, + resolvedSourceSpecs, +} = require('@npmcli/arborist/lib/script-allowed.js') // Pure helpers that implement the RFC's pin-mismatch table for // `npm approve-scripts` and `npm deny-scripts`. @@ -12,6 +15,8 @@ const { getTrustedRegistryIdentity } = require('@npmcli/arborist/lib/script-allo // Denying always writes `"": false`, regardless of `--allow-scripts-pin`, per the // RFC's asymmetric-pin rule. +const primaryResolvedSource = (node) => resolvedSourceSpecs(node)[0] || '' + // Convert an arborist Node into the spec string used for a versioned policy // entry. Returns `null` if the node cannot be represented as a versioned key // derived from trusted sources (lockfile URL for registry, hosted shortcut @@ -21,8 +26,7 @@ const versionedKeyFor = (node) => { if (!node) { return null } - /* istanbul ignore next: callers guarantee a string resolved */ - const resolved = typeof node.resolved === 'string' ? node.resolved : '' + const resolved = primaryResolvedSource(node) if (resolved.startsWith('git')) { try { const parsed = npa(resolved) @@ -69,8 +73,7 @@ const nameKeyFor = (node) => { if (!node) { return null } - /* istanbul ignore next: callers guarantee a string resolved */ - const resolved = typeof node.resolved === 'string' ? node.resolved : '' + const resolved = primaryResolvedSource(node) if (resolved.startsWith('git')) { try { const parsed = npa(resolved) @@ -105,15 +108,15 @@ const isSingleVersionPin = (key) => { // an approval. Per RFC, a name-only deny ("pkg": false) is widest and // the only remediation is to remove the entry. A versioned deny // ("pkg@1.2.3": false or a disjunction) blocks only specific versions; -// the user can either widen it via `npm deny-scripts ` or remove -// it to approve the currently-installed version only. +// the user can either widen it via `npm install-scripts deny ` or +// remove it to approve the currently-installed version only. const denyWarning = (key, subject, name) => { if (isNameOnlyKey(key)) { return `${key} is denied; remove the entry from allowScripts to approve ${subject}.` } /* istanbul ignore next: name fallback is defensive; callers pass nameKeyFor(sample) */ const widenTarget = name || 'this package' - return `${key} is a versioned deny; run \`npm deny-scripts ${widenTarget}\` ` + + return `${key} is a versioned deny; run \`npm install-scripts deny ${widenTarget}\` ` + `to widen the deny to all versions of ${widenTarget}, or remove the entry ` + `to approve ${subject}.` } @@ -164,7 +167,8 @@ const keyTargetsNode = (key, node) => { case 'git': { let resolvedParsed try { - resolvedParsed = node.resolved ? npa(node.resolved) : null + const resolved = primaryResolvedSource(node) + resolvedParsed = resolved ? npa(resolved) : null } catch { /* istanbul ignore next */ return false @@ -176,7 +180,8 @@ const keyTargetsNode = (key, node) => { case 'file': case 'directory': case 'remote': - return node.resolved === parsed.saveSpec || node.resolved === parsed.fetchSpec + return resolvedSourceSpecs(node) + .some(resolved => resolved === parsed.saveSpec || resolved === parsed.fetchSpec) default: return false } @@ -245,7 +250,41 @@ const applyApprovalForPackage = (existing, nodes, { pin = true } = {}) => { // package are removed. Per the RFC's pin-mismatch table, an existing // name-only entry (`pkg: true`) is replaced by `pkg@x.y.z: true` once // every installed version has a pin. - const installedKeys = new Set(nodes.map(versionedKeyFor).filter(Boolean)) + const versionedKeys = nodes.map(versionedKeyFor) + const installedKeys = new Set(versionedKeys.filter(Boolean)) + + // A registry dep with no `resolved` URL in the lockfile has no trustable + // version (getTrustedRegistryIdentity won't trust the tarball's + // node.version), so versionedKeyFor returns null and a `pkg@x.y.z` pin can + // never match it (npm/cli#9558). When any installed version can't be + // pinned, approve the whole package by name and drop now-redundant pins. + if (name && versionedKeys.some(key => !key)) { + for (const key of Object.keys(allowScripts)) { + if ( + keyTargetsNode(key, sample) && + key !== name && + isSingleVersionPin(key) && + allowScripts[key] === true + ) { + delete allowScripts[key] + changes.push({ key, change: 'removed-pinned-allow' }) + } + } + if (allowScripts[name] !== true) { + allowScripts[name] = true + changes.push({ key: name, change: 'added' }) + } + return { + allowScripts, + changes, + warning: changes.length + ? `${name}: approved by name (all versions) because its ` + + `package-lock.json entry has no "resolved" URL, so npm can't pin a ` + + `specific version. Run \`npm install\` to refresh the lockfile and ` + + `enable pinning.` + : undefined, + } + } for (const key of Object.keys(allowScripts)) { if ( diff --git a/deps/npm/lib/utils/check-allow-scripts.js b/deps/npm/lib/utils/check-allow-scripts.js index 5ef2bfb74cf..47984803cde 100644 --- a/deps/npm/lib/utils/check-allow-scripts.js +++ b/deps/npm/lib/utils/check-allow-scripts.js @@ -1,54 +1,27 @@ -const isScriptAllowed = require('@npmcli/arborist/lib/script-allowed.js') -const getInstallScripts = require('@npmcli/arborist/lib/install-scripts.js') +const { collectUnreviewedScripts } = require('@npmcli/arborist/lib/unreviewed-scripts.js') -// Walks arb.actualTree.inventory and returns the list of dep nodes that -// have install-relevant lifecycle scripts and are not yet covered (or -// explicitly denied) by the allowScripts policy. +// Walks a tree's inventory and returns the list of dep nodes that have +// install-relevant lifecycle scripts and are not yet covered (or explicitly +// denied) by the allowScripts policy. +// +// Thin wrapper around arborist's shared `collectUnreviewedScripts`, mapping +// the CLI's `({ arb, npm, tree })` shape onto the shared walk. Defaults to +// `arb.actualTree` (post-reify) but accepts an explicit tree so callers can +// pre-flight against the idealTree before scripts run. // // Returns an array of `{ node, scripts }` entries. `scripts` is an object // describing the relevant lifecycle scripts that would run. - -const checkAllowScripts = async ({ arb, npm, tree }) => { - const ignoreScripts = !!arb.options?.ignoreScripts - const dangerouslyAllowAll = !!npm?.flatOptions?.dangerouslyAllowAllScripts - - if (ignoreScripts || dangerouslyAllowAll) { - return [] - } - - // Defaults to actualTree (post-reify) but accepts an explicit tree so - // callers can pre-flight against the idealTree before scripts run. - const targetTree = tree || arb.actualTree - if (!targetTree?.inventory) { - return [] - } - - const policy = arb.options?.allowScripts || null - - const unreviewed = [] - for (const node of targetTree.inventory.values()) { - if (node.isProjectRoot || node.isWorkspace) { - continue - } - if (node.isLink) { - // Linked workspace dependencies are managed by the workspace owner. - continue - } - - const verdict = isScriptAllowed(node, policy) - if (verdict === true || verdict === false) { - continue - } - - const scripts = await getInstallScripts(node) - if (Object.keys(scripts).length === 0) { - continue - } - - unreviewed.push({ node, scripts }) - } - - return unreviewed -} +// +// `includeWhenIgnored` keeps listing unreviewed packages even when +// ignore-scripts is set, so approve/deny can show what you'd move from a +// blanket ignore-scripts to an allowlist. Execution callers leave it false. +const checkAllowScripts = async ({ arb, npm, tree, includeWhenIgnored = false }) => + collectUnreviewedScripts({ + tree: tree || arb.actualTree, + policy: arb.options?.allowScripts || null, + ignoreScripts: !!arb.options?.ignoreScripts, + dangerouslyAllowAllScripts: !!npm?.flatOptions?.dangerouslyAllowAllScripts, + includeWhenIgnored, + }) module.exports = checkAllowScripts diff --git a/deps/npm/lib/utils/cmd-list.js b/deps/npm/lib/utils/cmd-list.js index 1909df0d045..8816d829471 100644 --- a/deps/npm/lib/utils/cmd-list.js +++ b/deps/npm/lib/utils/cmd-list.js @@ -31,6 +31,7 @@ const commands = [ 'init', 'install', 'install-ci-test', + 'install-scripts', 'install-test', 'link', 'll', diff --git a/deps/npm/lib/utils/queryable.js b/deps/npm/lib/utils/queryable.js index e18222e83fc..fac7581e6f8 100644 --- a/deps/npm/lib/utils/queryable.js +++ b/deps/npm/lib/utils/queryable.js @@ -2,6 +2,8 @@ const util = require('node:util') const _delete = Symbol('delete') const _append = Symbol('append') +const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']) + const sqBracketsMatcher = str => str.match(/(.+)\[([^\]]+)\]\.?(.*)$/) // replaces any occurrence of an empty-brackets (e.g: []) with a special Symbol(append) to represent it @@ -122,6 +124,9 @@ const setter = ({ data, key, value, force }) => { // e.g: ['foo', 'bar', 'baz'] -> { foo: { bar: { baz: {} } } const keys = parseKeys(key) const setKeys = (_data, _key) => { + if (FORBIDDEN_KEYS.has(String(_key))) { + throw Object.assign(new Error(`Forbidden key: "${_key}"`), { code: 'EFORBIDDENKEY' }) + } // handles array indexes, converting valid integers to numbers // note that occurrences of Symbol(append) will throw so we just ignore these for now let maybeIndex = Number.NaN diff --git a/deps/npm/lib/utils/reify-output.js b/deps/npm/lib/utils/reify-output.js index b1e1ffbcddd..6e25f943406 100644 --- a/deps/npm/lib/utils/reify-output.js +++ b/deps/npm/lib/utils/reify-output.js @@ -16,6 +16,7 @@ const npmAuditReport = require('npm-audit-report') const { readTree: getFundingInfo } = require('libnpmfund') const { trustedDisplay } = require('@npmcli/arborist/lib/script-allowed.js') const auditError = require('./audit-error.js') +const { configSetAllowScripts } = require('./allow-scripts-remediation.js') const reifyOutput = (npm, arb, extras = {}) => { const { diff, actualTree } = arb @@ -65,7 +66,8 @@ const reifyOutput = (npm, arb, extras = {}) => { if (showDiff) { output.standard(`${chalk.green('add')} ${d.ideal.name} ${d.ideal.package.version}`) } - if (actualTree.inventory.has(d.ideal)) { + // Linked store packages live under .store, absent from the logical actualTree, so identity lookup misses them; count each store package node (non-link). + if (actualTree.inventory.has(d.ideal) || (d.ideal.isInStore && !d.ideal.isLink)) { summary.added++ summary.add.push({ name: d.ideal.name, @@ -243,10 +245,12 @@ const unreviewedScriptsMessage = (npm, unreviewedScripts) => { const pkg = count === 1 ? 'package has' : 'packages have' const header = `${count} ${pkg} install scripts not yet covered by allowScripts:` + const names = [] const lines = unreviewedScripts.map(({ node, scripts }) => { const { name, version } = trustedDisplay(node) /* istanbul ignore next: every test node has a name */ const display = name || '' + names.push(display) const ver = version ? `@${version}` : '' const events = Object.entries(scripts) .map(([event, cmd]) => `${event}: ${cmd}`) @@ -260,9 +264,28 @@ const unreviewedScriptsMessage = (npm, unreviewedScripts) => { header, ...lines, '', - 'Run `npm approve-scripts --allow-scripts-pending` to review, or `npm approve-scripts ` to allow.', + ...remediationLines(npm, names), ].join('\n') ) } +// `npm install-scripts` writes to a project package.json, which doesn't +// exist for global installs (it throws EGLOBAL). For those, point users at +// the mechanism that does work globally: the `--allow-scripts` flag for a +// one-off, or `npm config set allow-scripts` to persist it. +const remediationLines = (npm, names) => { + if (npm.global) { + const list = names.join(',') + return [ + `Run \`npm install -g --allow-scripts=${list}\` to allow these scripts ` + + `once, or \`${configSetAllowScripts(names)}\` to allow them for ` + + 'all global installs.', + ] + } + return [ + 'Run `npm install-scripts ls` to review, ' + + 'or `npm install-scripts approve ` to allow.', + ] +} + module.exports = reifyOutput diff --git a/deps/npm/lib/utils/sbom-cyclonedx.js b/deps/npm/lib/utils/sbom-cyclonedx.js index fe368e968ba..bd741718bef 100644 --- a/deps/npm/lib/utils/sbom-cyclonedx.js +++ b/deps/npm/lib/utils/sbom-cyclonedx.js @@ -76,7 +76,7 @@ const toCyclonedxItem = (node, { packageType }) => { // Calculate purl from package spec let spec = npa(node.pkgid) spec = (spec.type === 'alias') ? spec.subSpec : spec - const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${node.resolved}` : '') + const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${encodeURIComponent(node.resolved)}` : '') if (node.package) { const toNormalize = new PackageJson() diff --git a/deps/npm/lib/utils/sbom-spdx.js b/deps/npm/lib/utils/sbom-spdx.js index 8ea75c688bc..88797fd03ef 100644 --- a/deps/npm/lib/utils/sbom-spdx.js +++ b/deps/npm/lib/utils/sbom-spdx.js @@ -109,7 +109,7 @@ const toSpdxItem = (node, { packageType }) => { // Calculate purl from package spec let spec = npa(node.pkgid) spec = (spec.type === 'alias') ? spec.subSpec : spec - const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${node.resolved}` : '') + const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${encodeURIComponent(node.resolved)}` : '') /* For workspace nodes, use the location from their linkNode */ let location = node.location diff --git a/deps/npm/lib/utils/strict-allow-scripts-preflight.js b/deps/npm/lib/utils/strict-allow-scripts-preflight.js index a3f83ea4b66..0c500018184 100644 --- a/deps/npm/lib/utils/strict-allow-scripts-preflight.js +++ b/deps/npm/lib/utils/strict-allow-scripts-preflight.js @@ -1,4 +1,6 @@ const checkAllowScripts = require('./check-allow-scripts.js') +const { trustedDisplay } = require('@npmcli/arborist/lib/script-allowed.js') +const { configSetAllowScripts } = require('./allow-scripts-remediation.js') // Pre-flight check for `--strict-allow-scripts`. Call after arborist has // been constructed but before `arb.reify()` runs, so that install scripts @@ -46,13 +48,26 @@ const strictAllowScriptsPreflight = async ({ arb, npm, idealTreeOpts }) => { return ` ${label} (${events})` }).join('\n') + // `npm install-scripts` writes to a project package.json, which doesn't + // exist for global installs. Point global users at the `--allow-scripts` + // flag and `npm config set allow-scripts`, which both work for global + // installs. Use the trusted display identity so the suggested `npm config + // set` value matches what the policy matches on, not the tarball's + // self-reported name. + const names = unreviewed.map(({ node }) => trustedDisplay(node).name) + const remediation = npm.global + ? 'Allow them with `--allow-scripts`, persist them with ' + + `\`${configSetAllowScripts(names)}\`, or bypass this ` + + 'check with `--dangerously-allow-all-scripts`.' + : 'Approve them with `npm install-scripts approve`, deny them with ' + + '`npm install-scripts deny`, or bypass this check with ' + + '`--dangerously-allow-all-scripts`.' + throw Object.assign( new Error( `--strict-allow-scripts: ${unreviewed.length} package(s) have install ` + `scripts not covered by allowScripts:\n${lines}\n` + - 'Approve them with `npm approve-scripts`, deny them with ' + - '`npm deny-scripts`, or bypass this check with ' + - '`--dangerously-allow-all-scripts`.' + remediation ), { code: 'ESTRICTALLOWSCRIPTS' } ) diff --git a/deps/npm/lib/utils/verify-signatures.js b/deps/npm/lib/utils/verify-signatures.js index a4824d86d13..49e1d80df32 100644 --- a/deps/npm/lib/utils/verify-signatures.js +++ b/deps/npm/lib/utils/verify-signatures.js @@ -303,6 +303,11 @@ class VerifySignatures { verifyAttestations: true, ...this.buildRegistryConfig(registry), ...this.npm.flatOptions, + // These versions are already installed, so the before/min-release-age + // filter doesn't apply here. It was already applied at install time, and + // leaving it set makes pacote throw ETARGET for any version newer than + // the cutoff. See npm/cli#9277. + before: null, }) const signatures = _signatures || [] const result = { diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 1137b4d5fbe..707bc69f167 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -1,4 +1,4 @@ -.TH "NPM-ACCESS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-ACCESS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-access\fR - Set access level on published packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index b52bf3ed7f9..091bcf2e3fe 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,4 +1,4 @@ -.TH "NPM-ADDUSER" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-ADDUSER" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-adduser\fR - Add a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-approve-scripts.1 b/deps/npm/man/man1/npm-approve-scripts.1 index b6ac279a025..cd2aee3190b 100644 --- a/deps/npm/man/man1/npm-approve-scripts.1 +++ b/deps/npm/man/man1/npm-approve-scripts.1 @@ -1,4 +1,4 @@ -.TH "NPM-APPROVE-SCRIPTS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-APPROVE-SCRIPTS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-approve-scripts\fR - Approve install scripts for specific dependencies .SS "Synopsis" @@ -18,6 +18,8 @@ Manages the \fBallowScripts\fR field in your project's \fBpackage.json\fR, which .P In the current release, this field is advisory: install scripts still run by default, but installs print a list of packages whose scripts have not been reviewed. A future release will block unreviewed install scripts. .P +This command only works inside a project that has a \fBpackage.json\fR. Running it with \fB--global\fR (\fB-g\fR) fails with an \fBEGLOBAL\fR error, since global installs (\fBnpm install -g\fR) and one-off executions (\fBnpm exec\fR / \fBnpx\fR) have no project \fBpackage.json\fR to write to. To allow install scripts in those contexts, use the \fB--allow-scripts\fR flag at install time (for example \fBnpm install -g --allow-scripts=canvas,sharp\fR) or persist the setting with \fBnpm config set allow-scripts=canvas,sharp --location=user\fR. +.P There are three modes: .P .RS 2 @@ -35,6 +37,8 @@ npm approve-scripts --allow-scripts-pending \fB--allow-scripts-pending\fR is read-only: it lists every package whose install scripts are not yet covered by \fBallowScripts\fR, without modifying \fBpackage.json\fR. .P \fBapprove-scripts\fR honours the asymmetric pin rule: if you re-approve a package whose installed version has changed, the existing pin is rewritten to track the new installed version. Multi-version statements (\fBpkg@1 || 2\fR) are left alone, since they likely capture intent that the command cannot infer. Existing \fBfalse\fR entries always win; \fBapprove-scripts\fR will not silently re-allow a package you previously denied. +.P +If a registry dependency has no \fBresolved\fR URL in your \fBpackage-lock.json\fR (for example, an older lockfile or one written with \fBomit-lockfile-registry-resolved\fR), npm cannot verify a trusted version for it and cannot pin it: a \fBpkg@1.2.3\fR entry never matches, so the package keeps appearing under \fB--allow-scripts-pending\fR. \fBapprove-scripts\fR approves these by name (\fBpkg: true\fR) and warns when it does. To restore pinning, refresh the lockfile with \fBnpm install\fR. .SS "Examples" .P .RS 2 @@ -62,7 +66,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBallow-scripts-pending\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1 index f066529a8b8..4c9bf13ecc2 100644 --- a/deps/npm/man/man1/npm-audit.1 +++ b/deps/npm/man/man1/npm-audit.1 @@ -1,4 +1,4 @@ -.TH "NPM-AUDIT" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-AUDIT" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-audit\fR - Run a security audit .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index 6c9d745c20f..529f369d12d 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,4 +1,4 @@ -.TH "NPM-BUGS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-BUGS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-bugs\fR - Report bugs for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index 17e38319e16..1f609ffd785 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,4 +1,4 @@ -.TH "NPM-CACHE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-CACHE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-cache\fR - Manipulates packages cache .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1 index 467929979ed..2e62f4a1e73 100644 --- a/deps/npm/man/man1/npm-ci.1 +++ b/deps/npm/man/man1/npm-ci.1 @@ -1,4 +1,4 @@ -.TH "NPM-CI" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-CI" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-ci\fR - Clean install a project .SS "Synopsis" @@ -75,7 +75,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 @@ -242,6 +244,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index c6a82af87d9..5327001ec3f 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,4 +1,4 @@ -.TH "NPM-COMPLETION" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-COMPLETION" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-completion\fR - Tab Completion for npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index 28ae9ed07de..82fd108f72c 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,4 +1,4 @@ -.TH "NPM-CONFIG" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-CONFIG" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-config\fR - Manage the npm configuration files .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index c62112ff7f9..68e369035ea 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEDUPE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DEDUPE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-dedupe\fR - Reduce duplication in the package tree .SS "Synopsis" @@ -74,7 +74,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-deny-scripts.1 b/deps/npm/man/man1/npm-deny-scripts.1 index a466da7a30d..67daaa87b72 100644 --- a/deps/npm/man/man1/npm-deny-scripts.1 +++ b/deps/npm/man/man1/npm-deny-scripts.1 @@ -1,4 +1,4 @@ -.TH "NPM-DENY-SCRIPTS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DENY-SCRIPTS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-deny-scripts\fR - Deny install scripts for specific dependencies .SS "Synopsis" @@ -50,7 +50,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBallow-scripts-pending\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index 0e67565fba3..1d89f067e73 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEPRECATE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DEPRECATE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-deprecate\fR - Deprecate a version of a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1 index 1051276045f..cc06fc95438 100644 --- a/deps/npm/man/man1/npm-diff.1 +++ b/deps/npm/man/man1/npm-diff.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIFF" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DIFF" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-diff\fR - The registry diff command .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index a2a7e0ea36a..6c3e74e3c65 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIST-TAG" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DIST-TAG" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-dist-tag\fR - Modify package distribution tags .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index 943c26eb53f..952c18cf115 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DOCS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-docs\fR - Open documentation for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 0d40b9b45b1..1e8813a13a1 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCTOR" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-DOCTOR" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-doctor\fR - Check the health of your npm environment .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index d57bdc0ce6f..d46ea046ddb 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,4 +1,4 @@ -.TH "NPM-EDIT" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-EDIT" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-edit\fR - Edit an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-exec.1 b/deps/npm/man/man1/npm-exec.1 index 8987175e5d8..93245000380 100644 --- a/deps/npm/man/man1/npm-exec.1 +++ b/deps/npm/man/man1/npm-exec.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXEC" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-EXEC" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-exec\fR - Run a command from a local or remote npm package .SS "Synopsis" @@ -193,6 +193,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1 index ec315300c2f..0c4b22410bf 100644 --- a/deps/npm/man/man1/npm-explain.1 +++ b/deps/npm/man/man1/npm-explain.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLAIN" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-EXPLAIN" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-explain\fR - Explain installed packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index fbc61b1de01..bd6788e463e 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLORE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-EXPLORE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-explore\fR - Browse an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-find-dupes.1 b/deps/npm/man/man1/npm-find-dupes.1 index 57daa9d3225..8cab256a973 100644 --- a/deps/npm/man/man1/npm-find-dupes.1 +++ b/deps/npm/man/man1/npm-find-dupes.1 @@ -1,4 +1,4 @@ -.TH "NPM-FIND-DUPES" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-FIND-DUPES" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-find-dupes\fR - Find duplication in the package tree .SS "Synopsis" @@ -21,7 +21,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index 05a01775019..a334c59e990 100644 --- a/deps/npm/man/man1/npm-fund.1 +++ b/deps/npm/man/man1/npm-fund.1 @@ -1,4 +1,4 @@ -.TH "NPM-FUND" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-FUND" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-fund\fR - Retrieve funding information .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-get.1 b/deps/npm/man/man1/npm-get.1 index bbcfcae3a21..1eb86d69f16 100644 --- a/deps/npm/man/man1/npm-get.1 +++ b/deps/npm/man/man1/npm-get.1 @@ -1,4 +1,4 @@ -.TH "NPM-GET" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-GET" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-get\fR - Get a value from the npm configuration .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index b50eb9a9ac9..b1752ad2b56 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP-SEARCH" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-HELP-SEARCH" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-help-search\fR - Search npm help documentation .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index eb4353fbd7c..aef5394daaa 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-HELP" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-help\fR - Get help on npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index a55bf5cf7e4..990e0a58ed2 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,4 +1,4 @@ -.TH "NPM-INIT" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-INIT" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-init\fR - Create a package.json file .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1 index 4d0d125aac3..88db36a8799 100644 --- a/deps/npm/man/man1/npm-install-ci-test.1 +++ b/deps/npm/man/man1/npm-install-ci-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-CI-TEST" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-INSTALL-CI-TEST" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-install-ci-test\fR - Install a project with a clean slate and run tests .SS "Synopsis" @@ -23,7 +23,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 @@ -190,6 +192,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-install-scripts.1 b/deps/npm/man/man1/npm-install-scripts.1 new file mode 100644 index 00000000000..457b55c9fb7 --- /dev/null +++ b/deps/npm/man/man1/npm-install-scripts.1 @@ -0,0 +1,133 @@ +.TH "NPM-INSTALL-SCRIPTS" "1" "June 2026" "NPM@11.18.0" "" +.SH "NAME" +\fBnpm-install-scripts\fR - Manage install-script approvals for dependencies +.SS "Synopsis" +.P +.RS 2 +.nf +npm install-scripts approve \[lB] ...\[rB] +npm install-scripts approve --all +npm install-scripts deny \[lB] ...\[rB] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune +.fi +.RE +.P +Note: This command is unaware of workspaces. +.SS "Description" +.P +Manages the \fBallowScripts\fR field in your project's \fBpackage.json\fR, which records which of your dependencies are permitted to run install scripts (\fBpreinstall\fR, \fBinstall\fR, \fBpostinstall\fR, and \fBprepare\fR for non-registry sources). This is the recommended way to maintain that field. +.P +Dependency install scripts are blocked by default. Install commands silently skip lifecycle scripts for any dependency that does not have a matching entry in \fBallowScripts\fR, and end with a list of the packages whose scripts were skipped so you can review them here. +.P +This command only works inside a project that has a \fBpackage.json\fR. Running it with \fB--global\fR (\fB-g\fR) fails with an \fBEGLOBAL\fR error, since global installs (\fBnpm install -g\fR) and one-off executions (\fBnpm exec\fR / \fBnpx\fR) have no project \fBpackage.json\fR to write to. To allow install scripts in those contexts, use the \fB--allow-scripts\fR flag at install time (for example \fBnpm install -g --allow-scripts=canvas,sharp\fR) or persist the setting with \fBnpm config set allow-scripts=canvas,sharp --location=user\fR. +.P +There are four subcommands: +.P +.RS 2 +.nf +npm install-scripts approve \[lB] ...\[rB] +npm install-scripts approve --all +npm install-scripts deny \[lB] ...\[rB] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune +.fi +.RE +.P +\fBapprove\fR allows install scripts for the named packages. \fB\fR matches every installed version of that package. By default it writes pinned entries (\fBpkg@1.2.3\fR), which keep their approval narrowed to the specific version you reviewed. Pass \fB--no-allow-scripts-pin\fR to write name-only entries that allow any future version. \fB--all\fR approves every package with unreviewed install scripts in one go. +.P +\fBdeny\fR records an explicit denial for the named packages (a name-only \fBfalse\fR entry), which survives \fBnpm install-scripts approve --all\fR and excludes the package from any future blanket approval. \fB--all\fR denies every package with unreviewed install scripts. +.P +\fBls\fR is read-only: it lists every package whose install scripts are not yet covered by \fBallowScripts\fR, without modifying \fBpackage.json\fR. +.P +\fBprune\fR removes \fBallowScripts\fR entries that no longer match an installed package with an install script, either because the package is no longer installed (a transitive dependency changed, or a pinned \fBpkg@1.2.3\fR was upgraded) or because it no longer has an install script. Both approvals (\fBtrue\fR) and denials (\fBfalse\fR) are removed. It edits only the \fBallowScripts\fR field in \fBpackage.json\fR, never \fB.npmrc\fR or \fB--allow-scripts\fR. Pass \fB--dry-run\fR to preview without writing. Unparseable keys are left alone. +.P +\fBapprove\fR honours the asymmetric pin rule: if you re-approve a package whose installed version has changed, the existing pin is rewritten to track the new installed version. Multi-version statements (\fBpkg@1 || 2\fR) are left alone, since they likely capture intent that the command cannot infer. Existing \fBfalse\fR entries always win; \fBapprove\fR will not silently re-allow a package you previously denied. +.P +The standalone commands npm help approve-scripts and npm help deny-scripts are aliases for \fBnpm install-scripts approve\fR and \fBnpm install-scripts deny\fR. +.SS "Examples" +.P +.RS 2 +.nf +# Approve all currently-installed install scripts after reviewing them +npm install-scripts approve --all + +# Approve specific packages, pinned to their installed version +npm install-scripts approve canvas sharp + +# Deny a package so it stays blocked +npm install-scripts deny telemetry-pkg + +# Preview which packages still need review +npm install-scripts ls + +# Preview stale allowScripts entries, then remove them +npm install-scripts prune --dry-run +npm install-scripts prune +.fi +.RE +.SS "Configuration" +.SS "\fBall\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. +.SS "\fBallow-scripts-pin\fR" +.RS 0 +.IP \(bu 4 +Default: true +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Write pinned (\fBpkg@version\fR) entries when approving install scripts. Set to \fBfalse\fR to write name-only entries that allow any version. Has no effect on \fBnpm deny-scripts\fR, which always writes name-only entries regardless of this setting. +.SS "\fBdry-run\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Indicates that you don't want npm to make any changes and that it should only report what it would have done. This can be passed into any of the commands that modify your local installation, eg, \fBinstall\fR, \fBupdate\fR, \fBdedupe\fR, \fBuninstall\fR, as well as \fBpack\fR and \fBpublish\fR. +.P +Note: This is NOT honored by other network related commands, eg \fBdist-tags\fR, \fBowner\fR, etc. +.SS "\fBjson\fR" +.RS 0 +.IP \(bu 4 +Default: false +.IP \(bu 4 +Type: Boolean +.RE 0 + +.P +Whether or not to output JSON data, rather than the normal output. +.RS 0 +.IP \(bu 4 +In \fBnpm pkg set\fR it enables parsing set values with JSON.parse() before saving them to your \fBpackage.json\fR. +.RE 0 + +.P +Not supported by all npm commands. +.SS "See Also" +.RS 0 +.IP \(bu 4 +npm help approve-scripts +.IP \(bu 4 +npm help deny-scripts +.IP \(bu 4 +npm help install +.IP \(bu 4 +npm help rebuild +.IP \(bu 4 +\fBpackage.json\fR \fI\(la/configuring-npm/package-json\(ra\fR +.RE 0 diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index dd238cbf6c6..56a0a454c8e 100644 --- a/deps/npm/man/man1/npm-install-test.1 +++ b/deps/npm/man/man1/npm-install-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-TEST" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-INSTALL-TEST" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-install-test\fR - Install package(s) and run tests .SS "Synopsis" @@ -66,7 +66,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 @@ -267,6 +269,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 @@ -301,6 +305,11 @@ If passed to \fBnpm install\fR, will rebuild the npm tree such that only version If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. .P If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. .SS "\fBmin-release-age\fR" .RS 0 .IP \(bu 4 @@ -314,6 +323,36 @@ If set, npm will build the npm tree such that only versions that were available .P This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. .P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P This value is not exported to the environment for child processes. .SS "\fBbin-links\fR" .RS 0 diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index b51006e58e2..1c853a06d9e 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-INSTALL" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-install\fR - Install a package .SS "Synopsis" @@ -456,7 +456,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 @@ -657,6 +659,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 @@ -691,6 +695,11 @@ If passed to \fBnpm install\fR, will rebuild the npm tree such that only version If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. .P If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. .SS "\fBmin-release-age\fR" .RS 0 .IP \(bu 4 @@ -704,6 +713,36 @@ If set, npm will build the npm tree such that only versions that were available .P This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. .P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P This value is not exported to the environment for child processes. .SS "\fBbin-links\fR" .RS 0 diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index 5fc0057bfe9..9b45424b521 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,4 +1,4 @@ -.TH "NPM-LINK" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-LINK" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-link\fR - Symlink a package folder .SS "Synopsis" @@ -133,7 +133,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-ll.1 b/deps/npm/man/man1/npm-ll.1 index 860cb296e86..76cca43a86c 100644 --- a/deps/npm/man/man1/npm-ll.1 +++ b/deps/npm/man/man1/npm-ll.1 @@ -1,4 +1,4 @@ -.TH "NPM-LL" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-LL" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-ll\fR - List installed packages .SS "Synopsis" @@ -23,7 +23,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBjson\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-login.1 b/deps/npm/man/man1/npm-login.1 index 037be1840a4..c08365bf41b 100644 --- a/deps/npm/man/man1/npm-login.1 +++ b/deps/npm/man/man1/npm-login.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGIN" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-LOGIN" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-login\fR - Login to a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index d3fdd55251f..e27692a1f36 100644 --- a/deps/npm/man/man1/npm-logout.1 +++ b/deps/npm/man/man1/npm-logout.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGOUT" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-LOGOUT" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-logout\fR - Log out of the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index ac695c5c633..8d6a48be7ad 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,4 +1,4 @@ -.TH "NPM-LS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-LS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-ls\fR - List installed packages .SS "Synopsis" @@ -20,7 +20,7 @@ Positional arguments are \fBname@version-range\fR identifiers, which will limit .P .RS 2 .nf -npm@11.16.0 /path/to/npm +npm@11.18.0 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 .fi @@ -43,7 +43,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBjson\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1 index 25f1ca4680c..87b14daf94b 100644 --- a/deps/npm/man/man1/npm-org.1 +++ b/deps/npm/man/man1/npm-org.1 @@ -1,4 +1,4 @@ -.TH "NPM-ORG" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-ORG" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-org\fR - Manage orgs .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index 462141f446f..0b2677ecbe6 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,4 +1,4 @@ -.TH "NPM-OUTDATED" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-OUTDATED" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-outdated\fR - Check for outdated packages .SS "Synopsis" @@ -17,7 +17,7 @@ By default, only the direct dependencies of the root project and direct dependen In the output: .RS 0 .IP \(bu 4 -\fBwanted\fR is the maximum version of the package that satisfies the semver range specified in \fBpackage.json\fR. If there's no available semver range (i.e. you're running \fBnpm outdated --global\fR, or the package isn't included in \fBpackage.json\fR), then \fBwanted\fR shows the currently-installed version. +\fBwanted\fR is the maximum version of the package that satisfies the semver range specified in \fBpackage.json\fR. If there's no available semver range (i.e. you're running \fBnpm outdated --global\fR, or the package isn't included in \fBpackage.json\fR), then \fBwanted\fR shows the latest version. .IP \(bu 4 \fBlatest\fR is the version of the package tagged as latest in the registry. Running \fBnpm publish\fR with no special configuration will publish the package with a dist-tag of \fBlatest\fR. This may or may not be the maximum version of the package, or the most-recently published version of the package, depending on how the package's developer manages the latest npm help dist-tag. .IP \(bu 4 @@ -85,7 +85,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBjson\fR" .RS 0 .IP \(bu 4 @@ -181,6 +181,11 @@ If passed to \fBnpm install\fR, will rebuild the npm tree such that only version If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. .P If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. .SS "\fBmin-release-age\fR" .RS 0 .IP \(bu 4 @@ -194,6 +199,36 @@ If set, npm will build the npm tree such that only versions that were available .P This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. .P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P This value is not exported to the environment for child processes. .SS "See Also" .RS 0 diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index 7a90c8e0c28..b4239474547 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,4 +1,4 @@ -.TH "NPM-OWNER" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-OWNER" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-owner\fR - Manage package owners .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index 945b3f42e3c..4220d6eab1b 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,4 +1,4 @@ -.TH "NPM-PACK" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PACK" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-pack\fR - Create a tarball from a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1 index 0c9f579acb2..b214ef9bbe2 100644 --- a/deps/npm/man/man1/npm-ping.1 +++ b/deps/npm/man/man1/npm-ping.1 @@ -1,4 +1,4 @@ -.TH "NPM-PING" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PING" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-ping\fR - Ping npm registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pkg.1 b/deps/npm/man/man1/npm-pkg.1 index 525cc2fa92f..e61280ea9b3 100644 --- a/deps/npm/man/man1/npm-pkg.1 +++ b/deps/npm/man/man1/npm-pkg.1 @@ -1,4 +1,4 @@ -.TH "NPM-PKG" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PKG" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-pkg\fR - Manages your package.json .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index 0ad1dced9b9..8e5f186bc49 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,4 +1,4 @@ -.TH "NPM-PREFIX" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PREFIX" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-prefix\fR - Display prefix .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1 index ca1cdd366d8..7a3a7c3e73a 100644 --- a/deps/npm/man/man1/npm-profile.1 +++ b/deps/npm/man/man1/npm-profile.1 @@ -1,4 +1,4 @@ -.TH "NPM-PROFILE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PROFILE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-profile\fR - Change settings on your registry profile .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index b7dc1e212c4..d36938d3e27 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,4 +1,4 @@ -.TH "NPM-PRUNE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PRUNE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-prune\fR - Remove extraneous packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index 3bbb7139839..36ad2d781ac 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,4 +1,4 @@ -.TH "NPM-PUBLISH" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-PUBLISH" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-publish\fR - Publish a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-query.1 b/deps/npm/man/man1/npm-query.1 index cc73ad1e924..f5e07ec1954 100644 --- a/deps/npm/man/man1/npm-query.1 +++ b/deps/npm/man/man1/npm-query.1 @@ -1,4 +1,4 @@ -.TH "NPM-QUERY" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-QUERY" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-query\fR - Dependency selector query .SS "Synopsis" @@ -274,6 +274,69 @@ Type: null or Number Tells to expect a specific number of results from the command. .P This config cannot be used with: \fBexpect-results\fR +.SS "\fBbefore\fR" +.RS 0 +.IP \(bu 4 +Default: null +.IP \(bu 4 +Type: null or Date +.RE 0 + +.P +If passed to \fBnpm install\fR, will rebuild the npm tree such that only versions that were available \fBon or before\fR the given date are installed. If there are no versions available for the current set of dependencies, the command will error. +.P +If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. +.P +If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.SS "\fBmin-release-age\fR" +.RS 0 +.IP \(bu 4 +Default: null +.IP \(bu 4 +Type: null or Number +.RE 0 + +.P +If set, npm will build the npm tree such that only versions that were available more than the given number of days ago will be installed. If there are no versions available for the current set of dependencies, the command will error. +.P +This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. +.P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P +This value is not exported to the environment for child processes. .SH "SEE ALSO" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index af056260336..972bb0fadef 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,4 +1,4 @@ -.TH "NPM-REBUILD" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-REBUILD" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-rebuild\fR - Rebuild a package .SS "Synopsis" @@ -127,6 +127,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index 00b1754b495..f354706b7a9 100644 --- a/deps/npm/man/man1/npm-repo.1 +++ b/deps/npm/man/man1/npm-repo.1 @@ -1,4 +1,4 @@ -.TH "NPM-REPO" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-REPO" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-repo\fR - Open package repository page in the browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index 5fb602be957..754c1450517 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,4 +1,4 @@ -.TH "NPM-RESTART" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-RESTART" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-restart\fR - Restart a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 79ab7c6debc..21a04731a3c 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,4 +1,4 @@ -.TH "NPM-ROOT" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-ROOT" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-root\fR - Display npm root .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-run.1 b/deps/npm/man/man1/npm-run.1 index f20c43ab6a7..c481d3ea7f3 100644 --- a/deps/npm/man/man1/npm-run.1 +++ b/deps/npm/man/man1/npm-run.1 @@ -1,4 +1,4 @@ -.TH "NPM-RUN" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-RUN" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-run\fR - Run arbitrary package scripts .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-sbom.1 b/deps/npm/man/man1/npm-sbom.1 index e04ac0e6891..4528c2287d3 100644 --- a/deps/npm/man/man1/npm-sbom.1 +++ b/deps/npm/man/man1/npm-sbom.1 @@ -1,4 +1,4 @@ -.TH "NPM-SBOM" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-SBOM" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-sbom\fR - Generate a Software Bill of Materials (SBOM) .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index 51c9a99e58a..88088ac8303 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-SEARCH" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-SEARCH" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-search\fR - Search for packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-set.1 b/deps/npm/man/man1/npm-set.1 index 280d610a6e3..feee9c27be6 100644 --- a/deps/npm/man/man1/npm-set.1 +++ b/deps/npm/man/man1/npm-set.1 @@ -1,4 +1,4 @@ -.TH "NPM-SET" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-SET" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-set\fR - Set a value in the npm configuration .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 0f7214bda3f..12d1b01f555 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-SHRINKWRAP" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-shrinkwrap\fR - Lock down dependency versions for publication .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stage.1 b/deps/npm/man/man1/npm-stage.1 index 0fe39e8ff8c..9e14f2c5b25 100644 --- a/deps/npm/man/man1/npm-stage.1 +++ b/deps/npm/man/man1/npm-stage.1 @@ -1,4 +1,4 @@ -.TH "NPM-STAGE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-STAGE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-stage\fR - Stage packages for publishing .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index 385d6e8a232..37d94b17a7c 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,4 +1,4 @@ -.TH "NPM-STAR" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-STAR" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-star\fR - Mark your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index f028349ba81..4db22ed6039 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,4 +1,4 @@ -.TH "NPM-STARS" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-STARS" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-stars\fR - View packages marked as favorites .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index de0605d2fa8..0729d9cd175 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,4 +1,4 @@ -.TH "NPM-START" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-START" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-start\fR - Start a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index 57cadfb2fa8..e9261943c03 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,4 +1,4 @@ -.TH "NPM-STOP" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-STOP" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-stop\fR - Stop a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1 index 06d7b94acb7..d1e9e481cd8 100644 --- a/deps/npm/man/man1/npm-team.1 +++ b/deps/npm/man/man1/npm-team.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEAM" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-TEAM" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-team\fR - Manage organization teams and team memberships .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index 6c1108360e5..a9c28e79e98 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEST" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-TEST" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-test\fR - Test a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1 index 41a69ed9d9c..383a825d14f 100644 --- a/deps/npm/man/man1/npm-token.1 +++ b/deps/npm/man/man1/npm-token.1 @@ -1,4 +1,4 @@ -.TH "NPM-TOKEN" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-TOKEN" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-token\fR - Manage your authentication tokens .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-trust.1 b/deps/npm/man/man1/npm-trust.1 index 7b3c4d7990a..5dc2dfc702a 100644 --- a/deps/npm/man/man1/npm-trust.1 +++ b/deps/npm/man/man1/npm-trust.1 @@ -1,4 +1,4 @@ -.TH "NPM-TRUST" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-TRUST" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-trust\fR - Manage trusted publishing relationships between packages and CI/CD providers .SS "Synopsis" @@ -9,7 +9,7 @@ Note: This command is unaware of workspaces. Before using npm trust commands, ensure the following requirements are met: .RS 0 .IP \(bu 4 -\fBnpm version\fR: \fBnpm@11.10.0\fR or above is required. Use \fBnpm install -g npm@^11.10.0\fR to update if needed. +\fBnpm version\fR: \fBnpm@11.15.0\fR or above is required. Use \fBnpm install -g npm@^11.15.0\fR to update if needed. .IP \(bu 4 \fBWrite permissions on the package\fR: You must have write access to the package you're configuring. .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-undeprecate.1 b/deps/npm/man/man1/npm-undeprecate.1 index 8bb2936691c..2fc8e005009 100644 --- a/deps/npm/man/man1/npm-undeprecate.1 +++ b/deps/npm/man/man1/npm-undeprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNDEPRECATE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-UNDEPRECATE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-undeprecate\fR - Undeprecate a version of a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index 10845d76cb0..d2843a8a330 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNINSTALL" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-UNINSTALL" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-uninstall\fR - Remove a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index 1386bb85ce2..7c62b0c1324 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNPUBLISH" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-UNPUBLISH" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-unpublish\fR - Remove a package from the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-unstar.1 b/deps/npm/man/man1/npm-unstar.1 index 4fabb116f42..fe080180b66 100644 --- a/deps/npm/man/man1/npm-unstar.1 +++ b/deps/npm/man/man1/npm-unstar.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNSTAR" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-UNSTAR" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-unstar\fR - Remove an item from your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index e157c16d8a3..5ad8146b0da 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,4 +1,4 @@ -.TH "NPM-UPDATE" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-UPDATE" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-update\fR - Update packages .SS "Synopsis" @@ -128,7 +128,7 @@ Then \fBnpm update\fR will install \fBdep1@1.1.2\fR because that is the highest .P \fBnpm update -g\fR will apply the \fBupdate\fR action to each globally installed package that is \fBoutdated\fR -- that is, has a version that is different from \fBwanted\fR. .P -Note: Globally installed packages are treated as if they are installed with a caret semver range specified. So if you require to update to \fBlatest\fR you may need to run \fBnpm install -g \[lB]...\[rB]\fR +Note: Globally installed packages do not have a \fBpackage.json\fR semver range available, so their \fBwanted\fR version is \fBlatest\fR. .P NOTE: If a package has been upgraded to a version newer than \fBlatest\fR, it will be \fIdowngraded\fR. .SS "Configuration" @@ -174,7 +174,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBlegacy-bundling\fR" .RS 0 .IP \(bu 4 @@ -303,6 +305,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBdangerously-allow-all-scripts\fR" .RS 0 .IP \(bu 4 @@ -337,6 +341,11 @@ If passed to \fBnpm install\fR, will rebuild the npm tree such that only version If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. .P If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. .SS "\fBmin-release-age\fR" .RS 0 .IP \(bu 4 @@ -350,6 +359,36 @@ If set, npm will build the npm tree such that only versions that were available .P This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. .P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P This value is not exported to the environment for child processes. .SS "\fBbin-links\fR" .RS 0 diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 78612356235..d80b0e8288c 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,4 +1,4 @@ -.TH "NPM-VERSION" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-VERSION" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-version\fR - Bump a package version .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index 5ac8d354fbb..1c965ded858 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,4 +1,4 @@ -.TH "NPM-VIEW" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-VIEW" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-view\fR - View registry info .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index a0c1956514c..7ddb5ca6a84 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,4 +1,4 @@ -.TH "NPM-WHOAMI" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM-WHOAMI" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-whoami\fR - Display npm username .SS "Synopsis" diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 68369b132c9..58f6815ebad 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPM" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm\fR - javascript package manager .SS "Synopsis" @@ -12,7 +12,7 @@ npm Note: This command is unaware of workspaces. .SS "Version" .P -11.16.0 +11.18.0 .SS "Description" .P npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently. diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1 index 23671ac8cfb..c3a4f521f66 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -1,4 +1,4 @@ -.TH "NPX" "1" "May 2026" "NPM@11.16.0" "" +.TH "NPX" "1" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpx\fR - Run a command from a local or remote npm package .SS "Synopsis" diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5 index b0a8c9b4825..0202a97198c 100644 --- a/deps/npm/man/man5/folders.5 +++ b/deps/npm/man/man5/folders.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "May 2026" "NPM@11.16.0" "" +.TH "FOLDERS" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBFolders\fR - Folder structures used by npm .SS "Description" diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5 index e70fd2ed7b6..8e23936cba2 100644 --- a/deps/npm/man/man5/install.5 +++ b/deps/npm/man/man5/install.5 @@ -1,4 +1,4 @@ -.TH "INSTALL" "5" "May 2026" "NPM@11.16.0" "" +.TH "INSTALL" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBInstall\fR - Download and install node and npm .SS "Description" diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 index b0a8c9b4825..0202a97198c 100644 --- a/deps/npm/man/man5/npm-global.5 +++ b/deps/npm/man/man5/npm-global.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "May 2026" "NPM@11.16.0" "" +.TH "FOLDERS" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBFolders\fR - Folder structures used by npm .SS "Description" diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index 3d0c548f704..bd9d1bd5b7e 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "May 2026" "NPM@11.16.0" "" +.TH "PACKAGE.JSON" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" @@ -922,6 +922,20 @@ To make sure the package \fB@npm/foo\fR is always installed as version \fB1.0.0\ .fi .RE .P +Override values can use any specifier that npm accepts for dependencies, including an exact version, a semver range, a dist-tag, or a replacement specifier such as \fBnpm:\fR, \fBfile:\fR, or a Git URL. +.P +For example, if you only need to enforce a minimum patched release instead of one exact version, you can use a semver range: +.P +.RS 2 +.nf +{ + "overrides": { + "@npm/foo": "^1.0.0" + } +} +.fi +.RE +.P The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. This will cause \fB@npm/foo\fR to always be \fB1.0.0\fR while also making \fB@npm/bar\fR at any depth beyond \fB@npm/foo\fR also \fB1.0.0\fR: .P .RS 2 diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5 index 104ac0703d7..5f1f80576e9 100644 --- a/deps/npm/man/man5/npm-shrinkwrap-json.5 +++ b/deps/npm/man/man5/npm-shrinkwrap-json.5 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP.JSON" "5" "May 2026" "NPM@11.16.0" "" +.TH "NPM-SHRINKWRAP.JSON" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBnpm-shrinkwrap.json\fR - A publishable lockfile .SS "Description" diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index 7c5273d6344..14d449b3111 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH ".NPMRC" "5" "May 2026" "NPM@11.16.0" "" +.TH ".NPMRC" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fB.npmrc\fR - The npm config files .SS "Description" diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5 index 3d0c548f704..bd9d1bd5b7e 100644 --- a/deps/npm/man/man5/package-json.5 +++ b/deps/npm/man/man5/package-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "May 2026" "NPM@11.16.0" "" +.TH "PACKAGE.JSON" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" @@ -922,6 +922,20 @@ To make sure the package \fB@npm/foo\fR is always installed as version \fB1.0.0\ .fi .RE .P +Override values can use any specifier that npm accepts for dependencies, including an exact version, a semver range, a dist-tag, or a replacement specifier such as \fBnpm:\fR, \fBfile:\fR, or a Git URL. +.P +For example, if you only need to enforce a minimum patched release instead of one exact version, you can use a semver range: +.P +.RS 2 +.nf +{ + "overrides": { + "@npm/foo": "^1.0.0" + } +} +.fi +.RE +.P The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. This will cause \fB@npm/foo\fR to always be \fB1.0.0\fR while also making \fB@npm/bar\fR at any depth beyond \fB@npm/foo\fR also \fB1.0.0\fR: .P .RS 2 diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5 index 40742966252..0223c95c68a 100644 --- a/deps/npm/man/man5/package-lock-json.5 +++ b/deps/npm/man/man5/package-lock-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE-LOCK.JSON" "5" "May 2026" "NPM@11.16.0" "" +.TH "PACKAGE-LOCK.JSON" "5" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBpackage-lock.json\fR - A manifestation of the manifest .SS "Description" diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7 index d4b0b124d3f..eb4145df952 100644 --- a/deps/npm/man/man7/config.7 +++ b/deps/npm/man/man7/config.7 @@ -1,4 +1,4 @@ -.TH "CONFIG" "7" "May 2026" "NPM@11.16.0" "" +.TH "CONFIG" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBConfig\fR - About npm configuration .SS "Description" @@ -195,7 +195,7 @@ Type: Boolean .RE 0 .P -When running \fBnpm outdated\fR and \fBnpm ls\fR, setting \fB--all\fR will show all outdated or installed packages, rather than only those directly depended upon by the current project. +Show or act on all packages, not just the ones your project directly depends on. For \fBnpm outdated\fR and \fBnpm ls\fR this lists every outdated or installed package. For \fBnpm approve-scripts\fR and \fBnpm deny-scripts\fR it selects every package with pending install scripts. .SS "\fBallow-directory\fR" .RS 0 .IP \(bu 4 @@ -332,6 +332,11 @@ If passed to \fBnpm install\fR, will rebuild the npm tree such that only version If the requested version is a \fBdist-tag\fR and the given tag does not pass the \fB--before\fR filter, the most recent version less than or equal to that tag will be used. For example, \fBfoo@latest\fR might install \fBfoo@1.2\fR even though \fBlatest\fR is \fB2.0\fR. .P If \fBbefore\fR and \fBmin-release-age\fR are both set in the same source, \fBbefore\fR wins (an explicit absolute date overrides a relative window). Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +.P +As with \fBmin-release-age\fR, when this cutoff blocks a fix that \fBnpm audit +fix\fR would install, npm keeps the vulnerable version, warns, and exits with a non-zero code. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. .SS "\fBbin-links\fR" .RS 0 .IP \(bu 4 @@ -1018,7 +1023,9 @@ Type: "hoisted", "nested", "shallow", or "linked" .RE 0 .P -Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: (experimental) install in node_modules/.store, link in place, unhoisted. +Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. linked: install in node_modules/.store, link in place, unhoisted. +.P +We recommend that package authors use \fB--install-strategy=linked\fR during development to catch undeclared ("phantom") dependencies before publishing: the isolated layout only exposes a package's declared dependencies, so an \fBimport\fR of a package that was never added to \fBpackage.json\fR can fail instead of resolving by accident and shipping broken. See \fBCatching undeclared ("phantom") dependencies\fR \fI\(la/using-npm/developers#catching-undeclared-phantom-dependencies\(ra\fR. .SS "\fBjson\fR" .RS 0 .IP \(bu 4 @@ -1200,6 +1207,36 @@ If set, npm will build the npm tree such that only versions that were available .P This flag is a complement to \fBbefore\fR, which accepts an exact date instead of a relative number of days. The two may coexist (e.g. \fBmin-release-age\fR in your \fB.npmrc\fR is preserved when npm internally spawns a sub-process with \fB--before\fR while preparing a \fBgit:\fR or \fBgithub:\fR dependency); when both apply, \fBbefore\fR wins within a single source and across sources the standard precedence rules apply. .P +When this window stops \fBnpm audit fix\fR from installing a patched version (because the fix was published too recently), npm keeps the package at its vulnerable version, warns that the fix was blocked, and exits with a non-zero code. To install the fix, add the package to \fBmin-release-age-exclude\fR, or relax \fBmin-release-age\fR or \fBbefore\fR. +.P +Packages whose names match \fBmin-release-age-exclude\fR are exempt from this filter. +.P +This value is not exported to the environment for child processes. +.SS "\fBmin-release-age-exclude\fR" +.RS 0 +.IP \(bu 4 +Default: +.IP \(bu 4 +Type: String (can be set multiple times) +.RE 0 + +.P +A list of package names or \fBminimatch\fR glob patterns that are exempt from the \fBmin-release-age\fR (and \fBbefore\fR) filter. A matching package can always resolve to its newest version, even when a release-age window is set. +.P +For example, to apply a release-age window to third-party dependencies while letting internally maintained packages update immediately: +.P +.RS 2 +.nf +min-release-age=7 +min-release-age-exclude\[lB]\[rB]=@myorg/* +min-release-age-exclude\[lB]\[rB]=my-internal-pkg +.fi +.RE +.P +Only the named package is exempt; its own dependencies still follow the release-age policy unless they also match a pattern. Patterns match against the package name, so \fB@myorg/*\fR matches \fB@myorg/shared-utils\fR. +.P +Excluding a package does not change which registry it is fetched from. You should own your private scope on the public registry so that nobody else can publish a package with the same name. +.P This value is not exported to the environment for child processes. .SS "\fBname\fR" .RS 0 @@ -1556,7 +1593,9 @@ Defines behavior for replacing the registry host in a lockfile with the configur .P The default behavior is to replace package dist URLs from the default registry (https://registry.npmjs.org) to the configured registry. If set to "never", then use the registry value. If set to "always", then replace the registry host with the configured host every time. .P -You may also specify a bare hostname (e.g., "registry.npmjs.org"). +You may also specify a bare hostname (e.g., "registry.npmjs.org") to only replace URLs coming from that host. +.P +You may also specify a full URL including a path (e.g., "https://old-registry.example.com/npm/path"). In that case, resolved URLs whose host and path begin with that prefix will have the entire prefix replaced with the configured registry URL (host and path), without duplicating path segments. .SS "\fBsave\fR" .RS 0 .IP \(bu 4 @@ -1817,6 +1856,8 @@ Type: Boolean If \fBtrue\fR, turn the install-script policy from a warning into a hard error: any dependency with install scripts not covered by \fBallowScripts\fR will fail the install instead of running with a notice. .P Dependencies explicitly denied with \fBfalse\fR in \fBallowScripts\fR are always silently skipped; this setting only affects unreviewed entries. \fB--ignore-scripts\fR and \fB--dangerously-allow-all-scripts\fR both override this setting. +.P +Optional dependencies that cannot be installed on the current platform or engine (a non-matching \fBos\fR, \fBcpu\fR, or \fBlibc\fR) are not flagged, because their install scripts never run. .SS "\fBstrict-peer-deps\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man7/dependency-selectors.7 b/deps/npm/man/man7/dependency-selectors.7 index 4b67c2a3be5..0a9ea65ac2a 100644 --- a/deps/npm/man/man7/dependency-selectors.7 +++ b/deps/npm/man/man7/dependency-selectors.7 @@ -1,4 +1,4 @@ -.TH "SELECTORS" "7" "May 2026" "NPM@11.16.0" "" +.TH "SELECTORS" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBSelectors\fR - Dependency Selector Syntax & Querying .SS "Description" diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7 index 5b41ed26374..85cc7a5f794 100644 --- a/deps/npm/man/man7/developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,4 +1,4 @@ -.TH "DEVELOPERS" "7" "May 2026" "NPM@11.16.0" "" +.TH "DEVELOPERS" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBDevelopers\fR - Developer guide .SS "Description" @@ -184,6 +184,23 @@ npm install ../my-package to install it locally into the node_modules folder in that other place. .P Then go into the node-repl, and try using require("my-thing") to bring in your module's main module. +.SS "Catching undeclared (\"phantom\") dependencies" +.P +Under the default hoisted \fBnode_modules\fR layout, your package can \fBimport\fR a dependency it never declared and still resolve it. A transitive dependency hoisted alongside it, or your workspace root's \fBnode_modules\fR, happens to satisfy the \fBimport\fR. That undeclared ("phantom") dependency passes your own build silently, then fails for anyone who installs your package on its own. +.P +We recommend developing your package under \fB\[rs]fBinstall-strategy=linked\[rs]fR\fR \fI\(la/using-npm/config#install-strategy\(ra\fR. The isolated layout only exposes a package's \fIdeclared\fR dependencies, so an \fBimport\fR of an undeclared package fails for you during development instead of resolving by accident, shipping broken, and failing for your users: +.P +.RS 2 +.nf +npm install --install-strategy=linked +npm test +.fi +.RE +.RS 0 +.P +\fBNote:\fR This doesn't catch every case. A dependency that's still satisfied at your build by a \fBdevDependency\fR or by your workspace root's \fBnode_modules\fR can resolve fine for you and still be missing for whoever installs your package. So treat it as one check, not a guarantee, alongside auditing the dependencies your published package actually uses. +.RE 0 + .SS "Create a User Account" .P Create a user with the adduser command. It works like this: diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7 index 474becd6ff6..350348aa714 100644 --- a/deps/npm/man/man7/logging.7 +++ b/deps/npm/man/man7/logging.7 @@ -1,4 +1,4 @@ -.TH "LOGGING" "7" "May 2026" "NPM@11.16.0" "" +.TH "LOGGING" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBLogging\fR - Why, What & How we Log .SS "Description" diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7 index e0666bdf0f3..bb6cad63c51 100644 --- a/deps/npm/man/man7/orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,4 +1,4 @@ -.TH "ORGANIZATIONS" "7" "May 2026" "NPM@11.16.0" "" +.TH "ORGANIZATIONS" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBOrganizations\fR - Working with teams & organizations .SS "Description" diff --git a/deps/npm/man/man7/package-spec.7 b/deps/npm/man/man7/package-spec.7 index 76d07709632..2ec37301d54 100644 --- a/deps/npm/man/man7/package-spec.7 +++ b/deps/npm/man/man7/package-spec.7 @@ -1,4 +1,4 @@ -.TH "SPEC" "7" "May 2026" "NPM@11.16.0" "" +.TH "SPEC" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBspec\fR - Package name specifier .SS "Description" diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7 index cbfca0c6f42..49f471fd2cc 100644 --- a/deps/npm/man/man7/registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,4 +1,4 @@ -.TH "REGISTRY" "7" "May 2026" "NPM@11.16.0" "" +.TH "REGISTRY" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBRegistry\fR - The JavaScript Package Registry .SS "Description" diff --git a/deps/npm/man/man7/removal.7 b/deps/npm/man/man7/removal.7 index fa44b56539a..de875cb8e0c 100644 --- a/deps/npm/man/man7/removal.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,4 +1,4 @@ -.TH "REMOVAL" "7" "May 2026" "NPM@11.16.0" "" +.TH "REMOVAL" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBRemoval\fR - Cleaning the slate .SS "Synopsis" diff --git a/deps/npm/man/man7/scope.7 b/deps/npm/man/man7/scope.7 index 7857ede645f..793031ca011 100644 --- a/deps/npm/man/man7/scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,4 +1,4 @@ -.TH "SCOPE" "7" "May 2026" "NPM@11.16.0" "" +.TH "SCOPE" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBScope\fR - Scoped packages .SS "Description" diff --git a/deps/npm/man/man7/scripts.7 b/deps/npm/man/man7/scripts.7 index 5cfab1d64cd..368e0fd1893 100644 --- a/deps/npm/man/man7/scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,4 +1,4 @@ -.TH "SCRIPTS" "7" "May 2026" "NPM@11.16.0" "" +.TH "SCRIPTS" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBScripts\fR - How npm handles the "scripts" field .SS "Description" diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7 index be7a22047d9..5dfa00e6492 100644 --- a/deps/npm/man/man7/workspaces.7 +++ b/deps/npm/man/man7/workspaces.7 @@ -1,4 +1,4 @@ -.TH "WORKSPACES" "7" "May 2026" "NPM@11.16.0" "" +.TH "WORKSPACES" "7" "June 2026" "NPM@11.18.0" "" .SH "NAME" \fBWorkspaces\fR - Working with workspaces .SS "Description" diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index f16844ea73d..63157b9a550 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -24,6 +24,7 @@ const PlaceDep = require('../place-dep.js') const debug = require('../debug.js') const fromPath = require('../from-path.js') const calcDepFlags = require('../calc-dep-flags.js') +const { isReleaseAgeExcluded, trustedSpecName } = require('../release-age-exclude.js') const Shrinkwrap = require('../shrinkwrap.js') const { defaultLockfileVersion } = Shrinkwrap const Node = require('../node.js') @@ -96,6 +97,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { #loadFailures = new Set() #manifests = new Map() #mutateTree = false + #requestedTreeMutation = false // a map of each module in a peer set to the thing that depended on // that set of peers in the first place. Use a WeakMap so that we // don't hold onto references for nodes that are garbage collected. @@ -260,12 +262,13 @@ module.exports = cls => class IdealTreeBuilder extends cls { // set if we add anything, but also set here if we know we'll make // changes and thus have to maybe prune later. - this.#mutateTree = !!( + this.#requestedTreeMutation = !!( options.add || options.rm || update.all || update.names.length ) + this.#mutateTree = this.#requestedTreeMutation } // load the initial tree, either the virtualTree from a shrinkwrap, @@ -343,7 +346,9 @@ module.exports = cls => class IdealTreeBuilder extends cls { filter: node => node, visit: node => { for (const edge of node.edgesOut.values()) { - const skipPeerOptional = edge.type === 'peerOptional' && this.options.save === false + const skipPeerOptional = edge.type === 'peerOptional' && + this.options.save === false && + !this.#requestedTreeMutation if (!skipPeerOptional && (!edge.to || !edge.valid)) { this.#depsQueue.push(node) break // no need to continue the loop after the first hit @@ -533,7 +538,11 @@ module.exports = cls => class IdealTreeBuilder extends cls { // look up the names of file/directory/git specs if (!spec.name || isTag) { const _isRoot = tree.isProjectRoot || tree.isWorkspace - const mani = await pacote.manifest(spec, { ...this.options, _isRoot }) + const mani = await pacote.manifest(spec, { + ...this.options, + _isRoot, + before: this.#releaseAgeBefore(spec), + }) if (isTag) { // translate tag to a version spec = npa(`${mani.name}@${mani.version}`) @@ -574,6 +583,17 @@ module.exports = cls => class IdealTreeBuilder extends cls { // and leaving the user subject to getting it overwritten later anyway. async #queueVulnDependents (options) { for (const vuln of this.auditReport.values()) { + // A fix is available in-range but a release-age window blocks the patched + // version, so audit fix leaves this package at a vulnerable version. + if (vuln.fixBlockedByReleaseAge) { + const { version, before } = vuln.fixBlockedByReleaseAge + const cutoff = new Date(before).toISOString().slice(0, 10) + log.warn('audit', `A fix for ${vuln.name} is available (${vuln.name}@${version}) ` + + `but was published after the configured release-age cutoff (${cutoff}), so ` + + `${vuln.name} was left at a vulnerable version.\n` + + `To install it, add "${vuln.name}" to min-release-age-exclude, or relax ` + + 'min-release-age or before.') + } for (const node of vuln.nodes) { const bundler = node.getBundler() @@ -777,6 +797,7 @@ This is a one-time fix-up, please be patient... resolved: resolved, integrity: integrity, fullMetadata: false, + before: this.#releaseAgeBefore(spec), }) node.package = { ...mani, _id: `${mani.name}@${mani.version}` } } catch (er) { @@ -875,7 +896,7 @@ This is a one-time fix-up, please be patient... if (hasShrinkwrap) { await new Arborist({ ...this.options, path }) - .loadVirtual({ root: node }) + .loadVirtual({ root: node, subtreeOnly: true }) } if (hasBundle) { @@ -1030,9 +1051,16 @@ This is a one-time fix-up, please be patient... } const { from, valid, peerConflicted } = edgeIn if (!peerConflicted && !valid) { - if (this.#depsSeen.has(from) && this.options.save) { - // Re-queue already-processed nodes when a newly placed dep creates an invalid edge during npm install (save=true). - // This handles the case where a peerOptional dep was valid (missing) when the node was first processed, but becomes invalid when the dep is later placed by another path with a version that doesn't satisfy the peer spec. + if (this.#depsSeen.has(from) && + (this.options.save || + (this.options.save === false && this.#requestedTreeMutation))) { + // Re-queue already-processed nodes when a newly placed dep + // creates an invalid edge during npm install or another + // lockfile-mutating operation. This handles the case where a + // peerOptional dep was valid (missing) when the node was + // first processed, but becomes invalid when the dep is later + // placed by another path with a version that doesn't satisfy + // the peer spec. // See npm/cli#8726. this.#depsSeen.delete(from) this.#depsQueue.push(from) @@ -1243,11 +1271,16 @@ This is a one-time fix-up, please be patient... continue } - // If the edge has an error, there's a problem, unless it's peerOptional and we're not saving (e.g. npm ci), in which case we trust the lockfile and skip re-resolution. - // When saving (npm install), peerOptional invalid edges ARE treated as problems so the lockfile gets fixed. + // If the edge has an error, there's a problem, unless it's peerOptional + // and we're not saving or otherwise mutating (e.g. npm ci), in which + // case we trust the lockfile and skip re-resolution. When saving (npm + // install) or updating, peerOptional invalid edges ARE treated as + // problems so the lockfile gets fixed. // See npm/cli#8726. if (!edge.valid) { - if (edge.type !== 'peerOptional' || this.options.save !== false) { + if (edge.type !== 'peerOptional' || + this.options.save !== false || + this.#requestedTreeMutation) { problems.push(edge) } continue @@ -1279,6 +1312,19 @@ This is a one-time fix-up, please be patient... return problems } + // The effective `before` filter for a package, applying `min-release-age-exclude`. + // Returns null (no age filter) for an exempted package, otherwise the + // configured `before`. The exemption is keyed on the spec's trusted registry + // identity (alias targets are unwrapped) so an `npm:` alias key cannot disable + // the filter for the package it actually resolves to. + #releaseAgeBefore (spec) { + const { before, minReleaseAgeExclude } = this.options + if (!before) { + return before + } + return isReleaseAgeExcluded(trustedSpecName(spec), minReleaseAgeExclude) ? null : before + } + async #fetchManifest (spec, parent, edge) { // Enforce allow-* gates before consulting the manifest cache so a cached entry from a different edge cannot bypass the policy. this.#checkAllow(spec, edge) @@ -1286,6 +1332,7 @@ This is a one-time fix-up, please be patient... ...this.options, avoid: this.#avoidRange(spec.name), fullMetadata: true, + before: this.#releaseAgeBefore(spec), _isRoot: !!(edge?.from?.isProjectRoot || edge?.from?.isWorkspace), } // get the intended spec and stored metadata from yarn.lock file, @@ -1548,6 +1595,10 @@ This is a one-time fix-up, please be patient... !link.target.parent && !link.target.fsParent || unseenLink) { + // Forward the link's overrides before its subtree resolves, so a root override reaches a transitive dep across the link boundary (npm/cli#9659). + if (link.overrides) { + link.target.updateOverridesEdgeInAdded(link.overrides) + } this.addTracker('idealTree', link.target.name, link.target.location) this.#depsQueue.push(link.target) } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js index 14f432ca977..a07c55e3f28 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js @@ -4,6 +4,7 @@ const { join } = require('node:path') const { depth } = require('treeverse') const crypto = require('node:crypto') const { IsolatedNode, IsolatedLink } = require('../isolated-classes.js') +const nameFromFolder = require('@npmcli/name-from-folder') // generate short hash key based on the dependency tree starting at this node const getKey = (startNode) => { @@ -39,9 +40,12 @@ module.exports = cls => class IsolatedReifier extends cls { #processedEdges = new Set() #workspaceProxies = new Map() - #generateChild (node, location, pkg, isInStore, root) { + #generateChild (node, location, pkg, isInStore, root, inBundle = false) { const newChild = new IsolatedNode({ isInStore, + inBundle, + isRegistryDependency: node.isRegistryDependency, + isRootDependency: node.isRootDependency, location, name: node.packageName || node.name, optional: node.optional, @@ -151,11 +155,14 @@ module.exports = cls => class IsolatedReifier extends cls { this.#externalProxies.set(node, result) await this.#assignCommonProperties(node, result, !node.hasShrinkwrap) if (node.hasShrinkwrap) { + // strip any path traversal from package.json name fields before they hit path.join below + /* istanbul ignore next - packageName is always set for real packages */ + const safeName = nameFromFolder(node.packageName || node.path) const dir = join( node.root.path, 'node_modules', '.store', - `${node.packageName}@${node.version}` + `${safeName}@${node.version}` ) mkdirSync(dir, { recursive: true }) // TODO this approach feels wrong and shouldn't be necessary for shrinkwraps @@ -189,6 +196,13 @@ module.exports = cls => class IsolatedReifier extends cls { result.optional = node.optional result.resolved = node.resolved result.version = node.version + // Carry the source node's registry-dependency flag so the store node retains it. + // IsolatedNode has no edges to recompute it from, and reify's registry-tarball allow-remote exemption depends on it. + result.isRegistryDependency = node.isRegistryDependency + // Same reasoning for allow-remote=root: the store node has no edgesIn, so capture from the source node whether it satisfies a valid edge from the project root or a workspace. + result.isRootDependency = [...node.edgesIn].some(e => + e.valid && (e.from?.isProjectRoot || e.from?.isWorkspace) + ) return result } @@ -198,7 +212,8 @@ module.exports = cls => class IsolatedReifier extends cls { result.id = this.counter++ /* istanbul ignore next - packageName is always set for real packages */ result.name = result.isWorkspace ? (node.packageName || node.name) : node.name - result.packageName = node.packageName || node.name + // strip any path traversal from package.json name fields before they hit path.join below + result.packageName = nameFromFolder(node.packageName || node.path) result.package = { ...node.package } result.package.bundleDependencies = undefined @@ -251,8 +266,26 @@ module.exports = cls => class IsolatedReifier extends cls { } // local `file:` deps (non-workspace fsChildren) should be treated as local dependencies, not external, so they get symlinked directly instead of being extracted into the store. - const isLocal = (n) => n.isWorkspace || node.fsChildren?.has(n) + // A file: dep surfaces as a Link edge whose resolved spec starts with file:; detect it from the edge so the target is treated as local even when it is absent from idealTree.fsChildren (a workspace consumer, or a target outside the repo root via npm link). + const fileLinkTargets = new Set(edges.filter(e => e.to?.isLink && e.to.resolved?.startsWith('file:')).map(e => e.to.target)) + const isLocal = (n) => n.isWorkspace || node.fsChildren?.has(n) || fileLinkTargets.has(n) const optionalDeps = edges.filter(edge => edge.optional).map(edge => edge.to.target) + + // Optional peers declared only in peerDependenciesMeta (e.g. `@types/react`) have no edge, so the materialization above misses them. + // Resolve each from the tree and link it; if nobody provides it, node.resolve finds nothing and it stays omitted. + const peerMeta = node.package.peerDependenciesMeta + if (peerMeta) { + const resolvedNames = new Set([...nonOptionalDeps, ...optionalDeps].map(n => n.name)) + for (const peerName in peerMeta) { + if (!peerMeta[peerName]?.optional || resolvedNames.has(peerName)) { + continue + } + const resolved = node.resolve(peerName)?.target + if (resolved && resolved !== node && !resolved.inert && !isLocal(resolved)) { + optionalDeps.push(resolved) + } + } + } result.localDependencies = await Promise.all(nonOptionalDeps.filter(isLocal).map(n => this.#workspaceProxy(n))) result.externalDependencies = await Promise.all(nonOptionalDeps.filter(n => !isLocal(n) && !n.inert).map(n => this.#externalProxy(n))) result.externalOptionalDependencies = await Promise.all(optionalDeps.filter(n => !n.inert).map(n => this.#externalProxy(n))) @@ -367,7 +400,7 @@ module.exports = cls => class IsolatedReifier extends cls { }) bundledTree.nodes.forEach(node => { - this.#generateChild(node, node.location, node.pkg, false, root) + this.#generateChild(node, node.location, node.pkg, false, root, true) }) bundledTree.edges.forEach(edge => { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js index 2356227a5ba..2158f6d32ae 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js @@ -1,6 +1,6 @@ // mix-in implementing the loadActual method -const { dirname, join, normalize, relative, resolve } = require('node:path') +const { dirname, join, normalize, relative, resolve, sep } = require('node:path') const PackageJson = require('@npmcli/package-json') const { readdirScoped } = require('@npmcli/fs') @@ -70,6 +70,7 @@ module.exports = cls => class ActualLoader extends cls { // only reset root flags if we're not re-rooting, // otherwise leave as-is calcDepFlags(tree, !options.root) + this.#repropagateOverrides() this.actualTree = treeCheck(tree) return this.actualTree }) @@ -141,6 +142,7 @@ module.exports = cls => class ActualLoader extends cls { root: this.#actualTree, }) await this[_setWorkspaces](this.#actualTree) + this.#linkActualWorkspaces() this.#transplant(root) return this.#actualTree @@ -173,6 +175,8 @@ module.exports = cls => class ActualLoader extends cls { await Promise.all(promises) } + this.#linkActualWorkspaces() + if (!ignoreMissing) { await this.#findMissingEdges() } @@ -211,6 +215,48 @@ module.exports = cls => class ActualLoader extends cls { return this.#actualTree } + // Under the linked (isolated) strategy, workspaces the root does not depend on are not symlinked into the root node_modules, so neither the on-disk scan nor the hidden lockfile gives the root's workspace edges a node_modules/ link to resolve to. + // Synthesize those links from the authoritative workspaces map so npm ls and npm query surface the workspaces, matching hoisted and the logical package-lock. + #linkActualWorkspaces () { + const root = this.#actualTree + if (this.options.installStrategy !== 'linked' || !root.workspaces) { + return + } + // Declared workspaces ARE symlinked at root node_modules under linked, so a missing link there is a real problem that must surface as UNMET. + // Only undeclared workspaces are intentionally absent from root node_modules and need a synthesized link so their root edges resolve. + const pkg = root.package + const declared = new Set(Object.keys(Object.assign({}, + pkg.dependencies, + pkg.devDependencies, + pkg.optionalDependencies, + pkg.peerDependencies + ))) + // index loaded workspace targets by both path and realpath, so a workspace reached through a symlinked dir still matches + const byLoc = new Map() + for (const node of root.fsChildren) { + byLoc.set(node.path, node) + byLoc.set(node.realpath, node) + } + for (const [name, path] of root.workspaces.entries()) { + // declared workspaces, and any name already a root child, resolve their edge without a synthesized link + if (declared.has(name) || root.children.has(name)) { + continue + } + const target = byLoc.get(path) + if (target) { + // eslint-disable-next-line no-new + new Link({ + name, + path: resolve(root.path, 'node_modules', name), + realpath: target.realpath, + target, + parent: root, + root, + }) + } + } + } + #transplant (root) { if (!root || root === this.#actualTree) { return @@ -263,6 +309,9 @@ module.exports = cls => class ActualLoader extends cls { parent, root, loadOverrides, + // A package physically located in the linked strategy's store is a transitive dependency, not a real tree top, so it must not load its devDependencies. + // Never flag the loaded root itself, even if its own path happens to sit under a .store directory. + isInStore: path !== this.path && real.includes(`${sep}node_modules${sep}.store${sep}`), } try { @@ -352,6 +401,18 @@ module.exports = cls => class ActualLoader extends cls { } } + // Re-forward overrides through links once all edges are resolved, since a Link may forward before its subtree resolves and miss a transitive match (npm/cli#9619, #9659). + #repropagateOverrides () { + if (!this.#actualTree.overrides) { + return + } + for (const node of this.#actualTree.inventory.values()) { + if (node.isLink && node.overrides) { + node.recalculateOutEdgesOverrides() + } + } + } + async #findMissingEdges () { // try to resolve any missing edges by walking up the directory tree, // checking for the package in each node_modules folder. stop at the @@ -368,9 +429,10 @@ module.exports = cls => class ActualLoader extends cls { const depPromises = [] for (const [name, edge] of node.edgesOut.entries()) { - const notMissing = !edge.missing && - !(edge.to && (edge.to.dummy || edge.to.parent !== node)) - if (notMissing) { + // An unresolved optional edge reports missing === false, so check the target directly. + // Otherwise an installed optional dep that lives only as a store sibling is never loaded. + const resolved = edge.to && !edge.to.dummy && edge.to.parent === node + if (resolved) { continue } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js index e5a96a0b5f0..13626fc5ded 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js @@ -1,4 +1,4 @@ -const { resolve } = require('node:path') +const { isAbsolute, resolve } = require('node:path') // mixin providing the loadVirtual method const mapWorkspaces = require('@npmcli/map-workspaces') const PackageJson = require('@npmcli/package-json') @@ -17,6 +17,8 @@ const setWorkspaces = Symbol.for('setWorkspaces') module.exports = cls => class VirtualLoader extends cls { #rootOptionProvided + // when true, lockfile entries must stay inside `this.path` + #subtreeOnly = false // public method async loadVirtual (options = {}) { @@ -28,6 +30,8 @@ module.exports = cls => class VirtualLoader extends cls { // XXX: deprecate separate reify() options object. options = { ...this.options, ...options } + this.#subtreeOnly = !!options.subtreeOnly + if (options.root && options.root.meta) { await this.#loadFromShrinkwrap(options.root.meta, options.root) return treeCheck(this.virtualTree) @@ -166,12 +170,40 @@ module.exports = cls => class VirtualLoader extends cls { } } + // throw if the resolved path is outside `base`, only in subtreeOnly mode + #assertContained (base, resolvedPath, location) { + if (!this.#subtreeOnly) { + return + } + if (isAbsolute(location)) { + throw Object.assign( + new Error(`invalid lockfile entry: "${location}" must be a relative location`), + { code: 'EINVALIDLOCATION', location, base } + ) + } + const rel = relpath(base, resolvedPath) + if ( + rel === '..' || + rel.startsWith('../') || + isAbsolute(rel) || + // non-root key that collapses back to base (e.g. 'node_modules/..') + (rel === '' && location !== '') + ) { + throw Object.assign( + new Error(`invalid lockfile entry: "${location}" resolves outside of "${base}"`), + { code: 'EINVALIDLOCATION', location, base, resolvedPath } + ) + } + } + // links is the set of metadata, and nodes is the map of non-Link nodes // Set the targets to nodes in the set, if we have them (we might not) // XXX build-ideal-tree also has a #resolveLinks, is there overlap? async #resolveLinks (links, nodes) { for (const [location, meta] of links.entries()) { const targetPath = resolve(this.path, meta.resolved) + // check before nodes.get so we surface EINVALIDLOCATION instead of EMISSINGTARGET + this.#assertContained(this.path, targetPath, meta.resolved || location) const targetLoc = relpath(this.path, targetPath) const target = nodes.get(targetLoc) @@ -230,6 +262,7 @@ To fix: #loadNode (location, sw, loadOverrides) { const p = this.virtualTree ? this.virtualTree.realpath : this.path const path = resolve(p, location) + this.#assertContained(p, path, location) // shrinkwrap doesn't include package name unless necessary if (!sw.name) { sw.name = nameFromFolder(path) @@ -259,6 +292,7 @@ To fix: #loadLink (location, targetLoc, target) { const path = resolve(this.path, location) + this.#assertContained(this.path, path, location) const link = new Link({ installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js index e70a2186c29..a99d328f5d2 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js @@ -11,7 +11,7 @@ const { depth: dfwalk } = require('treeverse') const { isNodeGypPackage, defaultGypInstallScript } = require('@npmcli/node-gyp') const { promiseRetry } = require('@gar/promise-retry') const { log, time } = require('proc-log') -const { resolve } = require('node:path') +const { resolve, delimiter } = require('node:path') const { isScriptAllowed } = require('../script-allowed.js') const boolEnv = b => b ? '1' : '' @@ -199,10 +199,21 @@ module.exports = cls => class Builder extends cls { const { package: { bin, scripts = {} } } = node.target const { preinstall, install, postinstall, prepare } = scripts const tests = { bin, preinstall, install, postinstall, prepare } + // A denied package (allowScripts resolves to `false`) still gets its + // bins linked; only its lifecycle scripts are skipped, matching + // --ignore-scripts (npm/cli#9681). --dangerously-allow-all-scripts + // bypasses the gate. + const scriptsDenied = + !this.options.dangerouslyAllowAllScripts && + isScriptAllowed(node, this.options.allowScripts) === false for (const [key, has] of Object.entries(tests)) { - if (has) { - this.#queues[key].push(node) + if (!has) { + continue } + if (key !== 'bin' && scriptsDenied) { + continue + } + this.#queues[key].push(node) } } timeEnd() @@ -226,18 +237,6 @@ module.exports = cls => class Builder extends cls { return } - // Phase 1 allowScripts gate: a `false` verdict from the policy matcher - // means the user explicitly denied install scripts for this node, so skip - // it. `true` and `null` (unreviewed) both fall through to the existing - // detection logic — unreviewed nodes still run their scripts in Phase 1 - // and are surfaced via the post-reify advisory warning. The global - // --ignore-scripts kill switch in #build() still takes precedence, and - // --dangerously-allow-all-scripts bypasses this gate entirely. - if (!this.options.dangerouslyAllowAllScripts && - isScriptAllowed(node, this.options.allowScripts) === false) { - return - } - if (this.#oldMeta === null) { const { root: { meta } } = node this.#oldMeta = meta && meta.loadedFromDisk && @@ -301,6 +300,7 @@ module.exports = cls => class Builder extends cls { await promiseCallLimit(queue.map(node => async () => { const { path, + name, integrity, resolved, optional, @@ -309,6 +309,7 @@ module.exports = cls => class Builder extends cls { devOptional, package: pkg, location, + isInStore, } = node.target // skip any that we know we'll be deleting @@ -330,6 +331,12 @@ module.exports = cls => class Builder extends cls { npm_package_dev_optional: boolEnv(devOptional && !dev && !optional), } + // In the linked strategy a store package's dependencies are symlinked siblings in its store node_modules. + // A separate bin invoked by the script (e.g. napi-postinstall) resolves modules from its own realpath in the store and cannot see those deps, so expose them via NODE_PATH. + if (isInStore) { + const storeNodeModules = resolve(path, ...name.split('/').map(() => '..')) + env.NODE_PATH = [storeNodeModules, process.env.NODE_PATH].filter(Boolean).join(delimiter) + } const runOpts = { event, path, diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js index 38fb4e37589..db5171ff736 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js @@ -11,7 +11,7 @@ const { callLimit: promiseCallLimit } = require('promise-call-limit') const { depth: dfwalk } = require('treeverse') const { dirname, resolve, relative, join, sep } = require('node:path') const { log, time } = require('proc-log') -const { existsSync } = require('node:fs') +const { existsSync, realpathSync } = require('node:fs') const { lstat, mkdir, readdir, readlink, rm, symlink } = require('node:fs/promises') const { moveFile } = require('@npmcli/fs') const { subset, intersects } = require('semver') @@ -26,7 +26,8 @@ const optionalSet = require('../optional-set.js') const relpath = require('../relpath.js') const retirePath = require('../retire-path.js') const treeCheck = require('../tree-check.js') -const { defaultLockfileVersion } = require('../shrinkwrap.js') +const Shrinkwrap = require('../shrinkwrap.js') +const { defaultLockfileVersion } = Shrinkwrap const { saveTypeMap, hasSubKey } = require('../add-rm-pkg-deps.js') const { IsolatedNode, IsolatedLink } = require('../isolated-classes.js') @@ -77,6 +78,9 @@ module.exports = cls => class Reifier extends cls { #sparseTreeDirs = new Set() #sparseTreeRoots = new Set() #linkedActualForDiff = null + // Under the linked strategy the audit runs against this non-isolated ideal tree. + // The isolated tree's inventory has no queryable indexes and its edges route through symlinks, so auditing it reports no vulnerabilities. + #linkedIdealForAudit = null constructor (options) { super(options) @@ -86,7 +90,9 @@ module.exports = cls => class Reifier extends cls { // public method async reify (options = {}) { - const linked = (options.installStrategy || this.options.installStrategy) === 'linked' + // Global installs are normalized to the shallow strategy in the constructor; honor that here so a per-call installStrategy:'linked' can't re-engage the unsupported linked path. + const linked = !this.options.global && + (options.installStrategy || this.options.installStrategy) === 'linked' if (this.options.packageLockOnly && this.options.global) { const er = new Error('cannot generate lockfile for global packages') @@ -112,32 +118,50 @@ module.exports = cls => class Reifier extends cls { await this[_loadTrees](options) const oldTree = this.idealTree + // Kept to serialize the hidden lockfile from the on-disk .store/symlink layout. + let isolatedTree = null if (linked) { // swap out the tree with the isolated tree // this is currently technical debt which will be resolved in a refactor // of Node/Link trees - log.warn('reify', 'The "linked" install strategy is EXPERIMENTAL and may contain bugs.') this.idealTree = await this.createIsolatedTree() + isolatedTree = this.idealTree if (this.actualTree) { this.#linkedActualForDiff = this.#buildLinkedActualForDiff( this.idealTree, this.actualTree ) } + // Keep the non-isolated tree so the quick audit can run against it. + this.#linkedIdealForAudit = oldTree } - await this[_diffTrees]() - await this.#reifyPackages() - if (linked) { - // The sweep mutates node_modules on disk, so skip it for dry runs and lockfile-only installs (those modes also short-circuit #reifyPackages). - // The sweep itself scopes to in-filter workspaces when a filter is active, so it's safe to run for filtered installs too. - if (!this.options.dryRun && !this.options.packageLockOnly) { - await this.#cleanOrphanedStoreEntries() + try { + await this[_diffTrees]() + await this.#reifyPackages() + if (linked) { + // The sweep mutates node_modules on disk, so skip it for dry runs and lockfile-only installs (those modes also short-circuit #reifyPackages). + // The sweep itself scopes to in-filter workspaces when a filter is active, so it's safe to run for filtered installs too. + if (!this.options.dryRun && !this.options.packageLockOnly) { + await this.#cleanOrphanedStoreEntries() + } + } else if (!this.options.dryRun && !this.options.packageLockOnly) { + // The .store directory is exclusively a linked-strategy artifact, and load-actual ignores dot-directories, so the diff never sees it. + // Remove it here when switching away from linked so it does not linger under hoisted/nested. + // Only do this for a full-project install: a workspace-filtered or --workspaces=false install may leave out-of-scope workspaces with links still pointing into the store. + const filtered = this.options.workspaces.length > 0 || !this.options.workspacesEnabled + if (!filtered) { + await this.#removeStaleStoreDir() + } + } + } finally { + // Restore the non-isolated tree so the lockfile is preserved and a reused Arborist never sees the isolated tree, even if reify throws. + if (linked) { + this.idealTree = oldTree } - // swap back in the idealTree - // so that the lockfile is preserved - this.idealTree = oldTree + // The quick audit has captured its tree synchronously by now, so drop the stashed references even on throw. + this.#linkedIdealForAudit = null + this.#linkedActualForDiff = null } await this[_saveIdealTree](options) - this.#linkedActualForDiff = null // clean inert for (const node of this.idealTree.inventory.values()) { if (node.inert) { @@ -230,17 +254,24 @@ module.exports = cls => class Reifier extends cls { calcDepFlags(this.idealTree) } - // save the ideal's meta as a hidden lockfile after we actualize it - this.idealTree.meta.filename = - this.idealTree.realpath + '/node_modules/.package-lock.json' - this.idealTree.meta.hiddenLockfile = true - this.idealTree.meta.lockfileVersion = defaultLockfileVersion + // save the ideal's meta as a hidden lockfile after we actualize it. + // Under linked the logical tree is the hoisted layout, so the hidden lockfile is serialized from the isolated tree instead. + if (!linked) { + this.idealTree.meta.filename = + this.idealTree.realpath + '/node_modules/.package-lock.json' + this.idealTree.meta.hiddenLockfile = true + this.idealTree.meta.lockfileVersion = defaultLockfileVersion + } this.actualTree = this.idealTree this.idealTree = null if (!this.options.global && !this.options.dryRun) { - await this.actualTree.meta.save() + if (linked) { + await this.#saveLinkedHiddenLockfile(isolatedTree) + } else { + await this.actualTree.meta.save() + } const ignoreScripts = !!this.options.ignoreScripts // if we aren't doing a dry run or ignoring scripts and we actually made changes to the dep // tree, then run the dependencies scripts @@ -452,7 +483,10 @@ module.exports = cls => class Reifier extends cls { } if (includeRootDeps) { // add all non-workspace nodes to filterNodes - for (const tree of [this.idealTree, this.actualTree]) { + // Skip the actual tree under the linked diff wrapper: its edge targets have root===actualTree, not the wrapper, which trips Diff.calculate's filterNode guard. + // The ideal-side targets alone scope the diff. + const trees = this.#linkedActualForDiff ? [this.idealTree] : [this.idealTree, this.actualTree] + for (const tree of trees) { for (const { type, to } of tree.edgesOut.values()) { if (type !== 'workspace' && to) { filterNodes.push(to) @@ -642,7 +676,7 @@ module.exports = cls => class Reifier extends cls { .then(nodes => promiseAllRejectLate(nodes.map(node => new Arborist({ ...this.options, path: node.path, - }).loadVirtual({ root: node })))) + }).loadVirtual({ root: node, subtreeOnly: true })))) // reload the diff and sparse tree because the ideal tree changed .then(() => this[_diffTrees]()) .then(() => this[_createSparseTree]()) @@ -744,7 +778,8 @@ module.exports = cls => class Reifier extends cls { integrity: node.integrity, // A node counts as "root" for allow-* enforcement if it satisfies at least one valid dependency edge declared by the project root or a workspace. // node.parent is unsafe here: after hoisting, transitive packages can have the project root as their tree parent. - _isRoot: [...node.edgesIn].some(e => + // In the linked strategy the store node has no edgesIn, so isolated-reifier precomputes isRootDependency from the source node's edges. + _isRoot: node.isRootDependency || [...node.edgesIn].some(e => e.valid && (e.from?.isProjectRoot || e.from?.isWorkspace) ), // pacote's npa re-parses our `name@URL` spec as type=remote, so allowRemote would mis-fire on registry tarballs. @@ -822,6 +857,47 @@ module.exports = cls => class Reifier extends cls { return join(filePath) } + // Serialize the hidden lockfile from the isolated tree, which mirrors the on-disk .store/symlink layout. + // Its children are every materialized node_modules entry: store package dirs and all symlinks. + async #saveLinkedHiddenLockfile (isolatedTree) { + const path = isolatedTree.realpath + const meta = new Shrinkwrap({ + path, + hiddenLockfile: true, + lockfileVersion: defaultLockfileVersion, + resolveOptions: this.options, + }) + meta.reset() + meta.filename = resolve(path, 'node_modules/.package-lock.json') + const storeRe = /^(.*\/\.store\/.+?)\/node_modules\// + const containers = new Set() + const nodes = new Set() + for (const node of isolatedTree.children.values()) { + // Tree-only undeclared workspace self-links aren't on disk. + if (node.isUndeclaredWorkspaceLink) { + continue + } + nodes.add(node) + // Record the enclosing .store/ dir so loadVirtual can resolve a store package's sibling deps. + // node.location uses the platform separator; lockfile keys are posix. + const m = node.location.replace(/\\/g, '/').match(storeRe) + if (m) { + containers.add(m[1]) + } + } + // Workspace dirs hold their own dep symlinks; record them so the cache can validate those subtrees. + for (const ws of isolatedTree.fsChildren) { + nodes.add(ws) + } + for (const node of nodes) { + meta.add(node) + } + for (const loc of containers) { + meta.data.packages[loc] = {} + } + await meta.save() + } + // Build a flat actual tree wrapper for linked installs so the diff can correctly match store entries that already exist on disk. // The proxy tree from createIsolatedTree() is flat (all children on root), but loadActual() produces a nested tree where store entries are deep link targets. // This wrapper surfaces them at the root level for comparison. @@ -840,6 +916,10 @@ module.exports = cls => class Reifier extends cls { if (child.isLink && child.resolved?.startsWith('file:.store/') && !existsSync(child.realpath)) { continue } + // Skip a link whose on-disk target is a valid-but-wrong store key (e.g. an interrupted update), so the diff repoints it via ADD. + if (child.isLink && this.#linkTargetMismatch(child)) { + continue + } let entry if (child.isLink) { entry = new IsolatedLink(child) @@ -879,19 +959,28 @@ module.exports = cls => class Reifier extends cls { return wrapper } + // True when the link's on-disk target resolves to a different path than its ideal target. + // The caller only invokes this once both paths exist, so realpathSync won't throw. + #linkTargetMismatch (child) { + return realpathSync(child.path) !== realpathSync(child.realpath) + } + // When extracting a registry-resolved package, the spec we hand to pacote is name@URL. // pacote re-parses that with npa and gets spec.type === 'remote', so without an override the allow-remote gate would fire on every registry tarball (both =none and =root mis-fire). - // Returns true only when we are confident this is a registry-mediated install: the node's inbound edges must all be registry-typed (no exotic spec smuggled the URL in) AND the resolved URL's host must match the registry npm-registry-fetch selected for this spec, so a tampered lockfile pointing at an attacker host still hits the gate. + // Returns true only when we are confident this is a registry-mediated install. #isRegistryResolvedTarball (node) { if (!node.resolved || !node.isRegistryDependency) { return false } try { - // Hostnames are case-insensitive; lowercase both sides for safety even though WHATWG URL already normalizes. - const resolvedHost = new URL(node.resolved).hostname.toLowerCase() + // Match the effective fetch URL, not the raw lockfile value. + // #registryResolved applies replace-registry-host, rewriting a public-registry pin to the configured proxy/mirror so it matches. + const resolvedURL = new URL(this.#registryResolved(node.resolved)) // pickRegistry only consults spec.scope, so a bare-name (tag) parse is sufficient and avoids a node.version dependency. - const registryHost = new URL(pickRegistry(npa(node.name), this.options)).hostname.toLowerCase() - return resolvedHost === registryHost + const registry = new URL(pickRegistry(npa(node.name), this.options)) + const registryPath = registry.pathname.replace(/\/?$/, '/') + return resolvedURL.origin === registry.origin && + (registryPath === '/' || resolvedURL.pathname.startsWith(registryPath)) } catch { return false } @@ -908,36 +997,42 @@ module.exports = cls => class Reifier extends cls { // the default reg as the magical animal that it has been. try { const resolvedURL = hgi.parseUrl(resolved) + const registryURL = new URL(this.registry) + const registryPath = registryURL.pathname.replace(/\/$/, '') - if ((this.options.replaceRegistryHost === resolvedURL.hostname) || - this.options.replaceRegistryHost === 'always') { - const registryURL = new URL(this.registry) + let matchURL = null + try { + matchURL = new URL(this.options.replaceRegistryHost) + } catch { + // keep matchURL null + } - // Replace the host with the registry host while keeping the path intact - resolvedURL.hostname = registryURL.hostname - resolvedURL.port = registryURL.port - resolvedURL.protocol = registryURL.protocol + const matchHost = matchURL?.hostname ?? this.options.replaceRegistryHost + const matchPath = matchURL?.pathname.replace(/\/$/, '') ?? null + const hasPathPrefix = (pathname, prefix) => + pathname === prefix || pathname.startsWith(`${prefix}/`) - // Make sure we don't double-include the path if it's already there - const registryPath = registryURL.pathname.replace(/\/$/, '') + const hostMatches = this.options.replaceRegistryHost === 'always' || matchHost === resolvedURL.hostname + const pathMatches = !matchPath || hasPathPrefix(resolvedURL.pathname, matchPath) - if (registryPath && registryPath !== '/') { - // Check if the resolved pathname already starts with the registry path - // We need to ensure it's a proper path prefix, not just a string prefix - // e.g., registry path '/npm' should not match '/npm-run-path' - const hasRegistryPath = resolvedURL.pathname === registryPath || - resolvedURL.pathname.startsWith(registryPath + '/') + if (!hostMatches || !pathMatches) { + return resolved + } - if (!hasRegistryPath) { - // Since hostname is changed, we need to ensure the registry path is included - resolvedURL.pathname = registryPath + resolvedURL.pathname - } - } + resolvedURL.protocol = registryURL.protocol + resolvedURL.hostname = registryURL.hostname + resolvedURL.port = registryURL.port - return resolvedURL.toString() + if (matchPath) { + // full-URL prefix: swap old path prefix for the registry path + resolvedURL.pathname = registryPath + resolvedURL.pathname.slice(matchPath.length) + } else if (registryPath && !hasPathPrefix(resolvedURL.pathname, registryPath)) { + // host-only: prepend registry path if not already present + resolvedURL.pathname = registryPath + resolvedURL.pathname } - return resolved - } catch (e) { + + return resolvedURL.toString() + } catch { // if we could not parse the url at all then returning nothing // here means it will get removed from the tree in the next step return undefined @@ -1148,7 +1243,8 @@ module.exports = cls => class Reifier extends cls { // with the reification, and be resolved at a later time. const timeEnd = time.start('reify:audit') const options = { ...this.options } - const tree = this.idealTree + // Under the linked strategy idealTree is the isolated tree, which the audit cannot traverse; audit the non-isolated tree instead. + const tree = this.#linkedIdealForAudit || this.idealTree // if we're operating on a workspace, only audit the workspace deps if (this.options.workspaces.length) { @@ -1355,6 +1451,18 @@ module.exports = cls => class Reifier extends cls { timeEnd() } + // Remove the root .store left behind by a previous linked install when reifying under a non-linked strategy. + async #removeStaleStoreDir () { + const storeDir = resolve(this.path, 'node_modules', '.store') + if (!existsSync(storeDir)) { + return + } + log.silly('reify', 'removing stale .store from a previous linked install') + await rm(storeDir, { recursive: true, force: true }) + .catch(/* istanbul ignore next -- rm with force rarely fails */ + er => log.warn('cleanup', 'Failed to remove stale .store directory', er)) + } + // After a linked install, scan node_modules/.store/ and remove any directories that are not referenced by the current ideal tree. // Store entries become orphaned when dependencies are updated or removed, because the diff never sees the old store keys. // Then sweep the top-level node_modules/ for orphaned symlinks (e.g. an uninstalled dep whose store entry was just removed) so we don't leave dangling links. @@ -1362,9 +1470,27 @@ module.exports = cls => class Reifier extends cls { const nmDir = resolve(this.path, 'node_modules') const storeDir = resolve(nmDir, '.store') + // Enumerate on-disk store entries as full keys, descending one level into each @scope directory because scoped keys nest as .store/@scope/pkg@version-hash. let entries try { - entries = await readdir(storeDir) + const topLevel = await readdir(storeDir, { withFileTypes: true }) + entries = [] + for (const ent of topLevel) { + if (ent.name.startsWith('@')) { + let scoped + try { + scoped = await readdir(resolve(storeDir, ent.name)) + } catch { + /* istanbul ignore next -- readdir of an entry we just listed should not fail */ + continue + } + for (const name of scoped) { + entries.push(`${ent.name}/${name}`) + } + } else { + entries.push(ent.name) + } + } } catch { entries = null } @@ -1375,22 +1501,25 @@ module.exports = cls => class Reifier extends cls { // Locations are normalized to forward slashes here because IsolatedNode/IsolatedLink locations are built with path.join, which uses backslashes on Windows. const validKeys = new Set() const nmDirs = new Map() + // Valid bin shim names per node_modules dir, collected from each top-level entry's package.bin so the .bin sweep keeps only shims a still-installed package provides. + const binsByDir = new Map() const NM_PREFIX = 'node_modules/' const STORE_MARKER = '/.store/' for (const child of this.idealTree.children.values()) { const loc = child.location.replace(/\\/g, '/') if (child.isInStore) { - const key = loc.split('/')[2] + // Store location is node_modules/.store/{key}/node_modules/{pkg}. + // For a scoped package the key is @scope/pkg@version-hash, which spans two path segments, so reconstruct both instead of taking only the scope. + const parts = loc.split('/') + const key = parts[2].startsWith('@') ? `${parts[2]}/${parts[3]}` : parts[2] validKeys.add(key) continue } - if (!child.isLink) { - continue - } // Tree-only Links never exist on disk; skipping them lets the sweep remove any stale self-link left by an older npm version. - if (child.isUndeclaredWorkspaceLink) { + if (child.isLink && child.isUndeclaredWorkspaceLink) { continue } + // Real top-level Nodes (e.g. the root's bundled deps) fall through here too, so they are recorded as valid and never swept as stale. const nmIdx = loc.lastIndexOf(NM_PREFIX) if (nmIdx === -1 || loc.includes(STORE_MARKER)) { continue @@ -1411,6 +1540,19 @@ module.exports = cls => class Reifier extends cls { nmDirs.set(dir, set) } set.add(entry) + + // package.bin is normalized to an object keyed by bin name; shim names are unscoped even for scoped packages. + const bin = child.package?.bin + if (bin && typeof bin === 'object') { + let binSet = binsByDir.get(dir) + if (!binSet) { + binSet = new Set() + binsByDir.set(dir, binSet) + } + for (const bn of Object.keys(bin)) { + binSet.add(bn) + } + } } // Determine which node_modules directories to sweep. @@ -1462,19 +1604,69 @@ module.exports = cls => class Reifier extends cls { er => log.warn('cleanup', `Failed to remove orphaned store entry ${e}`, er)) ) ) + // Removing the last scoped orphan under a scope leaves an empty @scope directory behind, so prune any scope directory that is now empty. + const scopes = new Set( + orphaned.filter(e => e.startsWith('@')).map(e => e.split('/')[0]) + ) + await promiseAllRejectLate( + [...scopes].map(async scope => { + const scopeDir = resolve(storeDir, scope) + try { + const remaining = await readdir(scopeDir) + if (!remaining.length) { + await rm(scopeDir, { recursive: true, force: true }) + } + } catch { + /* istanbul ignore next -- readdir of a scope dir we just listed should not fail */ + } + }) + ) } } for (const [dir, valid] of nmDirs) { await this.#cleanOrphanedTopLevelLinks(dir, valid) + await this.#cleanStaleBinLinks(dir, binsByDir.get(dir)) } } + // Remove stale bin shims left in node_modules/.bin after an uninstall under linked, where the diff never emits an action to drop them. + // A shim is stale when no still-linked package provides its name, or when it is a dangling symlink; matching by name handles both POSIX symlinks and Windows .cmd/.ps1 shims. + async #cleanStaleBinLinks (nmDir, validBins = new Set()) { + const binDir = resolve(nmDir, '.bin') + let names + try { + names = await readdir(binDir) + } catch { + return + } + + const stale = names.filter(name => { + const base = name.replace(/\.(cmd|ps1)$/, '') + return !validBins.has(base) || !existsSync(resolve(binDir, name)) + }) + + if (!stale.length) { + return + } + + log.silly('reify', 'cleaning stale bin links', stale) + await promiseAllRejectLate( + stale.map(name => + rm(resolve(binDir, name), { force: true }) + .catch(/* istanbul ignore next -- rm with force rarely fails */ + er => log.warn('cleanup', `Failed to remove stale bin link ${name}`, er)) + ) + ) + } + // Remove node_modules/ entries that aren't represented in the ideal tree. // Run for the project root and each workspace's node_modules. // The linked diff path can't see these because #buildLinkedActualForDiff derives the actual tree from the ideal, so removed deps are never compared. - // Only symlinks whose target resolves inside the project root are removed — that covers store links (node_modules/.store/...) and workspace self-links (e.g. node_modules/ -> ../packages/) that npm itself created. - // Symlinks pointing outside the project (e.g. `npm link foo` without --save targeting the global prefix, or hand-made `ln -s` to an external path) and real directories are preserved. + // Two kinds of stale entry are removed: + // - symlinks whose target resolves inside the project root — store links (node_modules/.store/...) and workspace self-links (e.g. node_modules/ -> ../packages/) that npm itself created. + // - real package directories — hoisted-layout deps left behind when switching from the hoisted strategy to linked, where every valid top-level entry is a symlink. + // Symlinks pointing outside the project (e.g. `npm link foo` without --save targeting the global prefix, or hand-made `ln -s` to an external path) and non-package real directories are preserved. async #cleanOrphanedTopLevelLinks (nmDir, validTopLevel) { const projectPrefix = resolve(this.path) + sep let dirents @@ -1495,7 +1687,15 @@ module.exports = cls => class Reifier extends cls { return resolve(dirname(linkPath), target).startsWith(projectPrefix) } + // A real directory is stale only when it is an actual package (has a package.json), so unrelated user directories are never touched. + const isStaleRealPkg = (dirent, entPath) => + dirent.isDirectory() && existsSync(resolve(entPath, 'package.json')) + + const isOrphan = async (dirent, entPath) => + (dirent.isSymbolicLink() && await isOurOrphan(entPath)) || isStaleRealPkg(dirent, entPath) + const orphaned = [] + const scopes = new Set() for (const ent of dirents) { // skip npm-managed entries (.bin, .store, .package-lock.json, etc) if (ent.name.startsWith('.')) { @@ -1511,11 +1711,12 @@ module.exports = cls => class Reifier extends cls { } for (const pkgEnt of scoped) { const key = `${ent.name}${sep}${pkgEnt.name}` - if (!validTopLevel.has(key) && pkgEnt.isSymbolicLink() && await isOurOrphan(resolve(nmDir, key))) { + if (!validTopLevel.has(key) && await isOrphan(pkgEnt, resolve(nmDir, key))) { orphaned.push(key) + scopes.add(ent.name) } } - } else if (!validTopLevel.has(ent.name) && ent.isSymbolicLink() && await isOurOrphan(resolve(nmDir, ent.name))) { + } else if (!validTopLevel.has(ent.name) && await isOrphan(ent, resolve(nmDir, ent.name))) { orphaned.push(ent.name) } } @@ -1524,14 +1725,29 @@ module.exports = cls => class Reifier extends cls { return } - log.silly('reify', 'cleaning orphaned top-level links', orphaned) + log.silly('reify', 'cleaning orphaned top-level entries', orphaned) await promiseAllRejectLate( orphaned.map(name => rm(resolve(nmDir, name), { recursive: true, force: true }) .catch(/* istanbul ignore next -- rm with force rarely fails */ - er => log.warn('cleanup', `Failed to remove orphaned link ${name}`, er)) + er => log.warn('cleanup', `Failed to remove orphaned entry ${name}`, er)) ) ) + + // Removing the last package under a scope leaves an empty @scope directory behind, so prune any scope directory that is now empty. + await promiseAllRejectLate( + [...scopes].map(async scope => { + const scopeDir = resolve(nmDir, scope) + try { + const remaining = await readdir(scopeDir) + if (!remaining.length) { + await rm(scopeDir, { recursive: true, force: true }) + } + } catch { + /* istanbul ignore next -- readdir of a scope dir we just listed should not fail */ + } + }) + ) } // last but not least, we save the ideal tree metadata to the package-lock diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js b/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js index 3e74e100b6c..1c3e15dee19 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js @@ -6,6 +6,7 @@ const pickManifest = require('npm-pick-manifest') const Vuln = require('./vuln.js') const Calculator = require('@npmcli/metavuln-calculator') +const { isReleaseAgeExcluded } = require('./release-age-exclude.js') const { log, time } = require('proc-log') @@ -151,11 +152,6 @@ class AuditReport extends Map { continue } - // we will have loaded the source already if this is a metavuln - if (advisory.type === 'metavuln') { - vuln.addVia(this.get(advisory.dependency)) - } - // already marked this one, no need to do it again if (vuln.nodes.has(node)) { continue @@ -173,6 +169,11 @@ class AuditReport extends Map { // depends on root. this.topVulns.set(vuln.name, vuln) vuln.topNodes.add(dep) + } else { + // An in-range fix exists, but a `min-release-age`/`before` + // window may put the patched version out of reach, leaving the + // vulnerable version installed. + vuln.fixBlockedByReleaseAge = this.#fixBlockedByReleaseAge(vuln, spec) } } else { // calculate a metavuln, if necessary @@ -213,6 +214,17 @@ class AuditReport extends Map { } } + // post-loop reconciliation: establish all via links + // done here to ensure all vulns exist, avoid redundant setter triggers, + // and correctly handle multiple paths and omission cleanups. + for (const vuln of this.values()) { + for (const advisory of vuln.advisories) { + if (advisory.type === 'metavuln') { + vuln.addVia(this.get(advisory.dependency)) + } + } + } + timeEnd() } @@ -251,6 +263,53 @@ class AuditReport extends Map { } } + // A fix that `#fixAvailable` reports as installable in-range can still be + // unreachable when a release-age window (`before` / `min-release-age`) is set, + // because the patched version was published after the cutoff. `npm audit fix` + // then resolves back to a version that is still vulnerable, so detect that + // here and let callers warn about it. Only meaningful when an in-range fix + // exists (fixAvailable === true). Returns the blocked fix as + // `{ version, before }`, or `false` when nothing is blocked. + #fixBlockedByReleaseAge (vuln, spec) { + const { before, minReleaseAgeExclude } = this.options + // No window, or this package is explicitly exempt from it. + if (!before || isReleaseAgeExcluded(vuln.name, minReleaseAgeExclude)) { + return false + } + + // For `npm:` aliases the fix resolves against the alias target, so feed + // pickManifest the underlying range rather than the alias spec (which it + // rejects). Mirrors `#fixAvailable`. + const specObj = npa(spec) + if (specObj.subSpec) { + spec = specObj.subSpec.rawSpec + } + + // The version that would be installed if the window were lifted. + const { version } = pickManifest(vuln.packument, spec, { + ...this.options, + before: null, + avoid: vuln.range, + }) + + // What resolution can actually reach within the window. This mirrors how + // `build-ideal-tree` re-resolves the edge (non-strict avoid + `before`). + let windowed + try { + windowed = pickManifest(vuln.packument, spec, { + ...this.options, + avoid: vuln.range, + }) + } catch { + // Nothing is old enough to install at all: the fix is blocked. + return { version, before } + } + + // `_shouldAvoid` means the best version available within the window is still + // in the vulnerable range, so the only non-vulnerable fix is too new. + return windowed._shouldAvoid ? { version, before } : false + } + set () { throw new Error('do not call AuditReport.set() directly') } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/calc-dep-flags.js b/deps/npm/node_modules/@npmcli/arborist/lib/calc-dep-flags.js index 5f248485809..965127f5ac9 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/calc-dep-flags.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/calc-dep-flags.js @@ -35,12 +35,32 @@ const calcDepFlags = (tree, resetRoot = true) => { if (node.target == null) { continue } - node.target.dev = node.dev - node.target.optional = node.optional - node.target.devOptional = node.devOptional - node.target.peer = node.peer - node.target.extraneous = node.extraneous - queue.push(node.target) + // Only unset flags, matching the edge walk below, so multiple links to one target can't clobber a correct value. + let changed = false + if (node.target.dev && !node.dev) { + node.target.dev = false + changed = true + } + if (node.target.optional && !node.optional) { + node.target.optional = false + changed = true + } + if (node.target.devOptional && !node.devOptional) { + node.target.devOptional = false + changed = true + } + if (node.target.peer && !node.peer) { + node.target.peer = false + changed = true + } + if (node.target.extraneous && !node.extraneous) { + node.target.extraneous = false + changed = true + } + // queue target on first visit so its deps are walked + if (changed || !seen.has(node.target)) { + queue.push(node.target) + } continue } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js b/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js index bee7ce2768c..db93c298085 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js @@ -9,6 +9,27 @@ const npa = require('npm-package-arg') const { relative } = require('node:path') const fromPath = require('./from-path.js') +// A named ref (tag or branch) resolves to a commit hash, so look up the +// committish recorded for this edge in the lockfile to detect spec changes. +const lockedGitCommittish = (child, requestor) => { + const lock = requestor.root?.meta?.data?.packages?.[requestor.location] + const spec = lock && ( + lock.dependencies?.[child.name] || + lock.optionalDependencies?.[child.name] || + lock.devDependencies?.[child.name] || + lock.peerDependencies?.[child.name] + ) + if (!spec) { + return null + } + try { + const parsed = npa.resolve(child.name, spec, requestor.realpath) + return parsed.type === 'git' ? parsed.gitCommittish || '' : null + } catch { + return null + } +} + const depValid = (child, requested, requestor) => { // NB: we don't do much to verify 'tag' type requests. // Just verify that we got a remote resolution. Presumably, it @@ -94,6 +115,14 @@ const depValid = (child, requested, requestor) => { } } if (!requested.gitRange) { + // a named ref can't be verified against the resolved commit offline, + // so re-resolve if it differs from the committish in the lockfile + if (!reqCommit) { + const locked = lockedGitCommittish(child, requestor) + if (locked !== null && locked !== (requested.gitCommittish || '')) { + return false + } + } return true } return semver.satisfies(child.package.version, requested.gitRange, { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/install-scripts.js b/deps/npm/node_modules/@npmcli/arborist/lib/install-scripts.js index 47a7f982c04..29e9eace8eb 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/install-scripts.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/install-scripts.js @@ -1,4 +1,5 @@ const { isNodeGypPackage } = require('@npmcli/node-gyp') +const PackageJson = require('@npmcli/package-json') // Returns the install-relevant lifecycle scripts that would run for a // given arborist Node, or `{}` if there are none. @@ -70,15 +71,40 @@ const getInstallScripts = async (node) => { collected.install = 'node-gyp rebuild' } - // Lockfile-only nodes (e.g. `npm ci` before reify) carry - // `hasInstallScript: true` but no enumerated scripts: the lockfile - // records the presence flag but never the script bodies. Without this - // fallback the strict-allow-scripts preflight would miss them entirely - // and let postinstall run. We can't recover the real script body - // without fetching the manifest, so emit a sentinel describing that - // install scripts are present. + // Lockfile-only nodes carry `hasInstallScript: true` but no enumerated + // scripts: the lockfile records the presence flag, not the script bodies, + // so `node.package.scripts` is empty on a lockfile-driven install (`npm ci`, + // a repeat `npm install`). Before giving up, read the installed + // package.json from disk to recover the real script bodies. Builder#addToBuildSet + // does the same disk read to decide what to run, but unlike that path this + // one is read-only: we never mutate `node.package`. if (Object.keys(collected).length === 0 && node.hasInstallScript === true) { - collected.install = '(install scripts present)' + const { content } = await PackageJson.normalize(node.path) + .catch(() => ({ content: {} })) + /* istanbul ignore next: normalize resolves to an object with a scripts + object, or our catch fallback returns {}; defensive guard only. */ + const diskScripts = content?.scripts || {} + + if (diskScripts.preinstall) { + collected.preinstall = diskScripts.preinstall + } + if (diskScripts.install) { + collected.install = diskScripts.install + } + if (diskScripts.postinstall) { + collected.postinstall = diskScripts.postinstall + } + if (diskScripts.prepare && hasNonRegistryShape(node)) { + collected.prepare = diskScripts.prepare + } + + // Still nothing. The package isn't on disk yet (e.g. `npm ci` before + // reify) or its package.json is unreadable. Emit a sentinel so the + // advisory and the strict-allow-scripts preflight still surface that + // install scripts are present. + if (Object.keys(collected).length === 0) { + collected.install = '(install scripts present)' + } } return collected diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/isolated-classes.js b/deps/npm/node_modules/@npmcli/arborist/lib/isolated-classes.js index d9770a38679..fc119119664 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/isolated-classes.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/isolated-classes.js @@ -2,13 +2,6 @@ const CaseInsensitiveMap = require('./case-insensitive-map.js') const { resolve } = require('node:path') -// fake lib/inventory.js -class IsolatedInventory extends Map { - query () { - return [] - } -} - // fake lib/node.js class IsolatedNode { binPaths = [] @@ -18,8 +11,11 @@ class IsolatedNode { fsChildren = new Set() hasShrinkwrap = false integrity = null - inventory = new IsolatedInventory() + inventory = new Map() isInStore = false + inBundle = false + isRegistryDependency = false + isRootDependency = false linksIn = new Set() meta = { loadedFromDisk: false } optional = false @@ -47,6 +43,15 @@ class IsolatedNode { if (options.isInStore) { this.isInStore = true } + if (options.inBundle) { + this.inBundle = true + } + if (options.isRegistryDependency) { + this.isRegistryDependency = true + } + if (options.isRootDependency) { + this.isRootDependency = true + } if (options.optional) { this.optional = true } @@ -104,6 +109,11 @@ class IsolatedNode { return !!(hasInstallScript || install || preinstall || postinstall) } + /* istanbul ignore next -- emulate lib/node.js */ + get packageName () { + return this.package.name || null + } + get version () { return this.package.version } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/link.js b/deps/npm/node_modules/@npmcli/arborist/lib/link.js index 3824dc81ffb..89f993bb169 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/link.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/link.js @@ -109,21 +109,12 @@ class Link extends Node { // so this is a no-op [_loadDeps] () {} - // When a Link receives overrides (via edgesIn), forward them to the target node which holds the actual edgesOut — but only when the OverrideSet has at least one rule that names a dep the target actually depends on. - // Without this scope, the link forwards a generic ancestor OverrideSet that has no real effect on the target's edges, but still flips the target to "has overrides", which changes downstream `canReplaceWith` / placement decisions and causes `npm ci` to re-resolve lockfile-pinned edges from the registry. - // See npm/cli#9357. + // Forward overrides to the target only when a rule names a dep it needs, directly or transitively (npm/cli#9357, #9619). recalculateOutEdgesOverrides () { if (!this.target || !this.overrides) { return } - let hasMatchingRule = false - for (const rule of this.overrides.ruleset.values()) { - if (this.target.edgesOut.has(rule.name)) { - hasMatchingRule = true - break - } - } - if (!hasMatchingRule) { + if (!overrideMatchesSubtree(this.overrides, this.target)) { return } this.target.updateOverridesEdgeInAdded(this.overrides) @@ -143,4 +134,29 @@ class Link extends Node { } } +// True when an override rule applies to an edge reachable from the target at any depth. +// getEdgeRule matches on name and spec, returning the set itself when nothing applies, so a non-applicable version-qualified rule doesn't flip an intermediate node to "has overrides" (npm/cli#9357). +// Not a method: runs from the Node super-constructor, before subclass private methods exist. +const overrideMatchesSubtree = (overrides, target) => { + const seen = new Set() + const stack = [target] + while (stack.length) { + const node = stack.pop() + const resolved = node.isLink ? node.target : node + if (seen.has(resolved)) { + continue + } + seen.add(resolved) + for (const edge of resolved.edgesOut.values()) { + if (overrides.getEdgeRule(edge).name === edge.name) { + return true + } + if (edge.to) { + stack.push(edge.to) + } + } + } + return false +} + module.exports = Link diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/node.js b/deps/npm/node_modules/@npmcli/arborist/lib/node.js index 451ede1e52c..87b0ac41740 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/node.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/node.js @@ -927,7 +927,8 @@ class Node { isTop: srcTop, path: srcPath, } = sourceReference || {} - const thisDev = isTop && !globalTop && path + // A package in the linked strategy's .store is a transitive dependency that is structurally a tree top, but its devDependencies are never installed or required, so they must not be loaded. + const thisDev = isTop && !globalTop && path && !this.isInStore const srcDev = !sourceReference || srcTop && !srcGlobalTop && srcPath if (thisDev && srcDev) { this.#loadDepType(this.package.devDependencies, 'dev', ad) diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js b/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js index 626af0c908e..05faa551f76 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js @@ -9,6 +9,7 @@ const npa = require('npm-package-arg') const pacote = require('pacote') const semver = require('semver') const npmFetch = require('npm-registry-fetch') +const { isReleaseAgeExcluded } = require('./release-age-exclude.js') // handle results for parsed query asts, results are stored in a map that has a // key that points to each ast selector node and stores the resulting array of @@ -797,7 +798,8 @@ const hasParent = (node, compareNodes) => { // Only match if the node has a link whose parent is the compareNode. Without this check, nodes deep in the store (linked strategy) would incorrectly match as children of root via their fsParent chain. if (node.isTop && (node.resolveParent === compareNode)) { for (const link of node.linksIn) { - if (link.parent === compareNode) { + // A store-backing node (linked strategy) is reached through its logical Link, which matches via edgesIn below, so the store node itself is never a direct child. + if (link.parent === compareNode && !node.isInStore) { return true } } @@ -889,8 +891,9 @@ const getPackageVersions = async (name, opts) => { let candidates = Object.keys(packument.versions).sort(semver.compare) // if the packument has a time property, and the user passed a before flag, then - // we filter this list down to only those versions that existed before the specified date - if (packument.time && opts.before) { + // we filter this list down to only those versions that existed before the specified date. + // packages matching `min-release-age-exclude` are exempt from this filter. + if (packument.time && opts.before && !isReleaseAgeExcluded(name, opts.minReleaseAgeExclude)) { candidates = candidates.filter((version) => { // this version isn't found in the times at all, drop it if (!packument.time[version]) { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/release-age-exclude.js b/deps/npm/node_modules/@npmcli/arborist/lib/release-age-exclude.js new file mode 100644 index 00000000000..b85527cfcbe --- /dev/null +++ b/deps/npm/node_modules/@npmcli/arborist/lib/release-age-exclude.js @@ -0,0 +1,45 @@ +// Determine whether a package name is exempt from the `min-release-age` / +// `before` release-age filter, based on the `min-release-age-exclude` config. +// +// Patterns are exact package names or `minimatch` globs (e.g. `@myorg/*`), and +// match against the package name only. This is a "named-only" exemption: a +// matched package's own dependencies still follow the filter unless they match +// a pattern too. +// +// Callers must match against the resolved registry identity of a package, not +// the self-reported alias or dependency-edge name. For `npm:` aliases the +// fetched package is the alias target, so run specs through `trustedSpecName` +// first; otherwise an alias key could match an exclude pattern and turn the +// filter off for the unrelated package it resolves to. +const { minimatch } = require('minimatch') + +// This list only ever widens the exemption (turns the security filter off for a +// package), so disable pattern features that could silently turn it into a +// match-all: `nonegate` keeps a leading `!` literal (so a stray `!foo` exempts +// nothing instead of everything-but-foo), `nocomment` keeps a leading `#` +// literal, and `noext` disables extglobs. +const minimatchOptions = { nonegate: true, nocomment: true, noext: true } + +const isReleaseAgeExcluded = (name, patterns) => { + if (!name || !Array.isArray(patterns) || patterns.length === 0) { + return false + } + return patterns.some(pattern => + name === pattern || minimatch(name, pattern, minimatchOptions)) +} + +// Resolve the trusted registry name for an npa spec. For `npm:` aliases (e.g. +// `"x": "npm:other@1"`) the installed/fetched package is the alias target +// (`subSpec`), not the alias key, so the exemption must be keyed on the +// underlying package name. Mirrors `nameFromEdges` in script-allowed.js. +const trustedSpecName = (spec) => { + if (!spec) { + return undefined + } + if (spec.type === 'alias' && spec.subSpec && spec.subSpec.registry) { + return spec.subSpec.name + } + return spec.name +} + +module.exports = { isReleaseAgeExcluded, trustedSpecName } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/script-allowed.js b/deps/npm/node_modules/@npmcli/arborist/lib/script-allowed.js index 91734fa38c1..8c9b3fe118a 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/script-allowed.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/script-allowed.js @@ -24,13 +24,13 @@ const versionFromTgz = require('./version-from-tgz.js') // resolved committish const isScriptAllowed = (node, policy) => { - // Bundled dependencies cannot be allowlisted in Phase 1. The RFC defers - // allowlisting them to a follow-up RFC because matching by name@version - // from the bundled tarball would reintroduce manifest confusion (a - // bundled tarball can claim any name and version). Returning null here - // marks bundled deps as unreviewed regardless of any policy entries, so - // their install scripts surface in the Phase 1 advisory warning and - // (eventually) get blocked at the install-time gate. + // Bundled dependencies never run their install scripts and cannot be + // allowlisted. Matching by name@version from the bundled tarball would + // reintroduce manifest confusion (a bundled tarball can claim any name + // and version). Returning null marks them as not-allowed regardless of + // any policy entry, so their install scripts are blocked by the + // install-time gate. A package that needs a bundled dep's script must + // forward it as one of its own lifecycle scripts. if (node.inBundle) { return null } @@ -43,7 +43,9 @@ const isScriptAllowed = (node, policy) => { let anyDeny = false for (const [key, value] of Object.entries(policy)) { - if (!matches(node, key)) { + // Pass deny intent so matchRegistry can fail closed on an unverifiable + // version: a deny still blocks, an allow stays refused. + if (!matches(node, key, value === false)) { continue } if (value === false) { @@ -66,7 +68,7 @@ const isScriptAllowed = (node, policy) => { return null } -const matches = (node, key) => { +const matches = (node, key, failClosed) => { let parsed try { parsed = npa(key) @@ -78,7 +80,7 @@ const matches = (node, key) => { case 'tag': case 'range': case 'version': - return matchRegistry(node, parsed) + return matchRegistry(node, parsed, failClosed) case 'git': return matchGit(node, parsed) case 'file': @@ -97,7 +99,42 @@ const matches = (node, key) => { } } -const matchRegistry = (node, parsed) => { +const resolvedSourceSpecs = (node) => { + const specs = [] + const seen = new Set() + const add = (spec) => { + if (typeof spec !== 'string' || spec === '' || seen.has(spec)) { + return + } + seen.add(spec) + specs.push(spec) + } + + add(node?.resolved) + + if (!node?.resolved && node?.linksIn && typeof node.linksIn[Symbol.iterator] === 'function') { + let hasIncomingLink = false + for (const link of node.linksIn) { + hasIncomingLink = true + add(link.resolved) + } + + if (hasIncomingLink) { + // Link targets for local directory deps are separate inventory nodes + // whose own `resolved` is null. The incoming Link carries the saved spec + // (for example `file:../pkg`, relative to node_modules), while policy + // entries written by hand often use the dependency spec from package.json + // (for example `file:pkg`, resolved by npa to this target path). Include + // the real target paths so both forms can match the same local dep. + add(node.realpath) + add(node.path) + } + } + + return specs +} + +const matchRegistry = (node, parsed, failClosed) => { // If this node is not a registry dep, refuse the match. A registry-style // key (`pkg`, `pkg@1`, `pkg@1 || 2`) must not match a tarball or git node // even if their names happen to coincide. @@ -133,9 +170,14 @@ const matchRegistry = (node, parsed) => { if (parsed.fetchSpec === '*' || parsed.rawSpec === '' || parsed.rawSpec === '*') { return true } - if (!trusted.version || !isExactVersionDisjunction(parsed.fetchSpec)) { + if (!isExactVersionDisjunction(parsed.fetchSpec)) { return false } + // Unverifiable version (omit-lockfile-registry-resolved): a deny blocks, + // an allow is refused. + if (!trusted.version) { + return failClosed + } return semver.satisfies(trusted.version, parsed.fetchSpec, { loose: true }) } @@ -143,6 +185,10 @@ const matchRegistry = (node, parsed) => { /* istanbul ignore else: parsed.type at this point is always 'version'; the istanbul-ignored fallback below handles the impossible case. */ if (parsed.type === 'version') { + // Unverifiable version: a deny blocks, an allow is refused. + if (!trusted.version) { + return failClosed + } return trusted.version === parsed.fetchSpec } @@ -282,17 +328,13 @@ const matchGit = (node, parsed) => { } const matchFileOrDir = (node, parsed) => { - if (!node.resolved) { - return false - } - return node.resolved === parsed.saveSpec || node.resolved === parsed.fetchSpec + return resolvedSourceSpecs(node) + .some(resolved => resolved === parsed.saveSpec || resolved === parsed.fetchSpec) } const matchRemote = (node, parsed) => { - if (!node.resolved) { - return false - } - return node.resolved === parsed.fetchSpec || node.resolved === parsed.saveSpec + return resolvedSourceSpecs(node) + .some(resolved => resolved === parsed.fetchSpec || resolved === parsed.saveSpec) } const isRegistryNode = (node) => { @@ -319,11 +361,11 @@ const isRegistryNode = (node) => { return /^https?:\/\/[^/]+\/.+\/-\/[^/]+-\d/.test(node.resolved) } -// Trusted display identity for human-facing output (`npm install` -// advisory, `npm approve-scripts --allow-scripts-pending`). Same idea as -// getTrustedRegistryIdentity, but for DISPLAY only — version falls back -// to node.version when the URL doesn't carry one. Must never be used -// for policy matching. +// Trusted display identity for human-facing output (the `npm install` +// blocked-scripts summary and `npm approve-scripts --allow-scripts-pending`). +// Same as getTrustedRegistryIdentity, but for display only: version +// falls back to node.version when the URL doesn't carry one. Do not +// use for policy matching. const trustedDisplay = (node) => { const trusted = getTrustedRegistryIdentity(node) /* istanbul ignore next: defensive fallbacks for nodes without name/version */ @@ -335,6 +377,8 @@ const trustedDisplay = (node) => { module.exports = isScriptAllowed module.exports.isScriptAllowed = isScriptAllowed +module.exports.matches = matches module.exports.isExactVersionDisjunction = isExactVersionDisjunction module.exports.getTrustedRegistryIdentity = getTrustedRegistryIdentity +module.exports.resolvedSourceSpecs = resolvedSourceSpecs module.exports.trustedDisplay = trustedDisplay diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js b/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js index 6af902cdf8a..03cc86edbd4 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js @@ -172,6 +172,35 @@ const assertNoNewer = async (path, data, lockTime, dir, seen) => { return } + // The walk above can't reach two linked-strategy layouts: a store package's sibling deps under .store//node_modules (.store is a skipped dot-dir), and an undeclared workspace not symlinked into root node_modules. Walk those dirs, derived from the lockfile entries. + // A dir reachable through a link entry is skipped: it was already reached (or, if the symlink is stale, correctly stays unseen so the lockfile is rejected). This keeps the hoisted strategy's stale-symlink detection intact, since there every workspace is a link target. + const linkTargets = new Set() + for (const loc in data.packages) { + const { link, resolved } = data.packages[loc] + if (link && resolved) { + linkTargets.add(resolved.replace(/\\/g, '/')) + } + } + const extraDirs = new Set() + for (const loc in data.packages) { + const store = loc.match(/^(.*\/\.store\/.+?)\/node_modules\//) + if (store) { + // .store/ is never walked but has no entry, so mark it seen. + seen.add(store[1]) + extraDirs.add(`${store[1]}/node_modules`) + continue + } + // A workspace/fsChild dir outside node_modules, e.g. packages/a. + const i = loc.indexOf('/node_modules/') + const root = i === -1 ? loc : loc.slice(0, i) + if (root && !/(^|\/)node_modules(\/|$)/.test(root) && !linkTargets.has(root)) { + extraDirs.add(root) + } + } + for (const rel of extraDirs) { + await assertNoNewer(path, data, lockTime, resolve(path, rel), seen) + } + // assert that all the entries in the lockfile were seen for (const loc in data.packages) { if (!seen.has(loc)) { @@ -929,8 +958,14 @@ class Shrinkwrap { continue } const loc = relpath(this.path, node.path) - // Drop lockfile entries for extraneous nodes outside node_modules. These are stale workspace entries: the workspace was removed from package.json or its directory was deleted, so it should not be tracked in package-lock.json. - if (node.extraneous && !/(^|\/)node_modules\//.test(loc) && loc !== 'node_modules') { + // Drop lockfile entries for extraneous nodes outside node_modules that + // are direct fsChildren of the root (or detached link targets). These + // are stale top-level entries: a workspace or file: dep removed from + // the root manifest, or whose directory was deleted. Extraneous + // fsChildren nested under another package (e.g. a file: dep of another + // file: dep) are kept so `npm ci` can resolve the parent's dependency. + if (node.extraneous && !/(^|\/)node_modules\//.test(loc) && loc !== 'node_modules' && + (!node.fsParent || node.fsParent.isRoot)) { continue } const meta = Shrinkwrap.metaFromNode( diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/unreviewed-scripts.js b/deps/npm/node_modules/@npmcli/arborist/lib/unreviewed-scripts.js new file mode 100644 index 00000000000..f7bed387845 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/arborist/lib/unreviewed-scripts.js @@ -0,0 +1,101 @@ +const isScriptAllowed = require('./script-allowed.js') +const getInstallScripts = require('./install-scripts.js') + +// Shared allowScripts walk used by both the npm CLI +// (lib/utils/check-allow-scripts.js, lib/utils/strict-allow-scripts-preflight.js) +// and libnpmexec (npm exec / npx). It lives in arborist because that is the +// only package both callers can import. +// +// Walks a tree's inventory and returns the dep nodes that have +// install-relevant lifecycle scripts and are not yet covered (or explicitly +// denied) by the allowScripts policy. +// +// Returns an array of `{ node, scripts }` entries. `scripts` is an object +// describing the relevant lifecycle scripts that would run. +const collectUnreviewedScripts = async ({ + tree, + policy, + ignoreScripts = false, + dangerouslyAllowAllScripts = false, + includeWhenIgnored = false, +} = {}) => { + // With ignore-scripts set, no scripts run, so execution callers bail out + // here. approve/deny pass includeWhenIgnored so they keep listing + // unreviewed packages, which is what you need to move from a blanket + // ignore-scripts to an allowlist. Listing never runs anything. + if ((ignoreScripts && !includeWhenIgnored) || dangerouslyAllowAllScripts) { + return [] + } + + if (!tree?.inventory) { + return [] + } + + const resolvedPolicy = policy || null + + const unreviewed = [] + for (const node of tree.inventory.values()) { + if (node.isProjectRoot || node.isWorkspace) { + continue + } + if (node.isLink) { + // Linked workspace dependencies are managed by the workspace owner. + continue + } + if (node.inBundle) { + // Bundled dependencies never run their install scripts and cannot be + // allowlisted, so they are never "pending". Skipping them keeps them + // out of the advisory warning and out of strict-allow-scripts. A + // package that needs a bundled dep's script must forward it as one of + // its own lifecycle scripts. + continue + } + if (node.inert) { + // Inert = an optional dep that can't be installed here (failed the + // os/cpu/libc or engine check, or failed to load). reify drops it + // before any script runs, so its install scripts never execute and it + // must not be flagged (npm/cli#9562). + continue + } + + const verdict = isScriptAllowed(node, resolvedPolicy) + if (verdict === true || verdict === false) { + continue + } + + const scripts = await getInstallScripts(node) + if (Object.keys(scripts).length === 0) { + continue + } + + unreviewed.push({ node, scripts }) + } + + return unreviewed +} + +// Builds the `ESTRICTALLOWSCRIPTS` error thrown by the strict-mode preflight +// from a list of `{ node, scripts }` entries. `remediation` is the +// caller-specific guidance appended after the package list (npm install vs +// npm exec have different remediation commands). +const strictAllowScriptsError = (unreviewed, { remediation } = {}) => { + const lines = unreviewed.map(({ node, scripts }) => { + const events = Object.entries(scripts) + .map(([event, body]) => `${event}: ${body}`) + .join('; ') + const name = node.package?.name || node.name + const version = node.package?.version || '' + const label = version ? `${name}@${version}` : name + return ` ${label} (${events})` + }).join('\n') + + return Object.assign( + new Error( + `--strict-allow-scripts: ${unreviewed.length} package(s) have install ` + + `scripts not covered by allowScripts:\n${lines}\n${remediation}` + ), + { code: 'ESTRICTALLOWSCRIPTS' } + ) +} + +module.exports = { collectUnreviewedScripts, strictAllowScriptsError } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/vuln.js b/deps/npm/node_modules/@npmcli/arborist/lib/vuln.js index 2bffe54f2da..e6c6bbab383 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/vuln.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/vuln.js @@ -41,6 +41,7 @@ class Vuln { this.effects = new Set() this.topNodes = new Set() this.nodes = new Set() + this.fixBlockedByReleaseAge = false this.addAdvisory(advisory) this.packument = advisory.packument this.versions = advisory.versions @@ -126,6 +127,9 @@ class Vuln { range: this.simpleRange, nodes: [...this.nodes].map(n => n.location).sort(localeCompare), fixAvailable: this.#fixAvailable, + ...(this.fixBlockedByReleaseAge + ? { fixBlockedByReleaseAge: this.fixBlockedByReleaseAge } + : {}), } } diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index 712151e63a1..11c142a0092 100644 --- a/deps/npm/node_modules/@npmcli/arborist/package.json +++ b/deps/npm/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "9.7.0", + "version": "9.9.0", "description": "Manage node_modules trees", "dependencies": { "@gar/promise-retry": "^1.0.0", diff --git a/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js b/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js index 2cb03709d73..2bb1713458a 100644 --- a/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js +++ b/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js @@ -178,9 +178,10 @@ const definitions = { type: Boolean, short: 'a', description: ` - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show - all outdated or installed packages, rather than only those directly - depended upon by the current project. + Show or act on all packages, not just the ones your project directly + depends on. For \`npm outdated\` and \`npm ls\` this lists every outdated + or installed package. For \`npm approve-scripts\` and \`npm deny-scripts\` + it selects every package with pending install scripts. `, flatten, }), @@ -339,6 +340,13 @@ const definitions = { Across sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. + + As with \`min-release-age\`, when this cutoff blocks a fix that + \`npm audit fix\` would install, npm keeps the vulnerable version, warns, + and exits with a non-zero code. + + Packages whose names match \`min-release-age-exclude\` are exempt from + this filter. `, flatten, }), @@ -1200,8 +1208,15 @@ const definitions = { necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct deps at top-level. - linked: (experimental) install in node_modules/.store, link in place, - unhoisted. + linked: install in node_modules/.store, link in place, unhoisted. + + We recommend that package authors use \`--install-strategy=linked\` + during development to catch undeclared ("phantom") dependencies before + publishing: the isolated layout only exposes a package's declared + dependencies, so an \`import\` of a package that was never added to + \`package.json\` can fail instead of resolving by accident and shipping + broken. See [Catching undeclared ("phantom") + dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). `, flatten, }), @@ -1470,6 +1485,15 @@ const definitions = { spawns a sub-process with \`--before\` while preparing a \`git:\` or \`github:\` dependency); when both apply, \`before\` wins within a single source and across sources the standard precedence rules apply. + + When this window stops \`npm audit fix\` from installing a patched + version (because the fix was published too recently), npm keeps the + package at its vulnerable version, warns that the fix was blocked, and + exits with a non-zero code. To install the fix, add the package to + \`min-release-age-exclude\`, or relax \`min-release-age\` or \`before\`. + + Packages whose names match \`min-release-age-exclude\` are exempt from + this filter. `, flatten: (key, obj, flatOptions) => { const age = obj['min-release-age'] @@ -1480,6 +1504,45 @@ const definitions = { } }, }), + 'min-release-age-exclude': new Definition('min-release-age-exclude', { + default: [], + hint: '', + type: [Array, String], + envExport: false, + description: ` + A list of package names or \`minimatch\` glob patterns that are exempt + from the \`min-release-age\` (and \`before\`) filter. A matching package + can always resolve to its newest version, even when a release-age window + is set. + + For example, to apply a release-age window to third-party dependencies + while letting internally maintained packages update immediately: + + \`\`\` + min-release-age=7 + min-release-age-exclude[]=@myorg/* + min-release-age-exclude[]=my-internal-pkg + \`\`\` + + Only the named package is exempt; its own dependencies still follow the + release-age policy unless they also match a pattern. Patterns match + against the package name, so \`@myorg/*\` matches \`@myorg/shared-utils\`. + + Excluding a package does not change which registry it is fetched from. You + should own your private scope on the public registry so that nobody else + can publish a package with the same name. + `, + flatten: (key, obj, flatOptions) => { + // The config layer always resolves this to an array (nopt and .npmrc both + // coerce `[Array, String]` to a list, default `[]`), so treat it as one. + // A single value may still pack multiple names as a comma string. + const list = obj[key] + .flatMap(v => String(v).split(',')) + .map(v => v.trim()) + .filter(Boolean) + flatOptions.minReleaseAgeExclude = [...new Set(list)] + }, + }), 'node-gyp': new Definition('node-gyp', { default: (() => { try { @@ -1867,7 +1930,7 @@ const definitions = { }), 'replace-registry-host': new Definition('replace-registry-host', { default: 'npmjs', - hint: ' | hostname', + hint: ' | hostname | url', type: ['npmjs', 'never', 'always', String], description: ` Defines behavior for replacing the registry host in a lockfile with the @@ -1878,7 +1941,14 @@ const definitions = { "never", then use the registry value. If set to "always", then replace the registry host with the configured host every time. - You may also specify a bare hostname (e.g., "registry.npmjs.org"). + You may also specify a bare hostname (e.g., "registry.npmjs.org") to only + replace URLs coming from that host. + + You may also specify a full URL including a path (e.g., + "https://old-registry.example.com/npm/path"). In that case, resolved URLs + whose host and path begin with that prefix will have the entire prefix + replaced with the configured registry URL (host and path), without + duplicating path segments. `, flatten, }), @@ -2315,6 +2385,10 @@ const definitions = { always silently skipped; this setting only affects unreviewed entries. \`--ignore-scripts\` and \`--dangerously-allow-all-scripts\` both override this setting. + + Optional dependencies that cannot be installed on the current platform + or engine (a non-matching \`os\`, \`cpu\`, or \`libc\`) are not flagged, + because their install scripts never run. `, flatten, }), @@ -2453,6 +2527,36 @@ const definitions = { flatten (key, obj, flatOptions) { const value = obj[key] const ciName = ciInfo.name?.toLowerCase().split(' ').join('-') || null + // A more specific sub-category for the detected CI, appended to the + // ci token as `ci/{ci-name}/{sub-ci-name}` when present. + let subCiName = null + if (ciInfo.GITHUB_ACTIONS) { + // Env vars can be absent, empty, or whitespace; normalize before use. + const serverUrl = (process.env.GITHUB_SERVER_URL || '').trim() + const runnerEnv = (process.env.RUNNER_ENVIRONMENT || '').trim() + let serverHost = '' + try { + serverHost = new URL(serverUrl).hostname.toLowerCase() + } catch { + serverHost = '' + } + if (serverHost === 'github.com') { + if (runnerEnv === 'github-hosted') { + subCiName = 'dotcom-hosted' + } else if (runnerEnv === 'self-hosted') { + subCiName = 'dotcom-selfhosted' + } else { + subCiName = 'dotcom' + } + } else if (serverHost === 'ghe.com' || serverHost.endsWith('.ghe.com')) { + subCiName = 'ghecom' + } else if (serverHost) { + subCiName = 'ghes' + } + } + const ci = ciName + ? `ci/${ciName}${subCiName ? `/${subCiName}` : ''}` + : '' let inWorkspaces = false if (obj.workspaces || obj.workspace && obj.workspace.length) { inWorkspaces = true @@ -2463,7 +2567,7 @@ const definitions = { .replace(/\{platform\}/gi, process.platform) .replace(/\{arch\}/gi, process.arch) .replace(/\{workspaces\}/gi, inWorkspaces) - .replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '') + .replace(/\{ci\}/gi, ci) .trim() // We can't clobber the original or else subsequent flattening will fail diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json index 295855d76df..360b0ab128a 100644 --- a/deps/npm/node_modules/@npmcli/config/package.json +++ b/deps/npm/node_modules/@npmcli/config/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/config", - "version": "10.10.0", + "version": "10.12.0", "files": [ "bin/", "lib/" diff --git a/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js b/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js index 33063dd3552..e4e5bd87666 100644 --- a/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js +++ b/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js @@ -95,19 +95,23 @@ function gte(i, y) { function expand_(str, max, isTop) { /** @type {string[]} */ const expansions = []; - const m = (0, balanced_match_1.balanced)('{', '}', str); - if (!m) - return [str]; - // no need to expand pre, since it is guaranteed to be free of brace-sets - const pre = m.pre; - const post = m.post.length ? expand_(m.post, max, false) : ['']; - if (/\$$/.test(m.pre)) { - for (let k = 0; k < post.length && k < max; k++) { - const expansion = pre + '{' + m.body + '}' + post[k]; - expansions.push(expansion); + // The `{a},b}` rewrite below restarts expansion on a rewritten string with + // the same `max` and `isTop = true`. Loop instead of recursing so a long run + // of non-expanding `{}` groups can't exhaust the call stack. + for (;;) { + const m = (0, balanced_match_1.balanced)('{', '}', str); + if (!m) + return [str]; + // no need to expand pre, since it is guaranteed to be free of brace-sets + const pre = m.pre; + if (/\$$/.test(m.pre)) { + const post = m.post.length ? expand_(m.post, max, false) : ['']; + for (let k = 0; k < post.length && k < max; k++) { + const expansion = pre + '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + return expansions; } - } - else { const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); const isSequence = isNumericSequence || isAlphaSequence; @@ -116,10 +120,16 @@ function expand_(str, max, isTop) { // {a},b} if (m.post.match(/,(?!,).*\}/)) { str = m.pre + '{' + m.body + escClose + m.post; - return expand_(str, max, true); + isTop = true; + continue; } return [str]; } + // Only expand post once we know this brace set actually expands. Computing + // it before the early returns above expanded post a second time on every + // non-expanding `{}`, which is what made inputs like `a{},{},{}...` blow up + // exponentially. + const post = m.post.length ? expand_(m.post, max, false) : ['']; let n; if (isSequence) { n = m.body.split(/\.\./); @@ -195,7 +205,7 @@ function expand_(str, max, isTop) { } } } + return expansions; } - return expansions; } //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/brace-expansion/dist/esm/index.js b/deps/npm/node_modules/brace-expansion/dist/esm/index.js index 32399e7b2f5..b2d2aa91bb1 100644 --- a/deps/npm/node_modules/brace-expansion/dist/esm/index.js +++ b/deps/npm/node_modules/brace-expansion/dist/esm/index.js @@ -91,19 +91,23 @@ function gte(i, y) { function expand_(str, max, isTop) { /** @type {string[]} */ const expansions = []; - const m = balanced('{', '}', str); - if (!m) - return [str]; - // no need to expand pre, since it is guaranteed to be free of brace-sets - const pre = m.pre; - const post = m.post.length ? expand_(m.post, max, false) : ['']; - if (/\$$/.test(m.pre)) { - for (let k = 0; k < post.length && k < max; k++) { - const expansion = pre + '{' + m.body + '}' + post[k]; - expansions.push(expansion); + // The `{a},b}` rewrite below restarts expansion on a rewritten string with + // the same `max` and `isTop = true`. Loop instead of recursing so a long run + // of non-expanding `{}` groups can't exhaust the call stack. + for (;;) { + const m = balanced('{', '}', str); + if (!m) + return [str]; + // no need to expand pre, since it is guaranteed to be free of brace-sets + const pre = m.pre; + if (/\$$/.test(m.pre)) { + const post = m.post.length ? expand_(m.post, max, false) : ['']; + for (let k = 0; k < post.length && k < max; k++) { + const expansion = pre + '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + return expansions; } - } - else { const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); const isSequence = isNumericSequence || isAlphaSequence; @@ -112,10 +116,16 @@ function expand_(str, max, isTop) { // {a},b} if (m.post.match(/,(?!,).*\}/)) { str = m.pre + '{' + m.body + escClose + m.post; - return expand_(str, max, true); + isTop = true; + continue; } return [str]; } + // Only expand post once we know this brace set actually expands. Computing + // it before the early returns above expanded post a second time on every + // non-expanding `{}`, which is what made inputs like `a{},{},{}...` blow up + // exponentially. + const post = m.post.length ? expand_(m.post, max, false) : ['']; let n; if (isSequence) { n = m.body.split(/\.\./); @@ -191,7 +201,7 @@ function expand_(str, max, isTop) { } } } + return expansions; } - return expansions; } //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/brace-expansion/package.json b/deps/npm/node_modules/brace-expansion/package.json index 81524809e58..a5142f2787b 100644 --- a/deps/npm/node_modules/brace-expansion/package.json +++ b/deps/npm/node_modules/brace-expansion/package.json @@ -1,7 +1,7 @@ { "name": "brace-expansion", "description": "Brace expansion as known from sh/bash", - "version": "5.0.6", + "version": "5.0.7", "files": [ "dist" ], @@ -59,6 +59,6 @@ "module": "./dist/esm/index.js", "repository": { "type": "git", - "url": "git+ssh://git@github.com/juliangruber/brace-expansion.git" + "url": "git+https://github.com/juliangruber/brace-expansion.git" } } diff --git a/deps/npm/node_modules/libnpmdiff/package.json b/deps/npm/node_modules/libnpmdiff/package.json index 08783e3ecb1..31aadc1a771 100644 --- a/deps/npm/node_modules/libnpmdiff/package.json +++ b/deps/npm/node_modules/libnpmdiff/package.json @@ -1,6 +1,6 @@ { "name": "libnpmdiff", - "version": "8.1.9", + "version": "8.1.11", "description": "The registry diff", "repository": { "type": "git", @@ -47,7 +47,7 @@ "tap": "^16.3.8" }, "dependencies": { - "@npmcli/arborist": "^9.7.0", + "@npmcli/arborist": "^9.9.0", "@npmcli/installed-package-contents": "^4.0.0", "binary-extensions": "^3.0.0", "diff": "^8.0.2", diff --git a/deps/npm/node_modules/libnpmexec/lib/index.js b/deps/npm/node_modules/libnpmexec/lib/index.js index 3add22cd2ed..4d7c1266546 100644 --- a/deps/npm/node_modules/libnpmexec/lib/index.js +++ b/deps/npm/node_modules/libnpmexec/lib/index.js @@ -4,6 +4,7 @@ const { dirname, join, resolve } = require('node:path') const crypto = require('node:crypto') const { mkdir } = require('node:fs/promises') const Arborist = require('@npmcli/arborist') +const strictAllowScriptsPreflight = require('./strict-allow-scripts-preflight.js') const ciInfo = require('ci-info') const { log, input } = require('proc-log') const npa = require('npm-package-arg') @@ -18,8 +19,6 @@ const runScript = require('./run-script.js') const isWindows = require('./is-windows.js') const withLock = require('./with-lock.js') -const binPaths = [] - // when checking the local tree we look up manifests, cache those results by // spec.raw so we don't have to fetch again when we check npxCache const manifests = new Map() @@ -86,6 +85,9 @@ const missingFromTree = async ({ spec, tree, flatOptions, isNpxTree, shallow }) } } +// Strict-mode pre-flight for `npm exec` / `npx` lives in +// ./strict-allow-scripts-preflight.js + // see if the package.json at `path` has an entry that matches `cmd` // the path is a known-local directory, not a user-supplied dep, so // allow-directory must not gate this introspection @@ -109,6 +111,8 @@ const exec = async (opts) => { ...flatOptions } = opts + const binPaths = [] + let pkgPaths = opts.pkgPath if (typeof pkgPaths === 'string') { pkgPaths = [pkgPaths] @@ -192,7 +196,11 @@ const exec = async (opts) => { let commandManifest await Promise.all(packages.map(async (pkg, i) => { const spec = npa(pkg, path) - const { manifest, node } = await missingFromTree({ spec, tree: localTree, flatOptions }) + const { manifest, node } = await missingFromTree({ + spec, + tree: localTree, + flatOptions, + }) if (manifest) { // Package does not exist in the local tree needInstall.push({ spec, manifest }) @@ -301,11 +309,16 @@ const exec = async (opts) => { } } } - await withLock(lockPath, () => npxArb.reify({ - ...flatOptions, - save: true, - add, - })) + await withLock(lockPath, async () => { + // Hard-fail before reify if --strict-allow-scripts is set and + // any node has install scripts not covered by allowScripts. + await strictAllowScriptsPreflight(npxArb, { ...flatOptions, add }) + await npxArb.reify({ + ...flatOptions, + save: true, + add, + }) + }) } binPaths.push(resolve(installDir, 'node_modules/.bin')) const pkgJson = await PackageJson.load(installDir) diff --git a/deps/npm/node_modules/libnpmexec/lib/run-script.js b/deps/npm/node_modules/libnpmexec/lib/run-script.js index 13f16a74eb8..2de40454f9d 100644 --- a/deps/npm/node_modules/libnpmexec/lib/run-script.js +++ b/deps/npm/node_modules/libnpmexec/lib/run-script.js @@ -19,7 +19,9 @@ const run = async ({ // necessary for preventing bash/cmd keywords from overriding if (!isWindowsShell) { if (args.length > 0) { - args[0] = '"' + args[0] + '"' + // single-quote so shell metacharacters in the executable name are taken + // literally; double quotes still expand $(), backticks, $var and " + args[0] = `'${args[0].replace(/'/g, `'\\''`)}'` } } diff --git a/deps/npm/node_modules/libnpmexec/lib/strict-allow-scripts-preflight.js b/deps/npm/node_modules/libnpmexec/lib/strict-allow-scripts-preflight.js new file mode 100644 index 00000000000..579fd0c0fdd --- /dev/null +++ b/deps/npm/node_modules/libnpmexec/lib/strict-allow-scripts-preflight.js @@ -0,0 +1,40 @@ +const { collectUnreviewedScripts, strictAllowScriptsError } = require('@npmcli/arborist/lib/unreviewed-scripts.js') + +// Strict-mode pre-flight for `npm exec` / `npx`. When +// `--strict-allow-scripts` is set, build the npx-cache ideal tree and +// throw before reify if any node has install scripts not covered by +// the resolved `allowScripts` policy. The arborist gate already +// silently skips those scripts; this turns the silent skip into a +// hard failure for CI. Bypassed by `--ignore-scripts` and +// `--dangerously-allow-all-scripts`. +const strictAllowScriptsPreflight = async (arb, opts) => { + if (!opts.strictAllowScripts) { + return + } + if (opts.ignoreScripts || opts.dangerouslyAllowAllScripts) { + return + } + + if (!arb.idealTree) { + await arb.buildIdealTree(opts) + } + + const unreviewed = await collectUnreviewedScripts({ + tree: arb.idealTree, + policy: opts.allowScripts || null, + ignoreScripts: opts.ignoreScripts, + dangerouslyAllowAllScripts: opts.dangerouslyAllowAllScripts, + }) + + if (unreviewed.length === 0) { + return + } + + throw strictAllowScriptsError(unreviewed, { + remediation: + 'Pass --allow-scripts= for one-off approval, or bypass this ' + + 'check with --dangerously-allow-all-scripts.', + }) +} + +module.exports = strictAllowScriptsPreflight diff --git a/deps/npm/node_modules/libnpmexec/package.json b/deps/npm/node_modules/libnpmexec/package.json index b672050048b..097673618ae 100644 --- a/deps/npm/node_modules/libnpmexec/package.json +++ b/deps/npm/node_modules/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "10.2.9", + "version": "10.3.1", "files": [ "bin/", "lib/" @@ -61,7 +61,7 @@ }, "dependencies": { "@gar/promise-retry": "^1.0.0", - "@npmcli/arborist": "^9.7.0", + "@npmcli/arborist": "^9.9.0", "@npmcli/package-json": "^7.0.0", "@npmcli/run-script": "^10.0.0", "ci-info": "^4.0.0", diff --git a/deps/npm/node_modules/libnpmfund/package.json b/deps/npm/node_modules/libnpmfund/package.json index ab5b5a86d98..a6dc15e4b72 100644 --- a/deps/npm/node_modules/libnpmfund/package.json +++ b/deps/npm/node_modules/libnpmfund/package.json @@ -1,6 +1,6 @@ { "name": "libnpmfund", - "version": "7.0.23", + "version": "7.0.25", "main": "lib/index.js", "files": [ "bin/", @@ -46,7 +46,7 @@ "tap": "^16.3.8" }, "dependencies": { - "@npmcli/arborist": "^9.7.0" + "@npmcli/arborist": "^9.9.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" diff --git a/deps/npm/node_modules/libnpmpack/lib/index.js b/deps/npm/node_modules/libnpmpack/lib/index.js index df6d35cb172..6c8ee3fd633 100644 --- a/deps/npm/node_modules/libnpmpack/lib/index.js +++ b/deps/npm/node_modules/libnpmpack/lib/index.js @@ -37,7 +37,7 @@ async function pack (spec = 'file:.', opts = {}) { // check for explicit `false` so the default behavior is to skip writing to disk if (opts.dryRun === false) { const filename = `${manifest.name}-${manifest.version}.tgz` - .replace(/^@/, '').replace(/\//, '-') + .replace(/^@/, '').replace(/[/\\]/g, '-') const destination = path.resolve(opts.packDestination, filename) await writeFile(destination, tarball) } diff --git a/deps/npm/node_modules/libnpmpack/package.json b/deps/npm/node_modules/libnpmpack/package.json index 58ff8edc24d..92aa96af640 100644 --- a/deps/npm/node_modules/libnpmpack/package.json +++ b/deps/npm/node_modules/libnpmpack/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpack", - "version": "9.1.9", + "version": "9.1.11", "description": "Programmatic API for the bits behind npm pack", "author": "GitHub Inc.", "main": "lib/index.js", @@ -37,7 +37,7 @@ "bugs": "https://github.com/npm/libnpmpack/issues", "homepage": "https://npmjs.com/package/libnpmpack", "dependencies": { - "@npmcli/arborist": "^9.7.0", + "@npmcli/arborist": "^9.9.0", "@npmcli/run-script": "^10.0.0", "npm-package-arg": "^13.0.0", "pacote": "^21.0.2" diff --git a/deps/npm/node_modules/node-gyp/.release-please-manifest.json b/deps/npm/node_modules/node-gyp/.release-please-manifest.json index af7e1d8db13..7cf5faf7112 100644 --- a/deps/npm/node_modules/node-gyp/.release-please-manifest.json +++ b/deps/npm/node_modules/node-gyp/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "12.3.0" + ".": "12.4.0" } diff --git a/deps/npm/node_modules/node-gyp/CHANGELOG.md b/deps/npm/node_modules/node-gyp/CHANGELOG.md index 1b02c2184ab..83881ed2a39 100644 --- a/deps/npm/node_modules/node-gyp/CHANGELOG.md +++ b/deps/npm/node_modules/node-gyp/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## [12.4.0](https://github.com/nodejs/node-gyp/compare/v12.3.0...v12.4.0) (2026-05-15) + + +### Features + +* update gyp-next to v0.22.2 ([#3316](https://github.com/nodejs/node-gyp/issues/3316)) ([8ea71e5](https://github.com/nodejs/node-gyp/commit/8ea71e5a0d5577f8f780df7597fa1f94089e1be4)) + + +### Bug Fixes + +* retry downloads on retryable errors ([#3308](https://github.com/nodejs/node-gyp/issues/3308)) ([0793489](https://github.com/nodejs/node-gyp/commit/0793489b961c2cbf6c6b2182d968d0c262c3b573)) +* stop testing end-of-life Node.js v20 ([#3315](https://github.com/nodejs/node-gyp/issues/3315)) ([5c0ec47](https://github.com/nodejs/node-gyp/commit/5c0ec47797a18d3e65f0c4c83e5812289191cfe1)) +* test on Node.js v26 ([#3314](https://github.com/nodejs/node-gyp/issues/3314)) ([0e65639](https://github.com/nodejs/node-gyp/commit/0e65639baa8b64b5fecec3820a4f07dc7c4a42ad)) + + +### Miscellaneous + +* add workflow_dispatch trigger to tests workflow ([#3299](https://github.com/nodejs/node-gyp/issues/3299)) ([b2fcdcd](https://github.com/nodejs/node-gyp/commit/b2fcdcdd6aebdf0ab6d7d296fcabccf188883e01)) + ## [12.3.0](https://github.com/nodejs/node-gyp/compare/v12.2.0...v12.3.0) (2026-04-21) diff --git a/deps/npm/node_modules/node-gyp/gyp/.release-please-manifest.json b/deps/npm/node_modules/node-gyp/gyp/.release-please-manifest.json index 9242a4094d9..762fc35f4ce 100644 --- a/deps/npm/node_modules/node-gyp/gyp/.release-please-manifest.json +++ b/deps/npm/node_modules/node-gyp/gyp/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.22.1" + ".": "0.22.2" } diff --git a/deps/npm/node_modules/node-gyp/gyp/pyproject.toml b/deps/npm/node_modules/node-gyp/gyp/pyproject.toml index 239bef7844a..487cb75002d 100644 --- a/deps/npm/node_modules/node-gyp/gyp/pyproject.toml +++ b/deps/npm/node_modules/node-gyp/gyp/pyproject.toml @@ -4,20 +4,20 @@ build-backend = "setuptools.build_meta" [project] name = "gyp-next" -version = "0.22.1" +version = "0.22.2" authors = [ { name="Node.js contributors", email="ryzokuken@disroot.org" }, ] description = "A fork of the GYP build system for use in the Node.js projects" readme = "README.md" -license = { file="LICENSE" } +license = "BSD-3-Clause" +license-files = ["LICENSE"] requires-python = ">=3.9" -dependencies = ["packaging>=24.0", "setuptools>=69.5.1"] +dependencies = ["packaging>=24.0", "setuptools>=77.0.3"] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", diff --git a/deps/npm/node_modules/node-gyp/lib/download.js b/deps/npm/node_modules/node-gyp/lib/download.js index a9866d8a63a..dfaca798cf8 100644 --- a/deps/npm/node_modules/node-gyp/lib/download.js +++ b/deps/npm/node_modules/node-gyp/lib/download.js @@ -1,5 +1,5 @@ const { Readable } = require('stream') -const { EnvHttpProxyAgent } = require('undici') +const { Agent, EnvHttpProxyAgent, RetryAgent, fetch } = require('undici') const { promises: fs } = require('graceful-fs') const log = require('./log') @@ -48,7 +48,7 @@ async function createDispatcher (gyp) { const env = process.env const hasProxyEnv = env.http_proxy || env.HTTP_PROXY || env.https_proxy || env.HTTPS_PROXY if (!gyp.opts.proxy && !gyp.opts.cafile && !hasProxyEnv) { - return undefined + return new RetryAgent(new Agent(), { maxRetries: 3 }) } const opts = {} @@ -69,7 +69,7 @@ async function createDispatcher (gyp) { if (gyp.opts.noproxy) { opts.noProxy = gyp.opts.noproxy } - return new EnvHttpProxyAgent(opts) + return new RetryAgent(new EnvHttpProxyAgent(opts), { maxRetries: 3 }) } async function readCAFile (filename) { diff --git a/deps/npm/node_modules/node-gyp/package.json b/deps/npm/node_modules/node-gyp/package.json index 29d95ad41b6..7f579406da4 100644 --- a/deps/npm/node_modules/node-gyp/package.json +++ b/deps/npm/node_modules/node-gyp/package.json @@ -11,7 +11,7 @@ "bindings", "gyp" ], - "version": "12.3.0", + "version": "12.4.0", "installVersion": 11, "author": "Nathan Rajlich (http://tootallnate.net)", "repository": { diff --git a/deps/npm/node_modules/npm-profile/lib/index.js b/deps/npm/node_modules/npm-profile/lib/index.js index 83ab5e1b46b..734e08abb65 100644 --- a/deps/npm/node_modules/npm-profile/lib/index.js +++ b/deps/npm/node_modules/npm-profile/lib/index.js @@ -49,6 +49,33 @@ const isValidUrl = u => { } } +// npm's web-login response names the canonical npmjs registry in `doneUrl`, which a proxy/mirror forwards verbatim. +// The poll would then hit npmjs.org instead of the proxy that holds the session, so rewrite only that npmjs host to the configured registry origin, preserving the path prefix and query string. +// Any other done host is left untouched, since a non-npmjs canonical host cannot be inferred here and may be served intentionally. +const CANONICAL_REGISTRY_HOST = 'registry.npmjs.org' + +// doneUrl is already validated by isValidUrl and registry is the origin a prior +// POST /-/v1/login succeeded against, so both parse cleanly here. +const replaceDoneUrlOrigin = (doneUrl, registry) => { + if (!registry) { + return doneUrl + } + const done = new URL(doneUrl) + if (done.hostname !== CANONICAL_REGISTRY_HOST) { + return doneUrl + } + const reg = new URL(registry) + done.protocol = reg.protocol + done.host = reg.host + const prefix = reg.pathname.replace(/\/$/, '') + if (prefix && prefix !== '/' && + done.pathname !== prefix && + !done.pathname.startsWith(prefix + '/')) { + done.pathname = prefix + done.pathname + } + return done.href +} + const webAuth = async (opener, opts, body) => { try { const res = await fetch('/-/v1/login', { @@ -65,7 +92,7 @@ const webAuth = async (opener, opts, body) => { throw new WebLoginInvalidResponse('POST', res, content) } - return await webAuthOpener(opener, loginUrl, doneUrl, opts) + return await webAuthOpener(opener, loginUrl, replaceDoneUrlOrigin(doneUrl, opts.registry), opts) } catch (er) { if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) { throw new WebLoginNotSupported('POST', { diff --git a/deps/npm/node_modules/npm-profile/package.json b/deps/npm/node_modules/npm-profile/package.json index 0f97cc1efa1..bb7f23ec831 100644 --- a/deps/npm/node_modules/npm-profile/package.json +++ b/deps/npm/node_modules/npm-profile/package.json @@ -1,13 +1,13 @@ { "name": "npm-profile", - "version": "12.0.1", + "version": "12.0.2", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", "license": "ISC", "dependencies": { "npm-registry-fetch": "^19.0.0", - "proc-log": "^6.0.0" + "proc-log": "^6.1.0" }, "main": "./lib/index.js", "repository": { @@ -19,8 +19,8 @@ "lib/" ], "devDependencies": { - "@npmcli/eslint-config": "^5.0.0", - "@npmcli/template-oss": "4.27.1", + "@npmcli/eslint-config": "^7.0.0", + "@npmcli/template-oss": "5.1.1", "nock": "^13.5.6", "tap": "^16.0.1" }, @@ -46,7 +46,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.27.1", + "version": "5.1.1", "publish": true } } diff --git a/deps/npm/node_modules/pacote/lib/util/add-git-sha.js b/deps/npm/node_modules/pacote/lib/util/add-git-sha.js index 843fe5b600c..8518bff9e20 100644 --- a/deps/npm/node_modules/pacote/lib/util/add-git-sha.js +++ b/deps/npm/node_modules/pacote/lib/util/add-git-sha.js @@ -8,7 +8,10 @@ const addGitSha = (spec, sha) => { return `${base}#${sha}` } else { // don't use new URL for this, because it doesn't handle scp urls - return spec.rawSpec.replace(/#.*$/, '') + `#${sha}` + // strip the committish with indexOf/slice to avoid a regexp redos + const hashIndex = spec.rawSpec.indexOf('#') + const base = hashIndex === -1 ? spec.rawSpec : spec.rawSpec.slice(0, hashIndex) + return `${base}#${sha}` } } diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json index d7dfa447f6a..ee9bea58fc0 100644 --- a/deps/npm/node_modules/pacote/package.json +++ b/deps/npm/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "21.5.0", + "version": "21.5.1", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -28,7 +28,7 @@ "devDependencies": { "@npmcli/arborist": "^9.0.2", "@npmcli/eslint-config": "^6.0.0", - "@npmcli/template-oss": "4.29.0", + "@npmcli/template-oss": "5.1.0", "hosted-git-info": "^9.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", @@ -73,7 +73,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.29.0", + "version": "5.1.0", "windowsCI": false, "publish": "true" } diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/index.js b/deps/npm/node_modules/postcss-selector-parser/dist/index.js index 995741a7ff3..c4f9f2a2d7a 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/index.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/index.js @@ -1,17 +1,44 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _processor = _interopRequireDefault(require("./processor")); -var selectors = _interopRequireWildcard(require("./selectors")); -function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } -function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -var parser = function parser(processor) { - return new _processor["default"](processor); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; }; +var processor_1 = __importDefault(require("./processor")); +var selectors = __importStar(require("./selectors")); +var parser = function (processor) { return new processor_1.default(processor); }; Object.assign(parser, selectors); delete parser.__esModule; -var _default = parser; -exports["default"] = _default; -module.exports = exports.default; \ No newline at end of file +module.exports = parser; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/parser.js b/deps/npm/node_modules/postcss-selector-parser/dist/parser.js index e36af64dbd3..d462e71aad7 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/parser.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/parser.js @@ -1,1015 +1,1105 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _root = _interopRequireDefault(require("./selectors/root")); -var _selector = _interopRequireDefault(require("./selectors/selector")); -var _className = _interopRequireDefault(require("./selectors/className")); -var _comment = _interopRequireDefault(require("./selectors/comment")); -var _id = _interopRequireDefault(require("./selectors/id")); -var _tag = _interopRequireDefault(require("./selectors/tag")); -var _string = _interopRequireDefault(require("./selectors/string")); -var _pseudo = _interopRequireDefault(require("./selectors/pseudo")); -var _attribute = _interopRequireWildcard(require("./selectors/attribute")); -var _universal = _interopRequireDefault(require("./selectors/universal")); -var _combinator = _interopRequireDefault(require("./selectors/combinator")); -var _nesting = _interopRequireDefault(require("./selectors/nesting")); -var _sortAscending = _interopRequireDefault(require("./sortAscending")); -var _tokenize = _interopRequireWildcard(require("./tokenize")); -var tokens = _interopRequireWildcard(require("./tokenTypes")); -var types = _interopRequireWildcard(require("./selectors/types")); -var _util = require("./util"); -var _WHITESPACE_TOKENS, _Object$assign; -function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } -function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -var WHITESPACE_TOKENS = (_WHITESPACE_TOKENS = {}, _WHITESPACE_TOKENS[tokens.space] = true, _WHITESPACE_TOKENS[tokens.cr] = true, _WHITESPACE_TOKENS[tokens.feed] = true, _WHITESPACE_TOKENS[tokens.newline] = true, _WHITESPACE_TOKENS[tokens.tab] = true, _WHITESPACE_TOKENS); -var WHITESPACE_EQUIV_TOKENS = Object.assign({}, WHITESPACE_TOKENS, (_Object$assign = {}, _Object$assign[tokens.comment] = true, _Object$assign)); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +var _a, _b; +Object.defineProperty(exports, "__esModule", { value: true }); +var root_1 = __importDefault(require("./selectors/root")); +var selector_1 = __importDefault(require("./selectors/selector")); +var className_1 = __importDefault(require("./selectors/className")); +var comment_1 = __importDefault(require("./selectors/comment")); +var id_1 = __importDefault(require("./selectors/id")); +var tag_1 = __importDefault(require("./selectors/tag")); +var string_1 = __importDefault(require("./selectors/string")); +var pseudo_1 = __importDefault(require("./selectors/pseudo")); +var attribute_1 = __importStar(require("./selectors/attribute")); +var universal_1 = __importDefault(require("./selectors/universal")); +var combinator_1 = __importDefault(require("./selectors/combinator")); +var nesting_1 = __importDefault(require("./selectors/nesting")); +var sortAscending_1 = __importDefault(require("./sortAscending")); +var tokenize_1 = __importStar(require("./tokenize")); +var tokens = __importStar(require("./tokenTypes")); +var types = __importStar(require("./selectors/types")); +var util_1 = require("./util"); +var WHITESPACE_TOKENS = (_a = {}, + _a[tokens.space] = true, + _a[tokens.cr] = true, + _a[tokens.feed] = true, + _a[tokens.newline] = true, + _a[tokens.tab] = true, + _a); +var WHITESPACE_EQUIV_TOKENS = __assign(__assign({}, WHITESPACE_TOKENS), (_b = {}, _b[tokens.comment] = true, _b)); function tokenStart(token) { - return { - line: token[_tokenize.FIELDS.START_LINE], - column: token[_tokenize.FIELDS.START_COL] - }; + return { + line: token[tokenize_1.FIELDS.START_LINE], + column: token[tokenize_1.FIELDS.START_COL], + }; } function tokenEnd(token) { - return { - line: token[_tokenize.FIELDS.END_LINE], - column: token[_tokenize.FIELDS.END_COL] - }; + return { + line: token[tokenize_1.FIELDS.END_LINE], + column: token[tokenize_1.FIELDS.END_COL], + }; } function getSource(startLine, startColumn, endLine, endColumn) { - return { - start: { - line: startLine, - column: startColumn - }, - end: { - line: endLine, - column: endColumn - } - }; + return { + start: { + line: startLine, + column: startColumn, + }, + end: { + line: endLine, + column: endColumn, + }, + }; } function getTokenSource(token) { - return getSource(token[_tokenize.FIELDS.START_LINE], token[_tokenize.FIELDS.START_COL], token[_tokenize.FIELDS.END_LINE], token[_tokenize.FIELDS.END_COL]); + return getSource(token[tokenize_1.FIELDS.START_LINE], token[tokenize_1.FIELDS.START_COL], token[tokenize_1.FIELDS.END_LINE], token[tokenize_1.FIELDS.END_COL]); } function getTokenSourceSpan(startToken, endToken) { - if (!startToken) { - return undefined; - } - return getSource(startToken[_tokenize.FIELDS.START_LINE], startToken[_tokenize.FIELDS.START_COL], endToken[_tokenize.FIELDS.END_LINE], endToken[_tokenize.FIELDS.END_COL]); + if (!startToken) { + return undefined; + } + return getSource(startToken[tokenize_1.FIELDS.START_LINE], startToken[tokenize_1.FIELDS.START_COL], endToken[tokenize_1.FIELDS.END_LINE], endToken[tokenize_1.FIELDS.END_COL]); } function unescapeProp(node, prop) { - var value = node[prop]; - if (typeof value !== "string") { - return; - } - if (value.indexOf("\\") !== -1) { - (0, _util.ensureObject)(node, 'raws'); - node[prop] = (0, _util.unesc)(value); - if (node.raws[prop] === undefined) { - node.raws[prop] = value; + var value = node[prop]; + if (typeof value !== "string") { + return; } - } - return node; + if (value.indexOf("\\") !== -1) { + (0, util_1.ensureObject)(node, "raws"); + node[prop] = (0, util_1.unesc)(value); + if (node.raws[prop] === undefined) { + node.raws[prop] = value; + } + } + return node; } function indexesOf(array, item) { - var i = -1; - var indexes = []; - while ((i = array.indexOf(item, i + 1)) !== -1) { - indexes.push(i); - } - return indexes; + var i = -1; + var indexes = []; + while ((i = array.indexOf(item, i + 1)) !== -1) { + indexes.push(i); + } + return indexes; } function uniqs() { - var list = Array.prototype.concat.apply([], arguments); - return list.filter(function (item, i) { - return i === list.indexOf(item); - }); + var list = Array.prototype.concat.apply([], arguments); + return list.filter(function (item, i) { return i === list.indexOf(item); }); } -var Parser = /*#__PURE__*/function () { - function Parser(rule, options) { - if (options === void 0) { - options = {}; +var Parser = /** @class */ (function () { + function Parser(rule, options) { + if (options === void 0) { options = {}; } + this.rule = rule; + this.options = Object.assign({ lossy: false, safe: false }, options); + this.position = 0; + this.nestingDepth = 0; + this.maxNestingDepth = (0, util_1.resolveMaxNestingDepth)(this.options.maxNestingDepth); + this.css = typeof this.rule === "string" ? this.rule : this.rule.selector; + this.tokens = (0, tokenize_1.default)({ + css: this.css, + error: this._errorGenerator(), + safe: this.options.safe, + }); + var rootSource = getTokenSourceSpan(this.tokens[0], this.tokens[this.tokens.length - 1]); + this.root = new root_1.default({ source: rootSource }); + this.root.errorGenerator = this._errorGenerator(); + var selector = new selector_1.default({ + source: { start: { line: 1, column: 1 } }, + sourceIndex: 0, + }); + this.root.append(selector); + this.current = selector; + this.loop(); } - this.rule = rule; - this.options = Object.assign({ - lossy: false, - safe: false - }, options); - this.position = 0; - this.css = typeof this.rule === 'string' ? this.rule : this.rule.selector; - this.tokens = (0, _tokenize["default"])({ - css: this.css, - error: this._errorGenerator(), - safe: this.options.safe - }); - var rootSource = getTokenSourceSpan(this.tokens[0], this.tokens[this.tokens.length - 1]); - this.root = new _root["default"]({ - source: rootSource - }); - this.root.errorGenerator = this._errorGenerator(); - var selector = new _selector["default"]({ - source: { - start: { - line: 1, - column: 1 + Parser.prototype._errorGenerator = function () { + var _this = this; + return function (message, errorOptions) { + if (typeof _this.rule === "string") { + return new Error(message); + } + return _this.rule.error(message, errorOptions); + }; + }; + Parser.prototype.attribute = function () { + var attr = []; + var startingToken = this.currToken; + this.position++; + while (this.position < this.tokens.length && + this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) { + attr.push(this.currToken); + this.position++; } - }, - sourceIndex: 0 - }); - this.root.append(selector); - this.current = selector; - this.loop(); - } - var _proto = Parser.prototype; - _proto._errorGenerator = function _errorGenerator() { - var _this = this; - return function (message, errorOptions) { - if (typeof _this.rule === 'string') { - return new Error(message); - } - return _this.rule.error(message, errorOptions); - }; - }; - _proto.attribute = function attribute() { - var attr = []; - var startingToken = this.currToken; - this.position++; - while (this.position < this.tokens.length && this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) { - attr.push(this.currToken); - this.position++; - } - if (this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) { - return this.expected('closing square bracket', this.currToken[_tokenize.FIELDS.START_POS]); - } - var len = attr.length; - var node = { - source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]), - sourceIndex: startingToken[_tokenize.FIELDS.START_POS] + if (this.currToken[tokenize_1.FIELDS.TYPE] !== tokens.closeSquare) { + return this.expected("closing square bracket", this.currToken[tokenize_1.FIELDS.START_POS]); + } + var len = attr.length; + var node = { + source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]), + sourceIndex: startingToken[tokenize_1.FIELDS.START_POS], + }; + if (len === 1 && !~[tokens.word].indexOf(attr[0][tokenize_1.FIELDS.TYPE])) { + return this.expected("attribute", attr[0][tokenize_1.FIELDS.START_POS]); + } + var pos = 0; + var spaceBefore = ""; + var commentBefore = ""; + var lastAdded = null; + var spaceAfterMeaningfulToken = false; + while (pos < len) { + var token = attr[pos]; + var content = this.content(token); + var next = attr[pos + 1]; + switch (token[tokenize_1.FIELDS.TYPE]) { + case tokens.space: + // if ( + // len === 1 || + // pos === 0 && this.content(next) === '|' + // ) { + // return this.expected('attribute', token[TOKEN.START_POS], content); + // } + spaceAfterMeaningfulToken = true; + if (this.options.lossy) { + break; + } + if (lastAdded) { + (0, util_1.ensureObject)(node, "spaces", lastAdded); + var prevContent = node.spaces[lastAdded].after || ""; + node.spaces[lastAdded].after = prevContent + content; + var existingComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") || null; + if (existingComment) { + node.raws.spaces[lastAdded].after = existingComment + content; + } + } + else { + spaceBefore = spaceBefore + content; + commentBefore = commentBefore + content; + } + break; + case tokens.asterisk: + if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) { + node.operator = content; + lastAdded = "operator"; + } + else if ((!node.namespace || (lastAdded === "namespace" && !spaceAfterMeaningfulToken)) && + next) { + if (spaceBefore) { + (0, util_1.ensureObject)(node, "spaces", "attribute"); + node.spaces.attribute.before = spaceBefore; + spaceBefore = ""; + } + if (commentBefore) { + (0, util_1.ensureObject)(node, "raws", "spaces", "attribute"); + node.raws.spaces.attribute.before = spaceBefore; + commentBefore = ""; + } + node.namespace = (node.namespace || "") + content; + var rawValue = (0, util_1.getProp)(node, "raws", "namespace") || null; + if (rawValue) { + node.raws.namespace += content; + } + lastAdded = "namespace"; + } + spaceAfterMeaningfulToken = false; + break; + case tokens.dollar: + if (lastAdded === "value") { + var oldRawValue = (0, util_1.getProp)(node, "raws", "value"); + node.value += "$"; + if (oldRawValue) { + node.raws.value = oldRawValue + "$"; + } + break; + } + // Falls through + case tokens.caret: + if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) { + node.operator = content; + lastAdded = "operator"; + } + spaceAfterMeaningfulToken = false; + break; + case tokens.combinator: + if (content === "~" && next[tokenize_1.FIELDS.TYPE] === tokens.equals) { + node.operator = content; + lastAdded = "operator"; + } + if (content !== "|") { + spaceAfterMeaningfulToken = false; + break; + } + if (next[tokenize_1.FIELDS.TYPE] === tokens.equals) { + node.operator = content; + lastAdded = "operator"; + } + else if (!node.namespace && !node.attribute) { + node.namespace = true; + } + spaceAfterMeaningfulToken = false; + break; + case tokens.word: + if (next && + this.content(next) === "|" && + attr[pos + 2] && + attr[pos + 2][tokenize_1.FIELDS.TYPE] !== tokens.equals && // this look-ahead probably fails with comment nodes involved. + !node.operator && + !node.namespace) { + node.namespace = content; + lastAdded = "namespace"; + } + else if (!node.attribute || (lastAdded === "attribute" && !spaceAfterMeaningfulToken)) { + if (spaceBefore) { + (0, util_1.ensureObject)(node, "spaces", "attribute"); + node.spaces.attribute.before = spaceBefore; + spaceBefore = ""; + } + if (commentBefore) { + (0, util_1.ensureObject)(node, "raws", "spaces", "attribute"); + node.raws.spaces.attribute.before = commentBefore; + commentBefore = ""; + } + node.attribute = (node.attribute || "") + content; + var rawValue = (0, util_1.getProp)(node, "raws", "attribute") || null; + if (rawValue) { + node.raws.attribute += content; + } + lastAdded = "attribute"; + } + else if ((!node.value && node.value !== "") || + (lastAdded === "value" && !(spaceAfterMeaningfulToken || node.quoteMark))) { + var unescaped_1 = (0, util_1.unesc)(content); + var oldRawValue = (0, util_1.getProp)(node, "raws", "value") || ""; + var oldValue = node.value || ""; + node.value = oldValue + unescaped_1; + node.quoteMark = null; + if (unescaped_1 !== content || oldRawValue) { + (0, util_1.ensureObject)(node, "raws"); + node.raws.value = (oldRawValue || oldValue) + content; + } + lastAdded = "value"; + } + else { + var insensitive = content === "i" || content === "I"; + if ((node.value || node.value === "") && + (node.quoteMark || spaceAfterMeaningfulToken)) { + node.insensitive = insensitive; + if (!insensitive || content === "I") { + (0, util_1.ensureObject)(node, "raws"); + node.raws.insensitiveFlag = content; + } + lastAdded = "insensitive"; + if (spaceBefore) { + (0, util_1.ensureObject)(node, "spaces", "insensitive"); + node.spaces.insensitive.before = spaceBefore; + spaceBefore = ""; + } + if (commentBefore) { + (0, util_1.ensureObject)(node, "raws", "spaces", "insensitive"); + node.raws.spaces.insensitive.before = commentBefore; + commentBefore = ""; + } + } + else if (node.value || node.value === "") { + lastAdded = "value"; + node.value += content; + if (node.raws.value) { + node.raws.value += content; + } + } + } + spaceAfterMeaningfulToken = false; + break; + case tokens.str: + if (!node.attribute || !node.operator) { + return this.error("Expected an attribute followed by an operator preceding the string.", { + index: token[tokenize_1.FIELDS.START_POS], + }); + } + var _a = (0, attribute_1.unescapeValue)(content), unescaped = _a.unescaped, quoteMark = _a.quoteMark; + node.value = unescaped; + node.quoteMark = quoteMark; + lastAdded = "value"; + (0, util_1.ensureObject)(node, "raws"); + node.raws.value = content; + spaceAfterMeaningfulToken = false; + break; + case tokens.equals: + if (!node.attribute) { + return this.expected("attribute", token[tokenize_1.FIELDS.START_POS], content); + } + if (node.value) { + return this.error('Unexpected "=" found; an operator was already defined.', { + index: token[tokenize_1.FIELDS.START_POS], + }); + } + node.operator = node.operator ? node.operator + content : content; + lastAdded = "operator"; + spaceAfterMeaningfulToken = false; + break; + case tokens.comment: + if (lastAdded) { + if (spaceAfterMeaningfulToken || + (next && next[tokenize_1.FIELDS.TYPE] === tokens.space) || + lastAdded === "insensitive") { + var lastComment = (0, util_1.getProp)(node, "spaces", lastAdded, "after") || ""; + var rawLastComment = (0, util_1.getProp)(node, "raws", "spaces", lastAdded, "after") || lastComment; + (0, util_1.ensureObject)(node, "raws", "spaces", lastAdded); + node.raws.spaces[lastAdded].after = rawLastComment + content; + } + else { + var lastValue = node[lastAdded] || ""; + var rawLastValue = (0, util_1.getProp)(node, "raws", lastAdded) || lastValue; + (0, util_1.ensureObject)(node, "raws"); + node.raws[lastAdded] = rawLastValue + content; + } + } + else { + commentBefore = commentBefore + content; + } + break; + default: + return this.error("Unexpected \"".concat(content, "\" found."), { index: token[tokenize_1.FIELDS.START_POS] }); + } + pos++; + } + unescapeProp(node, "attribute"); + unescapeProp(node, "namespace"); + this.newNode(new attribute_1.default(node)); + this.position++; }; - if (len === 1 && !~[tokens.word].indexOf(attr[0][_tokenize.FIELDS.TYPE])) { - return this.expected('attribute', attr[0][_tokenize.FIELDS.START_POS]); - } - var pos = 0; - var spaceBefore = ''; - var commentBefore = ''; - var lastAdded = null; - var spaceAfterMeaningfulToken = false; - while (pos < len) { - var token = attr[pos]; - var content = this.content(token); - var next = attr[pos + 1]; - switch (token[_tokenize.FIELDS.TYPE]) { - case tokens.space: - // if ( - // len === 1 || - // pos === 0 && this.content(next) === '|' - // ) { - // return this.expected('attribute', token[TOKEN.START_POS], content); - // } - spaceAfterMeaningfulToken = true; - if (this.options.lossy) { - break; - } - if (lastAdded) { - (0, _util.ensureObject)(node, 'spaces', lastAdded); - var prevContent = node.spaces[lastAdded].after || ''; - node.spaces[lastAdded].after = prevContent + content; - var existingComment = (0, _util.getProp)(node, 'raws', 'spaces', lastAdded, 'after') || null; - if (existingComment) { - node.raws.spaces[lastAdded].after = existingComment + content; + /** + * return a node containing meaningless garbage up to (but not including) the specified token position. + * if the token position is negative, all remaining tokens are consumed. + * + * This returns an array containing a single string node if all whitespace, + * otherwise an array of comment nodes with space before and after. + * + * These tokens are not added to the current selector, the caller can add them or use them to amend + * a previous node's space metadata. + * + * In lossy mode, this returns only comments. + */ + Parser.prototype.parseWhitespaceEquivalentTokens = function (stopPosition) { + if (stopPosition < 0) { + stopPosition = this.tokens.length; + } + var startPosition = this.position; + var nodes = []; + var space = ""; + var lastComment = undefined; + do { + if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) { + if (!this.options.lossy) { + space += this.content(); + } } - } else { - spaceBefore = spaceBefore + content; - commentBefore = commentBefore + content; - } - break; - case tokens.asterisk: - if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { - node.operator = content; - lastAdded = 'operator'; - } else if ((!node.namespace || lastAdded === "namespace" && !spaceAfterMeaningfulToken) && next) { - if (spaceBefore) { - (0, _util.ensureObject)(node, 'spaces', 'attribute'); - node.spaces.attribute.before = spaceBefore; - spaceBefore = ''; + else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.comment) { + var spaces = {}; + if (space) { + spaces.before = space; + space = ""; + } + lastComment = new comment_1.default({ + value: this.content(), + source: getTokenSource(this.currToken), + sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS], + spaces: spaces, + }); + nodes.push(lastComment); } - if (commentBefore) { - (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); - node.raws.spaces.attribute.before = spaceBefore; - commentBefore = ''; + } while (++this.position < stopPosition); + if (space) { + if (lastComment) { + lastComment.spaces.after = space; } - node.namespace = (node.namespace || "") + content; - var rawValue = (0, _util.getProp)(node, 'raws', 'namespace') || null; - if (rawValue) { - node.raws.namespace += content; + else if (!this.options.lossy) { + var firstToken = this.tokens[startPosition]; + var lastToken = this.tokens[this.position - 1]; + nodes.push(new string_1.default({ + value: "", + source: getSource(firstToken[tokenize_1.FIELDS.START_LINE], firstToken[tokenize_1.FIELDS.START_COL], lastToken[tokenize_1.FIELDS.END_LINE], lastToken[tokenize_1.FIELDS.END_COL]), + sourceIndex: firstToken[tokenize_1.FIELDS.START_POS], + spaces: { before: space, after: "" }, + })); } - lastAdded = 'namespace'; - } - spaceAfterMeaningfulToken = false; - break; - case tokens.dollar: - if (lastAdded === "value") { - var oldRawValue = (0, _util.getProp)(node, 'raws', 'value'); - node.value += "$"; - if (oldRawValue) { - node.raws.value = oldRawValue + "$"; + } + return nodes; + }; + /** + * + * @param {*} nodes + */ + Parser.prototype.convertWhitespaceNodesToSpace = function (nodes, requiredSpace) { + var _this = this; + if (requiredSpace === void 0) { requiredSpace = false; } + var space = ""; + var rawSpace = ""; + nodes.forEach(function (n) { + var spaceBefore = _this.lossySpace(n.spaces.before, requiredSpace); + var rawSpaceBefore = _this.lossySpace(n.rawSpaceBefore, requiredSpace); + space += + spaceBefore + _this.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0); + rawSpace += + spaceBefore + + n.value + + _this.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0); + }); + if (rawSpace === space) { + rawSpace = undefined; + } + var result = { space: space, rawSpace: rawSpace }; + return result; + }; + Parser.prototype.isNamedCombinator = function (position) { + if (position === void 0) { position = this.position; } + return (this.tokens[position + 0] && + this.tokens[position + 0][tokenize_1.FIELDS.TYPE] === tokens.slash && + this.tokens[position + 1] && + this.tokens[position + 1][tokenize_1.FIELDS.TYPE] === tokens.word && + this.tokens[position + 2] && + this.tokens[position + 2][tokenize_1.FIELDS.TYPE] === tokens.slash); + }; + Parser.prototype.namedCombinator = function () { + if (this.isNamedCombinator()) { + var nameRaw = this.content(this.tokens[this.position + 1]); + var name = (0, util_1.unesc)(nameRaw).toLowerCase(); + var raws = {}; + if (name !== nameRaw) { + raws.value = "/".concat(nameRaw, "/"); } - break; - } - // Falls through - case tokens.caret: - if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { - node.operator = content; - lastAdded = 'operator'; - } - spaceAfterMeaningfulToken = false; - break; - case tokens.combinator: - if (content === '~' && next[_tokenize.FIELDS.TYPE] === tokens.equals) { - node.operator = content; - lastAdded = 'operator'; - } - if (content !== '|') { - spaceAfterMeaningfulToken = false; - break; - } - if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { - node.operator = content; - lastAdded = 'operator'; - } else if (!node.namespace && !node.attribute) { - node.namespace = true; - } - spaceAfterMeaningfulToken = false; - break; - case tokens.word: - if (next && this.content(next) === '|' && attr[pos + 2] && attr[pos + 2][_tokenize.FIELDS.TYPE] !== tokens.equals && - // this look-ahead probably fails with comment nodes involved. - !node.operator && !node.namespace) { - node.namespace = content; - lastAdded = 'namespace'; - } else if (!node.attribute || lastAdded === "attribute" && !spaceAfterMeaningfulToken) { - if (spaceBefore) { - (0, _util.ensureObject)(node, 'spaces', 'attribute'); - node.spaces.attribute.before = spaceBefore; - spaceBefore = ''; + var node = new combinator_1.default({ + value: "/".concat(name, "/"), + source: getSource(this.currToken[tokenize_1.FIELDS.START_LINE], this.currToken[tokenize_1.FIELDS.START_COL], this.tokens[this.position + 2][tokenize_1.FIELDS.END_LINE], this.tokens[this.position + 2][tokenize_1.FIELDS.END_COL]), + sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS], + raws: raws, + }); + this.position = this.position + 3; + return node; + } + else { + this.unexpected(); + } + }; + Parser.prototype.combinator = function () { + var _this = this; + if (this.content() === "|") { + return this.namespace(); + } + // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector. + var nextSigTokenPos = this.locateNextMeaningfulToken(this.position); + if (nextSigTokenPos < 0 || + this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.comma || + this.tokens[nextSigTokenPos][tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) { + var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); + if (nodes.length > 0) { + var last = this.current.last; + if (last) { + var _a = this.convertWhitespaceNodesToSpace(nodes), space = _a.space, rawSpace = _a.rawSpace; + if (rawSpace !== undefined) { + last.rawSpaceAfter += rawSpace; + } + last.spaces.after += space; + } + else { + nodes.forEach(function (n) { return _this.newNode(n); }); + } } - if (commentBefore) { - (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); - node.raws.spaces.attribute.before = commentBefore; - commentBefore = ''; + return; + } + var firstToken = this.currToken; + var spaceOrDescendantSelectorNodes = undefined; + if (nextSigTokenPos > this.position) { + spaceOrDescendantSelectorNodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); + } + var node; + if (this.isNamedCombinator()) { + node = this.namedCombinator(); + } + else if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.combinator) { + node = new combinator_1.default({ + value: this.content(), + source: getTokenSource(this.currToken), + sourceIndex: this.currToken[tokenize_1.FIELDS.START_POS], + }); + this.position++; + } + else if (WHITESPACE_TOKENS[this.currToken[tokenize_1.FIELDS.TYPE]]) { + // pass + } + else if (!spaceOrDescendantSelectorNodes) { + this.unexpected(); + } + if (node) { + if (spaceOrDescendantSelectorNodes) { + var _b = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes), space = _b.space, rawSpace = _b.rawSpace; + node.spaces.before = space; + node.rawSpaceBefore = rawSpace; } - node.attribute = (node.attribute || "") + content; - var _rawValue = (0, _util.getProp)(node, 'raws', 'attribute') || null; - if (_rawValue) { - node.raws.attribute += content; + } + else { + // descendant combinator + var _c = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true), space = _c.space, rawSpace = _c.rawSpace; + if (!rawSpace) { + rawSpace = space; } - lastAdded = 'attribute'; - } else if (!node.value && node.value !== "" || lastAdded === "value" && !(spaceAfterMeaningfulToken || node.quoteMark)) { - var _unescaped = (0, _util.unesc)(content); - var _oldRawValue = (0, _util.getProp)(node, 'raws', 'value') || ''; - var oldValue = node.value || ''; - node.value = oldValue + _unescaped; - node.quoteMark = null; - if (_unescaped !== content || _oldRawValue) { - (0, _util.ensureObject)(node, 'raws'); - node.raws.value = (_oldRawValue || oldValue) + content; + var spaces = {}; + var raws = { spaces: {} }; + if (space.endsWith(" ") && rawSpace.endsWith(" ")) { + spaces.before = space.slice(0, space.length - 1); + raws.spaces.before = rawSpace.slice(0, rawSpace.length - 1); } - lastAdded = 'value'; - } else { - var insensitive = content === 'i' || content === "I"; - if ((node.value || node.value === '') && (node.quoteMark || spaceAfterMeaningfulToken)) { - node.insensitive = insensitive; - if (!insensitive || content === "I") { - (0, _util.ensureObject)(node, 'raws'); - node.raws.insensitiveFlag = content; - } - lastAdded = 'insensitive'; - if (spaceBefore) { - (0, _util.ensureObject)(node, 'spaces', 'insensitive'); - node.spaces.insensitive.before = spaceBefore; - spaceBefore = ''; - } - if (commentBefore) { - (0, _util.ensureObject)(node, 'raws', 'spaces', 'insensitive'); - node.raws.spaces.insensitive.before = commentBefore; - commentBefore = ''; - } - } else if (node.value || node.value === '') { - lastAdded = 'value'; - node.value += content; - if (node.raws.value) { - node.raws.value += content; - } + else if (space[0] === " " && rawSpace[0] === " ") { + spaces.after = space.slice(1); + raws.spaces.after = rawSpace.slice(1); } - } - spaceAfterMeaningfulToken = false; - break; - case tokens.str: - if (!node.attribute || !node.operator) { - return this.error("Expected an attribute followed by an operator preceding the string.", { - index: token[_tokenize.FIELDS.START_POS] - }); - } - var _unescapeValue = (0, _attribute.unescapeValue)(content), - unescaped = _unescapeValue.unescaped, - quoteMark = _unescapeValue.quoteMark; - node.value = unescaped; - node.quoteMark = quoteMark; - lastAdded = 'value'; - (0, _util.ensureObject)(node, 'raws'); - node.raws.value = content; - spaceAfterMeaningfulToken = false; - break; - case tokens.equals: - if (!node.attribute) { - return this.expected('attribute', token[_tokenize.FIELDS.START_POS], content); - } - if (node.value) { - return this.error('Unexpected "=" found; an operator was already defined.', { - index: token[_tokenize.FIELDS.START_POS] - }); - } - node.operator = node.operator ? node.operator + content : content; - lastAdded = 'operator'; - spaceAfterMeaningfulToken = false; - break; - case tokens.comment: - if (lastAdded) { - if (spaceAfterMeaningfulToken || next && next[_tokenize.FIELDS.TYPE] === tokens.space || lastAdded === 'insensitive') { - var lastComment = (0, _util.getProp)(node, 'spaces', lastAdded, 'after') || ''; - var rawLastComment = (0, _util.getProp)(node, 'raws', 'spaces', lastAdded, 'after') || lastComment; - (0, _util.ensureObject)(node, 'raws', 'spaces', lastAdded); - node.raws.spaces[lastAdded].after = rawLastComment + content; - } else { - var lastValue = node[lastAdded] || ''; - var rawLastValue = (0, _util.getProp)(node, 'raws', lastAdded) || lastValue; - (0, _util.ensureObject)(node, 'raws'); - node.raws[lastAdded] = rawLastValue + content; + else { + raws.value = rawSpace; } - } else { - commentBefore = commentBefore + content; - } - break; - default: - return this.error("Unexpected \"" + content + "\" found.", { - index: token[_tokenize.FIELDS.START_POS] - }); - } - pos++; - } - unescapeProp(node, "attribute"); - unescapeProp(node, "namespace"); - this.newNode(new _attribute["default"](node)); - this.position++; - } - - /** - * return a node containing meaningless garbage up to (but not including) the specified token position. - * if the token position is negative, all remaining tokens are consumed. - * - * This returns an array containing a single string node if all whitespace, - * otherwise an array of comment nodes with space before and after. - * - * These tokens are not added to the current selector, the caller can add them or use them to amend - * a previous node's space metadata. - * - * In lossy mode, this returns only comments. - */; - _proto.parseWhitespaceEquivalentTokens = function parseWhitespaceEquivalentTokens(stopPosition) { - if (stopPosition < 0) { - stopPosition = this.tokens.length; - } - var startPosition = this.position; - var nodes = []; - var space = ""; - var lastComment = undefined; - do { - if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) { - if (!this.options.lossy) { - space += this.content(); - } - } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.comment) { - var spaces = {}; - if (space) { - spaces.before = space; - space = ""; - } - lastComment = new _comment["default"]({ - value: this.content(), - source: getTokenSource(this.currToken), - sourceIndex: this.currToken[_tokenize.FIELDS.START_POS], - spaces: spaces + node = new combinator_1.default({ + value: " ", + source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]), + sourceIndex: firstToken[tokenize_1.FIELDS.START_POS], + spaces: spaces, + raws: raws, + }); + } + if (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.space) { + node.spaces.after = this.optionalSpace(this.content()); + this.position++; + } + return this.newNode(node); + }; + Parser.prototype.comma = function () { + if (this.position === this.tokens.length - 1) { + this.root.trailingComma = true; + this.position++; + return; + } + this.current._inferEndPosition(); + var selector = new selector_1.default({ + source: { + start: tokenStart(this.tokens[this.position + 1]), + }, + sourceIndex: this.tokens[this.position + 1][tokenize_1.FIELDS.START_POS], }); - nodes.push(lastComment); - } - } while (++this.position < stopPosition); - if (space) { - if (lastComment) { - lastComment.spaces.after = space; - } else if (!this.options.lossy) { - var firstToken = this.tokens[startPosition]; - var lastToken = this.tokens[this.position - 1]; - nodes.push(new _string["default"]({ - value: '', - source: getSource(firstToken[_tokenize.FIELDS.START_LINE], firstToken[_tokenize.FIELDS.START_COL], lastToken[_tokenize.FIELDS.END_LINE], lastToken[_tokenize.FIELDS.END_COL]), - sourceIndex: firstToken[_tokenize.FIELDS.START_POS], - spaces: { - before: space, - after: '' - } + this.current.parent.append(selector); + this.current = selector; + this.position++; + }; + Parser.prototype.comment = function () { + var current = this.currToken; + this.newNode(new comment_1.default({ + value: this.content(), + source: getTokenSource(current), + sourceIndex: current[tokenize_1.FIELDS.START_POS], })); - } - } - return nodes; - } - - /** - * - * @param {*} nodes - */; - _proto.convertWhitespaceNodesToSpace = function convertWhitespaceNodesToSpace(nodes, requiredSpace) { - var _this2 = this; - if (requiredSpace === void 0) { - requiredSpace = false; - } - var space = ""; - var rawSpace = ""; - nodes.forEach(function (n) { - var spaceBefore = _this2.lossySpace(n.spaces.before, requiredSpace); - var rawSpaceBefore = _this2.lossySpace(n.rawSpaceBefore, requiredSpace); - space += spaceBefore + _this2.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0); - rawSpace += spaceBefore + n.value + _this2.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0); - }); - if (rawSpace === space) { - rawSpace = undefined; - } - var result = { - space: space, - rawSpace: rawSpace - }; - return result; - }; - _proto.isNamedCombinator = function isNamedCombinator(position) { - if (position === void 0) { - position = this.position; - } - return this.tokens[position + 0] && this.tokens[position + 0][_tokenize.FIELDS.TYPE] === tokens.slash && this.tokens[position + 1] && this.tokens[position + 1][_tokenize.FIELDS.TYPE] === tokens.word && this.tokens[position + 2] && this.tokens[position + 2][_tokenize.FIELDS.TYPE] === tokens.slash; - }; - _proto.namedCombinator = function namedCombinator() { - if (this.isNamedCombinator()) { - var nameRaw = this.content(this.tokens[this.position + 1]); - var name = (0, _util.unesc)(nameRaw).toLowerCase(); - var raws = {}; - if (name !== nameRaw) { - raws.value = "/" + nameRaw + "/"; - } - var node = new _combinator["default"]({ - value: "/" + name + "/", - source: getSource(this.currToken[_tokenize.FIELDS.START_LINE], this.currToken[_tokenize.FIELDS.START_COL], this.tokens[this.position + 2][_tokenize.FIELDS.END_LINE], this.tokens[this.position + 2][_tokenize.FIELDS.END_COL]), - sourceIndex: this.currToken[_tokenize.FIELDS.START_POS], - raws: raws - }); - this.position = this.position + 3; - return node; - } else { - this.unexpected(); - } - }; - _proto.combinator = function combinator() { - var _this3 = this; - if (this.content() === '|') { - return this.namespace(); - } - // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector. - var nextSigTokenPos = this.locateNextMeaningfulToken(this.position); - if (nextSigTokenPos < 0 || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.comma || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { - var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); - if (nodes.length > 0) { + this.position++; + }; + Parser.prototype.error = function (message, opts) { + throw this.root.error(message, opts); + }; + Parser.prototype.missingBackslash = function () { + return this.error("Expected a backslash preceding the semicolon.", { + index: this.currToken[tokenize_1.FIELDS.START_POS], + }); + }; + Parser.prototype.missingParenthesis = function () { + return this.expected("opening parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]); + }; + Parser.prototype.missingSquareBracket = function () { + return this.expected("opening square bracket", this.currToken[tokenize_1.FIELDS.START_POS]); + }; + Parser.prototype.unexpected = function () { + return this.error("Unexpected '".concat(this.content(), "'. Escaping special characters with \\ may help."), this.currToken[tokenize_1.FIELDS.START_POS]); + }; + Parser.prototype.unexpectedPipe = function () { + return this.error("Unexpected '|'.", this.currToken[tokenize_1.FIELDS.START_POS]); + }; + Parser.prototype.namespace = function () { + var before = (this.prevToken && this.content(this.prevToken)) || true; + if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.word) { + this.position++; + return this.word(before); + } + else if (this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.asterisk) { + this.position++; + return this.universal(before); + } + this.unexpectedPipe(); + }; + Parser.prototype.nesting = function () { + if (this.nextToken) { + var nextContent = this.content(this.nextToken); + if (nextContent === "|") { + this.position++; + return; + } + } + var current = this.currToken; + this.newNode(new nesting_1.default({ + value: this.content(), + source: getTokenSource(current), + sourceIndex: current[tokenize_1.FIELDS.START_POS], + })); + this.position++; + }; + Parser.prototype.parentheses = function () { var last = this.current.last; - if (last) { - var _this$convertWhitespa = this.convertWhitespaceNodesToSpace(nodes), - space = _this$convertWhitespa.space, - rawSpace = _this$convertWhitespa.rawSpace; - if (rawSpace !== undefined) { - last.rawSpaceAfter += rawSpace; - } - last.spaces.after += space; - } else { - nodes.forEach(function (n) { - return _this3.newNode(n); - }); - } - } - return; - } - var firstToken = this.currToken; - var spaceOrDescendantSelectorNodes = undefined; - if (nextSigTokenPos > this.position) { - spaceOrDescendantSelectorNodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); - } - var node; - if (this.isNamedCombinator()) { - node = this.namedCombinator(); - } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.combinator) { - node = new _combinator["default"]({ - value: this.content(), - source: getTokenSource(this.currToken), - sourceIndex: this.currToken[_tokenize.FIELDS.START_POS] - }); - this.position++; - } else if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) { - // pass - } else if (!spaceOrDescendantSelectorNodes) { - this.unexpected(); - } - if (node) { - if (spaceOrDescendantSelectorNodes) { - var _this$convertWhitespa2 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes), - _space = _this$convertWhitespa2.space, - _rawSpace = _this$convertWhitespa2.rawSpace; - node.spaces.before = _space; - node.rawSpaceBefore = _rawSpace; - } - } else { - // descendant combinator - var _this$convertWhitespa3 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true), - _space2 = _this$convertWhitespa3.space, - _rawSpace2 = _this$convertWhitespa3.rawSpace; - if (!_rawSpace2) { - _rawSpace2 = _space2; - } - var spaces = {}; - var raws = { - spaces: {} - }; - if (_space2.endsWith(' ') && _rawSpace2.endsWith(' ')) { - spaces.before = _space2.slice(0, _space2.length - 1); - raws.spaces.before = _rawSpace2.slice(0, _rawSpace2.length - 1); - } else if (_space2[0] === ' ' && _rawSpace2[0] === ' ') { - spaces.after = _space2.slice(1); - raws.spaces.after = _rawSpace2.slice(1); - } else { - raws.value = _rawSpace2; - } - node = new _combinator["default"]({ - value: ' ', - source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]), - sourceIndex: firstToken[_tokenize.FIELDS.START_POS], - spaces: spaces, - raws: raws - }); - } - if (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.space) { - node.spaces.after = this.optionalSpace(this.content()); - this.position++; - } - return this.newNode(node); - }; - _proto.comma = function comma() { - if (this.position === this.tokens.length - 1) { - this.root.trailingComma = true; - this.position++; - return; - } - this.current._inferEndPosition(); - var selector = new _selector["default"]({ - source: { - start: tokenStart(this.tokens[this.position + 1]) - }, - sourceIndex: this.tokens[this.position + 1][_tokenize.FIELDS.START_POS] - }); - this.current.parent.append(selector); - this.current = selector; - this.position++; - }; - _proto.comment = function comment() { - var current = this.currToken; - this.newNode(new _comment["default"]({ - value: this.content(), - source: getTokenSource(current), - sourceIndex: current[_tokenize.FIELDS.START_POS] - })); - this.position++; - }; - _proto.error = function error(message, opts) { - throw this.root.error(message, opts); - }; - _proto.missingBackslash = function missingBackslash() { - return this.error('Expected a backslash preceding the semicolon.', { - index: this.currToken[_tokenize.FIELDS.START_POS] - }); - }; - _proto.missingParenthesis = function missingParenthesis() { - return this.expected('opening parenthesis', this.currToken[_tokenize.FIELDS.START_POS]); - }; - _proto.missingSquareBracket = function missingSquareBracket() { - return this.expected('opening square bracket', this.currToken[_tokenize.FIELDS.START_POS]); - }; - _proto.unexpected = function unexpected() { - return this.error("Unexpected '" + this.content() + "'. Escaping special characters with \\ may help.", this.currToken[_tokenize.FIELDS.START_POS]); - }; - _proto.unexpectedPipe = function unexpectedPipe() { - return this.error("Unexpected '|'.", this.currToken[_tokenize.FIELDS.START_POS]); - }; - _proto.namespace = function namespace() { - var before = this.prevToken && this.content(this.prevToken) || true; - if (this.nextToken[_tokenize.FIELDS.TYPE] === tokens.word) { - this.position++; - return this.word(before); - } else if (this.nextToken[_tokenize.FIELDS.TYPE] === tokens.asterisk) { - this.position++; - return this.universal(before); - } - this.unexpectedPipe(); - }; - _proto.nesting = function nesting() { - if (this.nextToken) { - var nextContent = this.content(this.nextToken); - if (nextContent === "|") { + var unbalanced = 1; this.position++; - return; - } - } - var current = this.currToken; - this.newNode(new _nesting["default"]({ - value: this.content(), - source: getTokenSource(current), - sourceIndex: current[_tokenize.FIELDS.START_POS] - })); - this.position++; - }; - _proto.parentheses = function parentheses() { - var last = this.current.last; - var unbalanced = 1; - this.position++; - if (last && last.type === types.PSEUDO) { - var selector = new _selector["default"]({ - source: { - start: tokenStart(this.tokens[this.position]) - }, - sourceIndex: this.tokens[this.position][_tokenize.FIELDS.START_POS] - }); - var cache = this.current; - last.append(selector); - this.current = selector; - while (this.position < this.tokens.length && unbalanced) { - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { - unbalanced++; - } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { - unbalanced--; + if (last && last.type === types.PSEUDO) { + var selector = new selector_1.default({ + source: { start: tokenStart(this.tokens[this.position]) }, + sourceIndex: this.tokens[this.position][tokenize_1.FIELDS.START_POS], + }); + var cache = this.current; + last.append(selector); + this.current = selector; + // Track nesting depth so deeply nested pseudo selectors raise a + // catchable error instead of overflowing the call stack. The + // counter is restored in `finally` so the parser is never left in + // an inconsistent state, even on the error path. + this.nestingDepth++; + try { + if (this.nestingDepth > this.maxNestingDepth) { + this.error("Cannot parse selector: nesting depth exceeds the maximum of ".concat(this.maxNestingDepth, "."), { index: this.currToken[tokenize_1.FIELDS.START_POS] }); + } + while (this.position < this.tokens.length && unbalanced) { + if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) { + unbalanced++; + } + if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) { + unbalanced--; + } + if (unbalanced) { + this.parse(); + } + else { + this.current.source.end = tokenEnd(this.currToken); + this.current.parent.source.end = tokenEnd(this.currToken); + this.position++; + } + } + } + finally { + this.nestingDepth--; + } + this.current = cache; + } + else { + // I think this case should be an error. It's used to implement a basic parse of media queries + // but I don't think it's a good idea. + var parenStart = this.currToken; + var parenValue = "("; + var parenEnd = void 0; + while (this.position < this.tokens.length && unbalanced) { + if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) { + unbalanced++; + } + if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) { + unbalanced--; + } + parenEnd = this.currToken; + parenValue += this.parseParenthesisToken(this.currToken); + this.position++; + } + if (last) { + last.appendToPropertyAndEscape("value", parenValue, parenValue); + } + else { + this.newNode(new string_1.default({ + value: parenValue, + source: getSource(parenStart[tokenize_1.FIELDS.START_LINE], parenStart[tokenize_1.FIELDS.START_COL], parenEnd[tokenize_1.FIELDS.END_LINE], parenEnd[tokenize_1.FIELDS.END_COL]), + sourceIndex: parenStart[tokenize_1.FIELDS.START_POS], + })); + } } if (unbalanced) { - this.parse(); - } else { - this.current.source.end = tokenEnd(this.currToken); - this.current.parent.source.end = tokenEnd(this.currToken); - this.position++; - } - } - this.current = cache; - } else { - // I think this case should be an error. It's used to implement a basic parse of media queries - // but I don't think it's a good idea. - var parenStart = this.currToken; - var parenValue = "("; - var parenEnd; - while (this.position < this.tokens.length && unbalanced) { - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { - unbalanced++; - } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { - unbalanced--; - } - parenEnd = this.currToken; - parenValue += this.parseParenthesisToken(this.currToken); - this.position++; - } - if (last) { - last.appendToPropertyAndEscape("value", parenValue, parenValue); - } else { - this.newNode(new _string["default"]({ - value: parenValue, - source: getSource(parenStart[_tokenize.FIELDS.START_LINE], parenStart[_tokenize.FIELDS.START_COL], parenEnd[_tokenize.FIELDS.END_LINE], parenEnd[_tokenize.FIELDS.END_COL]), - sourceIndex: parenStart[_tokenize.FIELDS.START_POS] - })); - } - } - if (unbalanced) { - return this.expected('closing parenthesis', this.currToken[_tokenize.FIELDS.START_POS]); - } - }; - _proto.pseudo = function pseudo() { - var _this4 = this; - var pseudoStr = ''; - var startingToken = this.currToken; - while (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.colon) { - pseudoStr += this.content(); - this.position++; - } - if (!this.currToken) { - return this.expected(['pseudo-class', 'pseudo-element'], this.position - 1); - } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.word) { - this.splitWord(false, function (first, length) { - pseudoStr += first; - _this4.newNode(new _pseudo["default"]({ - value: pseudoStr, - source: getTokenSourceSpan(startingToken, _this4.currToken), - sourceIndex: startingToken[_tokenize.FIELDS.START_POS] + return this.expected("closing parenthesis", this.currToken[tokenize_1.FIELDS.START_POS]); + } + }; + Parser.prototype.pseudo = function () { + var _this = this; + var pseudoStr = ""; + var startingToken = this.currToken; + while (this.currToken && this.currToken[tokenize_1.FIELDS.TYPE] === tokens.colon) { + pseudoStr += this.content(); + this.position++; + } + if (!this.currToken) { + return this.expected(["pseudo-class", "pseudo-element"], this.position - 1); + } + if (this.currToken[tokenize_1.FIELDS.TYPE] === tokens.word) { + this.splitWord(false, function (first, length) { + pseudoStr += first; + _this.newNode(new pseudo_1.default({ + value: pseudoStr, + source: getTokenSourceSpan(startingToken, _this.currToken), + sourceIndex: startingToken[tokenize_1.FIELDS.START_POS], + })); + if (length > 1 && _this.nextToken && _this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis) { + _this.error("Misplaced parenthesis.", { + index: _this.nextToken[tokenize_1.FIELDS.START_POS], + }); + } + }); + } + else { + return this.expected(["pseudo-class", "pseudo-element"], this.currToken[tokenize_1.FIELDS.START_POS]); + } + }; + Parser.prototype.space = function () { + var content = this.content(); + // Handle space before and after the selector + if (this.position === 0 || + this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.comma || + this.prevToken[tokenize_1.FIELDS.TYPE] === tokens.openParenthesis || + this.current.nodes.every(function (node) { return node.type === "comment"; })) { + this.spaces = this.optionalSpace(content); + this.position++; + } + else if (this.position === this.tokens.length - 1 || + this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.comma || + this.nextToken[tokenize_1.FIELDS.TYPE] === tokens.closeParenthesis) { + this.current.last.spaces.after = this.optionalSpace(content); + this.position++; + } + else { + this.combinator(); + } + }; + Parser.prototype.string = function () { + var current = this.currToken; + this.newNode(new string_1.default({ + value: this.content(), + source: getTokenSource(current), + sourceIndex: current[tokenize_1.FIELDS.START_POS], })); - if (length > 1 && _this4.nextToken && _this4.nextToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { - _this4.error('Misplaced parenthesis.', { - index: _this4.nextToken[_tokenize.FIELDS.START_POS] - }); - } - }); - } else { - return this.expected(['pseudo-class', 'pseudo-element'], this.currToken[_tokenize.FIELDS.START_POS]); - } - }; - _proto.space = function space() { - var content = this.content(); - // Handle space before and after the selector - if (this.position === 0 || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.comma || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis || this.current.nodes.every(function (node) { - return node.type === 'comment'; - })) { - this.spaces = this.optionalSpace(content); - this.position++; - } else if (this.position === this.tokens.length - 1 || this.nextToken[_tokenize.FIELDS.TYPE] === tokens.comma || this.nextToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { - this.current.last.spaces.after = this.optionalSpace(content); - this.position++; - } else { - this.combinator(); - } - }; - _proto.string = function string() { - var current = this.currToken; - this.newNode(new _string["default"]({ - value: this.content(), - source: getTokenSource(current), - sourceIndex: current[_tokenize.FIELDS.START_POS] - })); - this.position++; - }; - _proto.universal = function universal(namespace) { - var nextToken = this.nextToken; - if (nextToken && this.content(nextToken) === '|') { - this.position++; - return this.namespace(); - } - var current = this.currToken; - this.newNode(new _universal["default"]({ - value: this.content(), - source: getTokenSource(current), - sourceIndex: current[_tokenize.FIELDS.START_POS] - }), namespace); - this.position++; - }; - _proto.splitWord = function splitWord(namespace, firstCallback) { - var _this5 = this; - var nextToken = this.nextToken; - var word = this.content(); - while (nextToken && ~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[_tokenize.FIELDS.TYPE])) { - this.position++; - var current = this.content(); - word += current; - if (current.lastIndexOf('\\') === current.length - 1) { - var next = this.nextToken; - if (next && next[_tokenize.FIELDS.TYPE] === tokens.space) { - word += this.requiredSpace(this.content(next)); - this.position++; - } - } - nextToken = this.nextToken; - } - var hasClass = indexesOf(word, '.').filter(function (i) { - // Allow escaped dot within class name - var escapedDot = word[i - 1] === '\\'; - // Allow decimal numbers percent in @keyframes - var isKeyframesPercent = /^\d+\.\d+%$/.test(word); - return !escapedDot && !isKeyframesPercent; - }); - var hasId = indexesOf(word, '#').filter(function (i) { - return word[i - 1] !== '\\'; + this.position++; + }; + Parser.prototype.universal = function (namespace) { + var nextToken = this.nextToken; + if (nextToken && this.content(nextToken) === "|") { + this.position++; + return this.namespace(); + } + var current = this.currToken; + this.newNode(new universal_1.default({ + value: this.content(), + source: getTokenSource(current), + sourceIndex: current[tokenize_1.FIELDS.START_POS], + }), namespace); + this.position++; + }; + Parser.prototype.splitWord = function (namespace, firstCallback) { + var _this = this; + var nextToken = this.nextToken; + var word = this.content(); + while (nextToken && + ~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[tokenize_1.FIELDS.TYPE])) { + this.position++; + var current = this.content(); + word += current; + if (current.lastIndexOf("\\") === current.length - 1) { + var next = this.nextToken; + if (next && next[tokenize_1.FIELDS.TYPE] === tokens.space) { + word += this.requiredSpace(this.content(next)); + this.position++; + } + } + nextToken = this.nextToken; + } + var hasClass = indexesOf(word, ".").filter(function (i) { + // Allow escaped dot within class name + var escapedDot = word[i - 1] === "\\"; + // Allow decimal numbers percent in @keyframes + var isKeyframesPercent = /^\d+\.\d+%$/.test(word); + return !escapedDot && !isKeyframesPercent; + }); + var hasId = indexesOf(word, "#").filter(function (i) { return word[i - 1] !== "\\"; }); + // Eliminate Sass interpolations from the list of id indexes + var interpolations = indexesOf(word, "#{"); + if (interpolations.length) { + hasId = hasId.filter(function (hashIndex) { return !~interpolations.indexOf(hashIndex); }); + } + var indices = (0, sortAscending_1.default)(uniqs(__spreadArray(__spreadArray([0], __read(hasClass), false), __read(hasId), false))); + indices.forEach(function (ind, i) { + var index = indices[i + 1] || word.length; + var value = word.slice(ind, index); + if (i === 0 && firstCallback) { + return firstCallback.call(_this, value, indices.length); + } + var node; + var current = _this.currToken; + var sourceIndex = current[tokenize_1.FIELDS.START_POS] + indices[i]; + var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1)); + if (~hasClass.indexOf(ind)) { + var classNameOpts = { + value: value.slice(1), + source: source, + sourceIndex: sourceIndex, + }; + node = new className_1.default(unescapeProp(classNameOpts, "value")); + } + else if (~hasId.indexOf(ind)) { + var idOpts = { + value: value.slice(1), + source: source, + sourceIndex: sourceIndex, + }; + node = new id_1.default(unescapeProp(idOpts, "value")); + } + else { + var tagOpts = { + value: value, + source: source, + sourceIndex: sourceIndex, + }; + unescapeProp(tagOpts, "value"); + node = new tag_1.default(tagOpts); + } + _this.newNode(node, namespace); + // Ensure that the namespace is used only once + namespace = null; + }); + this.position++; + }; + Parser.prototype.word = function (namespace) { + var nextToken = this.nextToken; + if (nextToken && this.content(nextToken) === "|") { + this.position++; + return this.namespace(); + } + return this.splitWord(namespace); + }; + Parser.prototype.loop = function () { + while (this.position < this.tokens.length) { + this.parse(true); + } + this.current._inferEndPosition(); + return this.root; + }; + Parser.prototype.parse = function (throwOnParenthesis) { + switch (this.currToken[tokenize_1.FIELDS.TYPE]) { + case tokens.space: + this.space(); + break; + case tokens.comment: + this.comment(); + break; + case tokens.openParenthesis: + this.parentheses(); + break; + case tokens.closeParenthesis: + if (throwOnParenthesis) { + this.missingParenthesis(); + } + break; + case tokens.openSquare: + this.attribute(); + break; + case tokens.dollar: + case tokens.caret: + case tokens.equals: + case tokens.word: + this.word(); + break; + case tokens.colon: + this.pseudo(); + break; + case tokens.comma: + this.comma(); + break; + case tokens.asterisk: + this.universal(); + break; + case tokens.ampersand: + this.nesting(); + break; + case tokens.slash: + case tokens.combinator: + this.combinator(); + break; + case tokens.str: + this.string(); + break; + // These cases throw; no break needed. + case tokens.closeSquare: + this.missingSquareBracket(); + case tokens.semicolon: + this.missingBackslash(); + default: + this.unexpected(); + } + }; + /** + * Helpers + */ + Parser.prototype.expected = function (description, index, found) { + if (Array.isArray(description)) { + var last = description.pop(); + description = "".concat(description.join(", "), " or ").concat(last); + } + var an = /^[aeiou]/.test(description[0]) ? "an" : "a"; + if (!found) { + return this.error("Expected ".concat(an, " ").concat(description, "."), { index: index }); + } + return this.error("Expected ".concat(an, " ").concat(description, ", found \"").concat(found, "\" instead."), { index: index }); + }; + Parser.prototype.requiredSpace = function (space) { + return this.options.lossy ? " " : space; + }; + Parser.prototype.optionalSpace = function (space) { + return this.options.lossy ? "" : space; + }; + Parser.prototype.lossySpace = function (space, required) { + if (this.options.lossy) { + return required ? " " : ""; + } + else { + return space; + } + }; + Parser.prototype.parseParenthesisToken = function (token) { + var content = this.content(token); + if (token[tokenize_1.FIELDS.TYPE] === tokens.space) { + return this.requiredSpace(content); + } + else { + return content; + } + }; + Parser.prototype.newNode = function (node, namespace) { + if (namespace) { + if (/^ +$/.test(namespace)) { + if (!this.options.lossy) { + this.spaces = (this.spaces || "") + namespace; + } + namespace = true; + } + node.namespace = namespace; + unescapeProp(node, "namespace"); + } + if (this.spaces) { + node.spaces.before = this.spaces; + this.spaces = ""; + } + return this.current.append(node); + }; + Parser.prototype.content = function (token) { + if (token === void 0) { token = this.currToken; } + return this.css.slice(token[tokenize_1.FIELDS.START_POS], token[tokenize_1.FIELDS.END_POS]); + }; + Object.defineProperty(Parser.prototype, "currToken", { + get: function () { + return this.tokens[this.position]; + }, + enumerable: false, + configurable: true }); - // Eliminate Sass interpolations from the list of id indexes - var interpolations = indexesOf(word, '#{'); - if (interpolations.length) { - hasId = hasId.filter(function (hashIndex) { - return !~interpolations.indexOf(hashIndex); - }); - } - var indices = (0, _sortAscending["default"])(uniqs([0].concat(hasClass, hasId))); - indices.forEach(function (ind, i) { - var index = indices[i + 1] || word.length; - var value = word.slice(ind, index); - if (i === 0 && firstCallback) { - return firstCallback.call(_this5, value, indices.length); - } - var node; - var current = _this5.currToken; - var sourceIndex = current[_tokenize.FIELDS.START_POS] + indices[i]; - var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1)); - if (~hasClass.indexOf(ind)) { - var classNameOpts = { - value: value.slice(1), - source: source, - sourceIndex: sourceIndex - }; - node = new _className["default"](unescapeProp(classNameOpts, "value")); - } else if (~hasId.indexOf(ind)) { - var idOpts = { - value: value.slice(1), - source: source, - sourceIndex: sourceIndex - }; - node = new _id["default"](unescapeProp(idOpts, "value")); - } else { - var tagOpts = { - value: value, - source: source, - sourceIndex: sourceIndex - }; - unescapeProp(tagOpts, "value"); - node = new _tag["default"](tagOpts); - } - _this5.newNode(node, namespace); - // Ensure that the namespace is used only once - namespace = null; + Object.defineProperty(Parser.prototype, "nextToken", { + get: function () { + return this.tokens[this.position + 1]; + }, + enumerable: false, + configurable: true }); - this.position++; - }; - _proto.word = function word(namespace) { - var nextToken = this.nextToken; - if (nextToken && this.content(nextToken) === '|') { - this.position++; - return this.namespace(); - } - return this.splitWord(namespace); - }; - _proto.loop = function loop() { - while (this.position < this.tokens.length) { - this.parse(true); - } - this.current._inferEndPosition(); - return this.root; - }; - _proto.parse = function parse(throwOnParenthesis) { - switch (this.currToken[_tokenize.FIELDS.TYPE]) { - case tokens.space: - this.space(); - break; - case tokens.comment: - this.comment(); - break; - case tokens.openParenthesis: - this.parentheses(); - break; - case tokens.closeParenthesis: - if (throwOnParenthesis) { - this.missingParenthesis(); - } - break; - case tokens.openSquare: - this.attribute(); - break; - case tokens.dollar: - case tokens.caret: - case tokens.equals: - case tokens.word: - this.word(); - break; - case tokens.colon: - this.pseudo(); - break; - case tokens.comma: - this.comma(); - break; - case tokens.asterisk: - this.universal(); - break; - case tokens.ampersand: - this.nesting(); - break; - case tokens.slash: - case tokens.combinator: - this.combinator(); - break; - case tokens.str: - this.string(); - break; - // These cases throw; no break needed. - case tokens.closeSquare: - this.missingSquareBracket(); - case tokens.semicolon: - this.missingBackslash(); - default: - this.unexpected(); - } - } - - /** - * Helpers - */; - _proto.expected = function expected(description, index, found) { - if (Array.isArray(description)) { - var last = description.pop(); - description = description.join(', ') + " or " + last; - } - var an = /^[aeiou]/.test(description[0]) ? 'an' : 'a'; - if (!found) { - return this.error("Expected " + an + " " + description + ".", { - index: index - }); - } - return this.error("Expected " + an + " " + description + ", found \"" + found + "\" instead.", { - index: index + Object.defineProperty(Parser.prototype, "prevToken", { + get: function () { + return this.tokens[this.position - 1]; + }, + enumerable: false, + configurable: true }); - }; - _proto.requiredSpace = function requiredSpace(space) { - return this.options.lossy ? ' ' : space; - }; - _proto.optionalSpace = function optionalSpace(space) { - return this.options.lossy ? '' : space; - }; - _proto.lossySpace = function lossySpace(space, required) { - if (this.options.lossy) { - return required ? ' ' : ''; - } else { - return space; - } - }; - _proto.parseParenthesisToken = function parseParenthesisToken(token) { - var content = this.content(token); - if (token[_tokenize.FIELDS.TYPE] === tokens.space) { - return this.requiredSpace(content); - } else { - return content; - } - }; - _proto.newNode = function newNode(node, namespace) { - if (namespace) { - if (/^ +$/.test(namespace)) { - if (!this.options.lossy) { - this.spaces = (this.spaces || '') + namespace; - } - namespace = true; - } - node.namespace = namespace; - unescapeProp(node, "namespace"); - } - if (this.spaces) { - node.spaces.before = this.spaces; - this.spaces = ''; - } - return this.current.append(node); - }; - _proto.content = function content(token) { - if (token === void 0) { - token = this.currToken; - } - return this.css.slice(token[_tokenize.FIELDS.START_POS], token[_tokenize.FIELDS.END_POS]); - }; - /** - * returns the index of the next non-whitespace, non-comment token. - * returns -1 if no meaningful token is found. - */ - _proto.locateNextMeaningfulToken = function locateNextMeaningfulToken(startPosition) { - if (startPosition === void 0) { - startPosition = this.position + 1; - } - var searchPosition = startPosition; - while (searchPosition < this.tokens.length) { - if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][_tokenize.FIELDS.TYPE]]) { - searchPosition++; - continue; - } else { - return searchPosition; - } - } - return -1; - }; - _createClass(Parser, [{ - key: "currToken", - get: function get() { - return this.tokens[this.position]; - } - }, { - key: "nextToken", - get: function get() { - return this.tokens[this.position + 1]; - } - }, { - key: "prevToken", - get: function get() { - return this.tokens[this.position - 1]; - } - }]); - return Parser; -}(); -exports["default"] = Parser; -module.exports = exports.default; \ No newline at end of file + /** + * returns the index of the next non-whitespace, non-comment token. + * returns -1 if no meaningful token is found. + */ + Parser.prototype.locateNextMeaningfulToken = function (startPosition) { + if (startPosition === void 0) { startPosition = this.position + 1; } + var searchPosition = startPosition; + while (searchPosition < this.tokens.length) { + if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][tokenize_1.FIELDS.TYPE]]) { + searchPosition++; + continue; + } + else { + return searchPosition; + } + } + return -1; + }; + return Parser; +}()); +exports.default = Parser; +//# sourceMappingURL=parser.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/processor.js b/deps/npm/node_modules/postcss-selector-parser/dist/processor.js index dbfa09188e6..60ed693c705 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/processor.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/processor.js @@ -1,170 +1,153 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _parser = _interopRequireDefault(require("./parser")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -var Processor = /*#__PURE__*/function () { - function Processor(func, options) { - this.func = func || function noop() {}; - this.funcRes = null; - this.options = options; - } - var _proto = Processor.prototype; - _proto._shouldUpdateSelector = function _shouldUpdateSelector(rule, options) { - if (options === void 0) { - options = {}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var parser_1 = __importDefault(require("./parser")); +var Processor = /** @class */ (function () { + function Processor(func, options) { + this.func = func || function noop() { }; + this.funcRes = null; + this.options = options; } - var merged = Object.assign({}, this.options, options); - if (merged.updateSelector === false) { - return false; - } else { - return typeof rule !== "string"; - } - }; - _proto._isLossy = function _isLossy(options) { - if (options === void 0) { - options = {}; - } - var merged = Object.assign({}, this.options, options); - if (merged.lossless === false) { - return true; - } else { - return false; - } - }; - _proto._root = function _root(rule, options) { - if (options === void 0) { - options = {}; - } - var parser = new _parser["default"](rule, this._parseOptions(options)); - return parser.root; - }; - _proto._parseOptions = function _parseOptions(options) { - return { - lossy: this._isLossy(options) + Processor.prototype._shouldUpdateSelector = function (rule, options) { + if (options === void 0) { options = {}; } + var merged = Object.assign({}, this.options, options); + if (merged.updateSelector === false) { + return false; + } + else { + return typeof rule !== "string"; + } }; - }; - _proto._run = function _run(rule, options) { - var _this = this; - if (options === void 0) { - options = {}; - } - return new Promise(function (resolve, reject) { - try { - var root = _this._root(rule, options); - Promise.resolve(_this.func(root)).then(function (transform) { - var string = undefined; - if (_this._shouldUpdateSelector(rule, options)) { - string = root.toString(); + Processor.prototype._isLossy = function (options) { + if (options === void 0) { options = {}; } + var merged = Object.assign({}, this.options, options); + if (merged.lossless === false) { + return true; + } + else { + return false; + } + }; + Processor.prototype._root = function (rule, options) { + if (options === void 0) { options = {}; } + var parser = new parser_1.default(rule, this._parseOptions(options)); + return parser.root; + }; + Processor.prototype._parseOptions = function (options) { + var merged = Object.assign({}, this.options, options); + return { + lossy: this._isLossy(merged), + maxNestingDepth: merged.maxNestingDepth, + }; + }; + Processor.prototype._stringifyOptions = function (options) { + var merged = Object.assign({}, this.options, options); + return { + maxNestingDepth: merged.maxNestingDepth, + }; + }; + Processor.prototype._run = function (rule, options) { + var _this = this; + if (options === void 0) { options = {}; } + return new Promise(function (resolve, reject) { + try { + var root_1 = _this._root(rule, options); + Promise.resolve(_this.func(root_1)) + .then(function (transform) { + var string = undefined; + if (_this._shouldUpdateSelector(rule, options)) { + string = root_1.toString(_this._stringifyOptions(options)); + rule.selector = string; + } + return { transform: transform, root: root_1, string: string }; + }) + .then(resolve, reject); + } + catch (e) { + reject(e); + return; + } + }); + }; + Processor.prototype._runSync = function (rule, options) { + if (options === void 0) { options = {}; } + var root = this._root(rule, options); + var transform = this.func(root); + if (transform && typeof transform.then === "function") { + throw new Error("Selector processor returned a promise to a synchronous call."); + } + var string = undefined; + if (options.updateSelector && typeof rule !== "string") { + string = root.toString(this._stringifyOptions(options)); rule.selector = string; - } - return { - transform: transform, - root: root, - string: string - }; - }).then(resolve, reject); - } catch (e) { - reject(e); - return; - } - }); - }; - _proto._runSync = function _runSync(rule, options) { - if (options === void 0) { - options = {}; - } - var root = this._root(rule, options); - var transform = this.func(root); - if (transform && typeof transform.then === "function") { - throw new Error("Selector processor returned a promise to a synchronous call."); - } - var string = undefined; - if (options.updateSelector && typeof rule !== "string") { - string = root.toString(); - rule.selector = string; - } - return { - transform: transform, - root: root, - string: string + } + return { transform: transform, root: root, string: string }; + }; + /** + * Process rule into a selector AST. + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {Promise} The AST of the selector after processing it. + */ + Processor.prototype.ast = function (rule, options) { + return this._run(rule, options).then(function (result) { return result.root; }); + }; + /** + * Process rule into a selector AST synchronously. + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {parser.Root} The AST of the selector after processing it. + */ + Processor.prototype.astSync = function (rule, options) { + return this._runSync(rule, options).root; + }; + /** + * Process a selector into a transformed value asynchronously + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {Promise} The value returned by the processor. + */ + Processor.prototype.transform = function (rule, options) { + return this._run(rule, options).then(function (result) { return result.transform; }); + }; + /** + * Process a selector into a transformed value synchronously. + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {any} The value returned by the processor. + */ + Processor.prototype.transformSync = function (rule, options) { + return this._runSync(rule, options).transform; + }; + /** + * Process a selector into a new selector string asynchronously. + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {string} the selector after processing. + */ + Processor.prototype.process = function (rule, options) { + var _this = this; + return this._run(rule, options).then(function (result) { return result.string || result.root.toString(_this._stringifyOptions(options)); }); + }; + /** + * Process a selector into a new selector string synchronously. + * + * @param rule {postcss.Rule | string} The css selector to be processed + * @param options The options for processing + * @returns {string} the selector after processing. + */ + Processor.prototype.processSync = function (rule, options) { + var result = this._runSync(rule, options); + return result.string || result.root.toString(this._stringifyOptions(options)); }; - } - - /** - * Process rule into a selector AST. - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {Promise} The AST of the selector after processing it. - */; - _proto.ast = function ast(rule, options) { - return this._run(rule, options).then(function (result) { - return result.root; - }); - } - - /** - * Process rule into a selector AST synchronously. - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {parser.Root} The AST of the selector after processing it. - */; - _proto.astSync = function astSync(rule, options) { - return this._runSync(rule, options).root; - } - - /** - * Process a selector into a transformed value asynchronously - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {Promise} The value returned by the processor. - */; - _proto.transform = function transform(rule, options) { - return this._run(rule, options).then(function (result) { - return result.transform; - }); - } - - /** - * Process a selector into a transformed value synchronously. - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {any} The value returned by the processor. - */; - _proto.transformSync = function transformSync(rule, options) { - return this._runSync(rule, options).transform; - } - - /** - * Process a selector into a new selector string asynchronously. - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {string} the selector after processing. - */; - _proto.process = function process(rule, options) { - return this._run(rule, options).then(function (result) { - return result.string || result.root.toString(); - }); - } - - /** - * Process a selector into a new selector string synchronously. - * - * @param rule {postcss.Rule | string} The css selector to be processed - * @param options The options for processing - * @returns {string} the selector after processing. - */; - _proto.processSync = function processSync(rule, options) { - var result = this._runSync(rule, options); - return result.string || result.root.toString(); - }; - return Processor; -}(); -exports["default"] = Processor; -module.exports = exports.default; \ No newline at end of file + return Processor; +}()); +exports.default = Processor; +//# sourceMappingURL=processor.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js index 0351a22bfa5..e1db54161fc 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js @@ -1,448 +1,440 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); exports.unescapeValue = unescapeValue; -var _cssesc = _interopRequireDefault(require("cssesc")); -var _unesc = _interopRequireDefault(require("../util/unesc")); -var _namespace = _interopRequireDefault(require("./namespace")); -var _types = require("./types"); -var _CSSESC_QUOTE_OPTIONS; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } +var cssesc_1 = __importDefault(require("cssesc")); +var unesc_1 = __importDefault(require("../util/unesc")); +var namespace_1 = __importDefault(require("./namespace")); +var types_1 = require("./types"); var deprecate = require("util-deprecate"); var WRAPPED_IN_QUOTES = /^('|")([^]*)\1$/; -var warnOfDeprecatedValueAssignment = deprecate(function () {}, "Assigning an attribute a value containing characters that might need to be escaped is deprecated. " + "Call attribute.setValue() instead."); -var warnOfDeprecatedQuotedAssignment = deprecate(function () {}, "Assigning attr.quoted is deprecated and has no effect. Assign to attr.quoteMark instead."); -var warnOfDeprecatedConstructor = deprecate(function () {}, "Constructing an Attribute selector with a value without specifying quoteMark is deprecated. Note: The value should be unescaped now."); +var warnOfDeprecatedValueAssignment = deprecate(function () { }, "Assigning an attribute a value containing characters that might need to be escaped is deprecated. " + + "Call attribute.setValue() instead."); +var warnOfDeprecatedQuotedAssignment = deprecate(function () { }, "Assigning attr.quoted is deprecated and has no effect. Assign to attr.quoteMark instead."); +var warnOfDeprecatedConstructor = deprecate(function () { }, "Constructing an Attribute selector with a value without specifying quoteMark is deprecated. Note: The value should be unescaped now."); function unescapeValue(value) { - var deprecatedUsage = false; - var quoteMark = null; - var unescaped = value; - var m = unescaped.match(WRAPPED_IN_QUOTES); - if (m) { - quoteMark = m[1]; - unescaped = m[2]; - } - unescaped = (0, _unesc["default"])(unescaped); - if (unescaped !== value) { - deprecatedUsage = true; - } - return { - deprecatedUsage: deprecatedUsage, - unescaped: unescaped, - quoteMark: quoteMark - }; -} -function handleDeprecatedContructorOpts(opts) { - if (opts.quoteMark !== undefined) { - return opts; - } - if (opts.value === undefined) { - return opts; - } - warnOfDeprecatedConstructor(); - var _unescapeValue = unescapeValue(opts.value), - quoteMark = _unescapeValue.quoteMark, - unescaped = _unescapeValue.unescaped; - if (!opts.raws) { - opts.raws = {}; - } - if (opts.raws.value === undefined) { - opts.raws.value = opts.value; - } - opts.value = unescaped; - opts.quoteMark = quoteMark; - return opts; -} -var Attribute = /*#__PURE__*/function (_Namespace) { - _inheritsLoose(Attribute, _Namespace); - function Attribute(opts) { - var _this; - if (opts === void 0) { - opts = {}; - } - _this = _Namespace.call(this, handleDeprecatedContructorOpts(opts)) || this; - _this.type = _types.ATTRIBUTE; - _this.raws = _this.raws || {}; - Object.defineProperty(_this.raws, 'unquoted', { - get: deprecate(function () { - return _this.value; - }, "attr.raws.unquoted is deprecated. Call attr.value instead."), - set: deprecate(function () { - return _this.value; - }, "Setting attr.raws.unquoted is deprecated and has no effect. attr.value is unescaped by default now.") - }); - _this._constructed = true; - return _this; - } - - /** - * Returns the Attribute's value quoted such that it would be legal to use - * in the value of a css file. The original value's quotation setting - * used for stringification is left unchanged. See `setValue(value, options)` - * if you want to control the quote settings of a new value for the attribute. - * - * You can also change the quotation used for the current value by setting quoteMark. - * - * Options: - * * quoteMark {'"' | "'" | null} - Use this value to quote the value. If this - * option is not set, the original value for quoteMark will be used. If - * indeterminate, a double quote is used. The legal values are: - * * `null` - the value will be unquoted and characters will be escaped as necessary. - * * `'` - the value will be quoted with a single quote and single quotes are escaped. - * * `"` - the value will be quoted with a double quote and double quotes are escaped. - * * preferCurrentQuoteMark {boolean} - if true, prefer the source quote mark - * over the quoteMark option value. - * * smart {boolean} - if true, will select a quote mark based on the value - * and the other options specified here. See the `smartQuoteMark()` - * method. - **/ - var _proto = Attribute.prototype; - _proto.getQuotedValue = function getQuotedValue(options) { - if (options === void 0) { - options = {}; - } - var quoteMark = this._determineQuoteMark(options); - var cssescopts = CSSESC_QUOTE_OPTIONS[quoteMark]; - var escaped = (0, _cssesc["default"])(this._value, cssescopts); - return escaped; - }; - _proto._determineQuoteMark = function _determineQuoteMark(options) { - return options.smart ? this.smartQuoteMark(options) : this.preferredQuoteMark(options); - } - - /** - * Set the unescaped value with the specified quotation options. The value - * provided must not include any wrapping quote marks -- those quotes will - * be interpreted as part of the value and escaped accordingly. - */; - _proto.setValue = function setValue(value, options) { - if (options === void 0) { - options = {}; + var deprecatedUsage = false; + var quoteMark = null; + var unescaped = value; + var m = unescaped.match(WRAPPED_IN_QUOTES); + if (m) { + quoteMark = m[1]; + unescaped = m[2]; } - this._value = value; - this._quoteMark = this._determineQuoteMark(options); - this._syncRawValue(); - } - - /** - * Intelligently select a quoteMark value based on the value's contents. If - * the value is a legal CSS ident, it will not be quoted. Otherwise a quote - * mark will be picked that minimizes the number of escapes. - * - * If there's no clear winner, the quote mark from these options is used, - * then the source quote mark (this is inverted if `preferCurrentQuoteMark` is - * true). If the quoteMark is unspecified, a double quote is used. - * - * @param options This takes the quoteMark and preferCurrentQuoteMark options - * from the quoteValue method. - */; - _proto.smartQuoteMark = function smartQuoteMark(options) { - var v = this.value; - var numSingleQuotes = v.replace(/[^']/g, '').length; - var numDoubleQuotes = v.replace(/[^"]/g, '').length; - if (numSingleQuotes + numDoubleQuotes === 0) { - var escaped = (0, _cssesc["default"])(v, { - isIdentifier: true - }); - if (escaped === v) { - return Attribute.NO_QUOTE; - } else { - var pref = this.preferredQuoteMark(options); - if (pref === Attribute.NO_QUOTE) { - // pick a quote mark that isn't none and see if it's smaller - var quote = this.quoteMark || options.quoteMark || Attribute.DOUBLE_QUOTE; - var opts = CSSESC_QUOTE_OPTIONS[quote]; - var quoteValue = (0, _cssesc["default"])(v, opts); - if (quoteValue.length < escaped.length) { - return quote; - } - } - return pref; - } - } else if (numDoubleQuotes === numSingleQuotes) { - return this.preferredQuoteMark(options); - } else if (numDoubleQuotes < numSingleQuotes) { - return Attribute.DOUBLE_QUOTE; - } else { - return Attribute.SINGLE_QUOTE; - } - } - - /** - * Selects the preferred quote mark based on the options and the current quote mark value. - * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)` - * instead. - */; - _proto.preferredQuoteMark = function preferredQuoteMark(options) { - var quoteMark = options.preferCurrentQuoteMark ? this.quoteMark : options.quoteMark; - if (quoteMark === undefined) { - quoteMark = options.preferCurrentQuoteMark ? options.quoteMark : this.quoteMark; - } - if (quoteMark === undefined) { - quoteMark = Attribute.DOUBLE_QUOTE; - } - return quoteMark; - }; - _proto._syncRawValue = function _syncRawValue() { - var rawValue = (0, _cssesc["default"])(this._value, CSSESC_QUOTE_OPTIONS[this.quoteMark]); - if (rawValue === this._value) { - if (this.raws) { - delete this.raws.value; - } - } else { - this.raws.value = rawValue; - } - }; - _proto._handleEscapes = function _handleEscapes(prop, value) { - if (this._constructed) { - var escaped = (0, _cssesc["default"])(value, { - isIdentifier: true - }); - if (escaped !== value) { - this.raws[prop] = escaped; - } else { - delete this.raws[prop]; - } + unescaped = (0, unesc_1.default)(unescaped); + if (unescaped !== value) { + deprecatedUsage = true; } - }; - _proto._spacesFor = function _spacesFor(name) { - var attrSpaces = { - before: '', - after: '' + return { + deprecatedUsage: deprecatedUsage, + unescaped: unescaped, + quoteMark: quoteMark, }; - var spaces = this.spaces[name] || {}; - var rawSpaces = this.raws.spaces && this.raws.spaces[name] || {}; - return Object.assign(attrSpaces, spaces, rawSpaces); - }; - _proto._stringFor = function _stringFor(name, spaceName, concat) { - if (spaceName === void 0) { - spaceName = name; - } - if (concat === void 0) { - concat = defaultAttrConcat; - } - var attrSpaces = this._spacesFor(spaceName); - return concat(this.stringifyProperty(name), attrSpaces); - } - - /** - * returns the offset of the attribute part specified relative to the - * start of the node of the output string. - * - * * "ns" - alias for "namespace" - * * "namespace" - the namespace if it exists. - * * "attribute" - the attribute name - * * "attributeNS" - the start of the attribute or its namespace - * * "operator" - the match operator of the attribute - * * "value" - The value (string or identifier) - * * "insensitive" - the case insensitivity flag; - * @param part One of the possible values inside an attribute. - * @returns -1 if the name is invalid or the value doesn't exist in this attribute. - */; - _proto.offsetOf = function offsetOf(name) { - var count = 1; - var attributeSpaces = this._spacesFor("attribute"); - count += attributeSpaces.before.length; - if (name === "namespace" || name === "ns") { - return this.namespace ? count : -1; - } - if (name === "attributeNS") { - return count; - } - count += this.namespaceString.length; - if (this.namespace) { - count += 1; - } - if (name === "attribute") { - return count; - } - count += this.stringifyProperty("attribute").length; - count += attributeSpaces.after.length; - var operatorSpaces = this._spacesFor("operator"); - count += operatorSpaces.before.length; - var operator = this.stringifyProperty("operator"); - if (name === "operator") { - return operator ? count : -1; - } - count += operator.length; - count += operatorSpaces.after.length; - var valueSpaces = this._spacesFor("value"); - count += valueSpaces.before.length; - var value = this.stringifyProperty("value"); - if (name === "value") { - return value ? count : -1; +} +function handleDeprecatedContructorOpts(opts) { + if (opts.quoteMark !== undefined) { + return opts; } - count += value.length; - count += valueSpaces.after.length; - var insensitiveSpaces = this._spacesFor("insensitive"); - count += insensitiveSpaces.before.length; - if (name === "insensitive") { - return this.insensitive ? count : -1; + if (opts.value === undefined) { + return opts; } - return -1; - }; - _proto.toString = function toString() { - var _this2 = this; - var selector = [this.rawSpaceBefore, '[']; - selector.push(this._stringFor('qualifiedAttribute', 'attribute')); - if (this.operator && (this.value || this.value === '')) { - selector.push(this._stringFor('operator')); - selector.push(this._stringFor('value')); - selector.push(this._stringFor('insensitiveFlag', 'insensitive', function (attrValue, attrSpaces) { - if (attrValue.length > 0 && !_this2.quoted && attrSpaces.before.length === 0 && !(_this2.spaces.value && _this2.spaces.value.after)) { - attrSpaces.before = " "; - } - return defaultAttrConcat(attrValue, attrSpaces); - })); + warnOfDeprecatedConstructor(); + var _a = unescapeValue(opts.value), quoteMark = _a.quoteMark, unescaped = _a.unescaped; + if (!opts.raws) { + opts.raws = {}; } - selector.push(']'); - selector.push(this.rawSpaceAfter); - return selector.join(''); - }; - _createClass(Attribute, [{ - key: "quoted", - get: function get() { - var qm = this.quoteMark; - return qm === "'" || qm === '"'; - }, - set: function set(value) { - warnOfDeprecatedQuotedAssignment(); + if (opts.raws.value === undefined) { + opts.raws.value = opts.value; } - - /** - * returns a single (`'`) or double (`"`) quote character if the value is quoted. - * returns `null` if the value is not quoted. - * returns `undefined` if the quotation state is unknown (this can happen when - * the attribute is constructed without specifying a quote mark.) - */ - }, { - key: "quoteMark", - get: function get() { - return this._quoteMark; + opts.value = unescaped; + opts.quoteMark = quoteMark; + return opts; +} +var Attribute = /** @class */ (function (_super) { + __extends(Attribute, _super); + function Attribute(opts) { + if (opts === void 0) { opts = {}; } + var _this = _super.call(this, handleDeprecatedContructorOpts(opts)) || this; + _this.type = types_1.ATTRIBUTE; + _this.raws = _this.raws || {}; + Object.defineProperty(_this.raws, "unquoted", { + get: deprecate(function () { return _this.value; }, "attr.raws.unquoted is deprecated. Call attr.value instead."), + set: deprecate(function () { return _this.value; }, "Setting attr.raws.unquoted is deprecated and has no effect. attr.value is unescaped by default now."), + }); + _this._constructed = true; + return _this; } - /** - * Set the quote mark to be used by this attribute's value. - * If the quote mark changes, the raw (escaped) value at `attr.raws.value` of the attribute - * value is updated accordingly. + * Returns the Attribute's value quoted such that it would be legal to use + * in the value of a css file. The original value's quotation setting + * used for stringification is left unchanged. See `setValue(value, options)` + * if you want to control the quote settings of a new value for the attribute. * - * @param {"'" | '"' | null} quoteMark The quote mark or `null` if the value should be unquoted. - */, - set: function set(quoteMark) { - if (!this._constructed) { - this._quoteMark = quoteMark; - return; - } - if (this._quoteMark !== quoteMark) { - this._quoteMark = quoteMark; + * You can also change the quotation used for the current value by setting quoteMark. + * + * Options: + * * quoteMark {'"' | "'" | null} - Use this value to quote the value. If this + * option is not set, the original value for quoteMark will be used. If + * indeterminate, a double quote is used. The legal values are: + * * `null` - the value will be unquoted and characters will be escaped as necessary. + * * `'` - the value will be quoted with a single quote and single quotes are escaped. + * * `"` - the value will be quoted with a double quote and double quotes are escaped. + * * preferCurrentQuoteMark {boolean} - if true, prefer the source quote mark + * over the quoteMark option value. + * * smart {boolean} - if true, will select a quote mark based on the value + * and the other options specified here. See the `smartQuoteMark()` + * method. + **/ + Attribute.prototype.getQuotedValue = function (options) { + if (options === void 0) { options = {}; } + var quoteMark = this._determineQuoteMark(options); + var cssescopts = CSSESC_QUOTE_OPTIONS[quoteMark]; + var escaped = (0, cssesc_1.default)(this._value, cssescopts); + return escaped; + }; + Attribute.prototype._determineQuoteMark = function (options) { + return options.smart ? this.smartQuoteMark(options) : this.preferredQuoteMark(options); + }; + /** + * Set the unescaped value with the specified quotation options. The value + * provided must not include any wrapping quote marks -- those quotes will + * be interpreted as part of the value and escaped accordingly. + */ + Attribute.prototype.setValue = function (value, options) { + if (options === void 0) { options = {}; } + this._value = value; + this._quoteMark = this._determineQuoteMark(options); this._syncRawValue(); - } - } - }, { - key: "qualifiedAttribute", - get: function get() { - return this.qualifiedName(this.raws.attribute || this.attribute); - } - }, { - key: "insensitiveFlag", - get: function get() { - return this.insensitive ? 'i' : ''; - } - }, { - key: "value", - get: function get() { - return this._value; - }, - set: + }; /** - * Before 3.0, the value had to be set to an escaped value including any wrapped - * quote marks. In 3.0, the semantics of `Attribute.value` changed so that the value - * is unescaped during parsing and any quote marks are removed. + * Intelligently select a quoteMark value based on the value's contents. If + * the value is a legal CSS ident, it will not be quoted. Otherwise a quote + * mark will be picked that minimizes the number of escapes. * - * Because the ambiguity of this semantic change, if you set `attr.value = newValue`, - * a deprecation warning is raised when the new value contains any characters that would - * require escaping (including if it contains wrapped quotes). + * If there's no clear winner, the quote mark from these options is used, + * then the source quote mark (this is inverted if `preferCurrentQuoteMark` is + * true). If the quoteMark is unspecified, a double quote is used. * - * Instead, you should call `attr.setValue(newValue, opts)` and pass options that describe - * how the new value is quoted. + * @param options This takes the quoteMark and preferCurrentQuoteMark options + * from the quoteValue method. */ - function set(v) { - if (this._constructed) { - var _unescapeValue2 = unescapeValue(v), - deprecatedUsage = _unescapeValue2.deprecatedUsage, - unescaped = _unescapeValue2.unescaped, - quoteMark = _unescapeValue2.quoteMark; - if (deprecatedUsage) { - warnOfDeprecatedValueAssignment(); + Attribute.prototype.smartQuoteMark = function (options) { + var v = this.value; + var numSingleQuotes = v.replace(/[^']/g, "").length; + var numDoubleQuotes = v.replace(/[^"]/g, "").length; + if (numSingleQuotes + numDoubleQuotes === 0) { + var escaped = (0, cssesc_1.default)(v, { isIdentifier: true }); + if (escaped === v) { + return Attribute.NO_QUOTE; + } + else { + var pref = this.preferredQuoteMark(options); + if (pref === Attribute.NO_QUOTE) { + // pick a quote mark that isn't none and see if it's smaller + var quote = this.quoteMark || options.quoteMark || Attribute.DOUBLE_QUOTE; + var opts = CSSESC_QUOTE_OPTIONS[quote]; + var quoteValue = (0, cssesc_1.default)(v, opts); + if (quoteValue.length < escaped.length) { + return quote; + } + } + return pref; + } } - if (unescaped === this._value && quoteMark === this._quoteMark) { - return; + else if (numDoubleQuotes === numSingleQuotes) { + return this.preferredQuoteMark(options); } - this._value = unescaped; - this._quoteMark = quoteMark; - this._syncRawValue(); - } else { - this._value = v; - } - } - }, { - key: "insensitive", - get: function get() { - return this._insensitive; - } - + else if (numDoubleQuotes < numSingleQuotes) { + return Attribute.DOUBLE_QUOTE; + } + else { + return Attribute.SINGLE_QUOTE; + } + }; /** - * Set the case insensitive flag. - * If the case insensitive flag changes, the raw (escaped) value at `attr.raws.insensitiveFlag` - * of the attribute is updated accordingly. + * Selects the preferred quote mark based on the options and the current quote mark value. + * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)` + * instead. + */ + Attribute.prototype.preferredQuoteMark = function (options) { + var quoteMark = options.preferCurrentQuoteMark ? this.quoteMark : options.quoteMark; + if (quoteMark === undefined) { + quoteMark = options.preferCurrentQuoteMark ? options.quoteMark : this.quoteMark; + } + if (quoteMark === undefined) { + quoteMark = Attribute.DOUBLE_QUOTE; + } + return quoteMark; + }; + Object.defineProperty(Attribute.prototype, "quoted", { + get: function () { + var qm = this.quoteMark; + return qm === "'" || qm === '"'; + }, + set: function (value) { + warnOfDeprecatedQuotedAssignment(); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Attribute.prototype, "quoteMark", { + /** + * returns a single (`'`) or double (`"`) quote character if the value is quoted. + * returns `null` if the value is not quoted. + * returns `undefined` if the quotation state is unknown (this can happen when + * the attribute is constructed without specifying a quote mark.) + */ + get: function () { + return this._quoteMark; + }, + /** + * Set the quote mark to be used by this attribute's value. + * If the quote mark changes, the raw (escaped) value at `attr.raws.value` of the attribute + * value is updated accordingly. + * + * @param {"'" | '"' | null} quoteMark The quote mark or `null` if the value should be unquoted. + */ + set: function (quoteMark) { + if (!this._constructed) { + this._quoteMark = quoteMark; + return; + } + if (this._quoteMark !== quoteMark) { + this._quoteMark = quoteMark; + this._syncRawValue(); + } + }, + enumerable: false, + configurable: true + }); + Attribute.prototype._syncRawValue = function () { + var rawValue = (0, cssesc_1.default)(this._value, CSSESC_QUOTE_OPTIONS[this.quoteMark]); + if (rawValue === this._value) { + if (this.raws) { + delete this.raws.value; + } + } + else { + this.raws.value = rawValue; + } + }; + Object.defineProperty(Attribute.prototype, "qualifiedAttribute", { + get: function () { + return this.qualifiedName(this.raws.attribute || this.attribute); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Attribute.prototype, "insensitiveFlag", { + get: function () { + return this.insensitive ? "i" : ""; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Attribute.prototype, "value", { + get: function () { + return this._value; + }, + /** + * Before 3.0, the value had to be set to an escaped value including any wrapped + * quote marks. In 3.0, the semantics of `Attribute.value` changed so that the value + * is unescaped during parsing and any quote marks are removed. + * + * Because the ambiguity of this semantic change, if you set `attr.value = newValue`, + * a deprecation warning is raised when the new value contains any characters that would + * require escaping (including if it contains wrapped quotes). + * + * Instead, you should call `attr.setValue(newValue, opts)` and pass options that describe + * how the new value is quoted. + */ + set: function (v) { + if (this._constructed) { + var _a = unescapeValue(v), deprecatedUsage = _a.deprecatedUsage, unescaped = _a.unescaped, quoteMark = _a.quoteMark; + if (deprecatedUsage) { + warnOfDeprecatedValueAssignment(); + } + if (unescaped === this._value && quoteMark === this._quoteMark) { + return; + } + this._value = unescaped; + this._quoteMark = quoteMark; + this._syncRawValue(); + } + else { + this._value = v; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Attribute.prototype, "insensitive", { + get: function () { + return this._insensitive; + }, + /** + * Set the case insensitive flag. + * If the case insensitive flag changes, the raw (escaped) value at `attr.raws.insensitiveFlag` + * of the attribute is updated accordingly. + * + * @param {true | false} insensitive true if the attribute should match case-insensitively. + */ + set: function (insensitive) { + if (!insensitive) { + this._insensitive = false; + // "i" and "I" can be used in "this.raws.insensitiveFlag" to store the original notation. + // When setting `attr.insensitive = false` both should be erased to ensure correct serialization. + if (this.raws && (this.raws.insensitiveFlag === "I" || this.raws.insensitiveFlag === "i")) { + this.raws.insensitiveFlag = undefined; + } + } + this._insensitive = insensitive; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Attribute.prototype, "attribute", { + get: function () { + return this._attribute; + }, + set: function (name) { + this._handleEscapes("attribute", name); + this._attribute = name; + }, + enumerable: false, + configurable: true + }); + Attribute.prototype._handleEscapes = function (prop, value) { + if (this._constructed) { + var escaped = (0, cssesc_1.default)(value, { isIdentifier: true }); + if (escaped !== value) { + this.raws[prop] = escaped; + } + else { + delete this.raws[prop]; + } + } + }; + Attribute.prototype._spacesFor = function (name) { + var attrSpaces = { before: "", after: "" }; + var spaces = this.spaces[name] || {}; + var rawSpaces = (this.raws.spaces && this.raws.spaces[name]) || {}; + return Object.assign(attrSpaces, spaces, rawSpaces); + }; + Attribute.prototype._stringFor = function (name, spaceName, concat) { + if (spaceName === void 0) { spaceName = name; } + if (concat === void 0) { concat = defaultAttrConcat; } + var attrSpaces = this._spacesFor(spaceName); + return concat(this.stringifyProperty(name), attrSpaces); + }; + /** + * returns the offset of the attribute part specified relative to the + * start of the node of the output string. * - * @param {true | false} insensitive true if the attribute should match case-insensitively. - */, - set: function set(insensitive) { - if (!insensitive) { - this._insensitive = false; - - // "i" and "I" can be used in "this.raws.insensitiveFlag" to store the original notation. - // When setting `attr.insensitive = false` both should be erased to ensure correct serialization. - if (this.raws && (this.raws.insensitiveFlag === 'I' || this.raws.insensitiveFlag === 'i')) { - this.raws.insensitiveFlag = undefined; + * * "ns" - alias for "namespace" + * * "namespace" - the namespace if it exists. + * * "attribute" - the attribute name + * * "attributeNS" - the start of the attribute or its namespace + * * "operator" - the match operator of the attribute + * * "value" - The value (string or identifier) + * * "insensitive" - the case insensitivity flag; + * @param part One of the possible values inside an attribute. + * @returns -1 if the name is invalid or the value doesn't exist in this attribute. + */ + Attribute.prototype.offsetOf = function (name) { + var count = 1; + var attributeSpaces = this._spacesFor("attribute"); + count += attributeSpaces.before.length; + if (name === "namespace" || name === "ns") { + return this.namespace ? count : -1; } - } - this._insensitive = insensitive; - } - }, { - key: "attribute", - get: function get() { - return this._attribute; + if (name === "attributeNS") { + return count; + } + count += this.namespaceString.length; + if (this.namespace) { + count += 1; + } + if (name === "attribute") { + return count; + } + count += this.stringifyProperty("attribute").length; + count += attributeSpaces.after.length; + var operatorSpaces = this._spacesFor("operator"); + count += operatorSpaces.before.length; + var operator = this.stringifyProperty("operator"); + if (name === "operator") { + return operator ? count : -1; + } + count += operator.length; + count += operatorSpaces.after.length; + var valueSpaces = this._spacesFor("value"); + count += valueSpaces.before.length; + var value = this.stringifyProperty("value"); + if (name === "value") { + return value ? count : -1; + } + count += value.length; + count += valueSpaces.after.length; + var insensitiveSpaces = this._spacesFor("insensitive"); + count += insensitiveSpaces.before.length; + if (name === "insensitive") { + return this.insensitive ? count : -1; + } + return -1; + }; + Attribute.prototype.toString = function () { + var _this = this; + var selector = [this.rawSpaceBefore, "["]; + selector.push(this._stringFor("qualifiedAttribute", "attribute")); + if (this.operator && (this.value || this.value === "")) { + selector.push(this._stringFor("operator")); + selector.push(this._stringFor("value")); + selector.push(this._stringFor("insensitiveFlag", "insensitive", function (attrValue, attrSpaces) { + if (attrValue.length > 0 && + !_this.quoted && + attrSpaces.before.length === 0 && + !(_this.spaces.value && _this.spaces.value.after)) { + attrSpaces.before = " "; + } + return defaultAttrConcat(attrValue, attrSpaces); + })); + } + selector.push("]"); + selector.push(this.rawSpaceAfter); + return selector.join(""); + }; + Attribute.NO_QUOTE = null; + Attribute.SINGLE_QUOTE = "'"; + Attribute.DOUBLE_QUOTE = '"'; + return Attribute; +}(namespace_1.default)); +exports.default = Attribute; +var CSSESC_QUOTE_OPTIONS = (_a = { + "'": { quotes: "single", wrap: true }, + '"': { quotes: "double", wrap: true } }, - set: function set(name) { - this._handleEscapes("attribute", name); - this._attribute = name; - } - }]); - return Attribute; -}(_namespace["default"]); -exports["default"] = Attribute; -Attribute.NO_QUOTE = null; -Attribute.SINGLE_QUOTE = "'"; -Attribute.DOUBLE_QUOTE = '"'; -var CSSESC_QUOTE_OPTIONS = (_CSSESC_QUOTE_OPTIONS = { - "'": { - quotes: 'single', - wrap: true - }, - '"': { - quotes: 'double', - wrap: true - } -}, _CSSESC_QUOTE_OPTIONS[null] = { - isIdentifier: true -}, _CSSESC_QUOTE_OPTIONS); + _a[null] = { isIdentifier: true }, + _a); function defaultAttrConcat(attrValue, attrSpaces) { - return "" + attrSpaces.before + attrValue + attrSpaces.after; -} \ No newline at end of file + return "".concat(attrSpaces.before).concat(attrValue).concat(attrSpaces.after); +} +//# sourceMappingURL=attribute.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js index af325977c11..106ede2d15e 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js @@ -1,50 +1,59 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _cssesc = _interopRequireDefault(require("cssesc")); -var _util = require("../util"); -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var ClassName = /*#__PURE__*/function (_Node) { - _inheritsLoose(ClassName, _Node); - function ClassName(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.CLASS; - _this._constructed = true; - return _this; - } - var _proto = ClassName.prototype; - _proto.valueToString = function valueToString() { - return '.' + _Node.prototype.valueToString.call(this); - }; - _createClass(ClassName, [{ - key: "value", - get: function get() { - return this._value; - }, - set: function set(v) { - if (this._constructed) { - var escaped = (0, _cssesc["default"])(v, { - isIdentifier: true - }); - if (escaped !== v) { - (0, _util.ensureObject)(this, "raws"); - this.raws.value = escaped; - } else if (this.raws) { - delete this.raws.value; - } - } - this._value = v; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cssesc_1 = __importDefault(require("cssesc")); +var util_1 = require("../util"); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var ClassName = /** @class */ (function (_super) { + __extends(ClassName, _super); + function ClassName(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.CLASS; + _this._constructed = true; + return _this; } - }]); - return ClassName; -}(_node["default"]); -exports["default"] = ClassName; -module.exports = exports.default; \ No newline at end of file + Object.defineProperty(ClassName.prototype, "value", { + get: function () { + return this._value; + }, + set: function (v) { + if (this._constructed) { + var escaped = (0, cssesc_1.default)(v, { isIdentifier: true }); + if (escaped !== v) { + (0, util_1.ensureObject)(this, "raws"); + this.raws.value = escaped; + } + else if (this.raws) { + delete this.raws.value; + } + } + this._value = v; + }, + enumerable: false, + configurable: true + }); + ClassName.prototype.valueToString = function () { + return "." + _super.prototype.valueToString.call(this); + }; + return ClassName; +}(node_1.default)); +exports.default = ClassName; +//# sourceMappingURL=className.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js index c6449f43cfd..304a0303ea0 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js @@ -1,21 +1,33 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Combinator = /*#__PURE__*/function (_Node) { - _inheritsLoose(Combinator, _Node); - function Combinator(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.COMBINATOR; - return _this; - } - return Combinator; -}(_node["default"]); -exports["default"] = Combinator; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var Combinator = /** @class */ (function (_super) { + __extends(Combinator, _super); + function Combinator(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.COMBINATOR; + return _this; + } + return Combinator; +}(node_1.default)); +exports.default = Combinator; +//# sourceMappingURL=combinator.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js index 1709d5be925..1e908d04f01 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js @@ -1,21 +1,33 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Comment = /*#__PURE__*/function (_Node) { - _inheritsLoose(Comment, _Node); - function Comment(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.COMMENT; - return _this; - } - return Comment; -}(_node["default"]); -exports["default"] = Comment; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var Comment = /** @class */ (function (_super) { + __extends(Comment, _super); + function Comment(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.COMMENT; + return _this; + } + return Comment; +}(node_1.default)); +exports.default = Comment; +//# sourceMappingURL=comment.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js index 688259324cd..bf895dfe84d 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js @@ -1,65 +1,43 @@ "use strict"; - -exports.__esModule = true; -exports.universal = exports.tag = exports.string = exports.selector = exports.root = exports.pseudo = exports.nesting = exports.id = exports.comment = exports.combinator = exports.className = exports.attribute = void 0; -var _attribute = _interopRequireDefault(require("./attribute")); -var _className = _interopRequireDefault(require("./className")); -var _combinator = _interopRequireDefault(require("./combinator")); -var _comment = _interopRequireDefault(require("./comment")); -var _id = _interopRequireDefault(require("./id")); -var _nesting = _interopRequireDefault(require("./nesting")); -var _pseudo = _interopRequireDefault(require("./pseudo")); -var _root = _interopRequireDefault(require("./root")); -var _selector = _interopRequireDefault(require("./selector")); -var _string = _interopRequireDefault(require("./string")); -var _tag = _interopRequireDefault(require("./tag")); -var _universal = _interopRequireDefault(require("./universal")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -var attribute = function attribute(opts) { - return new _attribute["default"](opts); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; }; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.universal = exports.tag = exports.string = exports.selector = exports.root = exports.pseudo = exports.nesting = exports.id = exports.comment = exports.combinator = exports.className = exports.attribute = void 0; +var attribute_1 = __importDefault(require("./attribute")); +var className_1 = __importDefault(require("./className")); +var combinator_1 = __importDefault(require("./combinator")); +var comment_1 = __importDefault(require("./comment")); +var id_1 = __importDefault(require("./id")); +var nesting_1 = __importDefault(require("./nesting")); +var pseudo_1 = __importDefault(require("./pseudo")); +var root_1 = __importDefault(require("./root")); +var selector_1 = __importDefault(require("./selector")); +var string_1 = __importDefault(require("./string")); +var tag_1 = __importDefault(require("./tag")); +var universal_1 = __importDefault(require("./universal")); +var attribute = function (opts) { return new attribute_1.default(opts); }; exports.attribute = attribute; -var className = function className(opts) { - return new _className["default"](opts); -}; +var className = function (opts) { return new className_1.default(opts); }; exports.className = className; -var combinator = function combinator(opts) { - return new _combinator["default"](opts); -}; +var combinator = function (opts) { return new combinator_1.default(opts); }; exports.combinator = combinator; -var comment = function comment(opts) { - return new _comment["default"](opts); -}; +var comment = function (opts) { return new comment_1.default(opts); }; exports.comment = comment; -var id = function id(opts) { - return new _id["default"](opts); -}; +var id = function (opts) { return new id_1.default(opts); }; exports.id = id; -var nesting = function nesting(opts) { - return new _nesting["default"](opts); -}; +var nesting = function (opts) { return new nesting_1.default(opts); }; exports.nesting = nesting; -var pseudo = function pseudo(opts) { - return new _pseudo["default"](opts); -}; +var pseudo = function (opts) { return new pseudo_1.default(opts); }; exports.pseudo = pseudo; -var root = function root(opts) { - return new _root["default"](opts); -}; +var root = function (opts) { return new root_1.default(opts); }; exports.root = root; -var selector = function selector(opts) { - return new _selector["default"](opts); -}; +var selector = function (opts) { return new selector_1.default(opts); }; exports.selector = selector; -var string = function string(opts) { - return new _string["default"](opts); -}; +var string = function (opts) { return new string_1.default(opts); }; exports.string = string; -var tag = function tag(opts) { - return new _tag["default"](opts); -}; +var tag = function (opts) { return new tag_1.default(opts); }; exports.tag = tag; -var universal = function universal(opts) { - return new _universal["default"](opts); -}; -exports.universal = universal; \ No newline at end of file +var universal = function (opts) { return new universal_1.default(opts); }; +exports.universal = universal; +//# sourceMappingURL=constructors.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js index 84755cbd541..045629e81e2 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js @@ -1,321 +1,433 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var types = _interopRequireWildcard(require("./types")); -function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } -function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Container = /*#__PURE__*/function (_Node) { - _inheritsLoose(Container, _Node); - function Container(opts) { - var _this; - _this = _Node.call(this, opts) || this; - if (!_this.nodes) { - _this.nodes = []; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; } - return _this; - } - var _proto = Container.prototype; - _proto.append = function append(selector) { - selector.parent = this; - this.nodes.push(selector); - return this; - }; - _proto.prepend = function prepend(selector) { - selector.parent = this; - this.nodes.unshift(selector); - for (var id in this.indexes) { - this.indexes[id]++; - } - return this; - }; - _proto.at = function at(index) { - return this.nodes[index]; - }; - _proto.index = function index(child) { - if (typeof child === 'number') { - return child; - } - return this.nodes.indexOf(child); - }; - _proto.removeChild = function removeChild(child) { - child = this.index(child); - this.at(child).parent = undefined; - this.nodes.splice(child, 1); - var index; - for (var id in this.indexes) { - index = this.indexes[id]; - if (index >= child) { - this.indexes[id] = index - 1; - } - } - return this; - }; - _proto.removeAll = function removeAll() { - for (var _iterator = _createForOfIteratorHelperLoose(this.nodes), _step; !(_step = _iterator()).done;) { - var node = _step.value; - node.parent = undefined; - } - this.nodes = []; - return this; - }; - _proto.empty = function empty() { - return this.removeAll(); - }; - _proto.insertAfter = function insertAfter(oldNode, newNode) { - var _this$nodes; - newNode.parent = this; - var oldIndex = this.index(oldNode); - var resetNode = []; - for (var i = 2; i < arguments.length; i++) { - resetNode.push(arguments[i]); - } - (_this$nodes = this.nodes).splice.apply(_this$nodes, [oldIndex + 1, 0, newNode].concat(resetNode)); - newNode.parent = this; - var index; - for (var id in this.indexes) { - index = this.indexes[id]; - if (oldIndex < index) { - this.indexes[id] = index + arguments.length - 1; - } - } - return this; - }; - _proto.insertBefore = function insertBefore(oldNode, newNode) { - var _this$nodes2; - newNode.parent = this; - var oldIndex = this.index(oldNode); - var resetNode = []; - for (var i = 2; i < arguments.length; i++) { - resetNode.push(arguments[i]); - } - (_this$nodes2 = this.nodes).splice.apply(_this$nodes2, [oldIndex, 0, newNode].concat(resetNode)); - newNode.parent = this; - var index; - for (var id in this.indexes) { - index = this.indexes[id]; - if (index >= oldIndex) { - this.indexes[id] = index + arguments.length - 1; - } - } - return this; - }; - _proto._findChildAtPosition = function _findChildAtPosition(line, col) { - var found = undefined; - this.each(function (node) { - if (node.atPosition) { - var foundChild = node.atPosition(line, col); - if (foundChild) { - found = foundChild; - return false; + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __values = (this && this.__values) || function(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; } - } else if (node.isAtPosition(line, col)) { - found = node; - return false; - } - }); - return found; - } - - /** - * Return the most specific node at the line and column number given. - * The source location is based on the original parsed location, locations aren't - * updated as selector nodes are mutated. - * - * Note that this location is relative to the location of the first character - * of the selector, and not the location of the selector in the overall document - * when used in conjunction with postcss. - * - * If not found, returns undefined. - * @param {number} line The line number of the node to find. (1-based index) - * @param {number} col The column number of the node to find. (1-based index) - */; - _proto.atPosition = function atPosition(line, col) { - if (this.isAtPosition(line, col)) { - return this._findChildAtPosition(line, col) || this; - } else { - return undefined; - } - }; - _proto._inferEndPosition = function _inferEndPosition() { - if (this.last && this.last.source && this.last.source.end) { - this.source = this.source || {}; - this.source.end = this.source.end || {}; - Object.assign(this.source.end, this.last.source.end); - } - }; - _proto.each = function each(callback) { - if (!this.lastEach) { - this.lastEach = 0; + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +}; +var __read = (this && this.__read) || function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } - if (!this.indexes) { - this.indexes = {}; - } - this.lastEach++; - var id = this.lastEach; - this.indexes[id] = 0; - if (!this.length) { - return undefined; + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } } - var index, result; - while (this.indexes[id] < this.length) { - index = this.indexes[id]; - result = callback(this.at(index), index); - if (result === false) { - break; - } - this.indexes[id] += 1; + return ar; +}; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } } - delete this.indexes[id]; - if (result === false) { - return false; + return to.concat(ar || Array.prototype.slice.call(from)); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../util"); +var node_1 = __importDefault(require("./node")); +var types = __importStar(require("./types")); +var Container = /** @class */ (function (_super) { + __extends(Container, _super); + function Container(opts) { + var _this = _super.call(this, opts) || this; + if (!_this.nodes) { + _this.nodes = []; + } + return _this; } - }; - _proto.walk = function walk(callback) { - return this.each(function (node, i) { - var result = callback(node, i); - if (result !== false && node.length) { - result = node.walk(callback); - } - if (result === false) { - return false; - } - }); - }; - _proto.walkAttributes = function walkAttributes(callback) { - var _this2 = this; - return this.walk(function (selector) { - if (selector.type === types.ATTRIBUTE) { - return callback.call(_this2, selector); - } - }); - }; - _proto.walkClasses = function walkClasses(callback) { - var _this3 = this; - return this.walk(function (selector) { - if (selector.type === types.CLASS) { - return callback.call(_this3, selector); - } - }); - }; - _proto.walkCombinators = function walkCombinators(callback) { - var _this4 = this; - return this.walk(function (selector) { - if (selector.type === types.COMBINATOR) { - return callback.call(_this4, selector); - } - }); - }; - _proto.walkComments = function walkComments(callback) { - var _this5 = this; - return this.walk(function (selector) { - if (selector.type === types.COMMENT) { - return callback.call(_this5, selector); - } - }); - }; - _proto.walkIds = function walkIds(callback) { - var _this6 = this; - return this.walk(function (selector) { - if (selector.type === types.ID) { - return callback.call(_this6, selector); - } - }); - }; - _proto.walkNesting = function walkNesting(callback) { - var _this7 = this; - return this.walk(function (selector) { - if (selector.type === types.NESTING) { - return callback.call(_this7, selector); - } - }); - }; - _proto.walkPseudos = function walkPseudos(callback) { - var _this8 = this; - return this.walk(function (selector) { - if (selector.type === types.PSEUDO) { - return callback.call(_this8, selector); - } + Container.prototype.append = function (selector) { + selector.parent = this; + this.nodes.push(selector); + return this; + }; + Container.prototype.prepend = function (selector) { + selector.parent = this; + this.nodes.unshift(selector); + for (var id in this.indexes) { + this.indexes[id]++; + } + return this; + }; + Container.prototype.at = function (index) { + return this.nodes[index]; + }; + Container.prototype.index = function (child) { + if (typeof child === "number") { + return child; + } + return this.nodes.indexOf(child); + }; + Object.defineProperty(Container.prototype, "first", { + get: function () { + return this.at(0); + }, + enumerable: false, + configurable: true }); - }; - _proto.walkTags = function walkTags(callback) { - var _this9 = this; - return this.walk(function (selector) { - if (selector.type === types.TAG) { - return callback.call(_this9, selector); - } + Object.defineProperty(Container.prototype, "last", { + get: function () { + return this.at(this.length - 1); + }, + enumerable: false, + configurable: true }); - }; - _proto.walkUniversals = function walkUniversals(callback) { - var _this10 = this; - return this.walk(function (selector) { - if (selector.type === types.UNIVERSAL) { - return callback.call(_this10, selector); - } + Object.defineProperty(Container.prototype, "length", { + get: function () { + return this.nodes.length; + }, + enumerable: false, + configurable: true }); - }; - _proto.split = function split(callback) { - var _this11 = this; - var current = []; - return this.reduce(function (memo, node, index) { - var split = callback.call(_this11, node); - current.push(node); - if (split) { - memo.push(current); - current = []; - } else if (index === _this11.length - 1) { - memo.push(current); - } - return memo; - }, []); - }; - _proto.map = function map(callback) { - return this.nodes.map(callback); - }; - _proto.reduce = function reduce(callback, memo) { - return this.nodes.reduce(callback, memo); - }; - _proto.every = function every(callback) { - return this.nodes.every(callback); - }; - _proto.some = function some(callback) { - return this.nodes.some(callback); - }; - _proto.filter = function filter(callback) { - return this.nodes.filter(callback); - }; - _proto.sort = function sort(callback) { - return this.nodes.sort(callback); - }; - _proto.toString = function toString() { - return this.map(String).join(''); - }; - _createClass(Container, [{ - key: "first", - get: function get() { - return this.at(0); - } - }, { - key: "last", - get: function get() { - return this.at(this.length - 1); - } - }, { - key: "length", - get: function get() { - return this.nodes.length; - } - }]); - return Container; -}(_node["default"]); -exports["default"] = Container; -module.exports = exports.default; \ No newline at end of file + Container.prototype.removeChild = function (child) { + child = this.index(child); + this.at(child).parent = undefined; + this.nodes.splice(child, 1); + var index; + for (var id in this.indexes) { + index = this.indexes[id]; + if (index >= child) { + this.indexes[id] = index - 1; + } + } + return this; + }; + Container.prototype.removeAll = function () { + var e_1, _a; + try { + for (var _b = __values(this.nodes), _c = _b.next(); !_c.done; _c = _b.next()) { + var node = _c.value; + node.parent = undefined; + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } + } + this.nodes = []; + return this; + }; + Container.prototype.empty = function () { + return this.removeAll(); + }; + Container.prototype.insertAfter = function (oldNode, newNode) { + var _a; + newNode.parent = this; + var oldIndex = this.index(oldNode); + var resetNode = []; + for (var i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + (_a = this.nodes).splice.apply(_a, __spreadArray([oldIndex + 1, 0, newNode], __read(resetNode), false)); + newNode.parent = this; + var index; + for (var id in this.indexes) { + index = this.indexes[id]; + if (oldIndex < index) { + this.indexes[id] = index + arguments.length - 1; + } + } + return this; + }; + Container.prototype.insertBefore = function (oldNode, newNode) { + var _a; + newNode.parent = this; + var oldIndex = this.index(oldNode); + var resetNode = []; + for (var i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + (_a = this.nodes).splice.apply(_a, __spreadArray([oldIndex, 0, newNode], __read(resetNode), false)); + newNode.parent = this; + var index; + for (var id in this.indexes) { + index = this.indexes[id]; + if (index >= oldIndex) { + this.indexes[id] = index + arguments.length - 1; + } + } + return this; + }; + Container.prototype._findChildAtPosition = function (line, col) { + var found = undefined; + this.each(function (node) { + if (node.atPosition) { + var foundChild = node.atPosition(line, col); + if (foundChild) { + found = foundChild; + return false; + } + } + else if (node.isAtPosition(line, col)) { + found = node; + return false; + } + }); + return found; + }; + /** + * Return the most specific node at the line and column number given. + * The source location is based on the original parsed location, locations aren't + * updated as selector nodes are mutated. + * + * Note that this location is relative to the location of the first character + * of the selector, and not the location of the selector in the overall document + * when used in conjunction with postcss. + * + * If not found, returns undefined. + * @param {number} line The line number of the node to find. (1-based index) + * @param {number} col The column number of the node to find. (1-based index) + */ + Container.prototype.atPosition = function (line, col) { + if (this.isAtPosition(line, col)) { + return this._findChildAtPosition(line, col) || this; + } + else { + return undefined; + } + }; + Container.prototype._inferEndPosition = function () { + if (this.last && this.last.source && this.last.source.end) { + this.source = this.source || {}; + this.source.end = this.source.end || {}; + Object.assign(this.source.end, this.last.source.end); + } + }; + Container.prototype.each = function (callback) { + if (!this.lastEach) { + this.lastEach = 0; + } + if (!this.indexes) { + this.indexes = {}; + } + this.lastEach++; + var id = this.lastEach; + this.indexes[id] = 0; + if (!this.length) { + return undefined; + } + var index, result; + while (this.indexes[id] < this.length) { + index = this.indexes[id]; + result = callback(this.at(index), index); + if (result === false) { + break; + } + this.indexes[id] += 1; + } + delete this.indexes[id]; + if (result === false) { + return false; + } + }; + Container.prototype.walk = function (callback, depth) { + if (depth === void 0) { depth = 0; } + // Bound recursion so a pathologically deep node tree raises a catchable + // error instead of overflowing the call stack (CVE-2026-9358 / CWE-674). + if (depth > util_1.MAX_NESTING_DEPTH) { + throw new Error("Cannot walk selector: nesting depth exceeds the maximum of ".concat(util_1.MAX_NESTING_DEPTH, ".")); + } + return this.each(function (node, i) { + var result = callback(node, i); + if (result !== false && node.length) { + result = node.walk(callback, depth + 1); + } + if (result === false) { + return false; + } + }); + }; + Container.prototype.walkAttributes = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.ATTRIBUTE) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkClasses = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.CLASS) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkCombinators = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.COMBINATOR) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkComments = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.COMMENT) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkIds = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.ID) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkNesting = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.NESTING) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkPseudos = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.PSEUDO) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkTags = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.TAG) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.walkUniversals = function (callback) { + var _this = this; + return this.walk(function (selector) { + if (selector.type === types.UNIVERSAL) { + return callback.call(_this, selector); + } + }); + }; + Container.prototype.split = function (callback) { + var _this = this; + var current = []; + return this.reduce(function (memo, node, index) { + var split = callback.call(_this, node); + current.push(node); + if (split) { + memo.push(current); + current = []; + } + else if (index === _this.length - 1) { + memo.push(current); + } + return memo; + }, []); + }; + Container.prototype.map = function (callback) { + return this.nodes.map(callback); + }; + Container.prototype.reduce = function (callback, memo) { + return this.nodes.reduce(callback, memo); + }; + Container.prototype.every = function (callback) { + return this.nodes.every(callback); + }; + Container.prototype.some = function (callback) { + return this.nodes.some(callback); + }; + Container.prototype.filter = function (callback) { + return this.nodes.filter(callback); + }; + Container.prototype.sort = function (callback) { + return this.nodes.sort(callback); + }; + Container.prototype.toString = function (options) { + if (options === void 0) { options = {}; } + return this._stringify(options, 0, (0, util_1.resolveMaxNestingDepth)(options.maxNestingDepth)); + }; + Container.prototype._stringify = function (options, depth, max) { + var _this = this; + return this.map(function (child) { return _this._stringifyChild(child, options, depth, max); }).join(""); + }; + // Serialize a child node. Historically `toString` used `this.map(String)`, + // which leniently coerced anything — including raw arrays inserted via + // `replaceWith(array)` / `insertBefore` / `insertAfter` (e.g. Tailwind's + // `:merge()` expansion). Fall back to `String(child)` for values that are not + // parser nodes so that behaviour is preserved. + Container.prototype._stringifyChild = function (child, options, depth, max) { + return typeof child._stringify === "function" + ? child._stringify(options, depth, max) + : String(child); + }; + return Container; +}(node_1.default)); +exports.default = Container; +//# sourceMappingURL=container.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js index f06161e97cb..b18a80efed1 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js @@ -1,58 +1,61 @@ "use strict"; - -exports.__esModule = true; -exports.isComment = exports.isCombinator = exports.isClassName = exports.isAttribute = void 0; -exports.isContainer = isContainer; -exports.isIdentifier = void 0; -exports.isNamespace = isNamespace; -exports.isNesting = void 0; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isUniversal = exports.isTag = exports.isString = exports.isSelector = exports.isRoot = exports.isPseudo = exports.isNesting = exports.isIdentifier = exports.isComment = exports.isCombinator = exports.isClassName = exports.isAttribute = void 0; exports.isNode = isNode; -exports.isPseudo = void 0; -exports.isPseudoClass = isPseudoClass; exports.isPseudoElement = isPseudoElement; -exports.isUniversal = exports.isTag = exports.isString = exports.isSelector = exports.isRoot = void 0; -var _types = require("./types"); -var _IS_TYPE; -var IS_TYPE = (_IS_TYPE = {}, _IS_TYPE[_types.ATTRIBUTE] = true, _IS_TYPE[_types.CLASS] = true, _IS_TYPE[_types.COMBINATOR] = true, _IS_TYPE[_types.COMMENT] = true, _IS_TYPE[_types.ID] = true, _IS_TYPE[_types.NESTING] = true, _IS_TYPE[_types.PSEUDO] = true, _IS_TYPE[_types.ROOT] = true, _IS_TYPE[_types.SELECTOR] = true, _IS_TYPE[_types.STRING] = true, _IS_TYPE[_types.TAG] = true, _IS_TYPE[_types.UNIVERSAL] = true, _IS_TYPE); +exports.isPseudoClass = isPseudoClass; +exports.isContainer = isContainer; +exports.isNamespace = isNamespace; +var types_1 = require("./types"); +var IS_TYPE = (_a = {}, + _a[types_1.ATTRIBUTE] = true, + _a[types_1.CLASS] = true, + _a[types_1.COMBINATOR] = true, + _a[types_1.COMMENT] = true, + _a[types_1.ID] = true, + _a[types_1.NESTING] = true, + _a[types_1.PSEUDO] = true, + _a[types_1.ROOT] = true, + _a[types_1.SELECTOR] = true, + _a[types_1.STRING] = true, + _a[types_1.TAG] = true, + _a[types_1.UNIVERSAL] = true, + _a); function isNode(node) { - return typeof node === "object" && IS_TYPE[node.type]; + return typeof node === "object" && IS_TYPE[node.type]; } function isNodeType(type, node) { - return isNode(node) && node.type === type; + return isNode(node) && node.type === type; } -var isAttribute = isNodeType.bind(null, _types.ATTRIBUTE); -exports.isAttribute = isAttribute; -var isClassName = isNodeType.bind(null, _types.CLASS); -exports.isClassName = isClassName; -var isCombinator = isNodeType.bind(null, _types.COMBINATOR); -exports.isCombinator = isCombinator; -var isComment = isNodeType.bind(null, _types.COMMENT); -exports.isComment = isComment; -var isIdentifier = isNodeType.bind(null, _types.ID); -exports.isIdentifier = isIdentifier; -var isNesting = isNodeType.bind(null, _types.NESTING); -exports.isNesting = isNesting; -var isPseudo = isNodeType.bind(null, _types.PSEUDO); -exports.isPseudo = isPseudo; -var isRoot = isNodeType.bind(null, _types.ROOT); -exports.isRoot = isRoot; -var isSelector = isNodeType.bind(null, _types.SELECTOR); -exports.isSelector = isSelector; -var isString = isNodeType.bind(null, _types.STRING); -exports.isString = isString; -var isTag = isNodeType.bind(null, _types.TAG); -exports.isTag = isTag; -var isUniversal = isNodeType.bind(null, _types.UNIVERSAL); -exports.isUniversal = isUniversal; +exports.isAttribute = isNodeType.bind(null, types_1.ATTRIBUTE); +exports.isClassName = isNodeType.bind(null, types_1.CLASS); +exports.isCombinator = isNodeType.bind(null, types_1.COMBINATOR); +exports.isComment = isNodeType.bind(null, types_1.COMMENT); +exports.isIdentifier = isNodeType.bind(null, types_1.ID); +exports.isNesting = isNodeType.bind(null, types_1.NESTING); +exports.isPseudo = isNodeType.bind(null, types_1.PSEUDO); +exports.isRoot = isNodeType.bind(null, types_1.ROOT); +exports.isSelector = isNodeType.bind(null, types_1.SELECTOR); +exports.isString = isNodeType.bind(null, types_1.STRING); +exports.isTag = isNodeType.bind(null, types_1.TAG); +exports.isUniversal = isNodeType.bind(null, types_1.UNIVERSAL); function isPseudoElement(node) { - return isPseudo(node) && node.value && (node.value.startsWith("::") || node.value.toLowerCase() === ":before" || node.value.toLowerCase() === ":after" || node.value.toLowerCase() === ":first-letter" || node.value.toLowerCase() === ":first-line"); + return ((0, exports.isPseudo)(node) && + node.value && + (node.value.startsWith("::") || + node.value.toLowerCase() === ":before" || + node.value.toLowerCase() === ":after" || + node.value.toLowerCase() === ":first-letter" || + node.value.toLowerCase() === ":first-line")); } function isPseudoClass(node) { - return isPseudo(node) && !isPseudoElement(node); + return (0, exports.isPseudo)(node) && !isPseudoElement(node); } function isContainer(node) { - return !!(isNode(node) && node.walk); + return !!(isNode(node) && node.walk); } function isNamespace(node) { - return isAttribute(node) || isTag(node); -} \ No newline at end of file + return (0, exports.isAttribute)(node) || (0, exports.isTag)(node); +} +//# sourceMappingURL=guards.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js index 8baef72860c..4fe9e73ebb0 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js @@ -1,25 +1,36 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var ID = /*#__PURE__*/function (_Node) { - _inheritsLoose(ID, _Node); - function ID(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.ID; - return _this; - } - var _proto = ID.prototype; - _proto.valueToString = function valueToString() { - return '#' + _Node.prototype.valueToString.call(this); - }; - return ID; -}(_node["default"]); -exports["default"] = ID; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var ID = /** @class */ (function (_super) { + __extends(ID, _super); + function ID(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.ID; + return _this; + } + ID.prototype.valueToString = function () { + return "#" + _super.prototype.valueToString.call(this); + }; + return ID; +}(node_1.default)); +exports.default = ID; +//# sourceMappingURL=id.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js index f1f6b7f5e63..101e8e4f4c9 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js @@ -1,21 +1,20 @@ "use strict"; - -exports.__esModule = true; -var _types = require("./types"); -Object.keys(_types).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (key in exports && exports[key] === _types[key]) return; - exports[key] = _types[key]; -}); -var _constructors = require("./constructors"); -Object.keys(_constructors).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (key in exports && exports[key] === _constructors[key]) return; - exports[key] = _constructors[key]; -}); -var _guards = require("./guards"); -Object.keys(_guards).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - if (key in exports && exports[key] === _guards[key]) return; - exports[key] = _guards[key]; -}); \ No newline at end of file +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./types"), exports); +__exportStar(require("./constructors"), exports); +__exportStar(require("./guards"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js index cc97647bd17..39f2f3ccfb7 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js @@ -1,80 +1,96 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _cssesc = _interopRequireDefault(require("cssesc")); -var _util = require("../util"); -var _node = _interopRequireDefault(require("./node")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Namespace = /*#__PURE__*/function (_Node) { - _inheritsLoose(Namespace, _Node); - function Namespace() { - return _Node.apply(this, arguments) || this; - } - var _proto = Namespace.prototype; - _proto.qualifiedName = function qualifiedName(value) { - if (this.namespace) { - return this.namespaceString + "|" + value; - } else { - return value; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cssesc_1 = __importDefault(require("cssesc")); +var util_1 = require("../util"); +var node_1 = __importDefault(require("./node")); +var Namespace = /** @class */ (function (_super) { + __extends(Namespace, _super); + function Namespace() { + return _super !== null && _super.apply(this, arguments) || this; } - }; - _proto.valueToString = function valueToString() { - return this.qualifiedName(_Node.prototype.valueToString.call(this)); - }; - _createClass(Namespace, [{ - key: "namespace", - get: function get() { - return this._namespace; - }, - set: function set(namespace) { - if (namespace === true || namespace === "*" || namespace === "&") { - this._namespace = namespace; - if (this.raws) { - delete this.raws.namespace; + Object.defineProperty(Namespace.prototype, "namespace", { + get: function () { + return this._namespace; + }, + set: function (namespace) { + if (namespace === true || namespace === "*" || namespace === "&") { + this._namespace = namespace; + if (this.raws) { + delete this.raws.namespace; + } + return; + } + var escaped = (0, cssesc_1.default)(namespace, { isIdentifier: true }); + this._namespace = namespace; + if (escaped !== namespace) { + (0, util_1.ensureObject)(this, "raws"); + this.raws.namespace = escaped; + } + else if (this.raws) { + delete this.raws.namespace; + } + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Namespace.prototype, "ns", { + get: function () { + return this._namespace; + }, + set: function (namespace) { + this.namespace = namespace; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Namespace.prototype, "namespaceString", { + get: function () { + if (this.namespace) { + var ns = this.stringifyProperty("namespace"); + if (ns === true) { + return ""; + } + else { + return ns; + } + } + else { + return ""; + } + }, + enumerable: false, + configurable: true + }); + Namespace.prototype.qualifiedName = function (value) { + if (this.namespace) { + return "".concat(this.namespaceString, "|").concat(value); } - return; - } - var escaped = (0, _cssesc["default"])(namespace, { - isIdentifier: true - }); - this._namespace = namespace; - if (escaped !== namespace) { - (0, _util.ensureObject)(this, "raws"); - this.raws.namespace = escaped; - } else if (this.raws) { - delete this.raws.namespace; - } - } - }, { - key: "ns", - get: function get() { - return this._namespace; - }, - set: function set(namespace) { - this.namespace = namespace; - } - }, { - key: "namespaceString", - get: function get() { - if (this.namespace) { - var ns = this.stringifyProperty("namespace"); - if (ns === true) { - return ''; - } else { - return ns; + else { + return value; } - } else { - return ''; - } - } - }]); - return Namespace; -}(_node["default"]); -exports["default"] = Namespace; -; -module.exports = exports.default; \ No newline at end of file + }; + Namespace.prototype.valueToString = function () { + return this.qualifiedName(_super.prototype.valueToString.call(this)); + }; + return Namespace; +}(node_1.default)); +exports.default = Namespace; +//# sourceMappingURL=namespace.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js index 218992875a6..045e5e36384 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js @@ -1,22 +1,34 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Nesting = /*#__PURE__*/function (_Node) { - _inheritsLoose(Nesting, _Node); - function Nesting(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.NESTING; - _this.value = '&'; - return _this; - } - return Nesting; -}(_node["default"]); -exports["default"] = Nesting; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var Nesting = /** @class */ (function (_super) { + __extends(Nesting, _super); + function Nesting(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.NESTING; + _this.value = "&"; + return _this; + } + return Nesting; +}(node_1.default)); +exports.default = Nesting; +//# sourceMappingURL=nesting.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js index 9a829510106..7537e8a34b6 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js @@ -1,192 +1,195 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _util = require("../util"); -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -var cloneNode = function cloneNode(obj, parent) { - if (typeof obj !== 'object' || obj === null) { - return obj; - } - var cloned = new obj.constructor(); - for (var i in obj) { - if (!obj.hasOwnProperty(i)) { - continue; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../util"); +var cloneNode = function (obj, parent, depth) { + if (depth === void 0) { depth = 0; } + // Bound recursion so a pathologically deep node tree raises a catchable + // error instead of overflowing the call stack (CVE-2026-9358 / CWE-674). + if (depth > util_1.MAX_NESTING_DEPTH) { + throw new Error("Cannot clone selector: nesting depth exceeds the maximum of ".concat(util_1.MAX_NESTING_DEPTH, ".")); } - var value = obj[i]; - var type = typeof value; - if (i === 'parent' && type === 'object') { - if (parent) { - cloned[i] = parent; - } - } else if (value instanceof Array) { - cloned[i] = value.map(function (j) { - return cloneNode(j, cloned); - }); - } else { - cloned[i] = cloneNode(value, cloned); + if (typeof obj !== "object" || obj === null) { + return obj; } - } - return cloned; -}; -var Node = /*#__PURE__*/function () { - function Node(opts) { - if (opts === void 0) { - opts = {}; - } - Object.assign(this, opts); - this.spaces = this.spaces || {}; - this.spaces.before = this.spaces.before || ''; - this.spaces.after = this.spaces.after || ''; - } - var _proto = Node.prototype; - _proto.remove = function remove() { - if (this.parent) { - this.parent.removeChild(this); - } - this.parent = undefined; - return this; - }; - _proto.replaceWith = function replaceWith() { - if (this.parent) { - for (var index in arguments) { - this.parent.insertBefore(this, arguments[index]); - } - this.remove(); - } - return this; - }; - _proto.next = function next() { - return this.parent.at(this.parent.index(this) + 1); - }; - _proto.prev = function prev() { - return this.parent.at(this.parent.index(this) - 1); - }; - _proto.clone = function clone(overrides) { - if (overrides === void 0) { - overrides = {}; - } - var cloned = cloneNode(this); - for (var name in overrides) { - cloned[name] = overrides[name]; + var cloned = new obj.constructor(); + for (var i in obj) { + if (!obj.hasOwnProperty(i)) { + continue; + } + var value = obj[i]; + var type = typeof value; + if (i === "parent" && type === "object") { + if (parent) { + cloned[i] = parent; + } + } + else if (value instanceof Array) { + cloned[i] = value.map(function (j) { return cloneNode(j, cloned, depth + 1); }); + } + else { + cloned[i] = cloneNode(value, cloned, depth + 1); + } } return cloned; - } - - /** - * Some non-standard syntax doesn't follow normal escaping rules for css. - * This allows non standard syntax to be appended to an existing property - * by specifying the escaped value. By specifying the escaped value, - * illegal characters are allowed to be directly inserted into css output. - * @param {string} name the property to set - * @param {any} value the unescaped value of the property - * @param {string} valueEscaped optional. the escaped value of the property. - */; - _proto.appendToPropertyAndEscape = function appendToPropertyAndEscape(name, value, valueEscaped) { - if (!this.raws) { - this.raws = {}; - } - var originalValue = this[name]; - var originalEscaped = this.raws[name]; - this[name] = originalValue + value; // this may trigger a setter that updates raws, so it has to be set first. - if (originalEscaped || valueEscaped !== value) { - this.raws[name] = (originalEscaped || originalValue) + valueEscaped; - } else { - delete this.raws[name]; // delete any escaped value that was created by the setter. - } - } - - /** - * Some non-standard syntax doesn't follow normal escaping rules for css. - * This allows the escaped value to be specified directly, allowing illegal - * characters to be directly inserted into css output. - * @param {string} name the property to set - * @param {any} value the unescaped value of the property - * @param {string} valueEscaped the escaped value of the property. - */; - _proto.setPropertyAndEscape = function setPropertyAndEscape(name, value, valueEscaped) { - if (!this.raws) { - this.raws = {}; - } - this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. - this.raws[name] = valueEscaped; - } - - /** - * When you want a value to passed through to CSS directly. This method - * deletes the corresponding raw value causing the stringifier to fallback - * to the unescaped value. - * @param {string} name the property to set. - * @param {any} value The value that is both escaped and unescaped. - */; - _proto.setPropertyWithoutEscape = function setPropertyWithoutEscape(name, value) { - this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. - if (this.raws) { - delete this.raws[name]; - } - } - - /** - * - * @param {number} line The number (starting with 1) - * @param {number} column The column number (starting with 1) - */; - _proto.isAtPosition = function isAtPosition(line, column) { - if (this.source && this.source.start && this.source.end) { - if (this.source.start.line > line) { - return false; - } - if (this.source.end.line < line) { - return false; - } - if (this.source.start.line === line && this.source.start.column > column) { - return false; - } - if (this.source.end.line === line && this.source.end.column < column) { - return false; - } - return true; - } - return undefined; - }; - _proto.stringifyProperty = function stringifyProperty(name) { - return this.raws && this.raws[name] || this[name]; - }; - _proto.valueToString = function valueToString() { - return String(this.stringifyProperty("value")); - }; - _proto.toString = function toString() { - return [this.rawSpaceBefore, this.valueToString(), this.rawSpaceAfter].join(''); - }; - _createClass(Node, [{ - key: "rawSpaceBefore", - get: function get() { - var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.before; - if (rawSpace === undefined) { - rawSpace = this.spaces && this.spaces.before; - } - return rawSpace || ""; - }, - set: function set(raw) { - (0, _util.ensureObject)(this, "raws", "spaces"); - this.raws.spaces.before = raw; - } - }, { - key: "rawSpaceAfter", - get: function get() { - var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.after; - if (rawSpace === undefined) { - rawSpace = this.spaces.after; - } - return rawSpace || ""; - }, - set: function set(raw) { - (0, _util.ensureObject)(this, "raws", "spaces"); - this.raws.spaces.after = raw; +}; +var Node = /** @class */ (function () { + function Node(opts) { + if (opts === void 0) { opts = {}; } + Object.assign(this, opts); + this.spaces = this.spaces || {}; + this.spaces.before = this.spaces.before || ""; + this.spaces.after = this.spaces.after || ""; } - }]); - return Node; -}(); -exports["default"] = Node; -module.exports = exports.default; \ No newline at end of file + Node.prototype.remove = function () { + if (this.parent) { + this.parent.removeChild(this); + } + this.parent = undefined; + return this; + }; + Node.prototype.replaceWith = function () { + if (this.parent) { + for (var index in arguments) { + this.parent.insertBefore(this, arguments[index]); + } + this.remove(); + } + return this; + }; + Node.prototype.next = function () { + return this.parent.at(this.parent.index(this) + 1); + }; + Node.prototype.prev = function () { + return this.parent.at(this.parent.index(this) - 1); + }; + Node.prototype.clone = function (overrides) { + if (overrides === void 0) { overrides = {}; } + var cloned = cloneNode(this); + for (var name in overrides) { + cloned[name] = overrides[name]; + } + return cloned; + }; + /** + * Some non-standard syntax doesn't follow normal escaping rules for css. + * This allows non standard syntax to be appended to an existing property + * by specifying the escaped value. By specifying the escaped value, + * illegal characters are allowed to be directly inserted into css output. + * @param {string} name the property to set + * @param {any} value the unescaped value of the property + * @param {string} valueEscaped optional. the escaped value of the property. + */ + Node.prototype.appendToPropertyAndEscape = function (name, value, valueEscaped) { + if (!this.raws) { + this.raws = {}; + } + var originalValue = this[name]; + var originalEscaped = this.raws[name]; + this[name] = originalValue + value; // this may trigger a setter that updates raws, so it has to be set first. + if (originalEscaped || valueEscaped !== value) { + this.raws[name] = (originalEscaped || originalValue) + valueEscaped; + } + else { + delete this.raws[name]; // delete any escaped value that was created by the setter. + } + }; + /** + * Some non-standard syntax doesn't follow normal escaping rules for css. + * This allows the escaped value to be specified directly, allowing illegal + * characters to be directly inserted into css output. + * @param {string} name the property to set + * @param {any} value the unescaped value of the property + * @param {string} valueEscaped the escaped value of the property. + */ + Node.prototype.setPropertyAndEscape = function (name, value, valueEscaped) { + if (!this.raws) { + this.raws = {}; + } + this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. + this.raws[name] = valueEscaped; + }; + /** + * When you want a value to passed through to CSS directly. This method + * deletes the corresponding raw value causing the stringifier to fallback + * to the unescaped value. + * @param {string} name the property to set. + * @param {any} value The value that is both escaped and unescaped. + */ + Node.prototype.setPropertyWithoutEscape = function (name, value) { + this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. + if (this.raws) { + delete this.raws[name]; + } + }; + /** + * + * @param {number} line The number (starting with 1) + * @param {number} column The column number (starting with 1) + */ + Node.prototype.isAtPosition = function (line, column) { + if (this.source && this.source.start && this.source.end) { + if (this.source.start.line > line) { + return false; + } + if (this.source.end.line < line) { + return false; + } + if (this.source.start.line === line && this.source.start.column > column) { + return false; + } + if (this.source.end.line === line && this.source.end.column < column) { + return false; + } + return true; + } + return undefined; + }; + Node.prototype.stringifyProperty = function (name) { + return (this.raws && this.raws[name]) || this[name]; + }; + Object.defineProperty(Node.prototype, "rawSpaceBefore", { + get: function () { + var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.before; + if (rawSpace === undefined) { + rawSpace = this.spaces && this.spaces.before; + } + return rawSpace || ""; + }, + set: function (raw) { + (0, util_1.ensureObject)(this, "raws", "spaces"); + this.raws.spaces.before = raw; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "rawSpaceAfter", { + get: function () { + var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.after; + if (rawSpace === undefined) { + rawSpace = this.spaces.after; + } + return rawSpace || ""; + }, + set: function (raw) { + (0, util_1.ensureObject)(this, "raws", "spaces"); + this.raws.spaces.after = raw; + }, + enumerable: false, + configurable: true + }); + Node.prototype.valueToString = function () { + return String(this.stringifyProperty("value")); + }; + Node.prototype.toString = function () { + return [this.rawSpaceBefore, this.valueToString(), this.rawSpaceAfter].join(""); + }; + // Internal recursion entry point used by Container serialization. Leaf + // nodes don't recurse, so they ignore the depth/limit and stringify + // themselves. Containers override this to thread the nesting depth. + Node.prototype._stringify = function () { + return this.toString(); + }; + return Node; +}()); +exports.default = Node; +//# sourceMappingURL=node.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js index 4371e5900f5..f8634a5edb4 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js @@ -1,26 +1,45 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _container = _interopRequireDefault(require("./container")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Pseudo = /*#__PURE__*/function (_Container) { - _inheritsLoose(Pseudo, _Container); - function Pseudo(opts) { - var _this; - _this = _Container.call(this, opts) || this; - _this.type = _types.PSEUDO; - return _this; - } - var _proto = Pseudo.prototype; - _proto.toString = function toString() { - var params = this.length ? '(' + this.map(String).join(',') + ')' : ''; - return [this.rawSpaceBefore, this.stringifyProperty("value"), params, this.rawSpaceAfter].join(''); - }; - return Pseudo; -}(_container["default"]); -exports["default"] = Pseudo; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __importDefault(require("./container")); +var types_1 = require("./types"); +var Pseudo = /** @class */ (function (_super) { + __extends(Pseudo, _super); + function Pseudo(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.PSEUDO; + return _this; + } + Pseudo.prototype._stringify = function (options, depth, max) { + var _this = this; + if (depth >= max) { + throw new Error("Cannot serialize selector: nesting depth exceeds the maximum of ".concat(max, ".")); + } + var params = this.length + ? "(" + + this.map(function (child) { return _this._stringifyChild(child, options, depth + 1, max); }).join(",") + + ")" + : ""; + return [this.rawSpaceBefore, this.stringifyProperty("value"), params, this.rawSpaceAfter].join(""); + }; + return Pseudo; +}(container_1.default)); +exports.default = Pseudo; +//# sourceMappingURL=pseudo.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js index 8c599d15809..920edbb0678 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js @@ -1,44 +1,56 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _container = _interopRequireDefault(require("./container")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Root = /*#__PURE__*/function (_Container) { - _inheritsLoose(Root, _Container); - function Root(opts) { - var _this; - _this = _Container.call(this, opts) || this; - _this.type = _types.ROOT; - return _this; - } - var _proto = Root.prototype; - _proto.toString = function toString() { - var str = this.reduce(function (memo, selector) { - memo.push(String(selector)); - return memo; - }, []).join(','); - return this.trailingComma ? str + ',' : str; - }; - _proto.error = function error(message, options) { - if (this._error) { - return this._error(message, options); - } else { - return new Error(message); +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __importDefault(require("./container")); +var types_1 = require("./types"); +var Root = /** @class */ (function (_super) { + __extends(Root, _super); + function Root(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.ROOT; + return _this; } - }; - _createClass(Root, [{ - key: "errorGenerator", - set: function set(handler) { - this._error = handler; - } - }]); - return Root; -}(_container["default"]); -exports["default"] = Root; -module.exports = exports.default; \ No newline at end of file + Root.prototype._stringify = function (options, depth, max) { + var _this = this; + var str = this.reduce(function (memo, selector) { + memo.push(_this._stringifyChild(selector, options, depth, max)); + return memo; + }, []).join(","); + return this.trailingComma ? str + "," : str; + }; + Root.prototype.error = function (message, options) { + if (this._error) { + return this._error(message, options); + } + else { + return new Error(message); + } + }; + Object.defineProperty(Root.prototype, "errorGenerator", { + set: function (handler) { + this._error = handler; + }, + enumerable: false, + configurable: true + }); + return Root; +}(container_1.default)); +exports.default = Root; +//# sourceMappingURL=root.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js index 8cc4bc1cddd..344d3f3f44f 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js @@ -1,21 +1,33 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _container = _interopRequireDefault(require("./container")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Selector = /*#__PURE__*/function (_Container) { - _inheritsLoose(Selector, _Container); - function Selector(opts) { - var _this; - _this = _Container.call(this, opts) || this; - _this.type = _types.SELECTOR; - return _this; - } - return Selector; -}(_container["default"]); -exports["default"] = Selector; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __importDefault(require("./container")); +var types_1 = require("./types"); +var Selector = /** @class */ (function (_super) { + __extends(Selector, _super); + function Selector(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.SELECTOR; + return _this; + } + return Selector; +}(container_1.default)); +exports.default = Selector; +//# sourceMappingURL=selector.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js index 4749791416b..eabbb0caf10 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js @@ -1,21 +1,33 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _node = _interopRequireDefault(require("./node")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var String = /*#__PURE__*/function (_Node) { - _inheritsLoose(String, _Node); - function String(opts) { - var _this; - _this = _Node.call(this, opts) || this; - _this.type = _types.STRING; - return _this; - } - return String; -}(_node["default"]); -exports["default"] = String; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var node_1 = __importDefault(require("./node")); +var types_1 = require("./types"); +var String = /** @class */ (function (_super) { + __extends(String, _super); + function String(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.STRING; + return _this; + } + return String; +}(node_1.default)); +exports.default = String; +//# sourceMappingURL=string.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js index 224e74de4a2..aed2a63127c 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js @@ -1,21 +1,33 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _namespace = _interopRequireDefault(require("./namespace")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Tag = /*#__PURE__*/function (_Namespace) { - _inheritsLoose(Tag, _Namespace); - function Tag(opts) { - var _this; - _this = _Namespace.call(this, opts) || this; - _this.type = _types.TAG; - return _this; - } - return Tag; -}(_namespace["default"]); -exports["default"] = Tag; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var namespace_1 = __importDefault(require("./namespace")); +var types_1 = require("./types"); +var Tag = /** @class */ (function (_super) { + __extends(Tag, _super); + function Tag(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.TAG; + return _this; + } + return Tag; +}(namespace_1.default)); +exports.default = Tag; +//# sourceMappingURL=tag.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js index 824cc0c7389..993ea644f4a 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js @@ -1,28 +1,16 @@ "use strict"; - -exports.__esModule = true; -exports.UNIVERSAL = exports.TAG = exports.STRING = exports.SELECTOR = exports.ROOT = exports.PSEUDO = exports.NESTING = exports.ID = exports.COMMENT = exports.COMBINATOR = exports.CLASS = exports.ATTRIBUTE = void 0; -var TAG = 'tag'; -exports.TAG = TAG; -var STRING = 'string'; -exports.STRING = STRING; -var SELECTOR = 'selector'; -exports.SELECTOR = SELECTOR; -var ROOT = 'root'; -exports.ROOT = ROOT; -var PSEUDO = 'pseudo'; -exports.PSEUDO = PSEUDO; -var NESTING = 'nesting'; -exports.NESTING = NESTING; -var ID = 'id'; -exports.ID = ID; -var COMMENT = 'comment'; -exports.COMMENT = COMMENT; -var COMBINATOR = 'combinator'; -exports.COMBINATOR = COMBINATOR; -var CLASS = 'class'; -exports.CLASS = CLASS; -var ATTRIBUTE = 'attribute'; -exports.ATTRIBUTE = ATTRIBUTE; -var UNIVERSAL = 'universal'; -exports.UNIVERSAL = UNIVERSAL; \ No newline at end of file +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UNIVERSAL = exports.ATTRIBUTE = exports.CLASS = exports.COMBINATOR = exports.COMMENT = exports.ID = exports.NESTING = exports.PSEUDO = exports.ROOT = exports.SELECTOR = exports.STRING = exports.TAG = void 0; +exports.TAG = "tag"; +exports.STRING = "string"; +exports.SELECTOR = "selector"; +exports.ROOT = "root"; +exports.PSEUDO = "pseudo"; +exports.NESTING = "nesting"; +exports.ID = "id"; +exports.COMMENT = "comment"; +exports.COMBINATOR = "combinator"; +exports.CLASS = "class"; +exports.ATTRIBUTE = "attribute"; +exports.UNIVERSAL = "universal"; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js index 5b5874380b8..f75bb336fd4 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js @@ -1,22 +1,34 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = void 0; -var _namespace = _interopRequireDefault(require("./namespace")); -var _types = require("./types"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var Universal = /*#__PURE__*/function (_Namespace) { - _inheritsLoose(Universal, _Namespace); - function Universal(opts) { - var _this; - _this = _Namespace.call(this, opts) || this; - _this.type = _types.UNIVERSAL; - _this.value = '*'; - return _this; - } - return Universal; -}(_namespace["default"]); -exports["default"] = Universal; -module.exports = exports.default; \ No newline at end of file +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var namespace_1 = __importDefault(require("./namespace")); +var types_1 = require("./types"); +var Universal = /** @class */ (function (_super) { + __extends(Universal, _super); + function Universal(opts) { + var _this = _super.call(this, opts) || this; + _this.type = types_1.UNIVERSAL; + _this.value = "*"; + return _this; + } + return Universal; +}(namespace_1.default)); +exports.default = Universal; +//# sourceMappingURL=universal.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js b/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js index 5666d5dc99f..86136e817cf 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js @@ -1,11 +1,7 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = sortAscending; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = sortAscending; function sortAscending(list) { - return list.sort(function (a, b) { - return a - b; - }); + return list.sort(function (a, b) { return a - b; }); } -; -module.exports = exports.default; \ No newline at end of file +//# sourceMappingURL=sortAscending.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js b/deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js index 59d8e6c6bf4..3a77aa093ee 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js @@ -1,70 +1,37 @@ "use strict"; - -exports.__esModule = true; -exports.word = exports.tilde = exports.tab = exports.str = exports.space = exports.slash = exports.singleQuote = exports.semicolon = exports.plus = exports.pipe = exports.openSquare = exports.openParenthesis = exports.newline = exports.greaterThan = exports.feed = exports.equals = exports.doubleQuote = exports.dollar = exports.cr = exports.comment = exports.comma = exports.combinator = exports.colon = exports.closeSquare = exports.closeParenthesis = exports.caret = exports.bang = exports.backslash = exports.at = exports.asterisk = exports.ampersand = void 0; -var ampersand = 38; // `&`.charCodeAt(0); -exports.ampersand = ampersand; -var asterisk = 42; // `*`.charCodeAt(0); -exports.asterisk = asterisk; -var at = 64; // `@`.charCodeAt(0); -exports.at = at; -var comma = 44; // `,`.charCodeAt(0); -exports.comma = comma; -var colon = 58; // `:`.charCodeAt(0); -exports.colon = colon; -var semicolon = 59; // `;`.charCodeAt(0); -exports.semicolon = semicolon; -var openParenthesis = 40; // `(`.charCodeAt(0); -exports.openParenthesis = openParenthesis; -var closeParenthesis = 41; // `)`.charCodeAt(0); -exports.closeParenthesis = closeParenthesis; -var openSquare = 91; // `[`.charCodeAt(0); -exports.openSquare = openSquare; -var closeSquare = 93; // `]`.charCodeAt(0); -exports.closeSquare = closeSquare; -var dollar = 36; // `$`.charCodeAt(0); -exports.dollar = dollar; -var tilde = 126; // `~`.charCodeAt(0); -exports.tilde = tilde; -var caret = 94; // `^`.charCodeAt(0); -exports.caret = caret; -var plus = 43; // `+`.charCodeAt(0); -exports.plus = plus; -var equals = 61; // `=`.charCodeAt(0); -exports.equals = equals; -var pipe = 124; // `|`.charCodeAt(0); -exports.pipe = pipe; -var greaterThan = 62; // `>`.charCodeAt(0); -exports.greaterThan = greaterThan; -var space = 32; // ` `.charCodeAt(0); -exports.space = space; -var singleQuote = 39; // `'`.charCodeAt(0); -exports.singleQuote = singleQuote; -var doubleQuote = 34; // `"`.charCodeAt(0); -exports.doubleQuote = doubleQuote; -var slash = 47; // `/`.charCodeAt(0); -exports.slash = slash; -var bang = 33; // `!`.charCodeAt(0); -exports.bang = bang; -var backslash = 92; // '\\'.charCodeAt(0); -exports.backslash = backslash; -var cr = 13; // '\r'.charCodeAt(0); -exports.cr = cr; -var feed = 12; // '\f'.charCodeAt(0); -exports.feed = feed; -var newline = 10; // '\n'.charCodeAt(0); -exports.newline = newline; -var tab = 9; // '\t'.charCodeAt(0); - +Object.defineProperty(exports, "__esModule", { value: true }); +exports.combinator = exports.word = exports.comment = exports.str = exports.tab = exports.newline = exports.feed = exports.cr = exports.backslash = exports.bang = exports.slash = exports.doubleQuote = exports.singleQuote = exports.space = exports.greaterThan = exports.pipe = exports.equals = exports.plus = exports.caret = exports.tilde = exports.dollar = exports.closeSquare = exports.openSquare = exports.closeParenthesis = exports.openParenthesis = exports.semicolon = exports.colon = exports.comma = exports.at = exports.asterisk = exports.ampersand = void 0; +exports.ampersand = 38; // `&`.charCodeAt(0); +exports.asterisk = 42; // `*`.charCodeAt(0); +exports.at = 64; // `@`.charCodeAt(0); +exports.comma = 44; // `,`.charCodeAt(0); +exports.colon = 58; // `:`.charCodeAt(0); +exports.semicolon = 59; // `;`.charCodeAt(0); +exports.openParenthesis = 40; // `(`.charCodeAt(0); +exports.closeParenthesis = 41; // `)`.charCodeAt(0); +exports.openSquare = 91; // `[`.charCodeAt(0); +exports.closeSquare = 93; // `]`.charCodeAt(0); +exports.dollar = 36; // `$`.charCodeAt(0); +exports.tilde = 126; // `~`.charCodeAt(0); +exports.caret = 94; // `^`.charCodeAt(0); +exports.plus = 43; // `+`.charCodeAt(0); +exports.equals = 61; // `=`.charCodeAt(0); +exports.pipe = 124; // `|`.charCodeAt(0); +exports.greaterThan = 62; // `>`.charCodeAt(0); +exports.space = 32; // ` `.charCodeAt(0); +exports.singleQuote = 39; // `'`.charCodeAt(0); +exports.doubleQuote = 34; // `"`.charCodeAt(0); +exports.slash = 47; // `/`.charCodeAt(0); +exports.bang = 33; // `!`.charCodeAt(0); +exports.backslash = 92; // '\\'.charCodeAt(0); +exports.cr = 13; // '\r'.charCodeAt(0); +exports.feed = 12; // '\f'.charCodeAt(0); +exports.newline = 10; // '\n'.charCodeAt(0); +exports.tab = 9; // '\t'.charCodeAt(0); // Expose aliases primarily for readability. -exports.tab = tab; -var str = singleQuote; - +exports.str = exports.singleQuote; // No good single character representation! -exports.str = str; -var comment = -1; -exports.comment = comment; -var word = -2; -exports.word = word; -var combinator = -3; -exports.combinator = combinator; \ No newline at end of file +exports.comment = -1; +exports.word = -2; +exports.combinator = -3; +//# sourceMappingURL=tokenTypes.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js b/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js index bf61d261b5c..f1f7c163111 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js @@ -1,239 +1,301 @@ "use strict"; - -exports.__esModule = true; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var _a, _b; +Object.defineProperty(exports, "__esModule", { value: true }); exports.FIELDS = void 0; -exports["default"] = tokenize; -var t = _interopRequireWildcard(require("./tokenTypes")); -var _unescapable, _wordDelimiters; -function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } -function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } -var unescapable = (_unescapable = {}, _unescapable[t.tab] = true, _unescapable[t.newline] = true, _unescapable[t.cr] = true, _unescapable[t.feed] = true, _unescapable); -var wordDelimiters = (_wordDelimiters = {}, _wordDelimiters[t.space] = true, _wordDelimiters[t.tab] = true, _wordDelimiters[t.newline] = true, _wordDelimiters[t.cr] = true, _wordDelimiters[t.feed] = true, _wordDelimiters[t.ampersand] = true, _wordDelimiters[t.asterisk] = true, _wordDelimiters[t.bang] = true, _wordDelimiters[t.comma] = true, _wordDelimiters[t.colon] = true, _wordDelimiters[t.semicolon] = true, _wordDelimiters[t.openParenthesis] = true, _wordDelimiters[t.closeParenthesis] = true, _wordDelimiters[t.openSquare] = true, _wordDelimiters[t.closeSquare] = true, _wordDelimiters[t.singleQuote] = true, _wordDelimiters[t.doubleQuote] = true, _wordDelimiters[t.plus] = true, _wordDelimiters[t.pipe] = true, _wordDelimiters[t.tilde] = true, _wordDelimiters[t.greaterThan] = true, _wordDelimiters[t.equals] = true, _wordDelimiters[t.dollar] = true, _wordDelimiters[t.caret] = true, _wordDelimiters[t.slash] = true, _wordDelimiters); +exports.default = tokenize; +var t = __importStar(require("./tokenTypes")); +var unescapable = (_a = {}, + _a[t.tab] = true, + _a[t.newline] = true, + _a[t.cr] = true, + _a[t.feed] = true, + _a); +var wordDelimiters = (_b = {}, + _b[t.space] = true, + _b[t.tab] = true, + _b[t.newline] = true, + _b[t.cr] = true, + _b[t.feed] = true, + _b[t.ampersand] = true, + _b[t.asterisk] = true, + _b[t.bang] = true, + _b[t.comma] = true, + _b[t.colon] = true, + _b[t.semicolon] = true, + _b[t.openParenthesis] = true, + _b[t.closeParenthesis] = true, + _b[t.openSquare] = true, + _b[t.closeSquare] = true, + _b[t.singleQuote] = true, + _b[t.doubleQuote] = true, + _b[t.plus] = true, + _b[t.pipe] = true, + _b[t.tilde] = true, + _b[t.greaterThan] = true, + _b[t.equals] = true, + _b[t.dollar] = true, + _b[t.caret] = true, + _b[t.slash] = true, + _b); var hex = {}; var hexChars = "0123456789abcdefABCDEF"; for (var i = 0; i < hexChars.length; i++) { - hex[hexChars.charCodeAt(i)] = true; + hex[hexChars.charCodeAt(i)] = true; } - /** * Returns the last index of the bar css word * @param {string} css The string in which the word begins * @param {number} start The index into the string where word's first letter occurs */ function consumeWord(css, start) { - var next = start; - var code; - do { - code = css.charCodeAt(next); - if (wordDelimiters[code]) { - return next - 1; - } else if (code === t.backslash) { - next = consumeEscape(css, next) + 1; - } else { - // All other characters are part of the word - next++; - } - } while (next < css.length); - return next - 1; + var next = start; + var code; + do { + code = css.charCodeAt(next); + if (wordDelimiters[code]) { + return next - 1; + } + else if (code === t.backslash) { + next = consumeEscape(css, next) + 1; + } + else { + // All other characters are part of the word + next++; + } + } while (next < css.length); + return next - 1; } - /** * Returns the last index of the escape sequence * @param {string} css The string in which the sequence begins * @param {number} start The index into the string where escape character (`\`) occurs. */ function consumeEscape(css, start) { - var next = start; - var code = css.charCodeAt(next + 1); - if (unescapable[code]) { - // just consume the escape char - } else if (hex[code]) { - var hexDigits = 0; - // consume up to 6 hex chars - do { - next++; - hexDigits++; - code = css.charCodeAt(next + 1); - } while (hex[code] && hexDigits < 6); - // if fewer than 6 hex chars, a trailing space ends the escape - if (hexDigits < 6 && code === t.space) { - next++; + var next = start; + var code = css.charCodeAt(next + 1); + if (unescapable[code]) { + // just consume the escape char + } + else if (hex[code]) { + var hexDigits = 0; + // consume up to 6 hex chars + do { + next++; + hexDigits++; + code = css.charCodeAt(next + 1); + } while (hex[code] && hexDigits < 6); + // if fewer than 6 hex chars, a trailing space ends the escape + if (hexDigits < 6 && code === t.space) { + next++; + } + } + else { + // the next char is part of the current word + next++; } - } else { - // the next char is part of the current word - next++; - } - return next; + return next; } -var FIELDS = { - TYPE: 0, - START_LINE: 1, - START_COL: 2, - END_LINE: 3, - END_COL: 4, - START_POS: 5, - END_POS: 6 +exports.FIELDS = { + TYPE: 0, + START_LINE: 1, + START_COL: 2, + END_LINE: 3, + END_COL: 4, + START_POS: 5, + END_POS: 6, }; -exports.FIELDS = FIELDS; function tokenize(input) { - var tokens = []; - var css = input.css.valueOf(); - var _css = css, - length = _css.length; - var offset = -1; - var line = 1; - var start = 0; - var end = 0; - var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType; - function unclosed(what, fix) { - if (input.safe) { - // fyi: this is never set to true. - css += fix; - next = css.length - 1; - } else { - throw input.error('Unclosed ' + what, line, start - offset, start); - } - } - while (start < length) { - code = css.charCodeAt(start); - if (code === t.newline) { - offset = start; - line += 1; + var tokens = []; + var css = input.css.valueOf(); + var length = css.length; + var offset = -1; + var line = 1; + var start = 0; + var end = 0; + var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType; + function unclosed(what, fix) { + if (input.safe) { + // fyi: this is never set to true. + css += fix; + next = css.length - 1; + } + else { + throw input.error("Unclosed " + what, line, start - offset, start); + } } - switch (code) { - case t.space: - case t.tab: - case t.newline: - case t.cr: - case t.feed: - next = start; - do { - next += 1; - code = css.charCodeAt(next); - if (code === t.newline) { - offset = next; + while (start < length) { + code = css.charCodeAt(start); + if (code === t.newline) { + offset = start; line += 1; - } - } while (code === t.space || code === t.newline || code === t.tab || code === t.cr || code === t.feed); - tokenType = t.space; - endLine = line; - endColumn = next - offset - 1; - end = next; - break; - case t.plus: - case t.greaterThan: - case t.tilde: - case t.pipe: - next = start; - do { - next += 1; - code = css.charCodeAt(next); - } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe); - tokenType = t.combinator; - endLine = line; - endColumn = start - offset; - end = next; - break; - - // Consume these characters as single tokens. - case t.asterisk: - case t.ampersand: - case t.bang: - case t.comma: - case t.equals: - case t.dollar: - case t.caret: - case t.openSquare: - case t.closeSquare: - case t.colon: - case t.semicolon: - case t.openParenthesis: - case t.closeParenthesis: - next = start; - tokenType = code; - endLine = line; - endColumn = start - offset; - end = next + 1; - break; - case t.singleQuote: - case t.doubleQuote: - quote = code === t.singleQuote ? "'" : '"'; - next = start; - do { - escaped = false; - next = css.indexOf(quote, next + 1); - if (next === -1) { - unclosed('quote', quote); - } - escapePos = next; - while (css.charCodeAt(escapePos - 1) === t.backslash) { - escapePos -= 1; - escaped = !escaped; - } - } while (escaped); - tokenType = t.str; - endLine = line; - endColumn = start - offset; - end = next + 1; - break; - default: - if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) { - next = css.indexOf('*/', start + 2) + 1; - if (next === 0) { - unclosed('comment', '*/'); - } - content = css.slice(start, next + 1); - lines = content.split('\n'); - last = lines.length - 1; - if (last > 0) { - nextLine = line + last; - nextOffset = next - lines[last].length; - } else { - nextLine = line; - nextOffset = offset; - } - tokenType = t.comment; - line = nextLine; - endLine = nextLine; - endColumn = next - nextOffset; - } else if (code === t.slash) { - next = start; - tokenType = code; - endLine = line; - endColumn = start - offset; - end = next + 1; - } else { - next = consumeWord(css, start); - tokenType = t.word; - endLine = line; - endColumn = next - offset; } - end = next + 1; - break; - } - - // Ensure that the token structure remains consistent - tokens.push([tokenType, - // [0] Token type - line, - // [1] Starting line - start - offset, - // [2] Starting column - endLine, - // [3] Ending line - endColumn, - // [4] Ending column - start, - // [5] Start position / Source index - end // [6] End position - ]); - - // Reset offset for the next token - if (nextOffset) { - offset = nextOffset; - nextOffset = null; + switch (code) { + case t.space: + case t.tab: + case t.newline: + case t.cr: + case t.feed: + next = start; + do { + next += 1; + code = css.charCodeAt(next); + if (code === t.newline) { + offset = next; + line += 1; + } + } while (code === t.space || + code === t.newline || + code === t.tab || + code === t.cr || + code === t.feed); + tokenType = t.space; + endLine = line; + endColumn = next - offset - 1; + end = next; + break; + case t.plus: + case t.greaterThan: + case t.tilde: + case t.pipe: + next = start; + do { + next += 1; + code = css.charCodeAt(next); + } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe); + tokenType = t.combinator; + endLine = line; + endColumn = start - offset; + end = next; + break; + // Consume these characters as single tokens. + case t.asterisk: + case t.ampersand: + case t.bang: + case t.comma: + case t.equals: + case t.dollar: + case t.caret: + case t.openSquare: + case t.closeSquare: + case t.colon: + case t.semicolon: + case t.openParenthesis: + case t.closeParenthesis: + next = start; + tokenType = code; + endLine = line; + endColumn = start - offset; + end = next + 1; + break; + case t.singleQuote: + case t.doubleQuote: + quote = code === t.singleQuote ? "'" : '"'; + next = start; + do { + escaped = false; + next = css.indexOf(quote, next + 1); + if (next === -1) { + unclosed("quote", quote); + } + escapePos = next; + while (css.charCodeAt(escapePos - 1) === t.backslash) { + escapePos -= 1; + escaped = !escaped; + } + } while (escaped); + tokenType = t.str; + endLine = line; + endColumn = start - offset; + end = next + 1; + break; + default: + if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) { + next = css.indexOf("*/", start + 2) + 1; + if (next === 0) { + unclosed("comment", "*/"); + } + content = css.slice(start, next + 1); + lines = content.split("\n"); + last = lines.length - 1; + if (last > 0) { + nextLine = line + last; + nextOffset = next - lines[last].length; + } + else { + nextLine = line; + nextOffset = offset; + } + tokenType = t.comment; + line = nextLine; + endLine = nextLine; + endColumn = next - nextOffset; + } + else if (code === t.slash) { + next = start; + tokenType = code; + endLine = line; + endColumn = start - offset; + end = next + 1; + } + else { + next = consumeWord(css, start); + tokenType = t.word; + endLine = line; + endColumn = next - offset; + } + end = next + 1; + break; + } + // Ensure that the token structure remains consistent + tokens.push([ + tokenType, // [0] Token type + line, // [1] Starting line + start - offset, // [2] Starting column + endLine, // [3] Ending line + endColumn, // [4] Ending column + start, // [5] Start position / Source index + end, // [6] End position + ]); + // Reset offset for the next token + if (nextOffset) { + offset = nextOffset; + nextOffset = null; + } + start = end; } - start = end; - } - return tokens; -} \ No newline at end of file + return tokens; +} +//# sourceMappingURL=tokenize.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js index 494941adaf2..7c64a460cac 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js @@ -1,17 +1,17 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = ensureObject; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = ensureObject; function ensureObject(obj) { - for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - props[_key - 1] = arguments[_key]; - } - while (props.length > 0) { - var prop = props.shift(); - if (!obj[prop]) { - obj[prop] = {}; + var props = []; + for (var _i = 1; _i < arguments.length; _i++) { + props[_i - 1] = arguments[_i]; + } + while (props.length > 0) { + var prop = props.shift(); + if (!obj[prop]) { + obj[prop] = {}; + } + obj = obj[prop]; } - obj = obj[prop]; - } } -module.exports = exports.default; \ No newline at end of file +//# sourceMappingURL=ensureObject.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js index a2b7a07307b..df696aa4f26 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js @@ -1,18 +1,18 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = getProp; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = getProp; function getProp(obj) { - for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - props[_key - 1] = arguments[_key]; - } - while (props.length > 0) { - var prop = props.shift(); - if (!obj[prop]) { - return undefined; + var props = []; + for (var _i = 1; _i < arguments.length; _i++) { + props[_i - 1] = arguments[_i]; } - obj = obj[prop]; - } - return obj; + while (props.length > 0) { + var prop = props.shift(); + if (!obj[prop]) { + return undefined; + } + obj = obj[prop]; + } + return obj; } -module.exports = exports.default; \ No newline at end of file +//# sourceMappingURL=getProp.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/index.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/index.js index f96ec11b6d4..616d59b3075 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/util/index.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/index.js @@ -1,13 +1,18 @@ "use strict"; - -exports.__esModule = true; -exports.unesc = exports.stripComments = exports.getProp = exports.ensureObject = void 0; -var _unesc = _interopRequireDefault(require("./unesc")); -exports.unesc = _unesc["default"]; -var _getProp = _interopRequireDefault(require("./getProp")); -exports.getProp = _getProp["default"]; -var _ensureObject = _interopRequireDefault(require("./ensureObject")); -exports.ensureObject = _ensureObject["default"]; -var _stripComments = _interopRequireDefault(require("./stripComments")); -exports.stripComments = _stripComments["default"]; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } \ No newline at end of file +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MAX_NESTING_DEPTH = exports.resolveMaxNestingDepth = exports.stripComments = exports.ensureObject = exports.getProp = exports.unesc = void 0; +var unesc_1 = require("./unesc"); +Object.defineProperty(exports, "unesc", { enumerable: true, get: function () { return __importDefault(unesc_1).default; } }); +var getProp_1 = require("./getProp"); +Object.defineProperty(exports, "getProp", { enumerable: true, get: function () { return __importDefault(getProp_1).default; } }); +var ensureObject_1 = require("./ensureObject"); +Object.defineProperty(exports, "ensureObject", { enumerable: true, get: function () { return __importDefault(ensureObject_1).default; } }); +var stripComments_1 = require("./stripComments"); +Object.defineProperty(exports, "stripComments", { enumerable: true, get: function () { return __importDefault(stripComments_1).default; } }); +var maxNestingDepth_1 = require("./maxNestingDepth"); +Object.defineProperty(exports, "resolveMaxNestingDepth", { enumerable: true, get: function () { return __importDefault(maxNestingDepth_1).default; } }); +Object.defineProperty(exports, "MAX_NESTING_DEPTH", { enumerable: true, get: function () { return maxNestingDepth_1.MAX_NESTING_DEPTH; } }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/maxNestingDepth.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/maxNestingDepth.js new file mode 100644 index 00000000000..48f0446e7d4 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/maxNestingDepth.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MAX_NESTING_DEPTH = void 0; +exports.default = resolveMaxNestingDepth; +/** + * The default maximum selector nesting depth allowed when parsing or + * serializing a selector. Going beyond this would otherwise recurse deeply + * enough to overflow the call stack (CVE-2026-9358 / CWE-674). Real-world + * selectors never get anywhere near this, so it acts purely as a safety net + * that turns an uncatchable stack overflow into a catchable error. + */ +exports.MAX_NESTING_DEPTH = 256; +/** + * Coerce a user-supplied nesting-depth limit into a safe value. Anything that + * is not a non-negative safe integer (NaN, Infinity, negative numbers, or a + * non-number) would disable or break the guard, so it falls back to the + * default. + * + * @param {unknown} value the limit provided through the `maxNestingDepth` option + * @returns {number} a safe, non-negative integer limit + */ +function resolveMaxNestingDepth(value) { + return Number.isSafeInteger(value) && value >= 0 ? value : exports.MAX_NESTING_DEPTH; +} +//# sourceMappingURL=maxNestingDepth.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js index 0baa0e07eb0..d2de33d4a14 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js @@ -1,21 +1,20 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = stripComments; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = stripComments; function stripComments(str) { - var s = ""; - var commentStart = str.indexOf("/*"); - var lastEnd = 0; - while (commentStart >= 0) { - s = s + str.slice(lastEnd, commentStart); - var commentEnd = str.indexOf("*/", commentStart + 2); - if (commentEnd < 0) { - return s; + var s = ""; + var commentStart = str.indexOf("/*"); + var lastEnd = 0; + while (commentStart >= 0) { + s = s + str.slice(lastEnd, commentStart); + var commentEnd = str.indexOf("*/", commentStart + 2); + if (commentEnd < 0) { + return s; + } + lastEnd = commentEnd + 2; + commentStart = str.indexOf("/*", lastEnd); } - lastEnd = commentEnd + 2; - commentStart = str.indexOf("/*", lastEnd); - } - s = s + str.slice(lastEnd); - return s; + s = s + str.slice(lastEnd); + return s; } -module.exports = exports.default; \ No newline at end of file +//# sourceMappingURL=stripComments.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js b/deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js index d5d960448b1..5d410ef30fb 100644 --- a/deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js @@ -1,76 +1,72 @@ "use strict"; - -exports.__esModule = true; -exports["default"] = unesc; // Many thanks for this post which made this migration much easier. // https://mathiasbynens.be/notes/css-escapes - +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = unesc; /** * * @param {string} str * @returns {[string, number]|undefined} */ function gobbleHex(str) { - var lower = str.toLowerCase(); - var hex = ''; - var spaceTerminated = false; - for (var i = 0; i < 6 && lower[i] !== undefined; i++) { - var code = lower.charCodeAt(i); - // check to see if we are dealing with a valid hex char [a-f|0-9] - var valid = code >= 97 && code <= 102 || code >= 48 && code <= 57; - // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point - spaceTerminated = code === 32; - if (!valid) { - break; + var lower = str.toLowerCase(); + var hex = ""; + var spaceTerminated = false; + for (var i = 0; i < 6 && lower[i] !== undefined; i++) { + var code = lower.charCodeAt(i); + // check to see if we are dealing with a valid hex char [a-f|0-9] + var valid = (code >= 97 && code <= 102) || (code >= 48 && code <= 57); + // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point + spaceTerminated = code === 32; + if (!valid) { + break; + } + hex += lower[i]; } - hex += lower[i]; - } - if (hex.length === 0) { - return undefined; - } - var codePoint = parseInt(hex, 16); - var isSurrogate = codePoint >= 0xD800 && codePoint <= 0xDFFF; - // Add special case for - // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point" - // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point - if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10FFFF) { - return ["\uFFFD", hex.length + (spaceTerminated ? 1 : 0)]; - } - return [String.fromCodePoint(codePoint), hex.length + (spaceTerminated ? 1 : 0)]; + if (hex.length === 0) { + return undefined; + } + var codePoint = parseInt(hex, 16); + var isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff; + // Add special case for + // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point" + // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point + if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10ffff) { + return ["\uFFFD", hex.length + (spaceTerminated ? 1 : 0)]; + } + return [String.fromCodePoint(codePoint), hex.length + (spaceTerminated ? 1 : 0)]; } var CONTAINS_ESCAPE = /\\/; function unesc(str) { - var needToProcess = CONTAINS_ESCAPE.test(str); - if (!needToProcess) { - return str; - } - var ret = ""; - for (var i = 0; i < str.length; i++) { - if (str[i] === "\\") { - var gobbled = gobbleHex(str.slice(i + 1, i + 7)); - if (gobbled !== undefined) { - ret += gobbled[0]; - i += gobbled[1]; - continue; - } - - // Retain a pair of \\ if double escaped `\\\\` - // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e - if (str[i + 1] === "\\") { - ret += "\\"; - i++; - continue; - } - - // if \\ is at the end of the string retain it - // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb - if (str.length === i + 1) { + var needToProcess = CONTAINS_ESCAPE.test(str); + if (!needToProcess) { + return str; + } + var ret = ""; + for (var i = 0; i < str.length; i++) { + if (str[i] === "\\") { + var gobbled = gobbleHex(str.slice(i + 1, i + 7)); + if (gobbled !== undefined) { + ret += gobbled[0]; + i += gobbled[1]; + continue; + } + // Retain a pair of \\ if double escaped `\\\\` + // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e + if (str[i + 1] === "\\") { + ret += "\\"; + i++; + continue; + } + // if \\ is at the end of the string retain it + // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb + if (str.length === i + 1) { + ret += str[i]; + } + continue; + } ret += str[i]; - } - continue; } - ret += str[i]; - } - return ret; + return ret; } -module.exports = exports.default; \ No newline at end of file +//# sourceMappingURL=unesc.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/postcss-selector-parser/package.json b/deps/npm/node_modules/postcss-selector-parser/package.json index c4f057c915b..12b12199b43 100644 --- a/deps/npm/node_modules/postcss-selector-parser/package.json +++ b/deps/npm/node_modules/postcss-selector-parser/package.json @@ -1,26 +1,12 @@ { "name": "postcss-selector-parser", - "version": "7.1.1", + "description": "Selector parser with built in methods for working with selector strings.", + "version": "7.1.4", "devDependencies": { - "@babel/cli": "^7.11.6", - "@babel/core": "^7.11.6", - "@babel/eslint-parser": "^7.11.5", - "@babel/eslint-plugin": "^7.11.5", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/preset-env": "^7.11.5", - "@babel/register": "^7.11.5", - "ava": "^5.1.0", - "babel-plugin-add-module-exports": "^1.0.4", - "coveralls-next": "^4.2.1", - "del-cli": "^5.0.0", - "eslint": "^8.28.0", - "eslint-plugin-import": "^2.26.0", - "glob": "^8.0.3", - "minimist": "^1.2.5", - "nyc": "^15.1.0", + "oxfmt": "^0.54.0", + "oxlint": "^1.69.0", "postcss": "^8.4.31", - "semver": "^7.3.2", - "typescript": "^4.0.3" + "typescript": "^5.4.0" }, "main": "dist/index.js", "types": "postcss-selector-parser.d.ts", @@ -30,17 +16,24 @@ "LICENSE-MIT", "dist", "postcss-selector-parser.d.ts", - "!**/__tests__" + "!**/__tests__", + "!dist/**/*.map" ], "scripts": { + "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"", + "build": "npm run clean && tsc", "typecheck": "tsc --noEmit --strict postcss-selector-parser.d.ts postcss-selector-parser.test.ts", - "pretest": "eslint src && npm run typecheck", - "prepare": "del-cli dist && BABEL_ENV=publish babel src --out-dir dist --ignore /__tests__/", - "lintfix": "eslint --fix src", - "report": "nyc report --reporter=html", - "test": "nyc ava src/__tests__/*.mjs", - "test:node22": "nyc ava src/__tests__/*.mjs --node-arguments=--no-experimental-detect-module", - "testone": "ava" + "lint": "oxlint", + "lint:fix": "oxlint --fix", + "format": "oxfmt src", + "format:check": "oxfmt --check src", + "pretests": "npm run build", + "tests": "node --test src/__tests__/*.mjs", + "precoverage": "npm run build", + "coverage": "node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs", + "test": "npm run lint && npm run typecheck && npm run coverage", + "prepare": "npm run build", + "release": "npx npmpub" }, "dependencies": { "cssesc": "^3.0.0", @@ -63,19 +56,8 @@ "url": "http://twitter.com/chriseppstein" } ], - "repository": "postcss/postcss-selector-parser", - "ava": { - "require": [ - "@babel/register" - ], - "concurrency": 5, - "timeout": "25s", - "nodeArguments": [] - }, - "nyc": { - "exclude": [ - "node_modules", - "**/__tests__" - ] + "repository": { + "type": "git", + "url": "https://github.com/postcss/postcss-selector-parser.git" } } diff --git a/deps/npm/node_modules/semver/classes/range.js b/deps/npm/node_modules/semver/classes/range.js index c2e605e5173..a7d6556febb 100644 --- a/deps/npm/node_modules/semver/classes/range.js +++ b/deps/npm/node_modules/semver/classes/range.js @@ -277,6 +277,11 @@ const parseComparator = (comp, options) => { const isX = id => !id || id.toLowerCase() === 'x' || id === '*' +const invalidXRangeOrder = (M, m, p) => ( + (isX(M) && !isX(m)) || + (isX(m) && p && !isX(p)) +) + // ~, ~> --> * (any, kinda silly) // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 @@ -294,6 +299,10 @@ const replaceTildes = (comp, options) => { const replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + // if we're including prereleases in the match, then the lower bound is + // -0, the lowest possible prerelease value, just like x-ranges and carets. + // this keeps `~1.2` equivalent to the `1.2.x` x-range it's documented as. + const z = options.includePrerelease ? '-0' : '' return comp.replace(r, (_, M, m, p, pr) => { debug('tilde', comp, _, M, m, p, pr) let ret @@ -301,10 +310,10 @@ const replaceTilde = (comp, options) => { if (isX(M)) { ret = '' } else if (isX(m)) { - ret = `>=${M}.0.0 <${+M + 1}.0.0-0` + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0` } else if (isX(p)) { // ~1.2 == >=1.2.0 <1.3.0-0 - ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0` + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0` } else if (pr) { debug('replaceTilde pr', pr) ret = `>=${M}.${m}.${p}-${pr @@ -373,10 +382,10 @@ const replaceCaret = (comp, options) => { if (M === '0') { if (m === '0') { ret = `>=${M}.${m}.${p - }${z} <${M}.${m}.${+p + 1}-0` + } <${M}.${m}.${+p + 1}-0` } else { ret = `>=${M}.${m}.${p - }${z} <${M}.${+m + 1}.0-0` + } <${M}.${+m + 1}.0-0` } } else { ret = `>=${M}.${m}.${p @@ -402,6 +411,10 @@ const replaceXRange = (comp, options) => { const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] return comp.replace(r, (ret, gtlt, M, m, p, pr) => { debug('xRange', comp, ret, gtlt, M, m, p, pr) + if (invalidXRangeOrder(M, m, p)) { + return comp + } + const xM = isX(M) const xm = xM || isX(m) const xp = xm || isX(p) diff --git a/deps/npm/node_modules/semver/classes/semver.js b/deps/npm/node_modules/semver/classes/semver.js index 92254be1bf0..5438127208d 100644 --- a/deps/npm/node_modules/semver/classes/semver.js +++ b/deps/npm/node_modules/semver/classes/semver.js @@ -6,6 +6,22 @@ const { safeRe: re, t } = require('../internal/re') const parseOptions = require('../internal/parse-options') const { compareIdentifiers } = require('../internal/identifiers') + +const isPrereleaseIdentifier = (prerelease, identifier) => { + const identifiers = identifier.split('.') + if (identifiers.length > prerelease.length) { + return false + } + + for (let i = 0; i < identifiers.length; i++) { + if (compareIdentifiers(prerelease[i], identifiers[i]) !== 0) { + return false + } + } + + return true +} + class SemVer { constructor (version, options) { options = parseOptions(options) @@ -309,8 +325,9 @@ class SemVer { if (identifierBase === false) { prerelease = [identifier] } - if (compareIdentifiers(this.prerelease[0], identifier) === 0) { - if (isNaN(this.prerelease[1])) { + if (isPrereleaseIdentifier(this.prerelease, identifier)) { + const prereleaseBase = this.prerelease[identifier.split('.').length] + if (isNaN(prereleaseBase)) { this.prerelease = prerelease } } else { diff --git a/deps/npm/node_modules/semver/package.json b/deps/npm/node_modules/semver/package.json index 6edb9ab49d9..0cb7c7bb465 100644 --- a/deps/npm/node_modules/semver/package.json +++ b/deps/npm/node_modules/semver/package.json @@ -1,6 +1,6 @@ { "name": "semver", - "version": "7.8.1", + "version": "7.8.5", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { @@ -14,7 +14,7 @@ "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "@npmcli/eslint-config": "^6.0.0", + "@npmcli/eslint-config": "^7.0.0", "@npmcli/template-oss": "5.0.0", "benchmark": "^2.1.4", "tap": "^16.0.0" diff --git a/deps/npm/node_modules/tar/dist/commonjs/header.js b/deps/npm/node_modules/tar/dist/commonjs/header.js index 16fb8120a29..f4a84fb76c3 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/header.js +++ b/deps/npm/node_modules/tar/dist/commonjs/header.js @@ -41,6 +41,7 @@ exports.Header = void 0; const node_path_1 = require("node:path"); const large = __importStar(require("./large-numbers.js")); const types = __importStar(require("./types.js")); +const notNegative = (n) => n === undefined || n < 0 ? undefined : n; class Header { cksumValid = false; needPax = false; @@ -78,22 +79,44 @@ class Header { if (!buf || !(buf.length >= off + 512)) { throw new Error('need 512 bytes for header'); } - this.path = ex?.path ?? decString(buf, off, 100); - this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8); - this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8); - this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8); - this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12); - this.mtime = ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12); + // Decode the typeflag (independent of any pending PAX/GNU extended header) + // up front so we can tell whether THIS block is itself an intermediary + // extension header (PAX `x`/`g`, GNU long-name `L`, GNU long-link `K`). + // Per POSIX pax, a PAX extended header describes the *next file entry*, not + // the extension headers that may sit between it and that file. Applying the + // pending PAX overrides (notably `size`) to an intervening `L`/`K`/`x`/`g` + // header desynchronizes the stream relative to other tar implementations + // and enables tar interpretation-conflict / file-smuggling attacks. + const t = decString(buf, off + 156, 1); + const isNormalFS = types.normalFsTypes.has(t); + const exForFields = isNormalFS ? ex : undefined; + const gexForFields = isNormalFS ? gex : undefined; + this.path = exForFields?.path ?? decString(buf, off, 100); + this.mode = + exForFields?.mode ?? + gexForFields?.mode ?? + decNumber(buf, off + 100, 8); + this.uid = + exForFields?.uid ?? gexForFields?.uid ?? decNumber(buf, off + 108, 8); + this.gid = + exForFields?.gid ?? gexForFields?.gid ?? decNumber(buf, off + 116, 8); + this.size = notNegative(exForFields?.size ?? + gexForFields?.size ?? + decNumber(buf, off + 124, 12)); + this.mtime = + exForFields?.mtime ?? + gexForFields?.mtime ?? + decDate(buf, off + 136, 12); this.cksum = decNumber(buf, off + 148, 12); // if we have extended or global extended headers, apply them now // See https://github.com/npm/node-tar/pull/187 - // Apply global before local, so it overrides - if (gex) - this.#slurp(gex, true); - if (ex) - this.#slurp(ex); + // Apply global before local, so it overrides. Never slurp the pending + // extended-header fields onto an intermediary extension header. + if (gexForFields) + this.#slurp(gexForFields, true); + if (exForFields) + this.#slurp(exForFields); // old tar versions marked dirs as a file with a trailing / - const t = decString(buf, off + 156, 1); if (types.isCode(t)) { this.#type = t || '0'; } @@ -111,12 +134,24 @@ class Header { this.linkpath = decString(buf, off + 157, 100); if (buf.subarray(off + 257, off + 265).toString() === 'ustar\u000000') { /* c8 ignore start */ - this.uname = ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32); - this.gname = ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32); + this.uname = + exForFields?.uname ?? + gexForFields?.uname ?? + decString(buf, off + 265, 32); + this.gname = + exForFields?.gname ?? + gexForFields?.gname ?? + decString(buf, off + 297, 32); this.devmaj = - ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; + exForFields?.devmaj ?? + gexForFields?.devmaj ?? + decNumber(buf, off + 329, 8) ?? + 0; this.devmin = - ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; + exForFields?.devmin ?? + gexForFields?.devmin ?? + decNumber(buf, off + 337, 8) ?? + 0; /* c8 ignore stop */ if (buf[off + 475] !== 0) { // definitely a prefix, definitely >130 chars. @@ -153,6 +188,7 @@ class Header { // null/undefined values are ignored. return !(v === null || v === undefined || + (k === 'size' && Number(v) < 0) || (k === 'path' && gex) || (k === 'linkpath' && gex) || k === 'global'); diff --git a/deps/npm/node_modules/tar/dist/commonjs/index.min.js b/deps/npm/node_modules/tar/dist/commonjs/index.min.js index 5bdc937545e..1a229a01e5a 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/index.min.js +++ b/deps/npm/node_modules/tar/dist/commonjs/index.min.js @@ -1,4 +1,4 @@ -"use strict";var d=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports);var We=d(F=>{"use strict";var Ro=F&&F.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(F,"__esModule",{value:!0});F.Minipass=F.isWritable=F.isReadable=F.isStream=void 0;var Br=typeof process=="object"&&process?process:{stdout:null,stderr:null},ss=require("node:events"),jr=Ro(require("node:stream")),vo=require("node:string_decoder"),To=s=>!!s&&typeof s=="object"&&(s instanceof Zt||s instanceof jr.default||(0,F.isReadable)(s)||(0,F.isWritable)(s));F.isStream=To;var Do=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.pipe=="function"&&s.pipe!==jr.default.Writable.prototype.pipe;F.isReadable=Do;var Po=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.write=="function"&&typeof s.end=="function";F.isWritable=Po;var le=Symbol("EOF"),ue=Symbol("maybeEmitEnd"),_e=Symbol("emittedEnd"),xt=Symbol("emittingEnd"),ft=Symbol("emittedError"),jt=Symbol("closed"),zr=Symbol("read"),Ut=Symbol("flush"),kr=Symbol("flushChunk"),K=Symbol("encoding"),Ue=Symbol("decoder"),O=Symbol("flowing"),dt=Symbol("paused"),qe=Symbol("resume"),R=Symbol("buffer"),I=Symbol("pipes"),v=Symbol("bufferLength"),Xi=Symbol("bufferPush"),qt=Symbol("bufferShift"),N=Symbol("objectMode"),y=Symbol("destroyed"),Qi=Symbol("error"),Ji=Symbol("emitData"),xr=Symbol("emitEnd"),es=Symbol("emitEnd2"),J=Symbol("async"),ts=Symbol("abort"),Wt=Symbol("aborted"),mt=Symbol("signal"),Ne=Symbol("dataListeners"),k=Symbol("discarded"),pt=s=>Promise.resolve().then(s),No=s=>s(),Mo=s=>s==="end"||s==="finish"||s==="prefinish",Lo=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,Ao=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Ht=class{src;dest;opts;ondrain;constructor(e,t,i){this.src=e,this.dest=t,this.opts=i,this.ondrain=()=>e[qe](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},is=class extends Ht{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,i){super(e,t,i),this.proxyErrors=r=>this.dest.emit("error",r),e.on("error",this.proxyErrors)}},Io=s=>!!s.objectMode,Fo=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",Zt=class extends ss.EventEmitter{[O]=!1;[dt]=!1;[I]=[];[R]=[];[N];[K];[J];[Ue];[le]=!1;[_e]=!1;[xt]=!1;[jt]=!1;[ft]=null;[v]=0;[y]=!1;[mt];[Wt]=!1;[Ne]=0;[k]=!1;writable=!0;readable=!0;constructor(...e){let t=e[0]||{};if(super(),t.objectMode&&typeof t.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Io(t)?(this[N]=!0,this[K]=null):Fo(t)?(this[K]=t.encoding,this[N]=!1):(this[N]=!1,this[K]=null),this[J]=!!t.async,this[Ue]=this[K]?new vo.StringDecoder(this[K]):null,t&&t.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[R]}),t&&t.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[I]});let{signal:i}=t;i&&(this[mt]=i,i.aborted?this[ts]():i.addEventListener("abort",()=>this[ts]()))}get bufferLength(){return this[v]}get encoding(){return this[K]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[N]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[J]}set async(e){this[J]=this[J]||!!e}[ts](){this[Wt]=!0,this.emit("abort",this[mt]?.reason),this.destroy(this[mt]?.reason)}get aborted(){return this[Wt]}set aborted(e){}write(e,t,i){if(this[Wt])return!1;if(this[le])throw new Error("write after end");if(this[y])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8");let r=this[J]?pt:No;if(!this[N]&&!Buffer.isBuffer(e)){if(Ao(e))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if(Lo(e))e=Buffer.from(e);else if(typeof e!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[N]?(this[O]&&this[v]!==0&&this[Ut](!0),this[O]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[O]):e.length?(typeof e=="string"&&!(t===this[K]&&!this[Ue]?.lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[K]&&(e=this[Ue].write(e)),this[O]&&this[v]!==0&&this[Ut](!0),this[O]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[O]):(this[v]!==0&&this.emit("readable"),i&&r(i),this[O])}read(e){if(this[y])return null;if(this[k]=!1,this[v]===0||e===0||e&&e>this[v])return this[ue](),null;this[N]&&(e=null),this[R].length>1&&!this[N]&&(this[R]=[this[K]?this[R].join(""):Buffer.concat(this[R],this[v])]);let t=this[zr](e||null,this[R][0]);return this[ue](),t}[zr](e,t){if(this[N])this[qt]();else{let i=t;e===i.length||e===null?this[qt]():typeof i=="string"?(this[R][0]=i.slice(e),t=i.slice(0,e),this[v]-=e):(this[R][0]=i.subarray(e),t=i.subarray(0,e),this[v]-=e)}return this.emit("data",t),!this[R].length&&!this[le]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t="utf8"),e!==void 0&&this.write(e,t),i&&this.once("end",i),this[le]=!0,this.writable=!1,(this[O]||!this[dt])&&this[ue](),this}[qe](){this[y]||(!this[Ne]&&!this[I].length&&(this[k]=!0),this[dt]=!1,this[O]=!0,this.emit("resume"),this[R].length?this[Ut]():this[le]?this[ue]():this.emit("drain"))}resume(){return this[qe]()}pause(){this[O]=!1,this[dt]=!0,this[k]=!1}get destroyed(){return this[y]}get flowing(){return this[O]}get paused(){return this[dt]}[Xi](e){this[N]?this[v]+=1:this[v]+=e.length,this[R].push(e)}[qt](){return this[N]?this[v]-=1:this[v]-=this[R][0].length,this[R].shift()}[Ut](e=!1){do;while(this[kr](this[qt]())&&this[R].length);!e&&!this[R].length&&!this[le]&&this.emit("drain")}[kr](e){return this.emit("data",e),this[O]}pipe(e,t){if(this[y])return e;this[k]=!1;let i=this[_e];return t=t||{},e===Br.stdout||e===Br.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this[I].push(t.proxyErrors?new is(this,e,t):new Ht(this,e,t)),this[J]?pt(()=>this[qe]()):this[qe]()),e}unpipe(e){let t=this[I].find(i=>i.dest===e);t&&(this[I].length===1?(this[O]&&this[Ne]===0&&(this[O]=!1),this[I]=[]):this[I].splice(this[I].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let i=super.on(e,t);if(e==="data")this[k]=!1,this[Ne]++,!this[I].length&&!this[O]&&this[qe]();else if(e==="readable"&&this[v]!==0)super.emit("readable");else if(Mo(e)&&this[_e])super.emit(e),this.removeAllListeners(e);else if(e==="error"&&this[ft]){let r=t;this[J]?pt(()=>r.call(this,this[ft])):r.call(this,this[ft])}return i}removeListener(e,t){return this.off(e,t)}off(e,t){let i=super.off(e,t);return e==="data"&&(this[Ne]=this.listeners("data").length,this[Ne]===0&&!this[k]&&!this[I].length&&(this[O]=!1)),i}removeAllListeners(e){let t=super.removeAllListeners(e);return(e==="data"||e===void 0)&&(this[Ne]=0,!this[k]&&!this[I].length&&(this[O]=!1)),t}get emittedEnd(){return this[_e]}[ue](){!this[xt]&&!this[_e]&&!this[y]&&this[R].length===0&&this[le]&&(this[xt]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[jt]&&this.emit("close"),this[xt]=!1)}emit(e,...t){let i=t[0];if(e!=="error"&&e!=="close"&&e!==y&&this[y])return!1;if(e==="data")return!this[N]&&!i?!1:this[J]?(pt(()=>this[Ji](i)),!0):this[Ji](i);if(e==="end")return this[xr]();if(e==="close"){if(this[jt]=!0,!this[_e]&&!this[y])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[ft]=i,super.emit(Qi,i);let n=!this[mt]||this.listeners("error").length?super.emit("error",i):!1;return this[ue](),n}else if(e==="resume"){let n=super.emit("resume");return this[ue](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let r=super.emit(e,...t);return this[ue](),r}[Ji](e){for(let i of this[I])i.dest.write(e)===!1&&this.pause();let t=this[k]?!1:super.emit("data",e);return this[ue](),t}[xr](){return this[_e]?!1:(this[_e]=!0,this.readable=!1,this[J]?(pt(()=>this[es]()),!0):this[es]())}[es](){if(this[Ue]){let t=this[Ue].end();if(t){for(let i of this[I])i.dest.write(t);this[k]||super.emit("data",t)}}for(let t of this[I])t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){let e=Object.assign([],{dataLength:0});this[N]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[N]||(e.dataLength+=i.length)}),await t,e}async concat(){if(this[N])throw new Error("cannot concat in objectMode");let e=await this.collect();return this[K]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(y,()=>t(new Error("stream destroyed"))),this.on("error",i=>t(i)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[k]=!1;let e=!1,t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[le])return t();let n,o,a=c=>{this.off("data",h),this.off("end",l),this.off(y,u),t(),o(c)},h=c=>{this.off("error",a),this.off("end",l),this.off(y,u),this.pause(),n({value:c,done:!!this[le]})},l=()=>{this.off("error",a),this.off("data",h),this.off(y,u),t(),n({done:!0,value:void 0})},u=()=>a(new Error("stream destroyed"));return new Promise((c,E)=>{o=E,n=c,this.once(y,u),this.once("error",a),this.once("end",l),this.once("data",h)})},throw:t,return:t,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[k]=!1;let e=!1,t=()=>(this.pause(),this.off(Qi,t),this.off(y,t),this.off("end",t),e=!0,{done:!0,value:void 0}),i=()=>{if(e)return t();let r=this.read();return r===null?t():{done:!1,value:r}};return this.once("end",t),this.once(Qi,t),this.once(y,t),{next:i,throw:t,return:t,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(e){if(this[y])return e?this.emit("error",e):this.emit(y),this;this[y]=!0,this[k]=!0,this[R].length=0,this[v]=0;let t=this;return typeof t.close=="function"&&!this[jt]&&t.close(),e?this.emit("error",e):this.emit(y),this}static get isStream(){return F.isStream}};F.Minipass=Zt});var Ke=d(W=>{"use strict";var Ur=W&&W.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(W,"__esModule",{value:!0});W.WriteStreamSync=W.WriteStream=W.ReadStreamSync=W.ReadStream=void 0;var Co=Ur(require("events")),B=Ur(require("fs")),Bo=We(),zo=B.default.writev,ye=Symbol("_autoClose"),$=Symbol("_close"),_t=Symbol("_ended"),p=Symbol("_fd"),rs=Symbol("_finished"),fe=Symbol("_flags"),ns=Symbol("_flush"),ls=Symbol("_handleChunk"),us=Symbol("_makeBuf"),yt=Symbol("_mode"),Gt=Symbol("_needDrain"),Ge=Symbol("_onerror"),Ye=Symbol("_onopen"),os=Symbol("_onread"),He=Symbol("_onwrite"),Ee=Symbol("_open"),V=Symbol("_path"),we=Symbol("_pos"),ee=Symbol("_queue"),Ze=Symbol("_read"),as=Symbol("_readSize"),ce=Symbol("_reading"),wt=Symbol("_remain"),hs=Symbol("_size"),Yt=Symbol("_write"),Me=Symbol("_writing"),Kt=Symbol("_defaultFlag"),Le=Symbol("_errored"),Vt=class extends Bo.Minipass{[Le]=!1;[p];[V];[as];[ce]=!1;[hs];[wt];[ye];constructor(e,t){if(t=t||{},super(t),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Le]=!1,this[p]=typeof t.fd=="number"?t.fd:void 0,this[V]=e,this[as]=t.readSize||16*1024*1024,this[ce]=!1,this[hs]=typeof t.size=="number"?t.size:1/0,this[wt]=this[hs],this[ye]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[p]=="number"?this[Ze]():this[Ee]()}get fd(){return this[p]}get path(){return this[V]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Ee](){B.default.open(this[V],"r",(e,t)=>this[Ye](e,t))}[Ye](e,t){e?this[Ge](e):(this[p]=t,this.emit("open",t),this[Ze]())}[us](){return Buffer.allocUnsafe(Math.min(this[as],this[wt]))}[Ze](){if(!this[ce]){this[ce]=!0;let e=this[us]();if(e.length===0)return process.nextTick(()=>this[os](null,0,e));B.default.read(this[p],e,0,e.length,null,(t,i,r)=>this[os](t,i,r))}}[os](e,t,i){this[ce]=!1,e?this[Ge](e):this[ls](t,i)&&this[Ze]()}[$](){if(this[ye]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,B.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}[Ge](e){this[ce]=!0,this[$](),this.emit("error",e)}[ls](e,t){let i=!1;return this[wt]-=e,e>0&&(i=super.write(ethis[Ye](e,t))}[Ye](e,t){this[Kt]&&this[fe]==="r+"&&e&&e.code==="ENOENT"?(this[fe]="w",this[Ee]()):e?this[Ge](e):(this[p]=t,this.emit("open",t),this[Me]||this[ns]())}end(e,t){return e&&this.write(e,t),this[_t]=!0,!this[Me]&&!this[ee].length&&typeof this[p]=="number"&&this[He](null,0),this}write(e,t){return typeof e=="string"&&(e=Buffer.from(e,t)),this[_t]?(this.emit("error",new Error("write() after end()")),!1):this[p]===void 0||this[Me]||this[ee].length?(this[ee].push(e),this[Gt]=!0,!1):(this[Me]=!0,this[Yt](e),!0)}[Yt](e){B.default.write(this[p],e,0,e.length,this[we],(t,i)=>this[He](t,i))}[He](e,t){e?this[Ge](e):(this[we]!==void 0&&typeof t=="number"&&(this[we]+=t),this[ee].length?this[ns]():(this[Me]=!1,this[_t]&&!this[rs]?(this[rs]=!0,this[$](),this.emit("finish")):this[Gt]&&(this[Gt]=!1,this.emit("drain"))))}[ns](){if(this[ee].length===0)this[_t]&&this[He](null,0);else if(this[ee].length===1)this[Yt](this[ee].pop());else{let e=this[ee];this[ee]=[],zo(this[p],e,this[we],(t,i)=>this[He](t,i))}}[$](){if(this[ye]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,B.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}};W.WriteStream=$t;var fs=class extends $t{[Ee](){let e;if(this[Kt]&&this[fe]==="r+")try{e=B.default.openSync(this[V],this[fe],this[yt])}catch(t){if(t?.code==="ENOENT")return this[fe]="w",this[Ee]();throw t}else e=B.default.openSync(this[V],this[fe],this[yt]);this[Ye](null,e)}[$](){if(this[ye]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,B.default.closeSync(e),this.emit("close")}}[Yt](e){let t=!0;try{this[He](null,B.default.writeSync(this[p],e,0,e.length,this[we])),t=!1}finally{if(t)try{this[$]()}catch{}}}};W.WriteStreamSync=fs});var Xt=d(b=>{"use strict";Object.defineProperty(b,"__esModule",{value:!0});b.dealias=b.isNoFile=b.isFile=b.isAsync=b.isSync=b.isAsyncNoFile=b.isSyncNoFile=b.isAsyncFile=b.isSyncFile=void 0;var ko=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),xo=s=>!!s.sync&&!!s.file;b.isSyncFile=xo;var jo=s=>!s.sync&&!!s.file;b.isAsyncFile=jo;var Uo=s=>!!s.sync&&!s.file;b.isSyncNoFile=Uo;var qo=s=>!s.sync&&!s.file;b.isAsyncNoFile=qo;var Wo=s=>!!s.sync;b.isSync=Wo;var Ho=s=>!s.sync;b.isAsync=Ho;var Zo=s=>!!s.file;b.isFile=Zo;var Go=s=>!s.file;b.isNoFile=Go;var Yo=s=>{let e=ko.get(s);return e||s},Ko=(s={})=>{if(!s)return{};let e={};for(let[t,i]of Object.entries(s)){let r=Yo(t);e[r]=i}return e.chmod===void 0&&e.noChmod===!1&&(e.chmod=!0),delete e.noChmod,e};b.dealias=Ko});var Ve=d(Qt=>{"use strict";Object.defineProperty(Qt,"__esModule",{value:!0});Qt.makeCommand=void 0;var Et=Xt(),Vo=(s,e,t,i,r)=>Object.assign((n=[],o,a)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(a=o,o=void 0),o=o?Array.from(o):[];let h=(0,Et.dealias)(n);if(r?.(h,o),(0,Et.isSyncFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return s(h,o)}else if((0,Et.isAsyncFile)(h)){let l=e(h,o);return a?l.then(()=>a(),a):l}else if((0,Et.isSyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return t(h,o)}else if((0,Et.isAsyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback only supported with file option");return i(h,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:e,syncNoFile:t,asyncNoFile:i,validate:r});Qt.makeCommand=Vo});var ds=d($e=>{"use strict";var $o=$e&&$e.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty($e,"__esModule",{value:!0});$e.constants=void 0;var Xo=$o(require("zlib")),Qo=Xo.default.constants||{ZLIB_VERNUM:4736};$e.constants=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},Qo))});var Ps=d(f=>{"use strict";var Jo=f&&f.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),ea=f&&f.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ta=f&&f.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs,ms=Wr?.writable===!0||Wr?.set!==void 0?s=>{Ae.Buffer.concat=s?oa:na}:s=>{},Ie=Symbol("_superWrite"),Fe=class extends Error{code;errno;constructor(e,t){super("zlib: "+e.message,{cause:e}),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,t??this.constructor)}get name(){return"ZlibError"}};f.ZlibError=Fe;var ps=Symbol("flushFlag"),bt=class extends sa.Minipass{#e=!1;#i=!1;#s;#n;#r;#t;#o;get sawError(){return this.#e}get handle(){return this.#t}get flushFlag(){return this.#s}constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(e),this.#s=e.flush??0,this.#n=e.finishFlush??0,this.#r=e.fullFlushFlag??0,typeof qr[t]!="function")throw new TypeError("Compression method not supported: "+t);try{this.#t=new qr[t](e)}catch(i){throw new Fe(i,this.constructor)}this.#o=i=>{this.#e||(this.#e=!0,this.close(),this.emit("error",i))},this.#t?.on("error",i=>this.#o(new Fe(i))),this.once("end",()=>this.close)}close(){this.#t&&(this.#t.close(),this.#t=void 0,this.emit("close"))}reset(){if(!this.#e)return(0,_s.default)(this.#t,"zlib binding closed"),this.#t.reset?.()}flush(e){this.ended||(typeof e!="number"&&(e=this.#r),this.write(Object.assign(Ae.Buffer.alloc(0),{[ps]:e})))}end(e,t,i){return typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&(t?this.write(e,t):this.write(e)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Ie](e){return super.write(e)}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=Ae.Buffer.from(e,t)),this.#e)return;(0,_s.default)(this.#t,"zlib binding closed");let r=this.#t._handle,n=r.close;r.close=()=>{};let o=this.#t.close;this.#t.close=()=>{},ms(!0);let a;try{let l=typeof e[ps]=="number"?e[ps]:this.#s;a=this.#t._processChunk(e,l),ms(!1)}catch(l){ms(!1),this.#o(new Fe(l,this.write))}finally{this.#t&&(this.#t._handle=r,r.close=n,this.#t.close=o,this.#t.removeAllListeners("error"))}this.#t&&this.#t.on("error",l=>this.#o(new Fe(l,this.write)));let h;if(a)if(Array.isArray(a)&&a.length>0){let l=a[0];h=this[Ie](Ae.Buffer.from(l));for(let u=1;u{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(e,t)}finally{this.handle.flush=i}this.handle&&(this.#e=e,this.#i=t)}}}};f.Zlib=ie;var ws=class extends ie{constructor(e){super(e,"Deflate")}};f.Deflate=ws;var ys=class extends ie{constructor(e){super(e,"Inflate")}};f.Inflate=ys;var Es=class extends ie{#e;constructor(e){super(e,"Gzip"),this.#e=e&&!!e.portable}[Ie](e){return this.#e?(this.#e=!1,e[9]=255,super[Ie](e)):super[Ie](e)}};f.Gzip=Es;var bs=class extends ie{constructor(e){super(e,"Gunzip")}};f.Gunzip=bs;var Ss=class extends ie{constructor(e){super(e,"DeflateRaw")}};f.DeflateRaw=Ss;var gs=class extends ie{constructor(e){super(e,"InflateRaw")}};f.InflateRaw=gs;var Os=class extends ie{constructor(e){super(e,"Unzip")}};f.Unzip=Os;var Jt=class extends bt{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||te.constants.BROTLI_OPERATION_FINISH,e.fullFlushFlag=te.constants.BROTLI_OPERATION_FLUSH,super(e,t)}},Rs=class extends Jt{constructor(e){super(e,"BrotliCompress")}};f.BrotliCompress=Rs;var vs=class extends Jt{constructor(e){super(e,"BrotliDecompress")}};f.BrotliDecompress=vs;var ei=class extends bt{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.ZSTD_e_continue,e.finishFlush=e.finishFlush||te.constants.ZSTD_e_end,e.fullFlushFlag=te.constants.ZSTD_e_flush,super(e,t)}},Ts=class extends ei{constructor(e){super(e,"ZstdCompress")}};f.ZstdCompress=Ts;var Ds=class extends ei{constructor(e){super(e,"ZstdDecompress")}};f.ZstdDecompress=Ds});var Gr=d(Xe=>{"use strict";Object.defineProperty(Xe,"__esModule",{value:!0});Xe.parse=Xe.encode=void 0;var aa=(s,e)=>{if(Number.isSafeInteger(s))s<0?la(s,e):ha(s,e);else throw Error("cannot encode number outside of javascript safe integer range");return e};Xe.encode=aa;var ha=(s,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=s&255,s=Math.floor(s/256)},la=(s,e)=>{e[0]=255;var t=!1;s=s*-1;for(var i=e.length;i>1;i--){var r=s&255;s=Math.floor(s/256),t?e[i-1]=Hr(r):r===0?e[i-1]=0:(t=!0,e[i-1]=Zr(r))}},ua=s=>{let e=s[0],t=e===128?fa(s.subarray(1,s.length)):e===255?ca(s):null;if(t===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(t))throw Error("parsed number outside of javascript safe integer range");return t};Xe.parse=ua;var ca=s=>{for(var e=s.length,t=0,i=!1,r=e-1;r>-1;r--){var n=Number(s[r]),o;i?o=Hr(n):n===0?o=n:(i=!0,o=Zr(n)),o!==0&&(t-=o*Math.pow(256,e-r-1))}return t},fa=s=>{for(var e=s.length,t=0,i=e-1;i>-1;i--){var r=Number(s[i]);r!==0&&(t+=r*Math.pow(256,e-i-1))}return t},Hr=s=>(255^s)&255,Zr=s=>(255^s)+1&255});var Ns=d(x=>{"use strict";Object.defineProperty(x,"__esModule",{value:!0});x.code=x.name=x.isName=x.isCode=void 0;var da=s=>x.name.has(s);x.isCode=da;var ma=s=>x.code.has(s);x.isName=ma;x.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);x.code=new Map(Array.from(x.name).map(s=>[s[1],s[0]]))});var Je=d(se=>{"use strict";var pa=se&&se.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),_a=se&&se.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Yr=se&&se.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r=t+512))throw new Error("need 512 bytes for header");this.path=i?.path??Ce(e,t,100),this.mode=i?.mode??r?.mode??be(e,t+100,8),this.uid=i?.uid??r?.uid??be(e,t+108,8),this.gid=i?.gid??r?.gid??be(e,t+116,8),this.size=i?.size??r?.size??be(e,t+124,12),this.mtime=i?.mtime??r?.mtime??Ms(e,t+136,12),this.cksum=be(e,t+148,12),r&&this.#i(r,!0),i&&this.#i(i);let n=Ce(e,t+156,1);if(St.isCode(n)&&(this.#e=n||"0"),this.#e==="0"&&this.path.slice(-1)==="/"&&(this.#e="5"),this.#e==="5"&&(this.size=0),this.linkpath=Ce(e,t+157,100),e.subarray(t+257,t+265).toString()==="ustar\x0000")if(this.uname=i?.uname??r?.uname??Ce(e,t+265,32),this.gname=i?.gname??r?.gname??Ce(e,t+297,32),this.devmaj=i?.devmaj??r?.devmaj??be(e,t+329,8)??0,this.devmin=i?.devmin??r?.devmin??be(e,t+337,8)??0,e[t+475]!==0){let a=Ce(e,t+345,155);this.path=a+"/"+this.path}else{let a=Ce(e,t+345,130);a&&(this.path=a+"/"+this.path),this.atime=i?.atime??r?.atime??Ms(e,t+476,12),this.ctime=i?.ctime??r?.ctime??Ms(e,t+488,12)}let o=256;for(let a=t;a!(r==null||i==="path"&&t||i==="linkpath"&&t||i==="global"))))}encode(e,t=0){if(e||(e=this.block=Buffer.alloc(512)),this.#e==="Unsupported"&&(this.#e="0"),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=wa(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Be(e,t,100,n)||this.needPax,this.needPax=Se(e,t+100,8,this.mode)||this.needPax,this.needPax=Se(e,t+108,8,this.uid)||this.needPax,this.needPax=Se(e,t+116,8,this.gid)||this.needPax,this.needPax=Se(e,t+124,12,this.size)||this.needPax,this.needPax=Ls(e,t+136,12,this.mtime)||this.needPax,e[t+156]=Number(this.#e.codePointAt(0)),this.needPax=Be(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=Be(e,t+265,32,this.uname)||this.needPax,this.needPax=Be(e,t+297,32,this.gname)||this.needPax,this.needPax=Se(e,t+329,8,this.devmaj)||this.needPax,this.needPax=Se(e,t+337,8,this.devmin)||this.needPax,this.needPax=Be(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=Be(e,t+345,155,o)||this.needPax:(this.needPax=Be(e,t+345,130,o)||this.needPax,this.needPax=Ls(e,t+476,12,this.atime)||this.needPax,this.needPax=Ls(e,t+488,12,this.ctime)||this.needPax);let a=256;for(let h=t;h{let i=s,r="",n,o=Qe.posix.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Qe.posix.dirname(i),i=Qe.posix.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=e?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=e?n=[i.slice(0,99),r,!0]:(i=Qe.posix.join(Qe.posix.basename(r),i),r=Qe.posix.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},Ce=(s,e,t)=>s.subarray(e,e+t).toString("utf8").replace(/\0.*/,""),Ms=(s,e,t)=>ya(be(s,e,t)),ya=s=>s===void 0?void 0:new Date(s*1e3),be=(s,e,t)=>Number(s[e])&128?Kr.parse(s.subarray(e,e+t)):ba(s,e,t),Ea=s=>isNaN(s)?void 0:s,ba=(s,e,t)=>Ea(parseInt(s.subarray(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),Sa={12:8589934591,8:2097151},Se=(s,e,t,i)=>i===void 0?!1:i>Sa[t]||i<0?(Kr.encode(i,s.subarray(e,e+t)),!0):(ga(s,e,t,i),!1),ga=(s,e,t,i)=>s.write(Oa(i,t),e,t,"ascii"),Oa=(s,e)=>Ra(Math.floor(s).toString(8),e),Ra=(s,e)=>(s.length===e-1?s:new Array(e-s.length-1).join("0")+s+" ")+"\0",Ls=(s,e,t,i)=>i===void 0?!1:Se(s,e,t,i.getTime()/1e3),va=new Array(156).join("\0"),Be=(s,e,t,i)=>i===void 0?!1:(s.write(i+va,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t)});var ii=d(ti=>{"use strict";Object.defineProperty(ti,"__esModule",{value:!0});ti.Pax=void 0;var Ta=require("node:path"),Da=Je(),Is=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(e,t=!1){this.atime=e.atime,this.charset=e.charset,this.comment=e.comment,this.ctime=e.ctime,this.dev=e.dev,this.gid=e.gid,this.global=t,this.gname=e.gname,this.ino=e.ino,this.linkpath=e.linkpath,this.mtime=e.mtime,this.nlink=e.nlink,this.path=e.path,this.size=e.size,this.uid=e.uid,this.uname=e.uname}encode(){let e=this.encodeBody();if(e==="")return Buffer.allocUnsafe(0);let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new Da.Header({path:("PaxHeader/"+(0,Ta.basename)(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:t,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(e,512,t,"utf8");for(let n=t+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(e,t,i=!1){return new s(Pa(Na(e),t),i)}};ti.Pax=Is;var Pa=(s,e)=>e?Object.assign({},e,s):s,Na=s=>s.replace(/\n$/,"").split(` -`).reduce(Ma,Object.create(null)),Ma=(s,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return s;e=e.slice((t+" ").length);let i=e.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=");return s[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(Number(o)*1e3):/^[0-9]+$/.test(o)?+o:o,s}});var et=d(si=>{"use strict";Object.defineProperty(si,"__esModule",{value:!0});si.normalizeWindowsPath=void 0;var La=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;si.normalizeWindowsPath=La!=="win32"?s=>s:s=>s&&s.replaceAll(/\\/g,"/")});var oi=d(ni=>{"use strict";Object.defineProperty(ni,"__esModule",{value:!0});ni.ReadEntry=void 0;var Aa=We(),ri=et(),Fs=class extends Aa.Minipass{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(e,t,i){switch(super({}),this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.remain=e.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=e.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!e.path)throw new Error("no path provided for tar.ReadEntry");this.path=(0,ri.normalizeWindowsPath)(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=this.remain,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath?(0,ri.normalizeWindowsPath)(e.linkpath):void 0,this.uname=e.uname,this.gname=e.gname,t&&this.#e(t),i&&this.#e(i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,r-t),this.ignore?!0:i>=t?super.write(e):super.write(e.subarray(0,i))}#e(e,t=!1){e.path&&(e.path=(0,ri.normalizeWindowsPath)(e.path)),e.linkpath&&(e.linkpath=(0,ri.normalizeWindowsPath)(e.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(e).filter(([i,r])=>!(r==null||i==="path"&&t))))}};ni.ReadEntry=Fs});var hi=d(ai=>{"use strict";Object.defineProperty(ai,"__esModule",{value:!0});ai.warnMethod=void 0;var Ia=(s,e,t,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!s.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),s.emit("warn",e,t,i)):t instanceof Error?s.emit("error",Object.assign(t,i)):s.emit("error",Object.assign(new Error(`${e}: ${t}`),i))};ai.warnMethod=Ia});var _i=d(pi=>{"use strict";Object.defineProperty(pi,"__esModule",{value:!0});pi.Parser=void 0;var Fa=require("events"),Cs=Ps(),Vr=Je(),$r=ii(),Ca=oi(),Ba=hi(),za=1024*1024,js=Buffer.from([31,139]),Us=Buffer.from([40,181,47,253]),ka=Math.max(js.length,Us.length),H=Symbol("state"),ze=Symbol("writeEntry"),de=Symbol("readEntry"),Bs=Symbol("nextEntry"),Xr=Symbol("processEntry"),re=Symbol("extendedHeader"),gt=Symbol("globalExtendedHeader"),ge=Symbol("meta"),Qr=Symbol("emitMeta"),_=Symbol("buffer"),me=Symbol("queue"),Oe=Symbol("ended"),zs=Symbol("emittedEnd"),ke=Symbol("emit"),S=Symbol("unzip"),li=Symbol("consumeChunk"),ui=Symbol("consumeChunkSub"),ks=Symbol("consumeBody"),Jr=Symbol("consumeMeta"),en=Symbol("consumeHeader"),Ot=Symbol("consuming"),xs=Symbol("bufferConcat"),ci=Symbol("maybeEnd"),tt=Symbol("writing"),Re=Symbol("aborted"),fi=Symbol("onDone"),xe=Symbol("sawValidEntry"),di=Symbol("sawNullBlock"),mi=Symbol("sawEOF"),tn=Symbol("closeStream"),xa=()=>!0,qs=class extends Fa.EventEmitter{file;strict;maxMetaEntrySize;filter;brotli;zstd;writable=!0;readable=!1;[me]=[];[_];[de];[ze];[H]="begin";[ge]="";[re];[gt];[Oe]=!1;[S];[Re]=!1;[xe];[di]=!1;[mi]=!1;[tt]=!1;[Ot]=!1;[zs]=!1;constructor(e={}){super(),this.file=e.file||"",this.on(fi,()=>{(this[H]==="begin"||this[xe]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(fi,e.ondone):this.on(fi,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||za,this.filter=typeof e.filter=="function"?e.filter:xa;let t=e.file&&(e.file.endsWith(".tar.br")||e.file.endsWith(".tbr"));this.brotli=!(e.gzip||e.zstd)&&e.brotli!==void 0?e.brotli:t?void 0:!1;let i=e.file&&(e.file.endsWith(".tar.zst")||e.file.endsWith(".tzst"));this.zstd=!(e.gzip||e.brotli)&&e.zstd!==void 0?e.zstd:i?!0:void 0,this.on("end",()=>this[tn]()),typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onReadEntry=="function"&&this.on("entry",e.onReadEntry)}warn(e,t,i={}){(0,Ba.warnMethod)(this,e,t,i)}[en](e,t){this[xe]===void 0&&(this[xe]=!1);let i;try{i=new Vr.Header(e,t,this[re],this[gt])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[di]?(this[mi]=!0,this[H]==="begin"&&(this[H]="header"),this[ke]("eof")):(this[di]=!0,this[ke]("nullBlock"));else if(this[di]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[ze]=new Ca.ReadEntry(i,this[re],this[gt]);if(!this[xe])if(n.remain){let o=()=>{n.invalid||(this[xe]=!0)};n.on("end",o)}else this[xe]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[ke]("ignoredEntry",n),this[H]="ignore",n.resume()):n.size>0&&(this[ge]="",n.on("data",o=>this[ge]+=o),this[H]="meta"):(this[re]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[ke]("ignoredEntry",n),this[H]=n.remain?"ignore":"header",n.resume()):(n.remain?this[H]="body":(this[H]="header",n.end()),this[de]?this[me].push(n):(this[me].push(n),this[Bs]())))}}}[tn](){queueMicrotask(()=>this.emit("close"))}[Xr](e){let t=!0;if(!e)this[de]=void 0,t=!1;else if(Array.isArray(e)){let[i,...r]=e;this.emit(i,...r)}else this[de]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",()=>this[Bs]()),t=!1);return t}[Bs](){do;while(this[Xr](this[me].shift()));if(this[me].length===0){let e=this[de];!e||e.flowing||e.size===e.remain?this[tt]||this.emit("drain"):e.once("drain",()=>this.emit("drain"))}}[ks](e,t){let i=this[ze];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=e.length&&t===0?e:e.subarray(t,t+r);return i.write(n),i.blockRemain||(this[H]="header",this[ze]=void 0,i.end()),n.length}[Jr](e,t){let i=this[ze],r=this[ks](e,t);return!this[ze]&&i&&this[Qr](i),r}[ke](e,t,i){this[me].length===0&&!this[de]?this.emit(e,t,i):this[me].push([e,t,i])}[Qr](e){switch(this[ke]("meta",this[ge]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[re]=$r.Pax.parse(this[ge],this[re],!1);break;case"GlobalExtendedHeader":this[gt]=$r.Pax.parse(this[ge],this[gt],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let t=this[re]??Object.create(null);this[re]=t,t.path=this[ge].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let t=this[re]||Object.create(null);this[re]=t,t.linkpath=this[ge].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+e.type)}}abort(e){this[Re]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this[Re])return i?.(),!1;if((this[S]===void 0||this.brotli===void 0&&this[S]===!1)&&e){if(this[_]&&(e=Buffer.concat([this[_],e]),this[_]=void 0),e.lengththis[li](u)),this[S].on("error",u=>this.abort(u)),this[S].on("end",()=>{this[Oe]=!0,this[li]()}),this[tt]=!0;let l=!!this[S][h?"end":"write"](e);return this[tt]=!1,i?.(),l}}this[tt]=!0,this[S]?this[S].write(e):this[li](e),this[tt]=!1;let n=this[me].length>0?!1:this[de]?this[de].flowing:!0;return!n&&this[me].length===0&&this[de]?.once("drain",()=>this.emit("drain")),i?.(),n}[xs](e){e&&!this[Re]&&(this[_]=this[_]?Buffer.concat([this[_],e]):e)}[ci](){if(this[Oe]&&!this[zs]&&!this[Re]&&!this[Ot]){this[zs]=!0;let e=this[ze];if(e&&e.blockRemain){let t=this[_]?this[_].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[_]&&e.write(this[_]),e.end()}this[ke](fi)}}[li](e){if(this[Ot]&&e)this[xs](e);else if(!e&&!this[_])this[ci]();else if(e){if(this[Ot]=!0,this[_]){this[xs](e);let t=this[_];this[_]=void 0,this[ui](t)}else this[ui](e);for(;this[_]&&this[_]?.length>=512&&!this[Re]&&!this[mi];){let t=this[_];this[_]=void 0,this[ui](t)}this[Ot]=!1}(!this[_]||this[Oe])&&this[ci]()}[ui](e){let t=0,i=e.length;for(;t+512<=i&&!this[Re]&&!this[mi];)switch(this[H]){case"begin":case"header":this[en](e,t),t+=512;break;case"ignore":case"body":t+=this[ks](e,t);break;case"meta":t+=this[Jr](e,t);break;default:throw new Error("invalid state: "+this[H])}t{"use strict";Object.defineProperty(wi,"__esModule",{value:!0});wi.stripTrailingSlashes=void 0;var ja=s=>{let e=s.length-1,t=-1;for(;e>-1&&s.charAt(e)==="/";)t=e,e--;return t===-1?s:s.slice(0,t)};wi.stripTrailingSlashes=ja});var st=d(C=>{"use strict";var Ua=C&&C.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),qa=C&&C.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Wa=C&&C.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=s.onReadEntry;s.onReadEntry=e?t=>{e(t),t.resume()}:t=>t.resume()},Ka=(s,e)=>{let t=new Map(e.map(n=>[(0,Ws.stripTrailingSlashes)(n),!0])),i=s.filter,r=(n,o="")=>{let a=o||(0,sn.parse)(n).root||".",h;if(n===a)h=!1;else{let l=t.get(n);h=l!==void 0?l:r((0,sn.dirname)(n),a)}return t.set(n,h),h};s.filter=i?(n,o)=>i(n,o)&&r((0,Ws.stripTrailingSlashes)(n)):n=>r((0,Ws.stripTrailingSlashes)(n))};C.filesFilter=Ka;var Va=s=>{let e=new Ei.Parser(s),t=s.file,i;try{i=it.default.openSync(t,"r");let r=it.default.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let t=new Ei.Parser(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("end",o),it.default.stat(r,(h,l)=>{if(h)a(h);else{let u=new Za.ReadStream(r,{readSize:i,size:l.size});u.on("error",a),u.pipe(t)}})})};C.list=(0,Ga.makeCommand)(Va,$a,s=>new Ei.Parser(s),s=>new Ei.Parser(s),(s,e)=>{e?.length&&(0,C.filesFilter)(s,e),s.noResume||Ya(s)})});var rn=d(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.modeFix=void 0;var Xa=(s,e,t)=>(s&=4095,t&&(s=(s|384)&-19),e&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);bi.modeFix=Xa});var Hs=d(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.stripAbsolutePath=void 0;var Qa=require("node:path"),{isAbsolute:Ja,parse:nn}=Qa.win32,eh=s=>{let e="",t=nn(s);for(;Ja(s)||t.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":t.root;s=s.slice(i.length),e+=i,t=nn(s)}return[e,s]};Si.stripAbsolutePath=eh});var Gs=d(rt=>{"use strict";Object.defineProperty(rt,"__esModule",{value:!0});rt.decode=rt.encode=void 0;var gi=["|","<",">","?",":"],Zs=gi.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),th=new Map(gi.map((s,e)=>[s,Zs[e]])),ih=new Map(Zs.map((s,e)=>[s,gi[e]])),sh=s=>gi.reduce((e,t)=>e.split(t).join(th.get(t)),s);rt.encode=sh;var rh=s=>Zs.reduce((e,t)=>e.split(t).join(ih.get(t)),s);rt.decode=rh});var sr=d(M=>{"use strict";var nh=M&&M.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),oh=M&&M.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ah=M&&M.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;re?(s=(0,ne.normalizeWindowsPath)(s).replace(/^\.(\/|$)/,""),(0,hh.stripTrailingSlashes)(e)+"/"+s):(0,ne.normalizeWindowsPath)(s),uh=16*1024*1024,an=Symbol("process"),hn=Symbol("file"),ln=Symbol("directory"),Ks=Symbol("symlink"),un=Symbol("hardlink"),Rt=Symbol("header"),Oi=Symbol("read"),Vs=Symbol("lstat"),Ri=Symbol("onlstat"),$s=Symbol("onread"),Xs=Symbol("onreadlink"),Qs=Symbol("openfile"),Js=Symbol("onopenfile"),ve=Symbol("close"),vi=Symbol("mode"),er=Symbol("awaitDrain"),Ys=Symbol("ondrain"),ae=Symbol("prefix"),Ti=class extends fn.Minipass{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#e=!1;constructor(e,t={}){let i=(0,pn.dealias)(t);super(),this.path=(0,ne.normalizeWindowsPath)(e),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||uh,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=(0,ne.normalizeWindowsPath)(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?(0,ne.normalizeWindowsPath)(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,a]=(0,wn.stripAbsolutePath)(this.path);o&&typeof a=="string"&&(this.path=a,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=lh.decode(this.path.replaceAll(/\\/g,"/")),e=e.replaceAll(/\\/g,"/")),this.absolute=(0,ne.normalizeWindowsPath)(i.absolute||on.default.resolve(this.cwd,e)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[Ri](n):this[Vs]()}warn(e,t,i={}){return(0,yn.warnMethod)(this,e,t,i)}emit(e,...t){return e==="error"&&(this.#e=!0),super.emit(e,...t)}[Vs](){oe.default.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Ri](t)})}[Ri](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=ch(e),this.emit("stat",e),this[an]()}[an](){switch(this.type){case"File":return this[hn]();case"Directory":return this[ln]();case"SymbolicLink":return this[Ks]();default:return this.end()}}[vi](e){return(0,mn.modeFix)(e,this.type==="Directory",this.portable)}[ae](e){return En(e,this.prefix)}[Rt](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new dn.Header({path:this[ae](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[ae](this.linkpath):this.linkpath,mode:this[vi](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new _n.Pax({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[ae](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[ae](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let e=this.header?.block;if(!e)throw new Error("failed to encode header");super.write(e)}[ln](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[Rt](),this.end()}[Ks](){oe.default.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Xs](t)})}[Xs](e){this.linkpath=(0,ne.normalizeWindowsPath)(e),this[Rt](),this.end()}[un](e){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=(0,ne.normalizeWindowsPath)(on.default.relative(this.cwd,e)),this.stat.size=0,this[Rt](),this.end()}[hn](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let e=`${this.stat.dev}:${this.stat.ino}`,t=this.linkCache.get(e);if(t?.indexOf(this.cwd)===0)return this[un](t);this.linkCache.set(e,this.absolute)}if(this[Rt](),this.stat.size===0)return this.end();this[Qs]()}[Qs](){oe.default.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[Js](t)})}[Js](e){if(this.fd=e,this.#e)return this[ve]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let t=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(t),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[Oi]()}[Oi](){let{fd:e,buf:t,offset:i,length:r,pos:n}=this;if(e===void 0||t===void 0)throw new Error("cannot read file without first opening");oe.default.read(e,t,i,r,n,(o,a)=>{if(o)return this[ve](()=>this.emit("error",o));this[$s](a)})}[ve](e=()=>{}){this.fd!==void 0&&oe.default.close(this.fd,e)}[$s](e){if(e<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(e>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(e===this.remain)for(let r=e;rthis[Ys]())}[er](e){this.once("drain",e)}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this.blockRemaine?this.emit("error",e):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[Oi]()}};M.WriteEntry=Ti;var tr=class extends Ti{sync=!0;[Vs](){this[Ri](oe.default.lstatSync(this.absolute))}[Ks](){this[Xs](oe.default.readlinkSync(this.absolute))}[Qs](){this[Js](oe.default.openSync(this.absolute,"r"))}[Oi](){let e=!0;try{let{fd:t,buf:i,offset:r,length:n,pos:o}=this;if(t===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let a=oe.default.readSync(t,i,r,n,o);this[$s](a),e=!1}finally{if(e)try{this[ve](()=>{})}catch{}}}[er](e){e()}[ve](e=()=>{}){this.fd!==void 0&&oe.default.closeSync(this.fd),e()}};M.WriteEntrySync=tr;var ir=class extends fn.Minipass{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(e,t,i={}){return(0,yn.warnMethod)(this,e,t,i)}constructor(e,t={}){let i=(0,pn.dealias)(t);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=e;let{type:r}=e;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=(0,ne.normalizeWindowsPath)(e.path),this.mode=e.mode!==void 0?this[vi](e.mode):void 0,this.uid=this.portable?void 0:e.uid,this.gid=this.portable?void 0:e.gid,this.uname=this.portable?void 0:e.uname,this.gname=this.portable?void 0:e.gname,this.size=e.size,this.mtime=this.noMtime?void 0:i.mtime||e.mtime,this.atime=this.portable?void 0:e.atime,this.ctime=this.portable?void 0:e.ctime,this.linkpath=e.linkpath!==void 0?(0,ne.normalizeWindowsPath)(e.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[a,h]=(0,wn.stripAbsolutePath)(this.path);a&&typeof h=="string"&&(this.path=h,n=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.onWriteEntry?.(this),this.header=new dn.Header({path:this[ae](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[ae](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new _n.Pax({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[ae](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[ae](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),e.pipe(this)}[ae](e){return En(e,this.prefix)}[vi](e){return(0,mn.modeFix)(e,this.type==="Directory",this.portable)}write(e,t,i){typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8"));let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e,i)}end(e,t,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,t??"utf8")),i&&this.once("finish",i),e?super.end(e,i):super.end(i),this}};M.WriteEntryTar=ir;var ch=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported"});var bn=d(ot=>{"use strict";Object.defineProperty(ot,"__esModule",{value:!0});ot.Node=ot.Yallist=void 0;var rr=class s{tail;head;length=0;static create(e=[]){return new s(e)}constructor(e=[]){for(let t of e)this.push(t)}*[Symbol.iterator](){for(let e=this.head;e;e=e.next)yield e.value}removeNode(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");let t=e.next,i=e.prev;return t&&(t.prev=i),i&&(i.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=i),this.length--,e.next=void 0,e.prev=void 0,e.list=void 0,t}unshiftNode(e){if(e===this.head)return;e.list&&e.list.removeNode(e);let t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}pushNode(e){if(e===this.tail)return;e.list&&e.list.removeNode(e);let t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}push(...e){for(let t=0,i=e.length;t1)i=t;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=e(i,r.value,n),r=r.next;return i}reduceReverse(e,t){let i,r=this.tail;if(arguments.length>1)i=t;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=e(i,r.value,n),r=r.prev;return i}toArray(){let e=new Array(this.length);for(let t=0,i=this.head;i;t++)e[t]=i.value,i=i.next;return e}toArrayReverse(){let e=new Array(this.length);for(let t=0,i=this.tail;i;t++)e[t]=i.value,i=i.prev;return e}slice(e=0,t=this.length){t<0&&(t+=this.length),e<0&&(e+=this.length);let i=new s;if(tthis.length&&(t=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(t=this.length);let r=this.length,n=this.tail;for(;n&&r>t;r--)n=n.prev;for(;n&&r>e;r--,n=n.prev)i.push(n.value);return i}splice(e,t=0,...i){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);let r=this.head;for(let o=0;r&&o{"use strict";var ph=L&&L.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),_h=L&&L.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),wh=L&&L.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(e.gzip&&(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new nr.Gzip(e.gzip)),e.brotli&&(typeof e.brotli!="object"&&(e.brotli={}),this.zip=new nr.BrotliCompress(e.brotli)),e.zstd&&(typeof e.zstd!="object"&&(e.zstd={}),this.zip=new nr.ZstdCompress(e.zstd)),!this.zip)throw new Error("impossible");let t=this.zip;t.on("data",i=>super.write(i)),t.on("end",()=>super.end()),t.on("drain",()=>this[hr]()),this.on("resume",()=>t.resume())}else this.on("drain",this[hr]);this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,e.mtime&&(this.mtime=e.mtime),this.filter=typeof e.filter=="function"?e.filter:()=>!0,this[X]=new Eh.Yallist,this[Q]=0,this.jobs=Number(e.jobs)||4,this[Dt]=!1,this[vt]=!1}[Tn](e){return super.write(e)}add(e){return this.write(e),this}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&this.add(e),this[vt]=!0,this[je](),i&&i(),this}write(e){if(this[vt])throw new Error("write after end");return e instanceof bh.ReadEntry?this[gn](e):this[Ni](e),this.flowing}[gn](e){let t=(0,lr.normalizeWindowsPath)(Rn.default.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let i=new Pt(e.path,t);i.entry=new ur.WriteEntryTar(e,this[ar](i)),i.entry.on("end",()=>this[or](i)),this[Q]+=1,this[X].push(i)}this[je]()}[Ni](e){let t=(0,lr.normalizeWindowsPath)(Rn.default.resolve(this.cwd,e));this[X].push(new Pt(e,t)),this[je]()}[cr](e){e.pending=!0,this[Q]+=1;let t=this.follow?"stat":"lstat";Ii.default[t](e.absolute,(i,r)=>{e.pending=!1,this[Q]-=1,i?this.emit("error",i):this[Pi](e,r)})}[Pi](e,t){if(this.statCache.set(e.absolute,t),e.stat=t,!this.filter(e.path,t))e.ignore=!0;else if(t.isFile()&&t.nlink>1&&!this.linkCache.get(`${t.dev}:${t.ino}`)&&!this.sync)if(e===this[Te])this[Di](e);else{let i=`${t.dev}:${t.ino}`,r=this[Tt].get(i);r?r.push(e):this[Tt].set(i,[e]),e.pendingLink=!0,e.pending=!0}this[je]()}[fr](e){e.pending=!0,this[Q]+=1,Ii.default.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[Q]-=1,t)return this.emit("error",t);this[Mi](e,i)})}[Mi](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[je]()}[je](){if(!this[Dt]){this[Dt]=!0;for(let e=this[X].head;e&&this[Q]1){let i=`${t.dev}:${t.ino}`,r=this[Tt].get(i);if(r){this[Tt].delete(i);for(let n of r)n.pending=!1,this[Di](n)}}this[je]()}[Di](e){if(e.pending&&e.pendingLink&&e===this[Te]&&(e.pending=!1,e.pendingLink=!1),!e.pending){if(e.entry){e===this[Te]&&!e.piped&&this[Li](e);return}if(!e.stat){let t=this.statCache.get(e.absolute);t?this[Pi](e,t):this[cr](e)}if(e.stat&&!e.ignore){if(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir){let t=this.readdirCache.get(e.absolute);if(t?this[Mi](e,t):this[fr](e),!e.readdir)return}if(e.entry=this[On](e),!e.entry){e.ignore=!0;return}e===this[Te]&&!e.piped&&this[Li](e)}}}[ar](e){return{onwarn:(t,i,r)=>this.warn(t,i,r),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[On](e){this[Q]+=1;try{return new this[Ai](e.path,this[ar](e)).on("end",()=>this[or](e)).on("error",i=>this.emit("error",i))}catch(t){this.emit("error",t)}}[hr](){this[Te]&&this[Te].entry&&this[Te].entry.resume()}[Li](e){e.piped=!0,e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)});let t=e.entry,i=this.zip;if(!t)throw new Error("cannot pipe without source");i?t.on("data",r=>{i.write(r)||t.pause()}):t.on("data",r=>{super.write(r)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(e,t,i={}){(0,Sh.warnMethod)(this,e,t,i)}};L.Pack=Fi;var dr=class extends Fi{sync=!0;constructor(e){super(e),this[Ai]=ur.WriteEntrySync}pause(){}resume(){}[cr](e){let t=this.follow?"statSync":"lstatSync";this[Pi](e,Ii.default[t](e.absolute))}[fr](e){this[Mi](e,Ii.default.readdirSync(e.absolute))}[Li](e){let t=e.entry,i=this.zip;if(e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)}),!t)throw new Error("Cannot pipe without source");i?t.on("data",r=>{i.write(r)}):t.on("data",r=>{super[Tn](r)})}};L.PackSync=dr});var mr=d(at=>{"use strict";var gh=at&&at.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(at,"__esModule",{value:!0});at.create=void 0;var Dn=Ke(),Pn=gh(require("node:path")),Nn=st(),Oh=Ve(),Bi=Ci(),Rh=(s,e)=>{let t=new Bi.PackSync(s),i=new Dn.WriteStreamSync(s.file,{mode:s.mode||438});t.pipe(i),Mn(t,e)},vh=(s,e)=>{let t=new Bi.Pack(s),i=new Dn.WriteStream(s.file,{mode:s.mode||438});t.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),t.on("error",o)});return Ln(t,e).catch(n=>t.emit("error",n)),r},Mn=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,Nn.list)({file:Pn.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},Ln=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,Nn.list)({file:Pn.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(t);s.end()},Th=(s,e)=>{let t=new Bi.PackSync(s);return Mn(t,e),t},Dh=(s,e)=>{let t=new Bi.Pack(s);return Ln(t,e).catch(i=>t.emit("error",i)),t};at.create=(0,Oh.makeCommand)(Rh,vh,Th,Dh,(s,e)=>{if(!e?.length)throw new TypeError("no paths specified to add to archive")})});var jn=d(ht=>{"use strict";var Ph=ht&&ht.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ht,"__esModule",{value:!0});ht.getWriteFlag=void 0;var Fn=Ph(require("fs")),Nh=process.env.__FAKE_PLATFORM__||process.platform,Cn=Nh==="win32",{O_CREAT:Bn,O_NOFOLLOW:An,O_TRUNC:zn,O_WRONLY:kn}=Fn.default.constants,xn=Number(process.env.__FAKE_FS_O_FILENAME__)||Fn.default.constants.UV_FS_O_FILEMAP||0,Mh=Cn&&!!xn,Lh=512*1024,Ah=xn|zn|Bn|kn,In=!Cn&&typeof An=="number"?An|zn|Bn|kn:null;ht.getWriteFlag=In!==null?()=>In:Mh?s=>s"w"});var qn=d(he=>{"use strict";var Un=he&&he.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(he,"__esModule",{value:!0});he.chownrSync=he.chownr=void 0;var ki=Un(require("node:fs")),Nt=Un(require("node:path")),pr=(s,e,t)=>{try{return ki.default.lchownSync(s,e,t)}catch(i){if(i?.code!=="ENOENT")throw i}},zi=(s,e,t,i)=>{ki.default.lchown(s,e,t,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},Ih=(s,e,t,i,r)=>{if(e.isDirectory())(0,he.chownr)(Nt.default.resolve(s,e.name),t,i,n=>{if(n)return r(n);let o=Nt.default.resolve(s,e.name);zi(o,t,i,r)});else{let n=Nt.default.resolve(s,e.name);zi(n,t,i,r)}},Fh=(s,e,t,i)=>{ki.default.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return zi(s,e,t,i);let o=n.length,a=null,h=l=>{if(!a){if(l)return i(a=l);if(--o===0)return zi(s,e,t,i)}};for(let l of n)Ih(s,l,e,t,h)})};he.chownr=Fh;var Ch=(s,e,t,i)=>{e.isDirectory()&&(0,he.chownrSync)(Nt.default.resolve(s,e.name),t,i),pr(Nt.default.resolve(s,e.name),t,i)},Bh=(s,e,t)=>{let i;try{i=ki.default.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return pr(s,e,t);throw n}for(let r of i)Ch(s,r,e,t);return pr(s,e,t)};he.chownrSync=Bh});var Wn=d(xi=>{"use strict";Object.defineProperty(xi,"__esModule",{value:!0});xi.CwdError=void 0;var _r=class extends Error{path;code;syscall="chdir";constructor(e,t){super(`${t}: Cannot cd into '${e}'`),this.path=e,this.code=t}get name(){return"CwdError"}};xi.CwdError=_r});var yr=d(ji=>{"use strict";Object.defineProperty(ji,"__esModule",{value:!0});ji.SymlinkError=void 0;var wr=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(e,t){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=e,this.path=t}get name(){return"SymlinkError"}};ji.SymlinkError=wr});var Kn=d(De=>{"use strict";var br=De&&De.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(De,"__esModule",{value:!0});De.mkdirSync=De.mkdir=void 0;var Hn=qn(),j=br(require("node:fs")),zh=br(require("node:fs/promises")),Ui=br(require("node:path")),Zn=Wn(),pe=et(),Gn=yr(),kh=(s,e)=>{j.default.stat(s,(t,i)=>{(t||!i.isDirectory())&&(t=new Zn.CwdError(s,t?.code||"ENOTDIR")),e(t)})},xh=(s,e,t)=>{s=(0,pe.normalizeWindowsPath)(s);let i=e.umask??18,r=e.mode|448,n=(r&i)!==0,o=e.uid,a=e.gid,h=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),l=e.preserve,u=e.unlink,c=(0,pe.normalizeWindowsPath)(e.cwd),E=(w,P)=>{w?t(w):P&&h?(0,Hn.chownr)(P,o,a,kt=>E(kt)):n?j.default.chmod(s,r,t):t()};if(s===c)return kh(s,E);if(l)return zh.default.mkdir(s,{mode:r,recursive:!0}).then(w=>E(null,w??void 0),E);let A=(0,pe.normalizeWindowsPath)(Ui.default.relative(c,s)).split("/");Er(c,A,r,u,c,void 0,E)};De.mkdir=xh;var Er=(s,e,t,i,r,n,o)=>{if(e.length===0)return o(null,n);let a=e.shift(),h=(0,pe.normalizeWindowsPath)(Ui.default.resolve(s+"/"+a));j.default.mkdir(h,t,Yn(h,e,t,i,r,n,o))},Yn=(s,e,t,i,r,n,o)=>a=>{a?j.default.lstat(s,(h,l)=>{if(h)h.path=h.path&&(0,pe.normalizeWindowsPath)(h.path),o(h);else if(l.isDirectory())Er(s,e,t,i,r,n,o);else if(i)j.default.unlink(s,u=>{if(u)return o(u);j.default.mkdir(s,t,Yn(s,e,t,i,r,n,o))});else{if(l.isSymbolicLink())return o(new Gn.SymlinkError(s,s+"/"+e.join("/")));o(a)}}):(n=n||s,Er(s,e,t,i,r,n,o))},jh=s=>{let e=!1,t;try{e=j.default.statSync(s).isDirectory()}catch(i){t=i?.code}finally{if(!e)throw new Zn.CwdError(s,t??"ENOTDIR")}},Uh=(s,e)=>{s=(0,pe.normalizeWindowsPath)(s);let t=e.umask??18,i=e.mode|448,r=(i&t)!==0,n=e.uid,o=e.gid,a=typeof n=="number"&&typeof o=="number"&&(n!==e.processUid||o!==e.processGid),h=e.preserve,l=e.unlink,u=(0,pe.normalizeWindowsPath)(e.cwd),c=w=>{w&&a&&(0,Hn.chownrSync)(w,n,o),r&&j.default.chmodSync(s,i)};if(s===u)return jh(u),c();if(h)return c(j.default.mkdirSync(s,{mode:i,recursive:!0})??void 0);let D=(0,pe.normalizeWindowsPath)(Ui.default.relative(u,s)).split("/"),A;for(let w=D.shift(),P=u;w&&(P+="/"+w);w=D.shift()){P=(0,pe.normalizeWindowsPath)(Ui.default.resolve(P));try{j.default.mkdirSync(P,i),A=A||P}catch{let kt=j.default.lstatSync(P);if(kt.isDirectory())continue;if(l){j.default.unlinkSync(P),j.default.mkdirSync(P,i),A=A||P;continue}else if(kt.isSymbolicLink())return new Gn.SymlinkError(P,P+"/"+D.join("/"))}}return c(A)};De.mkdirSync=Uh});var $n=d(qi=>{"use strict";Object.defineProperty(qi,"__esModule",{value:!0});qi.normalizeUnicode=void 0;var Sr=Object.create(null),Vn=1e4,lt=new Set,qh=s=>{lt.has(s)?lt.delete(s):Sr[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),lt.add(s);let e=Sr[s],t=lt.size-Vn;if(t>Vn/10){for(let i of lt)if(lt.delete(i),delete Sr[i],--t<=0)break}return e};qi.normalizeUnicode=qh});var Qn=d(Wi=>{"use strict";Object.defineProperty(Wi,"__esModule",{value:!0});Wi.PathReservations=void 0;var Xn=require("node:path"),Wh=$n(),Hh=yi(),Zh=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Gh=Zh==="win32",Yh=s=>s.split("/").slice(0,-1).reduce((t,i)=>{let r=t.at(-1);return r!==void 0&&(i=(0,Xn.join)(r,i)),t.push(i||"/"),t},[]),gr=class{#e=new Map;#i=new Map;#s=new Set;reserve(e,t){e=Gh?["win32 parallelization disabled"]:e.map(r=>(0,Hh.stripTrailingSlashes)((0,Xn.join)((0,Wh.normalizeUnicode)(r))));let i=new Set(e.map(r=>Yh(r)).reduce((r,n)=>r.concat(n)));this.#i.set(t,{dirs:i,paths:e});for(let r of e){let n=this.#e.get(r);n?n.push(t):this.#e.set(r,[t])}for(let r of i){let n=this.#e.get(r);if(!n)this.#e.set(r,[new Set([t])]);else{let o=n.at(-1);o instanceof Set?o.add(t):n.push(new Set([t]))}}return this.#r(t)}#n(e){let t=this.#i.get(e);if(!t)throw new Error("function does not have any path reservations");return{paths:t.paths.map(i=>this.#e.get(i)),dirs:[...t.dirs].map(i=>this.#e.get(i))}}check(e){let{paths:t,dirs:i}=this.#n(e);return t.every(r=>r&&r[0]===e)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(e))}#r(e){return this.#s.has(e)||!this.check(e)?!1:(this.#s.add(e),e(()=>this.#t(e)),!0)}#t(e){if(!this.#s.has(e))return!1;let t=this.#i.get(e);if(!t)throw new Error("invalid reservation");let{paths:i,dirs:r}=t,n=new Set;for(let o of i){let a=this.#e.get(o);if(!a||a?.[0]!==e)continue;let h=a[1];if(!h){this.#e.delete(o);continue}if(a.shift(),typeof h=="function")n.add(h);else for(let l of h)n.add(l)}for(let o of r){let a=this.#e.get(o),h=a?.[0];if(!(!a||!(h instanceof Set)))if(h.size===1&&a.length===1){this.#e.delete(o);continue}else if(h.size===1){a.shift();let l=a[0];typeof l=="function"&&n.add(l)}else h.delete(e)}return this.#s.delete(e),n.forEach(o=>this.#r(o)),!0}};Wi.PathReservations=gr});var Jn=d(Hi=>{"use strict";Object.defineProperty(Hi,"__esModule",{value:!0});Hi.umask=void 0;var Kh=()=>process.umask();Hi.umask=Kh});var Ir=d(z=>{"use strict";var Vh=z&&z.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),$h=z&&z.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),lo=z&&z.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{if(!Bt)return m.default.unlink(s,e);let t=s+".DELETE."+(0,uo.randomBytes)(16).toString("hex");m.default.rename(s,t,i=>{if(i)return e(i);m.default.unlink(t,e)})},ol=s=>{if(!Bt)return m.default.unlinkSync(s);let e=s+".DELETE."+(0,uo.randomBytes)(16).toString("hex");m.default.renameSync(s,e),m.default.unlinkSync(e)},ho=(s,e,t)=>s!==void 0&&s===s>>>0?s:e!==void 0&&e===e>>>0?e:t,Yi=class extends Jh.Parser{[Rr]=!1;[Ct]=!1;[Zi]=0;reservations=new tl.PathReservations;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(e={}){if(e.ondone=()=>{this[Rr]=!0,this[vr]()},super(e),this.transform=e.transform,this.chmod=!!e.chmod,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=e.preserveOwner===void 0&&typeof e.uid!="number"?!!(process.getuid&&process.getuid()===0):!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof e.maxDepth=="number"?e.maxDepth:rl,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||Bt,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=(0,U.normalizeWindowsPath)(g.default.resolve(e.cwd||process.cwd())),this.strip=Number(e.strip)||0,this.processUmask=this.chmod?typeof e.processUmask=="number"?e.processUmask:(0,il.umask)():0,this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[to](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[vr](){this[Rr]&&this[Zi]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[Or](e,t){let i=e[t],{type:r}=e;if(!i||this.preservePaths)return!0;let[n,o]=(0,el.stripAbsolutePath)(i),a=o.replaceAll(/\\/g,"/").split("/");if(a.includes("..")||Bt&&/^[a-z]:\.\.$/i.test(a[0]??"")){if(t==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${t} contains '..'`,{entry:e,[t]:i}),!1;let h=g.default.posix.dirname(e.path),l=g.default.posix.normalize(g.default.posix.join(h,a.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${t} escapes extraction directory`,{entry:e,[t]:i}),!1}return n&&(e[t]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${t}`,{entry:e,[t]:i})),!0}[oo](e){let t=(0,U.normalizeWindowsPath)(e.path),i=t.split("/");if(this.strip){if(i.length=this.strip)e.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),e.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:e,path:t,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[Or](e,"path")||!this[Or](e,"linkpath"))return!1;if(e.absolute=g.default.isAbsolute(e.path)?(0,U.normalizeWindowsPath)(g.default.resolve(e.path)):(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,e.path)),!this.preservePaths&&typeof e.absolute=="string"&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:(0,U.normalizeWindowsPath)(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=g.default.win32.parse(String(e.absolute));e.absolute=r+eo.encode(String(e.absolute).slice(r.length));let{root:n}=g.default.win32.parse(e.path);e.path=n+eo.encode(e.path.slice(n.length))}return!0}[to](e){if(!this[oo](e))return e.resume();switch(Qh.default.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[Tr](e);default:return this[no](e)}}[T](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[ut](),t.resume())}[Pe](e,t,i){(0,fo.mkdir)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t},i)}[At](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[It](e){return ho(this.uid,e.uid,this.processUid)}[Ft](e){return ho(this.gid,e.gid,this.processGid)}[Pr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=new Xh.WriteStream(String(e.absolute),{flags:(0,co.getWriteFlag)(e.size),mode:i,autoClose:!1});r.on("error",h=>{r.fd&&m.default.close(r.fd,()=>{}),r.write=()=>!0,this[T](h,e),t()});let n=1,o=h=>{if(h){r.fd&&m.default.close(r.fd,()=>{}),this[T](h,e),t();return}--n===0&&r.fd!==void 0&&m.default.close(r.fd,l=>{l?this[T](l,e):this[ut](),t()})};r.on("finish",()=>{let h=String(e.absolute),l=r.fd;if(typeof l=="number"&&e.mtime&&!this.noMtime){n++;let u=e.atime||new Date,c=e.mtime;m.default.futimes(l,u,c,E=>E?m.default.utimes(h,u,c,D=>o(D&&E)):o())}if(typeof l=="number"&&this[At](e)){n++;let u=this[It](e),c=this[Ft](e);typeof u=="number"&&typeof c=="number"&&m.default.fchown(l,u,c,E=>E?m.default.chown(h,u,c,D=>o(D&&E)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",h=>{this[T](h,e),t()}),e.pipe(a)),a.pipe(r)}[Nr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode;this[Pe](String(e.absolute),i,r=>{if(r){this[T](r,e),t();return}let n=1,o=()=>{--n===0&&(t(),this[ut](),e.resume())};e.mtime&&!this.noMtime&&(n++,m.default.utimes(String(e.absolute),e.atime||new Date,e.mtime,o)),this[At](e)&&(n++,m.default.chown(String(e.absolute),Number(this[It](e)),Number(this[Ft](e)),o)),o()})}[no](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[so](e,t){let i=(0,U.normalizeWindowsPath)(g.default.relative(this.cwd,g.default.resolve(g.default.dirname(String(e.absolute)),String(e.linkpath)))).split("/");this[Lt](e,this.cwd,i,()=>this[Gi](e,String(e.linkpath),"symlink",t),r=>{this[T](r,e),t()})}[ro](e,t){let i=(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,String(e.linkpath))),r=(0,U.normalizeWindowsPath)(String(e.linkpath)).split("/");this[Lt](e,this.cwd,r,()=>this[Gi](e,i,"link",t),n=>{this[T](n,e),t()})}[Lt](e,t,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let a=g.default.resolve(t,o);m.default.lstat(a,(h,l)=>{if(h)return r();if(l?.isSymbolicLink())return n(new mo.SymlinkError(a,g.default.resolve(a,i.join("/"))));this[Lt](e,a,i,r,n)})}[ao](){this[Zi]++}[ut](){this[Zi]--,this[vr]()}[Mr](e){this[ut](),e.resume()}[Dr](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&!Bt}[Tr](e){this[ao]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[io](e,i))}[io](e,t){let i=a=>{t(a)},r=()=>{this[Pe](this.cwd,this.dmode,a=>{if(a){this[T](a,e),i();return}this[Ct]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let a=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(a!==this.cwd)return this[Pe](a,this.dmode,h=>{if(h){this[T](h,e),i();return}o()})}o()},o=()=>{m.default.lstat(String(e.absolute),(a,h)=>{if(h&&(this.keep||this.newer&&h.mtime>(e.mtime??h.mtime))){this[Mr](e),i();return}if(a||this[Dr](e,h))return this[Z](null,e,i);if(h.isDirectory()){if(e.type==="Directory"){let l=this.chmod&&e.mode&&(h.mode&4095)!==e.mode,u=c=>this[Z](c??null,e,i);return l?m.default.chmod(String(e.absolute),Number(e.mode),u):u()}if(e.absolute!==this.cwd)return m.default.rmdir(String(e.absolute),l=>this[Z](l??null,e,i))}if(e.absolute===this.cwd)return this[Z](null,e,i);nl(String(e.absolute),l=>this[Z](l??null,e,i))})};this[Ct]?n():r()}[Z](e,t,i){if(e){this[T](e,t),i();return}switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[Pr](t,i);case"Link":return this[ro](t,i);case"SymbolicLink":return this[so](t,i);case"Directory":case"GNUDumpDir":return this[Nr](t,i)}}[Gi](e,t,i,r){m.default[i](t,String(e.absolute),n=>{n?this[T](n,e):(this[ut](),e.resume()),r()})}};z.Unpack=Yi;var Mt=s=>{try{return[null,s()]}catch(e){return[e,null]}},Lr=class extends Yi{sync=!0;[Z](e,t){return super[Z](e,t,()=>{})}[Tr](e){if(!this[Ct]){let n=this[Pe](this.cwd,this.dmode);if(n)return this[T](n,e);this[Ct]=!0}if(e.absolute!==this.cwd){let n=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(n!==this.cwd){let o=this[Pe](n,this.dmode);if(o)return this[T](o,e)}}let[t,i]=Mt(()=>m.default.lstatSync(String(e.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(e.mtime??i.mtime)))return this[Mr](e);if(t||this[Dr](e,i))return this[Z](null,e);if(i.isDirectory()){if(e.type==="Directory"){let o=this.chmod&&e.mode&&(i.mode&4095)!==e.mode,[a]=o?Mt(()=>{m.default.chmodSync(String(e.absolute),Number(e.mode))}):[];return this[Z](a,e)}let[n]=Mt(()=>m.default.rmdirSync(String(e.absolute)));this[Z](n,e)}let[r]=e.absolute===this.cwd?[]:Mt(()=>ol(String(e.absolute)));this[Z](r,e)}[Pr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=a=>{let h;try{m.default.closeSync(n)}catch(l){h=l}(a||h)&&this[T](a||h,e),t()},n;try{n=m.default.openSync(String(e.absolute),(0,co.getWriteFlag)(e.size),i)}catch(a){return r(a)}let o=this.transform&&this.transform(e)||e;o!==e&&(o.on("error",a=>this[T](a,e)),e.pipe(o)),o.on("data",a=>{try{m.default.writeSync(n,a,0,a.length)}catch(h){r(h)}}),o.on("end",()=>{let a=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,l=e.mtime;try{m.default.futimesSync(n,h,l)}catch(u){try{m.default.utimesSync(String(e.absolute),h,l)}catch{a=u}}}if(this[At](e)){let h=this[It](e),l=this[Ft](e);try{m.default.fchownSync(n,Number(h),Number(l))}catch(u){try{m.default.chownSync(String(e.absolute),Number(h),Number(l))}catch{a=a||u}}}r(a)})}[Nr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode,r=this[Pe](String(e.absolute),i);if(r){this[T](r,e),t();return}if(e.mtime&&!this.noMtime)try{m.default.utimesSync(String(e.absolute),e.atime||new Date,e.mtime)}catch{}if(this[At](e))try{m.default.chownSync(String(e.absolute),Number(this[It](e)),Number(this[Ft](e)))}catch{}t(),e.resume()}[Pe](e,t){try{return(0,fo.mkdirSync)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t})}catch(i){return i}}[Lt](e,t,i,r,n){if(this.preservePaths||i.length===0)return r();let o=t;for(let a of i){o=g.default.resolve(o,a);let[h,l]=Mt(()=>m.default.lstatSync(o));if(h)return r();if(l.isSymbolicLink())return n(new mo.SymlinkError(o,g.default.resolve(t,i.join("/"))))}r()}[Gi](e,t,i,r){let n=`${i}Sync`;try{m.default[n](t,String(e.absolute)),r(),e.resume()}catch(o){return this[T](o,e)}}};z.UnpackSync=Lr});var Fr=d(G=>{"use strict";var al=G&&G.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),hl=G&&G.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ll=G&&G.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=new Ki.UnpackSync(s),t=s.file,i=_o.default.statSync(t),r=s.maxReadSize||16*1024*1024;new po.ReadStreamSync(t,{readSize:r,size:i.size}).pipe(e)},ml=(s,e)=>{let t=new Ki.Unpack(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("close",o),_o.default.stat(r,(h,l)=>{if(h)a(h);else{let u=new po.ReadStream(r,{readSize:i,size:l.size});u.on("error",a),u.pipe(t)}})})};G.extract=(0,fl.makeCommand)(dl,ml,s=>new Ki.UnpackSync(s),s=>new Ki.Unpack(s),(s,e)=>{e?.length&&(0,cl.filesFilter)(s,e)})});var Vi=d(ct=>{"use strict";var wo=ct&&ct.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ct,"__esModule",{value:!0});ct.replace=void 0;var yo=Ke(),q=wo(require("node:fs")),Eo=wo(require("node:path")),bo=Je(),So=st(),pl=Ve(),_l=Xt(),go=Ci(),wl=(s,e)=>{let t=new go.PackSync(s),i=!0,r,n;try{try{r=q.default.openSync(s.file,"r+")}catch(h){if(h?.code==="ENOENT")r=q.default.openSync(s.file,"w+");else throw h}let o=q.default.fstatSync(r),a=Buffer.alloc(512);e:for(n=0;no.size)break;n+=l,s.mtimeCache&&h.mtime&&s.mtimeCache.set(String(h.path),h.mtime)}i=!1,yl(s,t,n,r,e)}finally{if(i)try{q.default.closeSync(r)}catch{}}},yl=(s,e,t,i,r)=>{let n=new yo.WriteStreamSync(s.file,{fd:i,start:t});e.pipe(n),bl(e,r)},El=(s,e)=>{e=Array.from(e);let t=new go.Pack(s),i=(n,o,a)=>{let h=(D,A)=>{D?q.default.close(n,w=>a(D)):a(null,A)},l=0;if(o===0)return h(null,0);let u=0,c=Buffer.alloc(512),E=(D,A)=>{if(D||A===void 0)return h(D);if(u+=A,u<512&&A)return q.default.read(n,c,u,c.length-u,l+u,E);if(l===0&&c[0]===31&&c[1]===139)return h(new Error("cannot append to compressed archives"));if(u<512)return h(null,l);let w=new bo.Header(c);if(!w.cksumValid)return h(null,l);let P=512*Math.ceil((w.size??0)/512);if(l+P+512>o||(l+=P+512,l>=o))return h(null,l);s.mtimeCache&&w.mtime&&s.mtimeCache.set(String(w.path),w.mtime),u=0,q.default.read(n,c,0,512,l,E)};q.default.read(n,c,0,512,l,E)};return new Promise((n,o)=>{t.on("error",o);let a="r+",h=(l,u)=>{if(l&&l.code==="ENOENT"&&a==="r+")return a="w+",q.default.open(s.file,a,h);if(l||!u)return o(l);q.default.fstat(u,(c,E)=>{if(c)return q.default.close(u,()=>o(c));i(u,E.size,(D,A)=>{if(D)return o(D);let w=new yo.WriteStream(s.file,{fd:u,start:A});t.pipe(w),w.on("error",o),w.on("close",n),Sl(t,e)})})};q.default.open(s.file,a,h)})},bl=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,So.list)({file:Eo.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},Sl=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,So.list)({file:Eo.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t);s.end()};ct.replace=(0,pl.makeCommand)(wl,El,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,e)=>{if(!(0,_l.isFile)(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!e?.length)throw new TypeError("no paths specified to add/replace")})});var Cr=d($i=>{"use strict";Object.defineProperty($i,"__esModule",{value:!0});$i.update=void 0;var gl=Ve(),zt=Vi();$i.update=(0,gl.makeCommand)(zt.replace.syncFile,zt.replace.asyncFile,zt.replace.syncNoFile,zt.replace.asyncNoFile,(s,e=[])=>{zt.replace.validate?.(s,e),Ol(s)});var Ol=s=>{let e=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=e?(t,i)=>e(t,i)&&!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0)):(t,i)=>!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0))}});var Oo=exports&&exports.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Rl=exports&&exports.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Y=exports&&exports.__exportStar||function(s,e){for(var t in s)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Oo(e,s,t)},vl=exports&&exports.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r()=>(e||s((e={exports:{}}).exports,e),e.exports);var We=d(F=>{"use strict";var Do=F&&F.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(F,"__esModule",{value:!0});F.Minipass=F.isWritable=F.isReadable=F.isStream=void 0;var kr=typeof process=="object"&&process?process:{stdout:null,stderr:null},ss=require("node:events"),qr=Do(require("node:stream")),Po=require("node:string_decoder"),No=s=>!!s&&typeof s=="object"&&(s instanceof Zt||s instanceof qr.default||(0,F.isReadable)(s)||(0,F.isWritable)(s));F.isStream=No;var Mo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.pipe=="function"&&s.pipe!==qr.default.Writable.prototype.pipe;F.isReadable=Mo;var Lo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.write=="function"&&typeof s.end=="function";F.isWritable=Lo;var ce=Symbol("EOF"),ue=Symbol("maybeEmitEnd"),we=Symbol("emittedEnd"),jt=Symbol("emittingEnd"),dt=Symbol("emittedError"),Ut=Symbol("closed"),xr=Symbol("read"),qt=Symbol("flush"),jr=Symbol("flushChunk"),K=Symbol("encoding"),Ue=Symbol("decoder"),R=Symbol("flowing"),mt=Symbol("paused"),qe=Symbol("resume"),O=Symbol("buffer"),I=Symbol("pipes"),v=Symbol("bufferLength"),Xi=Symbol("bufferPush"),Wt=Symbol("bufferShift"),N=Symbol("objectMode"),y=Symbol("destroyed"),Qi=Symbol("error"),Ji=Symbol("emitData"),Ur=Symbol("emitEnd"),es=Symbol("emitEnd2"),J=Symbol("async"),ts=Symbol("abort"),Ht=Symbol("aborted"),pt=Symbol("signal"),Ne=Symbol("dataListeners"),x=Symbol("discarded"),_t=s=>Promise.resolve().then(s),Ao=s=>s(),Io=s=>s==="end"||s==="finish"||s==="prefinish",Fo=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,Co=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Gt=class{src;dest;opts;ondrain;constructor(e,t,i){this.src=e,this.dest=t,this.opts=i,this.ondrain=()=>e[qe](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},is=class extends Gt{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,i){super(e,t,i),this.proxyErrors=r=>this.dest.emit("error",r),e.on("error",this.proxyErrors)}},Bo=s=>!!s.objectMode,zo=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",Zt=class extends ss.EventEmitter{[R]=!1;[mt]=!1;[I]=[];[O]=[];[N];[K];[J];[Ue];[ce]=!1;[we]=!1;[jt]=!1;[Ut]=!1;[dt]=null;[v]=0;[y]=!1;[pt];[Ht]=!1;[Ne]=0;[x]=!1;writable=!0;readable=!0;constructor(...e){let t=e[0]||{};if(super(),t.objectMode&&typeof t.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Bo(t)?(this[N]=!0,this[K]=null):zo(t)?(this[K]=t.encoding,this[N]=!1):(this[N]=!1,this[K]=null),this[J]=!!t.async,this[Ue]=this[K]?new Po.StringDecoder(this[K]):null,t&&t.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[O]}),t&&t.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[I]});let{signal:i}=t;i&&(this[pt]=i,i.aborted?this[ts]():i.addEventListener("abort",()=>this[ts]()))}get bufferLength(){return this[v]}get encoding(){return this[K]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[N]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[J]}set async(e){this[J]=this[J]||!!e}[ts](){this[Ht]=!0,this.emit("abort",this[pt]?.reason),this.destroy(this[pt]?.reason)}get aborted(){return this[Ht]}set aborted(e){}write(e,t,i){if(this[Ht])return!1;if(this[ce])throw new Error("write after end");if(this[y])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8");let r=this[J]?_t:Ao;if(!this[N]&&!Buffer.isBuffer(e)){if(Co(e))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if(Fo(e))e=Buffer.from(e);else if(typeof e!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[N]?(this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):e.length?(typeof e=="string"&&!(t===this[K]&&!this[Ue]?.lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[K]&&(e=this[Ue].write(e)),this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):(this[v]!==0&&this.emit("readable"),i&&r(i),this[R])}read(e){if(this[y])return null;if(this[x]=!1,this[v]===0||e===0||e&&e>this[v])return this[ue](),null;this[N]&&(e=null),this[O].length>1&&!this[N]&&(this[O]=[this[K]?this[O].join(""):Buffer.concat(this[O],this[v])]);let t=this[xr](e||null,this[O][0]);return this[ue](),t}[xr](e,t){if(this[N])this[Wt]();else{let i=t;e===i.length||e===null?this[Wt]():typeof i=="string"?(this[O][0]=i.slice(e),t=i.slice(0,e),this[v]-=e):(this[O][0]=i.subarray(e),t=i.subarray(0,e),this[v]-=e)}return this.emit("data",t),!this[O].length&&!this[ce]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t="utf8"),e!==void 0&&this.write(e,t),i&&this.once("end",i),this[ce]=!0,this.writable=!1,(this[R]||!this[mt])&&this[ue](),this}[qe](){this[y]||(!this[Ne]&&!this[I].length&&(this[x]=!0),this[mt]=!1,this[R]=!0,this.emit("resume"),this[O].length?this[qt]():this[ce]?this[ue]():this.emit("drain"))}resume(){return this[qe]()}pause(){this[R]=!1,this[mt]=!0,this[x]=!1}get destroyed(){return this[y]}get flowing(){return this[R]}get paused(){return this[mt]}[Xi](e){this[N]?this[v]+=1:this[v]+=e.length,this[O].push(e)}[Wt](){return this[N]?this[v]-=1:this[v]-=this[O][0].length,this[O].shift()}[qt](e=!1){do;while(this[jr](this[Wt]())&&this[O].length);!e&&!this[O].length&&!this[ce]&&this.emit("drain")}[jr](e){return this.emit("data",e),this[R]}pipe(e,t){if(this[y])return e;this[x]=!1;let i=this[we];return t=t||{},e===kr.stdout||e===kr.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this[I].push(t.proxyErrors?new is(this,e,t):new Gt(this,e,t)),this[J]?_t(()=>this[qe]()):this[qe]()),e}unpipe(e){let t=this[I].find(i=>i.dest===e);t&&(this[I].length===1?(this[R]&&this[Ne]===0&&(this[R]=!1),this[I]=[]):this[I].splice(this[I].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let i=super.on(e,t);if(e==="data")this[x]=!1,this[Ne]++,!this[I].length&&!this[R]&&this[qe]();else if(e==="readable"&&this[v]!==0)super.emit("readable");else if(Io(e)&&this[we])super.emit(e),this.removeAllListeners(e);else if(e==="error"&&this[dt]){let r=t;this[J]?_t(()=>r.call(this,this[dt])):r.call(this,this[dt])}return i}removeListener(e,t){return this.off(e,t)}off(e,t){let i=super.off(e,t);return e==="data"&&(this[Ne]=this.listeners("data").length,this[Ne]===0&&!this[x]&&!this[I].length&&(this[R]=!1)),i}removeAllListeners(e){let t=super.removeAllListeners(e);return(e==="data"||e===void 0)&&(this[Ne]=0,!this[x]&&!this[I].length&&(this[R]=!1)),t}get emittedEnd(){return this[we]}[ue](){!this[jt]&&!this[we]&&!this[y]&&this[O].length===0&&this[ce]&&(this[jt]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ut]&&this.emit("close"),this[jt]=!1)}emit(e,...t){let i=t[0];if(e!=="error"&&e!=="close"&&e!==y&&this[y])return!1;if(e==="data")return!this[N]&&!i?!1:this[J]?(_t(()=>this[Ji](i)),!0):this[Ji](i);if(e==="end")return this[Ur]();if(e==="close"){if(this[Ut]=!0,!this[we]&&!this[y])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[dt]=i,super.emit(Qi,i);let n=!this[pt]||this.listeners("error").length?super.emit("error",i):!1;return this[ue](),n}else if(e==="resume"){let n=super.emit("resume");return this[ue](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let r=super.emit(e,...t);return this[ue](),r}[Ji](e){for(let i of this[I])i.dest.write(e)===!1&&this.pause();let t=this[x]?!1:super.emit("data",e);return this[ue](),t}[Ur](){return this[we]?!1:(this[we]=!0,this.readable=!1,this[J]?(_t(()=>this[es]()),!0):this[es]())}[es](){if(this[Ue]){let t=this[Ue].end();if(t){for(let i of this[I])i.dest.write(t);this[x]||super.emit("data",t)}}for(let t of this[I])t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){let e=Object.assign([],{dataLength:0});this[N]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[N]||(e.dataLength+=i.length)}),await t,e}async concat(){if(this[N])throw new Error("cannot concat in objectMode");let e=await this.collect();return this[K]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(y,()=>t(new Error("stream destroyed"))),this.on("error",i=>t(i)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[x]=!1;let e=!1,t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[ce])return t();let n,o,a=u=>{this.off("data",h),this.off("end",l),this.off(y,c),t(),o(u)},h=u=>{this.off("error",a),this.off("end",l),this.off(y,c),this.pause(),n({value:u,done:!!this[ce]})},l=()=>{this.off("error",a),this.off("data",h),this.off(y,c),t(),n({done:!0,value:void 0})},c=()=>a(new Error("stream destroyed"));return new Promise((u,E)=>{o=E,n=u,this.once(y,c),this.once("error",a),this.once("end",l),this.once("data",h)})},throw:t,return:t,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[x]=!1;let e=!1,t=()=>(this.pause(),this.off(Qi,t),this.off(y,t),this.off("end",t),e=!0,{done:!0,value:void 0}),i=()=>{if(e)return t();let r=this.read();return r===null?t():{done:!1,value:r}};return this.once("end",t),this.once(Qi,t),this.once(y,t),{next:i,throw:t,return:t,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(e){if(this[y])return e?this.emit("error",e):this.emit(y),this;this[y]=!0,this[x]=!0,this[O].length=0,this[v]=0;let t=this;return typeof t.close=="function"&&!this[Ut]&&t.close(),e?this.emit("error",e):this.emit(y),this}static get isStream(){return F.isStream}};F.Minipass=Zt});var Ke=d(W=>{"use strict";var Wr=W&&W.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(W,"__esModule",{value:!0});W.WriteStreamSync=W.WriteStream=W.ReadStreamSync=W.ReadStream=void 0;var ko=Wr(require("events")),z=Wr(require("fs")),xo=We(),jo=z.default.writev,Ee=Symbol("_autoClose"),$=Symbol("_close"),wt=Symbol("_ended"),p=Symbol("_fd"),rs=Symbol("_finished"),de=Symbol("_flags"),ns=Symbol("_flush"),ls=Symbol("_handleChunk"),cs=Symbol("_makeBuf"),Et=Symbol("_mode"),Yt=Symbol("_needDrain"),Ze=Symbol("_onerror"),Ye=Symbol("_onopen"),os=Symbol("_onread"),He=Symbol("_onwrite"),be=Symbol("_open"),V=Symbol("_path"),ye=Symbol("_pos"),ee=Symbol("_queue"),Ge=Symbol("_read"),as=Symbol("_readSize"),fe=Symbol("_reading"),yt=Symbol("_remain"),hs=Symbol("_size"),Kt=Symbol("_write"),Me=Symbol("_writing"),Vt=Symbol("_defaultFlag"),Le=Symbol("_errored"),$t=class extends xo.Minipass{[Le]=!1;[p];[V];[as];[fe]=!1;[hs];[yt];[Ee];constructor(e,t){if(t=t||{},super(t),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Le]=!1,this[p]=typeof t.fd=="number"?t.fd:void 0,this[V]=e,this[as]=t.readSize||16*1024*1024,this[fe]=!1,this[hs]=typeof t.size=="number"?t.size:1/0,this[yt]=this[hs],this[Ee]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[p]=="number"?this[Ge]():this[be]()}get fd(){return this[p]}get path(){return this[V]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[be](){z.default.open(this[V],"r",(e,t)=>this[Ye](e,t))}[Ye](e,t){e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Ge]())}[cs](){return Buffer.allocUnsafe(Math.min(this[as],this[yt]))}[Ge](){if(!this[fe]){this[fe]=!0;let e=this[cs]();if(e.length===0)return process.nextTick(()=>this[os](null,0,e));z.default.read(this[p],e,0,e.length,null,(t,i,r)=>this[os](t,i,r))}}[os](e,t,i){this[fe]=!1,e?this[Ze](e):this[ls](t,i)&&this[Ge]()}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}[Ze](e){this[fe]=!0,this[$](),this.emit("error",e)}[ls](e,t){let i=!1;return this[yt]-=e,e>0&&(i=super.write(ethis[Ye](e,t))}[Ye](e,t){this[Vt]&&this[de]==="r+"&&e&&e.code==="ENOENT"?(this[de]="w",this[be]()):e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Me]||this[ns]())}end(e,t){return e&&this.write(e,t),this[wt]=!0,!this[Me]&&!this[ee].length&&typeof this[p]=="number"&&this[He](null,0),this}write(e,t){return typeof e=="string"&&(e=Buffer.from(e,t)),this[wt]?(this.emit("error",new Error("write() after end()")),!1):this[p]===void 0||this[Me]||this[ee].length?(this[ee].push(e),this[Yt]=!0,!1):(this[Me]=!0,this[Kt](e),!0)}[Kt](e){z.default.write(this[p],e,0,e.length,this[ye],(t,i)=>this[He](t,i))}[He](e,t){e?this[Ze](e):(this[ye]!==void 0&&typeof t=="number"&&(this[ye]+=t),this[ee].length?this[ns]():(this[Me]=!1,this[wt]&&!this[rs]?(this[rs]=!0,this[$](),this.emit("finish")):this[Yt]&&(this[Yt]=!1,this.emit("drain"))))}[ns](){if(this[ee].length===0)this[wt]&&this[He](null,0);else if(this[ee].length===1)this[Kt](this[ee].pop());else{let e=this[ee];this[ee]=[],jo(this[p],e,this[ye],(t,i)=>this[He](t,i))}}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}};W.WriteStream=Xt;var fs=class extends Xt{[be](){let e;if(this[Vt]&&this[de]==="r+")try{e=z.default.openSync(this[V],this[de],this[Et])}catch(t){if(t?.code==="ENOENT")return this[de]="w",this[be]();throw t}else e=z.default.openSync(this[V],this[de],this[Et]);this[Ye](null,e)}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.closeSync(e),this.emit("close")}}[Kt](e){let t=!0;try{this[He](null,z.default.writeSync(this[p],e,0,e.length,this[ye])),t=!1}finally{if(t)try{this[$]()}catch{}}}};W.WriteStreamSync=fs});var Qt=d(b=>{"use strict";Object.defineProperty(b,"__esModule",{value:!0});b.dealias=b.isNoFile=b.isFile=b.isAsync=b.isSync=b.isAsyncNoFile=b.isSyncNoFile=b.isAsyncFile=b.isSyncFile=void 0;var Uo=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),qo=s=>!!s.sync&&!!s.file;b.isSyncFile=qo;var Wo=s=>!s.sync&&!!s.file;b.isAsyncFile=Wo;var Ho=s=>!!s.sync&&!s.file;b.isSyncNoFile=Ho;var Go=s=>!s.sync&&!s.file;b.isAsyncNoFile=Go;var Zo=s=>!!s.sync;b.isSync=Zo;var Yo=s=>!s.sync;b.isAsync=Yo;var Ko=s=>!!s.file;b.isFile=Ko;var Vo=s=>!s.file;b.isNoFile=Vo;var $o=s=>{let e=Uo.get(s);return e||s},Xo=(s={})=>{if(!s)return{};let e={};for(let[t,i]of Object.entries(s)){let r=$o(t);e[r]=i}return e.chmod===void 0&&e.noChmod===!1&&(e.chmod=!0),delete e.noChmod,e};b.dealias=Xo});var Ve=d(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.makeCommand=void 0;var bt=Qt(),Qo=(s,e,t,i,r)=>Object.assign((n=[],o,a)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(a=o,o=void 0),o=o?Array.from(o):[];let h=(0,bt.dealias)(n);if(r?.(h,o),(0,bt.isSyncFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return s(h,o)}else if((0,bt.isAsyncFile)(h)){let l=e(h,o);return a?l.then(()=>a(),a):l}else if((0,bt.isSyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return t(h,o)}else if((0,bt.isAsyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback only supported with file option");return i(h,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:e,syncNoFile:t,asyncNoFile:i,validate:r});Jt.makeCommand=Qo});var ds=d($e=>{"use strict";var Jo=$e&&$e.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty($e,"__esModule",{value:!0});$e.constants=void 0;var ea=Jo(require("zlib")),ta=ea.default.constants||{ZLIB_VERNUM:4736};$e.constants=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},ta))});var Ps=d(f=>{"use strict";var ia=f&&f.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),sa=f&&f.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ra=f&&f.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs,ms=Gr?.writable===!0||Gr?.set!==void 0?s=>{Ae.Buffer.concat=s?la:ha}:s=>{},Ie=Symbol("_superWrite"),Fe=class extends Error{code;errno;constructor(e,t){super("zlib: "+e.message,{cause:e}),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,t??this.constructor)}get name(){return"ZlibError"}};f.ZlibError=Fe;var ps=Symbol("flushFlag"),St=class extends oa.Minipass{#e=!1;#i=!1;#s;#n;#r;#t;#o;get sawError(){return this.#e}get handle(){return this.#t}get flushFlag(){return this.#s}constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(e),this.#s=e.flush??0,this.#n=e.finishFlush??0,this.#r=e.fullFlushFlag??0,typeof Hr[t]!="function")throw new TypeError("Compression method not supported: "+t);try{this.#t=new Hr[t](e)}catch(i){throw new Fe(i,this.constructor)}this.#o=i=>{this.#e||(this.#e=!0,this.close(),this.emit("error",i))},this.#t?.on("error",i=>this.#o(new Fe(i))),this.once("end",()=>this.close)}close(){this.#t&&(this.#t.close(),this.#t=void 0,this.emit("close"))}reset(){if(!this.#e)return(0,_s.default)(this.#t,"zlib binding closed"),this.#t.reset?.()}flush(e){this.ended||(typeof e!="number"&&(e=this.#r),this.write(Object.assign(Ae.Buffer.alloc(0),{[ps]:e})))}end(e,t,i){return typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&(t?this.write(e,t):this.write(e)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Ie](e){return super.write(e)}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=Ae.Buffer.from(e,t)),this.#e)return;(0,_s.default)(this.#t,"zlib binding closed");let r=this.#t._handle,n=r.close;r.close=()=>{};let o=this.#t.close;this.#t.close=()=>{},ms(!0);let a;try{let l=typeof e[ps]=="number"?e[ps]:this.#s;a=this.#t._processChunk(e,l),ms(!1)}catch(l){ms(!1),this.#o(new Fe(l,this.write))}finally{this.#t&&(this.#t._handle=r,r.close=n,this.#t.close=o,this.#t.removeAllListeners("error"))}this.#t&&this.#t.on("error",l=>this.#o(new Fe(l,this.write)));let h;if(a)if(Array.isArray(a)&&a.length>0){let l=a[0];h=this[Ie](Ae.Buffer.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(e,t)}finally{this.handle.flush=i}this.handle&&(this.#e=e,this.#i=t)}}}};f.Zlib=ie;var ws=class extends ie{constructor(e){super(e,"Deflate")}};f.Deflate=ws;var ys=class extends ie{constructor(e){super(e,"Inflate")}};f.Inflate=ys;var Es=class extends ie{#e;constructor(e){super(e,"Gzip"),this.#e=e&&!!e.portable}[Ie](e){return this.#e?(this.#e=!1,e[9]=255,super[Ie](e)):super[Ie](e)}};f.Gzip=Es;var bs=class extends ie{constructor(e){super(e,"Gunzip")}};f.Gunzip=bs;var Ss=class extends ie{constructor(e){super(e,"DeflateRaw")}};f.DeflateRaw=Ss;var gs=class extends ie{constructor(e){super(e,"InflateRaw")}};f.InflateRaw=gs;var Rs=class extends ie{constructor(e){super(e,"Unzip")}};f.Unzip=Rs;var ei=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||te.constants.BROTLI_OPERATION_FINISH,e.fullFlushFlag=te.constants.BROTLI_OPERATION_FLUSH,super(e,t)}},Os=class extends ei{constructor(e){super(e,"BrotliCompress")}};f.BrotliCompress=Os;var vs=class extends ei{constructor(e){super(e,"BrotliDecompress")}};f.BrotliDecompress=vs;var ti=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.ZSTD_e_continue,e.finishFlush=e.finishFlush||te.constants.ZSTD_e_end,e.fullFlushFlag=te.constants.ZSTD_e_flush,super(e,t)}},Ts=class extends ti{constructor(e){super(e,"ZstdCompress")}};f.ZstdCompress=Ts;var Ds=class extends ti{constructor(e){super(e,"ZstdDecompress")}};f.ZstdDecompress=Ds});var Kr=d(Xe=>{"use strict";Object.defineProperty(Xe,"__esModule",{value:!0});Xe.parse=Xe.encode=void 0;var ca=(s,e)=>{if(Number.isSafeInteger(s))s<0?fa(s,e):ua(s,e);else throw Error("cannot encode number outside of javascript safe integer range");return e};Xe.encode=ca;var ua=(s,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=s&255,s=Math.floor(s/256)},fa=(s,e)=>{e[0]=255;var t=!1;s=s*-1;for(var i=e.length;i>1;i--){var r=s&255;s=Math.floor(s/256),t?e[i-1]=Zr(r):r===0?e[i-1]=0:(t=!0,e[i-1]=Yr(r))}},da=s=>{let e=s[0],t=e===128?pa(s.subarray(1,s.length)):e===255?ma(s):null;if(t===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(t))throw Error("parsed number outside of javascript safe integer range");return t};Xe.parse=da;var ma=s=>{for(var e=s.length,t=0,i=!1,r=e-1;r>-1;r--){var n=Number(s[r]),o;i?o=Zr(n):n===0?o=n:(i=!0,o=Yr(n)),o!==0&&(t-=o*Math.pow(256,e-r-1))}return t},pa=s=>{for(var e=s.length,t=0,i=e-1;i>-1;i--){var r=Number(s[i]);r!==0&&(t+=r*Math.pow(256,e-i-1))}return t},Zr=s=>(255^s)&255,Yr=s=>(255^s)+1&255});var Ns=d(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.code=C.name=C.normalFsTypes=C.isName=C.isCode=void 0;var _a=s=>C.name.has(s);C.isCode=_a;var wa=s=>C.code.has(s);C.isName=wa;C.normalFsTypes=new Set(["0","","1","2","3","4","5","6","7","D"]);C.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);C.code=new Map(Array.from(C.name).map(s=>[s[1],s[0]]))});var et=d(se=>{"use strict";var ya=se&&se.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ea=se&&se.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Vr=se&&se.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs===void 0||s<0?void 0:s,As=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#e="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(e,t=0,i,r){Buffer.isBuffer(e)?this.decode(e,t||0,i,r):e&&this.#i(e)}decode(e,t,i,r){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");let n=Ce(e,t+156,1),o=Je.normalFsTypes.has(n),a=o?i:void 0,h=o?r:void 0;if(this.path=a?.path??Ce(e,t,100),this.mode=a?.mode??h?.mode??Se(e,t+100,8),this.uid=a?.uid??h?.uid??Se(e,t+108,8),this.gid=a?.gid??h?.gid??Se(e,t+116,8),this.size=ba(a?.size??h?.size??Se(e,t+124,12)),this.mtime=a?.mtime??h?.mtime??Ms(e,t+136,12),this.cksum=Se(e,t+148,12),h&&this.#i(h,!0),a&&this.#i(a),Je.isCode(n)&&(this.#e=n||"0"),this.#e==="0"&&this.path.slice(-1)==="/"&&(this.#e="5"),this.#e==="5"&&(this.size=0),this.linkpath=Ce(e,t+157,100),e.subarray(t+257,t+265).toString()==="ustar\x0000")if(this.uname=a?.uname??h?.uname??Ce(e,t+265,32),this.gname=a?.gname??h?.gname??Ce(e,t+297,32),this.devmaj=a?.devmaj??h?.devmaj??Se(e,t+329,8)??0,this.devmin=a?.devmin??h?.devmin??Se(e,t+337,8)??0,e[t+475]!==0){let c=Ce(e,t+345,155);this.path=c+"/"+this.path}else{let c=Ce(e,t+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Ms(e,t+476,12),this.ctime=i?.ctime??r?.ctime??Ms(e,t+488,12)}let l=256;for(let c=t;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&t||i==="linkpath"&&t||i==="global"))))}encode(e,t=0){if(e||(e=this.block=Buffer.alloc(512)),this.#e==="Unsupported"&&(this.#e="0"),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=Sa(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Be(e,t,100,n)||this.needPax,this.needPax=ge(e,t+100,8,this.mode)||this.needPax,this.needPax=ge(e,t+108,8,this.uid)||this.needPax,this.needPax=ge(e,t+116,8,this.gid)||this.needPax,this.needPax=ge(e,t+124,12,this.size)||this.needPax,this.needPax=Ls(e,t+136,12,this.mtime)||this.needPax,e[t+156]=Number(this.#e.codePointAt(0)),this.needPax=Be(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=Be(e,t+265,32,this.uname)||this.needPax,this.needPax=Be(e,t+297,32,this.gname)||this.needPax,this.needPax=ge(e,t+329,8,this.devmaj)||this.needPax,this.needPax=ge(e,t+337,8,this.devmin)||this.needPax,this.needPax=Be(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=Be(e,t+345,155,o)||this.needPax:(this.needPax=Be(e,t+345,130,o)||this.needPax,this.needPax=Ls(e,t+476,12,this.atime)||this.needPax,this.needPax=Ls(e,t+488,12,this.ctime)||this.needPax);let a=256;for(let h=t;h{let i=s,r="",n,o=Qe.posix.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Qe.posix.dirname(i),i=Qe.posix.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=e?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=e?n=[i.slice(0,99),r,!0]:(i=Qe.posix.join(Qe.posix.basename(r),i),r=Qe.posix.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},Ce=(s,e,t)=>s.subarray(e,e+t).toString("utf8").replace(/\0.*/,""),Ms=(s,e,t)=>ga(Se(s,e,t)),ga=s=>s===void 0?void 0:new Date(s*1e3),Se=(s,e,t)=>Number(s[e])&128?$r.parse(s.subarray(e,e+t)):Oa(s,e,t),Ra=s=>isNaN(s)?void 0:s,Oa=(s,e,t)=>Ra(parseInt(s.subarray(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),va={12:8589934591,8:2097151},ge=(s,e,t,i)=>i===void 0?!1:i>va[t]||i<0?($r.encode(i,s.subarray(e,e+t)),!0):(Ta(s,e,t,i),!1),Ta=(s,e,t,i)=>s.write(Da(i,t),e,t,"ascii"),Da=(s,e)=>Pa(Math.floor(s).toString(8),e),Pa=(s,e)=>(s.length===e-1?s:new Array(e-s.length-1).join("0")+s+" ")+"\0",Ls=(s,e,t,i)=>i===void 0?!1:ge(s,e,t,i.getTime()/1e3),Na=new Array(156).join("\0"),Be=(s,e,t,i)=>i===void 0?!1:(s.write(i+Na,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t)});var si=d(ii=>{"use strict";Object.defineProperty(ii,"__esModule",{value:!0});ii.Pax=void 0;var Ma=require("node:path"),La=et(),Is=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(e,t=!1){this.atime=e.atime,this.charset=e.charset,this.comment=e.comment,this.ctime=e.ctime,this.dev=e.dev,this.gid=e.gid,this.global=t,this.gname=e.gname,this.ino=e.ino,this.linkpath=e.linkpath,this.mtime=e.mtime,this.nlink=e.nlink,this.path=e.path,this.size=e.size,this.uid=e.uid,this.uname=e.uname}encode(){let e=this.encodeBody();if(e==="")return Buffer.allocUnsafe(0);let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new La.Header({path:("PaxHeader/"+(0,Ma.basename)(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:t,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(e,512,t,"utf8");for(let n=t+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(e,t,i=!1){return new s(Aa(Ia(e),t),i)}};ii.Pax=Is;var Aa=(s,e)=>e?Object.assign({},e,s):s,Ia=s=>s.replace(/\n$/,"").split(` +`).reduce(Fa,Object.create(null)),Fa=(s,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return s;e=e.slice((t+" ").length);let i=e.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let a=+o;a>=0&&(s[n]=a);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s}});var tt=d(ri=>{"use strict";Object.defineProperty(ri,"__esModule",{value:!0});ri.normalizeWindowsPath=void 0;var Ca=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;ri.normalizeWindowsPath=Ca!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/")});var Cs=d(oi=>{"use strict";Object.defineProperty(oi,"__esModule",{value:!0});oi.ReadEntry=void 0;var Ba=We(),ni=tt(),Fs=class extends Ba.Minipass{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(e,t,i){switch(super({}),this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.remain=e.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=e.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!e.path)throw new Error("no path provided for tar.ReadEntry");this.path=(0,ni.normalizeWindowsPath)(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=this.remain,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath?(0,ni.normalizeWindowsPath)(e.linkpath):void 0,this.uname=e.uname,this.gname=e.gname,t&&this.#e(t),i&&this.#e(i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,r-t),this.ignore?!0:i>=t?super.write(e):super.write(e.subarray(0,i))}#e(e,t=!1){e.path&&(e.path=(0,ni.normalizeWindowsPath)(e.path)),e.linkpath&&(e.linkpath=(0,ni.normalizeWindowsPath)(e.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(e).filter(([i,r])=>!(r==null||i==="path"&&t))))}};oi.ReadEntry=Fs});var hi=d(ai=>{"use strict";Object.defineProperty(ai,"__esModule",{value:!0});ai.warnMethod=void 0;var za=(s,e,t,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!s.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),s.emit("warn",e,t,i)):t instanceof Error?s.emit("error",Object.assign(t,i)):s.emit("error",Object.assign(new Error(`${e}: ${t}`),i))};ai.warnMethod=za});var _i=d(pi=>{"use strict";Object.defineProperty(pi,"__esModule",{value:!0});pi.Parser=void 0;var ka=require("events"),Bs=Ps(),Xr=et(),Qr=si(),xa=Cs(),ja=hi(),Ua=1024*1024,qs=Buffer.from([31,139]),Ws=Buffer.from([40,181,47,253]),qa=Math.max(qs.length,Ws.length),H=Symbol("state"),ze=Symbol("writeEntry"),me=Symbol("readEntry"),zs=Symbol("nextEntry"),Jr=Symbol("processEntry"),re=Symbol("extendedHeader"),gt=Symbol("globalExtendedHeader"),Re=Symbol("meta"),en=Symbol("emitMeta"),_=Symbol("buffer"),pe=Symbol("queue"),Oe=Symbol("ended"),ks=Symbol("emittedEnd"),ke=Symbol("emit"),S=Symbol("unzip"),li=Symbol("consumeChunk"),ci=Symbol("consumeChunkSub"),xs=Symbol("consumeBody"),tn=Symbol("consumeMeta"),sn=Symbol("consumeHeader"),Rt=Symbol("consuming"),js=Symbol("bufferConcat"),ui=Symbol("maybeEnd"),it=Symbol("writing"),ne=Symbol("aborted"),fi=Symbol("onDone"),xe=Symbol("sawValidEntry"),di=Symbol("sawNullBlock"),mi=Symbol("sawEOF"),rn=Symbol("closeStream"),Wa=1e3,Ot=Symbol("compressedBytesRead"),Us=Symbol("decompressedBytesRead"),nn=Symbol("checkDecompressionRatio"),Ha=()=>!0,Hs=class extends ka.EventEmitter{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[pe]=[];[_];[me];[ze];[H]="begin";[Re]="";[re];[gt];[Oe]=!1;[S];[ne]=!1;[xe];[di]=!1;[mi]=!1;[it]=!1;[Rt]=!1;[ks]=!1;[Ot]=0;[Us]=0;constructor(e={}){super(),this.file=e.file||"",this.on(fi,()=>{(this[H]==="begin"||this[xe]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(fi,e.ondone):this.on(fi,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!e.strict,this.maxDecompressionRatio=typeof e.maxDecompressionRatio=="number"?e.maxDecompressionRatio:Wa,this.maxMetaEntrySize=e.maxMetaEntrySize||Ua,this.filter=typeof e.filter=="function"?e.filter:Ha;let t=e.file&&(e.file.endsWith(".tar.br")||e.file.endsWith(".tbr"));this.brotli=!(e.gzip||e.zstd)&&e.brotli!==void 0?e.brotli:t?void 0:!1;let i=e.file&&(e.file.endsWith(".tar.zst")||e.file.endsWith(".tzst"));this.zstd=!(e.gzip||e.brotli)&&e.zstd!==void 0?e.zstd:i?!0:void 0,this.on("end",()=>this[rn]()),typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onReadEntry=="function"&&this.on("entry",e.onReadEntry)}warn(e,t,i={}){(0,ja.warnMethod)(this,e,t,i)}[sn](e,t){this[xe]===void 0&&(this[xe]=!1);let i;try{i=new Xr.Header(e,t,this[re],this[gt])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[di]?(this[mi]=!0,this[H]==="begin"&&(this[H]="header"),this[ke]("eof")):(this[di]=!0,this[ke]("nullBlock"));else if(this[di]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[ze]=new xa.ReadEntry(i,this[re],this[gt]);if(!this[xe])if(n.remain){let o=()=>{n.invalid||(this[xe]=!0)};n.on("end",o)}else this[xe]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[ke]("ignoredEntry",n),this[H]="ignore",n.resume()):n.size>0&&(this[Re]="",n.on("data",o=>this[Re]+=o),this[H]="meta"):(this[re]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[ke]("ignoredEntry",n),this[H]=n.remain?"ignore":"header",n.resume()):(n.remain?this[H]="body":(this[H]="header",n.end()),this[me]?this[pe].push(n):(this[pe].push(n),this[zs]())))}}}[rn](){queueMicrotask(()=>this.emit("close"))}[Jr](e){let t=!0;if(!e)this[me]=void 0,t=!1;else if(Array.isArray(e)){let[i,...r]=e;this.emit(i,...r)}else this[me]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",()=>this[zs]()),t=!1);return t}[zs](){do;while(this[Jr](this[pe].shift()));if(this[pe].length===0){let e=this[me];!e||e.flowing||e.size===e.remain?this[it]||this.emit("drain"):e.once("drain",()=>this.emit("drain"))}}[xs](e,t){let i=this[ze];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=e.length&&t===0?e:e.subarray(t,t+r);return i.write(n),i.blockRemain||(this[H]="header",this[ze]=void 0,i.end()),n.length}[tn](e,t){let i=this[ze],r=this[xs](e,t);return!this[ze]&&i&&this[en](i),r}[ke](e,t,i){this[pe].length===0&&!this[me]?this.emit(e,t,i):this[pe].push([e,t,i])}[en](e){switch(this[ke]("meta",this[Re]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[re]=Qr.Pax.parse(this[Re],this[re],!1);break;case"GlobalExtendedHeader":this[gt]=Qr.Pax.parse(this[Re],this[gt],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let t=this[re]??Object.create(null);this[re]=t,t.path=this[Re].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let t=this[re]||Object.create(null);this[re]=t,t.linkpath=this[Re].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+e.type)}}abort(e){this[ne]||(this[ne]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1}))}[nn](e){this[Us]+=e.length;let t=this[Us]/this[Ot];return t>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${t.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this[ne])return i?.(),!1;if((this[S]===void 0||this.brotli===void 0&&this[S]===!1)&&e){if(this[_]&&(e=Buffer.concat([this[_],e]),this[_]=void 0),e.length{this[nn](c)&&this[li](c)}),this[S].on("error",c=>{this[ne]||this.abort(c)}),this[S].on("end",()=>{this[Oe]=!0,this[li]()}),this[it]=!0,this[Ot]+=e.length;let l=!!this[S][h?"end":"write"](e);return this[it]=!1,i?.(),l}}this[it]=!0,this[S]?(this[Ot]+=e.length,this[S].write(e)):this[li](e),this[it]=!1;let n=this[pe].length>0?!1:this[me]?this[me].flowing:!0;return!n&&this[pe].length===0&&this[me]?.once("drain",()=>this.emit("drain")),i?.(),n}[js](e){e&&!this[ne]&&(this[_]=this[_]?Buffer.concat([this[_],e]):e)}[ui](){if(this[Oe]&&!this[ks]&&!this[ne]&&!this[Rt]){this[ks]=!0;let e=this[ze];if(e?.blockRemain){let t=this[_]?this[_].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[_]&&e.write(this[_]),e.end()}this[ke](fi)}}[li](e){if(this[Rt]&&e)this[js](e);else if(!e&&!this[_])this[ui]();else if(e){if(this[Rt]=!0,this[_]){this[js](e);let t=this[_];this[_]=void 0,this[ci](t)}else this[ci](e);for(;this[_]&&this[_]?.length>=512&&!this[ne]&&!this[mi];){let t=this[_];this[_]=void 0,this[ci](t)}this[Rt]=!1}(!this[_]||this[Oe])&&this[ui]()}[ci](e){let t=0,i=e.length;for(;t+512<=i&&!this[ne]&&!this[mi];)switch(this[H]){case"begin":case"header":this[sn](e,t),t+=512;break;case"ignore":case"body":t+=this[xs](e,t);break;case"meta":t+=this[tn](e,t);break;default:throw new Error("invalid state: "+this[H])}t{"use strict";Object.defineProperty(wi,"__esModule",{value:!0});wi.stripTrailingSlashes=void 0;var Ga=s=>{let e=s.length-1,t=-1;for(;e>-1&&s.charAt(e)==="/";)t=e,e--;return t===-1?s:s.slice(0,t)};wi.stripTrailingSlashes=Ga});var rt=d(B=>{"use strict";var Za=B&&B.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ya=B&&B.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Ka=B&&B.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=s.onReadEntry;s.onReadEntry=e?t=>{e(t),t.resume()}:t=>t.resume()},Ja=(s,e)=>{let t=new Map(e.map(n=>[(0,Gs.stripTrailingSlashes)(n),!0])),i=s.filter,r=(n,o="")=>{let a=o||(0,on.parse)(n).root||".",h;if(n===a)h=!1;else{let l=t.get(n);h=l!==void 0?l:r((0,on.dirname)(n),a)}return t.set(n,h),h};s.filter=i?(n,o)=>i(n,o)&&r((0,Gs.stripTrailingSlashes)(n)):n=>r((0,Gs.stripTrailingSlashes)(n))};B.filesFilter=Ja;var eh=s=>{let e=new Ei.Parser(s),t=s.file,i;try{i=st.default.openSync(t,"r");let r=st.default.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let t=new Ei.Parser(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("end",o),st.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new $a.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};B.list=(0,Xa.makeCommand)(eh,th,s=>new Ei.Parser(s),s=>new Ei.Parser(s),(s,e)=>{e?.length&&(0,B.filesFilter)(s,e),s.noResume||Qa(s)})});var an=d(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.modeFix=void 0;var ih=(s,e,t)=>(s&=4095,t&&(s=(s|384)&-19),e&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);bi.modeFix=ih});var Zs=d(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.stripAbsolutePath=void 0;var sh=require("node:path"),{isAbsolute:rh,parse:hn}=sh.win32,nh=s=>{let e="",t=hn(s);for(;rh(s)||t.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":t.root;s=s.slice(i.length),e+=i,t=hn(s)}return[e,s]};Si.stripAbsolutePath=nh});var Ks=d(nt=>{"use strict";Object.defineProperty(nt,"__esModule",{value:!0});nt.decode=nt.encode=void 0;var gi=["|","<",">","?",":"],Ys=gi.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),oh=new Map(gi.map((s,e)=>[s,Ys[e]])),ah=new Map(Ys.map((s,e)=>[s,gi[e]])),hh=s=>gi.reduce((e,t)=>e.split(t).join(oh.get(t)),s);nt.encode=hh;var lh=s=>Ys.reduce((e,t)=>e.split(t).join(ah.get(t)),s);nt.decode=lh});var nr=d(M=>{"use strict";var ch=M&&M.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),uh=M&&M.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fh=M&&M.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;re?(s=(0,oe.normalizeWindowsPath)(s).replace(/^\.(\/|$)/,""),(0,dh.stripTrailingSlashes)(e)+"/"+s):(0,oe.normalizeWindowsPath)(s),ph=16*1024*1024,cn=Symbol("process"),un=Symbol("file"),fn=Symbol("directory"),$s=Symbol("symlink"),dn=Symbol("hardlink"),vt=Symbol("header"),Ri=Symbol("read"),Xs=Symbol("lstat"),Oi=Symbol("onlstat"),Qs=Symbol("onread"),Js=Symbol("onreadlink"),er=Symbol("openfile"),tr=Symbol("onopenfile"),ve=Symbol("close"),vi=Symbol("mode"),ir=Symbol("awaitDrain"),Vs=Symbol("ondrain"),he=Symbol("prefix"),Ti=class extends pn.Minipass{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#e=!1;constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.path=(0,oe.normalizeWindowsPath)(e),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||ph,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=(0,oe.normalizeWindowsPath)(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?(0,oe.normalizeWindowsPath)(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,a]=(0,bn.stripAbsolutePath)(this.path);o&&typeof a=="string"&&(this.path=a,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=mh.decode(this.path.replaceAll(/\\/g,"/")),e=e.replaceAll(/\\/g,"/")),this.absolute=(0,oe.normalizeWindowsPath)(i.absolute||ln.default.resolve(this.cwd,e)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[Oi](n):this[Xs]()}warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}emit(e,...t){return e==="error"&&(this.#e=!0),super.emit(e,...t)}[Xs](){ae.default.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Oi](t)})}[Oi](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=_h(e),this.emit("stat",e),this[cn]()}[cn](){switch(this.type){case"File":return this[un]();case"Directory":return this[fn]();case"SymbolicLink":return this[$s]();default:return this.end()}}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}[he](e){return gn(e,this.prefix)}[vt](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this[vi](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let e=this.header?.block;if(!e)throw new Error("failed to encode header");super.write(e)}[fn](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[vt](),this.end()}[$s](){ae.default.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Js](t)})}[Js](e){this.linkpath=(0,oe.normalizeWindowsPath)(e),this[vt](),this.end()}[dn](e){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=(0,oe.normalizeWindowsPath)(ln.default.relative(this.cwd,e)),this.stat.size=0,this[vt](),this.end()}[un](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let e=`${this.stat.dev}:${this.stat.ino}`,t=this.linkCache.get(e);if(t?.indexOf(this.cwd)===0)return this[dn](t);this.linkCache.set(e,this.absolute)}if(this[vt](),this.stat.size===0)return this.end();this[er]()}[er](){ae.default.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[tr](t)})}[tr](e){if(this.fd=e,this.#e)return this[ve]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let t=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(t),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[Ri]()}[Ri](){let{fd:e,buf:t,offset:i,length:r,pos:n}=this;if(e===void 0||t===void 0)throw new Error("cannot read file without first opening");ae.default.read(e,t,i,r,n,(o,a)=>{if(o)return this[ve](()=>this.emit("error",o));this[Qs](a)})}[ve](e=()=>{}){this.fd!==void 0&&ae.default.close(this.fd,e)}[Qs](e){if(e<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(e>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(e===this.remain)for(let r=e;rthis[Vs]())}[ir](e){this.once("drain",e)}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this.blockRemaine?this.emit("error",e):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[Ri]()}};M.WriteEntry=Ti;var sr=class extends Ti{sync=!0;[Xs](){this[Oi](ae.default.lstatSync(this.absolute))}[$s](){this[Js](ae.default.readlinkSync(this.absolute))}[er](){this[tr](ae.default.openSync(this.absolute,"r"))}[Ri](){let e=!0;try{let{fd:t,buf:i,offset:r,length:n,pos:o}=this;if(t===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let a=ae.default.readSync(t,i,r,n,o);this[Qs](a),e=!1}finally{if(e)try{this[ve](()=>{})}catch{}}}[ir](e){e()}[ve](e=()=>{}){this.fd!==void 0&&ae.default.closeSync(this.fd),e()}};M.WriteEntrySync=sr;var rr=class extends pn.Minipass{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=e;let{type:r}=e;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=(0,oe.normalizeWindowsPath)(e.path),this.mode=e.mode!==void 0?this[vi](e.mode):void 0,this.uid=this.portable?void 0:e.uid,this.gid=this.portable?void 0:e.gid,this.uname=this.portable?void 0:e.uname,this.gname=this.portable?void 0:e.gname,this.size=e.size,this.mtime=this.noMtime?void 0:i.mtime||e.mtime,this.atime=this.portable?void 0:e.atime,this.ctime=this.portable?void 0:e.ctime,this.linkpath=e.linkpath!==void 0?(0,oe.normalizeWindowsPath)(e.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[a,h]=(0,bn.stripAbsolutePath)(this.path);a&&typeof h=="string"&&(this.path=h,n=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),e.pipe(this)}[he](e){return gn(e,this.prefix)}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}write(e,t,i){typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8"));let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e,i)}end(e,t,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,t??"utf8")),i&&this.once("finish",i),e?super.end(e,i):super.end(i),this}};M.WriteEntryTar=rr;var _h=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported"});var Rn=d(at=>{"use strict";Object.defineProperty(at,"__esModule",{value:!0});at.Node=at.Yallist=void 0;var or=class s{tail;head;length=0;static create(e=[]){return new s(e)}constructor(e=[]){for(let t of e)this.push(t)}*[Symbol.iterator](){for(let e=this.head;e;e=e.next)yield e.value}removeNode(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");let t=e.next,i=e.prev;return t&&(t.prev=i),i&&(i.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=i),this.length--,e.next=void 0,e.prev=void 0,e.list=void 0,t}unshiftNode(e){if(e===this.head)return;e.list&&e.list.removeNode(e);let t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}pushNode(e){if(e===this.tail)return;e.list&&e.list.removeNode(e);let t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}push(...e){for(let t=0,i=e.length;t1)i=t;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=e(i,r.value,n),r=r.next;return i}reduceReverse(e,t){let i,r=this.tail;if(arguments.length>1)i=t;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=e(i,r.value,n),r=r.prev;return i}toArray(){let e=new Array(this.length);for(let t=0,i=this.head;i;t++)e[t]=i.value,i=i.next;return e}toArrayReverse(){let e=new Array(this.length);for(let t=0,i=this.tail;i;t++)e[t]=i.value,i=i.prev;return e}slice(e=0,t=this.length){t<0&&(t+=this.length),e<0&&(e+=this.length);let i=new s;if(tthis.length&&(t=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(t=this.length);let r=this.length,n=this.tail;for(;n&&r>t;r--)n=n.prev;for(;n&&r>e;r--,n=n.prev)i.push(n.value);return i}splice(e,t=0,...i){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);let r=this.head;for(let o=0;r&&o{"use strict";var bh=L&&L.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Sh=L&&L.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),gh=L&&L.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(e.gzip&&(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new ar.Gzip(e.gzip)),e.brotli&&(typeof e.brotli!="object"&&(e.brotli={}),this.zip=new ar.BrotliCompress(e.brotli)),e.zstd&&(typeof e.zstd!="object"&&(e.zstd={}),this.zip=new ar.ZstdCompress(e.zstd)),!this.zip)throw new Error("impossible");let t=this.zip;t.on("data",i=>super.write(i)),t.on("end",()=>super.end()),t.on("drain",()=>this[cr]()),this.on("resume",()=>t.resume())}else this.on("drain",this[cr]);this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,e.mtime&&(this.mtime=e.mtime),this.filter=typeof e.filter=="function"?e.filter:()=>!0,this[X]=new Oh.Yallist,this[Q]=0,this.jobs=Number(e.jobs)||4,this[Pt]=!1,this[Tt]=!1}[Nn](e){return super.write(e)}add(e){return this.write(e),this}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&this.add(e),this[Tt]=!0,this[je](),i&&i(),this}write(e){if(this[Tt])throw new Error("write after end");return typeof e=="string"?this[Ni](e):this[vn](e),this.flowing}[vn](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let i=new Nt(e.path,t);i.entry=new fr.WriteEntryTar(e,this[lr](i)),i.entry.on("end",()=>this[hr](i)),this[Q]+=1,this[X].push(i)}this[je]()}[Ni](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e));this[X].push(new Nt(e,t)),this[je]()}[dr](e){e.pending=!0,this[Q]+=1;let t=this.follow?"stat":"lstat";Ii.default[t](e.absolute,(i,r)=>{e.pending=!1,this[Q]-=1,i?this.emit("error",i):this[Pi](e,r)})}[Pi](e,t){if(this.statCache.set(e.absolute,t),e.stat=t,!this.filter(e.path,t))e.ignore=!0;else if(t.isFile()&&t.nlink>1&&!this.linkCache.get(`${t.dev}:${t.ino}`)&&!this.sync)if(e===this[Te])this[Di](e);else{let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);r?r.push(e):this[Dt].set(i,[e]),e.pendingLink=!0,e.pending=!0}this[je]()}[mr](e){e.pending=!0,this[Q]+=1,Ii.default.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[Q]-=1,t)return this.emit("error",t);this[Mi](e,i)})}[Mi](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[je]()}[je](){if(!this[Pt]){this[Pt]=!0;for(let e=this[X].head;e&&this[Q]1){let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);if(r){this[Dt].delete(i);for(let n of r)n.pending=!1,this[Di](n)}}this[je]()}[Di](e){if(e.pending&&e.pendingLink&&e===this[Te]&&(e.pending=!1,e.pendingLink=!1),!e.pending){if(e.entry){e===this[Te]&&!e.piped&&this[Li](e);return}if(!e.stat){let t=this.statCache.get(e.absolute);t?this[Pi](e,t):this[dr](e)}if(e.stat&&!e.ignore){if(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir){let t=this.readdirCache.get(e.absolute);if(t?this[Mi](e,t):this[mr](e),!e.readdir)return}if(e.entry=this[Tn](e),!e.entry){e.ignore=!0;return}e===this[Te]&&!e.piped&&this[Li](e)}}}[lr](e){return{onwarn:(t,i,r)=>this.warn(t,i,r),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[Tn](e){this[Q]+=1;try{return new this[Ai](e.path,this[lr](e)).on("end",()=>this[hr](e)).on("error",i=>this.emit("error",i))}catch(t){this.emit("error",t)}}[cr](){this[Te]&&this[Te].entry&&this[Te].entry.resume()}[Li](e){e.piped=!0,e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)});let t=e.entry,i=this.zip;if(!t)throw new Error("cannot pipe without source");i?t.on("data",r=>{i.write(r)||t.pause()}):t.on("data",r=>{super.write(r)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(e,t,i={}){(0,vh.warnMethod)(this,e,t,i)}};L.Pack=Fi;var pr=class extends Fi{sync=!0;constructor(e){super(e),this[Ai]=fr.WriteEntrySync}pause(){}resume(){}[dr](e){let t=this.follow?"statSync":"lstatSync";this[Pi](e,Ii.default[t](e.absolute))}[mr](e){this[Mi](e,Ii.default.readdirSync(e.absolute))}[Li](e){let t=e.entry,i=this.zip;if(e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)}),!t)throw new Error("Cannot pipe without source");i?t.on("data",r=>{i.write(r)}):t.on("data",r=>{super[Nn](r)})}};L.PackSync=pr});var _r=d(ht=>{"use strict";var Th=ht&&ht.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ht,"__esModule",{value:!0});ht.create=void 0;var Mn=Ke(),Ln=Th(require("node:path")),An=rt(),Dh=Ve(),Bi=Ci(),Ph=(s,e)=>{let t=new Bi.PackSync(s),i=new Mn.WriteStreamSync(s.file,{mode:s.mode||438});t.pipe(i),In(t,e)},Nh=(s,e)=>{let t=new Bi.Pack(s),i=new Mn.WriteStream(s.file,{mode:s.mode||438});t.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),t.on("error",o)});return Fn(t,e).catch(n=>t.emit("error",n)),r},In=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,An.list)({file:Ln.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},Fn=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,An.list)({file:Ln.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(t);s.end()},Mh=(s,e)=>{let t=new Bi.PackSync(s);return In(t,e),t},Lh=(s,e)=>{let t=new Bi.Pack(s);return Fn(t,e).catch(i=>t.emit("error",i)),t};ht.create=(0,Dh.makeCommand)(Ph,Nh,Mh,Lh,(s,e)=>{if(!e?.length)throw new TypeError("no paths specified to add to archive")})});var Wn=d(lt=>{"use strict";var Ah=lt&<.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(lt,"__esModule",{value:!0});lt.getWriteFlag=void 0;var zn=Ah(require("fs")),Ih=process.env.__FAKE_PLATFORM__||process.platform,kn=Ih==="win32",{O_CREAT:xn,O_NOFOLLOW:Cn,O_TRUNC:jn,O_WRONLY:Un}=zn.default.constants,qn=Number(process.env.__FAKE_FS_O_FILENAME__)||zn.default.constants.UV_FS_O_FILEMAP||0,Fh=kn&&!!qn,Ch=512*1024,Bh=qn|jn|xn|Un,Bn=!kn&&typeof Cn=="number"?Cn|jn|xn|Un:null;lt.getWriteFlag=Bn!==null?()=>Bn:Fh?s=>s"w"});var Gn=d(le=>{"use strict";var Hn=le&&le.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(le,"__esModule",{value:!0});le.chownrSync=le.chownr=void 0;var ki=Hn(require("node:fs")),Mt=Hn(require("node:path")),wr=(s,e,t)=>{try{return ki.default.lchownSync(s,e,t)}catch(i){if(i?.code!=="ENOENT")throw i}},zi=(s,e,t,i)=>{ki.default.lchown(s,e,t,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},zh=(s,e,t,i,r)=>{if(e.isDirectory())(0,le.chownr)(Mt.default.resolve(s,e.name),t,i,n=>{if(n)return r(n);let o=Mt.default.resolve(s,e.name);zi(o,t,i,r)});else{let n=Mt.default.resolve(s,e.name);zi(n,t,i,r)}},kh=(s,e,t,i)=>{ki.default.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return zi(s,e,t,i);let o=n.length,a=null,h=l=>{if(!a){if(l)return i(a=l);if(--o===0)return zi(s,e,t,i)}};for(let l of n)zh(s,l,e,t,h)})};le.chownr=kh;var xh=(s,e,t,i)=>{e.isDirectory()&&(0,le.chownrSync)(Mt.default.resolve(s,e.name),t,i),wr(Mt.default.resolve(s,e.name),t,i)},jh=(s,e,t)=>{let i;try{i=ki.default.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return wr(s,e,t);throw n}for(let r of i)xh(s,r,e,t);return wr(s,e,t)};le.chownrSync=jh});var Zn=d(xi=>{"use strict";Object.defineProperty(xi,"__esModule",{value:!0});xi.CwdError=void 0;var yr=class extends Error{path;code;syscall="chdir";constructor(e,t){super(`${t}: Cannot cd into '${e}'`),this.path=e,this.code=t}get name(){return"CwdError"}};xi.CwdError=yr});var br=d(ji=>{"use strict";Object.defineProperty(ji,"__esModule",{value:!0});ji.SymlinkError=void 0;var Er=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(e,t){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=e,this.path=t}get name(){return"SymlinkError"}};ji.SymlinkError=Er});var Xn=d(De=>{"use strict";var gr=De&&De.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(De,"__esModule",{value:!0});De.mkdirSync=De.mkdir=void 0;var Yn=Gn(),j=gr(require("node:fs")),Uh=gr(require("node:fs/promises")),Ui=gr(require("node:path")),Kn=Zn(),_e=tt(),Vn=br(),qh=(s,e)=>{j.default.stat(s,(t,i)=>{(t||!i.isDirectory())&&(t=new Kn.CwdError(s,t?.code||"ENOTDIR")),e(t)})},Wh=(s,e,t)=>{s=(0,_e.normalizeWindowsPath)(s);let i=e.umask??18,r=e.mode|448,n=(r&i)!==0,o=e.uid,a=e.gid,h=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),l=e.preserve,c=e.unlink,u=(0,_e.normalizeWindowsPath)(e.cwd),E=(w,P)=>{w?t(w):P&&h?(0,Yn.chownr)(P,o,a,xt=>E(xt)):n?j.default.chmod(s,r,t):t()};if(s===u)return qh(s,E);if(l)return Uh.default.mkdir(s,{mode:r,recursive:!0}).then(w=>E(null,w??void 0),E);let A=(0,_e.normalizeWindowsPath)(Ui.default.relative(u,s)).split("/");Sr(u,A,r,c,u,void 0,E)};De.mkdir=Wh;var Sr=(s,e,t,i,r,n,o)=>{if(e.length===0)return o(null,n);let a=e.shift(),h=(0,_e.normalizeWindowsPath)(Ui.default.resolve(s+"/"+a));j.default.mkdir(h,t,$n(h,e,t,i,r,n,o))},$n=(s,e,t,i,r,n,o)=>a=>{a?j.default.lstat(s,(h,l)=>{if(h)h.path=h.path&&(0,_e.normalizeWindowsPath)(h.path),o(h);else if(l.isDirectory())Sr(s,e,t,i,r,n,o);else if(i)j.default.unlink(s,c=>{if(c)return o(c);j.default.mkdir(s,t,$n(s,e,t,i,r,n,o))});else{if(l.isSymbolicLink())return o(new Vn.SymlinkError(s,s+"/"+e.join("/")));o(a)}}):(n=n||s,Sr(s,e,t,i,r,n,o))},Hh=s=>{let e=!1,t;try{e=j.default.statSync(s).isDirectory()}catch(i){t=i?.code}finally{if(!e)throw new Kn.CwdError(s,t??"ENOTDIR")}},Gh=(s,e)=>{s=(0,_e.normalizeWindowsPath)(s);let t=e.umask??18,i=e.mode|448,r=(i&t)!==0,n=e.uid,o=e.gid,a=typeof n=="number"&&typeof o=="number"&&(n!==e.processUid||o!==e.processGid),h=e.preserve,l=e.unlink,c=(0,_e.normalizeWindowsPath)(e.cwd),u=w=>{w&&a&&(0,Yn.chownrSync)(w,n,o),r&&j.default.chmodSync(s,i)};if(s===c)return Hh(c),u();if(h)return u(j.default.mkdirSync(s,{mode:i,recursive:!0})??void 0);let D=(0,_e.normalizeWindowsPath)(Ui.default.relative(c,s)).split("/"),A;for(let w=D.shift(),P=c;w&&(P+="/"+w);w=D.shift()){P=(0,_e.normalizeWindowsPath)(Ui.default.resolve(P));try{j.default.mkdirSync(P,i),A=A||P}catch{let xt=j.default.lstatSync(P);if(xt.isDirectory())continue;if(l){j.default.unlinkSync(P),j.default.mkdirSync(P,i),A=A||P;continue}else if(xt.isSymbolicLink())return new Vn.SymlinkError(P,P+"/"+D.join("/"))}}return u(A)};De.mkdirSync=Gh});var Jn=d(qi=>{"use strict";Object.defineProperty(qi,"__esModule",{value:!0});qi.normalizeUnicode=void 0;var Rr=Object.create(null),Qn=1e4,ct=new Set,Zh=s=>{ct.has(s)?ct.delete(s):Rr[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),ct.add(s);let e=Rr[s],t=ct.size-Qn;if(t>Qn/10){for(let i of ct)if(ct.delete(i),delete Rr[i],--t<=0)break}return e};qi.normalizeUnicode=Zh});var to=d(Wi=>{"use strict";Object.defineProperty(Wi,"__esModule",{value:!0});Wi.PathReservations=void 0;var eo=require("node:path"),Yh=Jn(),Kh=yi(),Vh=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,$h=Vh==="win32",Xh=s=>s.split("/").slice(0,-1).reduce((t,i)=>{let r=t.at(-1);return r!==void 0&&(i=(0,eo.join)(r,i)),t.push(i||"/"),t},[]),Or=class{#e=new Map;#i=new Map;#s=new Set;reserve(e,t){e=$h?["win32 parallelization disabled"]:e.map(r=>(0,Kh.stripTrailingSlashes)((0,eo.join)((0,Yh.normalizeUnicode)(r))));let i=new Set(e.map(r=>Xh(r)).reduce((r,n)=>r.concat(n)));this.#i.set(t,{dirs:i,paths:e});for(let r of e){let n=this.#e.get(r);n?n.push(t):this.#e.set(r,[t])}for(let r of i){let n=this.#e.get(r);if(!n)this.#e.set(r,[new Set([t])]);else{let o=n.at(-1);o instanceof Set?o.add(t):n.push(new Set([t]))}}return this.#r(t)}#n(e){let t=this.#i.get(e);if(!t)throw new Error("function does not have any path reservations");return{paths:t.paths.map(i=>this.#e.get(i)),dirs:[...t.dirs].map(i=>this.#e.get(i))}}check(e){let{paths:t,dirs:i}=this.#n(e);return t.every(r=>r&&r[0]===e)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(e))}#r(e){return this.#s.has(e)||!this.check(e)?!1:(this.#s.add(e),e(()=>this.#t(e)),!0)}#t(e){if(!this.#s.has(e))return!1;let t=this.#i.get(e);if(!t)throw new Error("invalid reservation");let{paths:i,dirs:r}=t,n=new Set;for(let o of i){let a=this.#e.get(o);if(!a||a?.[0]!==e)continue;let h=a[1];if(!h){this.#e.delete(o);continue}if(a.shift(),typeof h=="function")n.add(h);else for(let l of h)n.add(l)}for(let o of r){let a=this.#e.get(o),h=a?.[0];if(!(!a||!(h instanceof Set)))if(h.size===1&&a.length===1){this.#e.delete(o);continue}else if(h.size===1){a.shift();let l=a[0];typeof l=="function"&&n.add(l)}else h.delete(e)}return this.#s.delete(e),n.forEach(o=>this.#r(o)),!0}};Wi.PathReservations=Or});var io=d(Hi=>{"use strict";Object.defineProperty(Hi,"__esModule",{value:!0});Hi.umask=void 0;var Qh=()=>process.umask();Hi.umask=Qh});var Cr=d(k=>{"use strict";var Jh=k&&k.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),el=k&&k.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fo=k&&k.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{if(!zt)return m.default.unlink(s,e);let t=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.rename(s,t,i=>{if(i)return e(i);m.default.unlink(t,e)})},cl=s=>{if(!zt)return m.default.unlinkSync(s);let e=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.renameSync(s,e),m.default.unlinkSync(e)},uo=(s,e,t)=>s!==void 0&&s===s>>>0?s:e!==void 0&&e===e>>>0?e:t,Yi=class extends sl.Parser{[Tr]=!1;[Bt]=!1;[Gi]=0;reservations=new nl.PathReservations;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(e={}){if(e.ondone=()=>{this[Tr]=!0,this[Dr]()},super(e),this.transform=e.transform,this.chmod=!!e.chmod,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=e.preserveOwner===void 0&&typeof e.uid!="number"?process.getuid?.()===0:!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof e.maxDepth=="number"?e.maxDepth:hl,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||zt,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=(0,U.normalizeWindowsPath)(g.default.resolve(e.cwd||process.cwd())),this.strip=Number(e.strip)||0,this.processUmask=this.chmod?typeof e.processUmask=="number"?e.processUmask:(0,ol.umask)():0,this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[ro](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[Dr](){this[Tr]&&this[Gi]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[vr](e,t){let i=e[t],{type:r}=e;if(!i||this.preservePaths)return!0;let[n,o]=(0,rl.stripAbsolutePath)(i),a=o.replaceAll(/\\/g,"/").split("/");if(a.includes("..")||zt&&/^[a-z]:\.\.$/i.test(a[0]??"")){if(t==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${t} contains '..'`,{entry:e,[t]:i}),!1;let h=g.default.posix.dirname(e.path),l=g.default.posix.normalize(g.default.posix.join(h,a.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${t} escapes extraction directory`,{entry:e,[t]:i}),!1}return n&&(e[t]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${t}`,{entry:e,[t]:i})),!0}[lo](e){let t=(0,U.normalizeWindowsPath)(e.path),i=t.split("/");if(this.strip){if(i.length=this.strip)e.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),e.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:e,path:t,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[vr](e,"path")||!this[vr](e,"linkpath"))return!1;if(e.absolute=g.default.isAbsolute(e.path)?(0,U.normalizeWindowsPath)(g.default.resolve(e.path)):(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,e.path)),!this.preservePaths&&typeof e.absolute=="string"&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:(0,U.normalizeWindowsPath)(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=g.default.win32.parse(String(e.absolute));e.absolute=r+so.encode(String(e.absolute).slice(r.length));let{root:n}=g.default.win32.parse(e.path);e.path=n+so.encode(e.path.slice(n.length))}return!0}[ro](e){if(!this[lo](e))return e.resume();switch(il.default.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[Pr](e);default:return this[ho](e)}}[T](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[ut](),t.resume())}[Pe](e,t,i){(0,_o.mkdir)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t},i)}[It](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[Ft](e){return uo(this.uid,e.uid,this.processUid)}[Ct](e){return uo(this.gid,e.gid,this.processGid)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=new tl.WriteStream(String(e.absolute),{flags:(0,po.getWriteFlag)(e.size),mode:i,autoClose:!1});r.on("error",h=>{r.fd&&m.default.close(r.fd,()=>{}),r.write=()=>!0,this[T](h,e),t()});let n=1,o=h=>{if(h){r.fd&&m.default.close(r.fd,()=>{}),this[T](h,e),t();return}--n===0&&r.fd!==void 0&&m.default.close(r.fd,l=>{l?this[T](l,e):this[ut](),t()})};r.on("finish",()=>{let h=String(e.absolute),l=r.fd;if(typeof l=="number"&&e.mtime&&!this.noMtime){n++;let c=e.atime||new Date,u=e.mtime;m.default.futimes(l,c,u,E=>E?m.default.utimes(h,c,u,D=>o(D&&E)):o())}if(typeof l=="number"&&this[It](e)){n++;let c=this[Ft](e),u=this[Ct](e);typeof c=="number"&&typeof u=="number"&&m.default.fchown(l,c,u,E=>E?m.default.chown(h,c,u,D=>o(D&&E)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",h=>{this[T](h,e),t()}),e.pipe(a)),a.pipe(r)}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode;this[Pe](String(e.absolute),i,r=>{if(r){this[T](r,e),t();return}let n=1,o=()=>{--n===0&&(t(),this[ut](),e.resume())};e.mtime&&!this.noMtime&&(n++,m.default.utimes(String(e.absolute),e.atime||new Date,e.mtime,o)),this[It](e)&&(n++,m.default.chown(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)),o)),o()})}[ho](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[oo](e,t){let i=(0,U.normalizeWindowsPath)(g.default.relative(this.cwd,g.default.resolve(g.default.dirname(String(e.absolute)),String(e.linkpath)))).split("/");this[At](e,this.cwd,i,()=>this[Zi](e,String(e.linkpath),"symlink",t),r=>{this[T](r,e),t()})}[ao](e,t){let i=(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,String(e.linkpath))),r=(0,U.normalizeWindowsPath)(String(e.linkpath)).split("/");this[At](e,this.cwd,r,()=>this[Zi](e,i,"link",t),n=>{this[T](n,e),t()})}[At](e,t,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let a=g.default.resolve(t,o);m.default.lstat(a,(h,l)=>{if(h)return r();if(l?.isSymbolicLink())return n(new wo.SymlinkError(a,g.default.resolve(a,i.join("/"))));this[At](e,a,i,r,n)})}[co](){this[Gi]++}[ut](){this[Gi]--,this[Dr]()}[Ar](e){this[ut](),e.resume()}[Nr](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&!zt}[Pr](e){this[co]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[no](e,i))}[no](e,t){let i=a=>{t(a)},r=()=>{this[Pe](this.cwd,this.dmode,a=>{if(a){this[T](a,e),i();return}this[Bt]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let a=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(a!==this.cwd)return this[Pe](a,this.dmode,h=>{if(h){this[T](h,e),i();return}o()})}o()},o=()=>{m.default.lstat(String(e.absolute),(a,h)=>{if(h&&(this.keep||this.newer&&h.mtime>(e.mtime??h.mtime))){this[Ar](e),i();return}if(a||this[Nr](e,h))return this[G](null,e,i);if(h.isDirectory()){if(e.type==="Directory"){let l=this.chmod&&e.mode&&(h.mode&4095)!==e.mode,c=u=>this[G](u??null,e,i);return l?m.default.chmod(String(e.absolute),Number(e.mode),c):c()}if(e.absolute!==this.cwd)return m.default.rmdir(String(e.absolute),l=>this[G](l??null,e,i))}if(e.absolute===this.cwd)return this[G](null,e,i);ll(String(e.absolute),l=>this[G](l??null,e,i))})};this[Bt]?n():r()}[G](e,t,i){if(e){this[T](e,t),i();return}switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[Mr](t,i);case"Link":return this[ao](t,i);case"SymbolicLink":return this[oo](t,i);case"Directory":case"GNUDumpDir":return this[Lr](t,i)}}[Zi](e,t,i,r){m.default[i](t,String(e.absolute),n=>{n?this[T](n,e):(this[ut](),e.resume()),r()})}};k.Unpack=Yi;var Lt=s=>{try{return[null,s()]}catch(e){return[e,null]}},Ir=class extends Yi{sync=!0;[G](e,t){return super[G](e,t,()=>{})}[Pr](e){if(!this[Bt]){let n=this[Pe](this.cwd,this.dmode);if(n)return this[T](n,e);this[Bt]=!0}if(e.absolute!==this.cwd){let n=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(n!==this.cwd){let o=this[Pe](n,this.dmode);if(o)return this[T](o,e)}}let[t,i]=Lt(()=>m.default.lstatSync(String(e.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(e.mtime??i.mtime)))return this[Ar](e);if(t||this[Nr](e,i))return this[G](null,e);if(i.isDirectory()){if(e.type==="Directory"){let o=this.chmod&&e.mode&&(i.mode&4095)!==e.mode,[a]=o?Lt(()=>{m.default.chmodSync(String(e.absolute),Number(e.mode))}):[];return this[G](a,e)}let[n]=Lt(()=>m.default.rmdirSync(String(e.absolute)));this[G](n,e)}let[r]=e.absolute===this.cwd?[]:Lt(()=>cl(String(e.absolute)));this[G](r,e)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=a=>{let h;try{m.default.closeSync(n)}catch(l){h=l}(a||h)&&this[T](a||h,e),t()},n;try{n=m.default.openSync(String(e.absolute),(0,po.getWriteFlag)(e.size),i)}catch(a){return r(a)}let o=this.transform&&this.transform(e)||e;o!==e&&(o.on("error",a=>this[T](a,e)),e.pipe(o)),o.on("data",a=>{try{m.default.writeSync(n,a,0,a.length)}catch(h){r(h)}}),o.on("end",()=>{let a=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,l=e.mtime;try{m.default.futimesSync(n,h,l)}catch(c){try{m.default.utimesSync(String(e.absolute),h,l)}catch{a=c}}}if(this[It](e)){let h=this[Ft](e),l=this[Ct](e);try{m.default.fchownSync(n,Number(h),Number(l))}catch(c){try{m.default.chownSync(String(e.absolute),Number(h),Number(l))}catch{a=a||c}}}r(a)})}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode,r=this[Pe](String(e.absolute),i);if(r){this[T](r,e),t();return}if(e.mtime&&!this.noMtime)try{m.default.utimesSync(String(e.absolute),e.atime||new Date,e.mtime)}catch{}if(this[It](e))try{m.default.chownSync(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)))}catch{}t(),e.resume()}[Pe](e,t){try{return(0,_o.mkdirSync)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t})}catch(i){return i}}[At](e,t,i,r,n){if(this.preservePaths||i.length===0)return r();let o=t;for(let a of i){o=g.default.resolve(o,a);let[h,l]=Lt(()=>m.default.lstatSync(o));if(h)return r();if(l.isSymbolicLink())return n(new wo.SymlinkError(o,g.default.resolve(t,i.join("/"))))}r()}[Zi](e,t,i,r){let n=`${i}Sync`;try{m.default[n](t,String(e.absolute)),r(),e.resume()}catch(o){return this[T](o,e)}}};k.UnpackSync=Ir});var Br=d(Z=>{"use strict";var ul=Z&&Z.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),fl=Z&&Z.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),dl=Z&&Z.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=new Ki.UnpackSync(s),t=s.file,i=Eo.default.statSync(t),r=s.maxReadSize||16*1024*1024;new yo.ReadStreamSync(t,{readSize:r,size:i.size}).pipe(e)},yl=(s,e)=>{let t=new Ki.Unpack(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("close",o),Eo.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new yo.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};Z.extract=(0,_l.makeCommand)(wl,yl,s=>new Ki.UnpackSync(s),s=>new Ki.Unpack(s),(s,e)=>{e?.length&&(0,pl.filesFilter)(s,e)})});var Vi=d(ft=>{"use strict";var bo=ft&&ft.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ft,"__esModule",{value:!0});ft.replace=void 0;var So=Ke(),q=bo(require("node:fs")),go=bo(require("node:path")),Ro=et(),Oo=rt(),El=Ve(),bl=Qt(),vo=Ci(),Sl=(s,e)=>{let t=new vo.PackSync(s),i=!0,r,n;try{try{r=q.default.openSync(s.file,"r+")}catch(h){if(h?.code==="ENOENT")r=q.default.openSync(s.file,"w+");else throw h}let o=q.default.fstatSync(r),a=Buffer.alloc(512);e:for(n=0;no.size)break;n+=l,s.mtimeCache&&h.mtime&&s.mtimeCache.set(String(h.path),h.mtime)}i=!1,gl(s,t,n,r,e)}finally{if(i)try{q.default.closeSync(r)}catch{}}},gl=(s,e,t,i,r)=>{let n=new So.WriteStreamSync(s.file,{fd:i,start:t});e.pipe(n),Ol(e,r)},Rl=(s,e)=>{e=Array.from(e);let t=new vo.Pack(s),i=(n,o,a)=>{let h=(D,A)=>{D?q.default.close(n,w=>a(D)):a(null,A)},l=0;if(o===0)return h(null,0);let c=0,u=Buffer.alloc(512),E=(D,A)=>{if(D||A===void 0)return h(D);if(c+=A,c<512&&A)return q.default.read(n,u,c,u.length-c,l+c,E);if(l===0&&u[0]===31&&u[1]===139)return h(new Error("cannot append to compressed archives"));if(c<512)return h(null,l);let w=new Ro.Header(u);if(!w.cksumValid)return h(null,l);let P=512*Math.ceil((w.size??0)/512);if(l+P+512>o||(l+=P+512,l>=o))return h(null,l);s.mtimeCache&&w.mtime&&s.mtimeCache.set(String(w.path),w.mtime),c=0,q.default.read(n,u,0,512,l,E)};q.default.read(n,u,0,512,l,E)};return new Promise((n,o)=>{t.on("error",o);let a="r+",h=(l,c)=>{if(l&&l.code==="ENOENT"&&a==="r+")return a="w+",q.default.open(s.file,a,h);if(l||!c)return o(l);q.default.fstat(c,(u,E)=>{if(u)return q.default.close(c,()=>o(u));i(c,E.size,(D,A)=>{if(D)return o(D);let w=new So.WriteStream(s.file,{fd:c,start:A});t.pipe(w),w.on("error",o),w.on("close",n),vl(t,e)})})};q.default.open(s.file,a,h)})},Ol=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,Oo.list)({file:go.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},vl=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,Oo.list)({file:go.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t);s.end()};ft.replace=(0,El.makeCommand)(Sl,Rl,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,e)=>{if(!(0,bl.isFile)(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!e?.length)throw new TypeError("no paths specified to add/replace")})});var zr=d($i=>{"use strict";Object.defineProperty($i,"__esModule",{value:!0});$i.update=void 0;var Tl=Ve(),kt=Vi();$i.update=(0,Tl.makeCommand)(kt.replace.syncFile,kt.replace.asyncFile,kt.replace.syncNoFile,kt.replace.asyncNoFile,(s,e=[])=>{kt.replace.validate?.(s,e),Dl(s)});var Dl=s=>{let e=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=e?(t,i)=>e(t,i)&&!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0)):(t,i)=>!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0))}});var To=exports&&exports.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Pl=exports&&exports.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Y=exports&&exports.__exportStar||function(s,e){for(var t in s)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&To(e,s,t)},Nl=exports&&exports.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r p - : (p) => p && p.replaceAll(/\\/g, '/'); + (p) => String(p) + : (p) => String(p).replaceAll(/\\/g, '/'); //# sourceMappingURL=normalize-windows-path.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/tar/dist/commonjs/pack.js b/deps/npm/node_modules/tar/dist/commonjs/pack.js index bf8481bfae9..5a4c37a7663 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/pack.js +++ b/deps/npm/node_modules/tar/dist/commonjs/pack.js @@ -66,13 +66,12 @@ exports.PackJob = PackJob; const minipass_1 = require("minipass"); const zlib = __importStar(require("minizlib")); const yallist_1 = require("yallist"); -const read_entry_js_1 = require("./read-entry.js"); const warn_method_js_1 = require("./warn-method.js"); const EOF = Buffer.alloc(1024); const ONSTAT = Symbol('onStat'); const ENDED = Symbol('ended'); const QUEUE = Symbol('queue'); -const PENDINGLINKS = Symbol('queue'); +const PENDINGLINKS = Symbol('pendingLinks'); const CURRENT = Symbol('current'); const PROCESS = Symbol('process'); const PROCESSING = Symbol('processing'); @@ -230,11 +229,11 @@ class Pack extends minipass_1.Minipass { if (this[ENDED]) { throw new Error('write after end'); } - if (path instanceof read_entry_js_1.ReadEntry) { - this[ADDTARENTRY](path); + if (typeof path === 'string') { + this[ADDFSENTRY](path); } else { - this[ADDFSENTRY](path); + this[ADDTARENTRY](path); } return this.flowing; } diff --git a/deps/npm/node_modules/tar/dist/commonjs/parse.js b/deps/npm/node_modules/tar/dist/commonjs/parse.js index 999873ec640..2968e861ee6 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/parse.js +++ b/deps/npm/node_modules/tar/dist/commonjs/parse.js @@ -60,6 +60,10 @@ const SAW_VALID_ENTRY = Symbol('sawValidEntry'); const SAW_NULL_BLOCK = Symbol('sawNullBlock'); const SAW_EOF = Symbol('sawEOF'); const CLOSESTREAM = Symbol('closeStream'); +const MAX_DECOMPRESSION_RATIO = 1000; +const COMPRESSEDBYTESREAD = Symbol('compressedBytesRead'); +const DECOMPRESSEDBYTESREAD = Symbol('decompressedBytesRead'); +const CHECKDECOMPRESSIONRATIO = Symbol('checkDecompressionRatio'); const noop = () => true; class Parser extends events_1.EventEmitter { file; @@ -68,6 +72,7 @@ class Parser extends events_1.EventEmitter { filter; brotli; zstd; + maxDecompressionRatio; writable = true; readable = false; [QUEUE] = []; @@ -87,6 +92,8 @@ class Parser extends events_1.EventEmitter { [WRITING] = false; [CONSUMING] = false; [EMITTEDEND] = false; + [COMPRESSEDBYTESREAD] = 0; + [DECOMPRESSEDBYTESREAD] = 0; constructor(opt = {}) { super(); this.file = opt.file || ''; @@ -109,6 +116,10 @@ class Parser extends events_1.EventEmitter { }); } this.strict = !!opt.strict; + this.maxDecompressionRatio = + typeof opt.maxDecompressionRatio === 'number' ? + opt.maxDecompressionRatio + : MAX_DECOMPRESSION_RATIO; this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize; this.filter = typeof opt.filter === 'function' ? opt.filter : noop; // Unlike gzip, brotli doesn't have any magic bytes to identify it @@ -362,11 +373,23 @@ class Parser extends events_1.EventEmitter { } } abort(error) { + if (this[ABORTED]) { + return; + } this[ABORTED] = true; this.emit('abort', error); // always throws, even in non-strict mode this.warn('TAR_ABORT', error, { recoverable: false }); } + [CHECKDECOMPRESSIONRATIO](chunk) { + this[DECOMPRESSEDBYTESREAD] += chunk.length; + const ratio = this[DECOMPRESSEDBYTESREAD] / this[COMPRESSEDBYTESREAD]; + if (ratio > this.maxDecompressionRatio) { + this.abort(new Error(`max decompression ratio exceeded: ${ratio.toFixed(2)} > ${this.maxDecompressionRatio}`)); + return false; + } + return true; + } write(chunk, encoding, cb) { if (typeof encoding === 'function') { cb = encoding; @@ -450,13 +473,22 @@ class Parser extends events_1.EventEmitter { this[UNZIP] === undefined ? new minizlib_1.Unzip({}) : isZstd ? new minizlib_1.ZstdDecompress({}) : new minizlib_1.BrotliDecompress({}); - this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)); - this[UNZIP].on('error', er => this.abort(er)); + this[UNZIP].on('data', chunk => { + if (this[CHECKDECOMPRESSIONRATIO](chunk)) { + this[CONSUMECHUNK](chunk); + } + }); + this[UNZIP].on('error', er => { + if (!this[ABORTED]) { + this.abort(er); + } + }); this[UNZIP].on('end', () => { this[ENDED] = true; this[CONSUMECHUNK](); }); this[WRITING] = true; + this[COMPRESSEDBYTESREAD] += chunk.length; const ret = !!this[UNZIP][ended ? 'end' : 'write'](chunk); this[WRITING] = false; cb?.(); @@ -465,6 +497,7 @@ class Parser extends events_1.EventEmitter { } this[WRITING] = true; if (this[UNZIP]) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); } else { @@ -495,7 +528,7 @@ class Parser extends events_1.EventEmitter { !this[CONSUMING]) { this[EMITTEDEND] = true; const entry = this[WRITEENTRY]; - if (entry && entry.blockRemain) { + if (entry?.blockRemain) { // truncated, likely a damaged file const have = this[BUFFER] ? this[BUFFER].length : 0; this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${entry.blockRemain} more bytes, only ${have} available)`, { entry }); @@ -589,8 +622,10 @@ class Parser extends events_1.EventEmitter { if (!this[ABORTED]) { if (this[UNZIP]) { /* c8 ignore start */ - if (chunk) + if (chunk) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); + } /* c8 ignore stop */ this[UNZIP].end(); } diff --git a/deps/npm/node_modules/tar/dist/commonjs/pax.js b/deps/npm/node_modules/tar/dist/commonjs/pax.js index d30c0f3efbe..fce37f63058 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/pax.js +++ b/deps/npm/node_modules/tar/dist/commonjs/pax.js @@ -147,12 +147,36 @@ const parseKVLine = (set, line) => { return set; } const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1'); - const v = kv.join('='); - set[k] = - /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? - new Date(Number(v) * 1000) - : /^[0-9]+$/.test(v) ? +v - : v; + const v = kv.join('=').replace(/\0.*/, ''); + switch (k) { + case 'path': + case 'linkpath': + case 'type': + case 'charset': + case 'comment': + case 'gname': + case 'uname': + set[k] = v; + break; + case 'ctime': + case 'atime': + case 'mtime': + set[k] = new Date(Number(v) * 1000); + break; + case 'size': + const s = +v; + if (s >= 0) + set[k] = s; + break; + case 'gid': + case 'uid': + case 'dev': + case 'ino': + case 'nlink': + case 'mode': + set[k] = +v; + break; + } return set; }; //# sourceMappingURL=pax.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/tar/dist/commonjs/types.js b/deps/npm/node_modules/tar/dist/commonjs/types.js index cb9b684e843..7cbcc17ef19 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/types.js +++ b/deps/npm/node_modules/tar/dist/commonjs/types.js @@ -1,10 +1,30 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.code = exports.name = exports.isName = exports.isCode = void 0; +exports.code = exports.name = exports.normalFsTypes = exports.isName = exports.isCode = void 0; const isCode = (c) => exports.name.has(c); exports.isCode = isCode; const isName = (c) => exports.code.has(c); exports.isName = isName; +/** + * types that are a normal file system entry, not metadata. + * + * These can be the subject of extended/globalExtended headers, long path + * names, long linkpath names, etc. + * + * Any other types are meta, and cannot be targetted by extended PAX headers. + */ +exports.normalFsTypes = new Set([ + '0', + '', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + 'D', +]); // map types from key to human-friendly name exports.name = new Map([ ['0', 'File'], diff --git a/deps/npm/node_modules/tar/dist/commonjs/unpack.js b/deps/npm/node_modules/tar/dist/commonjs/unpack.js index 3df1031d84c..0e9f861abb8 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/unpack.js +++ b/deps/npm/node_modules/tar/dist/commonjs/unpack.js @@ -185,7 +185,7 @@ class Unpack extends parse_js_1.Parser { // default true for root this.preserveOwner = opt.preserveOwner === undefined && typeof opt.uid !== 'number' ? - !!(process.getuid && process.getuid() === 0) + !!(process.getuid?.() === 0) : !!opt.preserveOwner; this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? @@ -406,7 +406,7 @@ class Unpack extends parse_js_1.Parser { } } [MKDIR](dir, mode, cb) { - (0, mkdir_js_1.mkdir)((0, normalize_windows_path_js_1.normalizeWindowsPath)(dir), { + void (0, mkdir_js_1.mkdir)((0, normalize_windows_path_js_1.normalizeWindowsPath)(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, diff --git a/deps/npm/node_modules/tar/dist/esm/header.js b/deps/npm/node_modules/tar/dist/esm/header.js index 046d0037426..068c4ea0398 100644 --- a/deps/npm/node_modules/tar/dist/esm/header.js +++ b/deps/npm/node_modules/tar/dist/esm/header.js @@ -5,6 +5,7 @@ import { posix as pathModule } from 'node:path'; import * as large from './large-numbers.js'; import * as types from './types.js'; +const notNegative = (n) => n === undefined || n < 0 ? undefined : n; export class Header { cksumValid = false; needPax = false; @@ -42,22 +43,44 @@ export class Header { if (!buf || !(buf.length >= off + 512)) { throw new Error('need 512 bytes for header'); } - this.path = ex?.path ?? decString(buf, off, 100); - this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8); - this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8); - this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8); - this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12); - this.mtime = ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12); + // Decode the typeflag (independent of any pending PAX/GNU extended header) + // up front so we can tell whether THIS block is itself an intermediary + // extension header (PAX `x`/`g`, GNU long-name `L`, GNU long-link `K`). + // Per POSIX pax, a PAX extended header describes the *next file entry*, not + // the extension headers that may sit between it and that file. Applying the + // pending PAX overrides (notably `size`) to an intervening `L`/`K`/`x`/`g` + // header desynchronizes the stream relative to other tar implementations + // and enables tar interpretation-conflict / file-smuggling attacks. + const t = decString(buf, off + 156, 1); + const isNormalFS = types.normalFsTypes.has(t); + const exForFields = isNormalFS ? ex : undefined; + const gexForFields = isNormalFS ? gex : undefined; + this.path = exForFields?.path ?? decString(buf, off, 100); + this.mode = + exForFields?.mode ?? + gexForFields?.mode ?? + decNumber(buf, off + 100, 8); + this.uid = + exForFields?.uid ?? gexForFields?.uid ?? decNumber(buf, off + 108, 8); + this.gid = + exForFields?.gid ?? gexForFields?.gid ?? decNumber(buf, off + 116, 8); + this.size = notNegative(exForFields?.size ?? + gexForFields?.size ?? + decNumber(buf, off + 124, 12)); + this.mtime = + exForFields?.mtime ?? + gexForFields?.mtime ?? + decDate(buf, off + 136, 12); this.cksum = decNumber(buf, off + 148, 12); // if we have extended or global extended headers, apply them now // See https://github.com/npm/node-tar/pull/187 - // Apply global before local, so it overrides - if (gex) - this.#slurp(gex, true); - if (ex) - this.#slurp(ex); + // Apply global before local, so it overrides. Never slurp the pending + // extended-header fields onto an intermediary extension header. + if (gexForFields) + this.#slurp(gexForFields, true); + if (exForFields) + this.#slurp(exForFields); // old tar versions marked dirs as a file with a trailing / - const t = decString(buf, off + 156, 1); if (types.isCode(t)) { this.#type = t || '0'; } @@ -75,12 +98,24 @@ export class Header { this.linkpath = decString(buf, off + 157, 100); if (buf.subarray(off + 257, off + 265).toString() === 'ustar\u000000') { /* c8 ignore start */ - this.uname = ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32); - this.gname = ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32); + this.uname = + exForFields?.uname ?? + gexForFields?.uname ?? + decString(buf, off + 265, 32); + this.gname = + exForFields?.gname ?? + gexForFields?.gname ?? + decString(buf, off + 297, 32); this.devmaj = - ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; + exForFields?.devmaj ?? + gexForFields?.devmaj ?? + decNumber(buf, off + 329, 8) ?? + 0; this.devmin = - ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; + exForFields?.devmin ?? + gexForFields?.devmin ?? + decNumber(buf, off + 337, 8) ?? + 0; /* c8 ignore stop */ if (buf[off + 475] !== 0) { // definitely a prefix, definitely >130 chars. @@ -117,6 +152,7 @@ export class Header { // null/undefined values are ignored. return !(v === null || v === undefined || + (k === 'size' && Number(v) < 0) || (k === 'path' && gex) || (k === 'linkpath' && gex) || k === 'global'); diff --git a/deps/npm/node_modules/tar/dist/esm/index.min.js b/deps/npm/node_modules/tar/dist/esm/index.min.js index 89c9806c4bd..bf4036b4115 100644 --- a/deps/npm/node_modules/tar/dist/esm/index.min.js +++ b/deps/npm/node_modules/tar/dist/esm/index.min.js @@ -1,4 +1,4 @@ -var vr=Object.defineProperty;var Mr=(s,t)=>{for(var e in t)vr(s,e,{get:t[e],enumerable:!0})};import Vr from"events";import I from"fs";import{EventEmitter as Li}from"node:events";import Ds from"node:stream";import{StringDecoder as Br}from"node:string_decoder";var Ts=typeof process=="object"&&process?process:{stdout:null,stderr:null},Pr=s=>!!s&&typeof s=="object"&&(s instanceof A||s instanceof Ds||zr(s)||Ur(s)),zr=s=>!!s&&typeof s=="object"&&s instanceof Li&&typeof s.pipe=="function"&&s.pipe!==Ds.Writable.prototype.pipe,Ur=s=>!!s&&typeof s=="object"&&s instanceof Li&&typeof s.write=="function"&&typeof s.end=="function",q=Symbol("EOF"),Q=Symbol("maybeEmitEnd"),rt=Symbol("emittedEnd"),Ne=Symbol("emittingEnd"),Qt=Symbol("emittedError"),De=Symbol("closed"),xs=Symbol("read"),Ae=Symbol("flush"),Ls=Symbol("flushChunk"),z=Symbol("encoding"),Mt=Symbol("decoder"),g=Symbol("flowing"),Jt=Symbol("paused"),Bt=Symbol("resume"),b=Symbol("buffer"),D=Symbol("pipes"),_=Symbol("bufferLength"),gi=Symbol("bufferPush"),Ie=Symbol("bufferShift"),L=Symbol("objectMode"),w=Symbol("destroyed"),bi=Symbol("error"),_i=Symbol("emitData"),Ns=Symbol("emitEnd"),Oi=Symbol("emitEnd2"),Z=Symbol("async"),Ti=Symbol("abort"),Ce=Symbol("aborted"),jt=Symbol("signal"),Rt=Symbol("dataListeners"),C=Symbol("discarded"),te=s=>Promise.resolve().then(s),Hr=s=>s(),Wr=s=>s==="end"||s==="finish"||s==="prefinish",Gr=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,Zr=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),ke=class{src;dest;opts;ondrain;constructor(t,e,i){this.src=t,this.dest=e,this.opts=i,this.ondrain=()=>t[Bt](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(t){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},xi=class extends ke{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(t,e,i){super(t,e,i),this.proxyErrors=r=>this.dest.emit("error",r),t.on("error",this.proxyErrors)}},Yr=s=>!!s.objectMode,Kr=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",A=class extends Li{[g]=!1;[Jt]=!1;[D]=[];[b]=[];[L];[z];[Z];[Mt];[q]=!1;[rt]=!1;[Ne]=!1;[De]=!1;[Qt]=null;[_]=0;[w]=!1;[jt];[Ce]=!1;[Rt]=0;[C]=!1;writable=!0;readable=!0;constructor(...t){let e=t[0]||{};if(super(),e.objectMode&&typeof e.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Yr(e)?(this[L]=!0,this[z]=null):Kr(e)?(this[z]=e.encoding,this[L]=!1):(this[L]=!1,this[z]=null),this[Z]=!!e.async,this[Mt]=this[z]?new Br(this[z]):null,e&&e.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[b]}),e&&e.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[D]});let{signal:i}=e;i&&(this[jt]=i,i.aborted?this[Ti]():i.addEventListener("abort",()=>this[Ti]()))}get bufferLength(){return this[_]}get encoding(){return this[z]}set encoding(t){throw new Error("Encoding must be set at instantiation time")}setEncoding(t){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[L]}set objectMode(t){throw new Error("objectMode must be set at instantiation time")}get async(){return this[Z]}set async(t){this[Z]=this[Z]||!!t}[Ti](){this[Ce]=!0,this.emit("abort",this[jt]?.reason),this.destroy(this[jt]?.reason)}get aborted(){return this[Ce]}set aborted(t){}write(t,e,i){if(this[Ce])return!1;if(this[q])throw new Error("write after end");if(this[w])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof e=="function"&&(i=e,e="utf8"),e||(e="utf8");let r=this[Z]?te:Hr;if(!this[L]&&!Buffer.isBuffer(t)){if(Zr(t))t=Buffer.from(t.buffer,t.byteOffset,t.byteLength);else if(Gr(t))t=Buffer.from(t);else if(typeof t!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[L]?(this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[gi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):t.length?(typeof t=="string"&&!(e===this[z]&&!this[Mt]?.lastNeed)&&(t=Buffer.from(t,e)),Buffer.isBuffer(t)&&this[z]&&(t=this[Mt].write(t)),this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[gi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):(this[_]!==0&&this.emit("readable"),i&&r(i),this[g])}read(t){if(this[w])return null;if(this[C]=!1,this[_]===0||t===0||t&&t>this[_])return this[Q](),null;this[L]&&(t=null),this[b].length>1&&!this[L]&&(this[b]=[this[z]?this[b].join(""):Buffer.concat(this[b],this[_])]);let e=this[xs](t||null,this[b][0]);return this[Q](),e}[xs](t,e){if(this[L])this[Ie]();else{let i=e;t===i.length||t===null?this[Ie]():typeof i=="string"?(this[b][0]=i.slice(t),e=i.slice(0,t),this[_]-=t):(this[b][0]=i.subarray(t),e=i.subarray(0,t),this[_]-=t)}return this.emit("data",e),!this[b].length&&!this[q]&&this.emit("drain"),e}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e="utf8"),t!==void 0&&this.write(t,e),i&&this.once("end",i),this[q]=!0,this.writable=!1,(this[g]||!this[Jt])&&this[Q](),this}[Bt](){this[w]||(!this[Rt]&&!this[D].length&&(this[C]=!0),this[Jt]=!1,this[g]=!0,this.emit("resume"),this[b].length?this[Ae]():this[q]?this[Q]():this.emit("drain"))}resume(){return this[Bt]()}pause(){this[g]=!1,this[Jt]=!0,this[C]=!1}get destroyed(){return this[w]}get flowing(){return this[g]}get paused(){return this[Jt]}[gi](t){this[L]?this[_]+=1:this[_]+=t.length,this[b].push(t)}[Ie](){return this[L]?this[_]-=1:this[_]-=this[b][0].length,this[b].shift()}[Ae](t=!1){do;while(this[Ls](this[Ie]())&&this[b].length);!t&&!this[b].length&&!this[q]&&this.emit("drain")}[Ls](t){return this.emit("data",t),this[g]}pipe(t,e){if(this[w])return t;this[C]=!1;let i=this[rt];return e=e||{},t===Ts.stdout||t===Ts.stderr?e.end=!1:e.end=e.end!==!1,e.proxyErrors=!!e.proxyErrors,i?e.end&&t.end():(this[D].push(e.proxyErrors?new xi(this,t,e):new ke(this,t,e)),this[Z]?te(()=>this[Bt]()):this[Bt]()),t}unpipe(t){let e=this[D].find(i=>i.dest===t);e&&(this[D].length===1?(this[g]&&this[Rt]===0&&(this[g]=!1),this[D]=[]):this[D].splice(this[D].indexOf(e),1),e.unpipe())}addListener(t,e){return this.on(t,e)}on(t,e){let i=super.on(t,e);if(t==="data")this[C]=!1,this[Rt]++,!this[D].length&&!this[g]&&this[Bt]();else if(t==="readable"&&this[_]!==0)super.emit("readable");else if(Wr(t)&&this[rt])super.emit(t),this.removeAllListeners(t);else if(t==="error"&&this[Qt]){let r=e;this[Z]?te(()=>r.call(this,this[Qt])):r.call(this,this[Qt])}return i}removeListener(t,e){return this.off(t,e)}off(t,e){let i=super.off(t,e);return t==="data"&&(this[Rt]=this.listeners("data").length,this[Rt]===0&&!this[C]&&!this[D].length&&(this[g]=!1)),i}removeAllListeners(t){let e=super.removeAllListeners(t);return(t==="data"||t===void 0)&&(this[Rt]=0,!this[C]&&!this[D].length&&(this[g]=!1)),e}get emittedEnd(){return this[rt]}[Q](){!this[Ne]&&!this[rt]&&!this[w]&&this[b].length===0&&this[q]&&(this[Ne]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[De]&&this.emit("close"),this[Ne]=!1)}emit(t,...e){let i=e[0];if(t!=="error"&&t!=="close"&&t!==w&&this[w])return!1;if(t==="data")return!this[L]&&!i?!1:this[Z]?(te(()=>this[_i](i)),!0):this[_i](i);if(t==="end")return this[Ns]();if(t==="close"){if(this[De]=!0,!this[rt]&&!this[w])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(t==="error"){this[Qt]=i,super.emit(bi,i);let n=!this[jt]||this.listeners("error").length?super.emit("error",i):!1;return this[Q](),n}else if(t==="resume"){let n=super.emit("resume");return this[Q](),n}else if(t==="finish"||t==="prefinish"){let n=super.emit(t);return this.removeAllListeners(t),n}let r=super.emit(t,...e);return this[Q](),r}[_i](t){for(let i of this[D])i.dest.write(t)===!1&&this.pause();let e=this[C]?!1:super.emit("data",t);return this[Q](),e}[Ns](){return this[rt]?!1:(this[rt]=!0,this.readable=!1,this[Z]?(te(()=>this[Oi]()),!0):this[Oi]())}[Oi](){if(this[Mt]){let e=this[Mt].end();if(e){for(let i of this[D])i.dest.write(e);this[C]||super.emit("data",e)}}for(let e of this[D])e.end();let t=super.emit("end");return this.removeAllListeners("end"),t}async collect(){let t=Object.assign([],{dataLength:0});this[L]||(t.dataLength=0);let e=this.promise();return this.on("data",i=>{t.push(i),this[L]||(t.dataLength+=i.length)}),await e,t}async concat(){if(this[L])throw new Error("cannot concat in objectMode");let t=await this.collect();return this[z]?t.join(""):Buffer.concat(t,t.dataLength)}async promise(){return new Promise((t,e)=>{this.on(w,()=>e(new Error("stream destroyed"))),this.on("error",i=>e(i)),this.on("end",()=>t())})}[Symbol.asyncIterator](){this[C]=!1;let t=!1,e=async()=>(this.pause(),t=!0,{value:void 0,done:!0});return{next:()=>{if(t)return e();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[q])return e();let n,o,h=d=>{this.off("data",a),this.off("end",l),this.off(w,c),e(),o(d)},a=d=>{this.off("error",h),this.off("end",l),this.off(w,c),this.pause(),n({value:d,done:!!this[q]})},l=()=>{this.off("error",h),this.off("data",a),this.off(w,c),e(),n({done:!0,value:void 0})},c=()=>h(new Error("stream destroyed"));return new Promise((d,S)=>{o=S,n=d,this.once(w,c),this.once("error",h),this.once("end",l),this.once("data",a)})},throw:e,return:e,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[C]=!1;let t=!1,e=()=>(this.pause(),this.off(bi,e),this.off(w,e),this.off("end",e),t=!0,{done:!0,value:void 0}),i=()=>{if(t)return e();let r=this.read();return r===null?e():{done:!1,value:r}};return this.once("end",e),this.once(bi,e),this.once(w,e),{next:i,throw:e,return:e,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(t){if(this[w])return t?this.emit("error",t):this.emit(w),this;this[w]=!0,this[C]=!0,this[b].length=0,this[_]=0;let e=this;return typeof e.close=="function"&&!this[De]&&e.close(),t?this.emit("error",t):this.emit(w),this}static get isStream(){return Pr}};var $r=I.writev,ot=Symbol("_autoClose"),H=Symbol("_close"),ee=Symbol("_ended"),m=Symbol("_fd"),Ni=Symbol("_finished"),j=Symbol("_flags"),Di=Symbol("_flush"),ki=Symbol("_handleChunk"),Fi=Symbol("_makeBuf"),se=Symbol("_mode"),Fe=Symbol("_needDrain"),Ut=Symbol("_onerror"),Ht=Symbol("_onopen"),Ai=Symbol("_onread"),Pt=Symbol("_onwrite"),ht=Symbol("_open"),U=Symbol("_path"),nt=Symbol("_pos"),Y=Symbol("_queue"),zt=Symbol("_read"),Ii=Symbol("_readSize"),J=Symbol("_reading"),ie=Symbol("_remain"),Ci=Symbol("_size"),ve=Symbol("_write"),gt=Symbol("_writing"),Me=Symbol("_defaultFlag"),bt=Symbol("_errored"),_t=class extends A{[bt]=!1;[m];[U];[Ii];[J]=!1;[Ci];[ie];[ot];constructor(t,e){if(e=e||{},super(e),this.readable=!0,this.writable=!1,typeof t!="string")throw new TypeError("path must be a string");this[bt]=!1,this[m]=typeof e.fd=="number"?e.fd:void 0,this[U]=t,this[Ii]=e.readSize||16*1024*1024,this[J]=!1,this[Ci]=typeof e.size=="number"?e.size:1/0,this[ie]=this[Ci],this[ot]=typeof e.autoClose=="boolean"?e.autoClose:!0,typeof this[m]=="number"?this[zt]():this[ht]()}get fd(){return this[m]}get path(){return this[U]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[ht](){I.open(this[U],"r",(t,e)=>this[Ht](t,e))}[Ht](t,e){t?this[Ut](t):(this[m]=e,this.emit("open",e),this[zt]())}[Fi](){return Buffer.allocUnsafe(Math.min(this[Ii],this[ie]))}[zt](){if(!this[J]){this[J]=!0;let t=this[Fi]();if(t.length===0)return process.nextTick(()=>this[Ai](null,0,t));I.read(this[m],t,0,t.length,null,(e,i,r)=>this[Ai](e,i,r))}}[Ai](t,e,i){this[J]=!1,t?this[Ut](t):this[ki](e,i)&&this[zt]()}[H](){if(this[ot]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}[Ut](t){this[J]=!0,this[H](),this.emit("error",t)}[ki](t,e){let i=!1;return this[ie]-=t,t>0&&(i=super.write(tthis[Ht](t,e))}[Ht](t,e){this[Me]&&this[j]==="r+"&&t&&t.code==="ENOENT"?(this[j]="w",this[ht]()):t?this[Ut](t):(this[m]=e,this.emit("open",e),this[gt]||this[Di]())}end(t,e){return t&&this.write(t,e),this[ee]=!0,!this[gt]&&!this[Y].length&&typeof this[m]=="number"&&this[Pt](null,0),this}write(t,e){return typeof t=="string"&&(t=Buffer.from(t,e)),this[ee]?(this.emit("error",new Error("write() after end()")),!1):this[m]===void 0||this[gt]||this[Y].length?(this[Y].push(t),this[Fe]=!0,!1):(this[gt]=!0,this[ve](t),!0)}[ve](t){I.write(this[m],t,0,t.length,this[nt],(e,i)=>this[Pt](e,i))}[Pt](t,e){t?this[Ut](t):(this[nt]!==void 0&&typeof e=="number"&&(this[nt]+=e),this[Y].length?this[Di]():(this[gt]=!1,this[ee]&&!this[Ni]?(this[Ni]=!0,this[H](),this.emit("finish")):this[Fe]&&(this[Fe]=!1,this.emit("drain"))))}[Di](){if(this[Y].length===0)this[ee]&&this[Pt](null,0);else if(this[Y].length===1)this[ve](this[Y].pop());else{let t=this[Y];this[Y]=[],$r(this[m],t,this[nt],(e,i)=>this[Pt](e,i))}}[H](){if(this[ot]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}},Wt=class extends tt{[ht](){let t;if(this[Me]&&this[j]==="r+")try{t=I.openSync(this[U],this[j],this[se])}catch(e){if(e?.code==="ENOENT")return this[j]="w",this[ht]();throw e}else t=I.openSync(this[U],this[j],this[se]);this[Ht](null,t)}[H](){if(this[ot]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.closeSync(t),this.emit("close")}}[ve](t){let e=!0;try{this[Pt](null,I.writeSync(this[m],t,0,t.length,this[nt])),e=!1}finally{if(e)try{this[H]()}catch{}}}};import or from"node:path";import Vt from"node:fs";import{dirname as Ln,parse as Nn}from"path";var Xr=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),As=s=>!!s.sync&&!!s.file,Is=s=>!s.sync&&!!s.file,Cs=s=>!!s.sync&&!s.file,ks=s=>!s.sync&&!s.file;var Fs=s=>!!s.file;var qr=s=>{let t=Xr.get(s);return t||s},re=(s={})=>{if(!s)return{};let t={};for(let[e,i]of Object.entries(s)){let r=qr(e);t[r]=i}return t.chmod===void 0&&t.noChmod===!1&&(t.chmod=!0),delete t.noChmod,t};var K=(s,t,e,i,r)=>Object.assign((n=[],o,h)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(h=o,o=void 0),o=o?Array.from(o):[];let a=re(n);if(r?.(a,o),As(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return s(a,o)}else if(Is(a)){let l=t(a,o);return h?l.then(()=>h(),h):l}else if(Cs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return e(a,o)}else if(ks(a)){if(typeof h=="function")throw new TypeError("callback only supported with file option");return i(a,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:t,syncNoFile:e,asyncNoFile:i,validate:r});import{EventEmitter as _n}from"events";import Pi from"assert";import{Buffer as Ot}from"buffer";import*as vs from"zlib";import Qr from"zlib";var Jr=Qr.constants||{ZLIB_VERNUM:4736},M=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},Jr));var jr=Ot.concat,Ms=Object.getOwnPropertyDescriptor(Ot,"concat"),tn=s=>s,Mi=Ms?.writable===!0||Ms?.set!==void 0?s=>{Ot.concat=s?tn:jr}:s=>{},Tt=Symbol("_superWrite"),Gt=class extends Error{code;errno;constructor(t,e){super("zlib: "+t.message,{cause:t}),this.code=t.code,this.errno=t.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+t.message,Error.captureStackTrace(this,e??this.constructor)}get name(){return"ZlibError"}},Bi=Symbol("flushFlag"),ne=class extends A{#t=!1;#i=!1;#s;#n;#r;#e;#o;get sawError(){return this.#t}get handle(){return this.#e}get flushFlag(){return this.#s}constructor(t,e){if(!t||typeof t!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(t),this.#s=t.flush??0,this.#n=t.finishFlush??0,this.#r=t.fullFlushFlag??0,typeof vs[e]!="function")throw new TypeError("Compression method not supported: "+e);try{this.#e=new vs[e](t)}catch(i){throw new Gt(i,this.constructor)}this.#o=i=>{this.#t||(this.#t=!0,this.close(),this.emit("error",i))},this.#e?.on("error",i=>this.#o(new Gt(i))),this.once("end",()=>this.close)}close(){this.#e&&(this.#e.close(),this.#e=void 0,this.emit("close"))}reset(){if(!this.#t)return Pi(this.#e,"zlib binding closed"),this.#e.reset?.()}flush(t){this.ended||(typeof t!="number"&&(t=this.#r),this.write(Object.assign(Ot.alloc(0),{[Bi]:t})))}end(t,e,i){return typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&(e?this.write(t,e):this.write(t)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Tt](t){return super.write(t)}write(t,e,i){if(typeof e=="function"&&(i=e,e="utf8"),typeof t=="string"&&(t=Ot.from(t,e)),this.#t)return;Pi(this.#e,"zlib binding closed");let r=this.#e._handle,n=r.close;r.close=()=>{};let o=this.#e.close;this.#e.close=()=>{},Mi(!0);let h;try{let l=typeof t[Bi]=="number"?t[Bi]:this.#s;h=this.#e._processChunk(t,l),Mi(!1)}catch(l){Mi(!1),this.#o(new Gt(l,this.write))}finally{this.#e&&(this.#e._handle=r,r.close=n,this.#e.close=o,this.#e.removeAllListeners("error"))}this.#e&&this.#e.on("error",l=>this.#o(new Gt(l,this.write)));let a;if(h)if(Array.isArray(h)&&h.length>0){let l=h[0];a=this[Tt](Ot.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(t,e)}finally{this.handle.flush=i}this.handle&&(this.#t=t,this.#i=e)}}}};var ze=class extends Pe{#t;constructor(t){super(t,"Gzip"),this.#t=t&&!!t.portable}[Tt](t){return this.#t?(this.#t=!1,t[9]=255,super[Tt](t)):super[Tt](t)}};var Ue=class extends Pe{constructor(t){super(t,"Unzip")}},He=class extends ne{constructor(t,e){t=t||{},t.flush=t.flush||M.BROTLI_OPERATION_PROCESS,t.finishFlush=t.finishFlush||M.BROTLI_OPERATION_FINISH,t.fullFlushFlag=M.BROTLI_OPERATION_FLUSH,super(t,e)}},We=class extends He{constructor(t){super(t,"BrotliCompress")}},Ge=class extends He{constructor(t){super(t,"BrotliDecompress")}},Ze=class extends ne{constructor(t,e){t=t||{},t.flush=t.flush||M.ZSTD_e_continue,t.finishFlush=t.finishFlush||M.ZSTD_e_end,t.fullFlushFlag=M.ZSTD_e_flush,super(t,e)}},Ye=class extends Ze{constructor(t){super(t,"ZstdCompress")}},Ke=class extends Ze{constructor(t){super(t,"ZstdDecompress")}};import{posix as Zt}from"node:path";var Bs=(s,t)=>{if(Number.isSafeInteger(s))s<0?rn(s,t):sn(s,t);else throw Error("cannot encode number outside of javascript safe integer range");return t},sn=(s,t)=>{t[0]=128;for(var e=t.length;e>1;e--)t[e-1]=s&255,s=Math.floor(s/256)},rn=(s,t)=>{t[0]=255;var e=!1;s=s*-1;for(var i=t.length;i>1;i--){var r=s&255;s=Math.floor(s/256),e?t[i-1]=zs(r):r===0?t[i-1]=0:(e=!0,t[i-1]=Us(r))}},Ps=s=>{let t=s[0],e=t===128?on(s.subarray(1,s.length)):t===255?nn(s):null;if(e===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(e))throw Error("parsed number outside of javascript safe integer range");return e},nn=s=>{for(var t=s.length,e=0,i=!1,r=t-1;r>-1;r--){var n=Number(s[r]),o;i?o=zs(n):n===0?o=n:(i=!0,o=Us(n)),o!==0&&(e-=o*Math.pow(256,t-r-1))}return e},on=s=>{for(var t=s.length,e=0,i=t-1;i>-1;i--){var r=Number(s[i]);r!==0&&(e+=r*Math.pow(256,t-i-1))}return e},zs=s=>(255^s)&255,Us=s=>(255^s)+1&255;var zi={};Mr(zi,{code:()=>Ve,isCode:()=>oe,isName:()=>an,name:()=>he});var oe=s=>he.has(s),an=s=>Ve.has(s),he=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]),Ve=new Map(Array.from(he).map(s=>[s[1],s[0]]));var k=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#t="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(t,e=0,i,r){Buffer.isBuffer(t)?this.decode(t,e||0,i,r):t&&this.#i(t)}decode(t,e,i,r){if(e||(e=0),!t||!(t.length>=e+512))throw new Error("need 512 bytes for header");this.path=i?.path??xt(t,e,100),this.mode=i?.mode??r?.mode??at(t,e+100,8),this.uid=i?.uid??r?.uid??at(t,e+108,8),this.gid=i?.gid??r?.gid??at(t,e+116,8),this.size=i?.size??r?.size??at(t,e+124,12),this.mtime=i?.mtime??r?.mtime??Ui(t,e+136,12),this.cksum=at(t,e+148,12),r&&this.#i(r,!0),i&&this.#i(i);let n=xt(t,e+156,1);if(oe(n)&&(this.#t=n||"0"),this.#t==="0"&&this.path.slice(-1)==="/"&&(this.#t="5"),this.#t==="5"&&(this.size=0),this.linkpath=xt(t,e+157,100),t.subarray(e+257,e+265).toString()==="ustar\x0000")if(this.uname=i?.uname??r?.uname??xt(t,e+265,32),this.gname=i?.gname??r?.gname??xt(t,e+297,32),this.devmaj=i?.devmaj??r?.devmaj??at(t,e+329,8)??0,this.devmin=i?.devmin??r?.devmin??at(t,e+337,8)??0,t[e+475]!==0){let h=xt(t,e+345,155);this.path=h+"/"+this.path}else{let h=xt(t,e+345,130);h&&(this.path=h+"/"+this.path),this.atime=i?.atime??r?.atime??Ui(t,e+476,12),this.ctime=i?.ctime??r?.ctime??Ui(t,e+488,12)}let o=256;for(let h=e;h!(r==null||i==="path"&&e||i==="linkpath"&&e||i==="global"))))}encode(t,e=0){if(t||(t=this.block=Buffer.alloc(512)),this.#t==="Unsupported"&&(this.#t="0"),!(t.length>=e+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=ln(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Lt(t,e,100,n)||this.needPax,this.needPax=lt(t,e+100,8,this.mode)||this.needPax,this.needPax=lt(t,e+108,8,this.uid)||this.needPax,this.needPax=lt(t,e+116,8,this.gid)||this.needPax,this.needPax=lt(t,e+124,12,this.size)||this.needPax,this.needPax=Hi(t,e+136,12,this.mtime)||this.needPax,t[e+156]=Number(this.#t.codePointAt(0)),this.needPax=Lt(t,e+157,100,this.linkpath)||this.needPax,t.write("ustar\x0000",e+257,8),this.needPax=Lt(t,e+265,32,this.uname)||this.needPax,this.needPax=Lt(t,e+297,32,this.gname)||this.needPax,this.needPax=lt(t,e+329,8,this.devmaj)||this.needPax,this.needPax=lt(t,e+337,8,this.devmin)||this.needPax,this.needPax=Lt(t,e+345,i,o)||this.needPax,t[e+475]!==0?this.needPax=Lt(t,e+345,155,o)||this.needPax:(this.needPax=Lt(t,e+345,130,o)||this.needPax,this.needPax=Hi(t,e+476,12,this.atime)||this.needPax,this.needPax=Hi(t,e+488,12,this.ctime)||this.needPax);let h=256;for(let a=e;a{let i=s,r="",n,o=Zt.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Zt.dirname(i),i=Zt.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=t?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=t?n=[i.slice(0,99),r,!0]:(i=Zt.join(Zt.basename(r),i),r=Zt.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},xt=(s,t,e)=>s.subarray(t,t+e).toString("utf8").replace(/\0.*/,""),Ui=(s,t,e)=>cn(at(s,t,e)),cn=s=>s===void 0?void 0:new Date(s*1e3),at=(s,t,e)=>Number(s[t])&128?Ps(s.subarray(t,t+e)):dn(s,t,e),fn=s=>isNaN(s)?void 0:s,dn=(s,t,e)=>fn(parseInt(s.subarray(t,t+e).toString("utf8").replace(/\0.*$/,"").trim(),8)),un={12:8589934591,8:2097151},lt=(s,t,e,i)=>i===void 0?!1:i>un[e]||i<0?(Bs(i,s.subarray(t,t+e)),!0):(mn(s,t,e,i),!1),mn=(s,t,e,i)=>s.write(pn(i,e),t,e,"ascii"),pn=(s,t)=>En(Math.floor(s).toString(8),t),En=(s,t)=>(s.length===t-1?s:new Array(t-s.length-1).join("0")+s+" ")+"\0",Hi=(s,t,e,i)=>i===void 0?!1:lt(s,t,e,i.getTime()/1e3),wn=new Array(156).join("\0"),Lt=(s,t,e,i)=>i===void 0?!1:(s.write(i+wn,t,e,"utf8"),i.length!==Buffer.byteLength(i)||i.length>e);import{basename as Sn}from"node:path";var ct=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(t,e=!1){this.atime=t.atime,this.charset=t.charset,this.comment=t.comment,this.ctime=t.ctime,this.dev=t.dev,this.gid=t.gid,this.global=e,this.gname=t.gname,this.ino=t.ino,this.linkpath=t.linkpath,this.mtime=t.mtime,this.nlink=t.nlink,this.path=t.path,this.size=t.size,this.uid=t.uid,this.uname=t.uname}encode(){let t=this.encodeBody();if(t==="")return Buffer.allocUnsafe(0);let e=Buffer.byteLength(t),i=512*Math.ceil(1+e/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new k({path:("PaxHeader/"+Sn(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:e,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(t,512,e,"utf8");for(let n=e+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(t,e,i=!1){return new s(yn(Rn(t),e),i)}},yn=(s,t)=>t?Object.assign({},t,s):s,Rn=s=>s.replace(/\n$/,"").split(` -`).reduce(gn,Object.create(null)),gn=(s,t)=>{let e=parseInt(t,10);if(e!==Buffer.byteLength(t)+1)return s;t=t.slice((e+" ").length);let i=t.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=");return s[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(Number(o)*1e3):/^[0-9]+$/.test(o)?+o:o,s};var bn=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,f=bn!=="win32"?s=>s:s=>s&&s.replaceAll(/\\/g,"/");var Yt=class extends A{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(t,e,i){switch(super({}),this.pause(),this.extended=e,this.globalExtended=i,this.header=t,this.remain=t.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=t.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!t.path)throw new Error("no path provided for tar.ReadEntry");this.path=f(t.path),this.mode=t.mode,this.mode&&(this.mode=this.mode&4095),this.uid=t.uid,this.gid=t.gid,this.uname=t.uname,this.gname=t.gname,this.size=this.remain,this.mtime=t.mtime,this.atime=t.atime,this.ctime=t.ctime,this.linkpath=t.linkpath?f(t.linkpath):void 0,this.uname=t.uname,this.gname=t.gname,e&&this.#t(e),i&&this.#t(i,!0)}write(t){let e=t.length;if(e>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-e),this.blockRemain=Math.max(0,r-e),this.ignore?!0:i>=e?super.write(t):super.write(t.subarray(0,i))}#t(t,e=!1){t.path&&(t.path=f(t.path)),t.linkpath&&(t.linkpath=f(t.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(t).filter(([i,r])=>!(r==null||i==="path"&&e))))}};var Nt=(s,t,e,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=e instanceof Error&&e.code||t,i.tarCode=t,!s.strict&&i.recoverable!==!1?(e instanceof Error&&(i=Object.assign(e,i),e=e.message),s.emit("warn",t,e,i)):e instanceof Error?s.emit("error",Object.assign(e,i)):s.emit("error",Object.assign(new Error(`${t}: ${e}`),i))};var On=1024*1024,Ki=Buffer.from([31,139]),Vi=Buffer.from([40,181,47,253]),Tn=Math.max(Ki.length,Vi.length),B=Symbol("state"),Dt=Symbol("writeEntry"),et=Symbol("readEntry"),Wi=Symbol("nextEntry"),Hs=Symbol("processEntry"),V=Symbol("extendedHeader"),ae=Symbol("globalExtendedHeader"),ft=Symbol("meta"),Ws=Symbol("emitMeta"),p=Symbol("buffer"),it=Symbol("queue"),dt=Symbol("ended"),Gi=Symbol("emittedEnd"),At=Symbol("emit"),y=Symbol("unzip"),$e=Symbol("consumeChunk"),Xe=Symbol("consumeChunkSub"),Zi=Symbol("consumeBody"),Gs=Symbol("consumeMeta"),Zs=Symbol("consumeHeader"),le=Symbol("consuming"),Yi=Symbol("bufferConcat"),qe=Symbol("maybeEnd"),Kt=Symbol("writing"),ut=Symbol("aborted"),Qe=Symbol("onDone"),It=Symbol("sawValidEntry"),Je=Symbol("sawNullBlock"),je=Symbol("sawEOF"),Ys=Symbol("closeStream"),xn=()=>!0,st=class extends _n{file;strict;maxMetaEntrySize;filter;brotli;zstd;writable=!0;readable=!1;[it]=[];[p];[et];[Dt];[B]="begin";[ft]="";[V];[ae];[dt]=!1;[y];[ut]=!1;[It];[Je]=!1;[je]=!1;[Kt]=!1;[le]=!1;[Gi]=!1;constructor(t={}){super(),this.file=t.file||"",this.on(Qe,()=>{(this[B]==="begin"||this[It]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),t.ondone?this.on(Qe,t.ondone):this.on(Qe,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!t.strict,this.maxMetaEntrySize=t.maxMetaEntrySize||On,this.filter=typeof t.filter=="function"?t.filter:xn;let e=t.file&&(t.file.endsWith(".tar.br")||t.file.endsWith(".tbr"));this.brotli=!(t.gzip||t.zstd)&&t.brotli!==void 0?t.brotli:e?void 0:!1;let i=t.file&&(t.file.endsWith(".tar.zst")||t.file.endsWith(".tzst"));this.zstd=!(t.gzip||t.brotli)&&t.zstd!==void 0?t.zstd:i?!0:void 0,this.on("end",()=>this[Ys]()),typeof t.onwarn=="function"&&this.on("warn",t.onwarn),typeof t.onReadEntry=="function"&&this.on("entry",t.onReadEntry)}warn(t,e,i={}){Nt(this,t,e,i)}[Zs](t,e){this[It]===void 0&&(this[It]=!1);let i;try{i=new k(t,e,this[V],this[ae])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[Je]?(this[je]=!0,this[B]==="begin"&&(this[B]="header"),this[At]("eof")):(this[Je]=!0,this[At]("nullBlock"));else if(this[Je]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[Dt]=new Yt(i,this[V],this[ae]);if(!this[It])if(n.remain){let o=()=>{n.invalid||(this[It]=!0)};n.on("end",o)}else this[It]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[At]("ignoredEntry",n),this[B]="ignore",n.resume()):n.size>0&&(this[ft]="",n.on("data",o=>this[ft]+=o),this[B]="meta"):(this[V]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[At]("ignoredEntry",n),this[B]=n.remain?"ignore":"header",n.resume()):(n.remain?this[B]="body":(this[B]="header",n.end()),this[et]?this[it].push(n):(this[it].push(n),this[Wi]())))}}}[Ys](){queueMicrotask(()=>this.emit("close"))}[Hs](t){let e=!0;if(!t)this[et]=void 0,e=!1;else if(Array.isArray(t)){let[i,...r]=t;this.emit(i,...r)}else this[et]=t,this.emit("entry",t),t.emittedEnd||(t.on("end",()=>this[Wi]()),e=!1);return e}[Wi](){do;while(this[Hs](this[it].shift()));if(this[it].length===0){let t=this[et];!t||t.flowing||t.size===t.remain?this[Kt]||this.emit("drain"):t.once("drain",()=>this.emit("drain"))}}[Zi](t,e){let i=this[Dt];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=t.length&&e===0?t:t.subarray(e,e+r);return i.write(n),i.blockRemain||(this[B]="header",this[Dt]=void 0,i.end()),n.length}[Gs](t,e){let i=this[Dt],r=this[Zi](t,e);return!this[Dt]&&i&&this[Ws](i),r}[At](t,e,i){this[it].length===0&&!this[et]?this.emit(t,e,i):this[it].push([t,e,i])}[Ws](t){switch(this[At]("meta",this[ft]),t.type){case"ExtendedHeader":case"OldExtendedHeader":this[V]=ct.parse(this[ft],this[V],!1);break;case"GlobalExtendedHeader":this[ae]=ct.parse(this[ft],this[ae],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let e=this[V]??Object.create(null);this[V]=e,e.path=this[ft].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let e=this[V]||Object.create(null);this[V]=e,e.linkpath=this[ft].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+t.type)}}abort(t){this[ut]=!0,this.emit("abort",t),this.warn("TAR_ABORT",t,{recoverable:!1})}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this[ut])return i?.(),!1;if((this[y]===void 0||this.brotli===void 0&&this[y]===!1)&&t){if(this[p]&&(t=Buffer.concat([this[p],t]),this[p]=void 0),t.lengththis[$e](c)),this[y].on("error",c=>this.abort(c)),this[y].on("end",()=>{this[dt]=!0,this[$e]()}),this[Kt]=!0;let l=!!this[y][a?"end":"write"](t);return this[Kt]=!1,i?.(),l}}this[Kt]=!0,this[y]?this[y].write(t):this[$e](t),this[Kt]=!1;let n=this[it].length>0?!1:this[et]?this[et].flowing:!0;return!n&&this[it].length===0&&this[et]?.once("drain",()=>this.emit("drain")),i?.(),n}[Yi](t){t&&!this[ut]&&(this[p]=this[p]?Buffer.concat([this[p],t]):t)}[qe](){if(this[dt]&&!this[Gi]&&!this[ut]&&!this[le]){this[Gi]=!0;let t=this[Dt];if(t&&t.blockRemain){let e=this[p]?this[p].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${t.blockRemain} more bytes, only ${e} available)`,{entry:t}),this[p]&&t.write(this[p]),t.end()}this[At](Qe)}}[$e](t){if(this[le]&&t)this[Yi](t);else if(!t&&!this[p])this[qe]();else if(t){if(this[le]=!0,this[p]){this[Yi](t);let e=this[p];this[p]=void 0,this[Xe](e)}else this[Xe](t);for(;this[p]&&this[p]?.length>=512&&!this[ut]&&!this[je];){let e=this[p];this[p]=void 0,this[Xe](e)}this[le]=!1}(!this[p]||this[dt])&&this[qe]()}[Xe](t){let e=0,i=t.length;for(;e+512<=i&&!this[ut]&&!this[je];)switch(this[B]){case"begin":case"header":this[Zs](t,e),e+=512;break;case"ignore":case"body":e+=this[Zi](t,e);break;case"meta":e+=this[Gs](t,e);break;default:throw new Error("invalid state: "+this[B])}e{let t=s.length-1,e=-1;for(;t>-1&&s.charAt(t)==="/";)e=t,t--;return e===-1?s:s.slice(0,e)};var Dn=s=>{let t=s.onReadEntry;s.onReadEntry=t?e=>{t(e),e.resume()}:e=>e.resume()},$i=(s,t)=>{let e=new Map(t.map(n=>[mt(n),!0])),i=s.filter,r=(n,o="")=>{let h=o||Nn(n).root||".",a;if(n===h)a=!1;else{let l=e.get(n);a=l!==void 0?l:r(Ln(n),h)}return e.set(n,a),a};s.filter=i?(n,o)=>i(n,o)&&r(mt(n)):n=>r(mt(n))},An=s=>{let t=new st(s),e=s.file,i;try{i=Vt.openSync(e,"r");let r=Vt.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let e=new st(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("end",o),Vt.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},Ct=K(An,In,s=>new st(s),s=>new st(s),(s,t)=>{t?.length&&$i(s,t),s.noResume||Dn(s)});import ui from"fs";import $ from"fs";import Xs from"path";var Xi=(s,t,e)=>(s&=4095,e&&(s=(s|384)&-19),t&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);import{win32 as Cn}from"node:path";var{isAbsolute:kn,parse:Ks}=Cn,ce=s=>{let t="",e=Ks(s);for(;kn(s)||e.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":e.root;s=s.slice(i.length),t+=i,e=Ks(s)}return[t,s]};var ti=["|","<",">","?",":"],qi=ti.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),Fn=new Map(ti.map((s,t)=>[s,qi[t]])),vn=new Map(qi.map((s,t)=>[s,ti[t]])),Qi=s=>ti.reduce((t,e)=>t.split(e).join(Fn.get(e)),s),Vs=s=>qi.reduce((t,e)=>t.split(e).join(vn.get(e)),s);var tr=(s,t)=>t?(s=f(s).replace(/^\.(\/|$)/,""),mt(t)+"/"+s):f(s),Mn=16*1024*1024,qs=Symbol("process"),Qs=Symbol("file"),Js=Symbol("directory"),ji=Symbol("symlink"),js=Symbol("hardlink"),fe=Symbol("header"),ei=Symbol("read"),ts=Symbol("lstat"),ii=Symbol("onlstat"),es=Symbol("onread"),is=Symbol("onreadlink"),ss=Symbol("openfile"),rs=Symbol("onopenfile"),pt=Symbol("close"),si=Symbol("mode"),ns=Symbol("awaitDrain"),Ji=Symbol("ondrain"),X=Symbol("prefix"),de=class extends A{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#t=!1;constructor(t,e={}){let i=re(e);super(),this.path=f(t),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||Mn,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=f(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?f(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,h]=ce(this.path);o&&typeof h=="string"&&(this.path=h,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=Vs(this.path.replaceAll(/\\/g,"/")),t=t.replaceAll(/\\/g,"/")),this.absolute=f(i.absolute||Xs.resolve(this.cwd,t)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[ii](n):this[ts]()}warn(t,e,i={}){return Nt(this,t,e,i)}emit(t,...e){return t==="error"&&(this.#t=!0),super.emit(t,...e)}[ts](){$.lstat(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[ii](e)})}[ii](t){this.statCache.set(this.absolute,t),this.stat=t,t.isFile()||(t.size=0),this.type=Bn(t),this.emit("stat",t),this[qs]()}[qs](){switch(this.type){case"File":return this[Qs]();case"Directory":return this[Js]();case"SymbolicLink":return this[ji]();default:return this.end()}}[si](t){return Xi(t,this.type==="Directory",this.portable)}[X](t){return tr(t,this.prefix)}[fe](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new k({path:this[X](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[X](this.linkpath):this.linkpath,mode:this[si](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new ct({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[X](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[X](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let t=this.header?.block;if(!t)throw new Error("failed to encode header");super.write(t)}[Js](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[fe](),this.end()}[ji](){$.readlink(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[is](e)})}[is](t){this.linkpath=f(t),this[fe](),this.end()}[js](t){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=f(Xs.relative(this.cwd,t)),this.stat.size=0,this[fe](),this.end()}[Qs](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let t=`${this.stat.dev}:${this.stat.ino}`,e=this.linkCache.get(t);if(e?.indexOf(this.cwd)===0)return this[js](e);this.linkCache.set(t,this.absolute)}if(this[fe](),this.stat.size===0)return this.end();this[ss]()}[ss](){$.open(this.absolute,"r",(t,e)=>{if(t)return this.emit("error",t);this[rs](e)})}[rs](t){if(this.fd=t,this.#t)return this[pt]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let e=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(e),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[ei]()}[ei](){let{fd:t,buf:e,offset:i,length:r,pos:n}=this;if(t===void 0||e===void 0)throw new Error("cannot read file without first opening");$.read(t,e,i,r,n,(o,h)=>{if(o)return this[pt](()=>this.emit("error",o));this[es](h)})}[pt](t=()=>{}){this.fd!==void 0&&$.close(this.fd,t)}[es](t){if(t<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(t>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(t===this.remain)for(let r=t;rthis[Ji]())}[ns](t){this.once("drain",t)}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this.blockRemaint?this.emit("error",t):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[ei]()}},ri=class extends de{sync=!0;[ts](){this[ii]($.lstatSync(this.absolute))}[ji](){this[is]($.readlinkSync(this.absolute))}[ss](){this[rs]($.openSync(this.absolute,"r"))}[ei](){let t=!0;try{let{fd:e,buf:i,offset:r,length:n,pos:o}=this;if(e===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let h=$.readSync(e,i,r,n,o);this[es](h),t=!1}finally{if(t)try{this[pt](()=>{})}catch{}}}[ns](t){t()}[pt](t=()=>{}){this.fd!==void 0&&$.closeSync(this.fd),t()}},ni=class extends A{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(t,e,i={}){return Nt(this,t,e,i)}constructor(t,e={}){let i=re(e);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=t;let{type:r}=t;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=f(t.path),this.mode=t.mode!==void 0?this[si](t.mode):void 0,this.uid=this.portable?void 0:t.uid,this.gid=this.portable?void 0:t.gid,this.uname=this.portable?void 0:t.uname,this.gname=this.portable?void 0:t.gname,this.size=t.size,this.mtime=this.noMtime?void 0:i.mtime||t.mtime,this.atime=this.portable?void 0:t.atime,this.ctime=this.portable?void 0:t.ctime,this.linkpath=t.linkpath!==void 0?f(t.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[h,a]=ce(this.path);h&&typeof a=="string"&&(this.path=a,n=h)}this.remain=t.size,this.blockRemain=t.startBlockSize,this.onWriteEntry?.(this),this.header=new k({path:this[X](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[X](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new ct({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[X](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[X](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),t.pipe(this)}[X](t){return tr(t,this.prefix)}[si](t){return Xi(t,this.type==="Directory",this.portable)}write(t,e,i){typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8"));let r=t.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(t,i)}end(t,e,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,e??"utf8")),i&&this.once("finish",i),t?super.end(t,i):super.end(i),this}},Bn=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported";var oi=class s{tail;head;length=0;static create(t=[]){return new s(t)}constructor(t=[]){for(let e of t)this.push(e)}*[Symbol.iterator](){for(let t=this.head;t;t=t.next)yield t.value}removeNode(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");let e=t.next,i=t.prev;return e&&(e.prev=i),i&&(i.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=i),this.length--,t.next=void 0,t.prev=void 0,t.list=void 0,e}unshiftNode(t){if(t===this.head)return;t.list&&t.list.removeNode(t);let e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}pushNode(t){if(t===this.tail)return;t.list&&t.list.removeNode(t);let e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}push(...t){for(let e=0,i=t.length;e1)i=e;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=t(i,r.value,n),r=r.next;return i}reduceReverse(t,e){let i,r=this.tail;if(arguments.length>1)i=e;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=t(i,r.value,n),r=r.prev;return i}toArray(){let t=new Array(this.length);for(let e=0,i=this.head;i;e++)t[e]=i.value,i=i.next;return t}toArrayReverse(){let t=new Array(this.length);for(let e=0,i=this.tail;i;e++)t[e]=i.value,i=i.prev;return t}slice(t=0,e=this.length){e<0&&(e+=this.length),t<0&&(t+=this.length);let i=new s;if(ethis.length&&(e=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(e=this.length);let r=this.length,n=this.tail;for(;n&&r>e;r--)n=n.prev;for(;n&&r>t;r--,n=n.prev)i.push(n.value);return i}splice(t,e=0,...i){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);let r=this.head;for(let o=0;r&&o1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(t.gzip&&(typeof t.gzip!="object"&&(t.gzip={}),this.portable&&(t.gzip.portable=!0),this.zip=new ze(t.gzip)),t.brotli&&(typeof t.brotli!="object"&&(t.brotli={}),this.zip=new We(t.brotli)),t.zstd&&(typeof t.zstd!="object"&&(t.zstd={}),this.zip=new Ye(t.zstd)),!this.zip)throw new Error("impossible");let e=this.zip;e.on("data",i=>super.write(i)),e.on("end",()=>super.end()),e.on("drain",()=>this[as]()),this.on("resume",()=>e.resume())}else this.on("drain",this[as]);this.noDirRecurse=!!t.noDirRecurse,this.follow=!!t.follow,this.noMtime=!!t.noMtime,t.mtime&&(this.mtime=t.mtime),this.filter=typeof t.filter=="function"?t.filter:()=>!0,this[W]=new oi,this[G]=0,this.jobs=Number(t.jobs)||4,this[Ee]=!1,this[me]=!1}[nr](t){return super.write(t)}add(t){return this.write(t),this}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&this.add(t),this[me]=!0,this[kt](),i&&i(),this}write(t){if(this[me])throw new Error("write after end");return t instanceof Yt?this[ir](t):this[li](t),this.flowing}[ir](t){let e=f(rr.resolve(this.cwd,t.path));if(!this.filter(t.path,t))t.resume();else{let i=new mi(t.path,e);i.entry=new ni(t,this[hs](i)),i.entry.on("end",()=>this[os](i)),this[G]+=1,this[W].push(i)}this[kt]()}[li](t){let e=f(rr.resolve(this.cwd,t));this[W].push(new mi(t,e)),this[kt]()}[ls](t){t.pending=!0,this[G]+=1;let e=this.follow?"stat":"lstat";ui[e](t.absolute,(i,r)=>{t.pending=!1,this[G]-=1,i?this.emit("error",i):this[ai](t,r)})}[ai](t,e){if(this.statCache.set(t.absolute,e),t.stat=e,!this.filter(t.path,e))t.ignore=!0;else if(e.isFile()&&e.nlink>1&&!this.linkCache.get(`${e.dev}:${e.ino}`)&&!this.sync)if(t===this[Et])this[hi](t);else{let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);r?r.push(t):this[pe].set(i,[t]),t.pendingLink=!0,t.pending=!0}this[kt]()}[cs](t){t.pending=!0,this[G]+=1,ui.readdir(t.absolute,(e,i)=>{if(t.pending=!1,this[G]-=1,e)return this.emit("error",e);this[ci](t,i)})}[ci](t,e){this.readdirCache.set(t.absolute,e),t.readdir=e,this[kt]()}[kt](){if(!this[Ee]){this[Ee]=!0;for(let t=this[W].head;t&&this[G]1){let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);if(r){this[pe].delete(i);for(let n of r)n.pending=!1,this[hi](n)}}this[kt]()}[hi](t){if(t.pending&&t.pendingLink&&t===this[Et]&&(t.pending=!1,t.pendingLink=!1),!t.pending){if(t.entry){t===this[Et]&&!t.piped&&this[fi](t);return}if(!t.stat){let e=this.statCache.get(t.absolute);e?this[ai](t,e):this[ls](t)}if(t.stat&&!t.ignore){if(!this.noDirRecurse&&t.stat.isDirectory()&&!t.readdir){let e=this.readdirCache.get(t.absolute);if(e?this[ci](t,e):this[cs](t),!t.readdir)return}if(t.entry=this[sr](t),!t.entry){t.ignore=!0;return}t===this[Et]&&!t.piped&&this[fi](t)}}}[hs](t){return{onwarn:(e,i,r)=>this.warn(e,i,r),noPax:this.noPax,cwd:this.cwd,absolute:t.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[sr](t){this[G]+=1;try{return new this[di](t.path,this[hs](t)).on("end",()=>this[os](t)).on("error",i=>this.emit("error",i))}catch(e){this.emit("error",e)}}[as](){this[Et]&&this[Et].entry&&this[Et].entry.resume()}[fi](t){t.piped=!0,t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[li](o+r)});let e=t.entry,i=this.zip;if(!e)throw new Error("cannot pipe without source");i?e.on("data",r=>{i.write(r)||e.pause()}):e.on("data",r=>{super.write(r)||e.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(t,e,i={}){Nt(this,t,e,i)}},Ft=class extends wt{sync=!0;constructor(t){super(t),this[di]=ri}pause(){}resume(){}[ls](t){let e=this.follow?"statSync":"lstatSync";this[ai](t,ui[e](t.absolute))}[cs](t){this[ci](t,ui.readdirSync(t.absolute))}[fi](t){let e=t.entry,i=this.zip;if(t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[li](o+r)}),!e)throw new Error("Cannot pipe without source");i?e.on("data",r=>{i.write(r)}):e.on("data",r=>{super[nr](r)})}};var Hn=(s,t)=>{let e=new Ft(s),i=new Wt(s.file,{mode:s.mode||438});e.pipe(i),hr(e,t)},Wn=(s,t)=>{let e=new wt(s),i=new tt(s.file,{mode:s.mode||438});e.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),e.on("error",o)});return ar(e,t).catch(n=>e.emit("error",n)),r},hr=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:or.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},ar=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:or.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(e);s.end()},Gn=(s,t)=>{let e=new Ft(s);return hr(e,t),e},Zn=(s,t)=>{let e=new wt(s);return ar(e,t).catch(i=>e.emit("error",i)),e},Yn=K(Hn,Wn,Gn,Zn,(s,t)=>{if(!t?.length)throw new TypeError("no paths specified to add to archive")});import kr from"node:fs";import ro from"node:assert";import{randomBytes as Cr}from"node:crypto";import u from"node:fs";import R from"node:path";import fr from"fs";var Kn=process.env.__FAKE_PLATFORM__||process.platform,dr=Kn==="win32",{O_CREAT:ur,O_NOFOLLOW:lr,O_TRUNC:mr,O_WRONLY:pr}=fr.constants,Er=Number(process.env.__FAKE_FS_O_FILENAME__)||fr.constants.UV_FS_O_FILEMAP||0,Vn=dr&&!!Er,$n=512*1024,Xn=Er|mr|ur|pr,cr=!dr&&typeof lr=="number"?lr|mr|ur|pr:null,fs=cr!==null?()=>cr:Vn?s=>s<$n?Xn:"w":()=>"w";import Ei from"node:fs";import we from"node:path";var ds=(s,t,e)=>{try{return Ei.lchownSync(s,t,e)}catch(i){if(i?.code!=="ENOENT")throw i}},pi=(s,t,e,i)=>{Ei.lchown(s,t,e,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},qn=(s,t,e,i,r)=>{if(t.isDirectory())us(we.resolve(s,t.name),e,i,n=>{if(n)return r(n);let o=we.resolve(s,t.name);pi(o,e,i,r)});else{let n=we.resolve(s,t.name);pi(n,e,i,r)}},us=(s,t,e,i)=>{Ei.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return pi(s,t,e,i);let o=n.length,h=null,a=l=>{if(!h){if(l)return i(h=l);if(--o===0)return pi(s,t,e,i)}};for(let l of n)qn(s,l,t,e,a)})},Qn=(s,t,e,i)=>{t.isDirectory()&&ms(we.resolve(s,t.name),e,i),ds(we.resolve(s,t.name),e,i)},ms=(s,t,e)=>{let i;try{i=Ei.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return ds(s,t,e);throw n}for(let r of i)Qn(s,r,t,e);return ds(s,t,e)};import F from"node:fs";import Jn from"node:fs/promises";import wi from"node:path";var Se=class extends Error{path;code;syscall="chdir";constructor(t,e){super(`${e}: Cannot cd into '${t}'`),this.path=t,this.code=e}get name(){return"CwdError"}};var St=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(t,e){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=t,this.path=e}get name(){return"SymlinkError"}};var jn=(s,t)=>{F.stat(s,(e,i)=>{(e||!i.isDirectory())&&(e=new Se(s,e?.code||"ENOTDIR")),t(e)})},wr=(s,t,e)=>{s=f(s);let i=t.umask??18,r=t.mode|448,n=(r&i)!==0,o=t.uid,h=t.gid,a=typeof o=="number"&&typeof h=="number"&&(o!==t.processUid||h!==t.processGid),l=t.preserve,c=t.unlink,d=f(t.cwd),S=(E,x)=>{E?e(E):x&&a?us(x,o,h,Le=>S(Le)):n?F.chmod(s,r,e):e()};if(s===d)return jn(s,S);if(l)return Jn.mkdir(s,{mode:r,recursive:!0}).then(E=>S(null,E??void 0),S);let N=f(wi.relative(d,s)).split("/");ps(d,N,r,c,d,void 0,S)},ps=(s,t,e,i,r,n,o)=>{if(t.length===0)return o(null,n);let h=t.shift(),a=f(wi.resolve(s+"/"+h));F.mkdir(a,e,Sr(a,t,e,i,r,n,o))},Sr=(s,t,e,i,r,n,o)=>h=>{h?F.lstat(s,(a,l)=>{if(a)a.path=a.path&&f(a.path),o(a);else if(l.isDirectory())ps(s,t,e,i,r,n,o);else if(i)F.unlink(s,c=>{if(c)return o(c);F.mkdir(s,e,Sr(s,t,e,i,r,n,o))});else{if(l.isSymbolicLink())return o(new St(s,s+"/"+t.join("/")));o(h)}}):(n=n||s,ps(s,t,e,i,r,n,o))},to=s=>{let t=!1,e;try{t=F.statSync(s).isDirectory()}catch(i){e=i?.code}finally{if(!t)throw new Se(s,e??"ENOTDIR")}},yr=(s,t)=>{s=f(s);let e=t.umask??18,i=t.mode|448,r=(i&e)!==0,n=t.uid,o=t.gid,h=typeof n=="number"&&typeof o=="number"&&(n!==t.processUid||o!==t.processGid),a=t.preserve,l=t.unlink,c=f(t.cwd),d=E=>{E&&h&&ms(E,n,o),r&&F.chmodSync(s,i)};if(s===c)return to(c),d();if(a)return d(F.mkdirSync(s,{mode:i,recursive:!0})??void 0);let T=f(wi.relative(c,s)).split("/"),N;for(let E=T.shift(),x=c;E&&(x+="/"+E);E=T.shift()){x=f(wi.resolve(x));try{F.mkdirSync(x,i),N=N||x}catch{let Le=F.lstatSync(x);if(Le.isDirectory())continue;if(l){F.unlinkSync(x),F.mkdirSync(x,i),N=N||x;continue}else if(Le.isSymbolicLink())return new St(x,x+"/"+T.join("/"))}}return d(N)};import{join as br}from"node:path";var Es=Object.create(null),Rr=1e4,$t=new Set,gr=s=>{$t.has(s)?$t.delete(s):Es[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),$t.add(s);let t=Es[s],e=$t.size-Rr;if(e>Rr/10){for(let i of $t)if($t.delete(i),delete Es[i],--e<=0)break}return t};var eo=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,io=eo==="win32",so=s=>s.split("/").slice(0,-1).reduce((e,i)=>{let r=e.at(-1);return r!==void 0&&(i=br(r,i)),e.push(i||"/"),e},[]),Si=class{#t=new Map;#i=new Map;#s=new Set;reserve(t,e){t=io?["win32 parallelization disabled"]:t.map(r=>mt(br(gr(r))));let i=new Set(t.map(r=>so(r)).reduce((r,n)=>r.concat(n)));this.#i.set(e,{dirs:i,paths:t});for(let r of t){let n=this.#t.get(r);n?n.push(e):this.#t.set(r,[e])}for(let r of i){let n=this.#t.get(r);if(!n)this.#t.set(r,[new Set([e])]);else{let o=n.at(-1);o instanceof Set?o.add(e):n.push(new Set([e]))}}return this.#r(e)}#n(t){let e=this.#i.get(t);if(!e)throw new Error("function does not have any path reservations");return{paths:e.paths.map(i=>this.#t.get(i)),dirs:[...e.dirs].map(i=>this.#t.get(i))}}check(t){let{paths:e,dirs:i}=this.#n(t);return e.every(r=>r&&r[0]===t)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(t))}#r(t){return this.#s.has(t)||!this.check(t)?!1:(this.#s.add(t),t(()=>this.#e(t)),!0)}#e(t){if(!this.#s.has(t))return!1;let e=this.#i.get(t);if(!e)throw new Error("invalid reservation");let{paths:i,dirs:r}=e,n=new Set;for(let o of i){let h=this.#t.get(o);if(!h||h?.[0]!==t)continue;let a=h[1];if(!a){this.#t.delete(o);continue}if(h.shift(),typeof a=="function")n.add(a);else for(let l of a)n.add(l)}for(let o of r){let h=this.#t.get(o),a=h?.[0];if(!(!h||!(a instanceof Set)))if(a.size===1&&h.length===1){this.#t.delete(o);continue}else if(a.size===1){h.shift();let l=h[0];typeof l=="function"&&n.add(l)}else a.delete(t)}return this.#s.delete(t),n.forEach(o=>this.#r(o)),!0}};var _r=()=>process.umask();var Or=Symbol("onEntry"),Rs=Symbol("checkFs"),Tr=Symbol("checkFs2"),gs=Symbol("isReusable"),P=Symbol("makeFs"),bs=Symbol("file"),_s=Symbol("directory"),Ri=Symbol("link"),xr=Symbol("symlink"),Lr=Symbol("hardlink"),Re=Symbol("ensureNoSymlink"),Nr=Symbol("unsupported"),Dr=Symbol("checkPath"),ws=Symbol("stripAbsolutePath"),yt=Symbol("mkdir"),O=Symbol("onError"),yi=Symbol("pending"),Ar=Symbol("pend"),Xt=Symbol("unpend"),Ss=Symbol("ended"),ys=Symbol("maybeClose"),Os=Symbol("skip"),ge=Symbol("doChown"),be=Symbol("uid"),_e=Symbol("gid"),Oe=Symbol("checkedCwd"),no=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Te=no==="win32",oo=1024,ho=(s,t)=>{if(!Te)return u.unlink(s,t);let e=s+".DELETE."+Cr(16).toString("hex");u.rename(s,e,i=>{if(i)return t(i);u.unlink(e,t)})},ao=s=>{if(!Te)return u.unlinkSync(s);let t=s+".DELETE."+Cr(16).toString("hex");u.renameSync(s,t),u.unlinkSync(t)},Ir=(s,t,e)=>s!==void 0&&s===s>>>0?s:t!==void 0&&t===t>>>0?t:e,qt=class extends st{[Ss]=!1;[Oe]=!1;[yi]=0;reservations=new Si;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(t={}){if(t.ondone=()=>{this[Ss]=!0,this[ys]()},super(t),this.transform=t.transform,this.chmod=!!t.chmod,typeof t.uid=="number"||typeof t.gid=="number"){if(typeof t.uid!="number"||typeof t.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(t.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=t.uid,this.gid=t.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=t.preserveOwner===void 0&&typeof t.uid!="number"?!!(process.getuid&&process.getuid()===0):!!t.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof t.maxDepth=="number"?t.maxDepth:oo,this.forceChown=t.forceChown===!0,this.win32=!!t.win32||Te,this.newer=!!t.newer,this.keep=!!t.keep,this.noMtime=!!t.noMtime,this.preservePaths=!!t.preservePaths,this.unlink=!!t.unlink,this.cwd=f(R.resolve(t.cwd||process.cwd())),this.strip=Number(t.strip)||0,this.processUmask=this.chmod?typeof t.processUmask=="number"?t.processUmask:_r():0,this.umask=typeof t.umask=="number"?t.umask:this.processUmask,this.dmode=t.dmode||511&~this.umask,this.fmode=t.fmode||438&~this.umask,this.on("entry",e=>this[Or](e))}warn(t,e,i={}){return(t==="TAR_BAD_ARCHIVE"||t==="TAR_ABORT")&&(i.recoverable=!1),super.warn(t,e,i)}[ys](){this[Ss]&&this[yi]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[ws](t,e){let i=t[e],{type:r}=t;if(!i||this.preservePaths)return!0;let[n,o]=ce(i),h=o.replaceAll(/\\/g,"/").split("/");if(h.includes("..")||Te&&/^[a-z]:\.\.$/i.test(h[0]??"")){if(e==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${e} contains '..'`,{entry:t,[e]:i}),!1;let a=R.posix.dirname(t.path),l=R.posix.normalize(R.posix.join(a,h.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${e} escapes extraction directory`,{entry:t,[e]:i}),!1}return n&&(t[e]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${e}`,{entry:t,[e]:i})),!0}[Dr](t){let e=f(t.path),i=e.split("/");if(this.strip){if(i.length=this.strip)t.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),t.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:t,path:e,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[ws](t,"path")||!this[ws](t,"linkpath"))return!1;if(t.absolute=R.isAbsolute(t.path)?f(R.resolve(t.path)):f(R.resolve(this.cwd,t.path)),!this.preservePaths&&typeof t.absolute=="string"&&t.absolute.indexOf(this.cwd+"/")!==0&&t.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:t,path:f(t.path),resolvedPath:t.absolute,cwd:this.cwd}),!1;if(t.absolute===this.cwd&&t.type!=="Directory"&&t.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=R.win32.parse(String(t.absolute));t.absolute=r+Qi(String(t.absolute).slice(r.length));let{root:n}=R.win32.parse(t.path);t.path=n+Qi(t.path.slice(n.length))}return!0}[Or](t){if(!this[Dr](t))return t.resume();switch(ro.equal(typeof t.absolute,"string"),t.type){case"Directory":case"GNUDumpDir":t.mode&&(t.mode=t.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[Rs](t);default:return this[Nr](t)}}[O](t,e){t.name==="CwdError"?this.emit("error",t):(this.warn("TAR_ENTRY_ERROR",t,{entry:e}),this[Xt](),e.resume())}[yt](t,e,i){wr(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e},i)}[ge](t){return this.forceChown||this.preserveOwner&&(typeof t.uid=="number"&&t.uid!==this.processUid||typeof t.gid=="number"&&t.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[be](t){return Ir(this.uid,t.uid,this.processUid)}[_e](t){return Ir(this.gid,t.gid,this.processGid)}[bs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=new tt(String(t.absolute),{flags:fs(t.size),mode:i,autoClose:!1});r.on("error",a=>{r.fd&&u.close(r.fd,()=>{}),r.write=()=>!0,this[O](a,t),e()});let n=1,o=a=>{if(a){r.fd&&u.close(r.fd,()=>{}),this[O](a,t),e();return}--n===0&&r.fd!==void 0&&u.close(r.fd,l=>{l?this[O](l,t):this[Xt](),e()})};r.on("finish",()=>{let a=String(t.absolute),l=r.fd;if(typeof l=="number"&&t.mtime&&!this.noMtime){n++;let c=t.atime||new Date,d=t.mtime;u.futimes(l,c,d,S=>S?u.utimes(a,c,d,T=>o(T&&S)):o())}if(typeof l=="number"&&this[ge](t)){n++;let c=this[be](t),d=this[_e](t);typeof c=="number"&&typeof d=="number"&&u.fchown(l,c,d,S=>S?u.chown(a,c,d,T=>o(T&&S)):o())}o()});let h=this.transform&&this.transform(t)||t;h!==t&&(h.on("error",a=>{this[O](a,t),e()}),t.pipe(h)),h.pipe(r)}[_s](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode;this[yt](String(t.absolute),i,r=>{if(r){this[O](r,t),e();return}let n=1,o=()=>{--n===0&&(e(),this[Xt](),t.resume())};t.mtime&&!this.noMtime&&(n++,u.utimes(String(t.absolute),t.atime||new Date,t.mtime,o)),this[ge](t)&&(n++,u.chown(String(t.absolute),Number(this[be](t)),Number(this[_e](t)),o)),o()})}[Nr](t){t.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${t.type}`,{entry:t}),t.resume()}[xr](t,e){let i=f(R.relative(this.cwd,R.resolve(R.dirname(String(t.absolute)),String(t.linkpath)))).split("/");this[Re](t,this.cwd,i,()=>this[Ri](t,String(t.linkpath),"symlink",e),r=>{this[O](r,t),e()})}[Lr](t,e){let i=f(R.resolve(this.cwd,String(t.linkpath))),r=f(String(t.linkpath)).split("/");this[Re](t,this.cwd,r,()=>this[Ri](t,i,"link",e),n=>{this[O](n,t),e()})}[Re](t,e,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let h=R.resolve(e,o);u.lstat(h,(a,l)=>{if(a)return r();if(l?.isSymbolicLink())return n(new St(h,R.resolve(h,i.join("/"))));this[Re](t,h,i,r,n)})}[Ar](){this[yi]++}[Xt](){this[yi]--,this[ys]()}[Os](t){this[Xt](),t.resume()}[gs](t,e){return t.type==="File"&&!this.unlink&&e.isFile()&&e.nlink<=1&&!Te}[Rs](t){this[Ar]();let e=[t.path];t.linkpath&&e.push(t.linkpath),this.reservations.reserve(e,i=>this[Tr](t,i))}[Tr](t,e){let i=h=>{e(h)},r=()=>{this[yt](this.cwd,this.dmode,h=>{if(h){this[O](h,t),i();return}this[Oe]=!0,n()})},n=()=>{if(t.absolute!==this.cwd){let h=f(R.dirname(String(t.absolute)));if(h!==this.cwd)return this[yt](h,this.dmode,a=>{if(a){this[O](a,t),i();return}o()})}o()},o=()=>{u.lstat(String(t.absolute),(h,a)=>{if(a&&(this.keep||this.newer&&a.mtime>(t.mtime??a.mtime))){this[Os](t),i();return}if(h||this[gs](t,a))return this[P](null,t,i);if(a.isDirectory()){if(t.type==="Directory"){let l=this.chmod&&t.mode&&(a.mode&4095)!==t.mode,c=d=>this[P](d??null,t,i);return l?u.chmod(String(t.absolute),Number(t.mode),c):c()}if(t.absolute!==this.cwd)return u.rmdir(String(t.absolute),l=>this[P](l??null,t,i))}if(t.absolute===this.cwd)return this[P](null,t,i);ho(String(t.absolute),l=>this[P](l??null,t,i))})};this[Oe]?n():r()}[P](t,e,i){if(t){this[O](t,e),i();return}switch(e.type){case"File":case"OldFile":case"ContiguousFile":return this[bs](e,i);case"Link":return this[Lr](e,i);case"SymbolicLink":return this[xr](e,i);case"Directory":case"GNUDumpDir":return this[_s](e,i)}}[Ri](t,e,i,r){u[i](e,String(t.absolute),n=>{n?this[O](n,t):(this[Xt](),t.resume()),r()})}},ye=s=>{try{return[null,s()]}catch(t){return[t,null]}},xe=class extends qt{sync=!0;[P](t,e){return super[P](t,e,()=>{})}[Rs](t){if(!this[Oe]){let n=this[yt](this.cwd,this.dmode);if(n)return this[O](n,t);this[Oe]=!0}if(t.absolute!==this.cwd){let n=f(R.dirname(String(t.absolute)));if(n!==this.cwd){let o=this[yt](n,this.dmode);if(o)return this[O](o,t)}}let[e,i]=ye(()=>u.lstatSync(String(t.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(t.mtime??i.mtime)))return this[Os](t);if(e||this[gs](t,i))return this[P](null,t);if(i.isDirectory()){if(t.type==="Directory"){let o=this.chmod&&t.mode&&(i.mode&4095)!==t.mode,[h]=o?ye(()=>{u.chmodSync(String(t.absolute),Number(t.mode))}):[];return this[P](h,t)}let[n]=ye(()=>u.rmdirSync(String(t.absolute)));this[P](n,t)}let[r]=t.absolute===this.cwd?[]:ye(()=>ao(String(t.absolute)));this[P](r,t)}[bs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=h=>{let a;try{u.closeSync(n)}catch(l){a=l}(h||a)&&this[O](h||a,t),e()},n;try{n=u.openSync(String(t.absolute),fs(t.size),i)}catch(h){return r(h)}let o=this.transform&&this.transform(t)||t;o!==t&&(o.on("error",h=>this[O](h,t)),t.pipe(o)),o.on("data",h=>{try{u.writeSync(n,h,0,h.length)}catch(a){r(a)}}),o.on("end",()=>{let h=null;if(t.mtime&&!this.noMtime){let a=t.atime||new Date,l=t.mtime;try{u.futimesSync(n,a,l)}catch(c){try{u.utimesSync(String(t.absolute),a,l)}catch{h=c}}}if(this[ge](t)){let a=this[be](t),l=this[_e](t);try{u.fchownSync(n,Number(a),Number(l))}catch(c){try{u.chownSync(String(t.absolute),Number(a),Number(l))}catch{h=h||c}}}r(h)})}[_s](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode,r=this[yt](String(t.absolute),i);if(r){this[O](r,t),e();return}if(t.mtime&&!this.noMtime)try{u.utimesSync(String(t.absolute),t.atime||new Date,t.mtime)}catch{}if(this[ge](t))try{u.chownSync(String(t.absolute),Number(this[be](t)),Number(this[_e](t)))}catch{}e(),t.resume()}[yt](t,e){try{return yr(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e})}catch(i){return i}}[Re](t,e,i,r,n){if(this.preservePaths||i.length===0)return r();let o=e;for(let h of i){o=R.resolve(o,h);let[a,l]=ye(()=>u.lstatSync(o));if(a)return r();if(l.isSymbolicLink())return n(new St(o,R.resolve(e,i.join("/"))))}r()}[Ri](t,e,i,r){let n=`${i}Sync`;try{u[n](e,String(t.absolute)),r(),t.resume()}catch(o){return this[O](o,t)}}};var lo=s=>{let t=new xe(s),e=s.file,i=kr.statSync(e),r=s.maxReadSize||16*1024*1024;new Be(e,{readSize:r,size:i.size}).pipe(t)},co=(s,t)=>{let e=new qt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("close",o),kr.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},fo=K(lo,co,s=>new xe(s),s=>new qt(s),(s,t)=>{t?.length&&$i(s,t)});import v from"node:fs";import Fr from"node:path";var uo=(s,t)=>{let e=new Ft(s),i=!0,r,n;try{try{r=v.openSync(s.file,"r+")}catch(a){if(a?.code==="ENOENT")r=v.openSync(s.file,"w+");else throw a}let o=v.fstatSync(r),h=Buffer.alloc(512);t:for(n=0;no.size)break;n+=l,s.mtimeCache&&a.mtime&&s.mtimeCache.set(String(a.path),a.mtime)}i=!1,mo(s,e,n,r,t)}finally{if(i)try{v.closeSync(r)}catch{}}},mo=(s,t,e,i,r)=>{let n=new Wt(s.file,{fd:i,start:e});t.pipe(n),Eo(t,r)},po=(s,t)=>{t=Array.from(t);let e=new wt(s),i=(n,o,h)=>{let a=(T,N)=>{T?v.close(n,E=>h(T)):h(null,N)},l=0;if(o===0)return a(null,0);let c=0,d=Buffer.alloc(512),S=(T,N)=>{if(T||N===void 0)return a(T);if(c+=N,c<512&&N)return v.read(n,d,c,d.length-c,l+c,S);if(l===0&&d[0]===31&&d[1]===139)return a(new Error("cannot append to compressed archives"));if(c<512)return a(null,l);let E=new k(d);if(!E.cksumValid)return a(null,l);let x=512*Math.ceil((E.size??0)/512);if(l+x+512>o||(l+=x+512,l>=o))return a(null,l);s.mtimeCache&&E.mtime&&s.mtimeCache.set(String(E.path),E.mtime),c=0,v.read(n,d,0,512,l,S)};v.read(n,d,0,512,l,S)};return new Promise((n,o)=>{e.on("error",o);let h="r+",a=(l,c)=>{if(l&&l.code==="ENOENT"&&h==="r+")return h="w+",v.open(s.file,h,a);if(l||!c)return o(l);v.fstat(c,(d,S)=>{if(d)return v.close(c,()=>o(d));i(c,S.size,(T,N)=>{if(T)return o(T);let E=new tt(s.file,{fd:c,start:N});e.pipe(E),E.on("error",o),E.on("close",n),wo(e,t)})})};v.open(s.file,h,a)})},Eo=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:Fr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},wo=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:Fr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e);s.end()},vt=K(uo,po,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,t)=>{if(!Fs(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!t?.length)throw new TypeError("no paths specified to add/replace")});var So=K(vt.syncFile,vt.asyncFile,vt.syncNoFile,vt.asyncNoFile,(s,t=[])=>{vt.validate?.(s,t),yo(s)}),yo=s=>{let t=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=t?(e,i)=>t(e,i)&&!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0)):(e,i)=>!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0))};export{k as Header,wt as Pack,mi as PackJob,Ft as PackSync,st as Parser,ct as Pax,Yt as ReadEntry,qt as Unpack,xe as UnpackSync,de as WriteEntry,ri as WriteEntrySync,ni as WriteEntryTar,Yn as c,Yn as create,fo as extract,$i as filesFilter,Ct as list,vt as r,vt as replace,Ct as t,zi as types,So as u,So as update,fo as x}; +var zr=Object.defineProperty;var Ur=(s,t)=>{for(var e in t)zr(s,e,{get:t[e],enumerable:!0})};import Qr from"events";import I from"fs";import{EventEmitter as Di}from"node:events";import Cs from"node:stream";import{StringDecoder as Hr}from"node:string_decoder";var Ds=typeof process=="object"&&process?process:{stdout:null,stderr:null},Wr=s=>!!s&&typeof s=="object"&&(s instanceof A||s instanceof Cs||Gr(s)||Zr(s)),Gr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.pipe=="function"&&s.pipe!==Cs.Writable.prototype.pipe,Zr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.write=="function"&&typeof s.end=="function",Q=Symbol("EOF"),J=Symbol("maybeEmitEnd"),nt=Symbol("emittedEnd"),De=Symbol("emittingEnd"),qt=Symbol("emittedError"),Ne=Symbol("closed"),Ns=Symbol("read"),Ae=Symbol("flush"),As=Symbol("flushChunk"),z=Symbol("encoding"),Mt=Symbol("decoder"),g=Symbol("flowing"),Qt=Symbol("paused"),Bt=Symbol("resume"),b=Symbol("buffer"),N=Symbol("pipes"),_=Symbol("bufferLength"),bi=Symbol("bufferPush"),Ie=Symbol("bufferShift"),L=Symbol("objectMode"),w=Symbol("destroyed"),_i=Symbol("error"),Oi=Symbol("emitData"),Is=Symbol("emitEnd"),Ti=Symbol("emitEnd2"),Z=Symbol("async"),xi=Symbol("abort"),Ce=Symbol("aborted"),Jt=Symbol("signal"),Rt=Symbol("dataListeners"),C=Symbol("discarded"),jt=s=>Promise.resolve().then(s),Yr=s=>s(),Kr=s=>s==="end"||s==="finish"||s==="prefinish",Vr=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,$r=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Fe=class{src;dest;opts;ondrain;constructor(t,e,i){this.src=t,this.dest=e,this.opts=i,this.ondrain=()=>t[Bt](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(t){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},Li=class extends Fe{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(t,e,i){super(t,e,i),this.proxyErrors=r=>this.dest.emit("error",r),t.on("error",this.proxyErrors)}},Xr=s=>!!s.objectMode,qr=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",A=class extends Di{[g]=!1;[Qt]=!1;[N]=[];[b]=[];[L];[z];[Z];[Mt];[Q]=!1;[nt]=!1;[De]=!1;[Ne]=!1;[qt]=null;[_]=0;[w]=!1;[Jt];[Ce]=!1;[Rt]=0;[C]=!1;writable=!0;readable=!0;constructor(...t){let e=t[0]||{};if(super(),e.objectMode&&typeof e.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Xr(e)?(this[L]=!0,this[z]=null):qr(e)?(this[z]=e.encoding,this[L]=!1):(this[L]=!1,this[z]=null),this[Z]=!!e.async,this[Mt]=this[z]?new Hr(this[z]):null,e&&e.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[b]}),e&&e.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[N]});let{signal:i}=e;i&&(this[Jt]=i,i.aborted?this[xi]():i.addEventListener("abort",()=>this[xi]()))}get bufferLength(){return this[_]}get encoding(){return this[z]}set encoding(t){throw new Error("Encoding must be set at instantiation time")}setEncoding(t){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[L]}set objectMode(t){throw new Error("objectMode must be set at instantiation time")}get async(){return this[Z]}set async(t){this[Z]=this[Z]||!!t}[xi](){this[Ce]=!0,this.emit("abort",this[Jt]?.reason),this.destroy(this[Jt]?.reason)}get aborted(){return this[Ce]}set aborted(t){}write(t,e,i){if(this[Ce])return!1;if(this[Q])throw new Error("write after end");if(this[w])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof e=="function"&&(i=e,e="utf8"),e||(e="utf8");let r=this[Z]?jt:Yr;if(!this[L]&&!Buffer.isBuffer(t)){if($r(t))t=Buffer.from(t.buffer,t.byteOffset,t.byteLength);else if(Vr(t))t=Buffer.from(t);else if(typeof t!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[L]?(this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):t.length?(typeof t=="string"&&!(e===this[z]&&!this[Mt]?.lastNeed)&&(t=Buffer.from(t,e)),Buffer.isBuffer(t)&&this[z]&&(t=this[Mt].write(t)),this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):(this[_]!==0&&this.emit("readable"),i&&r(i),this[g])}read(t){if(this[w])return null;if(this[C]=!1,this[_]===0||t===0||t&&t>this[_])return this[J](),null;this[L]&&(t=null),this[b].length>1&&!this[L]&&(this[b]=[this[z]?this[b].join(""):Buffer.concat(this[b],this[_])]);let e=this[Ns](t||null,this[b][0]);return this[J](),e}[Ns](t,e){if(this[L])this[Ie]();else{let i=e;t===i.length||t===null?this[Ie]():typeof i=="string"?(this[b][0]=i.slice(t),e=i.slice(0,t),this[_]-=t):(this[b][0]=i.subarray(t),e=i.subarray(0,t),this[_]-=t)}return this.emit("data",e),!this[b].length&&!this[Q]&&this.emit("drain"),e}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e="utf8"),t!==void 0&&this.write(t,e),i&&this.once("end",i),this[Q]=!0,this.writable=!1,(this[g]||!this[Qt])&&this[J](),this}[Bt](){this[w]||(!this[Rt]&&!this[N].length&&(this[C]=!0),this[Qt]=!1,this[g]=!0,this.emit("resume"),this[b].length?this[Ae]():this[Q]?this[J]():this.emit("drain"))}resume(){return this[Bt]()}pause(){this[g]=!1,this[Qt]=!0,this[C]=!1}get destroyed(){return this[w]}get flowing(){return this[g]}get paused(){return this[Qt]}[bi](t){this[L]?this[_]+=1:this[_]+=t.length,this[b].push(t)}[Ie](){return this[L]?this[_]-=1:this[_]-=this[b][0].length,this[b].shift()}[Ae](t=!1){do;while(this[As](this[Ie]())&&this[b].length);!t&&!this[b].length&&!this[Q]&&this.emit("drain")}[As](t){return this.emit("data",t),this[g]}pipe(t,e){if(this[w])return t;this[C]=!1;let i=this[nt];return e=e||{},t===Ds.stdout||t===Ds.stderr?e.end=!1:e.end=e.end!==!1,e.proxyErrors=!!e.proxyErrors,i?e.end&&t.end():(this[N].push(e.proxyErrors?new Li(this,t,e):new Fe(this,t,e)),this[Z]?jt(()=>this[Bt]()):this[Bt]()),t}unpipe(t){let e=this[N].find(i=>i.dest===t);e&&(this[N].length===1?(this[g]&&this[Rt]===0&&(this[g]=!1),this[N]=[]):this[N].splice(this[N].indexOf(e),1),e.unpipe())}addListener(t,e){return this.on(t,e)}on(t,e){let i=super.on(t,e);if(t==="data")this[C]=!1,this[Rt]++,!this[N].length&&!this[g]&&this[Bt]();else if(t==="readable"&&this[_]!==0)super.emit("readable");else if(Kr(t)&&this[nt])super.emit(t),this.removeAllListeners(t);else if(t==="error"&&this[qt]){let r=e;this[Z]?jt(()=>r.call(this,this[qt])):r.call(this,this[qt])}return i}removeListener(t,e){return this.off(t,e)}off(t,e){let i=super.off(t,e);return t==="data"&&(this[Rt]=this.listeners("data").length,this[Rt]===0&&!this[C]&&!this[N].length&&(this[g]=!1)),i}removeAllListeners(t){let e=super.removeAllListeners(t);return(t==="data"||t===void 0)&&(this[Rt]=0,!this[C]&&!this[N].length&&(this[g]=!1)),e}get emittedEnd(){return this[nt]}[J](){!this[De]&&!this[nt]&&!this[w]&&this[b].length===0&&this[Q]&&(this[De]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ne]&&this.emit("close"),this[De]=!1)}emit(t,...e){let i=e[0];if(t!=="error"&&t!=="close"&&t!==w&&this[w])return!1;if(t==="data")return!this[L]&&!i?!1:this[Z]?(jt(()=>this[Oi](i)),!0):this[Oi](i);if(t==="end")return this[Is]();if(t==="close"){if(this[Ne]=!0,!this[nt]&&!this[w])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(t==="error"){this[qt]=i,super.emit(_i,i);let n=!this[Jt]||this.listeners("error").length?super.emit("error",i):!1;return this[J](),n}else if(t==="resume"){let n=super.emit("resume");return this[J](),n}else if(t==="finish"||t==="prefinish"){let n=super.emit(t);return this.removeAllListeners(t),n}let r=super.emit(t,...e);return this[J](),r}[Oi](t){for(let i of this[N])i.dest.write(t)===!1&&this.pause();let e=this[C]?!1:super.emit("data",t);return this[J](),e}[Is](){return this[nt]?!1:(this[nt]=!0,this.readable=!1,this[Z]?(jt(()=>this[Ti]()),!0):this[Ti]())}[Ti](){if(this[Mt]){let e=this[Mt].end();if(e){for(let i of this[N])i.dest.write(e);this[C]||super.emit("data",e)}}for(let e of this[N])e.end();let t=super.emit("end");return this.removeAllListeners("end"),t}async collect(){let t=Object.assign([],{dataLength:0});this[L]||(t.dataLength=0);let e=this.promise();return this.on("data",i=>{t.push(i),this[L]||(t.dataLength+=i.length)}),await e,t}async concat(){if(this[L])throw new Error("cannot concat in objectMode");let t=await this.collect();return this[z]?t.join(""):Buffer.concat(t,t.dataLength)}async promise(){return new Promise((t,e)=>{this.on(w,()=>e(new Error("stream destroyed"))),this.on("error",i=>e(i)),this.on("end",()=>t())})}[Symbol.asyncIterator](){this[C]=!1;let t=!1,e=async()=>(this.pause(),t=!0,{value:void 0,done:!0});return{next:()=>{if(t)return e();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[Q])return e();let n,o,h=d=>{this.off("data",a),this.off("end",l),this.off(w,c),e(),o(d)},a=d=>{this.off("error",h),this.off("end",l),this.off(w,c),this.pause(),n({value:d,done:!!this[Q]})},l=()=>{this.off("error",h),this.off("data",a),this.off(w,c),e(),n({done:!0,value:void 0})},c=()=>h(new Error("stream destroyed"));return new Promise((d,S)=>{o=S,n=d,this.once(w,c),this.once("error",h),this.once("end",l),this.once("data",a)})},throw:e,return:e,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[C]=!1;let t=!1,e=()=>(this.pause(),this.off(_i,e),this.off(w,e),this.off("end",e),t=!0,{done:!0,value:void 0}),i=()=>{if(t)return e();let r=this.read();return r===null?e():{done:!1,value:r}};return this.once("end",e),this.once(_i,e),this.once(w,e),{next:i,throw:e,return:e,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(t){if(this[w])return t?this.emit("error",t):this.emit(w),this;this[w]=!0,this[C]=!0,this[b].length=0,this[_]=0;let e=this;return typeof e.close=="function"&&!this[Ne]&&e.close(),t?this.emit("error",t):this.emit(w),this}static get isStream(){return Wr}};var Jr=I.writev,ht=Symbol("_autoClose"),H=Symbol("_close"),te=Symbol("_ended"),u=Symbol("_fd"),Ni=Symbol("_finished"),tt=Symbol("_flags"),Ai=Symbol("_flush"),ki=Symbol("_handleChunk"),vi=Symbol("_makeBuf"),ie=Symbol("_mode"),ke=Symbol("_needDrain"),Ut=Symbol("_onerror"),Ht=Symbol("_onopen"),Ii=Symbol("_onread"),Pt=Symbol("_onwrite"),at=Symbol("_open"),U=Symbol("_path"),ot=Symbol("_pos"),Y=Symbol("_queue"),zt=Symbol("_read"),Ci=Symbol("_readSize"),j=Symbol("_reading"),ee=Symbol("_remain"),Fi=Symbol("_size"),ve=Symbol("_write"),gt=Symbol("_writing"),Me=Symbol("_defaultFlag"),bt=Symbol("_errored"),_t=class extends A{[bt]=!1;[u];[U];[Ci];[j]=!1;[Fi];[ee];[ht];constructor(t,e){if(e=e||{},super(e),this.readable=!0,this.writable=!1,typeof t!="string")throw new TypeError("path must be a string");this[bt]=!1,this[u]=typeof e.fd=="number"?e.fd:void 0,this[U]=t,this[Ci]=e.readSize||16*1024*1024,this[j]=!1,this[Fi]=typeof e.size=="number"?e.size:1/0,this[ee]=this[Fi],this[ht]=typeof e.autoClose=="boolean"?e.autoClose:!0,typeof this[u]=="number"?this[zt]():this[at]()}get fd(){return this[u]}get path(){return this[U]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[at](){I.open(this[U],"r",(t,e)=>this[Ht](t,e))}[Ht](t,e){t?this[Ut](t):(this[u]=e,this.emit("open",e),this[zt]())}[vi](){return Buffer.allocUnsafe(Math.min(this[Ci],this[ee]))}[zt](){if(!this[j]){this[j]=!0;let t=this[vi]();if(t.length===0)return process.nextTick(()=>this[Ii](null,0,t));I.read(this[u],t,0,t.length,null,(e,i,r)=>this[Ii](e,i,r))}}[Ii](t,e,i){this[j]=!1,t?this[Ut](t):this[ki](e,i)&&this[zt]()}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}[Ut](t){this[j]=!0,this[H](),this.emit("error",t)}[ki](t,e){let i=!1;return this[ee]-=t,t>0&&(i=super.write(tthis[Ht](t,e))}[Ht](t,e){this[Me]&&this[tt]==="r+"&&t&&t.code==="ENOENT"?(this[tt]="w",this[at]()):t?this[Ut](t):(this[u]=e,this.emit("open",e),this[gt]||this[Ai]())}end(t,e){return t&&this.write(t,e),this[te]=!0,!this[gt]&&!this[Y].length&&typeof this[u]=="number"&&this[Pt](null,0),this}write(t,e){return typeof t=="string"&&(t=Buffer.from(t,e)),this[te]?(this.emit("error",new Error("write() after end()")),!1):this[u]===void 0||this[gt]||this[Y].length?(this[Y].push(t),this[ke]=!0,!1):(this[gt]=!0,this[ve](t),!0)}[ve](t){I.write(this[u],t,0,t.length,this[ot],(e,i)=>this[Pt](e,i))}[Pt](t,e){t?this[Ut](t):(this[ot]!==void 0&&typeof e=="number"&&(this[ot]+=e),this[Y].length?this[Ai]():(this[gt]=!1,this[te]&&!this[Ni]?(this[Ni]=!0,this[H](),this.emit("finish")):this[ke]&&(this[ke]=!1,this.emit("drain"))))}[Ai](){if(this[Y].length===0)this[te]&&this[Pt](null,0);else if(this[Y].length===1)this[ve](this[Y].pop());else{let t=this[Y];this[Y]=[],Jr(this[u],t,this[ot],(e,i)=>this[Pt](e,i))}}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}},Wt=class extends et{[at](){let t;if(this[Me]&&this[tt]==="r+")try{t=I.openSync(this[U],this[tt],this[ie])}catch(e){if(e?.code==="ENOENT")return this[tt]="w",this[at]();throw e}else t=I.openSync(this[U],this[tt],this[ie]);this[Ht](null,t)}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.closeSync(t),this.emit("close")}}[ve](t){let e=!0;try{this[Pt](null,I.writeSync(this[u],t,0,t.length,this[ot])),e=!1}finally{if(e)try{this[H]()}catch{}}}};import cr from"node:path";import Kt from"node:fs";import{dirname as Fn,parse as kn}from"path";var jr=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),Fs=s=>!!s.sync&&!!s.file,ks=s=>!s.sync&&!!s.file,vs=s=>!!s.sync&&!s.file,Ms=s=>!s.sync&&!s.file;var Bs=s=>!!s.file;var tn=s=>{let t=jr.get(s);return t||s},se=(s={})=>{if(!s)return{};let t={};for(let[e,i]of Object.entries(s)){let r=tn(e);t[r]=i}return t.chmod===void 0&&t.noChmod===!1&&(t.chmod=!0),delete t.noChmod,t};var K=(s,t,e,i,r)=>Object.assign((n=[],o,h)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(h=o,o=void 0),o=o?Array.from(o):[];let a=se(n);if(r?.(a,o),Fs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return s(a,o)}else if(ks(a)){let l=t(a,o);return h?l.then(()=>h(),h):l}else if(vs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return e(a,o)}else if(Ms(a)){if(typeof h=="function")throw new TypeError("callback only supported with file option");return i(a,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:t,syncNoFile:e,asyncNoFile:i,validate:r});import{EventEmitter as Dn}from"events";import zi from"assert";import{Buffer as Ot}from"buffer";import*as Ps from"zlib";import en from"zlib";var sn=en.constants||{ZLIB_VERNUM:4736},M=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},sn));var rn=Ot.concat,zs=Object.getOwnPropertyDescriptor(Ot,"concat"),nn=s=>s,Bi=zs?.writable===!0||zs?.set!==void 0?s=>{Ot.concat=s?nn:rn}:s=>{},Tt=Symbol("_superWrite"),Gt=class extends Error{code;errno;constructor(t,e){super("zlib: "+t.message,{cause:t}),this.code=t.code,this.errno=t.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+t.message,Error.captureStackTrace(this,e??this.constructor)}get name(){return"ZlibError"}},Pi=Symbol("flushFlag"),re=class extends A{#t=!1;#i=!1;#s;#n;#r;#e;#o;get sawError(){return this.#t}get handle(){return this.#e}get flushFlag(){return this.#s}constructor(t,e){if(!t||typeof t!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(t),this.#s=t.flush??0,this.#n=t.finishFlush??0,this.#r=t.fullFlushFlag??0,typeof Ps[e]!="function")throw new TypeError("Compression method not supported: "+e);try{this.#e=new Ps[e](t)}catch(i){throw new Gt(i,this.constructor)}this.#o=i=>{this.#t||(this.#t=!0,this.close(),this.emit("error",i))},this.#e?.on("error",i=>this.#o(new Gt(i))),this.once("end",()=>this.close)}close(){this.#e&&(this.#e.close(),this.#e=void 0,this.emit("close"))}reset(){if(!this.#t)return zi(this.#e,"zlib binding closed"),this.#e.reset?.()}flush(t){this.ended||(typeof t!="number"&&(t=this.#r),this.write(Object.assign(Ot.alloc(0),{[Pi]:t})))}end(t,e,i){return typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&(e?this.write(t,e):this.write(t)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Tt](t){return super.write(t)}write(t,e,i){if(typeof e=="function"&&(i=e,e="utf8"),typeof t=="string"&&(t=Ot.from(t,e)),this.#t)return;zi(this.#e,"zlib binding closed");let r=this.#e._handle,n=r.close;r.close=()=>{};let o=this.#e.close;this.#e.close=()=>{},Bi(!0);let h;try{let l=typeof t[Pi]=="number"?t[Pi]:this.#s;h=this.#e._processChunk(t,l),Bi(!1)}catch(l){Bi(!1),this.#o(new Gt(l,this.write))}finally{this.#e&&(this.#e._handle=r,r.close=n,this.#e.close=o,this.#e.removeAllListeners("error"))}this.#e&&this.#e.on("error",l=>this.#o(new Gt(l,this.write)));let a;if(h)if(Array.isArray(h)&&h.length>0){let l=h[0];a=this[Tt](Ot.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(t,e)}finally{this.handle.flush=i}this.handle&&(this.#t=t,this.#i=e)}}}};var ze=class extends Pe{#t;constructor(t){super(t,"Gzip"),this.#t=t&&!!t.portable}[Tt](t){return this.#t?(this.#t=!1,t[9]=255,super[Tt](t)):super[Tt](t)}};var Ue=class extends Pe{constructor(t){super(t,"Unzip")}},He=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.BROTLI_OPERATION_PROCESS,t.finishFlush=t.finishFlush||M.BROTLI_OPERATION_FINISH,t.fullFlushFlag=M.BROTLI_OPERATION_FLUSH,super(t,e)}},We=class extends He{constructor(t){super(t,"BrotliCompress")}},Ge=class extends He{constructor(t){super(t,"BrotliDecompress")}},Ze=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.ZSTD_e_continue,t.finishFlush=t.finishFlush||M.ZSTD_e_end,t.fullFlushFlag=M.ZSTD_e_flush,super(t,e)}},Ye=class extends Ze{constructor(t){super(t,"ZstdCompress")}},Ke=class extends Ze{constructor(t){super(t,"ZstdDecompress")}};import{posix as Zt}from"node:path";var Us=(s,t)=>{if(Number.isSafeInteger(s))s<0?an(s,t):hn(s,t);else throw Error("cannot encode number outside of javascript safe integer range");return t},hn=(s,t)=>{t[0]=128;for(var e=t.length;e>1;e--)t[e-1]=s&255,s=Math.floor(s/256)},an=(s,t)=>{t[0]=255;var e=!1;s=s*-1;for(var i=t.length;i>1;i--){var r=s&255;s=Math.floor(s/256),e?t[i-1]=Ws(r):r===0?t[i-1]=0:(e=!0,t[i-1]=Gs(r))}},Hs=s=>{let t=s[0],e=t===128?cn(s.subarray(1,s.length)):t===255?ln(s):null;if(e===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(e))throw Error("parsed number outside of javascript safe integer range");return e},ln=s=>{for(var t=s.length,e=0,i=!1,r=t-1;r>-1;r--){var n=Number(s[r]),o;i?o=Ws(n):n===0?o=n:(i=!0,o=Gs(n)),o!==0&&(e-=o*Math.pow(256,t-r-1))}return e},cn=s=>{for(var t=s.length,e=0,i=t-1;i>-1;i--){var r=Number(s[i]);r!==0&&(e+=r*Math.pow(256,t-i-1))}return e},Ws=s=>(255^s)&255,Gs=s=>(255^s)+1&255;var Hi={};Ur(Hi,{code:()=>Ve,isCode:()=>ne,isName:()=>dn,name:()=>oe,normalFsTypes:()=>Ui});var ne=s=>oe.has(s),dn=s=>Ve.has(s),Ui=new Set(["0","","1","2","3","4","5","6","7","D"]),oe=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]),Ve=new Map(Array.from(oe).map(s=>[s[1],s[0]]));var mn=s=>s===void 0||s<0?void 0:s,F=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#t="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(t,e=0,i,r){Buffer.isBuffer(t)?this.decode(t,e||0,i,r):t&&this.#i(t)}decode(t,e,i,r){if(e||(e=0),!t||!(t.length>=e+512))throw new Error("need 512 bytes for header");let n=xt(t,e+156,1),o=Ui.has(n),h=o?i:void 0,a=o?r:void 0;if(this.path=h?.path??xt(t,e,100),this.mode=h?.mode??a?.mode??lt(t,e+100,8),this.uid=h?.uid??a?.uid??lt(t,e+108,8),this.gid=h?.gid??a?.gid??lt(t,e+116,8),this.size=mn(h?.size??a?.size??lt(t,e+124,12)),this.mtime=h?.mtime??a?.mtime??Wi(t,e+136,12),this.cksum=lt(t,e+148,12),a&&this.#i(a,!0),h&&this.#i(h),ne(n)&&(this.#t=n||"0"),this.#t==="0"&&this.path.slice(-1)==="/"&&(this.#t="5"),this.#t==="5"&&(this.size=0),this.linkpath=xt(t,e+157,100),t.subarray(e+257,e+265).toString()==="ustar\x0000")if(this.uname=h?.uname??a?.uname??xt(t,e+265,32),this.gname=h?.gname??a?.gname??xt(t,e+297,32),this.devmaj=h?.devmaj??a?.devmaj??lt(t,e+329,8)??0,this.devmin=h?.devmin??a?.devmin??lt(t,e+337,8)??0,t[e+475]!==0){let c=xt(t,e+345,155);this.path=c+"/"+this.path}else{let c=xt(t,e+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Wi(t,e+476,12),this.ctime=i?.ctime??r?.ctime??Wi(t,e+488,12)}let l=256;for(let c=e;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&e||i==="linkpath"&&e||i==="global"))))}encode(t,e=0){if(t||(t=this.block=Buffer.alloc(512)),this.#t==="Unsupported"&&(this.#t="0"),!(t.length>=e+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=un(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Lt(t,e,100,n)||this.needPax,this.needPax=ct(t,e+100,8,this.mode)||this.needPax,this.needPax=ct(t,e+108,8,this.uid)||this.needPax,this.needPax=ct(t,e+116,8,this.gid)||this.needPax,this.needPax=ct(t,e+124,12,this.size)||this.needPax,this.needPax=Gi(t,e+136,12,this.mtime)||this.needPax,t[e+156]=Number(this.#t.codePointAt(0)),this.needPax=Lt(t,e+157,100,this.linkpath)||this.needPax,t.write("ustar\x0000",e+257,8),this.needPax=Lt(t,e+265,32,this.uname)||this.needPax,this.needPax=Lt(t,e+297,32,this.gname)||this.needPax,this.needPax=ct(t,e+329,8,this.devmaj)||this.needPax,this.needPax=ct(t,e+337,8,this.devmin)||this.needPax,this.needPax=Lt(t,e+345,i,o)||this.needPax,t[e+475]!==0?this.needPax=Lt(t,e+345,155,o)||this.needPax:(this.needPax=Lt(t,e+345,130,o)||this.needPax,this.needPax=Gi(t,e+476,12,this.atime)||this.needPax,this.needPax=Gi(t,e+488,12,this.ctime)||this.needPax);let h=256;for(let a=e;a{let i=s,r="",n,o=Zt.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Zt.dirname(i),i=Zt.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=t?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=t?n=[i.slice(0,99),r,!0]:(i=Zt.join(Zt.basename(r),i),r=Zt.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},xt=(s,t,e)=>s.subarray(t,t+e).toString("utf8").replace(/\0.*/,""),Wi=(s,t,e)=>pn(lt(s,t,e)),pn=s=>s===void 0?void 0:new Date(s*1e3),lt=(s,t,e)=>Number(s[t])&128?Hs(s.subarray(t,t+e)):wn(s,t,e),En=s=>isNaN(s)?void 0:s,wn=(s,t,e)=>En(parseInt(s.subarray(t,t+e).toString("utf8").replace(/\0.*$/,"").trim(),8)),Sn={12:8589934591,8:2097151},ct=(s,t,e,i)=>i===void 0?!1:i>Sn[e]||i<0?(Us(i,s.subarray(t,t+e)),!0):(yn(s,t,e,i),!1),yn=(s,t,e,i)=>s.write(Rn(i,e),t,e,"ascii"),Rn=(s,t)=>gn(Math.floor(s).toString(8),t),gn=(s,t)=>(s.length===t-1?s:new Array(t-s.length-1).join("0")+s+" ")+"\0",Gi=(s,t,e,i)=>i===void 0?!1:ct(s,t,e,i.getTime()/1e3),bn=new Array(156).join("\0"),Lt=(s,t,e,i)=>i===void 0?!1:(s.write(i+bn,t,e,"utf8"),i.length!==Buffer.byteLength(i)||i.length>e);import{basename as _n}from"node:path";var ft=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(t,e=!1){this.atime=t.atime,this.charset=t.charset,this.comment=t.comment,this.ctime=t.ctime,this.dev=t.dev,this.gid=t.gid,this.global=e,this.gname=t.gname,this.ino=t.ino,this.linkpath=t.linkpath,this.mtime=t.mtime,this.nlink=t.nlink,this.path=t.path,this.size=t.size,this.uid=t.uid,this.uname=t.uname}encode(){let t=this.encodeBody();if(t==="")return Buffer.allocUnsafe(0);let e=Buffer.byteLength(t),i=512*Math.ceil(1+e/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new F({path:("PaxHeader/"+_n(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:e,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(t,512,e,"utf8");for(let n=e+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(t,e,i=!1){return new s(On(Tn(t),e),i)}},On=(s,t)=>t?Object.assign({},t,s):s,Tn=s=>s.replace(/\n$/,"").split(` +`).reduce(xn,Object.create(null)),xn=(s,t)=>{let e=parseInt(t,10);if(e!==Buffer.byteLength(t)+1)return s;t=t.slice((e+" ").length);let i=t.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let h=+o;h>=0&&(s[n]=h);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s};var Ln=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,f=Ln!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/");var $e=class extends A{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(t,e,i){switch(super({}),this.pause(),this.extended=e,this.globalExtended=i,this.header=t,this.remain=t.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=t.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!t.path)throw new Error("no path provided for tar.ReadEntry");this.path=f(t.path),this.mode=t.mode,this.mode&&(this.mode=this.mode&4095),this.uid=t.uid,this.gid=t.gid,this.uname=t.uname,this.gname=t.gname,this.size=this.remain,this.mtime=t.mtime,this.atime=t.atime,this.ctime=t.ctime,this.linkpath=t.linkpath?f(t.linkpath):void 0,this.uname=t.uname,this.gname=t.gname,e&&this.#t(e),i&&this.#t(i,!0)}write(t){let e=t.length;if(e>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-e),this.blockRemain=Math.max(0,r-e),this.ignore?!0:i>=e?super.write(t):super.write(t.subarray(0,i))}#t(t,e=!1){t.path&&(t.path=f(t.path)),t.linkpath&&(t.linkpath=f(t.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(t).filter(([i,r])=>!(r==null||i==="path"&&e))))}};var Dt=(s,t,e,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=e instanceof Error&&e.code||t,i.tarCode=t,!s.strict&&i.recoverable!==!1?(e instanceof Error&&(i=Object.assign(e,i),e=e.message),s.emit("warn",t,e,i)):e instanceof Error?s.emit("error",Object.assign(e,i)):s.emit("error",Object.assign(new Error(`${t}: ${e}`),i))};var Nn=1024*1024,Xi=Buffer.from([31,139]),qi=Buffer.from([40,181,47,253]),An=Math.max(Xi.length,qi.length),B=Symbol("state"),Nt=Symbol("writeEntry"),it=Symbol("readEntry"),Zi=Symbol("nextEntry"),Zs=Symbol("processEntry"),V=Symbol("extendedHeader"),he=Symbol("globalExtendedHeader"),dt=Symbol("meta"),Ys=Symbol("emitMeta"),p=Symbol("buffer"),st=Symbol("queue"),mt=Symbol("ended"),Yi=Symbol("emittedEnd"),At=Symbol("emit"),y=Symbol("unzip"),Xe=Symbol("consumeChunk"),qe=Symbol("consumeChunkSub"),Ki=Symbol("consumeBody"),Ks=Symbol("consumeMeta"),Vs=Symbol("consumeHeader"),ae=Symbol("consuming"),Vi=Symbol("bufferConcat"),Qe=Symbol("maybeEnd"),Yt=Symbol("writing"),$=Symbol("aborted"),Je=Symbol("onDone"),It=Symbol("sawValidEntry"),je=Symbol("sawNullBlock"),ti=Symbol("sawEOF"),$s=Symbol("closeStream"),In=1e3,le=Symbol("compressedBytesRead"),$i=Symbol("decompressedBytesRead"),Xs=Symbol("checkDecompressionRatio"),Cn=()=>!0,rt=class extends Dn{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[st]=[];[p];[it];[Nt];[B]="begin";[dt]="";[V];[he];[mt]=!1;[y];[$]=!1;[It];[je]=!1;[ti]=!1;[Yt]=!1;[ae]=!1;[Yi]=!1;[le]=0;[$i]=0;constructor(t={}){super(),this.file=t.file||"",this.on(Je,()=>{(this[B]==="begin"||this[It]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),t.ondone?this.on(Je,t.ondone):this.on(Je,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!t.strict,this.maxDecompressionRatio=typeof t.maxDecompressionRatio=="number"?t.maxDecompressionRatio:In,this.maxMetaEntrySize=t.maxMetaEntrySize||Nn,this.filter=typeof t.filter=="function"?t.filter:Cn;let e=t.file&&(t.file.endsWith(".tar.br")||t.file.endsWith(".tbr"));this.brotli=!(t.gzip||t.zstd)&&t.brotli!==void 0?t.brotli:e?void 0:!1;let i=t.file&&(t.file.endsWith(".tar.zst")||t.file.endsWith(".tzst"));this.zstd=!(t.gzip||t.brotli)&&t.zstd!==void 0?t.zstd:i?!0:void 0,this.on("end",()=>this[$s]()),typeof t.onwarn=="function"&&this.on("warn",t.onwarn),typeof t.onReadEntry=="function"&&this.on("entry",t.onReadEntry)}warn(t,e,i={}){Dt(this,t,e,i)}[Vs](t,e){this[It]===void 0&&(this[It]=!1);let i;try{i=new F(t,e,this[V],this[he])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[je]?(this[ti]=!0,this[B]==="begin"&&(this[B]="header"),this[At]("eof")):(this[je]=!0,this[At]("nullBlock"));else if(this[je]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[Nt]=new $e(i,this[V],this[he]);if(!this[It])if(n.remain){let o=()=>{n.invalid||(this[It]=!0)};n.on("end",o)}else this[It]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[At]("ignoredEntry",n),this[B]="ignore",n.resume()):n.size>0&&(this[dt]="",n.on("data",o=>this[dt]+=o),this[B]="meta"):(this[V]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[At]("ignoredEntry",n),this[B]=n.remain?"ignore":"header",n.resume()):(n.remain?this[B]="body":(this[B]="header",n.end()),this[it]?this[st].push(n):(this[st].push(n),this[Zi]())))}}}[$s](){queueMicrotask(()=>this.emit("close"))}[Zs](t){let e=!0;if(!t)this[it]=void 0,e=!1;else if(Array.isArray(t)){let[i,...r]=t;this.emit(i,...r)}else this[it]=t,this.emit("entry",t),t.emittedEnd||(t.on("end",()=>this[Zi]()),e=!1);return e}[Zi](){do;while(this[Zs](this[st].shift()));if(this[st].length===0){let t=this[it];!t||t.flowing||t.size===t.remain?this[Yt]||this.emit("drain"):t.once("drain",()=>this.emit("drain"))}}[Ki](t,e){let i=this[Nt];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=t.length&&e===0?t:t.subarray(e,e+r);return i.write(n),i.blockRemain||(this[B]="header",this[Nt]=void 0,i.end()),n.length}[Ks](t,e){let i=this[Nt],r=this[Ki](t,e);return!this[Nt]&&i&&this[Ys](i),r}[At](t,e,i){this[st].length===0&&!this[it]?this.emit(t,e,i):this[st].push([t,e,i])}[Ys](t){switch(this[At]("meta",this[dt]),t.type){case"ExtendedHeader":case"OldExtendedHeader":this[V]=ft.parse(this[dt],this[V],!1);break;case"GlobalExtendedHeader":this[he]=ft.parse(this[dt],this[he],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let e=this[V]??Object.create(null);this[V]=e,e.path=this[dt].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let e=this[V]||Object.create(null);this[V]=e,e.linkpath=this[dt].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+t.type)}}abort(t){this[$]||(this[$]=!0,this.emit("abort",t),this.warn("TAR_ABORT",t,{recoverable:!1}))}[Xs](t){this[$i]+=t.length;let e=this[$i]/this[le];return e>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${e.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this[$])return i?.(),!1;if((this[y]===void 0||this.brotli===void 0&&this[y]===!1)&&t){if(this[p]&&(t=Buffer.concat([this[p],t]),this[p]=void 0),t.length{this[Xs](c)&&this[Xe](c)}),this[y].on("error",c=>{this[$]||this.abort(c)}),this[y].on("end",()=>{this[mt]=!0,this[Xe]()}),this[Yt]=!0,this[le]+=t.length;let l=!!this[y][a?"end":"write"](t);return this[Yt]=!1,i?.(),l}}this[Yt]=!0,this[y]?(this[le]+=t.length,this[y].write(t)):this[Xe](t),this[Yt]=!1;let n=this[st].length>0?!1:this[it]?this[it].flowing:!0;return!n&&this[st].length===0&&this[it]?.once("drain",()=>this.emit("drain")),i?.(),n}[Vi](t){t&&!this[$]&&(this[p]=this[p]?Buffer.concat([this[p],t]):t)}[Qe](){if(this[mt]&&!this[Yi]&&!this[$]&&!this[ae]){this[Yi]=!0;let t=this[Nt];if(t?.blockRemain){let e=this[p]?this[p].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${t.blockRemain} more bytes, only ${e} available)`,{entry:t}),this[p]&&t.write(this[p]),t.end()}this[At](Je)}}[Xe](t){if(this[ae]&&t)this[Vi](t);else if(!t&&!this[p])this[Qe]();else if(t){if(this[ae]=!0,this[p]){this[Vi](t);let e=this[p];this[p]=void 0,this[qe](e)}else this[qe](t);for(;this[p]&&this[p]?.length>=512&&!this[$]&&!this[ti];){let e=this[p];this[p]=void 0,this[qe](e)}this[ae]=!1}(!this[p]||this[mt])&&this[Qe]()}[qe](t){let e=0,i=t.length;for(;e+512<=i&&!this[$]&&!this[ti];)switch(this[B]){case"begin":case"header":this[Vs](t,e),e+=512;break;case"ignore":case"body":e+=this[Ki](t,e);break;case"meta":e+=this[Ks](t,e);break;default:throw new Error("invalid state: "+this[B])}e{let t=s.length-1,e=-1;for(;t>-1&&s.charAt(t)==="/";)e=t,t--;return e===-1?s:s.slice(0,e)};var vn=s=>{let t=s.onReadEntry;s.onReadEntry=t?e=>{t(e),e.resume()}:e=>e.resume()},Qi=(s,t)=>{let e=new Map(t.map(n=>[ut(n),!0])),i=s.filter,r=(n,o="")=>{let h=o||kn(n).root||".",a;if(n===h)a=!1;else{let l=e.get(n);a=l!==void 0?l:r(Fn(n),h)}return e.set(n,a),a};s.filter=i?(n,o)=>i(n,o)&&r(ut(n)):n=>r(ut(n))},Mn=s=>{let t=new rt(s),e=s.file,i;try{i=Kt.openSync(e,"r");let r=Kt.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let e=new rt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("end",o),Kt.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},Ct=K(Mn,Bn,s=>new rt(s),s=>new rt(s),(s,t)=>{t?.length&&Qi(s,t),s.noResume||vn(s)});import ui from"fs";import X from"fs";import js from"path";var Ji=(s,t,e)=>(s&=4095,e&&(s=(s|384)&-19),t&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);import{win32 as Pn}from"node:path";var{isAbsolute:zn,parse:qs}=Pn,ce=s=>{let t="",e=qs(s);for(;zn(s)||e.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":e.root;s=s.slice(i.length),t+=i,e=qs(s)}return[t,s]};var ei=["|","<",">","?",":"],ji=ei.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),Un=new Map(ei.map((s,t)=>[s,ji[t]])),Hn=new Map(ji.map((s,t)=>[s,ei[t]])),ts=s=>ei.reduce((t,e)=>t.split(e).join(Un.get(e)),s),Qs=s=>ji.reduce((t,e)=>t.split(e).join(Hn.get(e)),s);var rr=(s,t)=>t?(s=f(s).replace(/^\.(\/|$)/,""),ut(t)+"/"+s):f(s),Wn=16*1024*1024,tr=Symbol("process"),er=Symbol("file"),ir=Symbol("directory"),is=Symbol("symlink"),sr=Symbol("hardlink"),fe=Symbol("header"),ii=Symbol("read"),ss=Symbol("lstat"),si=Symbol("onlstat"),rs=Symbol("onread"),ns=Symbol("onreadlink"),os=Symbol("openfile"),hs=Symbol("onopenfile"),pt=Symbol("close"),ri=Symbol("mode"),as=Symbol("awaitDrain"),es=Symbol("ondrain"),q=Symbol("prefix"),de=class extends A{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#t=!1;constructor(t,e={}){let i=se(e);super(),this.path=f(t),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||Wn,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=f(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?f(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,h]=ce(this.path);o&&typeof h=="string"&&(this.path=h,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=Qs(this.path.replaceAll(/\\/g,"/")),t=t.replaceAll(/\\/g,"/")),this.absolute=f(i.absolute||js.resolve(this.cwd,t)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[si](n):this[ss]()}warn(t,e,i={}){return Dt(this,t,e,i)}emit(t,...e){return t==="error"&&(this.#t=!0),super.emit(t,...e)}[ss](){X.lstat(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[si](e)})}[si](t){this.statCache.set(this.absolute,t),this.stat=t,t.isFile()||(t.size=0),this.type=Gn(t),this.emit("stat",t),this[tr]()}[tr](){switch(this.type){case"File":return this[er]();case"Directory":return this[ir]();case"SymbolicLink":return this[is]();default:return this.end()}}[ri](t){return Ji(t,this.type==="Directory",this.portable)}[q](t){return rr(t,this.prefix)}[fe](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this[ri](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let t=this.header?.block;if(!t)throw new Error("failed to encode header");super.write(t)}[ir](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[fe](),this.end()}[is](){X.readlink(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[ns](e)})}[ns](t){this.linkpath=f(t),this[fe](),this.end()}[sr](t){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=f(js.relative(this.cwd,t)),this.stat.size=0,this[fe](),this.end()}[er](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let t=`${this.stat.dev}:${this.stat.ino}`,e=this.linkCache.get(t);if(e?.indexOf(this.cwd)===0)return this[sr](e);this.linkCache.set(t,this.absolute)}if(this[fe](),this.stat.size===0)return this.end();this[os]()}[os](){X.open(this.absolute,"r",(t,e)=>{if(t)return this.emit("error",t);this[hs](e)})}[hs](t){if(this.fd=t,this.#t)return this[pt]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let e=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(e),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[ii]()}[ii](){let{fd:t,buf:e,offset:i,length:r,pos:n}=this;if(t===void 0||e===void 0)throw new Error("cannot read file without first opening");X.read(t,e,i,r,n,(o,h)=>{if(o)return this[pt](()=>this.emit("error",o));this[rs](h)})}[pt](t=()=>{}){this.fd!==void 0&&X.close(this.fd,t)}[rs](t){if(t<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(t>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(t===this.remain)for(let r=t;rthis[es]())}[as](t){this.once("drain",t)}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this.blockRemaint?this.emit("error",t):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[ii]()}},ni=class extends de{sync=!0;[ss](){this[si](X.lstatSync(this.absolute))}[is](){this[ns](X.readlinkSync(this.absolute))}[os](){this[hs](X.openSync(this.absolute,"r"))}[ii](){let t=!0;try{let{fd:e,buf:i,offset:r,length:n,pos:o}=this;if(e===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let h=X.readSync(e,i,r,n,o);this[rs](h),t=!1}finally{if(t)try{this[pt](()=>{})}catch{}}}[as](t){t()}[pt](t=()=>{}){this.fd!==void 0&&X.closeSync(this.fd),t()}},oi=class extends A{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(t,e,i={}){return Dt(this,t,e,i)}constructor(t,e={}){let i=se(e);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=t;let{type:r}=t;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=f(t.path),this.mode=t.mode!==void 0?this[ri](t.mode):void 0,this.uid=this.portable?void 0:t.uid,this.gid=this.portable?void 0:t.gid,this.uname=this.portable?void 0:t.uname,this.gname=this.portable?void 0:t.gname,this.size=t.size,this.mtime=this.noMtime?void 0:i.mtime||t.mtime,this.atime=this.portable?void 0:t.atime,this.ctime=this.portable?void 0:t.ctime,this.linkpath=t.linkpath!==void 0?f(t.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[h,a]=ce(this.path);h&&typeof a=="string"&&(this.path=a,n=h)}this.remain=t.size,this.blockRemain=t.startBlockSize,this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),t.pipe(this)}[q](t){return rr(t,this.prefix)}[ri](t){return Ji(t,this.type==="Directory",this.portable)}write(t,e,i){typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8"));let r=t.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(t,i)}end(t,e,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,e??"utf8")),i&&this.once("finish",i),t?super.end(t,i):super.end(i),this}},Gn=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported";var hi=class s{tail;head;length=0;static create(t=[]){return new s(t)}constructor(t=[]){for(let e of t)this.push(e)}*[Symbol.iterator](){for(let t=this.head;t;t=t.next)yield t.value}removeNode(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");let e=t.next,i=t.prev;return e&&(e.prev=i),i&&(i.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=i),this.length--,t.next=void 0,t.prev=void 0,t.list=void 0,e}unshiftNode(t){if(t===this.head)return;t.list&&t.list.removeNode(t);let e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}pushNode(t){if(t===this.tail)return;t.list&&t.list.removeNode(t);let e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}push(...t){for(let e=0,i=t.length;e1)i=e;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=t(i,r.value,n),r=r.next;return i}reduceReverse(t,e){let i,r=this.tail;if(arguments.length>1)i=e;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=t(i,r.value,n),r=r.prev;return i}toArray(){let t=new Array(this.length);for(let e=0,i=this.head;i;e++)t[e]=i.value,i=i.next;return t}toArrayReverse(){let t=new Array(this.length);for(let e=0,i=this.tail;i;e++)t[e]=i.value,i=i.prev;return t}slice(t=0,e=this.length){e<0&&(e+=this.length),t<0&&(t+=this.length);let i=new s;if(ethis.length&&(e=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(e=this.length);let r=this.length,n=this.tail;for(;n&&r>e;r--)n=n.prev;for(;n&&r>t;r--,n=n.prev)i.push(n.value);return i}splice(t,e=0,...i){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);let r=this.head;for(let o=0;r&&o1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(t.gzip&&(typeof t.gzip!="object"&&(t.gzip={}),this.portable&&(t.gzip.portable=!0),this.zip=new ze(t.gzip)),t.brotli&&(typeof t.brotli!="object"&&(t.brotli={}),this.zip=new We(t.brotli)),t.zstd&&(typeof t.zstd!="object"&&(t.zstd={}),this.zip=new Ye(t.zstd)),!this.zip)throw new Error("impossible");let e=this.zip;e.on("data",i=>super.write(i)),e.on("end",()=>super.end()),e.on("drain",()=>this[fs]()),this.on("resume",()=>e.resume())}else this.on("drain",this[fs]);this.noDirRecurse=!!t.noDirRecurse,this.follow=!!t.follow,this.noMtime=!!t.noMtime,t.mtime&&(this.mtime=t.mtime),this.filter=typeof t.filter=="function"?t.filter:()=>!0,this[W]=new hi,this[G]=0,this.jobs=Number(t.jobs)||4,this[Ee]=!1,this[ue]=!1}[lr](t){return super.write(t)}add(t){return this.write(t),this}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&this.add(t),this[ue]=!0,this[Ft](),i&&i(),this}write(t){if(this[ue])throw new Error("write after end");return typeof t=="string"?this[ci](t):this[or](t),this.flowing}[or](t){let e=f(ar.resolve(this.cwd,t.path));if(!this.filter(t.path,t))t.resume();else{let i=new pi(t.path,e);i.entry=new oi(t,this[cs](i)),i.entry.on("end",()=>this[ls](i)),this[G]+=1,this[W].push(i)}this[Ft]()}[ci](t){let e=f(ar.resolve(this.cwd,t));this[W].push(new pi(t,e)),this[Ft]()}[ds](t){t.pending=!0,this[G]+=1;let e=this.follow?"stat":"lstat";ui[e](t.absolute,(i,r)=>{t.pending=!1,this[G]-=1,i?this.emit("error",i):this[li](t,r)})}[li](t,e){if(this.statCache.set(t.absolute,e),t.stat=e,!this.filter(t.path,e))t.ignore=!0;else if(e.isFile()&&e.nlink>1&&!this.linkCache.get(`${e.dev}:${e.ino}`)&&!this.sync)if(t===this[Et])this[ai](t);else{let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);r?r.push(t):this[pe].set(i,[t]),t.pendingLink=!0,t.pending=!0}this[Ft]()}[ms](t){t.pending=!0,this[G]+=1,ui.readdir(t.absolute,(e,i)=>{if(t.pending=!1,this[G]-=1,e)return this.emit("error",e);this[fi](t,i)})}[fi](t,e){this.readdirCache.set(t.absolute,e),t.readdir=e,this[Ft]()}[Ft](){if(!this[Ee]){this[Ee]=!0;for(let t=this[W].head;t&&this[G]1){let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);if(r){this[pe].delete(i);for(let n of r)n.pending=!1,this[ai](n)}}this[Ft]()}[ai](t){if(t.pending&&t.pendingLink&&t===this[Et]&&(t.pending=!1,t.pendingLink=!1),!t.pending){if(t.entry){t===this[Et]&&!t.piped&&this[di](t);return}if(!t.stat){let e=this.statCache.get(t.absolute);e?this[li](t,e):this[ds](t)}if(t.stat&&!t.ignore){if(!this.noDirRecurse&&t.stat.isDirectory()&&!t.readdir){let e=this.readdirCache.get(t.absolute);if(e?this[fi](t,e):this[ms](t),!t.readdir)return}if(t.entry=this[hr](t),!t.entry){t.ignore=!0;return}t===this[Et]&&!t.piped&&this[di](t)}}}[cs](t){return{onwarn:(e,i,r)=>this.warn(e,i,r),noPax:this.noPax,cwd:this.cwd,absolute:t.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[hr](t){this[G]+=1;try{return new this[mi](t.path,this[cs](t)).on("end",()=>this[ls](t)).on("error",i=>this.emit("error",i))}catch(e){this.emit("error",e)}}[fs](){this[Et]&&this[Et].entry&&this[Et].entry.resume()}[di](t){t.piped=!0,t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)});let e=t.entry,i=this.zip;if(!e)throw new Error("cannot pipe without source");i?e.on("data",r=>{i.write(r)||e.pause()}):e.on("data",r=>{super.write(r)||e.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(t,e,i={}){Dt(this,t,e,i)}},kt=class extends wt{sync=!0;constructor(t){super(t),this[mi]=ni}pause(){}resume(){}[ds](t){let e=this.follow?"statSync":"lstatSync";this[li](t,ui[e](t.absolute))}[ms](t){this[fi](t,ui.readdirSync(t.absolute))}[di](t){let e=t.entry,i=this.zip;if(t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)}),!e)throw new Error("Cannot pipe without source");i?e.on("data",r=>{i.write(r)}):e.on("data",r=>{super[lr](r)})}};var Vn=(s,t)=>{let e=new kt(s),i=new Wt(s.file,{mode:s.mode||438});e.pipe(i),fr(e,t)},$n=(s,t)=>{let e=new wt(s),i=new et(s.file,{mode:s.mode||438});e.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),e.on("error",o)});return dr(e,t).catch(n=>e.emit("error",n)),r},fr=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:cr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},dr=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:cr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(e);s.end()},Xn=(s,t)=>{let e=new kt(s);return fr(e,t),e},qn=(s,t)=>{let e=new wt(s);return dr(e,t).catch(i=>e.emit("error",i)),e},Qn=K(Vn,$n,Xn,qn,(s,t)=>{if(!t?.length)throw new TypeError("no paths specified to add to archive")});import Br from"node:fs";import co from"node:assert";import{randomBytes as Mr}from"node:crypto";import m from"node:fs";import R from"node:path";import pr from"fs";var Jn=process.env.__FAKE_PLATFORM__||process.platform,Er=Jn==="win32",{O_CREAT:wr,O_NOFOLLOW:mr,O_TRUNC:Sr,O_WRONLY:yr}=pr.constants,Rr=Number(process.env.__FAKE_FS_O_FILENAME__)||pr.constants.UV_FS_O_FILEMAP||0,jn=Er&&!!Rr,to=512*1024,eo=Rr|Sr|wr|yr,ur=!Er&&typeof mr=="number"?mr|Sr|wr|yr:null,us=ur!==null?()=>ur:jn?s=>s"w";import wi from"node:fs";import we from"node:path";var ps=(s,t,e)=>{try{return wi.lchownSync(s,t,e)}catch(i){if(i?.code!=="ENOENT")throw i}},Ei=(s,t,e,i)=>{wi.lchown(s,t,e,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},io=(s,t,e,i,r)=>{if(t.isDirectory())Es(we.resolve(s,t.name),e,i,n=>{if(n)return r(n);let o=we.resolve(s,t.name);Ei(o,e,i,r)});else{let n=we.resolve(s,t.name);Ei(n,e,i,r)}},Es=(s,t,e,i)=>{wi.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return Ei(s,t,e,i);let o=n.length,h=null,a=l=>{if(!h){if(l)return i(h=l);if(--o===0)return Ei(s,t,e,i)}};for(let l of n)io(s,l,t,e,a)})},so=(s,t,e,i)=>{t.isDirectory()&&ws(we.resolve(s,t.name),e,i),ps(we.resolve(s,t.name),e,i)},ws=(s,t,e)=>{let i;try{i=wi.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return ps(s,t,e);throw n}for(let r of i)so(s,r,t,e);return ps(s,t,e)};import k from"node:fs";import ro from"node:fs/promises";import Si from"node:path";var Se=class extends Error{path;code;syscall="chdir";constructor(t,e){super(`${e}: Cannot cd into '${t}'`),this.path=t,this.code=e}get name(){return"CwdError"}};var St=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(t,e){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=t,this.path=e}get name(){return"SymlinkError"}};var no=(s,t)=>{k.stat(s,(e,i)=>{(e||!i.isDirectory())&&(e=new Se(s,e?.code||"ENOTDIR")),t(e)})},gr=(s,t,e)=>{s=f(s);let i=t.umask??18,r=t.mode|448,n=(r&i)!==0,o=t.uid,h=t.gid,a=typeof o=="number"&&typeof h=="number"&&(o!==t.processUid||h!==t.processGid),l=t.preserve,c=t.unlink,d=f(t.cwd),S=(E,x)=>{E?e(E):x&&a?Es(x,o,h,Le=>S(Le)):n?k.chmod(s,r,e):e()};if(s===d)return no(s,S);if(l)return ro.mkdir(s,{mode:r,recursive:!0}).then(E=>S(null,E??void 0),S);let D=f(Si.relative(d,s)).split("/");Ss(d,D,r,c,d,void 0,S)},Ss=(s,t,e,i,r,n,o)=>{if(t.length===0)return o(null,n);let h=t.shift(),a=f(Si.resolve(s+"/"+h));k.mkdir(a,e,br(a,t,e,i,r,n,o))},br=(s,t,e,i,r,n,o)=>h=>{h?k.lstat(s,(a,l)=>{if(a)a.path=a.path&&f(a.path),o(a);else if(l.isDirectory())Ss(s,t,e,i,r,n,o);else if(i)k.unlink(s,c=>{if(c)return o(c);k.mkdir(s,e,br(s,t,e,i,r,n,o))});else{if(l.isSymbolicLink())return o(new St(s,s+"/"+t.join("/")));o(h)}}):(n=n||s,Ss(s,t,e,i,r,n,o))},oo=s=>{let t=!1,e;try{t=k.statSync(s).isDirectory()}catch(i){e=i?.code}finally{if(!t)throw new Se(s,e??"ENOTDIR")}},_r=(s,t)=>{s=f(s);let e=t.umask??18,i=t.mode|448,r=(i&e)!==0,n=t.uid,o=t.gid,h=typeof n=="number"&&typeof o=="number"&&(n!==t.processUid||o!==t.processGid),a=t.preserve,l=t.unlink,c=f(t.cwd),d=E=>{E&&h&&ws(E,n,o),r&&k.chmodSync(s,i)};if(s===c)return oo(c),d();if(a)return d(k.mkdirSync(s,{mode:i,recursive:!0})??void 0);let T=f(Si.relative(c,s)).split("/"),D;for(let E=T.shift(),x=c;E&&(x+="/"+E);E=T.shift()){x=f(Si.resolve(x));try{k.mkdirSync(x,i),D=D||x}catch{let Le=k.lstatSync(x);if(Le.isDirectory())continue;if(l){k.unlinkSync(x),k.mkdirSync(x,i),D=D||x;continue}else if(Le.isSymbolicLink())return new St(x,x+"/"+T.join("/"))}}return d(D)};import{join as xr}from"node:path";var ys=Object.create(null),Or=1e4,Vt=new Set,Tr=s=>{Vt.has(s)?Vt.delete(s):ys[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),Vt.add(s);let t=ys[s],e=Vt.size-Or;if(e>Or/10){for(let i of Vt)if(Vt.delete(i),delete ys[i],--e<=0)break}return t};var ho=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,ao=ho==="win32",lo=s=>s.split("/").slice(0,-1).reduce((e,i)=>{let r=e.at(-1);return r!==void 0&&(i=xr(r,i)),e.push(i||"/"),e},[]),yi=class{#t=new Map;#i=new Map;#s=new Set;reserve(t,e){t=ao?["win32 parallelization disabled"]:t.map(r=>ut(xr(Tr(r))));let i=new Set(t.map(r=>lo(r)).reduce((r,n)=>r.concat(n)));this.#i.set(e,{dirs:i,paths:t});for(let r of t){let n=this.#t.get(r);n?n.push(e):this.#t.set(r,[e])}for(let r of i){let n=this.#t.get(r);if(!n)this.#t.set(r,[new Set([e])]);else{let o=n.at(-1);o instanceof Set?o.add(e):n.push(new Set([e]))}}return this.#r(e)}#n(t){let e=this.#i.get(t);if(!e)throw new Error("function does not have any path reservations");return{paths:e.paths.map(i=>this.#t.get(i)),dirs:[...e.dirs].map(i=>this.#t.get(i))}}check(t){let{paths:e,dirs:i}=this.#n(t);return e.every(r=>r&&r[0]===t)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(t))}#r(t){return this.#s.has(t)||!this.check(t)?!1:(this.#s.add(t),t(()=>this.#e(t)),!0)}#e(t){if(!this.#s.has(t))return!1;let e=this.#i.get(t);if(!e)throw new Error("invalid reservation");let{paths:i,dirs:r}=e,n=new Set;for(let o of i){let h=this.#t.get(o);if(!h||h?.[0]!==t)continue;let a=h[1];if(!a){this.#t.delete(o);continue}if(h.shift(),typeof a=="function")n.add(a);else for(let l of a)n.add(l)}for(let o of r){let h=this.#t.get(o),a=h?.[0];if(!(!h||!(a instanceof Set)))if(a.size===1&&h.length===1){this.#t.delete(o);continue}else if(a.size===1){h.shift();let l=h[0];typeof l=="function"&&n.add(l)}else a.delete(t)}return this.#s.delete(t),n.forEach(o=>this.#r(o)),!0}};var Lr=()=>process.umask();var Dr=Symbol("onEntry"),_s=Symbol("checkFs"),Nr=Symbol("checkFs2"),Os=Symbol("isReusable"),P=Symbol("makeFs"),Ts=Symbol("file"),xs=Symbol("directory"),gi=Symbol("link"),Ar=Symbol("symlink"),Ir=Symbol("hardlink"),Re=Symbol("ensureNoSymlink"),Cr=Symbol("unsupported"),Fr=Symbol("checkPath"),Rs=Symbol("stripAbsolutePath"),yt=Symbol("mkdir"),O=Symbol("onError"),Ri=Symbol("pending"),kr=Symbol("pend"),$t=Symbol("unpend"),gs=Symbol("ended"),bs=Symbol("maybeClose"),Ls=Symbol("skip"),ge=Symbol("doChown"),be=Symbol("uid"),_e=Symbol("gid"),Oe=Symbol("checkedCwd"),fo=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Te=fo==="win32",mo=1024,uo=(s,t)=>{if(!Te)return m.unlink(s,t);let e=s+".DELETE."+Mr(16).toString("hex");m.rename(s,e,i=>{if(i)return t(i);m.unlink(e,t)})},po=s=>{if(!Te)return m.unlinkSync(s);let t=s+".DELETE."+Mr(16).toString("hex");m.renameSync(s,t),m.unlinkSync(t)},vr=(s,t,e)=>s!==void 0&&s===s>>>0?s:t!==void 0&&t===t>>>0?t:e,Xt=class extends rt{[gs]=!1;[Oe]=!1;[Ri]=0;reservations=new yi;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(t={}){if(t.ondone=()=>{this[gs]=!0,this[bs]()},super(t),this.transform=t.transform,this.chmod=!!t.chmod,typeof t.uid=="number"||typeof t.gid=="number"){if(typeof t.uid!="number"||typeof t.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(t.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=t.uid,this.gid=t.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=t.preserveOwner===void 0&&typeof t.uid!="number"?process.getuid?.()===0:!!t.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof t.maxDepth=="number"?t.maxDepth:mo,this.forceChown=t.forceChown===!0,this.win32=!!t.win32||Te,this.newer=!!t.newer,this.keep=!!t.keep,this.noMtime=!!t.noMtime,this.preservePaths=!!t.preservePaths,this.unlink=!!t.unlink,this.cwd=f(R.resolve(t.cwd||process.cwd())),this.strip=Number(t.strip)||0,this.processUmask=this.chmod?typeof t.processUmask=="number"?t.processUmask:Lr():0,this.umask=typeof t.umask=="number"?t.umask:this.processUmask,this.dmode=t.dmode||511&~this.umask,this.fmode=t.fmode||438&~this.umask,this.on("entry",e=>this[Dr](e))}warn(t,e,i={}){return(t==="TAR_BAD_ARCHIVE"||t==="TAR_ABORT")&&(i.recoverable=!1),super.warn(t,e,i)}[bs](){this[gs]&&this[Ri]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[Rs](t,e){let i=t[e],{type:r}=t;if(!i||this.preservePaths)return!0;let[n,o]=ce(i),h=o.replaceAll(/\\/g,"/").split("/");if(h.includes("..")||Te&&/^[a-z]:\.\.$/i.test(h[0]??"")){if(e==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${e} contains '..'`,{entry:t,[e]:i}),!1;let a=R.posix.dirname(t.path),l=R.posix.normalize(R.posix.join(a,h.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${e} escapes extraction directory`,{entry:t,[e]:i}),!1}return n&&(t[e]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${e}`,{entry:t,[e]:i})),!0}[Fr](t){let e=f(t.path),i=e.split("/");if(this.strip){if(i.length=this.strip)t.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),t.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:t,path:e,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[Rs](t,"path")||!this[Rs](t,"linkpath"))return!1;if(t.absolute=R.isAbsolute(t.path)?f(R.resolve(t.path)):f(R.resolve(this.cwd,t.path)),!this.preservePaths&&typeof t.absolute=="string"&&t.absolute.indexOf(this.cwd+"/")!==0&&t.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:t,path:f(t.path),resolvedPath:t.absolute,cwd:this.cwd}),!1;if(t.absolute===this.cwd&&t.type!=="Directory"&&t.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=R.win32.parse(String(t.absolute));t.absolute=r+ts(String(t.absolute).slice(r.length));let{root:n}=R.win32.parse(t.path);t.path=n+ts(t.path.slice(n.length))}return!0}[Dr](t){if(!this[Fr](t))return t.resume();switch(co.equal(typeof t.absolute,"string"),t.type){case"Directory":case"GNUDumpDir":t.mode&&(t.mode=t.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[_s](t);default:return this[Cr](t)}}[O](t,e){t.name==="CwdError"?this.emit("error",t):(this.warn("TAR_ENTRY_ERROR",t,{entry:e}),this[$t](),e.resume())}[yt](t,e,i){gr(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e},i)}[ge](t){return this.forceChown||this.preserveOwner&&(typeof t.uid=="number"&&t.uid!==this.processUid||typeof t.gid=="number"&&t.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[be](t){return vr(this.uid,t.uid,this.processUid)}[_e](t){return vr(this.gid,t.gid,this.processGid)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=new et(String(t.absolute),{flags:us(t.size),mode:i,autoClose:!1});r.on("error",a=>{r.fd&&m.close(r.fd,()=>{}),r.write=()=>!0,this[O](a,t),e()});let n=1,o=a=>{if(a){r.fd&&m.close(r.fd,()=>{}),this[O](a,t),e();return}--n===0&&r.fd!==void 0&&m.close(r.fd,l=>{l?this[O](l,t):this[$t](),e()})};r.on("finish",()=>{let a=String(t.absolute),l=r.fd;if(typeof l=="number"&&t.mtime&&!this.noMtime){n++;let c=t.atime||new Date,d=t.mtime;m.futimes(l,c,d,S=>S?m.utimes(a,c,d,T=>o(T&&S)):o())}if(typeof l=="number"&&this[ge](t)){n++;let c=this[be](t),d=this[_e](t);typeof c=="number"&&typeof d=="number"&&m.fchown(l,c,d,S=>S?m.chown(a,c,d,T=>o(T&&S)):o())}o()});let h=this.transform&&this.transform(t)||t;h!==t&&(h.on("error",a=>{this[O](a,t),e()}),t.pipe(h)),h.pipe(r)}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode;this[yt](String(t.absolute),i,r=>{if(r){this[O](r,t),e();return}let n=1,o=()=>{--n===0&&(e(),this[$t](),t.resume())};t.mtime&&!this.noMtime&&(n++,m.utimes(String(t.absolute),t.atime||new Date,t.mtime,o)),this[ge](t)&&(n++,m.chown(String(t.absolute),Number(this[be](t)),Number(this[_e](t)),o)),o()})}[Cr](t){t.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${t.type}`,{entry:t}),t.resume()}[Ar](t,e){let i=f(R.relative(this.cwd,R.resolve(R.dirname(String(t.absolute)),String(t.linkpath)))).split("/");this[Re](t,this.cwd,i,()=>this[gi](t,String(t.linkpath),"symlink",e),r=>{this[O](r,t),e()})}[Ir](t,e){let i=f(R.resolve(this.cwd,String(t.linkpath))),r=f(String(t.linkpath)).split("/");this[Re](t,this.cwd,r,()=>this[gi](t,i,"link",e),n=>{this[O](n,t),e()})}[Re](t,e,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let h=R.resolve(e,o);m.lstat(h,(a,l)=>{if(a)return r();if(l?.isSymbolicLink())return n(new St(h,R.resolve(h,i.join("/"))));this[Re](t,h,i,r,n)})}[kr](){this[Ri]++}[$t](){this[Ri]--,this[bs]()}[Ls](t){this[$t](),t.resume()}[Os](t,e){return t.type==="File"&&!this.unlink&&e.isFile()&&e.nlink<=1&&!Te}[_s](t){this[kr]();let e=[t.path];t.linkpath&&e.push(t.linkpath),this.reservations.reserve(e,i=>this[Nr](t,i))}[Nr](t,e){let i=h=>{e(h)},r=()=>{this[yt](this.cwd,this.dmode,h=>{if(h){this[O](h,t),i();return}this[Oe]=!0,n()})},n=()=>{if(t.absolute!==this.cwd){let h=f(R.dirname(String(t.absolute)));if(h!==this.cwd)return this[yt](h,this.dmode,a=>{if(a){this[O](a,t),i();return}o()})}o()},o=()=>{m.lstat(String(t.absolute),(h,a)=>{if(a&&(this.keep||this.newer&&a.mtime>(t.mtime??a.mtime))){this[Ls](t),i();return}if(h||this[Os](t,a))return this[P](null,t,i);if(a.isDirectory()){if(t.type==="Directory"){let l=this.chmod&&t.mode&&(a.mode&4095)!==t.mode,c=d=>this[P](d??null,t,i);return l?m.chmod(String(t.absolute),Number(t.mode),c):c()}if(t.absolute!==this.cwd)return m.rmdir(String(t.absolute),l=>this[P](l??null,t,i))}if(t.absolute===this.cwd)return this[P](null,t,i);uo(String(t.absolute),l=>this[P](l??null,t,i))})};this[Oe]?n():r()}[P](t,e,i){if(t){this[O](t,e),i();return}switch(e.type){case"File":case"OldFile":case"ContiguousFile":return this[Ts](e,i);case"Link":return this[Ir](e,i);case"SymbolicLink":return this[Ar](e,i);case"Directory":case"GNUDumpDir":return this[xs](e,i)}}[gi](t,e,i,r){m[i](e,String(t.absolute),n=>{n?this[O](n,t):(this[$t](),t.resume()),r()})}},ye=s=>{try{return[null,s()]}catch(t){return[t,null]}},xe=class extends Xt{sync=!0;[P](t,e){return super[P](t,e,()=>{})}[_s](t){if(!this[Oe]){let n=this[yt](this.cwd,this.dmode);if(n)return this[O](n,t);this[Oe]=!0}if(t.absolute!==this.cwd){let n=f(R.dirname(String(t.absolute)));if(n!==this.cwd){let o=this[yt](n,this.dmode);if(o)return this[O](o,t)}}let[e,i]=ye(()=>m.lstatSync(String(t.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(t.mtime??i.mtime)))return this[Ls](t);if(e||this[Os](t,i))return this[P](null,t);if(i.isDirectory()){if(t.type==="Directory"){let o=this.chmod&&t.mode&&(i.mode&4095)!==t.mode,[h]=o?ye(()=>{m.chmodSync(String(t.absolute),Number(t.mode))}):[];return this[P](h,t)}let[n]=ye(()=>m.rmdirSync(String(t.absolute)));this[P](n,t)}let[r]=t.absolute===this.cwd?[]:ye(()=>po(String(t.absolute)));this[P](r,t)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=h=>{let a;try{m.closeSync(n)}catch(l){a=l}(h||a)&&this[O](h||a,t),e()},n;try{n=m.openSync(String(t.absolute),us(t.size),i)}catch(h){return r(h)}let o=this.transform&&this.transform(t)||t;o!==t&&(o.on("error",h=>this[O](h,t)),t.pipe(o)),o.on("data",h=>{try{m.writeSync(n,h,0,h.length)}catch(a){r(a)}}),o.on("end",()=>{let h=null;if(t.mtime&&!this.noMtime){let a=t.atime||new Date,l=t.mtime;try{m.futimesSync(n,a,l)}catch(c){try{m.utimesSync(String(t.absolute),a,l)}catch{h=c}}}if(this[ge](t)){let a=this[be](t),l=this[_e](t);try{m.fchownSync(n,Number(a),Number(l))}catch(c){try{m.chownSync(String(t.absolute),Number(a),Number(l))}catch{h=h||c}}}r(h)})}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode,r=this[yt](String(t.absolute),i);if(r){this[O](r,t),e();return}if(t.mtime&&!this.noMtime)try{m.utimesSync(String(t.absolute),t.atime||new Date,t.mtime)}catch{}if(this[ge](t))try{m.chownSync(String(t.absolute),Number(this[be](t)),Number(this[_e](t)))}catch{}e(),t.resume()}[yt](t,e){try{return _r(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e})}catch(i){return i}}[Re](t,e,i,r,n){if(this.preservePaths||i.length===0)return r();let o=e;for(let h of i){o=R.resolve(o,h);let[a,l]=ye(()=>m.lstatSync(o));if(a)return r();if(l.isSymbolicLink())return n(new St(o,R.resolve(e,i.join("/"))))}r()}[gi](t,e,i,r){let n=`${i}Sync`;try{m[n](e,String(t.absolute)),r(),t.resume()}catch(o){return this[O](o,t)}}};var Eo=s=>{let t=new xe(s),e=s.file,i=Br.statSync(e),r=s.maxReadSize||16*1024*1024;new Be(e,{readSize:r,size:i.size}).pipe(t)},wo=(s,t)=>{let e=new Xt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("close",o),Br.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},So=K(Eo,wo,s=>new xe(s),s=>new Xt(s),(s,t)=>{t?.length&&Qi(s,t)});import v from"node:fs";import Pr from"node:path";var yo=(s,t)=>{let e=new kt(s),i=!0,r,n;try{try{r=v.openSync(s.file,"r+")}catch(a){if(a?.code==="ENOENT")r=v.openSync(s.file,"w+");else throw a}let o=v.fstatSync(r),h=Buffer.alloc(512);t:for(n=0;no.size)break;n+=l,s.mtimeCache&&a.mtime&&s.mtimeCache.set(String(a.path),a.mtime)}i=!1,Ro(s,e,n,r,t)}finally{if(i)try{v.closeSync(r)}catch{}}},Ro=(s,t,e,i,r)=>{let n=new Wt(s.file,{fd:i,start:e});t.pipe(n),bo(t,r)},go=(s,t)=>{t=Array.from(t);let e=new wt(s),i=(n,o,h)=>{let a=(T,D)=>{T?v.close(n,E=>h(T)):h(null,D)},l=0;if(o===0)return a(null,0);let c=0,d=Buffer.alloc(512),S=(T,D)=>{if(T||D===void 0)return a(T);if(c+=D,c<512&&D)return v.read(n,d,c,d.length-c,l+c,S);if(l===0&&d[0]===31&&d[1]===139)return a(new Error("cannot append to compressed archives"));if(c<512)return a(null,l);let E=new F(d);if(!E.cksumValid)return a(null,l);let x=512*Math.ceil((E.size??0)/512);if(l+x+512>o||(l+=x+512,l>=o))return a(null,l);s.mtimeCache&&E.mtime&&s.mtimeCache.set(String(E.path),E.mtime),c=0,v.read(n,d,0,512,l,S)};v.read(n,d,0,512,l,S)};return new Promise((n,o)=>{e.on("error",o);let h="r+",a=(l,c)=>{if(l&&l.code==="ENOENT"&&h==="r+")return h="w+",v.open(s.file,h,a);if(l||!c)return o(l);v.fstat(c,(d,S)=>{if(d)return v.close(c,()=>o(d));i(c,S.size,(T,D)=>{if(T)return o(T);let E=new et(s.file,{fd:c,start:D});e.pipe(E),E.on("error",o),E.on("close",n),_o(e,t)})})};v.open(s.file,h,a)})},bo=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:Pr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},_o=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:Pr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e);s.end()},vt=K(yo,go,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,t)=>{if(!Bs(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!t?.length)throw new TypeError("no paths specified to add/replace")});var Oo=K(vt.syncFile,vt.asyncFile,vt.syncNoFile,vt.asyncNoFile,(s,t=[])=>{vt.validate?.(s,t),To(s)}),To=s=>{let t=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=t?(e,i)=>t(e,i)&&!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0)):(e,i)=>!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0))};export{F as Header,wt as Pack,pi as PackJob,kt as PackSync,rt as Parser,ft as Pax,$e as ReadEntry,Xt as Unpack,xe as UnpackSync,de as WriteEntry,ni as WriteEntrySync,oi as WriteEntryTar,Qn as c,Qn as create,So as extract,Qi as filesFilter,Ct as list,vt as r,vt as replace,Ct as t,Hi as types,Oo as u,Oo as update,So as x}; //# sourceMappingURL=index.min.js.map diff --git a/deps/npm/node_modules/tar/dist/esm/normalize-windows-path.js b/deps/npm/node_modules/tar/dist/esm/normalize-windows-path.js index bde0c962344..cc75178aa9c 100644 --- a/deps/npm/node_modules/tar/dist/esm/normalize-windows-path.js +++ b/deps/npm/node_modules/tar/dist/esm/normalize-windows-path.js @@ -4,6 +4,6 @@ // so that we can use / as our one and only directory separator char. const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; export const normalizeWindowsPath = platform !== 'win32' ? - (p) => p - : (p) => p && p.replaceAll(/\\/g, '/'); + (p) => String(p) + : (p) => String(p).replaceAll(/\\/g, '/'); //# sourceMappingURL=normalize-windows-path.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/tar/dist/esm/pack.js b/deps/npm/node_modules/tar/dist/esm/pack.js index 6eae0ee73bd..ec441138051 100644 --- a/deps/npm/node_modules/tar/dist/esm/pack.js +++ b/deps/npm/node_modules/tar/dist/esm/pack.js @@ -26,13 +26,12 @@ export class PackJob { import { Minipass } from 'minipass'; import * as zlib from 'minizlib'; import { Yallist } from 'yallist'; -import { ReadEntry } from './read-entry.js'; import { warnMethod } from './warn-method.js'; const EOF = Buffer.alloc(1024); const ONSTAT = Symbol('onStat'); const ENDED = Symbol('ended'); const QUEUE = Symbol('queue'); -const PENDINGLINKS = Symbol('queue'); +const PENDINGLINKS = Symbol('pendingLinks'); const CURRENT = Symbol('current'); const PROCESS = Symbol('process'); const PROCESSING = Symbol('processing'); @@ -190,11 +189,11 @@ export class Pack extends Minipass { if (this[ENDED]) { throw new Error('write after end'); } - if (path instanceof ReadEntry) { - this[ADDTARENTRY](path); + if (typeof path === 'string') { + this[ADDFSENTRY](path); } else { - this[ADDFSENTRY](path); + this[ADDTARENTRY](path); } return this.flowing; } diff --git a/deps/npm/node_modules/tar/dist/esm/parse.js b/deps/npm/node_modules/tar/dist/esm/parse.js index 02454bfd2c4..fb303a5171b 100644 --- a/deps/npm/node_modules/tar/dist/esm/parse.js +++ b/deps/npm/node_modules/tar/dist/esm/parse.js @@ -57,6 +57,10 @@ const SAW_VALID_ENTRY = Symbol('sawValidEntry'); const SAW_NULL_BLOCK = Symbol('sawNullBlock'); const SAW_EOF = Symbol('sawEOF'); const CLOSESTREAM = Symbol('closeStream'); +const MAX_DECOMPRESSION_RATIO = 1000; +const COMPRESSEDBYTESREAD = Symbol('compressedBytesRead'); +const DECOMPRESSEDBYTESREAD = Symbol('decompressedBytesRead'); +const CHECKDECOMPRESSIONRATIO = Symbol('checkDecompressionRatio'); const noop = () => true; export class Parser extends EE { file; @@ -65,6 +69,7 @@ export class Parser extends EE { filter; brotli; zstd; + maxDecompressionRatio; writable = true; readable = false; [QUEUE] = []; @@ -84,6 +89,8 @@ export class Parser extends EE { [WRITING] = false; [CONSUMING] = false; [EMITTEDEND] = false; + [COMPRESSEDBYTESREAD] = 0; + [DECOMPRESSEDBYTESREAD] = 0; constructor(opt = {}) { super(); this.file = opt.file || ''; @@ -106,6 +113,10 @@ export class Parser extends EE { }); } this.strict = !!opt.strict; + this.maxDecompressionRatio = + typeof opt.maxDecompressionRatio === 'number' ? + opt.maxDecompressionRatio + : MAX_DECOMPRESSION_RATIO; this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize; this.filter = typeof opt.filter === 'function' ? opt.filter : noop; // Unlike gzip, brotli doesn't have any magic bytes to identify it @@ -359,11 +370,23 @@ export class Parser extends EE { } } abort(error) { + if (this[ABORTED]) { + return; + } this[ABORTED] = true; this.emit('abort', error); // always throws, even in non-strict mode this.warn('TAR_ABORT', error, { recoverable: false }); } + [CHECKDECOMPRESSIONRATIO](chunk) { + this[DECOMPRESSEDBYTESREAD] += chunk.length; + const ratio = this[DECOMPRESSEDBYTESREAD] / this[COMPRESSEDBYTESREAD]; + if (ratio > this.maxDecompressionRatio) { + this.abort(new Error(`max decompression ratio exceeded: ${ratio.toFixed(2)} > ${this.maxDecompressionRatio}`)); + return false; + } + return true; + } write(chunk, encoding, cb) { if (typeof encoding === 'function') { cb = encoding; @@ -447,13 +470,22 @@ export class Parser extends EE { this[UNZIP] === undefined ? new Unzip({}) : isZstd ? new ZstdDecompress({}) : new BrotliDecompress({}); - this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)); - this[UNZIP].on('error', er => this.abort(er)); + this[UNZIP].on('data', chunk => { + if (this[CHECKDECOMPRESSIONRATIO](chunk)) { + this[CONSUMECHUNK](chunk); + } + }); + this[UNZIP].on('error', er => { + if (!this[ABORTED]) { + this.abort(er); + } + }); this[UNZIP].on('end', () => { this[ENDED] = true; this[CONSUMECHUNK](); }); this[WRITING] = true; + this[COMPRESSEDBYTESREAD] += chunk.length; const ret = !!this[UNZIP][ended ? 'end' : 'write'](chunk); this[WRITING] = false; cb?.(); @@ -462,6 +494,7 @@ export class Parser extends EE { } this[WRITING] = true; if (this[UNZIP]) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); } else { @@ -492,7 +525,7 @@ export class Parser extends EE { !this[CONSUMING]) { this[EMITTEDEND] = true; const entry = this[WRITEENTRY]; - if (entry && entry.blockRemain) { + if (entry?.blockRemain) { // truncated, likely a damaged file const have = this[BUFFER] ? this[BUFFER].length : 0; this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${entry.blockRemain} more bytes, only ${have} available)`, { entry }); @@ -586,8 +619,10 @@ export class Parser extends EE { if (!this[ABORTED]) { if (this[UNZIP]) { /* c8 ignore start */ - if (chunk) + if (chunk) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); + } /* c8 ignore stop */ this[UNZIP].end(); } diff --git a/deps/npm/node_modules/tar/dist/esm/pax.js b/deps/npm/node_modules/tar/dist/esm/pax.js index 832808f344d..907193a4b93 100644 --- a/deps/npm/node_modules/tar/dist/esm/pax.js +++ b/deps/npm/node_modules/tar/dist/esm/pax.js @@ -143,12 +143,36 @@ const parseKVLine = (set, line) => { return set; } const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1'); - const v = kv.join('='); - set[k] = - /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? - new Date(Number(v) * 1000) - : /^[0-9]+$/.test(v) ? +v - : v; + const v = kv.join('=').replace(/\0.*/, ''); + switch (k) { + case 'path': + case 'linkpath': + case 'type': + case 'charset': + case 'comment': + case 'gname': + case 'uname': + set[k] = v; + break; + case 'ctime': + case 'atime': + case 'mtime': + set[k] = new Date(Number(v) * 1000); + break; + case 'size': + const s = +v; + if (s >= 0) + set[k] = s; + break; + case 'gid': + case 'uid': + case 'dev': + case 'ino': + case 'nlink': + case 'mode': + set[k] = +v; + break; + } return set; }; //# sourceMappingURL=pax.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/tar/dist/esm/types.js b/deps/npm/node_modules/tar/dist/esm/types.js index 27b982ae1e0..c33a6a4c5e1 100644 --- a/deps/npm/node_modules/tar/dist/esm/types.js +++ b/deps/npm/node_modules/tar/dist/esm/types.js @@ -1,5 +1,25 @@ export const isCode = (c) => name.has(c); export const isName = (c) => code.has(c); +/** + * types that are a normal file system entry, not metadata. + * + * These can be the subject of extended/globalExtended headers, long path + * names, long linkpath names, etc. + * + * Any other types are meta, and cannot be targetted by extended PAX headers. + */ +export const normalFsTypes = new Set([ + '0', + '', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + 'D', +]); // map types from key to human-friendly name export const name = new Map([ ['0', 'File'], diff --git a/deps/npm/node_modules/tar/dist/esm/unpack.js b/deps/npm/node_modules/tar/dist/esm/unpack.js index 46c53db2ad5..3bbdad99bcd 100644 --- a/deps/npm/node_modules/tar/dist/esm/unpack.js +++ b/deps/npm/node_modules/tar/dist/esm/unpack.js @@ -146,7 +146,7 @@ export class Unpack extends Parser { // default true for root this.preserveOwner = opt.preserveOwner === undefined && typeof opt.uid !== 'number' ? - !!(process.getuid && process.getuid() === 0) + !!(process.getuid?.() === 0) : !!opt.preserveOwner; this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? @@ -367,7 +367,7 @@ export class Unpack extends Parser { } } [MKDIR](dir, mode, cb) { - mkdir(normalizeWindowsPath(dir), { + void mkdir(normalizeWindowsPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, diff --git a/deps/npm/node_modules/tar/package.json b/deps/npm/node_modules/tar/package.json index 2ad5841e328..9d082e44049 100644 --- a/deps/npm/node_modules/tar/package.json +++ b/deps/npm/node_modules/tar/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter", "name": "tar", "description": "tar for node", - "version": "7.5.15", + "version": "7.5.19", "repository": { "type": "git", "url": "https://github.com/isaacs/node-tar.git" @@ -31,20 +31,20 @@ "yallist": "^5.0.0" }, "devDependencies": { - "@types/node": "^25.5.0", + "@types/node": "^25.9.1", "chmodr": "^2.0.2", "end-of-stream": "^1.4.3", - "esbuild": "^0.27.4", + "esbuild": "^0.28.0", "events-to-array": "^2.0.3", "mutate-fs": "^2.1.1", "nock": "^13.5.4", - "oxlint": "^1.57.0", - "oxlint-tsgolint": "^0.17.3", - "prettier": "^3.8.1", + "oxlint": "^1.67.0", + "oxlint-tsgolint": "^0.23.0", + "prettier": "^3.8.3", "rimraf": "^6.1.2", - "tap": "^21.6.2", - "tshy": "^3.3.2", - "typedoc": "^0.28.18" + "tap": "^21.7.4", + "tshy": "^4.1.2", + "typedoc": "^0.28.19" }, "license": "BlueOak-1.0.0", "engines": { @@ -85,7 +85,8 @@ "./header": "./src/header.ts", "./pax": "./src/pax.ts", "./types": "./src/types.ts" - } + }, + "selfLink": false }, "exports": { "./package.json": "./package.json", diff --git a/deps/npm/node_modules/tinyglobby/dist/index.cjs b/deps/npm/node_modules/tinyglobby/dist/index.cjs index 5badacb548b..c93b23393d3 100644 --- a/deps/npm/node_modules/tinyglobby/dist/index.cjs +++ b/deps/npm/node_modules/tinyglobby/dist/index.cjs @@ -26,10 +26,11 @@ let path = require("path"); let url = require("url"); let fdir = require("fdir"); let picomatch = require("picomatch"); -picomatch = __toESM(picomatch); +picomatch = __toESM(picomatch, 1); //#region src/utils.ts const isReadonlyArray = Array.isArray; const BACKSLASHES = /\\/g; +const DRIVE_RELATIVE_PATH = /^[A-Za-z]:$/; const isWin = process.platform === "win32"; const ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/; function getPartialMatcher(patterns, options = {}) { @@ -96,18 +97,21 @@ function buildRelative(cwd, root) { return p[p.length - 1] === "/" && result !== "" ? `${result}/` : result || "."; }; } +function ensureNonDriveRelativePath(path$1) { + return path$1.replace(DRIVE_RELATIVE_PATH, (match) => `${match}/`); +} const splitPatternOptions = { parts: true }; -function splitPattern(path$1) { +function splitPattern(path$2) { var _result$parts; - const result = picomatch.default.scan(path$1, splitPatternOptions); - return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path$1]; + const result = picomatch.default.scan(path$2, splitPatternOptions); + return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path$2]; } const ESCAPED_WIN32_BACKSLASHES = /\\(?![()[\]{}!+@])/g; -function convertPosixPathToPattern(path$2) { - return escapePosixPath(path$2); +function convertPosixPathToPattern(path$3) { + return escapePosixPath(path$3); } -function convertWin32PathToPattern(path$3) { - return escapeWin32Path(path$3).replace(ESCAPED_WIN32_BACKSLASHES, "/"); +function convertWin32PathToPattern(path$4) { + return escapeWin32Path(path$4).replace(ESCAPED_WIN32_BACKSLASHES, "/"); } /** * Converts a path to a pattern depending on the platform. @@ -118,8 +122,8 @@ function convertWin32PathToPattern(path$3) { const convertPathToPattern = isWin ? convertWin32PathToPattern : convertPosixPathToPattern; const POSIX_UNESCAPED_GLOB_SYMBOLS = /(? path$4.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"); -const escapeWin32Path = (path$5) => path$5.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +const escapePosixPath = (path$5) => path$5.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +const escapeWin32Path = (path$6) => path$6.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"); /** * Escapes a path's special characters depending on the platform. * @see {@link https://superchupu.dev/tinyglobby/documentation#escapePath} @@ -173,7 +177,7 @@ function normalizePattern(pattern, opts, props, isIgnore) { } const potentialRoot = path.posix.join(cwd, parentDir.slice(i * 3)); if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) { - props.root = potentialRoot; + props.root = ensureNonDriveRelativePath(potentialRoot); props.depthOffset = -n + i; } } @@ -193,7 +197,7 @@ function normalizePattern(pattern, opts, props, isIgnore) { } props.depthOffset = newCommonPath.length; props.commonPath = newCommonPath; - props.root = newCommonPath.length > 0 ? path.posix.join(cwd, ...newCommonPath) : cwd; + props.root = ensureNonDriveRelativePath(newCommonPath.length > 0 ? path.posix.join(cwd, ...newCommonPath) : cwd); } return result; } @@ -286,18 +290,15 @@ function formatPaths(paths, mapper) { } const defaultOptions = { caseSensitiveMatch: true, - cwd: process.cwd(), debug: !!process.env.TINYGLOBBY_DEBUG, expandDirectories: true, followSymbolicLinks: true, onlyFiles: true }; function getOptions(options) { - const opts = { - ...defaultOptions, - ...options - }; - opts.cwd = (opts.cwd instanceof URL ? (0, url.fileURLToPath)(opts.cwd) : (0, path.resolve)(opts.cwd)).replace(BACKSLASHES, "/"); + const opts = Object.assign({}, options); + for (const key in defaultOptions) if (opts[key] === void 0) Object.assign(opts, { [key]: defaultOptions[key] }); + opts.cwd = (opts.cwd instanceof URL ? (0, url.fileURLToPath)(opts.cwd) : (0, path.resolve)(opts.cwd || process.cwd())).replace(BACKSLASHES, "/"); opts.ignore = ensureStringArray(opts.ignore); opts.fs && (opts.fs = { readdir: opts.fs.readdir || fs.readdir, diff --git a/deps/npm/node_modules/tinyglobby/dist/index.d.cts b/deps/npm/node_modules/tinyglobby/dist/index.d.cts index 3e8e16aa2e9..b6e4902cd8f 100644 --- a/deps/npm/node_modules/tinyglobby/dist/index.d.cts +++ b/deps/npm/node_modules/tinyglobby/dist/index.d.cts @@ -145,4 +145,4 @@ declare function globSync(patterns: string | readonly string[], options?: Omit `${match}/`); +} const splitPatternOptions = { parts: true }; function splitPattern(path) { var _result$parts; @@ -149,7 +153,7 @@ function normalizePattern(pattern, opts, props, isIgnore) { } const potentialRoot = posix.join(cwd, parentDir.slice(i * 3)); if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) { - props.root = potentialRoot; + props.root = ensureNonDriveRelativePath(potentialRoot); props.depthOffset = -n + i; } } @@ -169,7 +173,7 @@ function normalizePattern(pattern, opts, props, isIgnore) { } props.depthOffset = newCommonPath.length; props.commonPath = newCommonPath; - props.root = newCommonPath.length > 0 ? posix.join(cwd, ...newCommonPath) : cwd; + props.root = ensureNonDriveRelativePath(newCommonPath.length > 0 ? posix.join(cwd, ...newCommonPath) : cwd); } return result; } @@ -262,18 +266,15 @@ function formatPaths(paths, mapper) { } const defaultOptions = { caseSensitiveMatch: true, - cwd: process.cwd(), debug: !!process.env.TINYGLOBBY_DEBUG, expandDirectories: true, followSymbolicLinks: true, onlyFiles: true }; function getOptions(options) { - const opts = { - ...defaultOptions, - ...options - }; - opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve(opts.cwd)).replace(BACKSLASHES, "/"); + const opts = Object.assign({}, options); + for (const key in defaultOptions) if (opts[key] === void 0) Object.assign(opts, { [key]: defaultOptions[key] }); + opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve(opts.cwd || process.cwd())).replace(BACKSLASHES, "/"); opts.ignore = ensureStringArray(opts.ignore); opts.fs && (opts.fs = { readdir: opts.fs.readdir || readdir, diff --git a/deps/npm/node_modules/tinyglobby/package.json b/deps/npm/node_modules/tinyglobby/package.json index 06dadac3a61..a42d4477587 100644 --- a/deps/npm/node_modules/tinyglobby/package.json +++ b/deps/npm/node_modules/tinyglobby/package.json @@ -1,6 +1,6 @@ { "name": "tinyglobby", - "version": "0.2.16", + "version": "0.2.17", "description": "A fast and minimal alternative to globby and fast-glob", "type": "module", "main": "./dist/index.cjs", @@ -22,8 +22,8 @@ "keywords": [ "glob", "patterns", - "fast", - "implementation" + "tiny", + "fast" ], "repository": { "type": "git", @@ -41,22 +41,19 @@ "picomatch": "^4.0.4" }, "devDependencies": { - "@biomejs/biome": "^2.4.10", - "@types/node": "^25.5.2", + "@biomejs/biome": "^2.4.16", + "@types/node": "^25.9.1", "@types/picomatch": "^4.0.3", "fast-glob": "^3.3.3", - "fs-fixture": "^2.13.0", + "fs-fixture": "^2.14.0", "glob": "^13.0.6", - "tinybench": "^6.0.0", - "tsdown": "^0.21.7", - "typescript": "^6.0.2" + "tinybench": "^6.0.2", + "tsdown": "^0.22.1", + "typescript": "^6.0.3" }, "engines": { "node": ">=12.0.0" }, - "publishConfig": { - "provenance": true - }, "scripts": { "bench": "node benchmark/bench.ts", "bench:setup": "node benchmark/setup.ts", diff --git a/deps/npm/node_modules/undici/docs/docs/api/Client.md b/deps/npm/node_modules/undici/docs/docs/api/Client.md index fdee5ea7026..e0d41b47805 100644 --- a/deps/npm/node_modules/undici/docs/docs/api/Client.md +++ b/deps/npm/node_modules/undici/docs/docs/api/Client.md @@ -27,6 +27,7 @@ Returns: `Client` * **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB. * **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable. * **webSocket** `WebSocketOptions` (optional) - WebSocket-specific configuration options. + * **maxFragments** `number` (optional) - Default: `131072` - Maximum number of fragments in a message. Set to 0 to disable the limit. * **maxPayloadSize** `number` (optional) - Default: `134217728` (128 MB) - Maximum allowed payload size in bytes for WebSocket messages. Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages. Set to 0 to disable the limit. * **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections. * **connect** `ConnectOptions | Function | null` (optional) - Default: `null`. diff --git a/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js b/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js index ef3d38ea4f2..9455517a19b 100644 --- a/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js +++ b/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js @@ -57,6 +57,9 @@ const EMPTY_BUF = Buffer.alloc(0) const FastBuffer = Buffer[Symbol.species] const addListener = util.addListener const removeAllListeners = util.removeAllListeners +const kIdleSocketValidation = Symbol('kIdleSocketValidation') +const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout') +const kSocketUsed = Symbol('kSocketUsed') let extractBody @@ -371,6 +374,11 @@ class Parser { return -1 } + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + const request = client[kQueue][client[kRunningIdx]] if (!request) { return -1 @@ -474,6 +482,11 @@ class Parser { return -1 } + if (client[kRunning] === 0) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + const request = client[kQueue][client[kRunningIdx]] /* istanbul ignore next: difficult to make a test case for */ @@ -647,6 +660,7 @@ class Parser { request.onComplete(headers) client[kQueue][client[kRunningIdx]++] = null + socket[kSocketUsed] = true if (socket[kWriting]) { assert(client[kRunning] === 0) @@ -705,6 +719,9 @@ async function connectH1 (client, socket) { socket[kWriting] = false socket[kReset] = false socket[kBlocking] = false + socket[kIdleSocketValidation] = 0 + socket[kIdleSocketValidationTimeout] = null + socket[kSocketUsed] = false socket[kParser] = new Parser(client, socket, llhttpInstance) addListener(socket, 'error', function (err) { @@ -751,6 +768,8 @@ async function connectH1 (client, socket) { const client = this[kClient] const parser = this[kParser] + clearIdleSocketValidation(this) + if (parser) { if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { this[kError] = parser.finish() || this[kError] @@ -816,7 +835,7 @@ async function connectH1 (client, socket) { return socket.destroyed }, busy (request) { - if (socket[kWriting] || socket[kReset] || socket[kBlocking]) { + if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) { return true } @@ -854,6 +873,31 @@ async function connectH1 (client, socket) { } } +function clearIdleSocketValidation (socket) { + if (socket[kIdleSocketValidationTimeout]) { + clearTimeout(socket[kIdleSocketValidationTimeout]) + socket[kIdleSocketValidationTimeout] = null + } + + socket[kIdleSocketValidation] = 0 +} + +function scheduleIdleSocketValidation (client, socket) { + socket[kIdleSocketValidation] = 1 + socket[kIdleSocketValidationTimeout] = setTimeout(() => { + socket[kIdleSocketValidationTimeout] = null + socket[kIdleSocketValidation] = 2 + + if (client[kSocket] === socket && !socket.destroyed) { + client[kResume]() + } + }, 0) + socket[kIdleSocketValidationTimeout].unref?.() +} + +/** + * @param {import('./client.js')} client + */ function resumeH1 (client) { const socket = client[kSocket] @@ -868,6 +912,32 @@ function resumeH1 (client) { socket[kNoRef] = false } + if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) { + if (socket[kIdleSocketValidation] === 0) { + scheduleIdleSocketValidation(client, socket) + socket[kParser].readMore() + if (socket.destroyed) { + return + } + return + } + + if (socket[kIdleSocketValidation] === 1) { + socket[kParser].readMore() + if (socket.destroyed) { + return + } + return + } + } + + if (client[kRunning] === 0) { + socket[kParser].readMore() + if (socket.destroyed) { + return + } + } + if (client[kSize] === 0) { if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) { socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE) @@ -961,6 +1031,7 @@ function writeH1 (client, request) { } const socket = client[kSocket] + clearIdleSocketValidation(socket) const abort = (err) => { if (request.aborted || request.completed) { diff --git a/deps/npm/node_modules/undici/lib/dispatcher/dispatcher-base.js b/deps/npm/node_modules/undici/lib/dispatcher/dispatcher-base.js index c999b2c2fb6..371a3ea1f6f 100644 --- a/deps/npm/node_modules/undici/lib/dispatcher/dispatcher-base.js +++ b/deps/npm/node_modules/undici/lib/dispatcher/dispatcher-base.js @@ -26,6 +26,7 @@ class DispatcherBase extends Dispatcher { get webSocketOptions () { return { + maxFragments: this[kWebSocketOptions].maxFragments ?? 131072, maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 } } diff --git a/deps/npm/node_modules/undici/lib/web/cookies/parse.js b/deps/npm/node_modules/undici/lib/web/cookies/parse.js index 3c48c26b93f..b3c25fb9423 100644 --- a/deps/npm/node_modules/undici/lib/web/cookies/parse.js +++ b/deps/npm/node_modules/undici/lib/web/cookies/parse.js @@ -275,32 +275,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) // If the attribute-name case-insensitively matches the string // "SameSite", the user agent MUST process the cookie-av as follows: - // 1. Let enforcement be "Default". - let enforcement = 'Default' - const attributeValueLowercase = attributeValue.toLowerCase() - // 2. If cookie-av's attribute-value is a case-insensitive match for - // "None", set enforcement to "None". - if (attributeValueLowercase.includes('none')) { - enforcement = 'None' - } - // 3. If cookie-av's attribute-value is a case-insensitive match for - // "Strict", set enforcement to "Strict". - if (attributeValueLowercase.includes('strict')) { - enforcement = 'Strict' + // 1. If cookie-av's attribute-value is a case-insensitive match for + // "None", append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of "None". + if (attributeValueLowercase === 'none') { + cookieAttributeList.sameSite = 'None' + } else if (attributeValueLowercase === 'strict') { + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", append an attribute to the cookie-attribute-list with + // an attribute-name of "SameSite" and an attribute-value of + // "Strict". + cookieAttributeList.sameSite = 'Strict' + } else if (attributeValueLowercase === 'lax') { + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of "Lax". + cookieAttributeList.sameSite = 'Lax' } - - // 4. If cookie-av's attribute-value is a case-insensitive match for - // "Lax", set enforcement to "Lax". - if (attributeValueLowercase.includes('lax')) { - enforcement = 'Lax' - } - - // 5. Append an attribute to the cookie-attribute-list with an - // attribute-name of "SameSite" and an attribute-value of - // enforcement. - cookieAttributeList.sameSite = enforcement } else { cookieAttributeList.unparsed ??= [] diff --git a/deps/npm/node_modules/undici/lib/web/websocket/receiver.js b/deps/npm/node_modules/undici/lib/web/websocket/receiver.js index 53e427eb2e4..a7dea7fae1c 100644 --- a/deps/npm/node_modules/undici/lib/web/websocket/receiver.js +++ b/deps/npm/node_modules/undici/lib/web/websocket/receiver.js @@ -20,6 +20,11 @@ const { closeWebSocketConnection } = require('./connection') const { PerMessageDeflate } = require('./permessage-deflate') const { MessageSizeExceededError } = require('../../core/errors') +function failWebsocketConnectionWithCode (ws, code, reason) { + closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason)) + failWebsocketConnection(ws, reason) +} + // This code was influenced by ws released under the MIT license. // Copyright (c) 2011 Einar Otto Stangvik // Copyright (c) 2013 Arnout Kazemier and contributors @@ -39,19 +44,23 @@ class ByteParser extends Writable { /** @type {Map} */ #extensions + /** @type {number} */ + #maxFragments + /** @type {number} */ #maxPayloadSize /** * @param {import('./websocket').WebSocket} ws * @param {Map|null} extensions - * @param {{ maxPayloadSize?: number }} [options] + * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options] */ constructor (ws, extensions, options = {}) { super() this.ws = ws this.#extensions = extensions == null ? new Map() : extensions + this.#maxFragments = options.maxFragments ?? 0 this.#maxPayloadSize = options.maxPayloadSize ?? 0 if (this.#extensions.has('permessage-deflate')) { @@ -75,9 +84,9 @@ class ByteParser extends Writable { if ( this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && - this.#info.payloadLength > this.#maxPayloadSize + this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize ) { - failWebsocketConnection(this.ws, 'Payload size exceeds maximum allowed size') + failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size') return false } @@ -242,10 +251,12 @@ class ByteParser extends Writable { this.#state = parserStates.INFO } else { if (!this.#info.compressed) { - this.writeFragments(body) + if (!this.writeFragments(body)) { + return + } if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { - failWebsocketConnection(this.ws, new MessageSizeExceededError().message) + failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message) return } @@ -264,14 +275,17 @@ class ByteParser extends Writable { this.#info.fin, (error, data) => { if (error) { - failWebsocketConnection(this.ws, error.message) + const code = error instanceof MessageSizeExceededError ? 1009 : 1007 + failWebsocketConnectionWithCode(this.ws, code, error.message) return } - this.writeFragments(data) + if (!this.writeFragments(data)) { + return + } if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) { - failWebsocketConnection(this.ws, new MessageSizeExceededError().message) + failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message) return } @@ -341,8 +355,17 @@ class ByteParser extends Writable { } writeFragments (fragment) { + if ( + this.#maxFragments > 0 && + this.#fragments.length === this.#maxFragments + ) { + failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments') + return false + } + this.#fragmentsBytes += fragment.length this.#fragments.push(fragment) + return true } consumeFragments () { diff --git a/deps/npm/node_modules/undici/lib/web/websocket/websocket.js b/deps/npm/node_modules/undici/lib/web/websocket/websocket.js index ccedb792169..80991e96a2e 100644 --- a/deps/npm/node_modules/undici/lib/web/websocket/websocket.js +++ b/deps/npm/node_modules/undici/lib/web/websocket/websocket.js @@ -435,9 +435,12 @@ class WebSocket extends EventTarget { // once this happens, the connection is open this[kResponse] = response - const maxPayloadSize = this[kController]?.dispatcher?.webSocketOptions?.maxPayloadSize + const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions + const maxFragments = webSocketOptions?.maxFragments + const maxPayloadSize = webSocketOptions?.maxPayloadSize const parser = new ByteParser(this, parsedExtensions, { + maxFragments, maxPayloadSize }) parser.on('drain', onParserDrain) diff --git a/deps/npm/node_modules/undici/package.json b/deps/npm/node_modules/undici/package.json index d1eef502c41..3c2001f391e 100644 --- a/deps/npm/node_modules/undici/package.json +++ b/deps/npm/node_modules/undici/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "6.26.0", + "version": "6.27.0", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { diff --git a/deps/npm/package.json b/deps/npm/package.json index e600a3c0095..b2ee14b3db8 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "11.16.0", + "version": "11.18.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ @@ -52,8 +52,8 @@ }, "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^9.7.0", - "@npmcli/config": "^10.10.0", + "@npmcli/arborist": "^9.9.0", + "@npmcli/config": "^10.12.0", "@npmcli/fs": "^5.0.0", "@npmcli/map-workspaces": "^5.0.3", "@npmcli/metavuln-calculator": "^9.0.3", @@ -77,11 +77,11 @@ "is-cidr": "^6.0.4", "json-parse-even-better-errors": "^5.0.0", "libnpmaccess": "^10.0.3", - "libnpmdiff": "^8.1.9", - "libnpmexec": "^10.2.9", - "libnpmfund": "^7.0.23", + "libnpmdiff": "^8.1.11", + "libnpmexec": "^10.3.1", + "libnpmfund": "^7.0.25", "libnpmorg": "^8.0.1", - "libnpmpack": "^9.1.9", + "libnpmpack": "^9.1.11", "libnpmpublish": "^11.2.0", "libnpmsearch": "^9.0.1", "libnpmteam": "^8.0.2", @@ -91,26 +91,26 @@ "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^12.3.0", + "node-gyp": "^12.4.0", "nopt": "^9.0.0", "npm-audit-report": "^7.0.0", "npm-install-checks": "^8.0.0", "npm-package-arg": "^13.0.2", "npm-pick-manifest": "^11.0.3", - "npm-profile": "^12.0.1", + "npm-profile": "^12.0.2", "npm-registry-fetch": "^19.1.1", "npm-user-validate": "^4.0.0", "p-map": "^7.0.4", - "pacote": "^21.5.0", + "pacote": "^21.5.1", "parse-conflict-json": "^5.0.1", "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", "read": "^5.0.1", - "semver": "^7.8.1", + "semver": "^7.8.5", "spdx-expression-parse": "^4.0.0", "ssri": "^13.0.1", "supports-color": "^10.2.2", - "tar": "^7.5.15", + "tar": "^7.5.19", "text-table": "~0.2.0", "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs index 829b64b3f80..84a67b23091 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -112,6 +112,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "maxsockets": 15, "message": "%s", "min-release-age": null, + "min-release-age-exclude": [], "node-gyp": "{CWD}/node_modules/node-gyp/bin/node-gyp.js", "node-options": null, "noproxy": [ @@ -301,6 +302,7 @@ logs-max = 10 maxsockets = 15 message = "%s" min-release-age = null +min-release-age-exclude = [] name = null node-gyp = "{CWD}/node_modules/node-gyp/bin/node-gyp.js" node-options = null diff --git a/deps/npm/tap-snapshots/test/lib/commands/install.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/install.js.test.cjs index dd618ee3688..5d78992b51b 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/install.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/install.js.test.cjs @@ -134,8 +134,8 @@ silly logfile done cleaning log files verbose stack Error: The developer of this package has specified the following through devEngines verbose stack Invalid devEngines.runtime verbose stack Invalid name "nondescript" does not match "node" for "runtime" -verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:247:27) -verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:292:7) +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:249:27) +verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:293:7) verbose stack at MockNpm.exec ({CWD}/lib/npm.js:193:9) error code EBADDEVENGINES error EBADDEVENGINES The developer of this package has specified the following through devEngines @@ -199,8 +199,8 @@ warn EBADDEVENGINES } verbose stack Error: The developer of this package has specified the following through devEngines verbose stack Invalid devEngines.runtime verbose stack Invalid name "nondescript" does not match "node" for "runtime" -verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:247:27) -verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:292:7) +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:249:27) +verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:293:7) verbose stack at MockNpm.exec ({CWD}/lib/npm.js:193:9) error code EBADDEVENGINES error EBADDEVENGINES The developer of this package has specified the following through devEngines @@ -225,8 +225,8 @@ silly logfile done cleaning log files verbose stack Error: The developer of this package has specified the following through devEngines verbose stack Invalid devEngines.runtime verbose stack Invalid name "nondescript" does not match "node" for "runtime" -verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:247:27) -verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:292:7) +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:249:27) +verbose stack at MockNpm.execCommandClass ({CWD}/lib/npm.js:293:7) verbose stack at MockNpm.exec ({CWD}/lib/npm.js:193:9) error code EBADDEVENGINES error EBADDEVENGINES The developer of this package has specified the following through devEngines diff --git a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs index 143d08dda8f..dbc6b9f13b0 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -181,6 +181,7 @@ Object { "man/man1/npm-help.1", "man/man1/npm-init.1", "man/man1/npm-install-ci-test.1", + "man/man1/npm-install-scripts.1", "man/man1/npm-install-test.1", "man/man1/npm-install.1", "man/man1/npm-link.1", diff --git a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs index 72671906850..1e2799652c9 100644 --- a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs @@ -125,6 +125,7 @@ Array [ "init", "install", "install-ci-test", + "install-scripts", "install-test", "link", "ll", @@ -216,9 +217,10 @@ The value \`private\` is an alias for \`restricted\`. * Default: false * Type: Boolean -When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. +Show or act on all packages, not just the ones your project directly depends +on. For \`npm outdated\` and \`npm ls\` this lists every outdated or installed +package. For \`npm approve-scripts\` and \`npm deny-scripts\` it selects every +package with pending install scripts. @@ -403,6 +405,13 @@ sources, the standard precedence applies (cli > env > project > user > global), so a higher-priority source can always relax or override a lower-priority one. +As with \`min-release-age\`, when this cutoff blocks a fix that \`npm audit +fix\` would install, npm keeps the vulnerable version, warns, and exits with +a non-zero code. + +Packages whose names match \`min-release-age-exclude\` are exempt from this +filter. + #### \`bin-links\` @@ -1080,8 +1089,16 @@ Sets the strategy for installing packages in node_modules. hoisted (default): Install non-duplicated in top-level, and duplicated as necessary within directory structure. nested: (formerly --legacy-bundling) install in place, no hoisting. shallow (formerly --global-style) only install direct -deps at top-level. linked: (experimental) install in node_modules/.store, -link in place, unhoisted. +deps at top-level. linked: install in node_modules/.store, link in place, +unhoisted. + +We recommend that package authors use \`--install-strategy=linked\` during +development to catch undeclared ("phantom") dependencies before publishing: +the isolated layout only exposes a package's declared dependencies, so an +\`import\` of a package that was never added to \`package.json\` can fail +instead of resolving by accident and shipping broken. See [Catching +undeclared ("phantom") +dependencies](/using-npm/developers#catching-undeclared-phantom-dependencies). @@ -1275,6 +1292,43 @@ your \`.npmrc\` is preserved when npm internally spawns a sub-process with apply, \`before\` wins within a single source and across sources the standard precedence rules apply. +When this window stops \`npm audit fix\` from installing a patched version +(because the fix was published too recently), npm keeps the package at its +vulnerable version, warns that the fix was blocked, and exits with a +non-zero code. To install the fix, add the package to +\`min-release-age-exclude\`, or relax \`min-release-age\` or \`before\`. + +Packages whose names match \`min-release-age-exclude\` are exempt from this +filter. + +This value is not exported to the environment for child processes. + +#### \`min-release-age-exclude\` + +* Default: +* Type: String (can be set multiple times) + +A list of package names or \`minimatch\` glob patterns that are exempt from +the \`min-release-age\` (and \`before\`) filter. A matching package can always +resolve to its newest version, even when a release-age window is set. + +For example, to apply a release-age window to third-party dependencies while +letting internally maintained packages update immediately: + +\`\`\` +min-release-age=7 +min-release-age-exclude[]=@myorg/* +min-release-age-exclude[]=my-internal-pkg +\`\`\` + +Only the named package is exempt; its own dependencies still follow the +release-age policy unless they also match a pattern. Patterns match against +the package name, so \`@myorg/*\` matches \`@myorg/shared-utils\`. + +Excluding a package does not change which registry it is fetched from. You +should own your private scope on the public registry so that nobody else can +publish a package with the same name. + This value is not exported to the environment for child processes. #### \`name\` @@ -1640,7 +1694,14 @@ registry (https://registry.npmjs.org) to the configured registry. If set to "never", then use the registry value. If set to "always", then replace the registry host with the configured host every time. -You may also specify a bare hostname (e.g., "registry.npmjs.org"). +You may also specify a bare hostname (e.g., "registry.npmjs.org") to only +replace URLs coming from that host. + +You may also specify a full URL including a path (e.g., +"https://old-registry.example.com/npm/path"). In that case, resolved URLs +whose host and path begin with that prefix will have the entire prefix +replaced with the configured registry URL (host and path), without +duplicating path segments. @@ -1897,6 +1958,10 @@ silently skipped; this setting only affects unreviewed entries. \`--ignore-scripts\` and \`--dangerously-allow-all-scripts\` both override this setting. +Optional dependencies that cannot be installed on the current platform or +engine (a non-matching \`os\`, \`cpu\`, or \`libc\`) are not flagged, because +their install scripts never run. + #### \`strict-peer-deps\` @@ -2497,6 +2562,7 @@ Array [ "maxsockets", "message", "min-release-age", + "min-release-age-exclude", "node-gyp", "node-options", "noproxy", @@ -2663,6 +2729,7 @@ Array [ "maxsockets", "message", "min-release-age", + "min-release-age-exclude", "node-gyp", "noproxy", "offline", @@ -2840,6 +2907,7 @@ Object { "logColor": false, "maxSockets": 15, "message": "%s", + "minReleaseAgeExclude": Array [], "name": null, "nodeBin": "{NODE}", "nodeGyp": "{CWD}/node_modules/node-gyp/bin/node-gyp.js", @@ -3053,7 +3121,7 @@ Options: [-a|--all] [--allow-scripts-pending] [--no-allow-scripts-pin] [--json] -a|--all - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show + Show or act on all packages, not just the ones your project directly --allow-scripts-pending List packages with install scripts that are not yet covered by the @@ -3566,7 +3634,7 @@ Options: [-a|--all] [--allow-scripts-pending] [--no-allow-scripts-pin] [--json] -a|--all - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show + Show or act on all packages, not just the ones your project directly --allow-scripts-pending List packages with install scripts that are not yet covered by the @@ -4251,8 +4319,10 @@ Options: [--allow-remote ] [--allow-scripts [--allow-scripts ...]] [--strict-allow-scripts] [--dangerously-allow-all-scripts] [--no-audit] -[--before ] [--min-release-age ] [--no-bin-links] [--no-fund] -[--dry-run] [--cpu ] [--os ] [--libc ] +[--before ] [--min-release-age ] +[--min-release-age-exclude [--min-release-age-exclude ...]] +[--no-bin-links] [--no-fund] [--dry-run] [--cpu ] [--os ] +[--libc ] [-w|--workspace [-w|--workspace ...]] [--workspaces] [--include-workspace-root] [--install-links] @@ -4328,6 +4398,9 @@ Options: --min-release-age If set, npm will build the npm tree such that only versions that were + --min-release-age-exclude + A list of package names or \`minimatch\` glob patterns that are exempt + --bin-links Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package @@ -4393,6 +4466,7 @@ aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall #### \`audit\` #### \`before\` #### \`min-release-age\` +#### \`min-release-age-exclude\` #### \`bin-links\` #### \`fund\` #### \`dry-run\` @@ -4529,6 +4603,52 @@ aliases: cit, clean-install-test, sit #### \`install-links\` ` +exports[`test/lib/docs.js TAP usage install-scripts > must match snapshot 1`] = ` +Manage install-script approvals for dependencies + +Usage: +npm install-scripts approve [ ...] +npm install-scripts approve --all +npm install-scripts deny [ ...] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune + +Options: +[-a|--all] [--no-allow-scripts-pin] [--dry-run] [--json] + + -a|--all + Show or act on all packages, not just the ones your project directly + + --allow-scripts-pin + Write pinned (\`pkg@version\`) entries when approving install scripts. + + --dry-run + Indicates that you don't want npm to make any changes and that it should + + --json + Whether or not to output JSON data, rather than the normal output. + + +Run "npm help install-scripts" for more info + +\`\`\`bash +npm install-scripts approve [ ...] +npm install-scripts approve --all +npm install-scripts deny [ ...] +npm install-scripts deny --all +npm install-scripts ls +npm install-scripts prune +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`all\` +#### \`allow-scripts-pin\` +#### \`dry-run\` +#### \`json\` +` + exports[`test/lib/docs.js TAP usage install-test > must match snapshot 1`] = ` Install package(s) and run tests @@ -4547,8 +4667,10 @@ Options: [--allow-remote ] [--allow-scripts [--allow-scripts ...]] [--strict-allow-scripts] [--dangerously-allow-all-scripts] [--no-audit] -[--before ] [--min-release-age ] [--no-bin-links] [--no-fund] -[--dry-run] [--cpu ] [--os ] [--libc ] +[--before ] [--min-release-age ] +[--min-release-age-exclude [--min-release-age-exclude ...]] +[--no-bin-links] [--no-fund] [--dry-run] [--cpu ] [--os ] +[--libc ] [-w|--workspace [-w|--workspace ...]] [--workspaces] [--include-workspace-root] [--install-links] @@ -4624,6 +4746,9 @@ Options: --min-release-age If set, npm will build the npm tree such that only versions that were + --min-release-age-exclude + A list of package names or \`minimatch\` glob patterns that are exempt + --bin-links Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package @@ -4689,6 +4814,7 @@ alias: it #### \`audit\` #### \`before\` #### \`min-release-age\` +#### \`min-release-age-exclude\` #### \`bin-links\` #### \`fund\` #### \`dry-run\` @@ -4841,7 +4967,7 @@ Options: [--workspaces] [--include-workspace-root] [--install-links] -a|--all - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show + Show or act on all packages, not just the ones your project directly --json Whether or not to output JSON data, rather than the normal output. @@ -4988,7 +5114,7 @@ Options: [--workspaces] [--include-workspace-root] [--install-links] -a|--all - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show + Show or act on all packages, not just the ones your project directly --json Whether or not to output JSON data, rather than the normal output. @@ -5135,9 +5261,10 @@ Options: [-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [-w|--workspace [-w|--workspace ...]] [--before ] [--min-release-age ] +[--min-release-age-exclude [--min-release-age-exclude ...]] -a|--all - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show + Show or act on all packages, not just the ones your project directly --json Whether or not to output JSON data, rather than the normal output. @@ -5160,6 +5287,9 @@ Options: --min-release-age If set, npm will build the npm tree such that only versions that were + --min-release-age-exclude + A list of package names or \`minimatch\` glob patterns that are exempt + Run "npm help outdated" for more info @@ -5175,6 +5305,7 @@ npm outdated [ ...] #### \`workspace\` #### \`before\` #### \`min-release-age\` +#### \`min-release-age-exclude\` ` exports[`test/lib/docs.js TAP usage owner > must match snapshot 1`] = ` @@ -5530,7 +5661,9 @@ Options: [-g|--global] [-w|--workspace [-w|--workspace ...]] [--workspaces] [--include-workspace-root] [--package-lock-only] -[--expect-results|--expect-result-count ] +[--expect-results|--expect-result-count ] [--before ] +[--min-release-age ] +[--min-release-age-exclude [--min-release-age-exclude ...]] -g|--global Operates in "global" mode, so that packages are installed into the @@ -5550,6 +5683,15 @@ Options: --expect-results Tells npm whether or not to expect results from the command. + --before + If passed to \`npm install\`, will rebuild the npm tree such that only + + --min-release-age + If set, npm will build the npm tree such that only versions that were + + --min-release-age-exclude + A list of package names or \`minimatch\` glob patterns that are exempt + Run "npm help query" for more info @@ -5564,6 +5706,9 @@ npm query #### \`package-lock-only\` #### \`expect-results\` #### \`expect-result-count\` +#### \`before\` +#### \`min-release-age\` +#### \`min-release-age-exclude\` ` exports[`test/lib/docs.js TAP usage rebuild > must match snapshot 1`] = ` @@ -6476,8 +6621,9 @@ Options: [--ignore-scripts] [--allow-scripts [--allow-scripts ...]] [--strict-allow-scripts] [--dangerously-allow-all-scripts] [--no-audit] -[--before ] [--min-release-age ] [--no-bin-links] [--no-fund] -[--dry-run] +[--before ] [--min-release-age ] +[--min-release-age-exclude [--min-release-age-exclude ...]] +[--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] [--workspaces] [--include-workspace-root] [--install-links] @@ -6532,6 +6678,9 @@ Options: --min-release-age If set, npm will build the npm tree such that only versions that were + --min-release-age-exclude + A list of package names or \`minimatch\` glob patterns that are exempt + --bin-links Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package @@ -6581,6 +6730,7 @@ aliases: u, up, upgrade, udpate #### \`audit\` #### \`before\` #### \`min-release-age\` +#### \`min-release-age-exclude\` #### \`bin-links\` #### \`fund\` #### \`dry-run\` diff --git a/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs index dc1c95cd3c5..a3837dc72ab 100644 --- a/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs @@ -35,12 +35,13 @@ All commands: completion, config, dedupe, deny-scripts, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, help-search, init, install, - install-ci-test, install-test, link, ll, login, logout, ls, - org, outdated, owner, pack, ping, pkg, prefix, profile, - prune, publish, query, rebuild, repo, restart, root, run, - sbom, search, set, shrinkwrap, stage, star, stars, start, - stop, team, test, token, trust, undeprecate, uninstall, - unpublish, unstar, update, version, view, whoami + install-ci-test, install-scripts, install-test, link, ll, + login, logout, ls, org, outdated, owner, pack, ping, pkg, + prefix, profile, prune, publish, query, rebuild, repo, + restart, root, run, sbom, search, set, shrinkwrap, stage, + star, stars, start, stop, team, test, token, trust, + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -81,6 +82,7 @@ All commands: help-search, init, install, install-ci-test, + install-scripts, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, @@ -136,6 +138,7 @@ All commands: help-search, init, install, install-ci-test, + install-scripts, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, @@ -182,12 +185,13 @@ All commands: completion, config, dedupe, deny-scripts, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, help-search, init, install, - install-ci-test, install-test, link, ll, login, logout, ls, - org, outdated, owner, pack, ping, pkg, prefix, profile, - prune, publish, query, rebuild, repo, restart, root, run, - sbom, search, set, shrinkwrap, stage, star, stars, start, - stop, team, test, token, trust, undeprecate, uninstall, - unpublish, unstar, update, version, view, whoami + install-ci-test, install-scripts, install-test, link, ll, + login, logout, ls, org, outdated, owner, pack, ping, pkg, + prefix, profile, prune, publish, query, rebuild, repo, + restart, root, run, sbom, search, set, shrinkwrap, stage, + star, stars, start, stop, team, test, token, trust, + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -228,6 +232,7 @@ All commands: help-search, init, install, install-ci-test, + install-scripts, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, @@ -283,6 +288,7 @@ All commands: help-search, init, install, install-ci-test, + install-scripts, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, @@ -337,6 +343,7 @@ All commands: fund, get, help, help-search, init, install, install-ci-test, + install-scripts, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, @@ -383,12 +390,13 @@ All commands: completion, config, dedupe, deny-scripts, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, help-search, init, install, - install-ci-test, install-test, link, ll, login, logout, ls, - org, outdated, owner, pack, ping, pkg, prefix, profile, - prune, publish, query, rebuild, repo, restart, root, run, - sbom, search, set, shrinkwrap, stage, star, stars, start, - stop, team, test, token, trust, undeprecate, uninstall, - unpublish, unstar, update, version, view, whoami + install-ci-test, install-scripts, install-test, link, ll, + login, logout, ls, org, outdated, owner, pack, ping, pkg, + prefix, profile, prune, publish, query, rebuild, repo, + restart, root, run, sbom, search, set, shrinkwrap, stage, + star, stars, start, stop, team, test, token, trust, + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -420,12 +428,13 @@ All commands: completion, config, dedupe, deny-scripts, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, help-search, init, install, - install-ci-test, install-test, link, ll, login, logout, ls, - org, outdated, owner, pack, ping, pkg, prefix, profile, - prune, publish, query, rebuild, repo, restart, root, run, - sbom, search, set, shrinkwrap, stage, star, stars, start, - stop, team, test, token, trust, undeprecate, uninstall, - unpublish, unstar, update, version, view, whoami + install-ci-test, install-scripts, install-test, link, ll, + login, logout, ls, org, outdated, owner, pack, ping, pkg, + prefix, profile, prune, publish, query, rebuild, repo, + restart, root, run, sbom, search, set, shrinkwrap, stage, + star, stars, start, stop, team, test, token, trust, + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -457,12 +466,13 @@ All commands: completion, config, dedupe, deny-scripts, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, help-search, init, install, - install-ci-test, install-test, link, ll, login, logout, ls, - org, outdated, owner, pack, ping, pkg, prefix, profile, - prune, publish, query, rebuild, repo, restart, root, run, - sbom, search, set, shrinkwrap, stage, star, stars, start, - stop, team, test, token, trust, undeprecate, uninstall, - unpublish, unstar, update, version, view, whoami + install-ci-test, install-scripts, install-test, link, ll, + login, logout, ls, org, outdated, owner, pack, ping, pkg, + prefix, profile, prune, publish, query, rebuild, repo, + restart, root, run, sbom, search, set, shrinkwrap, stage, + star, stars, start, stop, team, test, token, trust, + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} diff --git a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs index 40d4cd221ca..828a99679ea 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs @@ -10,6 +10,11 @@ exports[`test/lib/utils/reify-output.js TAP added packages should be looked up w added 1 package in {TIME} ` +exports[`test/lib/utils/reify-output.js TAP added packages should be looked up within returned tree linked store package counted though absent from actualTree > must match snapshot 1`] = ` + +added 1 package in {TIME} +` + exports[`test/lib/utils/reify-output.js TAP added packages should be looked up within returned tree missing added pkg in inventory > must match snapshot 1`] = ` up to date in {TIME} diff --git a/deps/npm/tap-snapshots/test/lib/utils/sbom-cyclonedx.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/sbom-cyclonedx.js.test.cjs index 124478bc829..6963299566d 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/sbom-cyclonedx.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/sbom-cyclonedx.js.test.cjs @@ -417,7 +417,7 @@ exports[`test/lib/utils/sbom-cyclonedx.js TAP single node - from git url > must "version": "1.0.0", "scope": "required", "author": "Author", - "purl": "pkg:npm/root@1.0.0?vcs_url=https://github.com/foo/bar#1234", + "purl": "pkg:npm/root@1.0.0?vcs_url=https%3A%2F%2Fgithub.com%2Ffoo%2Fbar%231234", "properties": [], "externalReferences": [ { diff --git a/deps/npm/tap-snapshots/test/lib/utils/sbom-spdx.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/sbom-spdx.js.test.cjs index 6adb6d26de1..eda01bcaa4e 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/sbom-spdx.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/sbom-spdx.js.test.cjs @@ -414,7 +414,7 @@ exports[`test/lib/utils/sbom-spdx.js TAP single node - from git url > must match { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", - "referenceLocator": "pkg:npm/root@1.0.0?vcs_url=https://github.com/foo/bar#1234" + "referenceLocator": "pkg:npm/root@1.0.0?vcs_url=https%3A%2F%2Fgithub.com%2Ffoo%2Fbar%231234" } ] } diff --git a/deps/npm/test/lib/commands/approve-scripts.js b/deps/npm/test/lib/commands/approve-scripts.js index dde7a358b12..4b2e7e5a73e 100644 --- a/deps/npm/test/lib/commands/approve-scripts.js +++ b/deps/npm/test/lib/commands/approve-scripts.js @@ -7,7 +7,7 @@ const mockNpm = async (t, opts = {}) => { return _mockNpm(t, opts) } -const setupProject = ({ allowScripts, withScripts = ['canvas'] } = {}) => { +const setupProject = ({ allowScripts, withScripts = ['canvas'], noResolved = [] } = {}) => { const pkg = { name: 'host', version: '1.0.0', @@ -28,11 +28,16 @@ const setupProject = ({ allowScripts, withScripts = ['canvas'] } = {}) => { scripts: { install: 'echo install' }, }), } - lockPackages[`node_modules/${name}`] = { + const lockEntry = { version: '1.0.0', - resolved: tarUrl, hasInstallScript: true, } + // Some lockfiles omit `resolved` for registry deps. Those nodes have no + // trustable version, so they can only be approved by name. + if (!noResolved.includes(name)) { + lockEntry.resolved = tarUrl + } + lockPackages[`node_modules/${name}`] = lockEntry } return { @@ -60,6 +65,18 @@ t.test('approve-scripts --pending lists unreviewed packages', async t => { t.match(out, /sharp@1\.0\.0/) }) +t.test('approve-scripts --pending lists unreviewed packages even with ignore-scripts set', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas', 'sharp'] }), + config: { 'allow-scripts-pending': true, 'ignore-scripts': true }, + }) + await npm.exec('approve-scripts', []) + const out = joinedOutput() + t.match(out, /2 packages have install scripts not yet covered/) + t.match(out, /canvas@1\.0\.0/) + t.match(out, /sharp@1\.0\.0/) +}) + t.test('approve-scripts --pending with no unreviewed says so', async t => { const { npm, joinedOutput } = await mockNpm(t, { prefixDir: setupProject({ @@ -107,6 +124,51 @@ t.test('approve-scripts --all approves every unreviewed package', async t => { }) }) +t.test('approve-scripts --all approves a dep without a resolved URL by name', async t => { + // Regression for npm/cli#9558: a dep with no `resolved` URL can't be + // pinned, but must still be approved by name, not silently skipped. + const { npm, prefix, logs } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'], noResolved: ['canvas'] }), + config: { all: true }, + }) + await npm.exec('approve-scripts', []) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { canvas: true }, 'approved by name, not skipped') + t.match( + logs.warn.byTitle('approve-scripts').join('\n'), + /no "resolved" URL/, + 'warns that a version pin could not be written' + ) +}) + +t.test('approve-scripts approves a dep without a resolved URL by name', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'], noResolved: ['canvas'] }), + }) + await npm.exec('approve-scripts', ['canvas']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { canvas: true }) +}) + +t.test('approve-scripts --pending is empty after a no-resolved dep is approved by name', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + allowScripts: { canvas: true }, + withScripts: ['canvas'], + noResolved: ['canvas'], + }), + config: { 'allow-scripts-pending': true }, + }) + await npm.exec('approve-scripts', []) + t.match( + joinedOutput(), + /No packages with unreviewed install scripts/, + 'name-only entry covers the dep even without a resolved URL' + ) +}) + t.test('approve-scripts errors on unknown package', async t => { const { npm } = await mockNpm(t, { prefixDir: setupProject({ withScripts: ['canvas'] }), @@ -117,6 +179,125 @@ t.test('approve-scripts errors on unknown package', async t => { ) }) +t.test('approve-scripts approves a package whose name contains dots', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['cordova.plugins.diagnostic'] }), + }) + await npm.exec('approve-scripts', ['cordova.plugins.diagnostic']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'cordova.plugins.diagnostic@1.0.0': true }) +}) + +t.test('approve-scripts approves a dotted name with a version specifier', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['cordova.plugins.diagnostic'] }), + }) + await npm.exec('approve-scripts', ['cordova.plugins.diagnostic@1.0.0']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'cordova.plugins.diagnostic@1.0.0': true }) +}) + +t.test('approve-scripts <@scope/pkg@version> approves a scoped name with a version', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + dependencies: { '@scope/pkg': '*' }, + }), + 'package-lock.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + lockfileVersion: 3, + requires: true, + packages: { + '': { name: 'host', version: '1.0.0', dependencies: { '@scope/pkg': '*' } }, + 'node_modules/@scope/pkg': { + version: '2.0.0', + resolved: 'https://registry.npmjs.org/@scope/pkg/-/pkg-2.0.0.tgz', + hasInstallScript: true, + }, + }, + }), + node_modules: { + '@scope': { + pkg: { + 'package.json': JSON.stringify({ + name: '@scope/pkg', + version: '2.0.0', + scripts: { install: 'echo install' }, + }), + }, + }, + }, + }, + }) + await npm.exec('approve-scripts', ['@scope/pkg@2.0.0']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { '@scope/pkg@2.0.0': true }) +}) + +t.test('approve-scripts errors when no installed version matches', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('approve-scripts', ['canvas@9.9.9']), + { code: 'ENOMATCH' } + ) +}) + +t.test('approve-scripts reports only the unmatched args and writes nothing', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + const err = await npm.exec('approve-scripts', ['canvas', 'not-installed']) + .then(() => null, e => e) + t.equal(err.code, 'ENOMATCH') + t.match(err.message, /not-installed/) + t.notMatch(err.message, /canvas/) + // Nothing is written when any arg fails to match. + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.notOk(pkg.allowScripts) +}) + +t.test('approve-scripts matches every installed version', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + // A tag carries no version to filter on, so it behaves like a bare name. + await npm.exec('approve-scripts', ['canvas@latest']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) +}) + +t.test('approve-scripts errors on an unparseable spec', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + // npm-package-arg throws on this; the raw string is used as the name and + // matches nothing. + await t.rejects( + npm.exec('approve-scripts', ['foo@@bar']), + { code: 'ENOMATCH' } + ) +}) + +t.test('approve-scripts errors on a spec with no package name', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + // A path spec parses but carries no name, so it matches no registry dep. + await t.rejects( + npm.exec('approve-scripts', ['./local-pkg']), + { code: 'ENOMATCH' } + ) +}) + t.test('approve-scripts respects existing deny entry', async t => { const { npm, prefix, logs } = await mockNpm(t, { prefixDir: setupProject({ @@ -166,6 +347,51 @@ t.test('approve-scripts --json outputs structured summary', async t => { }) }) +t.test('approve-scripts --pending --json lists unreviewed packages as JSON', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas', 'sharp'] }), + config: { 'allow-scripts-pending': true, json: true }, + }) + await npm.exec('approve-scripts', []) + const parsed = JSON.parse(joinedOutput()) + const byName = Object.fromEntries(parsed.allowScripts.map((e) => [e.name, e.changes])) + t.strictSame(byName, { + canvas: [{ key: 'canvas@1.0.0', change: 'pending' }], + sharp: [{ key: 'sharp@1.0.0', change: 'pending' }], + }) +}) + +t.test('approve-scripts --pending --json with no unreviewed emits empty list', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + allowScripts: { canvas: true }, + withScripts: ['canvas'], + }), + config: { 'allow-scripts-pending': true, json: true }, + }) + await npm.exec('approve-scripts', []) + t.strictSame(JSON.parse(joinedOutput()), { allowScripts: [] }) +}) + +t.test('approve-scripts --all --json with no unreviewed emits empty list', async t => { + const { npm, joinedOutput } = await _mockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: 'host', version: '1.0.0' }), + 'package-lock.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + lockfileVersion: 3, + requires: true, + packages: { '': { name: 'host', version: '1.0.0' } }, + }), + node_modules: {}, + }, + config: { all: true, json: true }, + }) + await npm.exec('approve-scripts', []) + t.strictSame(JSON.parse(joinedOutput()), { allowScripts: [] }) +}) + t.test('approve-scripts --all with no unreviewed packages prints message', async t => { const { npm, joinedOutput } = await _mockNpm(t, { prefixDir: { @@ -219,63 +445,83 @@ t.test('approve-scripts --pending lists package with no version', async t => { t.pass() }) -t.test('approve-scripts groups multiple installed versions of the same package', async t => { - // Two versions of lodash exist in the tree; both have install scripts. - // groupByPackage should put them in the same group (hits the - // `if (!groups[key])` falsy branch on the second node). - const { npm, prefix } = await _mockNpm(t, { - prefixDir: { - 'package.json': JSON.stringify({ - name: 'host', - version: '1.0.0', - dependencies: { 'top-of-tree': '*' }, - }), - 'package-lock.json': JSON.stringify({ - name: 'host', +const twoVersionFixture = { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + dependencies: { 'top-of-tree': '*' }, + }), + 'package-lock.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + lockfileVersion: 3, + requires: true, + packages: { + '': { name: 'host', version: '1.0.0', dependencies: { 'top-of-tree': '*' } }, + 'node_modules/lodash': { + version: '4.17.21', + resolved: 'https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz', + hasInstallScript: true, + }, + 'node_modules/top-of-tree': { version: '1.0.0', - lockfileVersion: 3, - requires: true, - packages: { - '': { name: 'host', version: '1.0.0', dependencies: { 'top-of-tree': '*' } }, - 'node_modules/lodash': { - version: '4.17.21', - resolved: 'https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz', - hasInstallScript: true, - }, - 'node_modules/top-of-tree': { - version: '1.0.0', - resolved: 'https://registry.npmjs.org/top-of-tree/-/top-of-tree-1.0.0.tgz', - dependencies: { lodash: '3.10.1' }, - }, - 'node_modules/top-of-tree/node_modules/lodash': { - version: '3.10.1', - resolved: 'https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz', - hasInstallScript: true, - }, - }, + resolved: 'https://registry.npmjs.org/top-of-tree/-/top-of-tree-1.0.0.tgz', + dependencies: { lodash: '3.10.1' }, + }, + 'node_modules/top-of-tree/node_modules/lodash': { + version: '3.10.1', + resolved: 'https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz', + hasInstallScript: true, + }, + }, + }), + node_modules: { + lodash: { + 'package.json': JSON.stringify({ + name: 'lodash', + version: '4.17.21', + scripts: { install: 'echo install' }, }), + }, + 'top-of-tree': { + 'package.json': JSON.stringify({ name: 'top-of-tree', version: '1.0.0' }), node_modules: { lodash: { 'package.json': JSON.stringify({ name: 'lodash', - version: '4.17.21', + version: '3.10.1', scripts: { install: 'echo install' }, }), }, - 'top-of-tree': { - 'package.json': JSON.stringify({ name: 'top-of-tree', version: '1.0.0' }), - node_modules: { - lodash: { - 'package.json': JSON.stringify({ - name: 'lodash', - version: '3.10.1', - scripts: { install: 'echo install' }, - }), - }, - }, - }, }, }, + }, +} + +t.test('approve-scripts --pending --json groups multiple versions under one name', async t => { + // Two versions of lodash are unreviewed; pendingSummary must collapse + // them into a single `lodash` entry (hits the `groups.has(display)` + // truthy branch on the second node). + const { npm, joinedOutput } = await _mockNpm(t, { + prefixDir: twoVersionFixture, + config: { 'allow-scripts-pending': true, json: true }, + }) + await npm.exec('approve-scripts', []) + const parsed = JSON.parse(joinedOutput()) + t.strictSame(parsed.allowScripts.map((e) => e.name), ['lodash']) + t.strictSame(parsed.allowScripts[0].changes.map((c) => c.key).sort(), [ + 'lodash@3.10.1', + 'lodash@4.17.21', + ]) + t.ok(parsed.allowScripts[0].changes.every((c) => c.change === 'pending')) +}) + +t.test('approve-scripts groups multiple installed versions of the same package', async t => { + // Two versions of lodash exist in the tree; both have install scripts. + // groupByPackage should put them in the same group (hits the + // `if (!groups[key])` falsy branch on the second node). + const { npm, prefix } = await _mockNpm(t, { + prefixDir: twoVersionFixture, }) await npm.exec('approve-scripts', ['lodash']) @@ -287,6 +533,26 @@ t.test('approve-scripts groups multiple installed versions of the same package', }) }) +t.test('approve-scripts pins only the matching installed version', async t => { + const { npm, prefix } = await _mockNpm(t, { + prefixDir: twoVersionFixture, + }) + await npm.exec('approve-scripts', ['lodash@4.17.21']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'lodash@4.17.21': true }) +}) + +t.test('approve-scripts pins only versions satisfying the range', async t => { + const { npm, prefix } = await _mockNpm(t, { + prefixDir: twoVersionFixture, + }) + await npm.exec('approve-scripts', ['lodash@^4']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'lodash@4.17.21': true }) +}) + t.test('approve-scripts --pending handles node with no version', async t => { // Exercise the ternary's falsy branch in runPending: `node.version ? '@'... : ''` // when the node has no version field. @@ -316,6 +582,37 @@ t.test('approve-scripts --pending handles node with no version', async t => { t.match(mockSync.joinedOutput(), / no-version-pkg \(install: do-stuff\)/) }) +t.test('approve-scripts --pending --json handles node with no version', async t => { + // Exercise pendingSummary's `version ? ... : display` falsy branch: the + // key is the bare name when the node has no version field. + const { npm, joinedOutput } = await _mockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: 'host', version: '1.0.0' }), + 'package-lock.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + lockfileVersion: 3, + requires: true, + packages: { '': { name: 'host', version: '1.0.0' } }, + }), + node_modules: {}, + }, + config: { 'allow-scripts-pending': true, json: true }, + mocks: { + '{LIB}/utils/check-allow-scripts.js': async () => [{ + node: { packageName: 'no-version-pkg', name: 'no-version-pkg', version: undefined }, + scripts: { install: 'do-stuff' }, + }], + }, + }) + await npm.exec('approve-scripts', []) + t.strictSame(JSON.parse(joinedOutput()), { + allowScripts: [ + { name: 'no-version-pkg', changes: [{ key: 'no-version-pkg', change: 'pending' }] }, + ], + }) +}) + t.test('forbidden semver range in package.json#allowScripts is dropped with a warning', async t => { // End-to-end: project declares a caret range in allowScripts. The // resolver must drop the entry, emit a warning, and the matching node @@ -385,10 +682,10 @@ t.test('approve-scripts --pending lists packages that only have binding.gyp', as t.match(out, /install: node-gyp rebuild/, 'synthetic node-gyp install is named') }) -t.test('approve-scripts --all skips bundled deps with a notice', async t => { - // Bundled deps cannot be allowlisted in Phase 1 (RFC defers their - // allowlisting to a follow-up). --all must not silently write a key - // derived from the bundled tarball's self-claimed identity. +t.test('approve-scripts --all never approves bundled deps', async t => { + // Bundled deps never run their install scripts and cannot be + // allowlisted. They never reach the unreviewed list, so --all must not + // write a key derived from the bundled tarball's self-claimed identity. const { npm, logs, prefix } = await _mockNpm(t, { prefixDir: { 'package.json': JSON.stringify({ @@ -445,7 +742,8 @@ t.test('approve-scripts --all skips bundled deps with a notice', async t => { 'non-bundled parent gets approved') t.notOk(Object.keys(pkg.allowScripts).some(k => k.startsWith('inner')), 'bundled inner is not approved') - t.match(logs.warn.byTitle('approve-scripts'), [/Skipping 1 bundled dependency/]) + t.strictSame(logs.warn.byTitle('approve-scripts'), [], + 'no warning; bundled deps are excluded upstream') }) t.test('approve-scripts positional is ignored', async t => { @@ -505,7 +803,7 @@ t.test('approve-scripts positional is ignored', async t => { ) }) -t.test('approve-scripts --all with only bundled deps prints "no eligible" notice', async t => { +t.test('approve-scripts --all with only bundled deps has nothing to review', async t => { const { npm, logs, joinedOutput, prefix } = await _mockNpm(t, { prefixDir: { 'package.json': JSON.stringify({ @@ -554,8 +852,9 @@ t.test('approve-scripts --all with only bundled deps prints "no eligible" notice config: { all: true }, }) await npm.exec('approve-scripts', []) - t.match(joinedOutput(), /No packages eligible for approval/) - t.match(logs.warn.byTitle('approve-scripts'), [/Skipping 1 bundled dependency/]) + t.match(joinedOutput(), /No packages with unreviewed install scripts/) + t.strictSame(logs.warn.byTitle('approve-scripts'), [], + 'no warning; bundled deps are excluded upstream') // Ensure no policy entry was written. const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) t.notOk(pkg.allowScripts, 'no allowScripts written') diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js index 04d09f1aee4..61887417216 100644 --- a/deps/npm/test/lib/commands/audit.js +++ b/deps/npm/test/lib/commands/audit.js @@ -163,6 +163,86 @@ t.test('audit fix - bulk endpoint', async t => { ) }) +t.test('audit fix exits non-zero when min-release-age blocks a fix', async t => { + const { npm, logs } = await loadMockNpm(t, { + prefixDir: tree, + config: { 'min-release-age': 30 }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: 'test-dep-a', + packuments: [{ version: '1.0.0' }, { version: '1.0.1' }], + }) + // 1.0.0 is old enough to install; the fix 1.0.1 was published too recently. + manifest.time['1.0.0'] = '2020-01-01T00:00:00.000Z' + manifest.time['1.0.1'] = new Date().toISOString() + await registry.package({ + manifest, + tarballs: { + '1.0.0': path.join(npm.prefix, 'test-dep-a-vuln'), + }, + times: 2, + }) + const advisory = registry.advisory({ id: 100, vulnerable_versions: '<1.0.1' }) + registry.nock.post('/-/npm/v1/security/advisories/bulk', body => { + const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex'))) + return t.same(unzipped, { 'test-dep-a': ['1.0.0'] }) + }) + .reply(200, { 'test-dep-a': [advisory] }) + .post('/-/npm/v1/security/advisories/bulk', body => { + const unzipped = JSON.parse(gunzip(Buffer.from(body, 'hex'))) + return t.same(unzipped, { 'test-dep-a': ['1.0.0'] }) + }) + .reply(200, { 'test-dep-a': [advisory] }) + + await npm.exec('audit', ['fix']) + + t.equal(process.exitCode, 1, 'exits non-zero because the fix was blocked') + t.ok( + logs.warn.some(w => + /left at a vulnerable version because a fix is newer than the release-age cutoff/.test(w)), + 'warns that the fix was blocked by min-release-age' + ) + const lock = JSON.parse(fs.readFileSync(path.join(npm.prefix, 'package-lock.json'), 'utf8')) + t.equal(lock.packages['node_modules/test-dep-a'].version, '1.0.0', + 'test-dep-a was left at the vulnerable version') +}) + +t.test('json audit reports fixBlockedByReleaseAge when a fix is too new', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: tree, + config: { + json: true, + 'min-release-age': 30, + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + const manifest = registry.manifest({ + name: 'test-dep-a', + packuments: [{ version: '1.0.0' }, { version: '1.0.1' }], + }) + manifest.time['1.0.0'] = '2020-01-01T00:00:00.000Z' + manifest.time['1.0.1'] = new Date().toISOString() + await registry.package({ manifest }) + const advisory = registry.advisory({ id: 100, vulnerable_versions: '<1.0.1' }) + const bulkBody = gzip(JSON.stringify({ 'test-dep-a': ['1.0.0'] })) + registry.nock.post('/-/npm/v1/security/advisories/bulk', bulkBody) + .reply(200, { + 'test-dep-a': [advisory], + }) + + await npm.exec('audit', []) + const report = JSON.parse(joinedOutput()) + t.match(report.vulnerabilities['test-dep-a'].fixBlockedByReleaseAge, { version: '1.0.1' }, + 'json output flags the fix that min-release-age blocked') +}) + t.test('audit fix no package lock', async t => { const { npm } = await loadMockNpm(t, { config: { @@ -906,6 +986,26 @@ t.test('audit signatures', async t => { t.matchSnapshot(joinedOutput()) }) + t.test('with min-release-age set verifies installed versions', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: installWithValidSigs, + config: { + 'min-release-age': 99999, + }, + }) + const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) + await manifestWithValidSigs({ registry }) + mockTUF({ npm, target: TUF_VALID_KEYS_TARGET }) + + // min-release-age flattens into a `before` cutoff that previously leaked + // into the exact-version manifest lookup, producing a spurious ETARGET on + // already-installed versions. See npm/cli#9277. + await npm.exec('audit', ['signatures']) + + t.notOk(process.exitCode, 'should exit successfully') + t.match(joinedOutput(), /audited 1 package/) + }) + t.test('with valid signatures using alias', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: installWithAlias, @@ -2238,3 +2338,31 @@ t.test('audit signatures', async t => { }) }) }) + +t.test('audit fix threads allowScripts policy through to arborist', async t => { + let capturedOpts + const FakeArborist = function (opts) { + capturedOpts = opts + this.options = opts + this.actualTree = { inventory: new Map() } + this.auditReport = {} + } + FakeArborist.prototype.audit = async () => {} + + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await npm.exec('audit', ['fix']) + t.strictSame(capturedOpts.allowScripts, { canvas: true }, + 'opts.allowScripts populated from package.json') +}) diff --git a/deps/npm/test/lib/commands/ci.js b/deps/npm/test/lib/commands/ci.js index 6db01d7b6ec..bc645c5cc40 100644 --- a/deps/npm/test/lib/commands/ci.js +++ b/deps/npm/test/lib/commands/ci.js @@ -150,6 +150,37 @@ t.test('--no-audit and --ignore-scripts', async t => { t.match(joinedOutput(), 'added 1 package in', 'would fail if install script ran') }) +t.test('allow-remote=none blocks same-host tarball outside registry path', async t => { + const token = 'test-path-token' + const registryUrl = 'https://registry.example.com/npm/' + const evilTarball = 'https://registry.example.com/evil/abbrev-1.0.0.tgz' + const lock = JSON.parse(JSON.stringify(packageLock)) + lock.packages['node_modules/abbrev'].resolved = evilTarball + lock.dependencies.abbrev.resolved = evilTarball + + const { npm } = await loadMockNpm(t, { + config: { + audit: false, + 'allow-remote': 'none', + registry: registryUrl, + [`//registry.example.com/npm/:_authToken`]: token, + }, + prefixDir: { + abbrev, + 'package.json': JSON.stringify(packageJson), + 'package-lock.json': JSON.stringify(lock), + }, + }) + + await t.rejects( + npm.exec('ci', []), + { code: 'EALLOWREMOTE' }, + 'sibling-path tarball is blocked by allow-remote=none' + ) + const nmAbbrev = path.join(npm.prefix, 'node_modules', 'abbrev') + t.equal(fs.existsSync(nmAbbrev), false, 'does not install tarball outside configured registry path') +}) + t.test('lifecycle scripts', async t => { const scripts = [] const { npm, registry } = await loadMockNpm(t, { diff --git a/deps/npm/test/lib/commands/dedupe.js b/deps/npm/test/lib/commands/dedupe.js index c94b0b8228c..22e3f0e2063 100644 --- a/deps/npm/test/lib/commands/dedupe.js +++ b/deps/npm/test/lib/commands/dedupe.js @@ -94,3 +94,30 @@ t.test('dedupe', async (t) => { fs.existsSync(path.join(npm.prefix, 'node_modules', 'test-dep-b', 'node_modules', 'test-sub')), 'test-dep-b/test-sub was removed') }) + +t.test('dedupe threads allowScripts policy through to arborist', async t => { + let capturedOpts + const FakeArborist = function (opts) { + capturedOpts = opts + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.dedupe = async () => {} + + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await npm.exec('dedupe', []) + t.strictSame(capturedOpts.allowScripts, { canvas: true }, + 'opts.allowScripts populated from package.json') +}) diff --git a/deps/npm/test/lib/commands/deny-scripts.js b/deps/npm/test/lib/commands/deny-scripts.js index fd9031c665d..1caf93b7151 100644 --- a/deps/npm/test/lib/commands/deny-scripts.js +++ b/deps/npm/test/lib/commands/deny-scripts.js @@ -80,7 +80,10 @@ t.test('deny-scripts --pending is rejected', async t => { prefixDir: setupProject({ withScripts: ['core-js'] }), config: { 'allow-scripts-pending': true }, }) - await t.rejects(npm.exec('deny-scripts', []), { code: 'EUSAGE' }) + await t.rejects(npm.exec('deny-scripts', []), { + code: 'EUSAGE', + message: /`npm deny-scripts --allow-scripts-pending` is not supported; run `npm install-scripts ls` to list unreviewed packages/, + }) }) t.test('deny-scripts --all denies every unreviewed package', async t => { @@ -104,6 +107,16 @@ t.test('deny-scripts errors on unknown package', async t => { ) }) +t.test('deny-scripts denies a dotted name with a version specifier', async t => { + const { npm, prefix } = await _mockNpm(t, { + prefixDir: setupProject({ withScripts: ['cordova.plugins.diagnostic'] }), + }) + await npm.exec('deny-scripts', ['cordova.plugins.diagnostic@1.0.0']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'cordova.plugins.diagnostic': false }) +}) + t.test('deny-scripts requires positional args or --all', async t => { const { npm } = await _mockNpm(t, { prefixDir: setupProject({ withScripts: ['core-js'] }), @@ -130,6 +143,25 @@ t.test('deny-scripts --all with no unreviewed packages prints message', async t t.match(joinedOutput(), /No packages with unreviewed install scripts/) }) +t.test('deny-scripts --all --json with no unreviewed emits empty list', async t => { + const { npm, joinedOutput } = await _mockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ name: 'host', version: '1.0.0' }), + 'package-lock.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + lockfileVersion: 3, + requires: true, + packages: { '': { name: 'host', version: '1.0.0' } }, + }), + node_modules: {}, + }, + config: { all: true, json: true }, + }) + await npm.exec('deny-scripts', []) + t.strictSame(JSON.parse(joinedOutput()), { allowScripts: [] }) +}) + t.test('deny-scripts fails on global', async t => { const { npm } = await _mockNpm(t, { config: { global: true }, diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js index 92ea993e3ed..45e7634da5e 100644 --- a/deps/npm/test/lib/commands/exec.js +++ b/deps/npm/test/lib/commands/exec.js @@ -220,6 +220,41 @@ t.test('finds workspace dep first', async t => { t.ok(exists.isFile(), 'bin ran, creating file') }) +t.test('finds workspace dep bin under linked install strategy', async t => { + const { npm } = await loadMockNpm(t, { + config: { + 'install-strategy': 'linked', + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: '@npmcli/npx-workspace-root-test', + workspaces: ['workspace-a', 'tool'], + }), + 'workspace-a': { + 'package.json': JSON.stringify({ + name: 'workspace-a', + dependencies: { tool: '*' }, + }), + }, + tool: { + 'package.json': JSON.stringify({ + name: 'tool', + version: '1.0.0', + bin: { 'npx-test': 'index.js' }, + }), + 'index.js': `#!/usr/bin/env node + require('fs').writeFileSync('npm-exec-test-success', '')`, + }, + }, + }) + + await npm.exec('install', []) + npm.config.set('workspace', ['workspace-a']) + await npm.exec('exec', ['npx-test']) + const exists = await fs.stat(path.join(npm.prefix, 'workspace-a', 'npm-exec-test-success')) + t.ok(exists.isFile(), 'workspace-local bin ran instead of falling back to the registry') +}) + t.test('npx --no-install @npmcli/npx-test', async t => { const registry = new MockRegistry({ tap: t, diff --git a/deps/npm/test/lib/commands/install-scripts.js b/deps/npm/test/lib/commands/install-scripts.js new file mode 100644 index 00000000000..523aba42bdd --- /dev/null +++ b/deps/npm/test/lib/commands/install-scripts.js @@ -0,0 +1,336 @@ +const t = require('tap') +const fs = require('node:fs') +const { resolve } = require('node:path') +const _mockNpm = require('../../fixtures/mock-npm') +const InstallScripts = require('../../../lib/commands/install-scripts.js') + +const mockNpm = async (t, opts = {}) => { + return _mockNpm(t, opts) +} + +const setupProject = ({ allowScripts, withScripts = ['canvas'], noScripts = [] } = {}) => { + const pkg = { + name: 'host', + version: '1.0.0', + dependencies: Object.fromEntries([...withScripts, ...noScripts].map((n) => [n, '*'])), + } + if (allowScripts !== undefined) { + pkg.allowScripts = allowScripts + } + + const lockPackages = { '': pkg } + const nodeModules = {} + for (const name of withScripts) { + nodeModules[name] = { + 'package.json': JSON.stringify({ + name, + version: '1.0.0', + scripts: { install: 'echo install' }, + }), + } + lockPackages[`node_modules/${name}`] = { + version: '1.0.0', + hasInstallScript: true, + resolved: `https://registry.npmjs.org/${name}/-/${name}-1.0.0.tgz`, + } + } + for (const name of noScripts) { + nodeModules[name] = { + 'package.json': JSON.stringify({ name, version: '1.0.0' }), + } + lockPackages[`node_modules/${name}`] = { + version: '1.0.0', + resolved: `https://registry.npmjs.org/${name}/-/${name}-1.0.0.tgz`, + } + } + + return { + 'package.json': JSON.stringify(pkg, null, 2), + 'package-lock.json': JSON.stringify({ + name: pkg.name, + version: pkg.version, + lockfileVersion: 3, + requires: true, + packages: lockPackages, + }), + node_modules: nodeModules, + } +} + +t.test('completion', async t => { + const comp = (argv) => + InstallScripts.completion({ conf: { argv: { remain: argv } } }) + + t.resolveMatch(comp(['npm', 'install-scripts']), ['approve', 'deny', 'ls', 'prune']) + t.resolveMatch(comp(['npm', 'install-scripts', 'approve']), []) + t.resolveMatch(comp(['npm', 'install-scripts', 'deny']), []) + t.resolveMatch(comp(['npm', 'install-scripts', 'ls']), []) + t.resolveMatch(comp(['npm', 'install-scripts', 'prune']), []) + await t.rejects(comp(['npm', 'install-scripts', 'frobnicate']), { + message: 'frobnicate not recognized', + }) +}) + +t.test('install-scripts approve writes a pinned entry', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await npm.exec('install-scripts', ['approve', 'canvas']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) +}) + +t.test('install-scripts approve --all approves every unreviewed package', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas', 'sharp'] }), + config: { all: true }, + }) + await npm.exec('install-scripts', ['approve']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { + 'canvas@1.0.0': true, + 'sharp@1.0.0': true, + }) +}) + +t.test('install-scripts deny writes a name-only false entry', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await npm.exec('install-scripts', ['deny', 'canvas']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { canvas: false }) +}) + +t.test('install-scripts deny --all denies every unreviewed package', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas', 'sharp'] }), + config: { all: true }, + }) + await npm.exec('install-scripts', ['deny']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { canvas: false, sharp: false }) +}) + +t.test('install-scripts ignores allow-scripts-pending and still writes', async t => { + // The namespace exposes listing through `ls`, so a stray + // `allow-scripts-pending` config must not divert approve into list mode. + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + config: { 'allow-scripts-pending': true }, + }) + await npm.exec('install-scripts', ['approve', 'canvas']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) +}) + +t.test('install-scripts ls lists unreviewed packages', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas', 'sharp'] }), + }) + await npm.exec('install-scripts', ['ls']) + const out = joinedOutput() + t.match(out, /2 packages have install scripts not yet covered by allowScripts/) + t.match(out, /canvas@1\.0\.0/) + t.match(out, /sharp@1\.0\.0/) +}) + +t.test('install-scripts ls with no unreviewed says so', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ allowScripts: { canvas: true }, withScripts: ['canvas'] }), + }) + await npm.exec('install-scripts', ['ls']) + t.match(joinedOutput(), /No packages with unreviewed install scripts/) +}) + +t.test('install-scripts ls rejects positional args', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('install-scripts', ['ls', 'canvas']), + /cannot be combined with positional arguments/ + ) +}) + +t.test('install-scripts with no subcommand errors with usage', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('install-scripts', []), + { code: 'EUSAGE' } + ) +}) + +t.test('install-scripts with an unknown subcommand errors', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('install-scripts', ['frobnicate']), + /`frobnicate` is not a recognized subcommand/ + ) +}) + +t.test('install-scripts approve errors on unknown package', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('install-scripts', ['approve', 'not-installed']), + { code: 'ENOMATCH' } + ) +}) + +t.test('install-scripts fails for global installs', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + config: { global: true }, + }) + await t.rejects( + npm.exec('install-scripts', ['approve', 'canvas']), + { code: 'EGLOBAL' } + ) +}) + +t.test('install-scripts prune removes not-installed and no-script entries', async t => { + const { npm, prefix, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + withScripts: ['canvas'], + noScripts: ['no-scripts-pkg'], + allowScripts: { + 'canvas@1.0.0': true, + 'no-scripts-pkg': true, + gone: true, + }, + }), + }) + await npm.exec('install-scripts', ['prune']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) + + const out = joinedOutput() + t.match(out, /Removed 2 unused allowScripts entries:/) + t.match(out, /no-scripts-pkg \(no install scripts\)/) + t.match(out, /gone \(package not installed\)/) +}) + +t.test('install-scripts prune removes unused deny entries too', async t => { + const { npm, prefix } = await mockNpm(t, { + prefixDir: setupProject({ + withScripts: ['canvas'], + allowScripts: { 'canvas@1.0.0': true, 'denied-gone': false }, + }), + }) + await npm.exec('install-scripts', ['prune']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) +}) + +t.test('install-scripts prune removes a stale version pin and drops the field', async t => { + const { npm, prefix, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + withScripts: ['canvas'], + allowScripts: { 'canvas@9.9.9': true }, + }), + }) + await npm.exec('install-scripts', ['prune']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.notOk('allowScripts' in pkg, 'allowScripts field is removed when empty') + // Singular wording for a single entry. + t.match(joinedOutput(), /Removed 1 unused allowScripts entry:/) +}) + +t.test('install-scripts prune --dry-run reports without writing', async t => { + const allowScripts = { 'canvas@1.0.0': true, gone: true } + const { npm, prefix, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'], allowScripts }), + config: { 'dry-run': true }, + }) + await npm.exec('install-scripts', ['prune']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, allowScripts, 'package.json is unchanged') + t.match(joinedOutput(), /Would remove 1 unused allowScripts entry:/) +}) + +t.test('install-scripts prune --json emits a machine-readable summary', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + withScripts: ['canvas'], + allowScripts: { 'canvas@1.0.0': true, gone: true }, + }), + config: { json: true }, + }) + await npm.exec('install-scripts', ['prune']) + + t.strictSame(JSON.parse(joinedOutput()), { + allowScripts: { + removed: [{ key: 'gone', value: true, reason: 'not-installed' }], + dryRun: false, + }, + }) +}) + +t.test('install-scripts prune with nothing unused says so', async t => { + const { npm, prefix, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ + withScripts: ['canvas'], + allowScripts: { 'canvas@1.0.0': true }, + }), + }) + await npm.exec('install-scripts', ['prune']) + + const pkg = JSON.parse(fs.readFileSync(resolve(prefix, 'package.json'), 'utf8')) + t.strictSame(pkg.allowScripts, { 'canvas@1.0.0': true }) + t.match(joinedOutput(), /No unused allowScripts entries\./) +}) + +t.test('install-scripts prune with no allowScripts field says so', async t => { + const { npm, joinedOutput } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await npm.exec('install-scripts', ['prune']) + t.match(joinedOutput(), /No unused allowScripts entries\./) +}) + +t.test('install-scripts prune rejects positional args', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + }) + await t.rejects( + npm.exec('install-scripts', ['prune', 'canvas']), + /cannot be combined with positional arguments/ + ) +}) + +t.test('install-scripts prune rejects --all', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + config: { all: true }, + }) + await t.rejects( + npm.exec('install-scripts', ['prune']), + /cannot be combined with positional arguments or `--all`/ + ) +}) + +t.test('install-scripts prune fails for global installs', async t => { + const { npm } = await mockNpm(t, { + prefixDir: setupProject({ withScripts: ['canvas'] }), + config: { global: true }, + }) + await t.rejects( + npm.exec('install-scripts', ['prune']), + { code: 'EGLOBAL' } + ) +}) diff --git a/deps/npm/test/lib/commands/link.js b/deps/npm/test/lib/commands/link.js index 184f7d64203..11ed182edd9 100644 --- a/deps/npm/test/lib/commands/link.js +++ b/deps/npm/test/lib/commands/link.js @@ -289,6 +289,44 @@ t.test('link global linked pkg to local workspace using args', async t => { t.matchSnapshot(await printLinks(), 'should create a local symlink to global pkg') }) +t.test('link --workspace --save targets the workspace manifest, not the root', async t => { + const { link, prefix } = await mockLink(t, { + globalPrefixDir: { + node_modules: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + }), + }, + }, + }, + prefixDir: { + 'package.json': JSON.stringify({ + name: 'my-project', + version: '1.0.0', + workspaces: ['packages/*'], + }), + packages: { + x: { + 'package.json': JSON.stringify({ + name: 'x', + version: '1.0.0', + }), + }, + }, + }, + config: { workspace: 'x', save: true }, + }) + + await link.exec(['a']) + + const root = JSON.parse(fs.readFileSync(join(prefix, 'package.json'), 'utf8')) + const ws = JSON.parse(fs.readFileSync(join(prefix, 'packages', 'x', 'package.json'), 'utf8')) + t.notOk(root.dependencies, 'root manifest should not get the dependency') + t.match(ws.dependencies, { a: /^file:/ }, 'workspace manifest should get the file: dependency') +}) + t.test('link pkg already in global space', async t => { const { npm, link, printLinks, prefix } = await mockLink(t, { globalPrefixDir: { @@ -523,3 +561,104 @@ t.test('test linked installed as symlinks', async t => { t.matchSnapshot(await printLinks(), 'linked package should not be installed') }) + +t.test('link threads allowScripts policy through to arborist', async t => { + const capturedOpts = [] + const FakeArborist = function (opts) { + capturedOpts.push(opts) + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.loadActual = async () => ({ isLink: false, children: new Map() }) + FakeArborist.prototype.reify = async () => {} + + const mock = await mockNpm(t, { + command: 'link', + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await mock.npm.exec('link', ['canvas']) + // the local Arborist is the last one constructed in linkInstall + const localOpts = capturedOpts[capturedOpts.length - 1] + t.strictSame(localOpts.allowScripts, { canvas: true }, + 'local arborist opts.allowScripts populated from package.json') +}) + +t.test('link threads allowScripts policy to the global install', async t => { + const capturedOpts = [] + const FakeArborist = function (opts) { + capturedOpts.push(opts) + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.loadActual = async () => ({ isLink: false, children: new Map() }) + FakeArborist.prototype.reify = async () => {} + + const mock = await mockNpm(t, { + command: 'link', + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await mock.npm.exec('link', ['canvas']) + // the global Arborist is constructed first; its missing-package install + // must carry the project policy. + t.strictSame(capturedOpts[0].allowScripts, { canvas: true }, + 'global arborist opts.allowScripts populated from package.json') +}) + +t.test('link runs the strict-allow-scripts preflight before the global install', async t => { + // The mocked preflight stands in for strict mode finding an uncovered + // script. It must run and throw before the global reify. + const calls = [] + const FakeArborist = function (opts) { + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.loadActual = async () => ({ isLink: false, children: new Map() }) + FakeArborist.prototype.reify = async () => { + calls.push('reify') + } + + const mock = await mockNpm(t, { + command: 'link', + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + '{LIB}/utils/strict-allow-scripts-preflight.js': async () => { + calls.push('preflight') + throw Object.assign(new Error('blocked'), { code: 'ESTRICTALLOWSCRIPTS' }) + }, + }, + }) + await t.rejects( + mock.npm.exec('link', ['canvas']), + { code: 'ESTRICTALLOWSCRIPTS' }, + 'the strict preflight blocks the link' + ) + t.strictSame(calls, ['preflight'], + 'preflight ran and the global reify never executed') +}) diff --git a/deps/npm/test/lib/commands/login.js b/deps/npm/test/lib/commands/login.js index 55568edd09f..4ebc7147e46 100644 --- a/deps/npm/test/lib/commands/login.js +++ b/deps/npm/test/lib/commands/login.js @@ -130,6 +130,19 @@ t.test('web', t => { }) t.match(outputs[0], '/npm-cli-test/login/cli/00000000-0000-0000-0000-000000000000') }) + t.test('proxy registry whose doneUrl points at the canonical registry', async t => { + // Regression for npm/cli#8875: a proxy/mirror returns a doneUrl on registry.npmjs.org. + // npm must poll the configured proxy where the session lives, not the canonical registry. + const proxy = 'https://proxy.registry.example/' + const { npm, registry, login, rc } = await mockLogin(t, { + registry: proxy, + config: { 'auth-type': 'web', registry: proxy }, + }) + registry.weblogin({ token: 'npm_proxy-token', doneRegistry: 'https://registry.npmjs.org' }) + await login.exec([]) + t.same(npm.config.get('//proxy.registry.example/:_authToken'), 'npm_proxy-token') + t.match(rc(), { '//proxy.registry.example/:_authToken': 'npm_proxy-token' }) + }) t.test('server error', async t => { const { registry, login } = await mockLogin(t, { config: { 'auth-type': 'web' }, diff --git a/deps/npm/test/lib/commands/ls.js b/deps/npm/test/lib/commands/ls.js index ab98773bc68..899a2b81690 100644 --- a/deps/npm/test/lib/commands/ls.js +++ b/deps/npm/test/lib/commands/ls.js @@ -5332,6 +5332,25 @@ t.test('ls --install-strategy=linked', async t => { node_modules: { 'workspace-a': t.fixture('symlink', '../packages/workspace-a'), // workspace-b intentionally NOT linked (undeclared in dependencies) + // The hidden lockfile a real linked install writes records only the + // declared workspace as linked into root node_modules, so loadActual + // resolves workspace-b's root edge as missing (the undeclared-workspace case). + '.package-lock.json': JSON.stringify({ + lockfileVersion: 3, + requires: true, + packages: { + 'node_modules/workspace-a': { + resolved: 'packages/workspace-a', + link: true, + }, + 'packages/workspace-a': { + version: '1.0.0', + }, + 'packages/workspace-b': { + version: '1.0.0', + }, + }, + }), }, }, }) @@ -5339,6 +5358,7 @@ t.test('ls --install-strategy=linked', async t => { const output = cleanCwd(result()) t.notMatch(output, /UNMET DEPENDENCY/, 'should not report undeclared workspace as UNMET DEPENDENCY') t.match(output, /workspace-a/, 'should list declared workspace') + t.match(output, /workspace-b/, 'should list undeclared workspace (npm/cli#9618)') }) t.test('should not report devDeps of store packages as UNMET DEPENDENCY', async t => { @@ -5397,7 +5417,20 @@ t.test('ls --install-strategy=linked', async t => { }, }, node_modules: { - // workspace-a is declared but its symlink is missing + // workspace-a is declared but its symlink is missing. + // The hidden lockfile records the workspace target without a root + // node_modules link, so loadActual resolves the declared workspace's + // root edge as missing (the declared-but-missing case), which must + // still be reported as UNMET DEPENDENCY. + '.package-lock.json': JSON.stringify({ + lockfileVersion: 3, + requires: true, + packages: { + 'packages/workspace-a': { + version: '1.0.0', + }, + }, + }), }, }, }) diff --git a/deps/npm/test/lib/commands/outdated.js b/deps/npm/test/lib/commands/outdated.js index e3709bf7c2b..34b8ea75190 100644 --- a/deps/npm/test/lib/commands/outdated.js +++ b/deps/npm/test/lib/commands/outdated.js @@ -57,6 +57,24 @@ const packument = spec => { }, }, }, + timed: { + name: 'timed', + 'dist-tags': { + latest: '2.0.0', + }, + versions: { + '1.0.0': { + version: '1.0.0', + }, + '2.0.0': { + version: '2.0.0', + }, + }, + time: { + '1.0.0': '2020-01-01T00:00:00.000Z', + '2.0.0': '2020-06-01T00:00:00.000Z', + }, + }, } if (spec.name === 'eta') { @@ -731,3 +749,57 @@ t.test('dependent location', async t => { ) }) }) + +t.test('min-release-age-exclude', async t => { + const prefixDir = { + 'package.json': JSON.stringify({ + name: 'project', + version: '1.0.0', + dependencies: { + timed: '^1.0.0', + }, + }, null, 2), + node_modules: { + timed: { + 'package.json': JSON.stringify({ + name: 'timed', + version: '1.0.0', + }, null, 2), + }, + }, + } + + await t.test('before hides the newer version', async t => { + const { outdated, joinedOutput } = await mockNpm(t, { + prefixDir, + config: { before: new Date('2020-03-01') }, + }) + await outdated.exec([]) + t.notMatch(joinedOutput(), 'timed', 'newer version filtered out by before') + }) + + await t.test('exact-name exclude restores the newer version', async t => { + const { outdated, joinedOutput } = await mockNpm(t, { + prefixDir, + config: { + before: new Date('2020-03-01'), + 'min-release-age-exclude': ['timed'], + }, + }) + await outdated.exec([]) + t.match(joinedOutput(), 'timed', 'excluded package is reported as outdated') + t.match(joinedOutput(), '2.0.0', 'latest 2.0.0 is surfaced') + }) + + await t.test('glob exclude restores the newer version', async t => { + const { outdated, joinedOutput } = await mockNpm(t, { + prefixDir, + config: { + before: new Date('2020-03-01'), + 'min-release-age-exclude': ['tim*'], + }, + }) + await outdated.exec([]) + t.match(joinedOutput(), '2.0.0', 'glob-excluded package shows newer version') + }) +}) diff --git a/deps/npm/test/lib/commands/prune.js b/deps/npm/test/lib/commands/prune.js index 65cfba5e5c0..235ca134ce1 100644 --- a/deps/npm/test/lib/commands/prune.js +++ b/deps/npm/test/lib/commands/prune.js @@ -19,3 +19,30 @@ t.test('should prune using Arborist', async (t) => { }) await npm.exec('prune', []) }) + +t.test('prune threads allowScripts policy through to arborist', async t => { + let capturedOpts + const FakeArborist = function (opts) { + capturedOpts = opts + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.prune = async () => {} + + const { npm } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await npm.exec('prune', []) + t.strictSame(capturedOpts.allowScripts, { canvas: true }, + 'opts.allowScripts populated from package.json') +}) diff --git a/deps/npm/test/lib/commands/publish.js b/deps/npm/test/lib/commands/publish.js index acf8c4c96a9..b204f7452a6 100644 --- a/deps/npm/test/lib/commands/publish.js +++ b/deps/npm/test/lib/commands/publish.js @@ -1624,3 +1624,37 @@ t.test('oidc token exchange - provenance', (t) => { t.end() }) + +t.test('passes script-shell config to lifecycle hooks', async t => { + const CAPTURED = [] + const { npm, registry } = await loadNpmWithRegistry(t, { + config: { + ...auth, + 'script-shell': '/bin/bash', + }, + prefixDir: { + 'package.json': JSON.stringify({ + ...pkgJson, + scripts: { + prepublishOnly: 'exit 0', + publish: 'exit 0', + postpublish: 'exit 0', + }, + }), + }, + mocks: { + '@npmcli/run-script': async (opts) => { + CAPTURED.push(opts) + }, + }, + }) + + registry.publish(pkg, {}) + await npm.exec('publish', []) + + for (const event of ['prepublishOnly', 'publish', 'postpublish']) { + const rs = CAPTURED.find(r => r.event === event) + t.ok(rs, `ran ${event}`) + t.equal(rs?.scriptShell, '/bin/bash', `${event} receives scriptShell`) + } +}) diff --git a/deps/npm/test/lib/commands/query.js b/deps/npm/test/lib/commands/query.js index 40dadc88858..cb9230c93fb 100644 --- a/deps/npm/test/lib/commands/query.js +++ b/deps/npm/test/lib/commands/query.js @@ -160,6 +160,61 @@ t.test('linked node', async t => { t.matchSnapshot(joinedOutput(), 'should return linked node res') }) +t.test('linked strategy reports logical location, not store backing path', async t => { + /* linked layout: nopt (direct) symlinked to its store key, abbrev a transitive dep of nopt */ + const linkedDir = { + prefixDir: { + node_modules: { + nopt: t.fixture('symlink', '.store/nopt-hash/node_modules/nopt'), + '.store': { + 'nopt-hash': { + node_modules: { + nopt: { + 'package.json': JSON.stringify({ + name: 'nopt', + version: '7.2.1', + dependencies: { abbrev: '^2.0.0' }, + }), + }, + abbrev: t.fixture('symlink', '../../abbrev-hash/node_modules/abbrev'), + }, + }, + 'abbrev-hash': { + node_modules: { + abbrev: { + 'package.json': JSON.stringify({ name: 'abbrev', version: '2.0.0' }), + }, + }, + }, + }, + }, + 'package.json': JSON.stringify({ + name: 'project', + version: '1.0.0', + dependencies: { nopt: '^7.0.0' }, + }), + }, + } + + await t.test(':root > * reports the logical link location', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, linkedDir) + await npm.exec('query', [':root > *']) + const res = JSON.parse(joinedOutput()) + t.equal(res.length, 1, 'returns a single result, not the store node duplicate') + t.equal(res[0].location, 'node_modules/nopt', 'reports the logical location') + t.match(res[0].realpath, /\.store/, 'realpath still resolves to the store') + }) + + await t.test(':root * keeps direct deps logical and transitive deps canonical', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, linkedDir) + await npm.exec('query', [':root *']) + const byName = Object.fromEntries(JSON.parse(joinedOutput()).map(n => [n.name, n.location])) + t.equal(byName.nopt, 'node_modules/nopt', 'direct dep keeps its logical location') + t.equal(byName.abbrev, 'node_modules/.store/abbrev-hash/node_modules/abbrev', + 'transitive dep reports its canonical store key, not a consumer symlink') + }) +}) + t.test('global', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { config: { @@ -434,3 +489,24 @@ t.test('missing', async t => { await npm.exec('query', [':missing']) t.matchSnapshot(joinedOutput(), 'should return missing node') }) + +t.test('linked strategy surfaces undeclared workspaces', async t => { + // npm/cli#9618: undeclared workspaces are not symlinked into root node_modules under linked, but must remain visible to `npm query`. + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { 'install-strategy': 'linked' }, + prefixDir: { + 'package.json': JSON.stringify({ + name: 'root', + version: '1.0.0', + workspaces: ['packages/*'], + }), + packages: { + a: { 'package.json': JSON.stringify({ name: 'a', version: '1.0.0' }) }, + b: { 'package.json': JSON.stringify({ name: 'b', version: '1.0.0' }) }, + }, + }, + }) + await npm.exec('query', [':root > *']) + const names = JSON.parse(joinedOutput()).map(n => n.name).sort() + t.same(names, ['a', 'b'], 'both undeclared workspaces are listed') +}) diff --git a/deps/npm/test/lib/commands/rebuild.js b/deps/npm/test/lib/commands/rebuild.js index de91fd3471b..1336fa1e7f2 100644 --- a/deps/npm/test/lib/commands/rebuild.js +++ b/deps/npm/test/lib/commands/rebuild.js @@ -244,6 +244,31 @@ t.test('emits Phase 1 advisory warning for unreviewed install scripts', async t ) }) +t.test('global advisory warning points at npm config set, not approve-scripts', async t => { + const { npm, logs } = await setupMockNpm(t, { + config: { + global: true, + }, + globalPrefixDir: { + node_modules: { + canvas: { + 'index.js': '', + 'package.json': JSON.stringify({ + name: 'canvas', + version: '1.0.0', + scripts: { install: 'echo install' }, + }), + }, + }, + }, + }) + await npm.exec('rebuild', []) + const warn = logs.warn.byTitle('rebuild').join('\n') + t.match(warn, /install scripts not yet covered by allowScripts/) + t.match(warn, /npm config set allow-scripts=canvas/) + t.notMatch(warn, /approve-scripts/) +}) + t.test('no advisory warning when allowScripts covers the package', async t => { const { npm, logs } = await setupMockNpm(t, { prefixDir: { @@ -281,3 +306,49 @@ t.test('no advisory warning when allowScripts covers the package', async t => { await npm.exec('rebuild', []) t.strictSame(logs.warn.byTitle('rebuild'), []) }) + +t.test('rebuild never targets a bundled dependency', async t => { + const { npm, prefix: path } = await setupMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + dependencies: { parent: '1.0.0' }, + }), + node_modules: { + parent: { + 'index.js': '', + 'package.json': JSON.stringify({ + name: 'parent', + version: '1.0.0', + bundleDependencies: ['bcrypt'], + dependencies: { bcrypt: '1.0.0' }, + }), + node_modules: { + bcrypt: { + 'index.js': '', + 'package.json': JSON.stringify({ + name: 'bcrypt', + version: '1.0.0', + bin: 'index.js', + scripts: { + install: "node -e \"require('fs').writeFileSync('ran', '')\"", + }, + }), + }, + }, + }, + }, + }, + }) + + const ranFile = resolve(path, 'node_modules/parent/node_modules/bcrypt/ran') + t.throws(() => fs.statSync(ranFile)) + + await npm.exec('rebuild', ['bcrypt']) + + t.throws( + () => fs.statSync(ranFile), + 'bundled bcrypt install script must not run' + ) +}) diff --git a/deps/npm/test/lib/commands/stage/approve.js b/deps/npm/test/lib/commands/stage/approve.js index d62ea04d431..dac2b244764 100644 --- a/deps/npm/test/lib/commands/stage/approve.js +++ b/deps/npm/test/lib/commands/stage/approve.js @@ -27,6 +27,7 @@ t.test('throws usageError without stage-id', async t => { }) await t.rejects(npm.exec('stage', ['approve']), { code: 'EUSAGE', + message: /npm stage approve /, }) }) diff --git a/deps/npm/test/lib/commands/token.js b/deps/npm/test/lib/commands/token.js index 56ab906d921..34297a923c8 100644 --- a/deps/npm/test/lib/commands/token.js +++ b/deps/npm/test/lib/commands/token.js @@ -13,6 +13,7 @@ const tokens = [ { key: 'abcd1234abcd1234', token: 'efgh5678efgh5678', + name: 'abcd001', cidr_whitelist: null, readonly: false, created: now, @@ -21,6 +22,7 @@ const tokens = [ { key: 'abcd1256', token: 'hgfe8765', + name: 'abcd002', cidr_whitelist: ['192.168.1.1/32'], readonly: true, created: now, @@ -63,9 +65,9 @@ t.test('token list', async t => { registry.getTokens(tokens) await npm.exec('token', []) t.strictSame(outputs, [ - `Token efgh5678efgh5678… with id abcd123 created ${now.slice(0, 10)}`, + `Token efgh5678efgh5678… with id abcd123 name abcd001 created ${now.slice(0, 10)}`, '', - `Token hgfe8765… with id abcd125 created ${now.slice(0, 10)}`, + `Token hgfe8765… with id abcd125 name abcd002 created ${now.slice(0, 10)}`, 'with IP whitelist: 192.168.1.1/32', '', ]) @@ -104,9 +106,9 @@ t.test('token list parseable output', async t => { registry.getTokens(tokens) await npm.exec('token', []) t.strictSame(outputs, [ - 'key\ttoken\tcreated\treadonly\tCIDR whitelist', - `abcd1234abcd1234\tefgh5678efgh5678\t${now}\tfalse\t`, - `abcd1256\thgfe8765\t${now}\ttrue\t192.168.1.1/32`, + 'key\ttoken\tid\tname\tcreated\treadonly\tCIDR whitelist', + `abcd1234abcd1234\tefgh5678efgh5678\tabcd123\tabcd001\t${now}\tfalse\t`, + `abcd1256\thgfe8765\tabcd125\tabcd002\t${now}\ttrue\t192.168.1.1/32`, ]) }) diff --git a/deps/npm/test/lib/commands/uninstall.js b/deps/npm/test/lib/commands/uninstall.js index 2ede1c4c1a7..049bf2da8b1 100644 --- a/deps/npm/test/lib/commands/uninstall.js +++ b/deps/npm/test/lib/commands/uninstall.js @@ -214,3 +214,30 @@ t.test('completion', async t => { const res = await uninstall.completion({ conf: { argv: { remain: ['npm', 'uninstall'] } } }) t.match(res, ['bar', 'foo']) }) + +t.test('uninstall threads allowScripts policy through to arborist', async t => { + let capturedOpts + const FakeArborist = function (opts) { + capturedOpts = opts + this.options = opts + this.actualTree = { inventory: new Map() } + } + FakeArborist.prototype.reify = async () => {} + + const { npm } = await _mockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'host', + version: '1.0.0', + allowScripts: { canvas: true }, + }), + }, + mocks: { + '@npmcli/arborist': FakeArborist, + '{LIB}/utils/reify-finish.js': async () => {}, + }, + }) + await npm.exec('uninstall', ['canvas']) + t.strictSame(capturedOpts.allowScripts, { canvas: true }, + 'opts.allowScripts populated from package.json') +}) diff --git a/deps/npm/test/lib/utils/allow-scripts-prune.js b/deps/npm/test/lib/utils/allow-scripts-prune.js new file mode 100644 index 00000000000..880b1dfe343 --- /dev/null +++ b/deps/npm/test/lib/utils/allow-scripts-prune.js @@ -0,0 +1,90 @@ +const t = require('tap') +const { classifyUnusedEntries } = require('../../../lib/utils/allow-scripts-prune.js') + +// Minimal registry node: `matches` derives name/version from the resolved URL. +const node = ({ name = 'pkg', version = '1.0.0' } = {}) => ({ + name, + version, + isRegistryDependency: true, + resolved: `https://registry.npmjs.org/${name}/-/${name}-${version}.tgz`, +}) + +const withScripts = (overrides) => ({ node: node(overrides), hasScripts: true }) +const noScripts = (overrides) => ({ node: node(overrides), hasScripts: false }) + +t.test('empty / nullish policy', t => { + t.same(classifyUnusedEntries({}, []), { remaining: {}, removed: [] }) + t.same(classifyUnusedEntries(null, []), { remaining: {}, removed: [] }) + t.same(classifyUnusedEntries(undefined, [withScripts()]), { remaining: {}, removed: [] }) + t.end() +}) + +t.test('keeps entries that match an installed package with scripts', t => { + const { remaining, removed } = classifyUnusedEntries( + { canvas: true, 'esbuild@1.0.0': true }, + [withScripts({ name: 'canvas' }), withScripts({ name: 'esbuild', version: '1.0.0' })] + ) + t.same(remaining, { canvas: true, 'esbuild@1.0.0': true }) + t.same(removed, []) + t.end() +}) + +t.test('removes entries for packages no longer installed', t => { + const { remaining, removed } = classifyUnusedEntries( + { canvas: true, gone: true }, + [withScripts({ name: 'canvas' })] + ) + t.same(remaining, { canvas: true }) + t.same(removed, [{ key: 'gone', value: true, reason: 'not-installed' }]) + t.end() +}) + +t.test('removes entries whose package no longer has install scripts', t => { + const { remaining, removed } = classifyUnusedEntries( + { canvas: true }, + [noScripts({ name: 'canvas' })] + ) + t.same(remaining, {}) + t.same(removed, [{ key: 'canvas', value: true, reason: 'no-scripts' }]) + t.end() +}) + +t.test('a matching version with scripts keeps the entry even if another lacks them', t => { + const { remaining, removed } = classifyUnusedEntries( + { canvas: true }, + [noScripts({ name: 'canvas', version: '1.0.0' }), withScripts({ name: 'canvas', version: '2.0.0' })] + ) + t.same(remaining, { canvas: true }) + t.same(removed, []) + t.end() +}) + +t.test('version-pinned entry is unused when that exact version is not installed', t => { + const { remaining, removed } = classifyUnusedEntries( + { 'canvas@1.0.0': true }, + [withScripts({ name: 'canvas', version: '2.0.0' })] + ) + t.same(remaining, {}) + t.same(removed, [{ key: 'canvas@1.0.0', value: true, reason: 'not-installed' }]) + t.end() +}) + +t.test('prunes unused deny (false) entries the same way', t => { + const { remaining, removed } = classifyUnusedEntries( + { 'denied-gone': false, 'denied-here': false }, + [withScripts({ name: 'denied-here' })] + ) + t.same(remaining, { 'denied-here': false }) + t.same(removed, [{ key: 'denied-gone', value: false, reason: 'not-installed' }]) + t.end() +}) + +t.test('keeps unparseable keys untouched', t => { + const { remaining, removed } = classifyUnusedEntries( + { 'a b': true, gone: true }, + [withScripts({ name: 'canvas' })] + ) + t.same(remaining, { 'a b': true }) + t.same(removed, [{ key: 'gone', value: true, reason: 'not-installed' }]) + t.end() +}) diff --git a/deps/npm/test/lib/utils/allow-scripts-writer.js b/deps/npm/test/lib/utils/allow-scripts-writer.js index 56314f8eb5a..8edf25be307 100644 --- a/deps/npm/test/lib/utils/allow-scripts-writer.js +++ b/deps/npm/test/lib/utils/allow-scripts-writer.js @@ -24,6 +24,23 @@ const node = (overrides = {}) => { } } +// A registry node with no `resolved` URL in the lockfile. Its trusted name +// comes from a dependency edge, but its version isn't trustable, so +// versionedKeyFor returns null (npm/cli#9558). +const noResolvedNode = (overrides = {}) => { + const name = overrides.name ?? 'pkg' + const version = overrides.version ?? '1.0.0' + return { + name, + packageName: overrides.packageName ?? name, + version, + resolved: undefined, + location: `node_modules/${name}`, + isRegistryDependency: true, + edgesIn: new Set([{ name, spec: overrides.spec ?? `^${version}` }]), + } +} + t.test('nameKeyFor / versionedKeyFor — registry', async t => { const n = node({ name: 'canvas', version: '2.11.0' }) t.equal(nameKeyFor(n), 'canvas') @@ -45,6 +62,48 @@ t.test('nameKeyFor / versionedKeyFor — file', async t => { t.equal(versionedKeyFor(n), 'file:../local') }) +t.test('nameKeyFor / versionedKeyFor — local directory link target', async t => { + const targetPath = path.resolve('local') + const n = { + name: 'local', + packageName: 'local', + version: '1.0.0', + resolved: null, + path: targetPath, + realpath: targetPath, + linksIn: new Set([{ resolved: 'file:../local' }]), + } + + t.equal(nameKeyFor(n), 'file:../local') + t.equal(versionedKeyFor(n), 'file:../local') + + t.strictSame( + applyApprovalForPackage({}, [n], { pin: true }).allowScripts, + { 'file:../local': true } + ) + t.match( + applyApprovalForPackage({ 'file:local': false }, [n], { pin: true }).warning, + /denied|versioned deny/ + ) +}) + +t.test('nameKeyFor / versionedKeyFor — empty link target has no portable file key', async t => { + const targetPath = path.resolve('local') + const n = { + name: 'local', + packageName: 'local', + version: '1.0.0', + resolved: null, + path: targetPath, + realpath: targetPath, + linksIn: new Set(), + } + + t.equal(nameKeyFor(n), null) + t.equal(versionedKeyFor(n), null) + t.strictSame(applyApprovalForPackage({}, [n], { pin: true }).allowScripts, {}) +}) + t.test('isSingleVersionPin', async t => { t.ok(isSingleVersionPin('pkg@1.2.3')) t.notOk(isSingleVersionPin('pkg')) @@ -172,6 +231,73 @@ t.test('applyApprovalForPackage — keeps existing pin matching one installed, a t.strictSame(allowScripts, { 'lodash@3.10.1': true, 'lodash@4.17.21': true }) }) +t.test('versionedKeyFor — registry dep without a resolved URL has no trustable version', async t => { + const n = noResolvedNode({ name: 'esbuild', version: '0.25.0' }) + t.equal(nameKeyFor(n), 'esbuild', 'name still recoverable from the dependency edge') + t.equal(versionedKeyFor(n), null, 'version cannot be trusted without a resolved URL') +}) + +t.test('applyApprovalForPackage — pin mode falls back to name-only when version is not trustable', async t => { + const { allowScripts, changes, warning } = applyApprovalForPackage( + {}, + [noResolvedNode({ name: 'esbuild', version: '0.25.0' })], + { pin: true } + ) + t.strictSame(allowScripts, { esbuild: true }, 'approved by name instead of silently skipped') + t.strictSame(changes, [{ key: 'esbuild', change: 'added' }]) + t.match(warning, /no "resolved" URL/, 'explains why a pin was not written') +}) + +t.test('applyApprovalForPackage — mixed resolved/no-resolved collapses to one name-only entry', async t => { + const { allowScripts, warning } = applyApprovalForPackage( + {}, + [ + node({ name: 'esbuild', version: '0.21.5' }), + noResolvedNode({ name: 'esbuild', version: '0.25.0' }), + ], + { pin: true } + ) + t.strictSame(allowScripts, { esbuild: true }, 'no redundant pin alongside the name-only entry') + t.match(warning, /no "resolved" URL/) +}) + +t.test('applyApprovalForPackage — existing pin collapses into name-only when a sibling cannot be pinned', async t => { + const { allowScripts, changes } = applyApprovalForPackage( + { 'esbuild@0.21.5': true }, + [ + node({ name: 'esbuild', version: '0.21.5' }), + noResolvedNode({ name: 'esbuild', version: '0.25.0' }), + ], + { pin: true } + ) + t.strictSame(allowScripts, { esbuild: true }) + t.match(changes, [ + { key: 'esbuild@0.21.5', change: 'removed-pinned-allow' }, + { key: 'esbuild', change: 'added' }, + ]) +}) + +t.test('applyApprovalForPackage — no-resolved dep already approved by name is a no-op', async t => { + const { allowScripts, changes } = applyApprovalForPackage( + { esbuild: true }, + [noResolvedNode({ name: 'esbuild', version: '0.25.0' })], + { pin: true } + ) + t.strictSame(allowScripts, { esbuild: true }) + t.strictSame(changes, []) +}) + +t.test('applyApprovalForPackage — no-resolved dep with name-only deny still loses to the deny', async t => { + const { allowScripts, changes, warning } = applyApprovalForPackage( + { esbuild: false }, + [noResolvedNode({ name: 'esbuild', version: '0.25.0' })], + { pin: true } + ) + t.strictSame(allowScripts, { esbuild: false }, 'deny wins; nothing approved') + t.strictSame(changes, []) + t.match(warning, /esbuild is denied/) +}) + t.test('applyDenyForPackage — empty allowScripts adds name-only false', async t => { const { allowScripts, changes } = applyDenyForPackage( {}, @@ -578,7 +704,7 @@ t.test('denyWarning branches on key shape per RFC §approve-scripts', async t => { pin: true } ) t.match(pinned.warning, /versioned deny/) - t.match(pinned.warning, /npm deny-scripts canvas/) + t.match(pinned.warning, /npm install-scripts deny canvas/) t.match(pinned.warning, /widen the deny to all versions/) t.match(pinned.warning, /remove the entry/) @@ -589,7 +715,7 @@ t.test('denyWarning branches on key shape per RFC §approve-scripts', async t => { pin: true } ) t.match(multi.warning, /versioned deny/) - t.match(multi.warning, /npm deny-scripts canvas/) + t.match(multi.warning, /npm install-scripts deny canvas/) }) t.test('denyWarning: tag-type key (pkg@latest: false) is name-only', async t => { diff --git a/deps/npm/test/lib/utils/check-allow-scripts.js b/deps/npm/test/lib/utils/check-allow-scripts.js index 8dea9674375..c67ec2a7cd7 100644 --- a/deps/npm/test/lib/utils/check-allow-scripts.js +++ b/deps/npm/test/lib/utils/check-allow-scripts.js @@ -57,6 +57,20 @@ t.test('returns [] when ignoreScripts is set', async t => { t.strictSame(result, []) }) +t.test('returns unreviewed nodes when ignoreScripts is set but includeWhenIgnored is true', async t => { + const checkAllowScripts = mockCheck(t) + const result = await checkAllowScripts({ + arb: arb({ + nodes: [node({ name: 'a', scripts: { install: 'do-stuff' } })], + ignoreScripts: true, + }), + npm: { flatOptions: {} }, + includeWhenIgnored: true, + }) + t.equal(result.length, 1) + t.strictSame(result[0].scripts, { install: 'do-stuff' }) +}) + t.test('returns [] when dangerouslyAllowAllScripts is set', async t => { const checkAllowScripts = mockCheck(t) const result = await checkAllowScripts({ @@ -135,46 +149,6 @@ t.test('prepare counts for non-registry sources only', async t => { t.equal(result[0].node.name, 'git-pkg') }) -t.test('detects synthetic node-gyp via binding.gyp runtime check', async t => { - const checkAllowScripts = mockCheck(t, { - '@npmcli/arborist/lib/install-scripts.js': async (n) => { - if (n.path === '/has-bindings') { - return { install: 'node-gyp rebuild' } - } - return {} - }, - }) - - const result = await checkAllowScripts({ - arb: arb({ - nodes: [ - node({ name: 'native', path: '/has-bindings' }), - node({ name: 'pure-js', path: '/no-bindings' }), - ], - }), - npm: { flatOptions: {} }, - }) - t.equal(result.length, 1) - t.equal(result[0].node.name, 'native') - t.strictSame(result[0].scripts, { install: 'node-gyp rebuild' }) -}) - -t.test('skips node-gyp detection when gypfile is explicitly false', async t => { - // Mock returns no scripts to simulate the gypfile:false short-circuit - // inside getInstallScripts. - const checkAllowScripts = mockCheck(t, { - '@npmcli/arborist/lib/install-scripts.js': async () => ({}), - }) - - const result = await checkAllowScripts({ - arb: arb({ - nodes: [node({ name: 'opt-out', gypfile: false })], - }), - npm: { flatOptions: {} }, - }) - t.strictSame(result, []) -}) - t.test('skips approved nodes', async t => { const checkAllowScripts = mockCheck(t) const result = await checkAllowScripts({ @@ -238,7 +212,7 @@ t.test('survives missing actualTree', async t => { t.strictSame(result, []) }) -t.test('bundled dep with install scripts is reported as unreviewed regardless of policy', async t => { +t.test('bundled dep with install scripts is never reported (never runs, never pending)', async t => { const checkAllowScripts = mockCheck(t) const bundled = node({ name: 'bundled-pkg', @@ -251,13 +225,12 @@ t.test('bundled dep with install scripts is reported as unreviewed regardless of const result = await checkAllowScripts({ arb: arb({ nodes: [bundled], - // Policy explicitly allows the bundled name — the matcher should - // still return null and the walker should still flag the bundled - // dep as unreviewed. + // Even with an explicit allow entry, a bundled dep never runs its + // install scripts and is never counted as pending, so the walker + // must not flag it. allowScripts: { 'bundled-pkg': true }, }), npm: { flatOptions: {} }, }) - t.equal(result.length, 1, 'bundled dep flagged despite explicit allow entry') - t.equal(result[0].node, bundled) + t.strictSame(result, [], 'bundled dep never flagged') }) diff --git a/deps/npm/test/lib/utils/queryable.js b/deps/npm/test/lib/utils/queryable.js index 7716d203261..5eca84214cd 100644 --- a/deps/npm/test/lib/utils/queryable.js +++ b/deps/npm/test/lib/utils/queryable.js @@ -963,3 +963,42 @@ t.test('bracket lovers', async t => { 'any top-level item cannot be parsed with square bracket notation' ) }) + +t.test('forbidden keys', async t => { + // defensive cleanup in case any assertion below unexpectedly mutates the prototype + t.teardown(() => { + delete Object.prototype.scripts + delete Object.prototype.polluted + }) + + for (const key of ['__proto__', 'constructor', 'prototype']) { + t.throws( + () => new Queryable({ name: 'demo' }).set(`${key}.scripts.postinstall`, 'cmd'), + { code: 'EFORBIDDENKEY' }, + `should throw EFORBIDDENKEY when '${key}' is used as a top-level key` + ) + } + + t.throws( + () => new Queryable({}).set('a.__proto__.scripts.postinstall', 'cmd'), + { code: 'EFORBIDDENKEY' }, + 'should throw when __proto__ appears nested in a dotted path' + ) + + t.throws( + () => new Queryable({}).set('foo[__proto__].scripts.postinstall', 'cmd'), + { code: 'EFORBIDDENKEY' }, + 'should throw when __proto__ is used via square bracket notation' + ) + + t.throws( + () => new Queryable({ scripts: { postinstall: 'x' } }).delete('__proto__.scripts'), + { code: 'EFORBIDDENKEY' }, + 'should block forbidden keys via delete() as well as set()' + ) + + t.notOk( + Object.prototype.scripts, + 'Object.prototype must not be polluted by any forbidden-key attempt' + ) +}) diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js index b1bc92b1c77..0f2be24b024 100644 --- a/deps/npm/test/lib/utils/reify-output.js +++ b/deps/npm/test/lib/utils/reify-output.js @@ -391,6 +391,25 @@ t.test('added packages should be looked up within returned tree', async t => { t.matchSnapshot(out) }) + + t.test('linked store package counted though absent from actualTree', async t => { + const out = await mockReify(t, { + actualTree: { + name: 'foo', + inventory: { + has: () => false, + }, + }, + diff: { + children: [ + { action: 'ADD', ideal: { path: 'test/baz', name: 'baz', isInStore: true, isLink: false, package: { version: '1.0.0' } } }, + { action: 'ADD', ideal: { path: 'test/baz-link', name: 'baz', isInStore: false, isLink: true, package: { version: '1.0.0' } } }, + ], + }, + }) + + t.matchSnapshot(out) + }) }) t.test('prints dedupe difference on dry-run', async t => { @@ -484,7 +503,40 @@ t.test('prints unreviewed install scripts summary', async t => { t.match(warn, /2 packages have install scripts not yet covered/) t.match(warn, /canvas@2\.11\.0 \(install: node-gyp rebuild\)/) t.match(warn, /sharp@0\.33\.2 \(preinstall: pre; postinstall: post\)/) - t.match(warn, /npm approve-scripts --allow-scripts-pending/) + t.match(warn, /npm install-scripts ls/) +}) + +t.test('global install suggests --allow-scripts, not approve-scripts', async t => { + const mockReifyWithExtras = async (t, reify, extras, config = {}) => { + const mock = await mockNpm(t, { config }) + reifyOutput(mock.npm, reify, extras) + mock.npm.finish() + return mock + } + + const baseReify = { + actualTree: { name: 'host', inventory: { has: () => false } }, + diff: { children: [] }, + } + + const unreviewedScripts = [ + { + node: { packageName: 'canvas', name: 'canvas', version: '2.11.0', path: '/x/canvas' }, + scripts: { install: 'node-gyp rebuild' }, + }, + { + node: { packageName: 'sharp', name: 'sharp', version: '0.33.2', path: '/x/sharp' }, + scripts: { preinstall: 'pre', postinstall: 'post' }, + }, + ] + + const mock = await mockReifyWithExtras(t, baseReify, { unreviewedScripts }, { global: true }) + const warn = mock.logs.warn.byTitle('allow-scripts').join('\n') + t.match(warn, /2 packages have install scripts not yet covered/) + t.match(warn, /canvas@2\.11\.0 \(install: node-gyp rebuild\)/) + t.match(warn, /npm install -g --allow-scripts=canvas,sharp/) + t.match(warn, /npm config set allow-scripts=canvas,sharp/) + t.notMatch(warn, /approve-scripts/) }) t.test('single unreviewed script uses singular wording', async t => { diff --git a/deps/npm/test/lib/utils/sbom-cyclonedx.js b/deps/npm/test/lib/utils/sbom-cyclonedx.js index ea569d41c57..f3105e3cd48 100644 --- a/deps/npm/test/lib/utils/sbom-cyclonedx.js +++ b/deps/npm/test/lib/utils/sbom-cyclonedx.js @@ -257,6 +257,17 @@ t.test('single node - from git url', t => { t.end() }) +t.test('git url with special chars is encoded into the vcs_url qualifier', t => { + const node = { ...root, type: 'git', resolved: 'https://github.com/foo/bar.git?a=b&c=d#1234' } + const res = cyclonedxOutput({ npm, nodes: [node] }) + const { purl } = res.metadata.component + // everything after vcs_url= must be a single percent-encoded value, so the + // committish/query can't leak out as an extra purl qualifier or subpath + t.equal(purl, 'pkg:npm/root@1.0.0?vcs_url=https%3A%2F%2Fgithub.com%2Ffoo%2Fbar.git%3Fa%3Db%26c%3Dd%231234') + t.notMatch(purl.split('vcs_url=')[1], /[#&]/) + t.end() +}) + t.test('single node - no package info', t => { const node = { ...root, package: undefined } const res = cyclonedxOutput({ npm, nodes: [node] }) diff --git a/deps/npm/test/lib/utils/sbom-spdx.js b/deps/npm/test/lib/utils/sbom-spdx.js index d2599b08245..1e21c945ca7 100644 --- a/deps/npm/test/lib/utils/sbom-spdx.js +++ b/deps/npm/test/lib/utils/sbom-spdx.js @@ -223,6 +223,17 @@ t.test('single node - from git url', t => { t.end() }) +t.test('git url with special chars is encoded into the vcs_url qualifier', t => { + const node = { ...root, type: 'git', resolved: 'https://github.com/foo/bar.git?a=b&c=d#1234' } + const res = spdxOutput({ npm, nodes: [node] }) + const purl = res.packages + .find(p => p.SPDXID === 'SPDXRef-Package-root-1.0.0') + .externalRefs.find(r => r.referenceType === 'purl').referenceLocator + t.equal(purl, 'pkg:npm/root@1.0.0?vcs_url=https%3A%2F%2Fgithub.com%2Ffoo%2Fbar.git%3Fa%3Db%26c%3Dd%231234') + t.notMatch(purl.split('vcs_url=')[1], /[#&]/) + t.end() +}) + t.test('single node - linked', t => { const node = { ...root, isLink: true, target: { edgesOut: [] } } const res = spdxOutput({ npm, nodes: [node] }) diff --git a/deps/npm/test/lib/utils/strict-allow-scripts-preflight.js b/deps/npm/test/lib/utils/strict-allow-scripts-preflight.js index e246c68998c..c67a6e4853a 100644 --- a/deps/npm/test/lib/utils/strict-allow-scripts-preflight.js +++ b/deps/npm/test/lib/utils/strict-allow-scripts-preflight.js @@ -76,6 +76,19 @@ t.test('throws when unreviewed install scripts exist (idealTree path)', async t ) }) +t.test('passes when the only unreviewed node is inert (platform-incompatible optional dep)', async t => { + // An inert dep is in the ideal tree but removed before any script runs, so + // strict mode must not reject it (npm/cli#9562). + const inertNode = { ...node({ name: 'fsevents' }), inert: true } + const arb = makeArb({ ideal: tree([inertNode]) }) + await preflight({ + arb, + npm: { flatOptions: { strictAllowScripts: true } }, + idealTreeOpts: {}, + }) + t.pass('no error thrown for inert node') +}) + t.test('passes when all install-script nodes are explicitly approved', async t => { const arb = makeArb({ ideal: tree([node({ name: 'canvas' })]), @@ -189,3 +202,33 @@ t.test('error label falls back to node.name when package.version is missing', as { message: /no-version-pkg \(install: node-gyp rebuild\)/ } ) }) + +t.test('project-scoped error suggests install-scripts approve / deny', async t => { + const arb = makeArb({ ideal: tree([node({ name: 'canvas' })]) }) + await t.rejects( + preflight({ + arb, + npm: { flatOptions: { strictAllowScripts: true } }, + idealTreeOpts: {}, + }), + { message: /Approve them with `npm install-scripts approve`/ } + ) +}) + +t.test('global error points at --allow-scripts, not approve-scripts', async t => { + const arb = makeArb({ ideal: tree([node({ name: 'canvas' })]) }) + await t.rejects( + preflight({ + arb, + npm: { global: true, flatOptions: { strictAllowScripts: true } }, + idealTreeOpts: {}, + }), + (err) => { + t.equal(err.code, 'ESTRICTALLOWSCRIPTS') + t.match(err.message, /--allow-scripts/) + t.match(err.message, /npm config set allow-scripts=canvas/) + t.notMatch(err.message, /approve-scripts/) + return true + } + ) +}) diff --git a/doc/changelogs/NSOLID_CHANGELOG_V6_NODE_V24.md b/doc/changelogs/NSOLID_CHANGELOG_V6_NODE_V24.md index 5d58ac29f95..74116ab7663 100644 --- a/doc/changelogs/NSOLID_CHANGELOG_V6_NODE_V24.md +++ b/doc/changelogs/NSOLID_CHANGELOG_V6_NODE_V24.md @@ -2,6 +2,15 @@ +## 2026-07-22, Version 24.18.0-nsolid-v6.3.3 'Krypton' + +### Commits + +* \[[`13c74c037f`](https://github.com/nodesource/nsolid/commit/13c74c037f)] - **agents**: fix statsdTags in reconfigure response (Santiago Gimeno) [#495](https://github.com/nodesource/nsolid/pull/495) +* \[[`bf7ae9b9d6`](https://github.com/nodesource/nsolid/commit/bf7ae9b9d6)] - **deps**: update libcurl to 8.21.0 (Santiago Gimeno) [#497](https://github.com/nodesource/nsolid/pull/497) +* \[[`2bd464bd04`](https://github.com/nodesource/nsolid/commit/2bd464bd04)] - **deps**: fix versions of minimatch & brace-expansion (Minwoo Jung) +* \[[`e5b2a4c557`](https://github.com/nodesource/nsolid/commit/e5b2a4c557)] - **test**: fix test-http-agent-keepalive again (Santiago Gimeno) [#488](https://github.com/nodesource/nsolid/pull/488) + ## 2026-06-24, Version 24.18.0-nsolid-v6.3.2 'Krypton' ### Commits diff --git a/src/node_version.h b/src/node_version.h index 824ad79f4cb..2e9ea3e02aa 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -36,7 +36,7 @@ #define NSOLID_MINOR_VERSION 3 #define NSOLID_PATCH_VERSION 3 -#define NSOLID_VERSION_IS_RELEASE 0 +#define NSOLID_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)