From 27eb09211672e49fd33a26b21a284d58006f208a Mon Sep 17 00:00:00 2001 From: npm CLI robot Date: Thu, 4 Aug 2022 21:23:58 -0700 Subject: [PATCH] deps: upgrade npm to 8.16.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/44119 Reviewed-By: Ruy Adorno Reviewed-By: Mohammed Keyvanzadeh Reviewed-By: Tobias Nießen Reviewed-By: Luigi Pinca Reviewed-By: Myles Borins --- deps/npm/docs/content/commands/npm-ci.md | 2 +- deps/npm/docs/content/commands/npm-exec.md | 2 +- deps/npm/docs/content/commands/npm-query.md | 235 +++ deps/npm/docs/content/using-npm/config.md | 20 +- .../content/using-npm/dependency-selectors.md | 168 ++ deps/npm/docs/output/commands/npm-ci.html | 2 +- deps/npm/docs/output/commands/npm-exec.html | 2 +- deps/npm/docs/output/commands/npm-ls.html | 2 +- deps/npm/docs/output/commands/npm-query.html | 363 ++++ deps/npm/docs/output/commands/npm.html | 2 +- deps/npm/docs/output/using-npm/config.html | 18 +- .../using-npm/dependency-selectors.html | 301 ++++ deps/npm/lib/commands/exec.js | 43 +- deps/npm/lib/commands/init.js | 10 +- deps/npm/lib/commands/ls.js | 2 +- deps/npm/lib/commands/query.js | 104 ++ .../lib/exec/get-workspace-location-msg.js | 25 - deps/npm/lib/utils/cmd-list.js | 1 + deps/npm/lib/utils/config/definitions.js | 20 +- deps/npm/lib/utils/open-url-prompt.js | 9 + deps/npm/man/man1/npm-access.1 | 2 +- deps/npm/man/man1/npm-adduser.1 | 2 +- deps/npm/man/man1/npm-audit.1 | 2 +- deps/npm/man/man1/npm-bin.1 | 2 +- deps/npm/man/man1/npm-bugs.1 | 2 +- deps/npm/man/man1/npm-cache.1 | 2 +- deps/npm/man/man1/npm-ci.1 | 4 +- deps/npm/man/man1/npm-completion.1 | 2 +- deps/npm/man/man1/npm-config.1 | 2 +- deps/npm/man/man1/npm-dedupe.1 | 2 +- deps/npm/man/man1/npm-deprecate.1 | 2 +- deps/npm/man/man1/npm-diff.1 | 2 +- deps/npm/man/man1/npm-dist-tag.1 | 2 +- deps/npm/man/man1/npm-docs.1 | 2 +- deps/npm/man/man1/npm-doctor.1 | 2 +- deps/npm/man/man1/npm-edit.1 | 2 +- deps/npm/man/man1/npm-exec.1 | 4 +- deps/npm/man/man1/npm-explain.1 | 2 +- deps/npm/man/man1/npm-explore.1 | 2 +- deps/npm/man/man1/npm-find-dupes.1 | 2 +- deps/npm/man/man1/npm-fund.1 | 2 +- deps/npm/man/man1/npm-help-search.1 | 2 +- deps/npm/man/man1/npm-help.1 | 2 +- deps/npm/man/man1/npm-hook.1 | 2 +- deps/npm/man/man1/npm-init.1 | 2 +- deps/npm/man/man1/npm-install-ci-test.1 | 2 +- deps/npm/man/man1/npm-install-test.1 | 2 +- deps/npm/man/man1/npm-install.1 | 2 +- deps/npm/man/man1/npm-link.1 | 2 +- deps/npm/man/man1/npm-logout.1 | 2 +- deps/npm/man/man1/npm-ls.1 | 4 +- deps/npm/man/man1/npm-org.1 | 2 +- deps/npm/man/man1/npm-outdated.1 | 2 +- deps/npm/man/man1/npm-owner.1 | 2 +- deps/npm/man/man1/npm-pack.1 | 2 +- deps/npm/man/man1/npm-ping.1 | 2 +- deps/npm/man/man1/npm-pkg.1 | 2 +- deps/npm/man/man1/npm-prefix.1 | 2 +- deps/npm/man/man1/npm-profile.1 | 2 +- deps/npm/man/man1/npm-prune.1 | 2 +- deps/npm/man/man1/npm-publish.1 | 2 +- deps/npm/man/man1/npm-query.1 | 240 +++ deps/npm/man/man1/npm-rebuild.1 | 2 +- deps/npm/man/man1/npm-repo.1 | 2 +- deps/npm/man/man1/npm-restart.1 | 2 +- deps/npm/man/man1/npm-root.1 | 2 +- deps/npm/man/man1/npm-run-script.1 | 2 +- deps/npm/man/man1/npm-search.1 | 2 +- deps/npm/man/man1/npm-set-script.1 | 2 +- deps/npm/man/man1/npm-shrinkwrap.1 | 2 +- deps/npm/man/man1/npm-star.1 | 2 +- deps/npm/man/man1/npm-stars.1 | 2 +- deps/npm/man/man1/npm-start.1 | 2 +- deps/npm/man/man1/npm-stop.1 | 2 +- deps/npm/man/man1/npm-team.1 | 2 +- deps/npm/man/man1/npm-test.1 | 2 +- deps/npm/man/man1/npm-token.1 | 2 +- deps/npm/man/man1/npm-uninstall.1 | 2 +- deps/npm/man/man1/npm-unpublish.1 | 2 +- deps/npm/man/man1/npm-unstar.1 | 2 +- deps/npm/man/man1/npm-update.1 | 2 +- deps/npm/man/man1/npm-version.1 | 2 +- deps/npm/man/man1/npm-view.1 | 2 +- deps/npm/man/man1/npm-whoami.1 | 2 +- deps/npm/man/man1/npm.1 | 4 +- deps/npm/man/man1/npx.1 | 2 +- deps/npm/man/man5/folders.5 | 2 +- deps/npm/man/man5/install.5 | 2 +- deps/npm/man/man5/npm-shrinkwrap-json.5 | 2 +- deps/npm/man/man5/npmrc.5 | 2 +- deps/npm/man/man5/package-json.5 | 2 +- deps/npm/man/man5/package-lock-json.5 | 2 +- deps/npm/man/man7/config.7 | 22 +- deps/npm/man/man7/dependency-selectors.7 | 245 +++ deps/npm/man/man7/developers.7 | 2 +- deps/npm/man/man7/logging.7 | 2 +- deps/npm/man/man7/orgs.7 | 2 +- deps/npm/man/man7/package-spec.7 | 2 +- deps/npm/man/man7/registry.7 | 2 +- deps/npm/man/man7/removal.7 | 2 +- deps/npm/man/man7/scope.7 | 2 +- deps/npm/man/man7/scripts.7 | 2 +- deps/npm/man/man7/workspaces.7 | 2 +- .../arborist/lib/arborist/build-ideal-tree.js | 3 +- .../@npmcli/arborist/lib/arborist/index.js | 4 + .../@npmcli/arborist/lib/arborist/reify.js | 10 +- .../@npmcli/arborist/lib/dep-valid.js | 2 +- .../node_modules/@npmcli/arborist/lib/edge.js | 6 +- .../@npmcli/arborist/lib/from-path.js | 19 +- .../node_modules/@npmcli/arborist/lib/node.js | 8 + .../arborist/lib/query-selector-all.js | 561 ++++++ .../@npmcli/arborist/package.json | 4 +- .../fs/lib/common/file-url-to-path/index.js | 17 - .../lib/common/file-url-to-path/polyfill.js | 121 -- .../@npmcli/fs/lib/common/owner-sync.js | 4 +- .../@npmcli/fs/lib/common/owner.js | 4 +- deps/npm/node_modules/@npmcli/fs/lib/index.js | 2 +- deps/npm/node_modules/@npmcli/fs/lib/mkdir.js | 19 + .../@npmcli/fs/lib/mkdir/index.js | 29 - .../@npmcli/fs/lib/mkdir/polyfill.js | 81 - .../@npmcli/fs/lib/with-temp-dir.js | 2 +- deps/npm/node_modules/@npmcli/fs/package.json | 8 +- deps/npm/node_modules/@npmcli/query/LICENSE | 20 + .../node_modules/@npmcli/query/lib/index.js | 187 ++ .../node_modules/@npmcli/query/package.json | 61 + .../@npmcli/run-script/lib/make-spawn-args.js | 7 +- .../@npmcli/run-script/lib/run-script-pkg.js | 2 + .../@npmcli/run-script/lib/set-path.js | 12 +- .../@npmcli/run-script/package.json | 2 +- deps/npm/node_modules/cssesc/LICENSE-MIT.txt | 20 + deps/npm/node_modules/cssesc/README.md | 201 +++ deps/npm/node_modules/cssesc/bin/cssesc | 116 ++ deps/npm/node_modules/cssesc/cssesc.js | 110 ++ deps/npm/node_modules/cssesc/man/cssesc.1 | 70 + deps/npm/node_modules/cssesc/package.json | 51 + .../libnpmexec/lib/cache-install-dir.js | 20 - .../libnpmexec/lib/file-exists.js | 22 +- deps/npm/node_modules/libnpmexec/lib/index.js | 234 +-- .../node_modules/libnpmexec/lib/run-script.js | 8 +- deps/npm/node_modules/libnpmexec/package.json | 6 +- .../npm/node_modules/npm-profile/lib/index.js | 9 +- .../npm/node_modules/npm-profile/package.json | 2 +- .../postcss-selector-parser/API.md | 873 +++++++++ .../postcss-selector-parser/LICENSE-MIT | 22 + .../postcss-selector-parser/dist/index.js | 24 + .../postcss-selector-parser/dist/parser.js | 1243 +++++++++++++ .../postcss-selector-parser/dist/processor.js | 206 +++ .../dist/selectors/attribute.js | 515 ++++++ .../dist/selectors/className.js | 69 + .../dist/selectors/combinator.js | 31 + .../dist/selectors/comment.js | 31 + .../dist/selectors/constructors.js | 102 ++ .../dist/selectors/container.js | 395 ++++ .../dist/selectors/guards.js | 64 + .../dist/selectors/id.js | 37 + .../dist/selectors/index.js | 27 + .../dist/selectors/namespace.js | 101 ++ .../dist/selectors/nesting.js | 32 + .../dist/selectors/node.js | 239 +++ .../dist/selectors/pseudo.js | 38 + .../dist/selectors/root.js | 60 + .../dist/selectors/selector.js | 31 + .../dist/selectors/string.js | 31 + .../dist/selectors/tag.js | 31 + .../dist/selectors/types.js | 28 + .../dist/selectors/universal.js | 32 + .../dist/sortAscending.js | 13 + .../dist/tokenTypes.js | 95 + .../postcss-selector-parser/dist/tokenize.js | 271 +++ .../dist/util/ensureObject.js | 22 + .../dist/util/getProp.js | 24 + .../dist/util/index.js | 22 + .../dist/util/stripComments.js | 27 + .../dist/util/unesc.js | 93 + .../postcss-selector-parser/package.json | 78 + .../postcss-selector-parser.d.ts | 555 ++++++ deps/npm/package.json | 4 +- .../test/lib/commands/completion.js.test.cjs | 1 + .../test/lib/commands/config.js.test.cjs | 2 + .../test/lib/commands/ls.js.test.cjs | 7 + .../test/lib/commands/query.js.test.cjs | 221 +++ .../test/lib/load-all-commands.js.test.cjs | 14 + .../tap-snapshots/test/lib/npm.js.test.cjs | 20 +- .../test/lib/utils/cmd-list.js.test.cjs | 6 + .../lib/utils/config/definitions.js.test.cjs | 20 +- .../lib/utils/config/describe-all.js.test.cjs | 20 +- deps/npm/test/fixtures/mock-npm.js | 2 +- deps/npm/test/lib/commands/exec.js | 1592 +---------------- deps/npm/test/lib/commands/ls.js | 38 + deps/npm/test/lib/commands/query.js | 199 +++ deps/npm/test/lib/utils/open-url-prompt.js | 29 + 191 files changed, 9588 insertions(+), 2119 deletions(-) create mode 100644 deps/npm/docs/content/commands/npm-query.md create mode 100644 deps/npm/docs/content/using-npm/dependency-selectors.md create mode 100644 deps/npm/docs/output/commands/npm-query.html create mode 100644 deps/npm/docs/output/using-npm/dependency-selectors.html create mode 100644 deps/npm/lib/commands/query.js delete mode 100644 deps/npm/lib/exec/get-workspace-location-msg.js create mode 100644 deps/npm/man/man1/npm-query.1 create mode 100644 deps/npm/man/man7/dependency-selectors.7 create mode 100644 deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js delete mode 100644 deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js delete mode 100644 deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js create mode 100644 deps/npm/node_modules/@npmcli/fs/lib/mkdir.js delete mode 100644 deps/npm/node_modules/@npmcli/fs/lib/mkdir/index.js delete mode 100644 deps/npm/node_modules/@npmcli/fs/lib/mkdir/polyfill.js create mode 100644 deps/npm/node_modules/@npmcli/query/LICENSE create mode 100644 deps/npm/node_modules/@npmcli/query/lib/index.js create mode 100644 deps/npm/node_modules/@npmcli/query/package.json create mode 100644 deps/npm/node_modules/cssesc/LICENSE-MIT.txt create mode 100644 deps/npm/node_modules/cssesc/README.md create mode 100755 deps/npm/node_modules/cssesc/bin/cssesc create mode 100644 deps/npm/node_modules/cssesc/cssesc.js create mode 100644 deps/npm/node_modules/cssesc/man/cssesc.1 create mode 100644 deps/npm/node_modules/cssesc/package.json delete mode 100644 deps/npm/node_modules/libnpmexec/lib/cache-install-dir.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/API.md create mode 100644 deps/npm/node_modules/postcss-selector-parser/LICENSE-MIT create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/index.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/parser.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/processor.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/util/index.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js create mode 100644 deps/npm/node_modules/postcss-selector-parser/package.json create mode 100644 deps/npm/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts create mode 100644 deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs create mode 100644 deps/npm/test/lib/commands/query.js diff --git a/deps/npm/docs/content/commands/npm-ci.md b/deps/npm/docs/content/commands/npm-ci.md index 30a03365ade814..3ecd7c6efb0957 100644 --- a/deps/npm/docs/content/commands/npm-ci.md +++ b/deps/npm/docs/content/commands/npm-ci.md @@ -67,7 +67,7 @@ $ npm ci added 154 packages in 5s ``` -Configure Travis to build using `npm ci` instead of `npm install`: +Configure Travis CI to build using `npm ci` instead of `npm install`: ```bash # .travis.yml diff --git a/deps/npm/docs/content/commands/npm-exec.md b/deps/npm/docs/content/commands/npm-exec.md index 8ccfa75c73386c..3d8de1ea54ad6f 100644 --- a/deps/npm/docs/content/commands/npm-exec.md +++ b/deps/npm/docs/content/commands/npm-exec.md @@ -127,7 +127,7 @@ $ npm exec -- foo@latest bar --package=@npmcli/foo * Default: * Type: String (can be set multiple times) -The package to install for [`npm exec`](/commands/npm-exec) +The package or packages to install for [`npm exec`](/commands/npm-exec) diff --git a/deps/npm/docs/content/commands/npm-query.md b/deps/npm/docs/content/commands/npm-query.md new file mode 100644 index 00000000000000..6166d5c0e71665 --- /dev/null +++ b/deps/npm/docs/content/commands/npm-query.md @@ -0,0 +1,235 @@ +--- +title: npm-query +section: 1 +description: Dependency selector query +--- + +### Synopsis + + + + + +```bash +npm query +``` + + + + + + +### Description + +The `npm query` command allows for usage of css selectors in order to retrieve +an array of dependency objects. + +### Piping npm query to other commands + +```bash +# find all dependencies with postinstall scripts & uninstall them +npm query ":attr(scripts, [postinstall])" | jq 'map(.name)|join("\n")' -r | xargs -I {} npm uninstall {} + +# find all git dependencies & explain who requires them +npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {} +``` + +### Extended Use Cases & Queries + +```stylus +// all deps +* + +// all direct deps +:root > * + +// direct production deps +:root > .prod + +// direct development deps +:root > .dev + +// any peer dep of a direct deps +:root > * > .peer + +// any workspace dep +.workspace + +// all workspaces that depend on another workspace +.workspace > .workspace + +// all workspaces that have peer deps +.workspace:has(.peer) + +// any dep named "lodash" +// equivalent to [name="lodash"] +#lodash + +// any deps named "lodash" & within semver range ^"1.2.3" +#lodash@^1.2.3 +// equivalent to... +[name="lodash"]:semver(^1.2.3) + +// get the hoisted node for a given semver range +#lodash@^1.2.3:not(:deduped) + +// querying deps with a specific version +#lodash@2.1.5 +// equivalent to... +[name="lodash"][version="2.1.5"] + +// has any deps +:has(*) + +// deps with no other deps (ie. "leaf" nodes) +:empty + +// manually querying git dependencies +[repository^=github:], +[repository^=git:], +[repository^=https://github.com], +[repository^=http://github.com], +[repository^=https://github.com], +[repository^=+git:...] + +// querying for all git dependencies +:type(git) + +// get production dependencies that aren't also dev deps +.prod:not(.dev) + +// get dependencies with specific licenses +[license=MIT], [license=ISC] + +// find all packages that have @ruyadorno as a contributor +:attr(contributors, [email=ruyadorno@github.com]) +``` + +### Example Response Output + +- an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped + +```json +[ + { + "name": "", + "version": "", + "description": "", + "homepage": "", + "bugs": {}, + "author": {}, + "license": {}, + "funding": {}, + "files": [], + "main": "", + "browser": "", + "bin": {}, + "man": [], + "directories": {}, + "repository": {}, + "scripts": {}, + "config": {}, + "dependencies": {}, + "devDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": {}, + "peerDependencies": {}, + "peerDependenciesMeta": {}, + "engines": {}, + "os": [], + "cpu": [], + "workspaces": {}, + "keywords": [], + ... + }, + ... +``` + +### Configuration + + + + +#### `global` + +* Default: false +* Type: Boolean + +Operates in "global" mode, so that packages are installed into the `prefix` +folder instead of the current working directory. See +[folders](/configuring-npm/folders) for more on the differences in behavior. + +* packages are installed into the `{prefix}/lib/node_modules` folder, instead + of the current working directory. +* bin files are linked to `{prefix}/bin` +* man pages are linked to `{prefix}/share/man` + + + + +#### `workspace` + +* Default: +* Type: String (can be set multiple times) + +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option. + +Valid values for the `workspace` config are either: + +* Workspace names +* Path to a workspace directory +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) + +When set for the `npm init` command, this may be set to the folder of a +workspace which does not yet exist, to create the folder and set it up as a +brand new workspace within the project. + +This value is not exported to the environment for child processes. + + + + +#### `workspaces` + +* Default: null +* Type: null or Boolean + +Set to true to run the command in the context of **all** configured +workspaces. + +Explicitly setting this to false will cause commands like `install` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the `node_modules` tree (install, update, etc.) +will link workspaces into the `node_modules` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the `workspace` config. + +This value is not exported to the environment for child processes. + + + + +#### `include-workspace-root` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the `workspace` config, or +all workspaces via the `workspaces` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +This value is not exported to the environment for child processes. + + + + + +## See Also + +* [dependency selector](/using-npm/dependency-selector) diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md index e3e1bd6c73bb3b..cd13237f34dd38 100644 --- a/deps/npm/docs/content/using-npm/config.md +++ b/deps/npm/docs/content/using-npm/config.md @@ -1244,7 +1244,7 @@ Directory in which `npm pack` will save tarballs. * Default: * Type: String (can be set multiple times) -The package to install for [`npm exec`](/commands/npm-exec) +The package or packages to install for [`npm exec`](/commands/npm-exec) @@ -1393,6 +1393,24 @@ The base URL of the npm registry. +#### `replace-registry-host` + +* Default: "npmjs" +* Type: "npmjs", "never", "always", or String + +Defines behavior for replacing the registry host in a lockfile with the +configured registry. + +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. + +You may also specify a bare hostname (e.g., "registry.npmjs.org"). + + + + #### `save` * Default: `true` unless when using `npm update` where it defaults to `false` diff --git a/deps/npm/docs/content/using-npm/dependency-selectors.md b/deps/npm/docs/content/using-npm/dependency-selectors.md new file mode 100644 index 00000000000000..9d65baf631a7ef --- /dev/null +++ b/deps/npm/docs/content/using-npm/dependency-selectors.md @@ -0,0 +1,168 @@ +--- +title: Dependency Selector Syntax & Querying +section: 7 +description: Dependency Selector Syntax & Querying +--- + +### Description + +The [`npm query`](/commands/npm-query) commmand exposes a new dependency selector syntax (informed by & respecting many aspects of the [CSS Selectors 4 Spec](https://dev.w3.org/csswg/selectors4/#relational)) which: + +- Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax +- Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible +- Unlocks the ability to answer complex, multi-faceted questions about dependencies, their relationships & associative metadata +- Consolidates redundant logic of similar query commands in `npm` (ex. `npm fund`, `npm ls`, `npm outdated`, `npm audit` ...) + +### Dependency Selector Syntax `v1.0.0` + +#### Overview: + +- there is no "type" or "tag" selectors (ex. `div, h1, a`) as a dependency/target is the only type of `Node` that can be queried +- the term "dependencies" is in reference to any `Node` found in a `tree` returned by `Arborist` + +#### Combinators + +- `>` direct descendant/child +- ` ` any descendant/child +- `~` sibling + +#### Selectors + +- `*` universal selector +- `#` dependency selector (equivalent to `[name="..."]`) +- `#@` (equivalent to `[name=]:semver()`) +- `,` selector list delimiter +- `.` dependency type selector +- `:` pseudo selector + +#### Dependency Type Selectors + +- `.prod` dependency found in the `dependencies` section of `package.json`, or is a child of said dependency +- `.dev` dependency found in the `devDependencies` section of `package.json`, or is a child of said dependency +- `.optional` dependency found in the `optionalDependencies` section of `package.json`, or has `"optional": true` set in its entry in the `peerDependenciesMeta` section of `package.json`, or a child of said dependency +- `.peer` dependency found in the `peerDependencies` section of `package.json` +- `.workspace` dependency found in the [`workspaces`](https://docs.npmjs.com/cli/v8/using-npm/workspaces) section of `package.json` +- `.bundled` dependency found in the `bundleDependencies` section of `package.json`, or is a child of said dependency + +#### Pseudo Selectors +- [`:not()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not) +- [`:has()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) +- [`:is()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is) +- [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) matches the root node/dependency +- [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) matches node/dependency it was queried against +- [`:empty`](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty) when a dependency has no dependencies +- [`:private`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#private) when a dependency is private +- `:link` when a dependency is linked (for instance, workspaces or packages manually [`linked`](https://docs.npmjs.com/cli/v8/commands/npm-link) +- `:deduped` when a dependency has been deduped (note that this does *not* always mean the dependency has been hoisted to the root of node_modules) +- `:override` when a dependency is an override (not implemented yet) +- `:extraneous` when a dependency exists but is not defined as a dependency of any node +- `:invalid` when a dependency version is out of its ancestors specified range +- `:missing` when a dependency is not found on disk +- `:semver()` matching a valid [`node-semver`](https://github.com/npm/node-semver) spec +- `:path()` [glob](https://www.npmjs.com/package/glob) matching based on dependencies path relative to the project +- `:type()` [based on currently recognized types](https://github.com/npm/npm-package-arg#result-object) + +#### [Attribute Selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) + +The attribute selector evaluates the key/value pairs in `package.json` if they are `String`s. + +- `[]` attribute selector (ie. existence of attribute) +- `[attribute=value]` attribute value is equivalant... +- `[attribute~=value]` attribute value contains word... +- `[attribute*=value]` attribute value contains string... +- `[attribute|=value]` attribute value is equal to or starts with... +- `[attribute^=value]` attribute value starts with... +- `[attribute$=value]` attribute value ends with... + +#### `Array` & `Object` Attribute Selectors + +The generic `:attr()` pseudo selector standardizes a pattern which can be used for attribute selection of `Object`s, `Array`s or `Arrays` of `Object`s accessible via `Arborist`'s `Node.package` metadata. This allows for iterative attribute selection beyond top-level `String` evaluation. The last argument passed to `:attr()` must be an `attribute` selector or a nested `:attr()`. See examples below: + +#### `Objects` + +```css +/* return dependencies that have a `scripts.test` containing `"tap"` */ +*:attr(scripts, [test~=tap]) +``` + +#### Nested `Objects` + +Nested objects are expressed as sequential arguments to `:attr()`. + +```css +/* return dependencies that have a testling config for opera browsers */ +*:attr(testling, browsers, [~=opera]) +``` + +#### `Arrays` + +`Array`s specifically uses a special/reserved `.` character in place of a typical attribute name. `Arrays` also support exact `value` matching when a `String` is passed to the selector. + +##### Example of an `Array` Attribute Selection: +```css +/* removes the distinction between properties & arrays */ +/* ie. we'd have to check the property & iterate to match selection */ +*:attr([keywords^=react]) +*:attr(contributors, :attr([name~=Jordan])) +``` + +##### Example of an `Array` matching directly to a value: +```css +/* return dependencies that have the exact keyword "react" */ +/* this is equivalent to `*:keywords([value="react"])` */ +*:attr([keywords=react]) +``` + +##### Example of an `Array` of `Object`s: +```css +/* returns */ +*:attr(contributors, [email=ruyadorno@github.com]) +``` + +### Groups + +Dependency groups are defined by the package relationships to their ancestors (ie. the dependency types that are defined in `package.json`). This approach is user-centric as the ecosystem has been taught to think about dependencies in these groups first-and-foremost. Dependencies are allowed to be included in multiple groups (ex. a `prod` dependency may also be a `dev` dependency (in that it's also required by another `dev` dependency) & may also be `bundled` - a selector for that type of dependency would look like: `*.prod.dev.bundled`). + +- `.prod` +- `.dev` +- `.optional` +- `.peer` +- `.bundled` +- `.workspace` + +Please note that currently `workspace` deps are always `prod` dependencies. Additionally the `.root` dependency is also considered a `prod` dependency. + +### Programmatic Usage + +- `Arborist`'s `Node` Class has a `.querySelectorAll()` method + - this method will return a filtered, flattened dependency Arborist `Node` list based on a valid query selector + +```js +const Arborist = require('@npmcli/arborist') +const arb = new Arborist({}) +``` + +```js +// root-level +arb.loadActual((tree) => { + // query all production dependencies + const results = await tree.querySelectorAll('.prod') + console.log(results) +}) +``` + +```js +// iterative +arb.loadActual((tree) => { + // query for the deduped version of react + const results = await tree.querySelectorAll('#react:not(:deduped)') + // query the deduped react for git deps + const deps = await results[0].querySelectorAll(':type(git)') + console.log(deps) +}) +``` + +## See Also + +* [npm query](/commands/npm-query) +* [@npmcli/arborist](https://npm.im/@npmcli/arborist] diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html index 51efa6ea98bc07..a67ad8237e7548 100644 --- a/deps/npm/docs/output/commands/npm-ci.html +++ b/deps/npm/docs/output/commands/npm-ci.html @@ -192,7 +192,7 @@

Example

$ npm ci
 added 154 packages in 5s
 
-

Configure Travis to build using npm ci instead of npm install:

+

Configure Travis CI to build using npm ci instead of npm install:

# .travis.yml
 install:
 - npm ci
diff --git a/deps/npm/docs/output/commands/npm-exec.html b/deps/npm/docs/output/commands/npm-exec.html
index 7a5195ba4a2630..917d71db366883 100644
--- a/deps/npm/docs/output/commands/npm-exec.html
+++ b/deps/npm/docs/output/commands/npm-exec.html
@@ -236,7 +236,7 @@ 

package

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

    The package to install for npm exec

    +

    The package or packages to install for npm exec

    call

    diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index ce8eda1b71176d..5641195679cffd 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -166,7 +166,7 @@

    Description

    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@8.15.1 /path/to/npm
    +
    npm@8.16.0 /path/to/npm
     └─┬ init-package-json@0.0.4
       └── promzard@0.1.5
     
    diff --git a/deps/npm/docs/output/commands/npm-query.html b/deps/npm/docs/output/commands/npm-query.html new file mode 100644 index 00000000000000..1a11fb9e8cd8b3 --- /dev/null +++ b/deps/npm/docs/output/commands/npm-query.html @@ -0,0 +1,363 @@ + + +npm-query + + + + + +
    +
    +

    npm-query

    +Dependency selector query +
    + +
    +

    Table of contents

    + +
    + +

    Synopsis

    + + + +
    npm query <selector>
    +
    + + + +

    Description

    +

    The npm query command allows for usage of css selectors in order to retrieve +an array of dependency objects.

    +

    Piping npm query to other commands

    +
    # find all dependencies with postinstall scripts & uninstall them
    +npm query ":attr(scripts, [postinstall])" | jq 'map(.name)|join("\n")' -r | xargs -I {} npm uninstall {}
    +
    +# find all git dependencies & explain who requires them
    +npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {}
    +
    +

    Extended Use Cases & Queries

    +
    // all deps
    +*
    +
    +// all direct deps
    +:root > *
    +
    +// direct production deps
    +:root > .prod
    +
    +// direct development deps
    +:root > .dev
    +
    +// any peer dep of a direct deps
    +:root > * > .peer
    +
    +// any workspace dep
    +.workspace
    +
    +// all workspaces that depend on another workspace
    +.workspace > .workspace
    +
    +// all workspaces that have peer deps
    +.workspace:has(.peer)
    +
    +// any dep named "lodash"
    +// equivalent to [name="lodash"]
    +#lodash
    +
    +// any deps named "lodash" & within semver range ^"1.2.3"
    +#lodash@^1.2.3
    +// equivalent to...
    +[name="lodash"]:semver(^1.2.3)
    +
    +// get the hoisted node for a given semver range
    +#lodash@^1.2.3:not(:deduped)
    +
    +// querying deps with a specific version
    +#lodash@2.1.5
    +// equivalent to...
    +[name="lodash"][version="2.1.5"]
    +
    +// has any deps
    +:has(*)
    +
    +// deps with no other deps (ie. "leaf" nodes)
    +:empty
    +
    +// manually querying git dependencies
    +[repository^=github:],
    +[repository^=git:],
    +[repository^=https://github.com],
    +[repository^=http://github.com],
    +[repository^=https://github.com],
    +[repository^=+git:...]
    +
    +// querying for all git dependencies
    +:type(git)
    +
    +// get production dependencies that aren't also dev deps
    +.prod:not(.dev)
    +
    +// get dependencies with specific licenses
    +[license=MIT], [license=ISC]
    +
    +// find all packages that have @ruyadorno as a contributor
    +:attr(contributors, [email=ruyadorno@github.com])
    +
    +

    Example Response Output

    +
      +
    • an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped
    • +
    +
    [
    +  {
    +    "name": "",
    +    "version": "",
    +    "description": "",
    +    "homepage": "",
    +    "bugs": {},
    +    "author": {},
    +    "license": {},
    +    "funding": {},
    +    "files": [],
    +    "main": "",
    +    "browser": "",
    +    "bin": {},
    +    "man": [],
    +    "directories": {},
    +    "repository": {},
    +    "scripts": {},
    +    "config": {},
    +    "dependencies": {},
    +    "devDependencies": {},
    +    "optionalDependencies": {},
    +    "bundledDependencies": {},
    +    "peerDependencies": {},
    +    "peerDependenciesMeta": {},
    +    "engines": {},
    +    "os": [],
    +    "cpu": [],
    +    "workspaces": {},
    +    "keywords": [],
    +    ...
    +  },
    +  ...
    +
    +

    Configuration

    + + + +

    global

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

    Operates in "global" mode, so that packages are installed into the prefix +folder instead of the current working directory. See +folders for more on the differences in behavior.

    +
      +
    • packages are installed into the {prefix}/lib/node_modules folder, instead +of the current working directory.
    • +
    • bin files are linked to {prefix}/bin
    • +
    • man pages are linked to {prefix}/share/man
    • +
    + + +

    workspace

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

    Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option.

    +

    Valid values for the workspace config are either:

    +
      +
    • Workspace names
    • +
    • Path to a workspace directory
    • +
    • Path to a parent workspace directory (will result in selecting all +workspaces within that folder)
    • +
    +

    When set for the npm init command, this may be set to the folder of a +workspace which does not yet exist, to create the folder and set it up as a +brand new workspace within the project.

    +

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

    + + +

    workspaces

    +
      +
    • Default: null
    • +
    • Type: null or Boolean
    • +
    +

    Set to true to run the command in the context of all configured +workspaces.

    +

    Explicitly setting this to false will cause commands like install to +ignore workspaces altogether. When not set explicitly:

    +
      +
    • Commands that operate on the node_modules tree (install, update, etc.) +will link workspaces into the node_modules folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +unless one or more workspaces are specified in the workspace config.
    • +
    +

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

    + + +

    include-workspace-root

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

    Include the workspace root when workspaces are enabled for a command.

    +

    When false, specifying individual workspaces via the workspace config, or +all workspaces via the workspaces flag, will cause npm to operate only on +the specified workspaces, and not on the root project.

    +

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

    + + + +

    See Also

    + +
    + + +
    + + + + \ No newline at end of file diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index b254b72c370861..8573a6d65caf3c 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -149,7 +149,7 @@

    Table of contents

    Version

    -

    8.15.1

    +

    8.16.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 diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html index 79bf005d61e15e..42880a27025546 100644 --- a/deps/npm/docs/output/using-npm/config.html +++ b/deps/npm/docs/output/using-npm/config.html @@ -142,7 +142,7 @@

    config

    Table of contents

    -
    +

    Description

    @@ -1146,7 +1146,7 @@

    package

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

    The package to install for npm exec

    +

    The package or packages to install for npm exec

    package-lock

    @@ -1265,6 +1265,20 @@

    registry

    The base URL of the npm registry.

    +

    replace-registry-host

    +
      +
    • Default: "npmjs"
    • +
    • Type: "npmjs", "never", "always", or String
    • +
    +

    Defines behavior for replacing the registry host in a lockfile with the +configured registry.

    +

    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.

    +

    You may also specify a bare hostname (e.g., "registry.npmjs.org").

    + +

    save

    • Default: true unless when using npm update where it defaults to false
    • diff --git a/deps/npm/docs/output/using-npm/dependency-selectors.html b/deps/npm/docs/output/using-npm/dependency-selectors.html new file mode 100644 index 00000000000000..7f691cc1df77e2 --- /dev/null +++ b/deps/npm/docs/output/using-npm/dependency-selectors.html @@ -0,0 +1,301 @@ + + +Dependency Selector Syntax & Querying + + + + + +
      +
      +

      Dependency Selector Syntax & Querying

      +Dependency Selector Syntax & Querying +
      + +
      +

      Table of contents

      + +
      + +

      Description

      +

      The npm query commmand exposes a new dependency selector syntax (informed by & respecting many aspects of the CSS Selectors 4 Spec) which:

      +
        +
      • Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax
      • +
      • Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible
      • +
      • Unlocks the ability to answer complex, multi-faceted questions about dependencies, their relationships & associative metadata
      • +
      • Consolidates redundant logic of similar query commands in npm (ex. npm fund, npm ls, npm outdated, npm audit ...)
      • +
      +

      Dependency Selector Syntax v1.0.0

      +

      Overview:

      +
        +
      • there is no "type" or "tag" selectors (ex. div, h1, a) as a dependency/target is the only type of Node that can be queried
      • +
      • the term "dependencies" is in reference to any Node found in a tree returned by Arborist
      • +
      +

      Combinators

      +
        +
      • > direct descendant/child
      • +
      • any descendant/child
      • +
      • ~ sibling
      • +
      +

      Selectors

      +
        +
      • * universal selector
      • +
      • #<name> dependency selector (equivalent to [name="..."])
      • +
      • #<name>@<version> (equivalent to [name=<name>]:semver(<version>))
      • +
      • , selector list delimiter
      • +
      • . dependency type selector
      • +
      • : pseudo selector
      • +
      +

      Dependency Type Selectors

      +
        +
      • .prod dependency found in the dependencies section of package.json, or is a child of said dependency
      • +
      • .dev dependency found in the devDependencies section of package.json, or is a child of said dependency
      • +
      • .optional dependency found in the optionalDependencies section of package.json, or has "optional": true set in its entry in the peerDependenciesMeta section of package.json, or a child of said dependency
      • +
      • .peer dependency found in the peerDependencies section of package.json
      • +
      • .workspace dependency found in the workspaces section of package.json
      • +
      • .bundled dependency found in the bundleDependencies section of package.json, or is a child of said dependency
      • +
      +

      Pseudo Selectors

      +
        +
      • :not(<selector>)
      • +
      • :has(<selector>)
      • +
      • :is(<selector list>)
      • +
      • :root matches the root node/dependency
      • +
      • :scope matches node/dependency it was queried against
      • +
      • :empty when a dependency has no dependencies
      • +
      • :private when a dependency is private
      • +
      • :link when a dependency is linked (for instance, workspaces or packages manually linked
      • +
      • :deduped when a dependency has been deduped (note that this does not always mean the dependency has been hoisted to the root of node_modules)
      • +
      • :override when a dependency is an override (not implemented yet)
      • +
      • :extraneous when a dependency exists but is not defined as a dependency of any node
      • +
      • :invalid when a dependency version is out of its ancestors specified range
      • +
      • :missing when a dependency is not found on disk
      • +
      • :semver(<spec>) matching a valid node-semver spec
      • +
      • :path(<path>) glob matching based on dependencies path relative to the project
      • +
      • :type(<type>) based on currently recognized types
      • +
      +

      Attribute Selectors

      +

      The attribute selector evaluates the key/value pairs in package.json if they are Strings.

      +
        +
      • [] attribute selector (ie. existence of attribute)
      • +
      • [attribute=value] attribute value is equivalant...
      • +
      • [attribute~=value] attribute value contains word...
      • +
      • [attribute*=value] attribute value contains string...
      • +
      • [attribute|=value] attribute value is equal to or starts with...
      • +
      • [attribute^=value] attribute value starts with...
      • +
      • [attribute$=value] attribute value ends with...
      • +
      +

      Array & Object Attribute Selectors

      +

      The generic :attr() pseudo selector standardizes a pattern which can be used for attribute selection of Objects, Arrays or Arrays of Objects accessible via Arborist's Node.package metadata. This allows for iterative attribute selection beyond top-level String evaluation. The last argument passed to :attr() must be an attribute selector or a nested :attr(). See examples below:

      +

      Objects

      +
      /* return dependencies that have a `scripts.test` containing `"tap"` */
      +*:attr(scripts, [test~=tap])
      +
      +

      Nested Objects

      +

      Nested objects are expressed as sequential arguments to :attr().

      +
      /* return dependencies that have a testling config for opera browsers */
      +*:attr(testling, browsers, [~=opera])
      +
      +

      Arrays

      +

      Arrays specifically uses a special/reserved . character in place of a typical attribute name. Arrays also support exact value matching when a String is passed to the selector.

      +
      Example of an Array Attribute Selection:
      +
      /* removes the distinction between properties & arrays */
      +/* ie. we'd have to check the property & iterate to match selection */
      +*:attr([keywords^=react])
      +*:attr(contributors, :attr([name~=Jordan]))
      +
      +
      Example of an Array matching directly to a value:
      +
      /* return dependencies that have the exact keyword "react" */
      +/* this is equivalent to `*:keywords([value="react"])` */
      +*:attr([keywords=react])
      +
      +
      Example of an Array of Objects:
      +
      /* returns */
      +*:attr(contributors, [email=ruyadorno@github.com])
      +
      +

      Groups

      +

      Dependency groups are defined by the package relationships to their ancestors (ie. the dependency types that are defined in package.json). This approach is user-centric as the ecosystem has been taught to think about dependencies in these groups first-and-foremost. Dependencies are allowed to be included in multiple groups (ex. a prod dependency may also be a dev dependency (in that it's also required by another dev dependency) & may also be bundled - a selector for that type of dependency would look like: *.prod.dev.bundled).

      +
        +
      • .prod
      • +
      • .dev
      • +
      • .optional
      • +
      • .peer
      • +
      • .bundled
      • +
      • .workspace
      • +
      +

      Please note that currently workspace deps are always prod dependencies. Additionally the .root dependency is also considered a prod dependency.

      +

      Programmatic Usage

      +
        +
      • Arborist's Node Class has a .querySelectorAll() method +
          +
        • this method will return a filtered, flattened dependency Arborist Node list based on a valid query selector
        • +
        +
      • +
      +
      const Arborist = require('@npmcli/arborist')
      +const arb = new Arborist({})
      +
      +
      // root-level
      +arb.loadActual((tree) => {
      +  // query all production dependencies
      +  const results = await tree.querySelectorAll('.prod')
      +  console.log(results)
      +})
      +
      +
      // iterative
      +arb.loadActual((tree) => {
      +  // query for the deduped version of react
      +  const results = await tree.querySelectorAll('#react:not(:deduped)')
      +  // query the deduped react for git deps
      +  const deps = await results[0].querySelectorAll(':type(git)')
      +  console.log(deps)
      +})
      +
      +

      See Also

      + +
      + + +
      + + + + \ No newline at end of file diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js index d9a686cc9a3be7..ddbb5f7cf9d79c 100644 --- a/deps/npm/lib/commands/exec.js +++ b/deps/npm/lib/commands/exec.js @@ -1,31 +1,6 @@ +const path = require('path') const libexec = require('libnpmexec') const BaseCommand = require('../base-command.js') -const getLocationMsg = require('../exec/get-workspace-location-msg.js') - -// it's like this: -// -// npm x pkg@version <-- runs the bin named "pkg" or the only bin if only 1 -// -// { name: 'pkg', bin: { pkg: 'pkg.js', foo: 'foo.js' }} <-- run pkg -// { name: 'pkg', bin: { foo: 'foo.js' }} <-- run foo? -// -// npm x -p pkg@version -- foo -// -// npm x -p pkg@version -- foo --registry=/dev/null -// -// const pkg = npm.config.get('package') || getPackageFrom(args[0]) -// const cmd = getCommand(pkg, args[0]) -// --> npm x -c 'cmd ...args.slice(1)' -// -// we've resolved cmd and args, and escaped them properly, and installed the -// relevant packages. -// -// Add the ${npx install prefix}/node_modules/.bin to PATH -// -// pkg = readPackageJson('./package.json') -// pkg.scripts.___npx = ${the -c arg} -// runScript({ pkg, event: 'npx', ... }) -// process.env.npm_lifecycle_event = 'npx' class Exec extends BaseCommand { static description = 'Run a command from a local or remote npm package' @@ -49,8 +24,10 @@ class Exec extends BaseCommand { static isShellout = true async exec (_args, { locationMsg, runPath } = {}) { - const path = this.npm.localPrefix + // This is where libnpmexec will look for locally installed packages + const localPrefix = this.npm.localPrefix + // This is where libnpmexec will actually run the scripts from if (!runPath) { runPath = process.cwd() } @@ -61,8 +38,9 @@ class Exec extends BaseCommand { flatOptions, localBin, globalBin, + globalDir, } = this.npm - const output = (...outputArgs) => this.npm.output(...outputArgs) + const output = this.npm.output.bind(this.npm) const scriptShell = this.npm.config.get('script-shell') || undefined const packages = this.npm.config.get('package') const yes = this.npm.config.get('yes') @@ -81,9 +59,10 @@ class Exec extends BaseCommand { localBin, locationMsg, globalBin, + globalPath: path.resolve(globalDir, '..'), output, packages, - path, + path: localPrefix, runPath, scriptShell, yes, @@ -92,10 +71,10 @@ class Exec extends BaseCommand { async execWorkspaces (args, filters) { await this.setWorkspaces(filters) - const color = this.npm.color - for (const path of this.workspacePaths) { - const locationMsg = await getLocationMsg({ color, path }) + for (const [name, path] of this.workspaces) { + const locationMsg = + `in workspace ${this.npm.chalk.green(name)} at location:\n${this.npm.chalk.dim(path)}` await this.exec(args, { locationMsg, runPath: path }) } } diff --git a/deps/npm/lib/commands/init.js b/deps/npm/lib/commands/init.js index cff8340dcd7074..039f08e06059e6 100644 --- a/deps/npm/lib/commands/init.js +++ b/deps/npm/lib/commands/init.js @@ -10,7 +10,6 @@ const PackageJson = require('@npmcli/package-json') const log = require('../utils/log-shim.js') const updateWorkspaces = require('../workspaces/update-workspaces.js') -const getLocationMsg = require('../exec/get-workspace-location-msg.js') const BaseCommand = require('../base-command.js') class Init extends BaseCommand { @@ -119,13 +118,7 @@ class Init extends BaseCommand { localBin, globalBin, } = this.npm - // this function is definitely called. But because of coverage map stuff - // it ends up both uncovered, and the coverage report doesn't even mention. - // the tests do assert that some output happens, so we know this line is - // being hit. - /* istanbul ignore next */ - const output = (...outputArgs) => this.npm.output(...outputArgs) - const locationMsg = await getLocationMsg({ color, path }) + const output = this.npm.output.bind(this.npm) const runPath = path const scriptShell = this.npm.config.get('script-shell') || undefined const yes = this.npm.config.get('yes') @@ -135,7 +128,6 @@ class Init extends BaseCommand { args: newArgs, color, localBin, - locationMsg, globalBin, output, path, diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js index d3932072b7d348..073ca0c6992e83 100644 --- a/deps/npm/lib/commands/ls.js +++ b/deps/npm/lib/commands/ls.js @@ -92,7 +92,7 @@ class LS extends ArboristWorkspaceCmd { } if (this.npm.flatOptions.includeWorkspaceRoot - && !edge.to.isWorkspace) { + && edge.to && !edge.to.isWorkspace) { return true } diff --git a/deps/npm/lib/commands/query.js b/deps/npm/lib/commands/query.js new file mode 100644 index 00000000000000..371fddef9b4408 --- /dev/null +++ b/deps/npm/lib/commands/query.js @@ -0,0 +1,104 @@ +'use strict' + +const { resolve } = require('path') +const Arborist = require('@npmcli/arborist') +const BaseCommand = require('../base-command.js') + +class QuerySelectorItem { + constructor (node) { + // all enumerable properties from the target + Object.assign(this, node.target.package) + + // append extra info + this.pkgid = node.target.pkgid + this.location = node.target.location + this.path = node.target.path + this.realpath = node.target.realpath + this.resolved = node.target.resolved + this.from = [] + this.to = [] + this.dev = node.target.dev + this.inBundle = node.target.inBundle + this.deduped = this.from.length > 1 + for (const edge of node.target.edgesIn) { + this.from.push(edge.from.location) + } + for (const [, edge] of node.target.edgesOut) { + if (edge.to) { + this.to.push(edge.to.location) + } + } + } +} + +class Query extends BaseCommand { + #response = [] // response is the query response + #seen = new Set() // paths we've seen so we can keep response deduped + + static description = 'Retrieve a filtered list of packages' + static name = 'query' + static usage = [''] + + static ignoreImplicitWorkspace = false + + static params = [ + 'global', + 'workspace', + 'workspaces', + 'include-workspace-root', + ] + + get parsedResponse () { + return JSON.stringify(this.#response, null, 2) + } + + async exec (args) { + // one dir up from wherever node_modules lives + const where = resolve(this.npm.dir, '..') + const opts = { + ...this.npm.flatOptions, + path: where, + } + const arb = new Arborist(opts) + const tree = await arb.loadActual(opts) + const items = await tree.querySelectorAll(args[0]) + this.buildResponse(items) + + this.npm.output(this.parsedResponse) + } + + async execWorkspaces (args, filters) { + await this.setWorkspaces(filters) + const opts = { + ...this.npm.flatOptions, + path: this.npm.prefix, + } + const arb = new Arborist(opts) + const tree = await arb.loadActual(opts) + for (const workspacePath of this.workspacePaths) { + let items + if (workspacePath === tree.root.path) { + // include-workspace-root + items = await tree.querySelectorAll(args[0]) + } else { + const [workspace] = await tree.querySelectorAll(`.workspace:path(${workspacePath})`) + items = await workspace.target.querySelectorAll(args[0]) + } + this.buildResponse(items) + } + this.npm.output(this.parsedResponse) + } + + // builds a normalized inventory + buildResponse (items) { + for (const node of items) { + if (!this.#seen.has(node.target.location)) { + const item = new QuerySelectorItem(node) + this.#response.push(item) + this.#seen.add(item.location) + } + } + } +} + +module.exports = Query diff --git a/deps/npm/lib/exec/get-workspace-location-msg.js b/deps/npm/lib/exec/get-workspace-location-msg.js deleted file mode 100644 index 813b11e7892223..00000000000000 --- a/deps/npm/lib/exec/get-workspace-location-msg.js +++ /dev/null @@ -1,25 +0,0 @@ -const chalk = require('chalk') -const readPackageJson = require('read-package-json-fast') - -const nocolor = { - dim: s => s, - green: s => s, -} - -const getLocationMsg = async ({ color, path }) => { - const colorize = color ? chalk : nocolor - const { _id } = - await readPackageJson(`${path}/package.json`) - .catch(() => ({})) - - const workspaceMsg = _id - ? ` in workspace ${colorize.green(_id)}` - : ` in a ${colorize.green('new')} workspace` - const locationMsg = ` at location:\n${ - colorize.dim(path) - }` - - return `${workspaceMsg}${locationMsg}` -} - -module.exports = getLocationMsg diff --git a/deps/npm/lib/utils/cmd-list.js b/deps/npm/lib/utils/cmd-list.js index c1d20186a82a6d..38439542a21f9e 100644 --- a/deps/npm/lib/utils/cmd-list.js +++ b/deps/npm/lib/utils/cmd-list.js @@ -114,6 +114,7 @@ const cmdList = [ 'profile', 'prune', 'publish', + 'query', 'rebuild', 'repo', 'restart', diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js index 7d6af2473f2bd6..a132c8456b0fa0 100644 --- a/deps/npm/lib/utils/config/definitions.js +++ b/deps/npm/lib/utils/config/definitions.js @@ -1470,7 +1470,7 @@ define('package', { hint: '', type: [String, Array], description: ` - The package to install for [\`npm exec\`](/commands/npm-exec) + The package or packages to install for [\`npm exec\`](/commands/npm-exec) `, flatten, }) @@ -1649,6 +1649,24 @@ define('registry', { flatten, }) +define('replace-registry-host', { + default: 'npmjs', + hint: ' | hostname', + type: ['npmjs', 'never', 'always', String], + description: ` + Defines behavior for replacing the registry host in a lockfile with the + configured registry. + + 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. + + You may also specify a bare hostname (e.g., "registry.npmjs.org"). + `, + flatten, +}) + define('save', { default: true, defaultDescription: `\`true\` unless when using \`npm update\` where it diff --git a/deps/npm/lib/utils/open-url-prompt.js b/deps/npm/lib/utils/open-url-prompt.js index 3eb3ac288c0355..290040e5d14aa7 100644 --- a/deps/npm/lib/utils/open-url-prompt.js +++ b/deps/npm/lib/utils/open-url-prompt.js @@ -34,6 +34,11 @@ const promptOpen = async (npm, url, title, prompt, emitter) => { }) const tryOpen = await new Promise(resolve => { + rl.on('SIGINT', () => { + rl.close() + resolve('SIGINT') + }) + rl.question(prompt, () => { resolve(true) }) @@ -50,6 +55,10 @@ const promptOpen = async (npm, url, title, prompt, emitter) => { } }) + if (tryOpen === 'SIGINT') { + throw new Error('canceled') + } + if (!tryOpen) { return } diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 2c3f67180c1c89..703268cab4d879 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" "July 2022" "" "" +.TH "NPM\-ACCESS" "1" "August 2022" "" "" .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 fc27cef4516a28..5e46279d09d22a 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" "July 2022" "" "" +.TH "NPM\-ADDUSER" "1" "August 2022" "" "" .SH "NAME" \fBnpm-adduser\fR \- Add a registry user account .SS Synopsis diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1 index ac628b8a80c517..41b431b401d242 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" "July 2022" "" "" +.TH "NPM\-AUDIT" "1" "August 2022" "" "" .SH "NAME" \fBnpm-audit\fR \- Run a security audit .SS Synopsis diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1 index a3316780613917..a9c32cbf3e61c5 100644 --- a/deps/npm/man/man1/npm-bin.1 +++ b/deps/npm/man/man1/npm-bin.1 @@ -1,4 +1,4 @@ -.TH "NPM\-BIN" "1" "July 2022" "" "" +.TH "NPM\-BIN" "1" "August 2022" "" "" .SH "NAME" \fBnpm-bin\fR \- Display npm bin folder .SS Synopsis diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index d401d152d4fa9c..ded7cba677ce4a 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" "July 2022" "" "" +.TH "NPM\-BUGS" "1" "August 2022" "" "" .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 379fdccedd94b7..1825e026f1811c 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" "July 2022" "" "" +.TH "NPM\-CACHE" "1" "August 2022" "" "" .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 6a83ab881caec5..da444f6f45ef82 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" "July 2022" "" "" +.TH "NPM\-CI" "1" "August 2022" "" "" .SH "NAME" \fBnpm-ci\fR \- Clean install a project .SS Synopsis @@ -66,7 +66,7 @@ added 154 packages in 5s .fi .RE .P -Configure Travis to build using \fBnpm ci\fP instead of \fBnpm install\fP: +Configure Travis CI to build using \fBnpm ci\fP instead of \fBnpm install\fP: .P .RS 2 .nf diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index 6fedc9f5a4cab2..167ea44f368d9d 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" "July 2022" "" "" +.TH "NPM\-COMPLETION" "1" "August 2022" "" "" .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 1898ee6cdc630e..87719ca60f7b88 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" "July 2022" "" "" +.TH "NPM\-CONFIG" "1" "August 2022" "" "" .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 cdae87193198e6..6ea6dd169d279b 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" "July 2022" "" "" +.TH "NPM\-DEDUPE" "1" "August 2022" "" "" .SH "NAME" \fBnpm-dedupe\fR \- Reduce duplication in the package tree .SS Synopsis diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index ba9c1d083e9bf1..3ed0d4e4fa7546 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" "July 2022" "" "" +.TH "NPM\-DEPRECATE" "1" "August 2022" "" "" .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 6d5f0eb2c64e00..1776fbc23b09e5 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" "July 2022" "" "" +.TH "NPM\-DIFF" "1" "August 2022" "" "" .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 b96b7c26e4f7d2..f176336ebecff6 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" "July 2022" "" "" +.TH "NPM\-DIST\-TAG" "1" "August 2022" "" "" .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 d15191dd13ab94..f79dc835da073c 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" "July 2022" "" "" +.TH "NPM\-DOCS" "1" "August 2022" "" "" .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 aa4affb8908d37..14651e098d31db 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" "July 2022" "" "" +.TH "NPM\-DOCTOR" "1" "August 2022" "" "" .SH "NAME" \fBnpm-doctor\fR \- Check your npm environment .SS Synopsis diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index 7b0725b669c44d..d9c2c132439ab9 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" "July 2022" "" "" +.TH "NPM\-EDIT" "1" "August 2022" "" "" .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 f29a7bcb7d77b4..d2467f0c98f0dc 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" "July 2022" "" "" +.TH "NPM\-EXEC" "1" "August 2022" "" "" .SH "NAME" \fBnpm-exec\fR \- Run a command from a local or remote npm package .SS Synopsis @@ -129,7 +129,7 @@ Type: String (can be set multiple times) .RE .P -The package to install for npm help \fBexec\fP +The package or packages to install for npm help \fBexec\fP .SS \fBcall\fP .RS 0 .IP \(bu 2 diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1 index 0a0dd0a14991c4..7ff603fc1b3a0e 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" "July 2022" "" "" +.TH "NPM\-EXPLAIN" "1" "August 2022" "" "" .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 e46d75eec6a2b7..6bd60c93fcc03d 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" "July 2022" "" "" +.TH "NPM\-EXPLORE" "1" "August 2022" "" "" .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 6c5aa7e1b43131..e433180e7a6f09 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" "July 2022" "" "" +.TH "NPM\-FIND\-DUPES" "1" "August 2022" "" "" .SH "NAME" \fBnpm-find-dupes\fR \- Find duplication in the package tree .SS Synopsis diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index 06612675a4a0da..77631d7d7e9f5e 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" "July 2022" "" "" +.TH "NPM\-FUND" "1" "August 2022" "" "" .SH "NAME" \fBnpm-fund\fR \- Retrieve funding information .SS Synopsis diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index 69b13814f1af26..5cd66df0e33e55 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" "July 2022" "" "" +.TH "NPM\-HELP\-SEARCH" "1" "August 2022" "" "" .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 7c541c114df917..3ff6c4452cd82a 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" "July 2022" "" "" +.TH "NPM\-HELP" "1" "August 2022" "" "" .SH "NAME" \fBnpm-help\fR \- Get help on npm .SS Synopsis diff --git a/deps/npm/man/man1/npm-hook.1 b/deps/npm/man/man1/npm-hook.1 index 0eee4018b4eac4..abecdbfc279ff3 100644 --- a/deps/npm/man/man1/npm-hook.1 +++ b/deps/npm/man/man1/npm-hook.1 @@ -1,4 +1,4 @@ -.TH "NPM\-HOOK" "1" "July 2022" "" "" +.TH "NPM\-HOOK" "1" "August 2022" "" "" .SH "NAME" \fBnpm-hook\fR \- Manage registry hooks .SS Synopsis diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index b21a794af47cc2..1098fa467d03ee 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" "July 2022" "" "" +.TH "NPM\-INIT" "1" "August 2022" "" "" .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 10f785698528d9..6a55a8fd978a67 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" "July 2022" "" "" +.TH "NPM\-INSTALL\-CI\-TEST" "1" "August 2022" "" "" .SH "NAME" \fBnpm-install-ci-test\fR \- Install a project with a clean slate and run tests .SS Synopsis diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index 0cd44530fd7e0b..55360a9f7dc19e 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" "July 2022" "" "" +.TH "NPM\-INSTALL\-TEST" "1" "August 2022" "" "" .SH "NAME" \fBnpm-install-test\fR \- Install package(s) and run tests .SS Synopsis diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index f54f1e202cd067..4b350b83c586c0 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" "July 2022" "" "" +.TH "NPM\-INSTALL" "1" "August 2022" "" "" .SH "NAME" \fBnpm-install\fR \- Install a package .SS Synopsis diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index 8943060964e156..a577656a249ea3 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" "July 2022" "" "" +.TH "NPM\-LINK" "1" "August 2022" "" "" .SH "NAME" \fBnpm-link\fR \- Symlink a package folder .SS Synopsis diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index 1e0d35f9005bb8..6481d8e9840f5c 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" "July 2022" "" "" +.TH "NPM\-LOGOUT" "1" "August 2022" "" "" .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 cc465caebe5a1e..f0852befaace42 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" "July 2022" "" "" +.TH "NPM\-LS" "1" "August 2022" "" "" .SH "NAME" \fBnpm-ls\fR \- List installed packages .SS Synopsis @@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf -npm@8\.15\.1 /path/to/npm +npm@8\.16\.0 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 .fi diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1 index 9545a27ced04f9..09d1bedfc2b171 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" "July 2022" "" "" +.TH "NPM\-ORG" "1" "August 2022" "" "" .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 b18a2bd064b137..ab0bd8520b81b8 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" "July 2022" "" "" +.TH "NPM\-OUTDATED" "1" "August 2022" "" "" .SH "NAME" \fBnpm-outdated\fR \- Check for outdated packages .SS Synopsis diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index ebdf9f719c8412..6df79588f5f24f 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" "July 2022" "" "" +.TH "NPM\-OWNER" "1" "August 2022" "" "" .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 f89580c2090606..9b8ebd69a9e592 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" "July 2022" "" "" +.TH "NPM\-PACK" "1" "August 2022" "" "" .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 c60ce739dfea26..7972db6b7b0bea 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" "July 2022" "" "" +.TH "NPM\-PING" "1" "August 2022" "" "" .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 9bffc812fc6f84..9bf1c007dfe7ef 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" "July 2022" "" "" +.TH "NPM\-PKG" "1" "August 2022" "" "" .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 fcc9f57bcfbb13..906021bf21de2e 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" "July 2022" "" "" +.TH "NPM\-PREFIX" "1" "August 2022" "" "" .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 285f4e118be6ea..f0b19a614bb758 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" "July 2022" "" "" +.TH "NPM\-PROFILE" "1" "August 2022" "" "" .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 0a3c631fb57dc1..c2209502fc578d 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" "July 2022" "" "" +.TH "NPM\-PRUNE" "1" "August 2022" "" "" .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 664e5664ba95d7..e45c52a88e9d43 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" "July 2022" "" "" +.TH "NPM\-PUBLISH" "1" "August 2022" "" "" .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 new file mode 100644 index 00000000000000..a6b4d040304d74 --- /dev/null +++ b/deps/npm/man/man1/npm-query.1 @@ -0,0 +1,240 @@ +.TH "NPM\-QUERY" "1" "August 2022" "" "" +.SH "NAME" +\fBnpm-query\fR \- Dependency selector query +.SS Synopsis +.P +.RS 2 +.nf +npm query +.fi +.RE +.SS Description +.P +The \fBnpm query\fP command allows for usage of css selectors in order to retrieve +an array of dependency objects\. +.SS Piping npm query to other commands +.P +.RS 2 +.nf +# find all dependencies with postinstall scripts & uninstall them +npm query ":attr(scripts, [postinstall])" | jq 'map(\.name)|join("\\n")' \-r | xargs \-I {} npm uninstall {} + +# find all git dependencies & explain who requires them +npm query ":type(git)" | jq 'map(\.name)' | xargs \-I {} npm why {} +.fi +.RE +.SS Extended Use Cases & Queries +.P +.RS 2 +.nf +// all deps +* + +// all direct deps +:root > * + +// direct production deps +:root > \.prod + +// direct development deps +:root > \.dev + +// any peer dep of a direct deps +:root > * > \.peer + +// any workspace dep +\|\.workspace + +// all workspaces that depend on another workspace +\|\.workspace > \.workspace + +// all workspaces that have peer deps +\|\.workspace:has(\.peer) + +// any dep named "lodash" +// equivalent to [name="lodash"] +#lodash + +// any deps named "lodash" & within semver range ^"1\.2\.3" +#lodash@^1\.2\.3 +// equivalent to\.\.\. +[name="lodash"]:semver(^1\.2\.3) + +// get the hoisted node for a given semver range +#lodash@^1\.2\.3:not(:deduped) + +// querying deps with a specific version +#lodash@2\.1\.5 +// equivalent to\.\.\. +[name="lodash"][version="2\.1\.5"] + +// has any deps +:has(*) + +// deps with no other deps (ie\. "leaf" nodes) +:empty + +// manually querying git dependencies +[repository^=github:], +[repository^=git:], +[repository^=https://github\.com], +[repository^=http://github\.com], +[repository^=https://github\.com], +[repository^=+git:\.\.\.] + +// querying for all git dependencies +:type(git) + +// get production dependencies that aren't also dev deps +\|\.prod:not(\.dev) + +// get dependencies with specific licenses +[license=MIT], [license=ISC] + +// find all packages that have @ruyadorno as a contributor +:attr(contributors, [email=ruyadorno@github\.com]) +.fi +.RE +.SS Example Response Output +.RS 0 +.IP \(bu 2 +an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped + +.RE +.P +.RS 2 +.nf +[ + { + "name": "", + "version": "", + "description": "", + "homepage": "", + "bugs": {}, + "author": {}, + "license": {}, + "funding": {}, + "files": [], + "main": "", + "browser": "", + "bin": {}, + "man": [], + "directories": {}, + "repository": {}, + "scripts": {}, + "config": {}, + "dependencies": {}, + "devDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": {}, + "peerDependencies": {}, + "peerDependenciesMeta": {}, + "engines": {}, + "os": [], + "cpu": [], + "workspaces": {}, + "keywords": [], + \.\.\. + }, + \.\.\. +.fi +.RE +.SS Configuration +.SS \fBglobal\fP +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Operates in "global" mode, so that packages are installed into the \fBprefix\fP +folder instead of the current working directory\. See +npm help folders for more on the differences in behavior\. +.RS 0 +.IP \(bu 2 +packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead +of the current working directory\. +.IP \(bu 2 +bin files are linked to \fB{prefix}/bin\fP +.IP \(bu 2 +man pages are linked to \fB{prefix}/share/man\fP + +.RE +.SS \fBworkspace\fP +.RS 0 +.IP \(bu 2 +Default: +.IP \(bu 2 +Type: String (can be set multiple times) + +.RE +.P +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option\. +.P +Valid values for the \fBworkspace\fP config are either: +.RS 0 +.IP \(bu 2 +Workspace names +.IP \(bu 2 +Path to a workspace directory +.IP \(bu 2 +Path to a parent workspace directory (will result in selecting all +workspaces within that folder) + +.RE +.P +When set for the \fBnpm init\fP command, this may be set to the folder of a +workspace which does not yet exist, to create the folder and set it up as a +brand new workspace within the project\. +.P +This value is not exported to the environment for child processes\. +.SS \fBworkspaces\fP +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: null or Boolean + +.RE +.P +Set to true to run the command in the context of \fBall\fR configured +workspaces\. +.P +Explicitly setting this to false will cause commands like \fBinstall\fP to +ignore workspaces altogether\. When not set explicitly: +.RS 0 +.IP \(bu 2 +Commands that operate on the \fBnode_modules\fP tree (install, update, etc\.) +will link workspaces into the \fBnode_modules\fP folder\. \- Commands that do +other things (test, exec, publish, etc\.) will operate on the root project, +\fIunless\fR one or more workspaces are specified in the \fBworkspace\fP config\. + +.RE +.P +This value is not exported to the environment for child processes\. +.SS \fBinclude\-workspace\-root\fP +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Include the workspace root when workspaces are enabled for a command\. +.P +When false, specifying individual workspaces via the \fBworkspace\fP config, or +all workspaces via the \fBworkspaces\fP flag, will cause npm to operate only on +the specified workspaces, and not on the root project\. +.P +This value is not exported to the environment for child processes\. +.SH See Also +.RS 0 +.IP \(bu 2 +npm help dependency selector + +.RE diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index a59bfb49bf9c17..96461f98494f03 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" "July 2022" "" "" +.TH "NPM\-REBUILD" "1" "August 2022" "" "" .SH "NAME" \fBnpm-rebuild\fR \- Rebuild a package .SS Synopsis diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index a56585cfe18840..f473b406cb7c52 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" "July 2022" "" "" +.TH "NPM\-REPO" "1" "August 2022" "" "" .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 99da68ba9ae4e5..1dde3f5538ff2e 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" "July 2022" "" "" +.TH "NPM\-RESTART" "1" "August 2022" "" "" .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 093aacaf1d78c0..1ef2690ea51651 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" "July 2022" "" "" +.TH "NPM\-ROOT" "1" "August 2022" "" "" .SH "NAME" \fBnpm-root\fR \- Display npm root .SS Synopsis diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1 index 6c056ca9f6be3c..8034b90bc295bb 100644 --- a/deps/npm/man/man1/npm-run-script.1 +++ b/deps/npm/man/man1/npm-run-script.1 @@ -1,4 +1,4 @@ -.TH "NPM\-RUN\-SCRIPT" "1" "July 2022" "" "" +.TH "NPM\-RUN\-SCRIPT" "1" "August 2022" "" "" .SH "NAME" \fBnpm-run-script\fR \- Run arbitrary package scripts .SS Synopsis diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index 7ecd371aa95962..2bc4a90cd589e4 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" "July 2022" "" "" +.TH "NPM\-SEARCH" "1" "August 2022" "" "" .SH "NAME" \fBnpm-search\fR \- Search for packages .SS Synopsis diff --git a/deps/npm/man/man1/npm-set-script.1 b/deps/npm/man/man1/npm-set-script.1 index 66197695fa93a1..10e80ceebb0643 100644 --- a/deps/npm/man/man1/npm-set-script.1 +++ b/deps/npm/man/man1/npm-set-script.1 @@ -1,4 +1,4 @@ -.TH "NPM\-SET\-SCRIPT" "1" "July 2022" "" "" +.TH "NPM\-SET\-SCRIPT" "1" "August 2022" "" "" .SH "NAME" \fBnpm-set-script\fR \- Set tasks in the scripts section of package\.json .SS Synopsis diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 702c2d18a3ba28..125f961da14381 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" "July 2022" "" "" +.TH "NPM\-SHRINKWRAP" "1" "August 2022" "" "" .SH "NAME" \fBnpm-shrinkwrap\fR \- Lock down dependency versions for publication .SS Synopsis diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index 1abbc968298f33..a588e020971096 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" "July 2022" "" "" +.TH "NPM\-STAR" "1" "August 2022" "" "" .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 f4c52978e0ae45..d0c9be4e69db53 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" "July 2022" "" "" +.TH "NPM\-STARS" "1" "August 2022" "" "" .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 5176b3b3dc12e1..634514c030691e 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" "July 2022" "" "" +.TH "NPM\-START" "1" "August 2022" "" "" .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 da3d1e3a1f0523..9d5fb0d332a382 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" "July 2022" "" "" +.TH "NPM\-STOP" "1" "August 2022" "" "" .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 2b16d2db0ea322..63fa957a491d09 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" "July 2022" "" "" +.TH "NPM\-TEAM" "1" "August 2022" "" "" .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 f67c2752d7fcd0..5467d706eeb862 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" "July 2022" "" "" +.TH "NPM\-TEST" "1" "August 2022" "" "" .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 f16b421f0f1852..38c8a5b2f5a5f2 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" "July 2022" "" "" +.TH "NPM\-TOKEN" "1" "August 2022" "" "" .SH "NAME" \fBnpm-token\fR \- Manage your authentication tokens .SS Synopsis diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index 654a0ae681f401..eefb3e79fa170b 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" "July 2022" "" "" +.TH "NPM\-UNINSTALL" "1" "August 2022" "" "" .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 6577e11e837765..3ecc3d6868ccce 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" "July 2022" "" "" +.TH "NPM\-UNPUBLISH" "1" "August 2022" "" "" .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 43600931c9f8df..327aed2290f107 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" "July 2022" "" "" +.TH "NPM\-UNSTAR" "1" "August 2022" "" "" .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 54bf4184fbf6f6..0c60874939aae8 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" "July 2022" "" "" +.TH "NPM\-UPDATE" "1" "August 2022" "" "" .SH "NAME" \fBnpm-update\fR \- Update packages .SS Synopsis diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 40c157adf971e0..40685823b70da2 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" "July 2022" "" "" +.TH "NPM\-VERSION" "1" "August 2022" "" "" .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 b3d9488a9f9be2..91df44561d0957 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" "July 2022" "" "" +.TH "NPM\-VIEW" "1" "August 2022" "" "" .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 27a7bbb4ce87e6..e44429ac4147dc 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" "July 2022" "" "" +.TH "NPM\-WHOAMI" "1" "August 2022" "" "" .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 b3bc8bb417198d..2d92f18f6fc8ac 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,10 +1,10 @@ -.TH "NPM" "1" "July 2022" "" "" +.TH "NPM" "1" "August 2022" "" "" .SH "NAME" \fBnpm\fR \- javascript package manager .SS Synopsis .SS Version .P -8\.15\.1 +8\.16\.0 .SS Description .P npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1 index 47eefc4dd25796..4af0ed99356eb8 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -1,4 +1,4 @@ -.TH "NPX" "1" "July 2022" "" "" +.TH "NPX" "1" "August 2022" "" "" .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 924ee0fa243d1c..b6efd3c880333d 100644 --- a/deps/npm/man/man5/folders.5 +++ b/deps/npm/man/man5/folders.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "July 2022" "" "" +.TH "FOLDERS" "5" "August 2022" "" "" .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 7d8c5693027cc2..b006ed81d89f49 100644 --- a/deps/npm/man/man5/install.5 +++ b/deps/npm/man/man5/install.5 @@ -1,4 +1,4 @@ -.TH "INSTALL" "5" "July 2022" "" "" +.TH "INSTALL" "5" "August 2022" "" "" .SH "NAME" \fBinstall\fR \- Download and install node and npm .SS Description diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5 index 931d1ae49f01c3..fa88d6a447b82c 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" "July 2022" "" "" +.TH "NPM\-SHRINKWRAP\.JSON" "5" "August 2022" "" "" .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 a4d2ee239f8543..7f506bf225839f 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH "NPMRC" "5" "July 2022" "" "" +.TH "NPMRC" "5" "August 2022" "" "" .SH "NAME" \fBnpmrc\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 ae522f1de8294a..d4f9723112b166 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" "July 2022" "" "" +.TH "PACKAGE\.JSON" "5" "August 2022" "" "" .SH "NAME" \fBpackage.json\fR \- Specifics of npm's package\.json handling .SS Description diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5 index ad4fa609649f72..5dc67f04d60f81 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" "July 2022" "" "" +.TH "PACKAGE\-LOCK\.JSON" "5" "August 2022" "" "" .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 bb0c65e9851255..ba185464ed05be 100644 --- a/deps/npm/man/man7/config.7 +++ b/deps/npm/man/man7/config.7 @@ -1,4 +1,4 @@ -.TH "CONFIG" "7" "July 2022" "" "" +.TH "CONFIG" "7" "August 2022" "" "" .SH "NAME" \fBconfig\fR \- More than you probably want to know about npm configuration .SS Description @@ -1315,7 +1315,7 @@ Type: String (can be set multiple times) .RE .P -The package to install for npm help \fBexec\fP +The package or packages to install for npm help \fBexec\fP .SS \fBpackage\-lock\fP .RS 0 .IP \(bu 2 @@ -1460,6 +1460,24 @@ Type: URL .RE .P The base URL of the npm registry\. +.SS \fBreplace\-registry\-host\fP +.RS 0 +.IP \(bu 2 +Default: "npmjs" +.IP \(bu 2 +Type: "npmjs", "never", "always", or String + +.RE +.P +Defines behavior for replacing the registry host in a lockfile with the +configured registry\. +.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")\. .SS \fBsave\fP .RS 0 .IP \(bu 2 diff --git a/deps/npm/man/man7/dependency-selectors.7 b/deps/npm/man/man7/dependency-selectors.7 new file mode 100644 index 00000000000000..ae6f58bd1b30fe --- /dev/null +++ b/deps/npm/man/man7/dependency-selectors.7 @@ -0,0 +1,245 @@ +.TH "DEPENDENCY" "" "August 2022" "" "" +.SH "NAME" +\fBDependency\fR +.SS Description +.P +The npm help \fBquery\fP commmand exposes a new dependency selector syntax (informed by & respecting many aspects of the CSS Selectors 4 Spec \fIhttps://dev\.w3\.org/csswg/selectors4/#relational)\fR which: +.RS 0 +.IP \(bu 2 +Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax +.IP \(bu 2 +Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible +.IP \(bu 2 +Unlocks the ability to answer complex, multi\-faceted questions about dependencies, their relationships & associative metadata +.IP \(bu 2 +Consolidates redundant logic of similar query commands in \fBnpm\fP (ex\. \fBnpm fund\fP, \fBnpm ls\fP, \fBnpm outdated\fP, \fBnpm audit\fP \.\.\.) + +.RE +.SS Dependency Selector Syntax \fBv1\.0\.0\fP +.SS Overview: +.RS 0 +.IP \(bu 2 +there is no "type" or "tag" selectors (ex\. \fBdiv, h1, a\fP) as a dependency/target is the only type of \fBNode\fP that can be queried +.IP \(bu 2 +the term "dependencies" is in reference to any \fBNode\fP found in a \fBtree\fP returned by \fBArborist\fP + +.RE +.SS Combinators +.RS 0 +.IP \(bu 2 +\fB>\fP direct descendant/child +.IP \(bu 2 +\fB \fP any descendant/child +.IP \(bu 2 +\fB~\fP sibling + +.RE +.SS Selectors +.RS 0 +.IP \(bu 2 +\fB*\fP universal selector +.IP \(bu 2 +\fB#\fP dependency selector (equivalent to \fB[name="\.\.\."]\fP) +.IP \(bu 2 +\fB#@\fP (equivalent to \fB[name=]:semver()\fP) +.IP \(bu 2 +\fB,\fP selector list delimiter +.IP \(bu 2 +\fB\|\.\fP dependency type selector +.IP \(bu 2 +\fB:\fP pseudo selector + +.RE +.SS Dependency Type Selectors +.RS 0 +.IP \(bu 2 +\fB\|\.prod\fP dependency found in the \fBdependencies\fP section of \fBpackage\.json\fP, or is a child of said dependency +.IP \(bu 2 +\fB\|\.dev\fP dependency found in the \fBdevDependencies\fP section of \fBpackage\.json\fP, or is a child of said dependency +.IP \(bu 2 +\fB\|\.optional\fP dependency found in the \fBoptionalDependencies\fP section of \fBpackage\.json\fP, or has \fB"optional": true\fP set in its entry in the \fBpeerDependenciesMeta\fP section of \fBpackage\.json\fP, or a child of said dependency +.IP \(bu 2 +\fB\|\.peer\fP dependency found in the \fBpeerDependencies\fP section of \fBpackage\.json\fP +.IP \(bu 2 +\fB\|\.workspace\fP dependency found in the \fBworkspaces\fP \fIhttps://docs\.npmjs\.com/cli/v8/using\-npm/workspaces\fR section of \fBpackage\.json\fP +.IP \(bu 2 +\fB\|\.bundled\fP dependency found in the \fBbundleDependencies\fP section of \fBpackage\.json\fP, or is a child of said dependency + +.RE +.SS Pseudo Selectors +.RS 0 +.IP \(bu 2 +\fB:not()\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:not\fR +.IP \(bu 2 +\fB:has()\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:has\fR +.IP \(bu 2 +\fB:is()\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:is\fR +.IP \(bu 2 +\fB:root\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:root\fR matches the root node/dependency +.IP \(bu 2 +\fB:scope\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:scope\fR matches node/dependency it was queried against +.IP \(bu 2 +\fB:empty\fP \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/:empty\fR when a dependency has no dependencies +.IP \(bu 2 +\fB:private\fP \fIhttps://docs\.npmjs\.com/cli/v8/configuring\-npm/package\-json#private\fR when a dependency is private +.IP \(bu 2 +\fB:link\fP when a dependency is linked (for instance, workspaces or packages manually \fBlinked\fP \fIhttps://docs\.npmjs\.com/cli/v8/commands/npm\-link\fR +.IP \(bu 2 +\fB:deduped\fP when a dependency has been deduped (note that this does \fInot\fR always mean the dependency has been hoisted to the root of node_modules) +.IP \(bu 2 +\fB:override\fP when a dependency is an override (not implemented yet) +.IP \(bu 2 +\fB:extraneous\fP when a dependency exists but is not defined as a dependency of any node +.IP \(bu 2 +\fB:invalid\fP when a dependency version is out of its ancestors specified range +.IP \(bu 2 +\fB:missing\fP when a dependency is not found on disk +.IP \(bu 2 +\fB:semver()\fP matching a valid \fBnode\-semver\fP \fIhttps://github\.com/npm/node\-semver\fR spec +.IP \(bu 2 +\fB:path()\fP glob \fIhttps://www\.npmjs\.com/package/glob\fR matching based on dependencies path relative to the project +.IP \(bu 2 +\fB:type()\fP based on currently recognized types \fIhttps://github\.com/npm/npm\-package\-arg#result\-object\fR + +.RE +.SS Attribute Selectors \fIhttps://developer\.mozilla\.org/en\-US/docs/Web/CSS/Attribute_selectors\fR +.P +The attribute selector evaluates the key/value pairs in \fBpackage\.json\fP if they are \fBString\fPs\. +.RS 0 +.IP \(bu 2 +\fB[]\fP attribute selector (ie\. existence of attribute) +.IP \(bu 2 +\fB[attribute=value]\fP attribute value is equivalant\.\.\. +.IP \(bu 2 +\fB[attribute~=value]\fP attribute value contains word\.\.\. +.IP \(bu 2 +\fB[attribute*=value]\fP attribute value contains string\.\.\. +.IP \(bu 2 +\fB[attribute|=value]\fP attribute value is equal to or starts with\.\.\. +.IP \(bu 2 +\fB[attribute^=value]\fP attribute value starts with\.\.\. +.IP \(bu 2 +\fB[attribute$=value]\fP attribute value ends with\.\.\. + +.RE +.SS \fBArray\fP & \fBObject\fP Attribute Selectors +.P +The generic \fB:attr()\fP pseudo selector standardizes a pattern which can be used for attribute selection of \fBObject\fPs, \fBArray\fPs or \fBArrays\fP of \fBObject\fPs accessible via \fBArborist\fP\|'s \fBNode\.package\fP metadata\. This allows for iterative attribute selection beyond top\-level \fBString\fP evaluation\. The last argument passed to \fB:attr()\fP must be an \fBattribute\fP selector or a nested \fB:attr()\fP\|\. See examples below: +.SS \fBObjects\fP +.P +.RS 2 +.nf +/* return dependencies that have a `scripts\.test` containing `"tap"` */ +*:attr(scripts, [test~=tap]) +.fi +.RE +.SS Nested \fBObjects\fP +.P +Nested objects are expressed as sequential arguments to \fB:attr()\fP\|\. +.P +.RS 2 +.nf +/* return dependencies that have a testling config for opera browsers */ +*:attr(testling, browsers, [~=opera]) +.fi +.RE +.SS \fBArrays\fP +.P +\fBArray\fPs specifically uses a special/reserved \fB\|\.\fP character in place of a typical attribute name\. \fBArrays\fP also support exact \fBvalue\fP matching when a \fBString\fP is passed to the selector\. +.SS Example of an \fBArray\fP Attribute Selection: +.P +.RS 2 +.nf +/* removes the distinction between properties & arrays */ +/* ie\. we'd have to check the property & iterate to match selection */ +*:attr([keywords^=react]) +*:attr(contributors, :attr([name~=Jordan])) +.fi +.RE +.SS Example of an \fBArray\fP matching directly to a value: +.P +.RS 2 +.nf +/* return dependencies that have the exact keyword "react" */ +/* this is equivalent to `*:keywords([value="react"])` */ +*:attr([keywords=react]) +.fi +.RE +.SS Example of an \fBArray\fP of \fBObject\fPs: +.P +.RS 2 +.nf +/* returns */ +*:attr(contributors, [email=ruyadorno@github\.com]) +.fi +.RE +.SS Groups +.P +Dependency groups are defined by the package relationships to their ancestors (ie\. the dependency types that are defined in \fBpackage\.json\fP)\. This approach is user\-centric as the ecosystem has been taught to think about dependencies in these groups first\-and\-foremost\. Dependencies are allowed to be included in multiple groups (ex\. a \fBprod\fP dependency may also be a \fBdev\fP dependency (in that it's also required by another \fBdev\fP dependency) & may also be \fBbundled\fP \- a selector for that type of dependency would look like: \fB*\.prod\.dev\.bundled\fP)\. +.RS 0 +.IP \(bu 2 +\fB\|\.prod\fP +.IP \(bu 2 +\fB\|\.dev\fP +.IP \(bu 2 +\fB\|\.optional\fP +.IP \(bu 2 +\fB\|\.peer\fP +.IP \(bu 2 +\fB\|\.bundled\fP +.IP \(bu 2 +\fB\|\.workspace\fP + +.RE +.P +Please note that currently \fBworkspace\fP deps are always \fBprod\fP dependencies\. Additionally the \fB\|\.root\fP dependency is also considered a \fBprod\fP dependency\. +.SS Programmatic Usage +.RS 0 +.IP \(bu 2 +\fBArborist\fP\|'s \fBNode\fP Class has a \fB\|\.querySelectorAll()\fP method +.RS +.IP \(bu 2 +this method will return a filtered, flattened dependency Arborist \fBNode\fP list based on a valid query selector + +.RE + +.RE +.P +.RS 2 +.nf +const Arborist = require('@npmcli/arborist') +const arb = new Arborist({}) +.fi +.RE +.P +.RS 2 +.nf +// root\-level +arb\.loadActual((tree) => { + // query all production dependencies + const results = await tree\.querySelectorAll('\.prod') + console\.log(results) +}) +.fi +.RE +.P +.RS 2 +.nf +// iterative +arb\.loadActual((tree) => { + // query for the deduped version of react + const results = await tree\.querySelectorAll('#react:not(:deduped)') + // query the deduped react for git deps + const deps = await results[0]\.querySelectorAll(':type(git)') + console\.log(deps) +}) +.fi +.RE +.SH See Also +.RS 0 +.IP \(bu 2 +npm help query +.IP \(bu 2 +[@npmcli/arborist](https://npm\.im/@npmcli/arborist] + +.RE diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7 index 595fc387ca48c5..171decac45d67f 100644 --- a/deps/npm/man/man7/developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,4 +1,4 @@ -.TH "DEVELOPERS" "7" "July 2022" "" "" +.TH "DEVELOPERS" "7" "August 2022" "" "" .SH "NAME" \fBdevelopers\fR \- Developer Guide .SS Description diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7 index 9f637cff885945..b2aa408db5e682 100644 --- a/deps/npm/man/man7/logging.7 +++ b/deps/npm/man/man7/logging.7 @@ -1,4 +1,4 @@ -.TH "LOGGING" "7" "July 2022" "" "" +.TH "LOGGING" "7" "August 2022" "" "" .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 cb718d7476aa8a..a5e2f41a07d8c7 100644 --- a/deps/npm/man/man7/orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,4 +1,4 @@ -.TH "ORGS" "7" "July 2022" "" "" +.TH "ORGS" "7" "August 2022" "" "" .SH "NAME" \fBorgs\fR \- Working with Teams & Orgs .SS Description diff --git a/deps/npm/man/man7/package-spec.7 b/deps/npm/man/man7/package-spec.7 index 01da091d16b6f0..c728cc523b2fa2 100644 --- a/deps/npm/man/man7/package-spec.7 +++ b/deps/npm/man/man7/package-spec.7 @@ -1,4 +1,4 @@ -.TH "PACKAGE\-SPEC" "7" "July 2022" "" "" +.TH "PACKAGE\-SPEC" "7" "August 2022" "" "" .SH "NAME" \fBpackage-spec\fR \- Package name specifier .SS Description diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7 index 0afd375ae74660..6afd6295c665b1 100644 --- a/deps/npm/man/man7/registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,4 +1,4 @@ -.TH "REGISTRY" "7" "July 2022" "" "" +.TH "REGISTRY" "7" "August 2022" "" "" .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 e30f3afbd7889d..8493d9b82b199b 100644 --- a/deps/npm/man/man7/removal.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,4 +1,4 @@ -.TH "REMOVAL" "7" "July 2022" "" "" +.TH "REMOVAL" "7" "August 2022" "" "" .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 825b9298f063c7..cd4690e240ba1a 100644 --- a/deps/npm/man/man7/scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,4 +1,4 @@ -.TH "SCOPE" "7" "July 2022" "" "" +.TH "SCOPE" "7" "August 2022" "" "" .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 87a6d72492cff3..e5e3acaeff872a 100644 --- a/deps/npm/man/man7/scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,4 +1,4 @@ -.TH "SCRIPTS" "7" "July 2022" "" "" +.TH "SCRIPTS" "7" "August 2022" "" "" .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 6575130ec7f759..d567ef197877c4 100644 --- a/deps/npm/man/man7/workspaces.7 +++ b/deps/npm/man/man7/workspaces.7 @@ -1,4 +1,4 @@ -.TH "WORKSPACES" "7" "July 2022" "" "" +.TH "WORKSPACES" "7" "August 2022" "" "" .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 0e98ed6fc533c1..945bae56b63de4 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 @@ -1076,9 +1076,8 @@ This is a one-time fix-up, please be patient... // if it fails at this point, though, dont' worry because it // may well be an optional dep that has gone missing. it'll // fail later anyway. - const from = fromPath(placed) promises.push(...this[_problemEdges](placed).map(e => - this[_fetchManifest](npa.resolve(e.name, e.spec, from)) + this[_fetchManifest](npa.resolve(e.name, e.spec, fromPath(placed, e))) .catch(er => null))) }, }) diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js index cb6ef1e0c2ccb9..9564f7648f92cf 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js @@ -74,8 +74,12 @@ class Arborist extends Base { cache: options.cache || `${homedir()}/.npm/_cacache`, packumentCache: options.packumentCache || new Map(), workspacesEnabled: options.workspacesEnabled !== false, + replaceRegistryHost: options.replaceRegistryHost, lockfileVersion: lockfileVersion(options.lockfileVersion), } + this.replaceRegistryHost = this.options.replaceRegistryHost = + (!this.options.replaceRegistryHost || this.options.replaceRegistryHost === 'npmjs') ? + 'registry.npmjs.org' : this.options.replaceRegistryHost this[_workspacesEnabled] = this.options.workspacesEnabled 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 4f1061e4abe500..7663a3a342cc6d 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js @@ -712,13 +712,19 @@ module.exports = cls => class Reifier extends cls { [_registryResolved] (resolved) { // the default registry url is a magic value meaning "the currently // configured registry". + // `resolved` must never be falsey. // // XXX: use a magic string that isn't also a valid value, like // ${REGISTRY} or something. This has to be threaded through the // Shrinkwrap and Node classes carefully, so for now, just treat // the default reg as the magical animal that it has been. - return resolved && resolved - .replace(/^https?:\/\/registry\.npmjs\.org\//, this.registry) + const resolvedURL = new URL(resolved) + if ((this.options.replaceRegistryHost === resolvedURL.hostname) + || this.options.replaceRegistryHost === 'always') { + // this.registry always has a trailing slash + resolved = `${this.registry.slice(0, -1)}${resolvedURL.pathname}${resolvedURL.searchParams}` + } + return resolved } // bundles are *sort of* like shrinkwraps, in that the branch is defined 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 c69ab557ae491a..d02f397fcdf17e 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js @@ -20,7 +20,7 @@ const depValid = (child, requested, requestor) => { // file: deps that depend on other files/dirs, we must resolve the // location based on the *requestor* file/dir, not where it ends up. // '' is equivalent to '*' - requested = npa.resolve(child.name, requested || '*', fromPath(requestor)) + requested = npa.resolve(child.name, requested || '*', fromPath(requestor, requestor.edgesOut.get(child.name))) } catch (er) { // Not invalid because the child doesn't match, but because // the spec itself is not supported. Nothing would match, diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/edge.js b/deps/npm/node_modules/@npmcli/arborist/lib/edge.js index a04404f2265633..5b248b91662085 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/edge.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/edge.js @@ -169,7 +169,11 @@ class Edge { if (this.overrides && this.overrides.value && this.overrides.name === this.name) { if (this.overrides.value.startsWith('$')) { const ref = this.overrides.value.slice(1) - const pkg = this.from.root.package + // we may be a virtual root, if we are we want to resolve reference overrides + // from the real root, not the virtual one + const pkg = this.from.sourceReference + ? this.from.sourceReference.root.package + : this.from.root.package const overrideSpec = (pkg.devDependencies && pkg.devDependencies[ref]) || (pkg.optionalDependencies && pkg.optionalDependencies[ref]) || (pkg.dependencies && pkg.dependencies[ref]) || diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/from-path.js b/deps/npm/node_modules/@npmcli/arborist/lib/from-path.js index 2a3617844c0016..1006f73af3d073 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/from-path.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/from-path.js @@ -6,8 +6,19 @@ const { dirname } = require('path') const npa = require('npm-package-arg') -const fromPath = (node, spec) => - spec && spec.type === 'file' ? dirname(spec.fetchSpec) - : node.realpath +const fromPath = (node, spec, edge) => { + if (edge && edge.overrides && edge.overrides.name === edge.name && edge.overrides.value) { + // fromPath could be called with a node that has a virtual root, if that happens + // we want to make sure we get the real root node when overrides are in use. this + // is to allow things like overriding a dependency with a tarball file that's a + // relative path from the project root + return node.sourceReference + ? node.sourceReference.root.realpath + : node.root.realpath + } -module.exports = node => fromPath(node, node.resolved && npa(node.resolved)) + return spec && spec.type === 'file' ? dirname(spec.fetchSpec) + : node.realpath +} + +module.exports = (node, edge) => fromPath(node, node.resolved && npa(node.resolved), edge) diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/node.js b/deps/npm/node_modules/@npmcli/arborist/lib/node.js index 66d46d746abf3e..be973565750a1d 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/node.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/node.js @@ -69,6 +69,8 @@ const consistentResolve = require('./consistent-resolve.js') const printableTree = require('./printable.js') const CaseInsensitiveMap = require('./case-insensitive-map.js') +const querySelectorAll = require('./query-selector-all.js') + class Node { constructor (options) { // NB: path can be null if it's a link target @@ -1446,6 +1448,12 @@ class Node { return base === name && basename(nm) === 'node_modules' ? dir : false } + // maybe accept both string value or array of strings + // seems to be what dom API does + querySelectorAll (query) { + return querySelectorAll(this, query) + } + toJSON () { return printableTree(this) } 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 new file mode 100644 index 00000000000000..6c540dea3c872e --- /dev/null +++ b/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js @@ -0,0 +1,561 @@ +'use strict' + +const { resolve } = require('path') +const { parser, arrayDelimiter } = require('@npmcli/query') +const localeCompare = require('@isaacs/string-locale-compare')('en') +const npa = require('npm-package-arg') +const minimatch = require('minimatch') +const semver = require('semver') + +// 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 +// arborist nodes as its value, that is essential to how we handle multiple +// query selectors, e.g: `#a, #b, #c` <- 3 diff ast selector nodes +class Results { + #currentAstSelector + #initialItems + #inventory + #pendingCombinator + #results = new Map() + #targetNode + + constructor (opts) { + this.#currentAstSelector = opts.rootAstNode.nodes[0] + this.#inventory = opts.inventory + this.#initialItems = opts.initialItems + this.#targetNode = opts.targetNode + + this.currentResults = this.#initialItems + + // reset by rootAstNode walker + this.currentAstNode = opts.rootAstNode + } + + get currentResults () { + return this.#results.get(this.#currentAstSelector) + } + + set currentResults (value) { + this.#results.set(this.#currentAstSelector, value) + } + + // retrieves the initial items to which start the filtering / matching + // for most of the different types of recognized ast nodes, e.g: class (aka + // depType), id, *, etc in different contexts we need to start with the + // current list of filtered results, for example a query for `.workspace` + // actually means the same as `*.workspace` so we want to start with the full + // inventory if that's the first ast node we're reading but if it appears in + // the middle of a query it should respect the previous filtered results, + // combinators are a special case in which we always want to have the + // complete inventory list in order to use the left-hand side ast node as a + // filter combined with the element on its right-hand side + get initialItems () { + const firstParsed = + (this.currentAstNode.parent.nodes[0] === this.currentAstNode) && + (this.currentAstNode.parent.parent.type === 'root') + + if (firstParsed) { + return this.#initialItems + } + if (this.currentAstNode.prev().type === 'combinator') { + return this.#inventory + } + return this.currentResults + } + + // combinators need information about previously filtered items along + // with info of the items parsed / retrieved from the selector right + // past the combinator, for this reason combinators are stored and + // only ran as the last part of each selector logic + processPendingCombinator (nextResults) { + if (this.#pendingCombinator) { + const res = this.#pendingCombinator(this.currentResults, nextResults) + this.#pendingCombinator = null + this.currentResults = res + } else { + this.currentResults = nextResults + } + } + + // when collecting results to a root astNode, we traverse the list of child + // selector nodes and collect all of their resulting arborist nodes into a + // single/flat Set of items, this ensures we also deduplicate items + collect (rootAstNode) { + return new Set(rootAstNode.nodes.flatMap(n => this.#results.get(n))) + } + + // selector types map to the '.type' property of the ast nodes via `${astNode.type}Type` + // + // attribute selector [name=value], etc + attributeType () { + const nextResults = this.initialItems.filter(node => + attributeMatch(this.currentAstNode, node.package) + ) + this.processPendingCombinator(nextResults) + } + + // dependency type selector (i.e. .prod, .dev, etc) + // css calls this class, we interpret is as dependency type + classType () { + const depTypeFn = depTypes[String(this.currentAstNode)] + if (!depTypeFn) { + throw Object.assign( + new Error(`\`${String(this.currentAstNode)}\` is not a supported dependency type.`), + { code: 'EQUERYNODEPTYPE' } + ) + } + const nextResults = depTypeFn(this.initialItems) + this.processPendingCombinator(nextResults) + } + + // combinators (i.e. '>', ' ', '~') + combinatorType () { + this.#pendingCombinator = combinators[String(this.currentAstNode)] + } + + // name selectors (i.e. #foo, #foo@1.0.0) + // css calls this id, we interpret it as name + idType () { + const spec = npa(this.currentAstNode.value) + const nextResults = this.initialItems.filter(node => + (node.name === spec.name || node.package.name === spec.name) && + (semver.satisfies(node.version, spec.fetchSpec) || !spec.rawSpec)) + this.processPendingCombinator(nextResults) + } + + // pseudo selectors (prefixed with :) + pseudoType () { + const pseudoFn = `${this.currentAstNode.value.slice(1)}Pseudo` + if (!this[pseudoFn]) { + throw Object.assign( + new Error(`\`${this.currentAstNode.value + }\` is not a supported pseudo selector.`), + { code: 'EQUERYNOPSEUDO' } + ) + } + const nextResults = this[pseudoFn]() + this.processPendingCombinator(nextResults) + } + + selectorType () { + this.#currentAstSelector = this.currentAstNode + // starts a new array in which resulting items + // can be stored for each given ast selector + if (!this.currentResults) { + this.currentResults = [] + } + } + + universalType () { + this.processPendingCombinator(this.initialItems) + } + + // pseudo selectors map to the 'value' property of the pseudo selectors in the ast nodes + // via selectors via `${value.slice(1)}Pseudo` + attrPseudo () { + const { lookupProperties, attributeMatcher } = this.currentAstNode + + return this.initialItems.filter(node => { + let objs = [node.package] + for (const prop of lookupProperties) { + // if an isArray symbol is found that means we'll need to iterate + // over the previous found array to basically make sure we traverse + // all its indexes testing for possible objects that may eventually + // hold more keys specified in a selector + if (prop === arrayDelimiter) { + objs = objs.flat() + continue + } + + // otherwise just maps all currently found objs + // to the next prop from the lookup properties list, + // filters out any empty key lookup + objs = objs.flatMap(obj => obj[prop] || []) + + // in case there's no property found in the lookup + // just filters that item out + const noAttr = objs.every(obj => !obj) + if (noAttr) { + return false + } + } + + // if any of the potential object matches + // that item should be in the final result + return objs.some(obj => attributeMatch(attributeMatcher, obj)) + }) + } + + emptyPseudo () { + return this.initialItems.filter(node => node.edgesOut.size === 0) + } + + extraneousPseudo () { + return this.initialItems.filter(node => node.extraneous) + } + + hasPseudo () { + const found = [] + for (const item of this.initialItems) { + const res = retrieveNodesFromParsedAst({ + // This is the one time initialItems differs from inventory + initialItems: [item], + inventory: this.#inventory, + rootAstNode: this.currentAstNode.nestedNode, + targetNode: item, + }) + if (res.size > 0) { + found.push(item) + } + } + return found + } + + invalidPseudo () { + const found = [] + for (const node of this.initialItems) { + for (const edge of node.edgesIn) { + if (edge.invalid) { + found.push(node) + break + } + } + } + return found + } + + isPseudo () { + const res = retrieveNodesFromParsedAst({ + initialItems: this.initialItems, + inventory: this.#inventory, + rootAstNode: this.currentAstNode.nestedNode, + targetNode: this.currentAstNode, + }) + return [...res] + } + + linkPseudo () { + return this.initialItems.filter(node => node.isLink || (node.isTop && !node.isRoot)) + } + + missingPseudo () { + return this.#inventory.reduce((res, node) => { + for (const edge of node.edgesOut.values()) { + if (edge.missing) { + const pkg = { name: edge.name, version: edge.spec } + res.push(new this.#targetNode.constructor({ pkg })) + } + } + return res + }, []) + } + + notPseudo () { + const res = retrieveNodesFromParsedAst({ + initialItems: this.initialItems, + inventory: this.#inventory, + rootAstNode: this.currentAstNode.nestedNode, + targetNode: this.currentAstNode, + }) + const internalSelector = new Set(res) + return this.initialItems.filter(node => + !internalSelector.has(node)) + } + + pathPseudo () { + return this.initialItems.filter(node => { + if (!this.currentAstNode.pathValue) { + return true + } + return minimatch( + node.realpath.replace(/\\+/g, '/'), + resolve(node.root.realpath, this.currentAstNode.pathValue).replace(/\\+/g, '/') + ) + }) + } + + privatePseudo () { + return this.initialItems.filter(node => node.package.private) + } + + rootPseudo () { + return this.initialItems.filter(node => node === this.#targetNode.root) + } + + scopePseudo () { + return this.initialItems.filter(node => node === this.#targetNode) + } + + semverPseudo () { + if (!this.currentAstNode.semverValue) { + return this.initialItems + } + return this.initialItems.filter(node => + semver.satisfies(node.version, this.currentAstNode.semverValue)) + } + + typePseudo () { + if (!this.currentAstNode.typeValue) { + return this.initialItems + } + return this.initialItems + .flatMap(node => { + const found = [] + for (const edge of node.edgesIn) { + if (npa(`${edge.name}@${edge.spec}`).type === this.currentAstNode.typeValue) { + found.push(edge.to) + } + } + return found + }) + } + + dedupedPseudo () { + return this.initialItems.filter(node => node.target.edgesIn.size > 1) + } +} + +// operators for attribute selectors +const attributeOperators = { + // attribute value is equivalent + '=' ({ attr, value, insensitive }) { + return attr === value + }, + // attribute value contains word + '~=' ({ attr, value, insensitive }) { + return (attr.match(/\w+/g) || []).includes(value) + }, + // attribute value contains string + '*=' ({ attr, value, insensitive }) { + return attr.includes(value) + }, + // attribute value is equal or starts with + '|=' ({ attr, value, insensitive }) { + return attr.startsWith(`${value}-`) + }, + // attribute value starts with + '^=' ({ attr, value, insensitive }) { + return attr.startsWith(value) + }, + // attribute value ends with + '$=' ({ attr, value, insensitive }) { + return attr.endsWith(value) + }, +} + +const attributeOperator = ({ attr, value, insensitive, operator }) => { + if (typeof attr === 'number') { + attr = String(attr) + } + if (typeof attr !== 'string') { + // It's an object or an array, bail + return false + } + if (insensitive) { + attr = attr.toLowerCase() + } + return attributeOperators[operator]({ + attr, + insensitive, + value, + }) +} + +const attributeMatch = (matcher, obj) => { + const insensitive = !!matcher.insensitive + const operator = matcher.operator || '' + const attribute = matcher.qualifiedAttribute + let value = matcher.value || '' + // return early if checking existence + if (operator === '') { + return Boolean(obj[attribute]) + } + if (insensitive) { + value = value.toLowerCase() + } + // in case the current object is an array + // then we try to match every item in the array + if (Array.isArray(obj[attribute])) { + return obj[attribute].find((i, index) => { + const attr = obj[attribute][index] || '' + return attributeOperator({ attr, value, insensitive, operator }) + }) + } else { + const attr = obj[attribute] || '' + return attributeOperator({ attr, value, insensitive, operator }) + } +} + +const edgeIsType = (node, type, seen = new Set()) => { + for (const edgeIn of node.edgesIn) { + // TODO Need a test with an infinite loop + if (seen.has(edgeIn)) { + continue + } + seen.add(edgeIn) + if (edgeIn.type === type || edgeIn.from[type] || edgeIsType(edgeIn.from, type, seen)) { + return true + } + } + return false +} + +const filterByType = (nodes, type) => { + const found = [] + for (const node of nodes) { + if (node[type] || edgeIsType(node, type)) { + found.push(node) + } + } + return found +} + +const depTypes = { + // dependency + '.prod' (prevResults) { + const found = [] + for (const node of prevResults) { + if (!node.dev) { + found.push(node) + } + } + return found + }, + // devDependency + '.dev' (prevResults) { + return filterByType(prevResults, 'dev') + }, + // optionalDependency + '.optional' (prevResults) { + return filterByType(prevResults, 'optional') + }, + // peerDependency + '.peer' (prevResults) { + return filterByType(prevResults, 'peer') + }, + // workspace + '.workspace' (prevResults) { + return prevResults.filter(node => node.isWorkspace) + }, + // bundledDependency + '.bundled' (prevResults) { + return prevResults.filter(node => node.inBundle) + }, +} + +// checks if a given node has a direct parent in any of the nodes provided in +// the compare nodes array +const hasParent = (node, compareNodes) => { + // All it takes is one so we loop and return on the first hit + for (const compareNode of compareNodes) { + // follows logical parent for link anscestors + if (node.isTop && (node.resolveParent === compareNode)) { + return true + } + // follows edges-in to check if they match a possible parent + for (const edge of node.edgesIn) { + if (edge && edge.from === compareNode) { + return true + } + } + } + return false +} + +// checks if a given node is a descendant of any of the nodes provided in the +// compareNodes array +const hasAscendant = (node, compareNodes, seen = new Set()) => { + // TODO (future) loop over ancestry property + if (hasParent(node, compareNodes)) { + return true + } + + if (node.isTop && node.resolveParent) { + return hasAscendant(node.resolveParent, compareNodes) + } + for (const edge of node.edgesIn) { + // TODO Need a test with an infinite loop + if (seen.has(edge)) { + continue + } + seen.add(edge) + if (edge && edge.from && hasAscendant(edge.from, compareNodes, seen)) { + return true + } + } + return false +} + +const combinators = { + // direct descendant + '>' (prevResults, nextResults) { + return nextResults.filter(node => hasParent(node, prevResults)) + }, + // any descendant + ' ' (prevResults, nextResults) { + return nextResults.filter(node => hasAscendant(node, prevResults)) + }, + // sibling + '~' (prevResults, nextResults) { + // Return any node in nextResults that is a sibling of (aka shares a + // parent with) a node in prevResults + const parentNodes = new Set() // Parents of everything in prevResults + for (const node of prevResults) { + for (const edge of node.edgesIn) { + // edge.from always exists cause it's from another node's edgesIn + parentNodes.add(edge.from) + } + } + return nextResults.filter(node => + !prevResults.includes(node) && hasParent(node, [...parentNodes]) + ) + }, +} + +const retrieveNodesFromParsedAst = (opts) => { + // when we first call this it's the parsed query. all other times it's + // results.currentNode.nestedNode + const rootAstNode = opts.rootAstNode + + if (!rootAstNode.nodes) { + return new Set() + } + + const results = new Results(opts) + + rootAstNode.walk((nextAstNode) => { + // This is the only place we reset currentAstNode + results.currentAstNode = nextAstNode + const updateFn = `${results.currentAstNode.type}Type` + if (typeof results[updateFn] !== 'function') { + throw Object.assign( + new Error(`\`${results.currentAstNode.type}\` is not a supported selector.`), + { code: 'EQUERYNOSELECTOR' } + ) + } + results[updateFn]() + }) + + return results.collect(rootAstNode) +} + +// We are keeping this async in the event that we do add async operators, we +// won't have to have a breaking change on this function signature. +const querySelectorAll = async (targetNode, query) => { + // This never changes ever we just pass it around. But we can't scope it to + // this whole file if we ever want to support concurrent calls to this + // function. + const inventory = [...targetNode.root.inventory.values()] + // res is a Set of items returned for each parsed css ast selector + const res = retrieveNodesFromParsedAst({ + initialItems: inventory, + inventory, + rootAstNode: parser(query), + targetNode, + }) + + // returns nodes ordered by realpath + return [...res].sort((a, b) => localeCompare(a.location, b.location)) +} + +module.exports = querySelectorAll diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index 48814eda69166f..7bfb90a079da44 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": "5.3.1", + "version": "5.4.0", "description": "Manage node_modules trees", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", @@ -11,12 +11,14 @@ "@npmcli/name-from-folder": "^1.0.1", "@npmcli/node-gyp": "^2.0.0", "@npmcli/package-json": "^2.0.0", + "@npmcli/query": "^1.1.1", "@npmcli/run-script": "^4.1.3", "bin-links": "^3.0.0", "cacache": "^16.0.6", "common-ancestor-path": "^1.0.1", "json-parse-even-better-errors": "^2.3.1", "json-stringify-nice": "^1.1.4", + "minimatch": "^5.1.0", "mkdirp": "^1.0.4", "mkdirp-infer-owner": "^2.0.0", "nopt": "^5.0.0", diff --git a/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js b/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js deleted file mode 100644 index 7755d1c10e6d0f..00000000000000 --- a/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const url = require('url') - -const node = require('../node.js') -const polyfill = require('./polyfill.js') - -const useNative = node.satisfies('>=10.12.0') - -const fileURLToPath = (path) => { - // the polyfill is tested separately from this module, no need to hack - // process.version to try to trigger it just for coverage - // istanbul ignore next - return useNative - ? url.fileURLToPath(path) - : polyfill(path) -} - -module.exports = fileURLToPath diff --git a/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js b/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js deleted file mode 100644 index 6cc90f0b07d79f..00000000000000 --- a/deps/npm/node_modules/@npmcli/fs/lib/common/file-url-to-path/polyfill.js +++ /dev/null @@ -1,121 +0,0 @@ -const { URL, domainToUnicode } = require('url') - -const CHAR_LOWERCASE_A = 97 -const CHAR_LOWERCASE_Z = 122 - -const isWindows = process.platform === 'win32' - -class ERR_INVALID_FILE_URL_HOST extends TypeError { - constructor (platform) { - super(`File URL host must be "localhost" or empty on ${platform}`) - this.code = 'ERR_INVALID_FILE_URL_HOST' - } - - toString () { - return `${this.name} [${this.code}]: ${this.message}` - } -} - -class ERR_INVALID_FILE_URL_PATH extends TypeError { - constructor (msg) { - super(`File URL path ${msg}`) - this.code = 'ERR_INVALID_FILE_URL_PATH' - } - - toString () { - return `${this.name} [${this.code}]: ${this.message}` - } -} - -class ERR_INVALID_ARG_TYPE extends TypeError { - constructor (name, actual) { - super(`The "${name}" argument must be one of type string or an instance ` + - `of URL. Received type ${typeof actual} ${actual}`) - this.code = 'ERR_INVALID_ARG_TYPE' - } - - toString () { - return `${this.name} [${this.code}]: ${this.message}` - } -} - -class ERR_INVALID_URL_SCHEME extends TypeError { - constructor (expected) { - super(`The URL must be of scheme ${expected}`) - this.code = 'ERR_INVALID_URL_SCHEME' - } - - toString () { - return `${this.name} [${this.code}]: ${this.message}` - } -} - -const isURLInstance = (input) => { - return input != null && input.href && input.origin -} - -const getPathFromURLWin32 = (url) => { - const hostname = url.hostname - let pathname = url.pathname - for (let n = 0; n < pathname.length; n++) { - if (pathname[n] === '%') { - const third = pathname.codePointAt(n + 2) | 0x20 - if ((pathname[n + 1] === '2' && third === 102) || - (pathname[n + 1] === '5' && third === 99)) { - throw new ERR_INVALID_FILE_URL_PATH('must not include encoded \\ or / characters') - } - } - } - - pathname = pathname.replace(/\//g, '\\') - pathname = decodeURIComponent(pathname) - if (hostname !== '') { - return `\\\\${domainToUnicode(hostname)}${pathname}` - } - - const letter = pathname.codePointAt(1) | 0x20 - const sep = pathname[2] - if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z || - (sep !== ':')) { - throw new ERR_INVALID_FILE_URL_PATH('must be absolute') - } - - return pathname.slice(1) -} - -const getPathFromURLPosix = (url) => { - if (url.hostname !== '') { - throw new ERR_INVALID_FILE_URL_HOST(process.platform) - } - - const pathname = url.pathname - - for (let n = 0; n < pathname.length; n++) { - if (pathname[n] === '%') { - const third = pathname.codePointAt(n + 2) | 0x20 - if (pathname[n + 1] === '2' && third === 102) { - throw new ERR_INVALID_FILE_URL_PATH('must not include encoded / characters') - } - } - } - - return decodeURIComponent(pathname) -} - -const fileURLToPath = (path) => { - if (typeof path === 'string') { - path = new URL(path) - } else if (!isURLInstance(path)) { - throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path) - } - - if (path.protocol !== 'file:') { - throw new ERR_INVALID_URL_SCHEME('file') - } - - return isWindows - ? getPathFromURLWin32(path) - : getPathFromURLPosix(path) -} - -module.exports = fileURLToPath diff --git a/deps/npm/node_modules/@npmcli/fs/lib/common/owner-sync.js b/deps/npm/node_modules/@npmcli/fs/lib/common/owner-sync.js index 2055c4b21dec90..8fa18d5121effb 100644 --- a/deps/npm/node_modules/@npmcli/fs/lib/common/owner-sync.js +++ b/deps/npm/node_modules/@npmcli/fs/lib/common/owner-sync.js @@ -1,6 +1,6 @@ const { dirname, resolve } = require('path') +const url = require('url') -const fileURLToPath = require('./file-url-to-path/index.js') const fs = require('../fs.js') // given a path, find the owner of the nearest parent @@ -13,7 +13,7 @@ const find = (path) => { // fs methods accept URL objects with a scheme of file: so we need to unwrap // those into an actual path string before we can resolve it const resolved = path != null && path.href && path.origin - ? resolve(fileURLToPath(path)) + ? resolve(url.fileURLToPath(path)) : resolve(path) let stat diff --git a/deps/npm/node_modules/@npmcli/fs/lib/common/owner.js b/deps/npm/node_modules/@npmcli/fs/lib/common/owner.js index e3468b077d00ec..3fe167cfc30aa2 100644 --- a/deps/npm/node_modules/@npmcli/fs/lib/common/owner.js +++ b/deps/npm/node_modules/@npmcli/fs/lib/common/owner.js @@ -1,6 +1,6 @@ const { dirname, resolve } = require('path') +const url = require('url') -const fileURLToPath = require('./file-url-to-path/index.js') const fs = require('../fs.js') // given a path, find the owner of the nearest parent @@ -13,7 +13,7 @@ const find = async (path) => { // fs methods accept URL objects with a scheme of file: so we need to unwrap // those into an actual path string before we can resolve it const resolved = path != null && path.href && path.origin - ? resolve(fileURLToPath(path)) + ? resolve(url.fileURLToPath(path)) : resolve(path) let stat diff --git a/deps/npm/node_modules/@npmcli/fs/lib/index.js b/deps/npm/node_modules/@npmcli/fs/lib/index.js index 43892df5fee076..3a98648eca9a14 100644 --- a/deps/npm/node_modules/@npmcli/fs/lib/index.js +++ b/deps/npm/node_modules/@npmcli/fs/lib/index.js @@ -2,7 +2,7 @@ module.exports = { ...require('./fs.js'), copyFile: require('./copy-file.js'), cp: require('./cp/index.js'), - mkdir: require('./mkdir/index.js'), + mkdir: require('./mkdir.js'), mkdtemp: require('./mkdtemp.js'), rm: require('./rm/index.js'), withTempDir: require('./with-temp-dir.js'), diff --git a/deps/npm/node_modules/@npmcli/fs/lib/mkdir.js b/deps/npm/node_modules/@npmcli/fs/lib/mkdir.js new file mode 100644 index 00000000000000..098d8d0a09ae3f --- /dev/null +++ b/deps/npm/node_modules/@npmcli/fs/lib/mkdir.js @@ -0,0 +1,19 @@ +const fs = require('./fs.js') +const getOptions = require('./common/get-options.js') +const withOwner = require('./with-owner.js') + +// extends mkdir with the ability to specify an owner of the new dir +const mkdir = async (path, opts) => { + const options = getOptions(opts, { + copy: ['mode', 'recursive'], + wrap: 'mode', + }) + + return withOwner( + path, + () => fs.mkdir(path, options), + opts + ) +} + +module.exports = mkdir diff --git a/deps/npm/node_modules/@npmcli/fs/lib/mkdir/index.js b/deps/npm/node_modules/@npmcli/fs/lib/mkdir/index.js deleted file mode 100644 index e2691042daa26f..00000000000000 --- a/deps/npm/node_modules/@npmcli/fs/lib/mkdir/index.js +++ /dev/null @@ -1,29 +0,0 @@ -const fs = require('../fs.js') -const getOptions = require('../common/get-options.js') -const node = require('../common/node.js') -const withOwner = require('../with-owner.js') - -const polyfill = require('./polyfill.js') - -// node 10.12.0 added the options parameter, which allows recursive and mode -// properties to be passed -const useNative = node.satisfies('>=10.12.0') - -// extends mkdir with the ability to specify an owner of the new dir -const mkdir = async (path, opts) => { - const options = getOptions(opts, { - copy: ['mode', 'recursive'], - wrap: 'mode', - }) - - // the polyfill is tested separately from this module, no need to hack - // process.version to try to trigger it just for coverage - // istanbul ignore next - return withOwner( - path, - () => useNative ? fs.mkdir(path, options) : polyfill(path, options), - opts - ) -} - -module.exports = mkdir diff --git a/deps/npm/node_modules/@npmcli/fs/lib/mkdir/polyfill.js b/deps/npm/node_modules/@npmcli/fs/lib/mkdir/polyfill.js deleted file mode 100644 index 4f8e6f006a30ec..00000000000000 --- a/deps/npm/node_modules/@npmcli/fs/lib/mkdir/polyfill.js +++ /dev/null @@ -1,81 +0,0 @@ -const { dirname } = require('path') - -const fileURLToPath = require('../common/file-url-to-path/index.js') -const fs = require('../fs.js') - -const defaultOptions = { - mode: 0o777, - recursive: false, -} - -const mkdir = async (path, opts) => { - const options = { ...defaultOptions, ...opts } - - // if we're not in recursive mode, just call the real mkdir with the path and - // the mode option only - if (!options.recursive) { - return fs.mkdir(path, options.mode) - } - - const makeDirectory = async (dir, mode) => { - // we can't use dirname directly since these functions support URL - // objects with the file: protocol as the path input, so first we get a - // string path, then we can call dirname on that - const parent = dir != null && dir.href && dir.origin - ? dirname(fileURLToPath(dir)) - : dirname(dir) - - // if the parent is the dir itself, try to create it. anything but EISDIR - // should be rethrown - if (parent === dir) { - try { - await fs.mkdir(dir, opts) - } catch (err) { - if (err.code !== 'EISDIR') { - throw err - } - } - return undefined - } - - try { - await fs.mkdir(dir, mode) - return dir - } catch (err) { - // ENOENT means the parent wasn't there, so create that - if (err.code === 'ENOENT') { - const made = await makeDirectory(parent, mode) - await makeDirectory(dir, mode) - // return the shallowest path we created, i.e. the result of creating - // the parent - return made - } - - // an EEXIST means there's already something there - // an EROFS means we have a read-only filesystem and can't create a dir - // any other error is fatal and we should give up now - if (err.code !== 'EEXIST' && err.code !== 'EROFS') { - throw err - } - - // stat the directory, if the result is a directory, then we successfully - // created this one so return its path. otherwise, we reject with the - // original error by ignoring the error in the catch - try { - const stat = await fs.stat(dir) - if (stat.isDirectory()) { - // if it already existed, we didn't create anything so return - // undefined - return undefined - } - } catch (_) {} - - // if the thing that's there isn't a directory, then just re-throw - throw err - } - } - - return makeDirectory(path, options.mode) -} - -module.exports = mkdir diff --git a/deps/npm/node_modules/@npmcli/fs/lib/with-temp-dir.js b/deps/npm/node_modules/@npmcli/fs/lib/with-temp-dir.js index ac9ebb714b9892..ad08e6ee6e6d62 100644 --- a/deps/npm/node_modules/@npmcli/fs/lib/with-temp-dir.js +++ b/deps/npm/node_modules/@npmcli/fs/lib/with-temp-dir.js @@ -1,7 +1,7 @@ const { join, sep } = require('path') const getOptions = require('./common/get-options.js') -const mkdir = require('./mkdir/index.js') +const mkdir = require('./mkdir.js') const mkdtemp = require('./mkdtemp.js') const rm = require('./rm/index.js') diff --git a/deps/npm/node_modules/@npmcli/fs/package.json b/deps/npm/node_modules/@npmcli/fs/package.json index 799bf514f200b5..9e18028218d1a2 100644 --- a/deps/npm/node_modules/@npmcli/fs/package.json +++ b/deps/npm/node_modules/@npmcli/fs/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/fs", - "version": "2.1.0", + "version": "2.1.1", "description": "filesystem utilities for the npm cli", "main": "lib/index.js", "files": [ @@ -33,8 +33,8 @@ "license": "ISC", "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.1.2", - "tap": "^15.1.6" + "@npmcli/template-oss": "3.5.0", + "tap": "^16.0.1" }, "dependencies": { "@gar/promisify": "^1.1.3", @@ -45,6 +45,6 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.1.2" + "version": "3.5.0" } } diff --git a/deps/npm/node_modules/@npmcli/query/LICENSE b/deps/npm/node_modules/@npmcli/query/LICENSE new file mode 100644 index 00000000000000..5fc208ff122e08 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/query/LICENSE @@ -0,0 +1,20 @@ + + +ISC License + +Copyright npm, Inc. + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/@npmcli/query/lib/index.js b/deps/npm/node_modules/@npmcli/query/lib/index.js new file mode 100644 index 00000000000000..36a8c700caae12 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/query/lib/index.js @@ -0,0 +1,187 @@ +'use strict' + +const npa = require('npm-package-arg') +const parser = require('postcss-selector-parser') +const semver = require('semver') + +const arrayDelimiter = Symbol('arrayDelimiter') + +const escapeSlashes = str => + str.replace(/\//g, '\\/') + +const unescapeSlashes = str => + str.replace(/\\\//g, '/') + +const fixupIds = astNode => { + const { name, rawSpec: part } = npa(astNode.value) + const versionParts = [{ astNode, part }] + let currentAstNode = astNode.next() + + if (!part) { + return + } + + while (currentAstNode) { + versionParts.push({ astNode: currentAstNode, part: String(currentAstNode) }) + currentAstNode = currentAstNode.next() + } + + let version + let length = versionParts.length + while (!version && length) { + version = + semver.valid( + versionParts.slice(0, length).reduce((res, i) => `${res}${i.part}`, '') + ) + length-- + } + + astNode.value = `${name}@${version}` + + for (let i = 1; i <= length; i++) { + versionParts[i].astNode.remove() + } +} + +// recursively fixes up any :attr pseudo-class found +const fixupAttr = astNode => { + const properties = [] + const matcher = {} + for (const selectorAstNode of astNode.nodes) { + const [firstAstNode] = selectorAstNode.nodes + if (firstAstNode.type === 'tag') { + properties.push(firstAstNode.value) + } + } + + const lastSelectorAstNode = astNode.nodes.pop() + const [attributeAstNode] = lastSelectorAstNode.nodes + + if (attributeAstNode.value === ':attr') { + const appendParts = fixupAttr(attributeAstNode) + properties.push(arrayDelimiter, ...appendParts.lookupProperties) + matcher.qualifiedAttribute = appendParts.attributeMatcher.qualifiedAttribute + matcher.operator = appendParts.attributeMatcher.operator + matcher.value = appendParts.attributeMatcher.value + + // backwards compatibility + matcher.attribute = appendParts.attributeMatcher.attribute + + if (appendParts.attributeMatcher.insensitive) { + matcher.insensitive = true + } + } else { + if (attributeAstNode.type !== 'attribute') { + throw Object.assign( + new Error('`:attr` pseudo-class expects an attribute matcher as the last value'), + { code: 'EQUERYATTR' } + ) + } + + matcher.qualifiedAttribute = unescapeSlashes(attributeAstNode.qualifiedAttribute) + matcher.operator = attributeAstNode.operator + matcher.value = attributeAstNode.value + + // backwards compatibility + matcher.attribute = matcher.qualifiedAttribute + + if (attributeAstNode.insensitive) { + matcher.insensitive = true + } + } + + astNode.lookupProperties = properties + astNode.attributeMatcher = matcher + astNode.nodes.length = 0 + return astNode +} + +// fixed up nested pseudo nodes will have their internal selectors moved +// to a new root node that will be referenced by the `nestedNode` property, +// this tweak makes it simpler to reuse `retrieveNodesFromParsedAst` to +// recursively parse and extract results from the internal selectors +const fixupNestedPseudo = astNode => { + // create a new ast root node and relocate any children + // selectors of the current ast node to this new root + const newRootNode = parser.root() + astNode.nestedNode = newRootNode + newRootNode.nodes = [...astNode.nodes] + + // clean up the ast by removing the children nodes from the + // current ast node while also cleaning up their `parent` refs + astNode.nodes.length = 0 + for (const currAstNode of newRootNode.nodes) { + currAstNode.parent = newRootNode + } + + // recursively fixup nodes of any nested selector + transformAst(newRootNode) +} + +const fixupSemverSpecs = astNode => { + const children = astNode.nodes[0].nodes + const value = children.reduce((res, i) => `${res}${String(i)}`, '') + + astNode.semverValue = value + astNode.nodes.length = 0 +} + +const fixupTypes = astNode => { + const [valueAstNode] = astNode.nodes[0].nodes + const { value } = valueAstNode || {} + astNode.typeValue = value + astNode.nodes.length = 0 +} + +const fixupPaths = astNode => { + astNode.pathValue = unescapeSlashes(String(astNode.nodes[0])) + astNode.nodes.length = 0 +} + +// a few of the supported ast nodes need to be tweaked in order to properly be +// interpreted as proper arborist query selectors, namely semver ranges from +// both ids and :semver pseudo-class selectors need to be translated from what +// are usually multiple ast nodes, such as: tag:1, class:.0, class:.0 to a +// single `1.0.0` value, other pseudo-class selectors also get preprocessed in +// order to make it simpler to execute later when traversing each ast node +// using rootNode.walk(), such as :path, :type, etc. transformAst handles all +// these modifications to the parsed ast by doing an extra, initial traversal +// of the parsed ast from the query and modifying the parsed nodes accordingly +const transformAst = selector => { + selector.walk((nextAstNode) => { + if (nextAstNode.type === 'id') { + fixupIds(nextAstNode) + } + + switch (nextAstNode.value) { + case ':attr': + return fixupAttr(nextAstNode) + case ':is': + case ':has': + case ':not': + return fixupNestedPseudo(nextAstNode) + case ':path': + return fixupPaths(nextAstNode) + case ':semver': + return fixupSemverSpecs(nextAstNode) + case ':type': + return fixupTypes(nextAstNode) + } + }) +} + +const queryParser = (query) => { + // if query is an empty string or any falsy + // value, just returns an empty result + if (!query) { + return [] + } + + return parser(transformAst) + .astSync(escapeSlashes(query), { lossless: false }) +} + +module.exports = { + parser: queryParser, + arrayDelimiter, +} diff --git a/deps/npm/node_modules/@npmcli/query/package.json b/deps/npm/node_modules/@npmcli/query/package.json new file mode 100644 index 00000000000000..0c9247e0bb23bc --- /dev/null +++ b/deps/npm/node_modules/@npmcli/query/package.json @@ -0,0 +1,61 @@ +{ + "name": "@npmcli/query", + "version": "1.1.1", + "description": "npm query parser and tools", + "main": "lib/index.js", + "scripts": { + "test": "tap", + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "snap": "tap", + "posttest": "npm run lint" + }, + "contributors": [ + { + "name": "Ruy Adorno", + "url": "https://ruyadorno.com", + "twitter": "ruyadorno" + } + ], + "keywords": [ + "ast", + "npm", + "npmcli", + "parser", + "postcss", + "postcss-selector-parser", + "query" + ], + "author": "GitHub Inc.", + "license": "ISC", + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "3.5.0" + }, + "devDependencies": { + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "3.5.0", + "tap": "^16.2.0" + }, + "dependencies": { + "npm-package-arg": "^9.1.0", + "postcss-selector-parser": "^6.0.10", + "semver": "^7.3.7" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/query.git" + } +} diff --git a/deps/npm/node_modules/@npmcli/run-script/lib/make-spawn-args.js b/deps/npm/node_modules/@npmcli/run-script/lib/make-spawn-args.js index f2253d7cc607b1..7725fd976c893d 100644 --- a/deps/npm/node_modules/@npmcli/run-script/lib/make-spawn-args.js +++ b/deps/npm/node_modules/@npmcli/run-script/lib/make-spawn-args.js @@ -20,6 +20,7 @@ const makeSpawnArgs = options => { event, path, scriptShell = isWindows ? process.env.ComSpec || 'cmd' : 'sh', + binPaths, env = {}, stdio, cmd, @@ -27,7 +28,7 @@ const makeSpawnArgs = options => { stdioString = false, } = options - const spawnEnv = setPATH(path, { + const spawnEnv = setPATH(path, binPaths, { // we need to at least save the PATH environment var ...process.env, ...env, @@ -100,7 +101,9 @@ const makeSpawnArgs = options => { // delete the script, this is just a best effort try { unlink(scriptFile) - } catch (err) {} + } catch (err) { + // ignore errors + } } return [scriptShell, spawnArgs, spawnOpts, cleanup] diff --git a/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js b/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js index 84c5e2bfe0c521..ec6ef31e50ab0e 100644 --- a/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js +++ b/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js @@ -14,6 +14,7 @@ const runScriptPkg = async options => { event, path, scriptShell, + binPaths = false, env = {}, stdio = 'pipe', pkg, @@ -58,6 +59,7 @@ const runScriptPkg = async options => { event, path, scriptShell, + binPaths, env: packageEnvs(env, pkg), stdio, cmd, diff --git a/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js b/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js index 07671f44579dc1..c59c270d9969a0 100644 --- a/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js +++ b/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js @@ -1,5 +1,4 @@ -const { resolve, dirname } = require('path') -const isWindows = require('./is-windows.js') +const { resolve, dirname, delimiter } = require('path') // the path here is relative, even though it does not need to be // in order to make the posix tests pass in windows const nodeGypPath = resolve(__dirname, '../lib/node-gyp-bin') @@ -7,18 +6,19 @@ const nodeGypPath = resolve(__dirname, '../lib/node-gyp-bin') // Windows typically calls its PATH environ 'Path', but this is not // guaranteed, nor is it guaranteed to be the only one. Merge them // all together in the order they appear in the object. -const setPATH = (projectPath, env) => { - // not require('path').delimiter, because we fake this for testing - const delimiter = isWindows ? ';' : ':' +const setPATH = (projectPath, binPaths, env) => { const PATH = Object.keys(env).filter(p => /^path$/i.test(p) && env[p]) .map(p => env[p].split(delimiter)) .reduce((set, p) => set.concat(p.filter(concatted => !set.includes(concatted))), []) .join(delimiter) const pathArr = [] + if (binPaths) { + pathArr.push(...binPaths) + } // unshift the ./node_modules/.bin from every folder // walk up until dirname() does nothing, at the root - // XXX should we specify a cwd that we don't go above? + // XXX we should specify a cwd that we don't go above let p = projectPath let pp do { diff --git a/deps/npm/node_modules/@npmcli/run-script/package.json b/deps/npm/node_modules/@npmcli/run-script/package.json index c096f39421bf11..a6629826d29c2c 100644 --- a/deps/npm/node_modules/@npmcli/run-script/package.json +++ b/deps/npm/node_modules/@npmcli/run-script/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/run-script", - "version": "4.1.7", + "version": "4.2.0", "description": "Run a lifecycle script for a package (descendant of npm-lifecycle)", "author": "GitHub Inc.", "license": "ISC", diff --git a/deps/npm/node_modules/cssesc/LICENSE-MIT.txt b/deps/npm/node_modules/cssesc/LICENSE-MIT.txt new file mode 100644 index 00000000000000..a41e0a7ef970ec --- /dev/null +++ b/deps/npm/node_modules/cssesc/LICENSE-MIT.txt @@ -0,0 +1,20 @@ +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/cssesc/README.md b/deps/npm/node_modules/cssesc/README.md new file mode 100644 index 00000000000000..58fb8fe0b6b91f --- /dev/null +++ b/deps/npm/node_modules/cssesc/README.md @@ -0,0 +1,201 @@ +# cssesc [![Build status](https://travis-ci.org/mathiasbynens/cssesc.svg?branch=master)](https://travis-ci.org/mathiasbynens/cssesc) [![Code coverage status](https://img.shields.io/codecov/c/github/mathiasbynens/cssesc.svg)](https://codecov.io/gh/mathiasbynens/cssesc) + +A JavaScript library for escaping CSS strings and identifiers while generating the shortest possible ASCII-only output. + +This is a JavaScript library for [escaping text for use in CSS strings or identifiers](https://mathiasbynens.be/notes/css-escapes) while generating the shortest possible valid ASCII-only output. [Here’s an online demo.](https://mothereff.in/css-escapes) + +[A polyfill for the CSSOM `CSS.escape()` method is available in a separate repository.](https://mths.be/cssescape) (In comparison, _cssesc_ is much more powerful.) + +Feel free to fork if you see possible improvements! + +## Installation + +Via [npm](https://www.npmjs.com/): + +```bash +npm install cssesc +``` + +In a browser: + +```html + +``` + +In [Node.js](https://nodejs.org/): + +```js +const cssesc = require('cssesc'); +``` + +In Ruby using [the `ruby-cssesc` wrapper gem](https://github.com/borodean/ruby-cssesc): + +```bash +gem install ruby-cssesc +``` + +```ruby +require 'ruby-cssesc' +CSSEsc.escape('I ♥ Ruby', is_identifier: true) +``` + +In Sass using [`sassy-escape`](https://github.com/borodean/sassy-escape): + +```bash +gem install sassy-escape +``` + +```scss +body { + content: escape('I ♥ Sass', $is-identifier: true); +} +``` + +## API + +### `cssesc(value, options)` + +This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) [escape sequences for use in CSS strings or identifiers](https://mathiasbynens.be/notes/css-escapes). + +```js +cssesc('Ich ♥ Bücher'); +// → 'Ich \\2665 B\\FC cher' + +cssesc('foo 𝌆 bar'); +// → 'foo \\1D306 bar' +``` + +By default, `cssesc` returns a string that can be used as part of a CSS string. If the target is a CSS identifier rather than a CSS string, use the `isIdentifier: true` setting (see below). + +The optional `options` argument accepts an object with the following options: + +#### `isIdentifier` + +The default value for the `isIdentifier` option is `false`. This means that the input text will be escaped for use in a CSS string literal. If you want to use the result as a CSS identifier instead (in a selector, for example), set this option to `true`. + +```js +cssesc('123a2b'); +// → '123a2b' + +cssesc('123a2b', { + 'isIdentifier': true +}); +// → '\\31 23a2b' +``` + +#### `quotes` + +The default value for the `quotes` option is `'single'`. This means that any occurences of `'` in the input text will be escaped as `\'`, so that the output can be used in a CSS string literal wrapped in single quotes. + +```js +cssesc('Lorem ipsum "dolor" sit \'amet\' etc.'); +// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.' +// → "Lorem ipsum \"dolor\" sit \\'amet\\' etc." + +cssesc('Lorem ipsum "dolor" sit \'amet\' etc.', { + 'quotes': 'single' +}); +// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.' +// → "Lorem ipsum \"dolor\" sit \\'amet\\' etc." +``` + +If you want to use the output as part of a CSS string literal wrapped in double quotes, set the `quotes` option to `'double'`. + +```js +cssesc('Lorem ipsum "dolor" sit \'amet\' etc.', { + 'quotes': 'double' +}); +// → 'Lorem ipsum \\"dolor\\" sit \'amet\' etc.' +// → "Lorem ipsum \\\"dolor\\\" sit 'amet' etc." +``` + +#### `wrap` + +The `wrap` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, the output will be a valid CSS string literal wrapped in quotes. The type of quotes can be specified through the `quotes` setting. + +```js +cssesc('Lorem ipsum "dolor" sit \'amet\' etc.', { + 'quotes': 'single', + 'wrap': true +}); +// → '\'Lorem ipsum "dolor" sit \\\'amet\\\' etc.\'' +// → "\'Lorem ipsum \"dolor\" sit \\\'amet\\\' etc.\'" + +cssesc('Lorem ipsum "dolor" sit \'amet\' etc.', { + 'quotes': 'double', + 'wrap': true +}); +// → '"Lorem ipsum \\"dolor\\" sit \'amet\' etc."' +// → "\"Lorem ipsum \\\"dolor\\\" sit \'amet\' etc.\"" +``` + +#### `escapeEverything` + +The `escapeEverything` option takes a boolean value (`true` or `false`), and defaults to `false` (disabled). When enabled, all the symbols in the output will be escaped, even printable ASCII symbols. + +```js +cssesc('lolwat"foo\'bar', { + 'escapeEverything': true +}); +// → '\\6C\\6F\\6C\\77\\61\\74\\"\\66\\6F\\6F\\\'\\62\\61\\72' +// → "\\6C\\6F\\6C\\77\\61\\74\\\"\\66\\6F\\6F\\'\\62\\61\\72" +``` + +#### Overriding the default options globally + +The global default settings can be overridden by modifying the `css.options` object. This saves you from passing in an `options` object for every call to `encode` if you want to use the non-default setting. + +```js +// Read the global default setting for `escapeEverything`: +cssesc.options.escapeEverything; +// → `false` by default + +// Override the global default setting for `escapeEverything`: +cssesc.options.escapeEverything = true; + +// Using the global default setting for `escapeEverything`, which is now `true`: +cssesc('foo © bar ≠ baz 𝌆 qux'); +// → '\\66\\6F\\6F\\ \\A9\\ \\62\\61\\72\\ \\2260\\ \\62\\61\\7A\\ \\1D306\\ \\71\\75\\78' +``` + +### `cssesc.version` + +A string representing the semantic version number. + +### Using the `cssesc` binary + +To use the `cssesc` binary in your shell, simply install cssesc globally using npm: + +```bash +npm install -g cssesc +``` + +After that you will be able to escape text for use in CSS strings or identifiers from the command line: + +```bash +$ cssesc 'föo ♥ bår 𝌆 baz' +f\F6o \2665 b\E5r \1D306 baz +``` + +If the output needs to be a CSS identifier rather than part of a string literal, use the `-i`/`--identifier` option: + +```bash +$ cssesc --identifier 'föo ♥ bår 𝌆 baz' +f\F6o\ \2665\ b\E5r\ \1D306\ baz +``` + +See `cssesc --help` for the full list of options. + +## Support + +This library supports the Node.js and browser versions mentioned in [`.babelrc`](https://github.com/mathiasbynens/cssesc/blob/master/.babelrc). For a version that supports a wider variety of legacy browsers and environments out-of-the-box, [see v0.1.0](https://github.com/mathiasbynens/cssesc/releases/tag/v0.1.0). + +## Author + +| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | +|---| +| [Mathias Bynens](https://mathiasbynens.be/) | + +## License + +This library is available under the [MIT](https://mths.be/mit) license. diff --git a/deps/npm/node_modules/cssesc/bin/cssesc b/deps/npm/node_modules/cssesc/bin/cssesc new file mode 100755 index 00000000000000..188c034ffe9483 --- /dev/null +++ b/deps/npm/node_modules/cssesc/bin/cssesc @@ -0,0 +1,116 @@ +#!/usr/bin/env node +const fs = require('fs'); +const cssesc = require('../cssesc.js'); +const strings = process.argv.splice(2); +const stdin = process.stdin; +const options = {}; +const log = console.log; + +const main = function() { + const option = strings[0]; + + if (/^(?:-h|--help|undefined)$/.test(option)) { + log( + 'cssesc v%s - https://mths.be/cssesc', + cssesc.version + ); + log([ + '\nUsage:\n', + '\tcssesc [string]', + '\tcssesc [-i | --identifier] [string]', + '\tcssesc [-s | --single-quotes] [string]', + '\tcssesc [-d | --double-quotes] [string]', + '\tcssesc [-w | --wrap] [string]', + '\tcssesc [-e | --escape-everything] [string]', + '\tcssesc [-v | --version]', + '\tcssesc [-h | --help]', + '\nExamples:\n', + '\tcssesc \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'', + '\tcssesc --identifier \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'', + '\tcssesc --escape-everything \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'', + '\tcssesc --double-quotes --wrap \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\'', + '\techo \'f\xF6o \u2665 b\xE5r \uD834\uDF06 baz\' | cssesc' + ].join('\n')); + return process.exit(1); + } + + if (/^(?:-v|--version)$/.test(option)) { + log('v%s', cssesc.version); + return process.exit(1); + } + + strings.forEach(function(string) { + // Process options + if (/^(?:-i|--identifier)$/.test(string)) { + options.isIdentifier = true; + return; + } + if (/^(?:-s|--single-quotes)$/.test(string)) { + options.quotes = 'single'; + return; + } + if (/^(?:-d|--double-quotes)$/.test(string)) { + options.quotes = 'double'; + return; + } + if (/^(?:-w|--wrap)$/.test(string)) { + options.wrap = true; + return; + } + if (/^(?:-e|--escape-everything)$/.test(string)) { + options.escapeEverything = true; + return; + } + + // Process string(s) + let result; + try { + result = cssesc(string, options); + log(result); + } catch (exception) { + log(exception.message + '\n'); + log('Error: failed to escape.'); + log('If you think this is a bug in cssesc, please report it:'); + log('https://github.com/mathiasbynens/cssesc/issues/new'); + log( + '\nStack trace using cssesc@%s:\n', + cssesc.version + ); + log(exception.stack); + return process.exit(1); + } + }); + // Return with exit status 0 outside of the `forEach` loop, in case + // multiple strings were passed in. + return process.exit(0); + +}; + +if (stdin.isTTY) { + // handle shell arguments + main(); +} else { + let timeout; + // Either the script is called from within a non-TTY context, or `stdin` + // content is being piped in. + if (!process.stdout.isTTY) { + // The script was called from a non-TTY context. This is a rather uncommon + // use case we don’t actively support. However, we don’t want the script + // to wait forever in such cases, so… + timeout = setTimeout(function() { + // …if no piped data arrived after a whole minute, handle shell + // arguments instead. + main(); + }, 60000); + } + let data = ''; + stdin.on('data', function(chunk) { + clearTimeout(timeout); + data += chunk; + }); + stdin.on('end', function() { + strings.push(data.trim()); + main(); + }); + stdin.resume(); +} diff --git a/deps/npm/node_modules/cssesc/cssesc.js b/deps/npm/node_modules/cssesc/cssesc.js new file mode 100644 index 00000000000000..1c0928e45667c8 --- /dev/null +++ b/deps/npm/node_modules/cssesc/cssesc.js @@ -0,0 +1,110 @@ +/*! https://mths.be/cssesc v3.0.0 by @mathias */ +'use strict'; + +var object = {}; +var hasOwnProperty = object.hasOwnProperty; +var merge = function merge(options, defaults) { + if (!options) { + return defaults; + } + var result = {}; + for (var key in defaults) { + // `if (defaults.hasOwnProperty(key) { … }` is not needed here, since + // only recognized option names are used. + result[key] = hasOwnProperty.call(options, key) ? options[key] : defaults[key]; + } + return result; +}; + +var regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/; +var regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/; +var regexAlwaysEscape = /['"\\]/; +var regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g; + +// https://mathiasbynens.be/notes/css-escapes#css +var cssesc = function cssesc(string, options) { + options = merge(options, cssesc.options); + if (options.quotes != 'single' && options.quotes != 'double') { + options.quotes = 'single'; + } + var quote = options.quotes == 'double' ? '"' : '\''; + var isIdentifier = options.isIdentifier; + + var firstChar = string.charAt(0); + var output = ''; + var counter = 0; + var length = string.length; + while (counter < length) { + var character = string.charAt(counter++); + var codePoint = character.charCodeAt(); + var value = void 0; + // If it’s not a printable ASCII character… + if (codePoint < 0x20 || codePoint > 0x7E) { + if (codePoint >= 0xD800 && codePoint <= 0xDBFF && counter < length) { + // It’s a high surrogate, and there is a next character. + var extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { + // next character is low surrogate + codePoint = ((codePoint & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; + } else { + // It’s an unmatched surrogate; only append this code unit, in case + // the next code unit is the high surrogate of a surrogate pair. + counter--; + } + } + value = '\\' + codePoint.toString(16).toUpperCase() + ' '; + } else { + if (options.escapeEverything) { + if (regexAnySingleEscape.test(character)) { + value = '\\' + character; + } else { + value = '\\' + codePoint.toString(16).toUpperCase() + ' '; + } + } else if (/[\t\n\f\r\x0B]/.test(character)) { + value = '\\' + codePoint.toString(16).toUpperCase() + ' '; + } else if (character == '\\' || !isIdentifier && (character == '"' && quote == character || character == '\'' && quote == character) || isIdentifier && regexSingleEscape.test(character)) { + value = '\\' + character; + } else { + value = character; + } + } + output += value; + } + + if (isIdentifier) { + if (/^-[-\d]/.test(output)) { + output = '\\-' + output.slice(1); + } else if (/\d/.test(firstChar)) { + output = '\\3' + firstChar + ' ' + output.slice(1); + } + } + + // Remove spaces after `\HEX` escapes that are not followed by a hex digit, + // since they’re redundant. Note that this is only possible if the escape + // sequence isn’t preceded by an odd number of backslashes. + output = output.replace(regexExcessiveSpaces, function ($0, $1, $2) { + if ($1 && $1.length % 2) { + // It’s not safe to remove the space, so don’t. + return $0; + } + // Strip the space. + return ($1 || '') + $2; + }); + + if (!isIdentifier && options.wrap) { + return quote + output + quote; + } + return output; +}; + +// Expose default options (so they can be overridden globally). +cssesc.options = { + 'escapeEverything': false, + 'isIdentifier': false, + 'quotes': 'single', + 'wrap': false +}; + +cssesc.version = '3.0.0'; + +module.exports = cssesc; diff --git a/deps/npm/node_modules/cssesc/man/cssesc.1 b/deps/npm/node_modules/cssesc/man/cssesc.1 new file mode 100644 index 00000000000000..eee4996daf5436 --- /dev/null +++ b/deps/npm/node_modules/cssesc/man/cssesc.1 @@ -0,0 +1,70 @@ +.Dd August 9, 2013 +.Dt cssesc 1 +.Sh NAME +.Nm cssesc +.Nd escape text for use in CSS string literals or identifiers +.Sh SYNOPSIS +.Nm +.Op Fl i | -identifier Ar string +.br +.Op Fl s | -single-quotes Ar string +.br +.Op Fl d | -double-quotes Ar string +.br +.Op Fl w | -wrap Ar string +.br +.Op Fl e | -escape-everything Ar string +.br +.Op Fl v | -version +.br +.Op Fl h | -help +.Sh DESCRIPTION +.Nm +escapes strings for use in CSS string literals or identifiers while generating the shortest possible valid ASCII-only output. +.Sh OPTIONS +.Bl -ohang -offset +.It Sy "-s, --single-quotes" +Escape any occurences of ' in the input string as \\', so that the output can be used in a CSS string literal wrapped in single quotes. +.It Sy "-d, --double-quotes" +Escape any occurences of " in the input string as \\", so that the output can be used in a CSS string literal wrapped in double quotes. +.It Sy "-w, --wrap" +Make sure the output is a valid CSS string literal wrapped in quotes. The type of quotes can be specified using the +.Ar -s | --single-quotes +or +.Ar -d | --double-quotes +settings. +.It Sy "-e, --escape-everything" +Escape all the symbols in the output, even printable ASCII symbols. +.It Sy "-v, --version" +Print cssesc's version. +.It Sy "-h, --help" +Show the help screen. +.El +.Sh EXIT STATUS +The +.Nm cssesc +utility exits with one of the following values: +.Pp +.Bl -tag -width flag -compact +.It Li 0 +.Nm +successfully escaped the given text and printed the result. +.It Li 1 +.Nm +wasn't instructed to escape anything (for example, the +.Ar --help +flag was set); or, an error occurred. +.El +.Sh EXAMPLES +.Bl -ohang -offset +.It Sy "cssesc 'foo bar baz'" +Print an escaped version of the given text. +.It Sy echo\ 'foo bar baz'\ |\ cssesc +Print an escaped version of the text that gets piped in. +.El +.Sh BUGS +cssesc's bug tracker is located at . +.Sh AUTHOR +Mathias Bynens +.Sh WWW + diff --git a/deps/npm/node_modules/cssesc/package.json b/deps/npm/node_modules/cssesc/package.json new file mode 100644 index 00000000000000..076c84dc83018b --- /dev/null +++ b/deps/npm/node_modules/cssesc/package.json @@ -0,0 +1,51 @@ +{ + "name": "cssesc", + "version": "3.0.0", + "description": "A JavaScript library for escaping CSS strings and identifiers while generating the shortest possible ASCII-only output.", + "homepage": "https://mths.be/cssesc", + "engines": { + "node": ">=4" + }, + "main": "cssesc.js", + "bin": "bin/cssesc", + "man": "man/cssesc.1", + "keywords": [ + "css", + "escape", + "identifier", + "string", + "tool" + ], + "license": "MIT", + "author": { + "name": "Mathias Bynens", + "url": "https://mathiasbynens.be/" + }, + "repository": { + "type": "git", + "url": "https://github.com/mathiasbynens/cssesc.git" + }, + "bugs": "https://github.com/mathiasbynens/cssesc/issues", + "files": [ + "LICENSE-MIT.txt", + "cssesc.js", + "bin/", + "man/" + ], + "scripts": { + "build": "grunt template && babel cssesc.js -o cssesc.js", + "test": "mocha tests", + "cover": "istanbul cover --report html node_modules/.bin/_mocha tests -- -u exports -R spec" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-preset-env": "^1.6.1", + "codecov": "^1.0.1", + "grunt": "^1.0.1", + "grunt-template": "^1.0.0", + "istanbul": "^0.4.4", + "mocha": "^2.5.3", + "regenerate": "^1.2.1", + "requirejs": "^2.1.16" + } +} diff --git a/deps/npm/node_modules/libnpmexec/lib/cache-install-dir.js b/deps/npm/node_modules/libnpmexec/lib/cache-install-dir.js deleted file mode 100644 index 77466938762d08..00000000000000 --- a/deps/npm/node_modules/libnpmexec/lib/cache-install-dir.js +++ /dev/null @@ -1,20 +0,0 @@ -const crypto = require('crypto') - -const { resolve } = require('path') - -const cacheInstallDir = ({ npxCache, packages }) => { - if (!npxCache) { - throw new Error('Must provide a valid npxCache path') - } - - // only packages not found in ${prefix}/node_modules - return resolve(npxCache, getHash(packages)) -} - -const getHash = (packages) => - crypto.createHash('sha512') - .update(packages.sort((a, b) => a.localeCompare(b, 'en')).join('\n')) - .digest('hex') - .slice(0, 16) - -module.exports = cacheInstallDir diff --git a/deps/npm/node_modules/libnpmexec/lib/file-exists.js b/deps/npm/node_modules/libnpmexec/lib/file-exists.js index f89cfc217d61d7..e5cd474dac388f 100644 --- a/deps/npm/node_modules/libnpmexec/lib/file-exists.js +++ b/deps/npm/node_modules/libnpmexec/lib/file-exists.js @@ -1,23 +1,25 @@ const { resolve } = require('path') -const { promisify } = require('util') -const stat = promisify(require('fs').stat) +const fs = require('@npmcli/fs') const walkUp = require('walk-up-path') -const fileExists = (file) => stat(file) - .then((res) => res.isFile()) - .catch(() => false) - -const localFileExists = async (dir, binName, root = '/') => { - root = resolve(root).toLowerCase() +const fileExists = async (file) => { + try { + const res = await fs.stat(file) + return res.isFile() + } catch { + return false + } +} - for (const path of walkUp(resolve(dir))) { +const localFileExists = async (dir, binName, root) => { + for (const path of walkUp(dir)) { const binDir = resolve(path, 'node_modules', '.bin') if (await fileExists(resolve(binDir, binName))) { return binDir } - if (path.toLowerCase() === root) { + if (path.toLowerCase() === resolve(root).toLowerCase()) { return false } } diff --git a/deps/npm/node_modules/libnpmexec/lib/index.js b/deps/npm/node_modules/libnpmexec/lib/index.js index dfe7560120702d..fcc596d3137784 100644 --- a/deps/npm/node_modules/libnpmexec/lib/index.js +++ b/deps/npm/node_modules/libnpmexec/lib/index.js @@ -1,27 +1,76 @@ -const { delimiter, dirname, resolve } = require('path') +'use strict' + const { promisify } = require('util') -const read = promisify(require('read')) const Arborist = require('@npmcli/arborist') const ciDetect = require('@npmcli/ci-detect') +const crypto = require('crypto') const log = require('proc-log') -const npmlog = require('npmlog') const mkdirp = require('mkdirp-infer-owner') const npa = require('npm-package-arg') +const npmlog = require('npmlog') const pacote = require('pacote') +const read = promisify(require('read')) +const semver = require('semver') -const cacheInstallDir = require('./cache-install-dir.js') const { fileExists, localFileExists } = require('./file-exists.js') const getBinFromManifest = require('./get-bin-from-manifest.js') const noTTY = require('./no-tty.js') const runScript = require('./run-script.js') const isWindows = require('./is-windows.js') -const _localManifest = Symbol('localManifest') -/* istanbul ignore next */ -const PATH = ( - process.env.PATH || process.env.Path || process.env.path -).split(delimiter) +const { dirname, resolve } = require('path') + +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() + +const getManifest = async (spec, flatOptions) => { + if (!manifests.get(spec.raw)) { + const manifest = await pacote.manifest(spec, { ...flatOptions, preferOnline: true }) + manifests.set(spec.raw, manifest) + } + return manifests.get(spec.raw) +} + +// Returns the required manifest if the spec is missing from the tree +const missingFromTree = async ({ spec, tree, flatOptions }) => { + if (spec.registry && (spec.rawSpec === '' || spec.type !== 'tag')) { + // registry spec that is not a specific tag. + const nodesBySpec = tree.inventory.query('packageName', spec.name) + for (const node of nodesBySpec) { + if (spec.type === 'tag') { + // package requested by name only + return + } else if (spec.type === 'version') { + // package requested by specific version + if (node.pkgid === spec.raw) { + return + } + } else { + // package requested by version range, only remaining registry type + if (semver.satisfies(node.package.version, spec.rawSpec)) { + return + } + } + } + return await getManifest(spec, flatOptions) + } else { + // non-registry spec, or a specific tag. Look up manifest and check + // resolved to see if it's in the tree. + const manifest = await getManifest(spec, flatOptions) + const nodesByManifest = tree.inventory.query('packageName', manifest.name) + for (const node of nodesByManifest) { + if (node.package.resolved === manifest._resolved) { + // we have a package by the same name and the same resolved destination, nothing to add. + return + } + } + return manifest + } +} const exec = async (opts) => { const { @@ -31,8 +80,10 @@ const exec = async (opts) => { localBin = resolve('./node_modules/.bin'), locationMsg = undefined, globalBin = '', + globalPath = '', output, - packages: _packages = [], + // dereference values because we manipulate it later + packages: [...packages] = [], path = '.', runPath = '.', scriptShell = isWindows ? process.env.ComSpec || 'cmd' : 'sh', @@ -40,10 +91,7 @@ const exec = async (opts) => { ...flatOptions } = opts - // dereferences values because we manipulate it later - const packages = [..._packages] - const pathArr = [...PATH] - const _run = () => runScript({ + const run = () => runScript({ args, call, color, @@ -51,125 +99,101 @@ const exec = async (opts) => { locationMsg, output, path, - pathArr, + binPaths, runPath, scriptShell, }) - // nothing to maybe install, skip the arborist dance + // interactive mode if (!call && !args.length && !packages.length) { - return await _run() + return run() } - const needPackageCommandSwap = args.length && !packages.length - // if there's an argument and no package has been explicitly asked for - // check the local and global bin paths for a binary named the same as - // the argument and run it if it exists, otherwise fall through to - // the behavior of treating the single argument as a package name + const needPackageCommandSwap = (args.length > 0) && (packages.length === 0) + // If they asked for a command w/o specifying a package, see if there is a + // bin that directly matches that name either globally or in the local tree. if (needPackageCommandSwap) { - let binExists = false const dir = dirname(dirname(localBin)) - const localBinPath = await localFileExists(dir, args[0]) + const localBinPath = await localFileExists(dir, args[0], '/') if (localBinPath) { - pathArr.unshift(localBinPath) - binExists = true + binPaths.push(localBinPath) + return await run() } else if (await fileExists(`${globalBin}/${args[0]}`)) { - pathArr.unshift(globalBin) - binExists = true - } - - if (binExists) { - return await _run() + binPaths.push(globalBin) + return await run() } + // We swap out args[0] with the bin from the manifest later packages.push(args[0]) } - // figure out whether we need to install stuff, or if local is fine - const localArb = new Arborist({ - ...flatOptions, - path, - }) + const localArb = new Arborist({ ...flatOptions, path }) const localTree = await localArb.loadActual() - const getLocalManifest = ({ tree, name }) => { - // look up the package name in the current tree inventory, - // if it's found then return that normalized pkg data - const [node] = tree.inventory.query('packageName', name) - - if (node) { - return { - _id: node.pkgid, - ...node.package, - [_localManifest]: true, - } + // Find anything that isn't installed locally + const needInstall = [] + await Promise.all(packages.map(async pkg => { + const spec = npa(pkg, path) + const manifest = await missingFromTree({ spec, tree: localTree, flatOptions }) + if (manifest) { + // Package does not exist in the local tree + needInstall.push({ spec, manifest }) } - } - - // If we do `npm exec foo`, and have a `foo` locally, then we'll - // always use that, so we don't really need to fetch the manifest. - // So: run npa on each packages entry, and if it is a name with a - // rawSpec==='', then try to find that node name in the tree inventory - // and only pacote fetch if that fails. - const manis = await Promise.all(packages.map(async p => { - const spec = npa(p, path) - if (spec.type === 'tag' && spec.rawSpec === '') { - const localManifest = getLocalManifest({ - tree: localTree, - name: spec.name, - }) - if (localManifest) { - return localManifest - } - } - // Force preferOnline to true so we are making sure to pull in the latest - // This is especially useful if the user didn't give us a version, and - // they expect to be running @latest - return await pacote.manifest(p, { - ...flatOptions, - preferOnline: true, - }) })) if (needPackageCommandSwap) { - args[0] = getBinFromManifest(manis[0]) - } + // Either we have a scoped package or the bin of our package we inferred + // from arg[0] might not be identical to the package name + const spec = npa(args[0]) + let commandManifest + if (needInstall.length === 0) { + commandManifest = await getManifest(spec, flatOptions) + } else { + commandManifest = needInstall[0].manifest + } + + args[0] = getBinFromManifest(commandManifest) - // are all packages from the manifest list installed? - const needInstall = - manis.some(manifest => !manifest[_localManifest]) + // See if the package is installed globally, and run the translated bin + const globalArb = new Arborist({ ...flatOptions, path: globalPath, global: true }) + const globalTree = await globalArb.loadActual() + const globalManifest = await missingFromTree({ spec, tree: globalTree, flatOptions }) + if (!globalManifest) { + binPaths.push(globalBin) + return await run() + } + } - if (needInstall) { + const add = [] + if (needInstall.length > 0) { + // Install things to the npx cache, if needed const { npxCache } = flatOptions - const installDir = cacheInstallDir({ npxCache, packages }) + if (!npxCache) { + throw new Error('Must provide a valid npxCache path') + } + const hash = crypto.createHash('sha512') + .update(packages.sort((a, b) => a.localeCompare(b, 'en')).join('\n')) + .digest('hex') + .slice(0, 16) + const installDir = resolve(npxCache, hash) await mkdirp(installDir) - const arb = new Arborist({ + const npxArb = new Arborist({ ...flatOptions, path: installDir, }) - const tree = await arb.loadActual() - - // inspect the npx-space installed tree to check if the package is already - // there, if that's the case also check that it's version matches the same - // version expected by the user requested pkg returned by pacote.manifest - const filterMissingPackagesFromInstallDir = (mani) => { - const localManifest = getLocalManifest({ tree, name: mani.name }) - if (localManifest) { - return localManifest.version !== mani.version + const npxTree = await npxArb.loadActual() + await Promise.all(needInstall.map(async ({ spec }) => { + const manifest = await missingFromTree({ spec, tree: npxTree, flatOptions }) + if (manifest) { + // Manifest is not in npxCache, we need to install it there + if (!spec.registry) { + add.push(manifest._from) + } else { + add.push(manifest._id) + } } - return true - } - - // at this point, we have to ensure that we get the exact same - // version, because it's something that has only ever been installed - // by npm exec in the cache install directory - const add = manis - .filter(mani => !mani[_localManifest]) - .filter(filterMissingPackagesFromInstallDir) - .map(mani => mani._id || mani._from) - .sort((a, b) => a.localeCompare(b, 'en')) + })) - // no need to install if already present if (add.length) { if (!yes) { // set -n to always say no @@ -196,15 +220,15 @@ const exec = async (opts) => { } } } - await arb.reify({ + await npxArb.reify({ ...flatOptions, add, }) } - pathArr.unshift(resolve(installDir, 'node_modules/.bin')) + binPaths.push(resolve(installDir, 'node_modules/.bin')) } - return await _run() + return await run() } module.exports = exec diff --git a/deps/npm/node_modules/libnpmexec/lib/run-script.js b/deps/npm/node_modules/libnpmexec/lib/run-script.js index 97543e6ff0d08f..18dcf7d8356c59 100644 --- a/deps/npm/node_modules/libnpmexec/lib/run-script.js +++ b/deps/npm/node_modules/libnpmexec/lib/run-script.js @@ -1,5 +1,3 @@ -const { delimiter } = require('path') - const chalk = require('chalk') const ciDetect = require('@npmcli/ci-detect') const runScript = require('@npmcli/run-script') @@ -22,7 +20,7 @@ const run = async ({ locationMsg, output = () => {}, path, - pathArr, + binPaths, runPath, scriptShell, }) => { @@ -71,11 +69,9 @@ const run = async ({ // we always run in cwd, not --prefix path: runPath, stdioString: true, + binPaths, event: 'npx', args, - env: { - PATH: pathArr.join(delimiter), - }, stdio: 'inherit', }) } finally { diff --git a/deps/npm/node_modules/libnpmexec/package.json b/deps/npm/node_modules/libnpmexec/package.json index d163103ea2b0bf..9fcb0b20167847 100644 --- a/deps/npm/node_modules/libnpmexec/package.json +++ b/deps/npm/node_modules/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "4.0.8", + "version": "4.0.9", "files": [ "bin/", "lib/" @@ -57,7 +57,8 @@ "dependencies": { "@npmcli/arborist": "^5.0.0", "@npmcli/ci-detect": "^2.0.0", - "@npmcli/run-script": "^4.1.3", + "@npmcli/fs": "^2.1.1", + "@npmcli/run-script": "^4.2.0", "chalk": "^4.1.0", "mkdirp-infer-owner": "^2.0.0", "npm-package-arg": "^9.0.1", @@ -66,6 +67,7 @@ "proc-log": "^2.0.0", "read": "^1.0.7", "read-package-json-fast": "^2.0.2", + "semver": "^7.3.7", "walk-up-path": "^1.0.0" }, "templateOSS": { diff --git a/deps/npm/node_modules/npm-profile/lib/index.js b/deps/npm/node_modules/npm-profile/lib/index.js index e4ac5622e0d5c6..ce78882a55438d 100644 --- a/deps/npm/node_modules/npm-profile/lib/index.js +++ b/deps/npm/node_modules/npm-profile/lib/index.js @@ -56,13 +56,11 @@ const webAuth = (opener, opts, body) => { const { hostname } = opts body.hostname = hostname || os.hostname() const target = '/-/v1/login' + const doneEmitter = new EventEmitter() return fetch(target, { ...opts, method: 'POST', body, - headers: { - 'npm-use-webauthn': opts.authType === 'webauthn', - }, }).then(res => { return Promise.all([res, res.json()]) }).then(([res, content]) => { @@ -75,8 +73,6 @@ const webAuth = (opener, opts, body) => { }).then(({ doneUrl, loginUrl }) => { log.verbose('web auth', 'opening url pair') - const doneEmitter = new EventEmitter() - const openPromise = opener(loginUrl, doneEmitter) const webAuthCheckPromise = webAuthCheckLogin(doneUrl, { ...opts, cache: false }) .then(authResult => { @@ -93,6 +89,9 @@ const webAuth = (opener, opts, body) => { ([, authResult]) => authResult ) }).catch(er => { + // cancel open prompt if it's present + doneEmitter.emit('abort') + if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) { throw new WebLoginNotSupported('POST', { status: er.statusCode, diff --git a/deps/npm/node_modules/npm-profile/package.json b/deps/npm/node_modules/npm-profile/package.json index bd4ebd31761159..457a1fb0988fba 100644 --- a/deps/npm/node_modules/npm-profile/package.json +++ b/deps/npm/node_modules/npm-profile/package.json @@ -1,6 +1,6 @@ { "name": "npm-profile", - "version": "6.2.0", + "version": "6.2.1", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", diff --git a/deps/npm/node_modules/postcss-selector-parser/API.md b/deps/npm/node_modules/postcss-selector-parser/API.md new file mode 100644 index 00000000000000..6aa1f1438f1be4 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/API.md @@ -0,0 +1,873 @@ +# API Documentation + +*Please use only this documented API when working with the parser. Methods +not documented here are subject to change at any point.* + +## `parser` function + +This is the module's main entry point. + +```js +const parser = require('postcss-selector-parser'); +``` + +### `parser([transform], [options])` + +Creates a new `processor` instance + +```js +const processor = parser(); +``` + +Or, with optional transform function + +```js +const transform = selectors => { + selectors.walkUniversals(selector => { + selector.remove(); + }); +}; + +const processor = parser(transform) + +// Example +const result = processor.processSync('*.class'); +// => .class +``` + +[See processor documentation](#processor) + +Arguments: + +* `transform (function)`: Provide a function to work with the parsed AST. +* `options (object)`: Provide default options for all calls on the returned `Processor`. + +### `parser.attribute([props])` + +Creates a new attribute selector. + +```js +parser.attribute({attribute: 'href'}); +// => [href] +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.className([props])` + +Creates a new class selector. + +```js +parser.className({value: 'button'}); +// => .button +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.combinator([props])` + +Creates a new selector combinator. + +```js +parser.combinator({value: '+'}); +// => + +``` + +Arguments: + +* `props (object)`: The new node's properties. + +Notes: +* **Descendant Combinators** The value of descendant combinators created by the + parser always just a single space (`" "`). For descendant selectors with no + comments, additional space is now stored in `node.spaces.before`. Depending + on the location of comments, additional spaces may be stored in + `node.raws.spaces.before`, `node.raws.spaces.after`, or `node.raws.value`. +* **Named Combinators** Although, nonstandard and unlikely to ever become a standard, + named combinators like `/deep/` and `/for/` are parsed as combinators. The + `node.value` is name after being unescaped and normalized as lowercase. The + original value for the combinator name is stored in `node.raws.value`. + + +### `parser.comment([props])` + +Creates a new comment. + +```js +parser.comment({value: '/* Affirmative, Dave. I read you. */'}); +// => /* Affirmative, Dave. I read you. */ +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.id([props])` + +Creates a new id selector. + +```js +parser.id({value: 'search'}); +// => #search +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.nesting([props])` + +Creates a new nesting selector. + +```js +parser.nesting(); +// => & +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.pseudo([props])` + +Creates a new pseudo selector. + +```js +parser.pseudo({value: '::before'}); +// => ::before +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.root([props])` + +Creates a new root node. + +```js +parser.root(); +// => (empty) +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.selector([props])` + +Creates a new selector node. + +```js +parser.selector(); +// => (empty) +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.string([props])` + +Creates a new string node. + +```js +parser.string(); +// => (empty) +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.tag([props])` + +Creates a new tag selector. + +```js +parser.tag({value: 'button'}); +// => button +``` + +Arguments: + +* `props (object)`: The new node's properties. + +### `parser.universal([props])` + +Creates a new universal selector. + +```js +parser.universal(); +// => * +``` + +Arguments: + +* `props (object)`: The new node's properties. + +## Node types + +### `node.type` + +A string representation of the selector type. It can be one of the following; +`attribute`, `class`, `combinator`, `comment`, `id`, `nesting`, `pseudo`, +`root`, `selector`, `string`, `tag`, or `universal`. Note that for convenience, +these constants are exposed on the main `parser` as uppercased keys. So for +example you can get `id` by querying `parser.ID`. + +```js +parser.attribute({attribute: 'href'}).type; +// => 'attribute' +``` + +### `node.parent` + +Returns the parent node. + +```js +root.nodes[0].parent === root; +``` + +### `node.toString()`, `String(node)`, or `'' + node` + +Returns a string representation of the node. + +```js +const id = parser.id({value: 'search'}); +console.log(String(id)); +// => #search +``` + +### `node.next()` & `node.prev()` + +Returns the next/previous child of the parent node. + +```js +const next = id.next(); +if (next && next.type !== 'combinator') { + throw new Error('Qualified IDs are not allowed!'); +} +``` + +### `node.replaceWith(node)` + +Replace a node with another. + +```js +const attr = selectors.first.first; +const className = parser.className({value: 'test'}); +attr.replaceWith(className); +``` + +Arguments: + +* `node`: The node to substitute the original with. + +### `node.remove()` + +Removes the node from its parent node. + +```js +if (node.type === 'id') { + node.remove(); +} +``` + +### `node.clone()` + +Returns a copy of a node, detached from any parent containers that the +original might have had. + +```js +const cloned = parser.id({value: 'search'}); +String(cloned); + +// => #search +``` + +### `node.isAtPosition(line, column)` + +Return a `boolean` indicating whether this node includes the character at the +position of the given line and column. Returns `undefined` if the nodes lack +sufficient source metadata to determine the position. + +Arguments: + +* `line`: 1-index based line number relative to the start of the selector. +* `column`: 1-index based column number relative to the start of the selector. + +### `node.spaces` + +Extra whitespaces around the node will be moved into `node.spaces.before` and +`node.spaces.after`. So for example, these spaces will be moved as they have +no semantic meaning: + +```css + h1 , h2 {} +``` + +For descendent selectors, the value is always a single space. + +```css +h1 h2 {} +``` + +Additional whitespace is found in either the `node.spaces.before` and `node.spaces.after` depending on the presence of comments or other whitespace characters. If the actual whitespace does not start or end with a single space, the node's raw value is set to the actual space(s) found in the source. + +### `node.source` + +An object describing the node's start/end, line/column source position. + +Within the following CSS, the `.bar` class node ... + +```css +.foo, + .bar {} +``` + +... will contain the following `source` object. + +```js +source: { + start: { + line: 2, + column: 3 + }, + end: { + line: 2, + column: 6 + } +} +``` + +### `node.sourceIndex` + +The zero-based index of the node within the original source string. + +Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`. + +```css +.foo, .bar, .baz {} +``` + +## Container types + +The `root`, `selector`, and `pseudo` nodes have some helper methods for working +with their children. + +### `container.nodes` + +An array of the container's children. + +```js +// Input: h1 h2 +selectors.at(0).nodes.length // => 3 +selectors.at(0).nodes[0].value // => 'h1' +selectors.at(0).nodes[1].value // => ' ' +``` + +### `container.first` & `container.last` + +The first/last child of the container. + +```js +selector.first === selector.nodes[0]; +selector.last === selector.nodes[selector.nodes.length - 1]; +``` + +### `container.at(index)` + +Returns the node at position `index`. + +```js +selector.at(0) === selector.first; +selector.at(0) === selector.nodes[0]; +``` + +Arguments: + +* `index`: The index of the node to return. + +### `container.atPosition(line, column)` + +Returns the node at the source position `index`. + +```js +selector.at(0) === selector.first; +selector.at(0) === selector.nodes[0]; +``` + +Arguments: + +* `index`: The index of the node to return. + +### `container.index(node)` + +Return the index of the node within its container. + +```js +selector.index(selector.nodes[2]) // => 2 +``` + +Arguments: + +* `node`: A node within the current container. + +### `container.length` + +Proxy to the length of the container's nodes. + +```js +container.length === container.nodes.length +``` + +### `container` Array iterators + +The container class provides proxies to certain Array methods; these are: + +* `container.map === container.nodes.map` +* `container.reduce === container.nodes.reduce` +* `container.every === container.nodes.every` +* `container.some === container.nodes.some` +* `container.filter === container.nodes.filter` +* `container.sort === container.nodes.sort` + +Note that these methods only work on a container's immediate children; recursive +iteration is provided by `container.walk`. + +### `container.each(callback)` + +Iterate the container's immediate children, calling `callback` for each child. +You may return `false` within the callback to break the iteration. + +```js +let className; +selectors.each((selector, index) => { + if (selector.type === 'class') { + className = selector.value; + return false; + } +}); +``` + +Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding +or removing nodes from the container. + +Arguments: + +* `callback (function)`: A function to call for each node, which receives `node` + and `index` arguments. + +### `container.walk(callback)` + +Like `container#each`, but will also iterate child nodes as long as they are +`container` types. + +```js +selectors.walk((selector, index) => { + // all nodes +}); +``` + +Arguments: + +* `callback (function)`: A function to call for each node, which receives `node` + and `index` arguments. + +This iterator is safe to use whilst mutating `container.nodes`, +like `container#each`. + +### `container.walk` proxies + +The container class provides proxy methods for iterating over types of nodes, +so that it is easier to write modules that target specific selectors. Those +methods are: + +* `container.walkAttributes` +* `container.walkClasses` +* `container.walkCombinators` +* `container.walkComments` +* `container.walkIds` +* `container.walkNesting` +* `container.walkPseudos` +* `container.walkTags` +* `container.walkUniversals` + +### `container.split(callback)` + +This method allows you to split a group of nodes by returning `true` from +a callback. It returns an array of arrays, where each inner array corresponds +to the groups that you created via the callback. + +```js +// (input) => h1 h2>>h3 +const list = selectors.first.split(selector => { + return selector.type === 'combinator'; +}); + +// (node values) => [['h1', ' '], ['h2', '>>'], ['h3']] +``` + +Arguments: + +* `callback (function)`: A function to call for each node, which receives `node` + as an argument. + +### `container.prepend(node)` & `container.append(node)` + +Add a node to the start/end of the container. Note that doing so will set +the parent property of the node to this container. + +```js +const id = parser.id({value: 'search'}); +selector.append(id); +``` + +Arguments: + +* `node`: The node to add. + +### `container.insertBefore(old, new)` & `container.insertAfter(old, new)` + +Add a node before or after an existing node in a container: + +```js +selectors.walk(selector => { + if (selector.type !== 'class') { + const className = parser.className({value: 'theme-name'}); + selector.parent.insertAfter(selector, className); + } +}); +``` + +Arguments: + +* `old`: The existing node in the container. +* `new`: The new node to add before/after the existing node. + +### `container.removeChild(node)` + +Remove the node from the container. Note that you can also use +`node.remove()` if you would like to remove just a single node. + +```js +selector.length // => 2 +selector.remove(id) +selector.length // => 1; +id.parent // undefined +``` + +Arguments: + +* `node`: The node to remove. + +### `container.removeAll()` or `container.empty()` + +Remove all children from the container. + +```js +selector.removeAll(); +selector.length // => 0 +``` + +## Root nodes + +A root node represents a comma separated list of selectors. Indeed, all +a root's `toString()` method does is join its selector children with a ','. +Other than this, it has no special functionality and acts like a container. + +### `root.trailingComma` + +This will be set to `true` if the input has a trailing comma, in order to +support parsing of legacy CSS hacks. + +## Selector nodes + +A selector node represents a single complex selector. For example, this +selector string `h1 h2 h3, [href] > p`, is represented as two selector nodes. +It has no special functionality of its own. + +## Pseudo nodes + +A pseudo selector extends a container node; if it has any parameters of its +own (such as `h1:not(h2, h3)`), they will be its children. Note that the pseudo +`value` will always contain the colons preceding the pseudo identifier. This +is so that both `:before` and `::before` are properly represented in the AST. + +## Attribute nodes + +### `attribute.quoted` + +Returns `true` if the attribute's value is wrapped in quotation marks, false if it is not. +Remains `undefined` if there is no attribute value. + +```css +[href=foo] /* false */ +[href='foo'] /* true */ +[href="foo"] /* true */ +[href] /* undefined */ +``` + +### `attribute.qualifiedAttribute` + +Returns the attribute name qualified with the namespace if one is given. + +### `attribute.offsetOf(part)` + + Returns the offset of the attribute part specified relative to the + start of the node of the output string. This is useful in raising + error messages about a specific part of the attribute, especially + in combination with `attribute.sourceIndex`. + + Returns `-1` if the name is invalid or the value doesn't exist in this + attribute. + + The legal values for `part` are: + + * `"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 + +### `attribute.raws.unquoted` + +Returns the unquoted content of the attribute's value. +Remains `undefined` if there is no attribute value. + +```css +[href=foo] /* foo */ +[href='foo'] /* foo */ +[href="foo"] /* foo */ +[href] /* undefined */ +``` + +### `attribute.spaces` + +Like `node.spaces` with the `before` and `after` values containing the spaces +around the element, the parts of the attribute can also have spaces before +and after them. The for each of `attribute`, `operator`, `value` and +`insensitive` there is corresponding property of the same nam in +`node.spaces` that has an optional `before` or `after` string containing only +whitespace. + +Note that corresponding values in `attributes.raws.spaces` contain values +including any comments. If set, these values will override the +`attribute.spaces` value. Take care to remove them if changing +`attribute.spaces`. + +### `attribute.raws` + +The raws object stores comments and other information necessary to re-render +the node exactly as it was in the source. + +If a comment is embedded within the identifiers for the `namespace`, `attribute` +or `value` then a property is placed in the raws for that value containing the full source of the propery including comments. + +If a comment is embedded within the space between parts of the attribute +then the raw for that space is set accordingly. + +Setting an attribute's property `raws` value to be deleted. + +For now, changing the spaces required also updating or removing any of the +raws values that override them. + +Example: `[ /*before*/ href /* after-attr */ = /* after-operator */ te/*inside-value*/st/* wow */ /*omg*/i/*bbq*/ /*whodoesthis*/]` would parse as: + +```js +{ + attribute: "href", + operator: "=", + value: "test", + spaces: { + before: '', + after: '', + attribute: { before: ' ', after: ' ' }, + operator: { after: ' ' }, + value: { after: ' ' }, + insensitive: { after: ' ' } + }, + raws: { + spaces: { + attribute: { before: ' /*before*/ ', after: ' /* after-attr */ ' }, + operator: { after: ' /* after-operator */ ' }, + value: { after: '/* wow */ /*omg*/' }, + insensitive: { after: '/*bbq*/ /*whodoesthis*/' } + }, + unquoted: 'test', + value: 'te/*inside-value*/st' + } +} +``` + +## `Processor` + +### `ProcessorOptions` + +* `lossless` - When `true`, whitespace is preserved. Defaults to `true`. +* `updateSelector` - When `true`, if any processor methods are passed a postcss + `Rule` node instead of a string, then that Rule's selector is updated + with the results of the processing. Defaults to `true`. + +### `process|processSync(selectors, [options])` + +Processes the `selectors`, returning a string from the result of processing. + +Note: when the `updateSelector` option is set, the rule's selector +will be updated with the resulting string. + +**Example:** + +```js +const parser = require("postcss-selector-parser"); +const processor = parser(); + +let result = processor.processSync(' .class'); +console.log(result); +// => .class + +// Asynchronous operation +let promise = processor.process(' .class').then(result => { + console.log(result) + // => .class +}); + +// To have the parser normalize whitespace values, utilize the options +result = processor.processSync(' .class ', {lossless: false}); +console.log(result); +// => .class + +// For better syntax errors, pass a PostCSS Rule node. +const postcss = require('postcss'); +rule = postcss.rule({selector: ' #foo > a, .class '}); +processor.process(rule, {lossless: false, updateSelector: true}).then(result => { + console.log(result); + // => #foo>a,.class + console.log("rule:", rule.selector); + // => rule: #foo>a,.class +}) +``` + +Arguments: + +* `selectors (string|postcss.Rule)`: Either a selector string or a PostCSS Rule + node. +* `[options] (object)`: Process options + + +### `ast|astSync(selectors, [options])` + +Like `process()` and `processSync()` but after +processing the `selectors` these methods return the `Root` node of the result +instead of a string. + +Note: when the `updateSelector` option is set, the rule's selector +will be updated with the resulting string. + +### `transform|transformSync(selectors, [options])` + +Like `process()` and `processSync()` but after +processing the `selectors` these methods return the value returned by the +processor callback. + +Note: when the `updateSelector` option is set, the rule's selector +will be updated with the resulting string. + +### Error Handling Within Selector Processors + +The root node passed to the selector processor callback +has a method `error(message, options)` that returns an +error object. This method should always be used to raise +errors relating to the syntax of selectors. The options +to this method are passed to postcss's error constructor +([documentation](http://api.postcss.org/Container.html#error)). + +#### Async Error Example + +```js +let processor = (root) => { + return new Promise((resolve, reject) => { + root.walkClasses((classNode) => { + if (/^(.*)[-_]/.test(classNode.value)) { + let msg = "classes may not have underscores or dashes in them"; + reject(root.error(msg, { + index: classNode.sourceIndex + RegExp.$1.length + 1, + word: classNode.value + })); + } + }); + resolve(); + }); +}; + +const postcss = require("postcss"); +const parser = require("postcss-selector-parser"); +const selectorProcessor = parser(processor); +const plugin = postcss.plugin('classValidator', (options) => { + return (root) => { + let promises = []; + root.walkRules(rule => { + promises.push(selectorProcessor.process(rule)); + }); + return Promise.all(promises); + }; +}); +postcss(plugin()).process(` +.foo-bar { + color: red; +} +`.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString())); + +// CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them +// +// > 1 | .foo-bar { +// | ^ +// 2 | color: red; +// 3 | } +``` + +#### Synchronous Error Example + +```js +let processor = (root) => { + root.walkClasses((classNode) => { + if (/.*[-_]/.test(classNode.value)) { + let msg = "classes may not have underscores or dashes in them"; + throw root.error(msg, { + index: classNode.sourceIndex, + word: classNode.value + }); + } + }); +}; + +const postcss = require("postcss"); +const parser = require("postcss-selector-parser"); +const selectorProcessor = parser(processor); +const plugin = postcss.plugin('classValidator', (options) => { + return (root) => { + root.walkRules(rule => { + selectorProcessor.processSync(rule); + }); + }; +}); +postcss(plugin()).process(` +.foo-bar { + color: red; +} +`.trim(), {from: 'test.css'}).catch((e) => console.error(e.toString())); + +// CssSyntaxError: classValidator: ./test.css:1:5: classes may not have underscores or dashes in them +// +// > 1 | .foo-bar { +// | ^ +// 2 | color: red; +// 3 | } +``` diff --git a/deps/npm/node_modules/postcss-selector-parser/LICENSE-MIT b/deps/npm/node_modules/postcss-selector-parser/LICENSE-MIT new file mode 100644 index 00000000000000..fd0e863a614fbc --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) Ben Briggs (http://beneb.info) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/index.js b/deps/npm/node_modules/postcss-selector-parser/dist/index.js new file mode 100644 index 00000000000000..6e76a32bdd4426 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/index.js @@ -0,0 +1,24 @@ +"use strict"; + +exports.__esModule = true; +exports["default"] = void 0; + +var _processor = _interopRequireDefault(require("./processor")); + +var selectors = _interopRequireWildcard(require("./selectors")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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); +}; + +Object.assign(parser, selectors); +delete parser.__esModule; +var _default = parser; +exports["default"] = _default; +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..8af1cff1ba07ed --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/parser.js @@ -0,0 +1,1243 @@ +"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() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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); 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)); + +function tokenStart(token) { + return { + line: token[_tokenize.FIELDS.START_LINE], + column: token[_tokenize.FIELDS.START_COL] + }; +} + +function tokenEnd(token) { + return { + line: token[_tokenize.FIELDS.END_LINE], + column: token[_tokenize.FIELDS.END_COL] + }; +} + +function getSource(startLine, startColumn, endLine, 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]); +} + +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]); +} + +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; + } + } + + return node; +} + +function indexesOf(array, item) { + 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 Parser = /*#__PURE__*/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.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 + } + } + }); + 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 (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; + } + } 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 = ''; + } + + if (commentBefore) { + (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); + node.raws.spaces.attribute.before = spaceBefore; + commentBefore = ''; + } + + node.namespace = (node.namespace || "") + content; + var rawValue = (0, _util.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.getProp)(node, 'raws', 'value'); + node.value += "$"; + + if (oldRawValue) { + node.raws.value = oldRawValue + "$"; + } + + 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 = ''; + } + + if (commentBefore) { + (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); + node.raws.spaces.attribute.before = commentBefore; + commentBefore = ''; + } + + node.attribute = (node.attribute || "") + content; + + var _rawValue = (0, _util.getProp)(node, 'raws', 'attribute') || null; + + if (_rawValue) { + node.raws.attribute += content; + } + + lastAdded = 'attribute'; + } else if (!node.value && node.value !== "" || lastAdded === "value" && !spaceAfterMeaningfulToken) { + 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; + } + + 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; + } + } + } + + 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 { + 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 + }); + 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: '' + } + })); + } + } + + 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) { + var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); + + if (nodes.length > 0) { + 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.startsWith(' ') && _rawSpace2.startsWith(' ')) { + 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]) + } + }); + 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.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); + } + }; + + _proto.nesting = function nesting() { + if (this.nextToken) { + var nextContent = this.content(this.nextToken); + + if (nextContent === "|") { + 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 - 1]) + } + }); + 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 (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] + })); + + 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] !== '\\'; + }); // 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; + }); + 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 + }); + }; + + _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 diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/processor.js b/deps/npm/node_modules/postcss-selector-parser/dist/processor.js new file mode 100644 index 00000000000000..a00170c281f966 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/processor.js @@ -0,0 +1,206 @@ +"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 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) + }; + }; + + _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(); + 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 + }; + } + /** + * 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 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 new file mode 100644 index 00000000000000..8f535e5d731299 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/attribute.js @@ -0,0 +1,515 @@ +"use strict"; + +exports.__esModule = true; +exports.unescapeValue = unescapeValue; +exports["default"] = void 0; + +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); 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 || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +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."); + +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 = {}; + } + + 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]; + } + } + }; + + _proto._spacesFor = function _spacesFor(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); + }; + + _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; + } + + 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; + }; + + _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); + })); + } + + 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(); + } + /** + * 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; + } + /** + * 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 set(quoteMark) { + if (!this._constructed) { + this._quoteMark = quoteMark; + return; + } + + if (this._quoteMark !== quoteMark) { + this._quoteMark = quoteMark; + + 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; + } + /** + * 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 set(v) { + if (this._constructed) { + var _unescapeValue2 = unescapeValue(v), + deprecatedUsage = _unescapeValue2.deprecatedUsage, + unescaped = _unescapeValue2.unescaped, + quoteMark = _unescapeValue2.quoteMark; + + if (deprecatedUsage) { + warnOfDeprecatedValueAssignment(); + } + + if (unescaped === this._value && quoteMark === this._quoteMark) { + return; + } + + this._value = unescaped; + this._quoteMark = quoteMark; + + this._syncRawValue(); + } else { + this._value = v; + } + } + }, { + key: "attribute", + get: function get() { + return this._attribute; + }, + 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); + +function defaultAttrConcat(attrValue, attrSpaces) { + return "" + attrSpaces.before + attrValue + attrSpaces.after; +} \ 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 new file mode 100644 index 00000000000000..22409914cf728d --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/className.js @@ -0,0 +1,69 @@ +"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); 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 || 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; + } + }]); + + return ClassName; +}(_node["default"]); + +exports["default"] = ClassName; +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..271ab4d3b1f446 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/combinator.js @@ -0,0 +1,31 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..e778094e110c2f --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/comment.js @@ -0,0 +1,31 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..078023eb28f2d7 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/constructors.js @@ -0,0 +1,102 @@ +"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); +}; + +exports.attribute = attribute; + +var className = function className(opts) { + return new _className["default"](opts); +}; + +exports.className = className; + +var combinator = function combinator(opts) { + return new _combinator["default"](opts); +}; + +exports.combinator = combinator; + +var comment = function comment(opts) { + return new _comment["default"](opts); +}; + +exports.comment = comment; + +var id = function id(opts) { + return new _id["default"](opts); +}; + +exports.id = id; + +var nesting = function nesting(opts) { + return new _nesting["default"](opts); +}; + +exports.nesting = nesting; + +var pseudo = function pseudo(opts) { + return new _pseudo["default"](opts); +}; + +exports.pseudo = pseudo; + +var root = function root(opts) { + return new _root["default"](opts); +}; + +exports.root = root; + +var selector = function selector(opts) { + return new _selector["default"](opts); +}; + +exports.selector = selector; + +var string = function string(opts) { + return new _string["default"](opts); +}; + +exports.string = string; + +var tag = function tag(opts) { + return new _tag["default"](opts); +}; + +exports.tag = tag; + +var universal = function universal(opts) { + return new _universal["default"](opts); +}; + +exports.universal = universal; \ 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 new file mode 100644 index 00000000000000..cf6176d9be6dd5 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/container.js @@ -0,0 +1,395 @@ +"use strict"; + +exports.__esModule = true; +exports["default"] = void 0; + +var _node = _interopRequireDefault(require("./node")); + +var types = _interopRequireWildcard(require("./types")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { 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."); } it = o[Symbol.iterator](); return it.next.bind(it); } + +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); 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 || 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 = []; + } + + 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); + 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) { + newNode.parent = this; + var oldIndex = this.index(oldNode); + this.nodes.splice(oldIndex + 1, 0, newNode); + newNode.parent = this; + var index; + + for (var id in this.indexes) { + index = this.indexes[id]; + + if (oldIndex <= index) { + this.indexes[id] = index + 1; + } + } + + return this; + }; + + _proto.insertBefore = function insertBefore(oldNode, newNode) { + newNode.parent = this; + var oldIndex = this.index(oldNode); + this.nodes.splice(oldIndex, 0, newNode); + newNode.parent = this; + var index; + + for (var id in this.indexes) { + index = this.indexes[id]; + + if (index <= oldIndex) { + this.indexes[id] = index + 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; + } + } 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; + } + + 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; + } + }; + + _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); + } + }); + }; + + _proto.walkTags = function walkTags(callback) { + var _this9 = this; + + return this.walk(function (selector) { + if (selector.type === types.TAG) { + return callback.call(_this9, selector); + } + }); + }; + + _proto.walkUniversals = function walkUniversals(callback) { + var _this10 = this; + + return this.walk(function (selector) { + if (selector.type === types.UNIVERSAL) { + return callback.call(_this10, selector); + } + }); + }; + + _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 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 new file mode 100644 index 00000000000000..c949af57eb1fdf --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/guards.js @@ -0,0 +1,64 @@ +"use strict"; + +exports.__esModule = true; +exports.isNode = isNode; +exports.isPseudoElement = isPseudoElement; +exports.isPseudoClass = isPseudoClass; +exports.isContainer = isContainer; +exports.isNamespace = isNamespace; +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; + +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); + +function isNode(node) { + return typeof node === "object" && IS_TYPE[node.type]; +} + +function isNodeType(type, node) { + 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; + +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"); +} + +function isPseudoClass(node) { + return isPseudo(node) && !isPseudoElement(node); +} + +function isContainer(node) { + return !!(isNode(node) && node.walk); +} + +function isNamespace(node) { + return isAttribute(node) || isTag(node); +} \ 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 new file mode 100644 index 00000000000000..4e83147e3c4efb --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/id.js @@ -0,0 +1,37 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..1fe9b138a5a26e --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/index.js @@ -0,0 +1,27 @@ +"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 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 new file mode 100644 index 00000000000000..fd6c729e16661f --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/namespace.js @@ -0,0 +1,101 @@ +"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); 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 || 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; + } + }; + + _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; + } + + 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 ''; + } + } + }]); + + return Namespace; +}(_node["default"]); + +exports["default"] = Namespace; +; +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..3288c78f2dddba --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/nesting.js @@ -0,0 +1,32 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..e8eca11c70ecf4 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/node.js @@ -0,0 +1,239 @@ +"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); 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; + } + + 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); + } + } + + 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]; + } + + 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; + } + }]); + + return Node; +}(); + +exports["default"] = Node; +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..a0e7bca170a76d --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/pseudo.js @@ -0,0 +1,38 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..be5c2ccb2dac83 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/root.js @@ -0,0 +1,60 @@ +"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); 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 || 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); + } + }; + + _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 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 new file mode 100644 index 00000000000000..699eeb6e546f91 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/selector.js @@ -0,0 +1,31 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..e61df30c74a0a3 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/string.js @@ -0,0 +1,31 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..e298db15fafd1f --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/tag.js @@ -0,0 +1,31 @@ +"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 || 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 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 new file mode 100644 index 00000000000000..ab897b8ce5c129 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/types.js @@ -0,0 +1,28 @@ +"use strict"; + +exports.__esModule = 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; +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 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 new file mode 100644 index 00000000000000..cf25473d1c3d4d --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/selectors/universal.js @@ -0,0 +1,32 @@ +"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 || 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 diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js b/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js new file mode 100644 index 00000000000000..3ef56acc570c8f --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/sortAscending.js @@ -0,0 +1,13 @@ +"use strict"; + +exports.__esModule = true; +exports["default"] = sortAscending; + +function sortAscending(list) { + return list.sort(function (a, b) { + return a - b; + }); +} + +; +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..48314b93e00581 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/tokenTypes.js @@ -0,0 +1,95 @@ +"use strict"; + +exports.__esModule = 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; +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); +// Expose aliases primarily for readability. + +exports.tab = tab; +var str = 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 diff --git a/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js b/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js new file mode 100644 index 00000000000000..bee9fee632e84c --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/tokenize.js @@ -0,0 +1,271 @@ +"use strict"; + +exports.__esModule = true; +exports["default"] = tokenize; +exports.FIELDS = void 0; + +var t = _interopRequireWildcard(require("./tokenTypes")); + +var _unescapable, _wordDelimiters; + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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); +var hex = {}; +var hexChars = "0123456789abcdefABCDEF"; + +for (var i = 0; i < hexChars.length; i++) { + 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; +} +/** + * 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++; + } + } else { + // the next char is part of the current word + 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 = 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; + } + + 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; + } + + return tokens; +} \ 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 new file mode 100644 index 00000000000000..3472e075228405 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/ensureObject.js @@ -0,0 +1,22 @@ +"use strict"; + +exports.__esModule = 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] = {}; + } + + obj = obj[prop]; + } +} + +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..53e07c90253eb1 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/getProp.js @@ -0,0 +1,24 @@ +"use strict"; + +exports.__esModule = 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; + } + + obj = obj[prop]; + } + + return obj; +} + +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..043fda8c64b9a8 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/index.js @@ -0,0 +1,22 @@ +"use strict"; + +exports.__esModule = true; +exports.stripComments = exports.ensureObject = exports.getProp = exports.unesc = 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 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 new file mode 100644 index 00000000000000..c74f1fecdcc641 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/stripComments.js @@ -0,0 +1,27 @@ +"use strict"; + +exports.__esModule = 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; + } + + lastEnd = commentEnd + 2; + commentStart = str.indexOf("/*", lastEnd); + } + + s = s + str.slice(lastEnd); + return s; +} + +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..e4fac839ddd035 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/dist/util/unesc.js @@ -0,0 +1,93 @@ +"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 + +/** + * + * @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; + } + + 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)]; +} + +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) { + ret += str[i]; + } + + continue; + } + + ret += str[i]; + } + + return ret; +} + +module.exports = exports.default; \ 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 new file mode 100644 index 00000000000000..a6f33589ba051d --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/package.json @@ -0,0 +1,78 @@ +{ + "name": "postcss-selector-parser", + "version": "6.0.10", + "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": "^3.12.1", + "babel-plugin-add-module-exports": "^1.0.4", + "coveralls": "^3.1.0", + "del-cli": "^3.0.1", + "eslint": "^7.9.0", + "eslint-plugin-import": "^2.22.0", + "glob": "^7.1.6", + "minimist": "^1.2.5", + "nyc": "^15.1.0", + "postcss": "^8.0.0", + "semver": "^7.3.2", + "typescript": "^4.0.3" + }, + "main": "dist/index.js", + "types": "postcss-selector-parser.d.ts", + "files": [ + "API.md", + "CHANGELOG.md", + "LICENSE-MIT", + "dist", + "postcss-selector-parser.d.ts", + "!**/__tests__" + ], + "scripts": { + "pretest": "eslint src && tsc --noEmit postcss-selector-parser.d.ts", + "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__/*.js ", + "testone": "ava" + }, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "license": "MIT", + "engines": { + "node": ">=4" + }, + "homepage": "https://github.com/postcss/postcss-selector-parser", + "contributors": [ + { + "name": "Ben Briggs", + "email": "beneb.info@gmail.com", + "url": "http://beneb.info" + }, + { + "name": "Chris Eppstein", + "email": "chris@eppsteins.net", + "url": "http://twitter.com/chriseppstein" + } + ], + "repository": "postcss/postcss-selector-parser", + "ava": { + "require": [ + "@babel/register" + ], + "concurrency": 5, + "timeout": "25s" + }, + "nyc": { + "exclude": [ + "node_modules", + "**/__tests__" + ] + } +} diff --git a/deps/npm/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts b/deps/npm/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts new file mode 100644 index 00000000000000..89a2c5239edb16 --- /dev/null +++ b/deps/npm/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts @@ -0,0 +1,555 @@ +// Type definitions for postcss-selector-parser 2.2.3 +// Definitions by: Chris Eppstein + +/*~ Note that ES6 modules cannot directly export callable functions. + *~ This file should be imported using the CommonJS-style: + *~ import x = require('someLibrary'); + *~ + *~ Refer to the documentation to understand common + *~ workarounds for this limitation of ES6 modules. + */ + +/*~ This declaration specifies that the function + *~ is the exported object from the file + */ +export = parser; + +// A type that's T but not U. +type Diff = T extends U ? never : T; + +// TODO: Conditional types in TS 1.8 will really clean this up. +declare function parser(): parser.Processor; +declare function parser(processor: parser.AsyncProcessor): parser.Processor; +declare function parser(processor: parser.AsyncProcessor): parser.Processor; +declare function parser(processor: parser.SyncProcessor): parser.Processor; +declare function parser(processor: parser.SyncProcessor): parser.Processor; +declare function parser(processor?: parser.SyncProcessor | parser.AsyncProcessor): parser.Processor; + +/*~ If you want to expose types from your module as well, you can + *~ place them in this block. Often you will want to describe the + *~ shape of the return type of the function; that type should + *~ be declared in here, as this example shows. + */ +declare namespace parser { + /* copied from postcss -- so we don't need to add a dependency */ + type ErrorOptions = { + plugin?: string; + word?: string; + index?: number + }; + /* the bits we use of postcss.Rule, copied from postcss -- so we don't need to add a dependency */ + type PostCSSRuleNode = { + selector: string + /** + * @returns postcss.CssSyntaxError but it's a complex object, caller + * should cast to it if they have a dependency on postcss. + */ + error(message: string, options?: ErrorOptions): Error; + }; + /** Accepts a string */ + type Selectors = string | PostCSSRuleNode + type ProcessorFn = (root: parser.Root) => ReturnType; + type SyncProcessor = ProcessorFn; + type AsyncProcessor = ProcessorFn>; + + const TAG: "tag"; + const STRING: "string"; + const SELECTOR: "selector"; + const ROOT: "root"; + const PSEUDO: "pseudo"; + const NESTING: "nesting"; + const ID: "id"; + const COMMENT: "comment"; + const COMBINATOR: "combinator"; + const CLASS: "class"; + const ATTRIBUTE: "attribute"; + const UNIVERSAL: "universal"; + + interface NodeTypes { + tag: Tag, + string: String, + selector: Selector, + root: Root, + pseudo: Pseudo, + nesting: Nesting, + id: Identifier, + comment: Comment, + combinator: Combinator, + class: ClassName, + attribute: Attribute, + universal: Universal + } + + type Node = NodeTypes[keyof NodeTypes]; + + function isNode(node: any): node is Node; + + interface Options { + /** + * Preserve whitespace when true. Default: false; + */ + lossless: boolean; + /** + * When true and a postcss.Rule is passed, set the result of + * processing back onto the rule when done. Default: false. + */ + updateSelector: boolean; + } + class Processor< + TransformType = never, + SyncSelectorsType extends Selectors | never = Selectors + > { + res: Root; + readonly result: String; + ast(selectors: Selectors, options?: Partial): Promise; + astSync(selectors: SyncSelectorsType, options?: Partial): Root; + transform(selectors: Selectors, options?: Partial): Promise; + transformSync(selectors: SyncSelectorsType, options?: Partial): TransformType; + process(selectors: Selectors, options?: Partial): Promise; + processSync(selectors: SyncSelectorsType, options?: Partial): string; + } + interface ParserOptions { + css: string; + error: (message: string, options: ErrorOptions) => Error; + options: Options; + } + class Parser { + input: ParserOptions; + lossy: boolean; + position: number; + root: Root; + selectors: string; + current: Selector; + constructor(input: ParserOptions); + /** + * Raises an error, if the processor is invoked on + * a postcss Rule node, a better error message is raised. + */ + error(message: string, options?: ErrorOptions): void; + } + interface NodeSource { + start?: { + line: number, + column: number + }, + end?: { + line: number, + column: number + } + } + interface SpaceAround { + before: string; + after: string; + } + interface Spaces extends SpaceAround { + [spaceType: string]: string | Partial | undefined; + } + interface NodeOptions { + value: Value; + spaces?: Partial; + source?: NodeSource; + sourceIndex?: number; + } + interface Base< + Value extends string | undefined = string, + ParentType extends Container | undefined = Container | undefined + > { + type: keyof NodeTypes; + parent: ParentType; + value: Value; + spaces: Spaces; + source?: NodeSource; + sourceIndex: number; + rawSpaceBefore: string; + rawSpaceAfter: string; + remove(): Node; + replaceWith(...nodes: Node[]): Node; + next(): Node; + prev(): Node; + clone(opts: {[override: string]:any}): Node; + /** + * Return whether this node includes the character at the position of the given line and column. + * Returns undefined if the nodes lack sufficient source metadata to determine the position. + * @param line 1-index based line number relative to the start of the selector. + * @param column 1-index based column number relative to the start of the selector. + */ + isAtPosition(line: number, column: number): boolean | undefined; + /** + * 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 name the property to set + * @param value the unescaped value of the property + * @param valueEscaped optional. the escaped value of the property. + */ + setPropertyAndEscape(name: string, value: any, valueEscaped: string): void; + /** + * 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 name the property to set. + * @param value The value that is both escaped and unescaped. + */ + setPropertyWithoutEscape(name: string, value: any): void; + /** + * 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. + */ + appendToPropertyAndEscape(name: string, value: any, valueEscaped: string): void; + toString(): string; + } + interface ContainerOptions extends NodeOptions { + nodes?: Array; + } + interface Container< + Value extends string | undefined = string, + Child extends Node = Node + > extends Base { + nodes: Array; + append(selector: Selector): this; + prepend(selector: Selector): this; + at(index: number): Child; + /** + * 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 line The line number of the node to find. (1-based index) + * @param col The column number of the node to find. (1-based index) + */ + atPosition(line: number, column: number): Child; + index(child: Child): number; + readonly first: Child; + readonly last: Child; + readonly length: number; + removeChild(child: Child): this; + removeAll(): Container; + empty(): Container; + insertAfter(oldNode: Child, newNode: Child): this; + insertBefore(oldNode: Child, newNode: Child): this; + each(callback: (node: Child) => boolean | void): boolean | undefined; + walk( + callback: (node: Node) => boolean | void + ): boolean | undefined; + walkAttributes( + callback: (node: Attribute) => boolean | void + ): boolean | undefined; + walkClasses( + callback: (node: ClassName) => boolean | void + ): boolean | undefined; + walkCombinators( + callback: (node: Combinator) => boolean | void + ): boolean | undefined; + walkComments( + callback: (node: Comment) => boolean | void + ): boolean | undefined; + walkIds( + callback: (node: Identifier) => boolean | void + ): boolean | undefined; + walkNesting( + callback: (node: Nesting) => boolean | void + ): boolean | undefined; + walkPseudos( + callback: (node: Pseudo) => boolean | void + ): boolean | undefined; + walkTags(callback: (node: Tag) => boolean | void): boolean | undefined; + split(callback: (node: Child) => boolean): [Child[], Child[]]; + map(callback: (node: Child) => T): T[]; + reduce( + callback: ( + previousValue: Child, + currentValue: Child, + currentIndex: number, + array: readonly Child[] + ) => Child + ): Child; + reduce( + callback: ( + previousValue: Child, + currentValue: Child, + currentIndex: number, + array: readonly Child[] + ) => Child, + initialValue: Child + ): Child; + reduce( + callback: ( + previousValue: T, + currentValue: Child, + currentIndex: number, + array: readonly Child[] + ) => T, + initialValue: T + ): T; + every(callback: (node: Child) => boolean): boolean; + some(callback: (node: Child) => boolean): boolean; + filter(callback: (node: Child) => boolean): Child[]; + sort(callback: (nodeA: Child, nodeB: Child) => number): Child[]; + toString(): string; + } + function isContainer(node: any): node is Root | Selector | Pseudo; + + interface NamespaceOptions extends NodeOptions { + namespace?: string | true; + } + interface Namespace extends Base { + /** alias for namespace */ + ns: string | true; + /** + * namespace prefix. + */ + namespace: string | true; + /** + * If a namespace exists, prefix the value provided with it, separated by |. + */ + qualifiedName(value: string): string; + /** + * A string representing the namespace suitable for output. + */ + readonly namespaceString: string; + } + function isNamespace(node: any): node is Attribute | Tag; + + interface Root extends Container { + type: "root"; + /** + * Raises an error, if the processor is invoked on + * a postcss Rule node, a better error message is raised. + */ + error(message: string, options?: ErrorOptions): Error; + nodeAt(line: number, column: number): Node + } + function root(opts: ContainerOptions): Root; + function isRoot(node: any): node is Root; + + interface _Selector extends Container> { + type: "selector"; + } + type Selector = _Selector; + function selector(opts: ContainerOptions): Selector; + function isSelector(node: any): node is Selector; + + interface CombinatorRaws { + value?: string; + spaces?: { + before?: string; + after?: string; + }; + } + interface Combinator extends Base { + type: "combinator"; + raws?: CombinatorRaws; + } + function combinator(opts: NodeOptions): Combinator; + function isCombinator(node: any): node is Combinator; + + interface ClassName extends Base { + type: "class"; + } + function className(opts: NamespaceOptions): ClassName; + function isClassName(node: any): node is ClassName; + + type AttributeOperator = "=" | "~=" | "|=" | "^=" | "$=" | "*="; + type QuoteMark = '"' | "'" | null; + interface PreferredQuoteMarkOptions { + quoteMark?: QuoteMark; + preferCurrentQuoteMark?: boolean; + } + interface SmartQuoteMarkOptions extends PreferredQuoteMarkOptions { + smart?: boolean; + } + interface AttributeOptions extends NamespaceOptions { + attribute: string; + operator?: AttributeOperator; + insensitive?: boolean; + quoteMark?: QuoteMark; + /** @deprecated Use quoteMark instead. */ + quoted?: boolean; + spaces?: { + before?: string; + after?: string; + attribute?: Partial; + operator?: Partial; + value?: Partial; + insensitive?: Partial; + } + raws: { + unquoted?: string; + attribute?: string; + operator?: string; + value?: string; + insensitive?: string; + spaces?: { + attribute?: Partial; + operator?: Partial; + value?: Partial; + insensitive?: Partial; + } + }; + } + interface Attribute extends Namespace { + type: "attribute"; + attribute: string; + operator?: AttributeOperator; + insensitive?: boolean; + quoteMark: QuoteMark; + quoted?: boolean; + spaces: { + before: string; + after: string; + attribute?: Partial; + operator?: Partial; + value?: Partial; + insensitive?: Partial; + } + raws: { + /** @deprecated The attribute value is unquoted, use that instead.. */ + unquoted?: string; + attribute?: string; + operator?: string; + /** The value of the attribute with quotes and escapes. */ + value?: string; + insensitive?: string; + spaces?: { + attribute?: Partial; + operator?: Partial; + value?: Partial; + insensitive?: Partial; + } + }; + /** + * The attribute name after having been qualified with a namespace. + */ + readonly qualifiedAttribute: string; + + /** + * The case insensitivity flag or an empty string depending on whether this + * attribute is case insensitive. + */ + readonly insensitiveFlag : 'i' | ''; + + /** + * 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 or + * `set quoteMark(mark)` if you want to change the quote settings of the current + * value. + * + * You can also change the quotation used for the current value by setting quoteMark. + **/ + getQuotedValue(options?: SmartQuoteMarkOptions): string; + + /** + * 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. + * @param value + */ + setValue(value: string, options?: SmartQuoteMarkOptions): void; + + /** + * 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. + **/ + smartQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark; + + /** + * 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. + */ + preferredQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark + + /** + * 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. + */ + offsetOf(part: "ns" | "namespace" | "attribute" | "attributeNS" | "operator" | "value" | "insensitive"): number; + } + function attribute(opts: AttributeOptions): Attribute; + function isAttribute(node: any): node is Attribute; + + interface Pseudo extends Container { + type: "pseudo"; + } + function pseudo(opts: ContainerOptions): Pseudo; + /** + * Checks wether the node is the Psuedo subtype of node. + */ + function isPseudo(node: any): node is Pseudo; + + /** + * Checks wether the node is, specifically, a pseudo element instead of + * pseudo class. + */ + function isPseudoElement(node: any): node is Pseudo; + + /** + * Checks wether the node is, specifically, a pseudo class instead of + * pseudo element. + */ + function isPseudoClass(node: any): node is Pseudo; + + + interface Tag extends Namespace { + type: "tag"; + } + function tag(opts: NamespaceOptions): Tag; + function isTag(node: any): node is Tag; + + interface Comment extends Base { + type: "comment"; + } + function comment(opts: NodeOptions): Comment; + function isComment(node: any): node is Comment; + + interface Identifier extends Base { + type: "id"; + } + function id(opts: any): any; + function isIdentifier(node: any): node is Identifier; + + interface Nesting extends Base { + type: "nesting"; + } + function nesting(opts: any): any; + function isNesting(node: any): node is Nesting; + + interface String extends Base { + type: "string"; + } + function string(opts: NodeOptions): String; + function isString(node: any): node is String; + + interface Universal extends Base { + type: "universal"; + } + function universal(opts?: NamespaceOptions): any; + function isUniversal(node: any): node is Universal; +} diff --git a/deps/npm/package.json b/deps/npm/package.json index 7526c4754b0ff5..6efd43f49e96f4 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "8.15.1", + "version": "8.16.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ @@ -62,7 +62,7 @@ "@npmcli/fs": "^2.1.0", "@npmcli/map-workspaces": "^2.0.3", "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.1.7", + "@npmcli/run-script": "^4.2.0", "abbrev": "~1.1.1", "archy": "~1.0.0", "cacache": "^16.1.1", diff --git a/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs index 232cfec669778f..f08ef0f37c3601 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs @@ -87,6 +87,7 @@ Array [ profile prune publish + query rebuild repo restart 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 095fd9b7886c21..a455def634c3a1 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 @@ -121,6 +121,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "read-only": false, "rebuild-bundle": true, "registry": "https://registry.npmjs.org/", + "replace-registry-host": "npmjs", "save": true, "save-bundle": false, "save-dev": false, @@ -277,6 +278,7 @@ proxy = null read-only = false rebuild-bundle = true registry = "https://registry.npmjs.org/" +replace-registry-host = "npmjs" save = true save-bundle = false save-dev = false diff --git a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs index 1c8d3e59c3fe19..c56f8b162dc731 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs @@ -678,6 +678,13 @@ dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries-and-not ` +exports[`test/lib/commands/ls.js TAP ls workspace and missing optional dep > should omit missing optional dep 1`] = ` +root@ {CWD}/tap-testdir-ls-ls-workspace-and-missing-optional-dep ++-- baz@1.0.0 -> ./baz +\`-- foo@1.0.0 + +` + exports[`test/lib/commands/ls.js TAP show multiple invalid reasons > ls result 1`] = ` test-npm-ls@1.0.0 {cwd}/tap-testdir-ls-show-multiple-invalid-reasons +-- cat@1.0.0 invalid: "^2.0.0" from the root project diff --git a/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs new file mode 100644 index 00000000000000..0a2aa769ee6380 --- /dev/null +++ b/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs @@ -0,0 +1,221 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/query.js TAP global > should return global package 1`] = ` +[ + { + "name": "lorem", + "version": "2.0.0", + "_id": "lorem@2.0.0", + "pkgid": "lorem@2.0.0", + "location": "node_modules/lorem", + "path": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem", + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` + +exports[`test/lib/commands/query.js TAP include-workspace-root > should return workspace object and root object 1`] = ` +[ + { + "name": "project", + "workspaces": [ + "c" + ], + "dependencies": { + "a": "^1.0.0", + "b": "^1.0.0" + }, + "pkgid": "project@", + "location": "", + "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix", + "resolved": null, + "from": [], + "to": [ + "node_modules/c", + "node_modules/a", + "node_modules/b" + ], + "dev": false, + "inBundle": false, + "deduped": false + }, + { + "name": "c", + "version": "1.0.0", + "_id": "c@1.0.0", + "pkgid": "c@1.0.0", + "location": "c", + "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c", + "resolved": null, + "from": [], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` + +exports[`test/lib/commands/query.js TAP linked node > should return linked node res 1`] = ` +[ + { + "name": "a", + "version": "1.0.0", + "_id": "a@1.0.0", + "pkgid": "a@1.0.0", + "location": "a", + "path": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a", + "resolved": null, + "from": [], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` + +exports[`test/lib/commands/query.js TAP recursive tree > should return everything in the tree, accounting for recursion 1`] = ` +[ + { + "name": "project", + "dependencies": { + "a": "^1.0.0", + "b": "^1.0.0" + }, + "pkgid": "project@", + "location": "", + "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix", + "resolved": null, + "from": [], + "to": [ + "node_modules/a", + "node_modules/b" + ], + "dev": false, + "inBundle": false, + "deduped": false + }, + { + "pkgid": "a@", + "location": "node_modules/a", + "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a", + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + }, + { + "pkgid": "b@", + "location": "node_modules/b", + "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b", + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` + +exports[`test/lib/commands/query.js TAP simple query > should return root object and direct children 1`] = ` +[ + { + "name": "project", + "dependencies": { + "a": "^1.0.0", + "b": "^1.0.0" + }, + "peerDependencies": { + "c": "1.0.0" + }, + "pkgid": "project@", + "location": "", + "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix", + "resolved": null, + "from": [], + "to": [ + "node_modules/a", + "node_modules/b" + ], + "dev": false, + "inBundle": false, + "deduped": false + }, + { + "pkgid": "a@", + "location": "node_modules/a", + "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a", + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + }, + { + "pkgid": "b@", + "location": "node_modules/b", + "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b", + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` + +exports[`test/lib/commands/query.js TAP workspace query > should return workspace object 1`] = ` +[ + { + "name": "c", + "version": "1.0.0", + "_id": "c@1.0.0", + "pkgid": "c@1.0.0", + "location": "c", + "path": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c", + "realpath": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c", + "resolved": null, + "from": [], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false + } +] +` diff --git a/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs index 88b1d49556fd89..eac037f4b27081 100644 --- a/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/load-all-commands.js.test.cjs @@ -693,6 +693,20 @@ Options: Run "npm help publish" for more info ` +exports[`test/lib/load-all-commands.js TAP load each command query > must match snapshot 1`] = ` +Retrieve a filtered list of packages + +Usage: +npm query + +Options: +[-g|--global] +[-w|--workspace [-w|--workspace ...]] +[-ws|--workspaces] [--include-workspace-root] + +Run "npm help query" for more info +` + exports[`test/lib/load-all-commands.js TAP load each command rebuild > must match snapshot 1`] = ` Rebuild a package 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 8d5f188b07924c..455c61eaacc573 100644 --- a/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs @@ -26,7 +26,7 @@ All commands: edit, exec, explain, explore, find-dupes, fund, get, help, hook, init, install, install-ci-test, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, ping, - pkg, prefix, profile, prune, publish, rebuild, repo, + pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, search, set, set-script, shrinkwrap, star, stars, start, stop, team, test, token, uninstall, unpublish, unstar, update, version, view, whoami @@ -62,7 +62,7 @@ All commands: edit, exec, explain, explore, find-dupes, fund, get, help, hook, init, install, install-ci-test, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, ping, - pkg, prefix, profile, prune, publish, rebuild, repo, + pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, search, set, set-script, shrinkwrap, star, stars, start, stop, team, test, token, uninstall, unpublish, unstar, update, version, view, whoami @@ -98,7 +98,7 @@ All commands: edit, exec, explain, explore, find-dupes, fund, get, help, hook, init, install, install-ci-test, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, ping, - pkg, prefix, profile, prune, publish, rebuild, repo, + pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, search, set, set-script, shrinkwrap, star, stars, start, stop, team, test, token, uninstall, unpublish, unstar, update, version, view, whoami @@ -134,7 +134,7 @@ All commands: edit, exec, explain, explore, find-dupes, fund, get, help, hook, init, install, install-ci-test, install-test, link, ll, login, logout, ls, org, outdated, owner, pack, ping, - pkg, prefix, profile, prune, publish, rebuild, repo, + pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, search, set, set-script, shrinkwrap, star, stars, start, stop, team, test, token, uninstall, unpublish, unstar, update, version, view, whoami @@ -746,6 +746,18 @@ All commands: Run "npm help publish" for more info + query Retrieve a filtered list of packages + + Usage: + npm query + + Options: + [-g|--global] + [-w|--workspace [-w|--workspace ...]] + [-ws|--workspaces] [--include-workspace-root] + + Run "npm help query" for more info + rebuild Rebuild a package Usage: diff --git a/deps/npm/tap-snapshots/test/lib/utils/cmd-list.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/cmd-list.js.test.cjs index 9413f8e9a6d520..dd0df9b868c7a0 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/cmd-list.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/cmd-list.js.test.cjs @@ -218,6 +218,11 @@ Object { "publi": "publish", "publis": "publish", "publish": "publish", + "q": "query", + "qu": "query", + "que": "query", + "quer": "query", + "query": "query", "r": "r", "rb": "rb", "reb": "rebuild", @@ -453,6 +458,7 @@ Object { "profile", "prune", "publish", + "query", "rebuild", "repo", "restart", diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs index 89c9969d69424d..024ad345a5d321 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/config/definitions.js.test.cjs @@ -116,6 +116,7 @@ Array [ "read-only", "rebuild-bundle", "registry", + "replace-registry-host", "save", "save-bundle", "save-dev", @@ -1315,7 +1316,7 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for packa * Default: * Type: String (can be set multiple times) -The package to install for [\`npm exec\`](/commands/npm-exec) +The package or packages to install for [\`npm exec\`](/commands/npm-exec) ` exports[`test/lib/utils/config/definitions.js TAP > config description for package-lock 1`] = ` @@ -1460,6 +1461,23 @@ exports[`test/lib/utils/config/definitions.js TAP > config description for regis The base URL of the npm registry. ` +exports[`test/lib/utils/config/definitions.js TAP > config description for replace-registry-host 1`] = ` +#### \`replace-registry-host\` + +* Default: "npmjs" +* Type: "npmjs", "never", "always", or String + +Defines behavior for replacing the registry host in a lockfile with the +configured registry. + +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. + +You may also specify a bare hostname (e.g., "registry.npmjs.org"). +` + exports[`test/lib/utils/config/definitions.js TAP > config description for save 1`] = ` #### \`save\` diff --git a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs index a9247f49c04187..a03d22e5e6305b 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/config/describe-all.js.test.cjs @@ -1117,7 +1117,7 @@ Directory in which \`npm pack\` will save tarballs. * Default: * Type: String (can be set multiple times) -The package to install for [\`npm exec\`](/commands/npm-exec) +The package or packages to install for [\`npm exec\`](/commands/npm-exec) @@ -1266,6 +1266,24 @@ The base URL of the npm registry. +#### \`replace-registry-host\` + +* Default: "npmjs" +* Type: "npmjs", "never", "always", or String + +Defines behavior for replacing the registry host in a lockfile with the +configured registry. + +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. + +You may also specify a bare hostname (e.g., "registry.npmjs.org"). + + + + #### \`save\` * Default: \`true\` unless when using \`npm update\` where it defaults to \`false\` diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js index 90bf7da4c10bc7..adf6c7432a5612 100644 --- a/deps/npm/test/fixtures/mock-npm.js +++ b/deps/npm/test/fixtures/mock-npm.js @@ -63,7 +63,7 @@ const LoadMockNpm = async (t, { prefixDir = {}, homeDir = {}, cacheDir = {}, - globalPrefixDir = {}, + globalPrefixDir = { lib: {} }, config = {}, mocks = {}, globals = null, diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js index 049ed327c8fc5e..6e4c3e2246a6ab 100644 --- a/deps/npm/test/lib/commands/exec.js +++ b/deps/npm/test/lib/commands/exec.js @@ -1,1547 +1,99 @@ const t = require('tap') -const { fake: mockNpm } = require('../../fixtures/mock-npm') -const { resolve, delimiter } = require('path') +const fs = require('@npmcli/fs') +const path = require('path') +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const MockRegistry = require('../../fixtures/mock-registry.js') -const ARB_CTOR = [] -const ARB_ACTUAL_TREE = {} -const ARB_REIFY = [] -class Arborist { - constructor (options) { - ARB_CTOR.push(options) - this.path = options.path - } - - async loadActual () { - return ARB_ACTUAL_TREE[this.path] - } - - async reify (options) { - ARB_REIFY.push(options) - } -} - -let PROGRESS_ENABLED = true -const LOG_WARN = [] -let PROGRESS_IGNORED = false -const flatOptions = { - npxCache: 'npx-cache-dir', - color: false, - cache: 'cache-dir', - legacyPeerDeps: false, - package: [], -} -const config = { - cache: 'bad-cache-dir', // this should never show up passed into libnpmexec - yes: true, - call: '', - package: [], - 'script-shell': 'shell-cmd', -} - -const npm = mockNpm({ - flatOptions, - config, - localPrefix: 'local-prefix', - localBin: 'local-bin', - globalBin: 'global-bin', -}) - -const RUN_SCRIPTS = [] -const runScript = async opt => { - RUN_SCRIPTS.push(opt) - if (!PROGRESS_IGNORED && PROGRESS_ENABLED) { - throw new Error('progress not disabled during run script!') - } -} - -const MANIFESTS = {} -const pacote = { - manifest: async (spec, options) => { - return MANIFESTS[spec] - }, -} - -const MKDIRPS = [] -const mkdirp = async path => MKDIRPS.push(path) - -let READ_RESULT = '' -let READ_ERROR = null -const READ = [] -const read = (options, cb) => { - READ.push(options) - process.nextTick(() => cb(READ_ERROR, READ_RESULT)) -} - -let CI_NAME = 'travis-ci' - -const log = { - 'proc-log': { - warn: (...args) => { - LOG_WARN.push(args) - }, - }, - npmlog: { - disableProgress: () => { - PROGRESS_ENABLED = false - }, - enableProgress: () => { - PROGRESS_ENABLED = true - }, - clearProgress: () => {}, - }, -} - -const mocks = { - libnpmexec: t.mock('libnpmexec', { - '@npmcli/arborist': Arborist, - '@npmcli/run-script': runScript, - '@npmcli/ci-detect': () => CI_NAME, - pacote, - read, - 'mkdirp-infer-owner': mkdirp, - ...log, - }), - ...log, -} -const Exec = t.mock('../../../lib/commands/exec.js', mocks) -const exec = new Exec(npm) - -t.afterEach(() => { - MKDIRPS.length = 0 - ARB_CTOR.length = 0 - ARB_REIFY.length = 0 - RUN_SCRIPTS.length = 0 - READ.length = 0 - READ_RESULT = '' - READ_ERROR = null - LOG_WARN.length = 0 - PROGRESS_IGNORED = false - flatOptions.legacyPeerDeps = false - flatOptions.color = false - config['script-shell'] = 'shell-cmd' - config.package = [] - flatOptions.package = [] - config.call = '' - config.yes = true - npm.color = false - npm.localBin = 'local-bin' - npm.globalBin = 'global-bin' -}) - -t.test('npx foo, bin already exists locally', async t => { - const path = t.testdir({ - node_modules: { - '.bin': { - foo: 'just some file', - }, - }, - }) - - PROGRESS_IGNORED = true - npm.localBin = resolve(path, 'node_modules', '.bin') - - await exec.exec(['foo', 'one arg', 'two arg']) - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - cache: flatOptions.cache, - npxCache: flatOptions.npxCache, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { - PATH: [npm.localBin, process.env.PATH].join(delimiter), - }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npx foo, bin already exists globally', async t => { - const path = t.testdir({ - node_modules: { - '.bin': { - foo: 'just some file', - }, - }, - }) - - PROGRESS_IGNORED = true - npm.globalBin = resolve(path, 'node_modules', '.bin') - - await exec.exec(['foo', 'one arg', 'two arg']) - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { - PATH: [npm.globalBin, process.env.PATH].join(delimiter), - }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec foo, already present locally', async t => { - const path = t.testdir() - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - await exec.exec(['foo', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec , run interactive shell', t => { - CI_NAME = null - const { isTTY } = process.stdin - process.stdin.isTTY = true - t.teardown(() => (process.stdin.isTTY = isTTY)) - - const run = async (t, doRun) => { - LOG_WARN.length = 0 - ARB_CTOR.length = 0 - MKDIRPS.length = 0 - ARB_REIFY.length = 0 - npm._mockOutputs.length = 0 - await exec.exec([]) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.strictSame(ARB_CTOR, [], 'no need to instantiate arborist') - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - if (doRun) { - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'shell-cmd' } }, - args: [], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) - } else { - t.strictSame(RUN_SCRIPTS, []) - } - - RUN_SCRIPTS.length = 0 - } - t.test('print message when tty and not in CI', async t => { - CI_NAME = null - process.stdin.isTTY = true - await run(t, true) - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, - [ - [ - /* eslint-disable-next-line max-len */ - `\nEntering npm script environment at location:\n${process.cwd()}\nType 'exit' or ^D when finished\n`, - ], - ], - 'printed message about interactive shell' - ) - }) - - t.test('print message with color when tty and not in CI', async t => { - CI_NAME = null - process.stdin.isTTY = true - npm.color = true - flatOptions.color = true - - await run(t, true) - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, - [ - [ - /* eslint-disable-next-line max-len */ - `\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m at location:\u001b[0m\n\u001b[0m\u001b[2m${process.cwd()}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`, - ], - ], - 'printed message about interactive shell' - ) - }) - - t.test('no message when not TTY', async t => { - CI_NAME = null - process.stdin.isTTY = false - await run(t, true) - t.strictSame(LOG_WARN, []) - t.strictSame(npm._mockOutputs, [], 'no message about interactive shell') - }) - - t.test('print warning when in CI and interactive', async t => { - CI_NAME = 'travis-ci' - process.stdin.isTTY = true - await run(t, false) - t.strictSame(LOG_WARN, [['exec', 'Interactive mode disabled in CI environment']]) - t.strictSame(npm._mockOutputs, [], 'no message about interactive shell') - }) - - t.test('not defined script-shell config value', async t => { - CI_NAME = null - process.stdin.isTTY = true - config['script-shell'] = undefined - - await exec.exec([]) - - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: /sh|cmd/ } }, - }, - ]) - - LOG_WARN.length = 0 - ARB_CTOR.length = 0 - MKDIRPS.length = 0 - ARB_REIFY.length = 0 - npm._mockOutputs.length = 0 - RUN_SCRIPTS.length = 0 - }) - - t.end() -}) - -t.test('npm exec foo, not present locally or in central loc', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - await exec.exec(['foo', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add: ['foo@'], legacyPeerDeps: false }], 'need to install foo@') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec foo, packageLockOnly set to true', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - npm.localPrefix = path - npm.config.set('package-lock-only', true) - t.teardown(() => { - npm.config.set('package-lock-only', false) - }) - - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - await exec.exec(['foo', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ - path, - packageLockOnly: false, - }]) - t.match(ARB_REIFY, [{ - add: ['foo@'], - legacyPeerDeps: false, - packageLockOnly: false, - }], 'need to install foo@') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec foo, not present locally but in central loc', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - await exec.exec(['foo', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to install again, already there') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec foo, present locally but wrong version', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/2badf4630f1cfaad') - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS['foo@2.x'] = { - name: 'foo', - version: '2.3.4', - bin: { - foo: 'foo', - }, - _from: 'foo@2.x', - } - await exec.exec(['foo@2.x', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add: ['foo@2.x'], legacyPeerDeps: false }], 'need to add foo@2.x') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec foo, present locally but outdated version', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '2.3.4', - bin: { - foo: 'foo', - }, - _from: 'foo@2.x', - } - await exec.exec(['foo', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add: ['foo'], legacyPeerDeps: false }], 'need to add foo@2.x') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec --package=foo bar', async t => { - const path = t.testdir() - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - config.package = ['foo'] - flatOptions.package = ['foo'] - await exec.exec(['bar', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'bar' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('npm exec @foo/bar -- --some=arg, locally installed', async t => { - const foobarManifest = { - name: '@foo/bar', - version: '1.2.3', - bin: { - foo: 'foo', - bar: 'bar', - }, - } - const path = t.testdir({ - node_modules: { - '@foo/bar': { - 'package.json': JSON.stringify(foobarManifest), - }, - }, - }) - const pkg = { - name: '@foo/bar', - version: '1.2.3', - bin: { foo: 'foo', bar: 'bar' }, - } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS['@foo/bar'] = foobarManifest - await exec.exec(['@foo/bar', '--some=arg']) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'bar' } }, - args: ['--some=arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test( - 'npm exec @foo/bar, with same bin alias and no unscoped named bin, locally installed', - async t => { - const pkg = { - name: '@foo/bar', - version: '1.2.3', - bin: { - baz: 'corge', // pick the first one - qux: 'corge', - quux: 'corge', - }, - } - const path = t.testdir({ - node_modules: { - '@foo/bar': { - 'package.json': JSON.stringify(pkg), - }, - }, - }) - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS['@foo/bar'] = pkg - await exec.exec(['@foo/bar', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'baz' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) - } -) - -t.test( - 'npm exec @foo/bar, with different bin alias and no unscoped named bin, locally installed', - async t => { - const path = t.testdir() - const pkg = { - name: '@foo/bar', - version: '1.2.3.', - bin: { foo: 'qux', corge: 'qux', baz: 'quux' }, - } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ - ...pkg, - package: pkg, - pkgid: `${pkg.name}@${pkg.version}`, - }]) - }, - }, - } - MANIFESTS['@foo/bar'] = { - name: '@foo/bar', - version: '1.2.3', - bin: { - foo: 'qux', - corge: 'qux', - baz: 'quux', - }, - _from: 'foo@', - _id: '@foo/bar@1.2.3', - } - await t.rejects(exec.exec(['@foo/bar']), { - message: 'could not determine executable to run', - pkgid: '@foo/bar@1.2.3', - }) - } -) - -t.test('run command with 2 packages, need install, verify sort', async t => { - // test both directions, should use same install dir both times - // also test the read() call here, verify that the prompts match - const cases = [ - ['foo', 'bar'], - ['bar', 'foo'], - ] - t.plan(cases.length) - for (const packages of cases) { - t.test(packages.join(', '), async t => { - config.package = packages - const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b, 'en')) - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', - }, - _from: 'bar@', - } - await exec.exec(['foobar', 'one arg', 'two arg']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add, legacyPeerDeps: false }], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foobar' } }, - args: ['one arg', 'two arg'], - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) - }) - } -}) - -t.test('npm exec foo, no bin in package', async t => { - const pkg = { name: 'foo', version: '1.2.3' } - const path = t.testdir({ - node_modules: { - foo: { - 'package.json': JSON.stringify(pkg), - }, - }, - }) - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ - ...pkg, - package: pkg, - pkgid: `${pkg.name}@${pkg.version}`, - }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - _from: 'foo@', - _id: 'foo@1.2.3', - } - await t.rejects(exec.exec(['foo']), { - message: 'could not determine executable to run', - pkgid: 'foo@1.2.3', - }) -}) - -t.test('npm exec foo, many bins in package, none named foo', async t => { - const path = t.testdir() - const pkg = { - name: 'foo', - version: '1.2.3', - bin: { bar: 'bar', baz: 'baz' }, - } - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ - ...pkg, - package: pkg, - pkgid: `${pkg.name}@${pkg.version}`, - }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - bar: 'bar', - baz: 'baz', - }, - _from: 'foo@', - _id: 'foo@1.2.3', - } - await t.rejects(exec.exec(['foo']), { - message: 'could not determine executable to run', - pkgid: 'foo@1.2.3', - }) -}) - -t.test('npm exec -p foo -c "ls -laF"', async t => { - const path = t.testdir() - const pkg = { name: 'foo', version: '1.2.3' } - npm.localPrefix = path - config.package = ['foo'] - config.call = 'ls -laF' - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - _from: 'foo@', - } - await exec.exec([]) - t.strictSame(MKDIRPS, [], 'no need to make any dirs') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no need to reify anything') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'ls -laF' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH: process.env.PATH }, - stdio: 'inherit', - }, - ]) -}) - -t.test('positional args and --call together is an error', async t => { - config.call = 'true' - await t.rejects(exec.exec(['foo']), exec.usage) -}) - -t.test('prompt when installs are needed if not already present and shell is a TTY', async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' - }) - process.stdout.isTTY = true - process.stdin.isTTY = true - CI_NAME = false - - const packages = ['foo', 'bar'] - READ_RESULT = 'yolo' - - config.package = packages - config.yes = undefined - - const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b, 'en')) - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', +t.test('call with args', async t => { + const { npm } = await loadMockNpm(t, { + config: { + call: 'foo', }, - _from: 'bar@', - } - await exec.exec(['foobar']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add, legacyPeerDeps: false }], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) - t.strictSame(READ, [ - { - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }, - ]) -}) - -t.test( - /* eslint-disable-next-line max-len */ - 'skip prompt when installs are needed if not already present and shell is not a tty (multiple packages)', - async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' - }) - process.stdout.isTTY = false - process.stdin.isTTY = false - CI_NAME = false - - const packages = ['foo', 'bar'] - READ_RESULT = 'yolo' - - config.package = packages - config.yes = undefined - - const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b, 'en')) - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', - }, - _from: 'bar@', - } - await exec.exec(['foobar']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add, legacyPeerDeps: false }], 'need to install both packages') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) - t.strictSame(READ, [], 'should not have prompted') - t.strictSame( - LOG_WARN, - [['exec', 'The following packages were not found and will be installed: bar, foo']], - 'should have printed a warning' - ) - } -) - -t.test( - /* eslint-disable-next-line max-len */ - 'skip prompt when installs are needed if not already present and shell is not a tty (single package)', - async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' - }) - process.stdout.isTTY = false - process.stdin.isTTY = false - CI_NAME = false - - const packages = ['foo'] - READ_RESULT = 'yolo' - - config.package = packages - config.yes = undefined - - const add = packages.map(p => `${p}@`).sort((a, b) => a.localeCompare(b, 'en')) - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - await exec.exec(['foobar']) - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.match(ARB_REIFY, [{ add, legacyPeerDeps: false }], 'need to install the package') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foobar' } }, - banner: false, - path: process.cwd(), - stdioString: true, - event: 'npx', - env: { PATH }, - stdio: 'inherit', - }, - ]) - t.strictSame(READ, [], 'should not have prompted') - t.strictSame( - LOG_WARN, - [['exec', 'The following package was not found and will be installed: foo']], - 'should have printed a warning' - ) - } -) - -t.test('abort if prompt rejected', async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' }) - process.stdout.isTTY = true - process.stdin.isTTY = true - CI_NAME = false - - const packages = ['foo', 'bar'] - READ_RESULT = 'no, why would I want such a thing??' - config.package = packages - config.yes = undefined - - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', - }, - _from: 'bar@', - } - await t.rejects(exec.exec(['foobar']), /canceled/, 'should be canceled') - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, [ - { - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }, - ]) + await t.rejects( + npm.exec('exec', ['bar']), + { code: 'EUSAGE' } + ) }) -t.test('abort if prompt false', async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' +t.test('registry package', async t => { + const registry = new MockRegistry({ + tap: t, + registry: 'https://registry.npmjs.org/', }) - process.stdout.isTTY = true - process.stdin.isTTY = true - CI_NAME = false - - const packages = ['foo', 'bar'] - READ_ERROR = 'canceled' - config.package = packages - config.yes = undefined + const manifest = registry.manifest({ name: '@npmcli/npx-test' }) + manifest.versions['1.0.0'].bin = { 'npx-test': 'index.js' } - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, + const { npm } = await loadMockNpm(t, { + config: { + yes: true, }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() + prefixDir: { + 'npm-exec-test': { + 'package.json': JSON.stringify(manifest), + 'index.js': `#!/usr/bin/env node + require('fs').writeFileSync('npm-exec-test-success', '')`, }, }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', - }, - _from: 'bar@', - } - await t.rejects(exec.exec(['foobar']), 'canceled', 'should be canceled') - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, [ - { - prompt: 'Need to install the following packages:\n bar\n foo\nOk to proceed? ', - default: 'y', - }, - ]) -}) - -t.test('abort if -n provided', async t => { - const stdoutTTY = process.stdout.isTTY - const stdinTTY = process.stdin.isTTY - t.teardown(() => { - process.stdout.isTTY = stdoutTTY - process.stdin.isTTY = stdinTTY - CI_NAME = 'travis-ci' + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, + }), }) - process.stdout.isTTY = true - process.stdin.isTTY = true - CI_NAME = false - const packages = ['foo', 'bar'] + await registry.package({ + times: 2, + manifest, + tarballs: { + '1.0.0': path.join(npm.prefix, 'npm-exec-test'), + } }) - config.package = packages - config.yes = false - - const path = t.testdir() - const installDir = resolve('npx-cache-dir/07de77790e5f40f2') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - MANIFESTS.bar = { - name: 'bar', - version: '1.2.3', - bin: { - bar: 'bar', - }, - _from: 'bar@', - } - await t.rejects(exec.exec(['foobar']), /canceled/, 'should be canceled') - t.strictSame(MKDIRPS, [installDir], 'need to make install dir') - t.match(ARB_CTOR, [{ path }]) - t.strictSame(ARB_REIFY, [], 'no install performed') - t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') - t.strictSame(RUN_SCRIPTS, []) - t.strictSame(READ, []) -}) - -t.test('forward legacyPeerDeps opt', async t => { - const path = t.testdir() - const installDir = resolve('npx-cache-dir/f7fbba6e0636f890') - npm.localPrefix = path - ARB_ACTUAL_TREE[path] = { - inventory: { - query () { - return new Set() - }, - }, - } - ARB_ACTUAL_TREE[installDir] = { - inventory: { - query () { - return new Set() - }, - }, - } - MANIFESTS.foo = { - name: 'foo', - version: '1.2.3', - bin: { - foo: 'foo', - }, - _from: 'foo@', - } - config.yes = true - flatOptions.legacyPeerDeps = true - await exec.exec(['foo']) - t.match( - ARB_REIFY, - [{ add: ['foo@'], legacyPeerDeps: true }], - 'need to install foo@ using legacyPeerDeps opt' - ) + await npm.exec('exec', ['@npmcli/npx-test']) + const exists = await fs.stat(path.join(npm.prefix, 'npm-exec-test-success')) + t.ok(exists.isFile(), 'bin ran, creating file') }) t.test('workspaces', async t => { - npm.localPrefix = t.testdir({ - node_modules: { - '.bin': { - a: '', - foo: '', - }, - }, - packages: { - a: { + const registry = new MockRegistry({ + tap: t, + registry: 'https://registry.npmjs.org/', + }) + + const manifest = registry.manifest({ name: '@npmcli/npx-test' }) + manifest.versions['1.0.0'].bin = { 'npx-test': 'index.js' } + + const { npm } = await loadMockNpm(t, { + config: { + yes: true, + workspace: ['workspace-a'], + }, + prefixDir: { + 'npm-exec-test': { + 'package.json': JSON.stringify(manifest), + 'index.js': `#!/usr/bin/env node + require('fs').writeFileSync('npm-exec-test-success', '')`, + }, + 'package.json': JSON.stringify({ + name: '@npmcli/npx-workspace-test', + workspaces: ['workspace-a'], + }), + 'workspace-a': { 'package.json': JSON.stringify({ - name: 'a', - version: '1.0.0', - bin: 'cli.js', - }), - 'cli.js': '', - }, - b: { - 'package.json': JSON.stringify({ - name: 'b', - version: '1.0.0', + name: 'workspace-a', }), }, }, - 'package.json': JSON.stringify({ - name: 'root', - version: '1.0.0', - workspaces: ['packages/*'], + globals: ({ prefix }) => ({ + 'process.cwd': () => prefix, }), }) - const pkg = { name: 'foo', version: '1.2.3', bin: { foo: 'foo' } } - PROGRESS_IGNORED = true - npm.localBin = resolve(npm.localPrefix, 'node_modules', '.bin') - - // with arg matching existing bin, run scripts in the context of a workspace - await exec.execWorkspaces(['foo', 'one arg', 'two arg'], ['a', 'b']) - - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: npm.localPrefix, - stdioString: true, - event: 'npx', - env: { - PATH: [npm.localBin, process.env.PATH].join(delimiter), - }, - stdio: 'inherit', - }, - { - pkg: { scripts: { npx: 'foo' } }, - args: ['one arg', 'two arg'], - banner: false, - path: npm.localPrefix, - stdioString: true, - event: 'npx', - env: { - PATH: [npm.localBin, process.env.PATH].join(delimiter), - }, - stdio: 'inherit', - }, - ], 'should run with multiple args across multiple workspaces') - - // clean up - RUN_SCRIPTS.length = 0 - - // with packages, run scripts in the context of a workspace - config.package = ['foo'] - config.call = 'foo' - config.yes = false - - ARB_ACTUAL_TREE[npm.localPrefix] = { - inventory: { - query () { - return new Set([{ ...pkg, package: pkg }]) - }, - }, - } - - await exec.execWorkspaces([], ['a', 'b']) - - // path should point to the workspace folder - t.match(RUN_SCRIPTS, [ - { - pkg: { scripts: { npx: 'foo' } }, - args: [], - banner: false, - path: resolve(npm.localPrefix, 'packages', 'a'), - stdioString: true, - event: 'npx', - stdio: 'inherit', - }, - { - pkg: { scripts: { npx: 'foo' } }, - args: [], - banner: false, - path: resolve(npm.localPrefix, 'packages', 'b'), - stdioString: true, - event: 'npx', - stdio: 'inherit', - }, - ], 'should run without args in multiple workspaces') - - t.match(ARB_CTOR, [ - { path: npm.localPrefix }, - { path: npm.localPrefix }, - ]) - - // no args, spawn interactive shell - CI_NAME = null - config.package = [] - config.call = '' - process.stdin.isTTY = true - - await exec.execWorkspaces([], ['a']) - - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, - [ - [ - `\nEntering npm script environment in workspace a@1.0.0 at location:\n${resolve( - npm.localPrefix, - 'packages/a' - )}\nType 'exit' or ^D when finished\n`, - ], - ], - 'printed message about interactive shell' - ) - - npm.color = true - flatOptions.color = true - npm._mockOutputs.length = 0 - await exec.execWorkspaces([], ['a']) - - t.strictSame(LOG_WARN, []) - t.strictSame( - npm._mockOutputs, - [ - [ - /* eslint-disable-next-line max-len */ - `\u001b[0m\u001b[0m\n\u001b[0mEntering npm script environment\u001b[0m\u001b[0m in workspace \u001b[32ma@1.0.0\u001b[39m at location:\u001b[0m\n\u001b[0m\u001b[2m${resolve( - npm.localPrefix, - 'packages/a' - /* eslint-disable-next-line max-len */ - )}\u001b[22m\u001b[0m\u001b[1m\u001b[22m\n\u001b[1mType 'exit' or ^D when finished\u001b[22m\n\u001b[1m\u001b[22m`, - ], - ], - 'printed message about interactive shell' - ) + await registry.package({ manifest, + tarballs: { + '1.0.0': path.join(npm.prefix, 'npm-exec-test'), + } }) + await npm.exec('exec', ['@npmcli/npx-test']) + const exists = await fs.stat(path.join(npm.prefix, 'workspace-a', 'npm-exec-test-success')) + t.ok(exists.isFile(), 'bin ran, creating file inside workspace') }) diff --git a/deps/npm/test/lib/commands/ls.js b/deps/npm/test/lib/commands/ls.js index 412d5ce6532a04..f4cd4ef33d58e7 100644 --- a/deps/npm/test/lib/commands/ls.js +++ b/deps/npm/test/lib/commands/ls.js @@ -178,6 +178,44 @@ t.test('ls', t => { ) }) + t.test('workspace and missing optional dep', async t => { + npm.prefix = npm.localPrefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'root', + dependencies: { + foo: '^1.0.0', + }, + optionalDependencies: { + bar: '^1.0.0', + }, + workspaces: ['./baz'], + }), + baz: { + 'package.json': JSON.stringify({ + name: 'baz', + version: '1.0.0', + }), + }, + node_modules: { + baz: t.fixture('symlink', '../baz'), + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + }), + }, + }, + }) + + npm.flatOptions.includeWorkspaceRoot = true + t.teardown(() => { + delete npm.flatOptions.includeWorkspaceRoot + }) + + await ls.execWorkspaces([], ['baz']) + t.matchSnapshot(redactCwd(result), 'should omit missing optional dep') + }) + t.test('extraneous deps', async t => { npm.prefix = t.testdir({ 'package.json': JSON.stringify({ diff --git a/deps/npm/test/lib/commands/query.js b/deps/npm/test/lib/commands/query.js new file mode 100644 index 00000000000000..fb5b4843c34ee7 --- /dev/null +++ b/deps/npm/test/lib/commands/query.js @@ -0,0 +1,199 @@ +const t = require('tap') +const { load: loadMockNpm } = require('../../fixtures/mock-npm') + +t.cleanSnapshot = (str) => { + const normalizePath = p => p + .replace(/\\+/g, '/') + .replace(/\r\n/g, '\n') + return normalizePath(str) + .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}') + // normalize between windows and posix + .replace(new RegExp('lib/node_modules', 'g'), 'node_modules') +} + +t.test('simple query', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + node_modules: { + a: { + name: 'a', + version: '1.0.0', + }, + b: { + name: 'b', + version: '^2.0.0', + }, + }, + 'package.json': JSON.stringify({ + name: 'project', + dependencies: { + a: '^1.0.0', + b: '^1.0.0', + }, + peerDependencies: { + c: '1.0.0', + }, + }), + }, + }) + await npm.exec('query', [':root, :root > *']) + t.matchSnapshot(joinedOutput(), 'should return root object and direct children') +}) + +t.test('recursive tree', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + node_modules: { + a: { + name: 'a', + version: '1.0.0', + }, + b: { + name: 'b', + version: '^2.0.0', + dependencies: { + a: '1.0.0', + }, + }, + }, + 'package.json': JSON.stringify({ + name: 'project', + dependencies: { + a: '^1.0.0', + b: '^1.0.0', + }, + }), + }, + }) + await npm.exec('query', ['*']) + t.matchSnapshot(joinedOutput(), 'should return everything in the tree, accounting for recursion') +}) +t.test('workspace query', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + workspaces: ['c'], + }, + prefixDir: { + node_modules: { + a: { + name: 'a', + version: '1.0.0', + }, + b: { + name: 'b', + version: '^2.0.0', + }, + c: t.fixture('symlink', '../c'), + }, + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + }), + }, + 'package.json': JSON.stringify({ + name: 'project', + workspaces: ['c'], + dependencies: { + a: '^1.0.0', + b: '^1.0.0', + }, + }), + }, + }) + await npm.exec('query', [':scope'], ['c']) + t.matchSnapshot(joinedOutput(), 'should return workspace object') +}) + +t.test('include-workspace-root', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + 'include-workspace-root': true, + workspaces: ['c'], + }, + prefixDir: { + node_modules: { + a: { + name: 'a', + version: '1.0.0', + }, + b: { + name: 'b', + version: '^2.0.0', + }, + c: t.fixture('symlink', '../c'), + }, + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + }), + }, + 'package.json': JSON.stringify({ + name: 'project', + workspaces: ['c'], + dependencies: { + a: '^1.0.0', + b: '^1.0.0', + }, + }), + }, + }) + await npm.exec('query', [':scope'], ['c']) + t.matchSnapshot(joinedOutput(), 'should return workspace object and root object') +}) +t.test('linked node', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + node_modules: { + a: t.fixture('symlink', '../a'), + }, + a: { + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + }), + }, + 'package.json': JSON.stringify({ + name: 'project', + dependencies: { + a: 'file:./a', + }, + }), + }, + }) + await npm.exec('query', ['[name=a]']) + t.matchSnapshot(joinedOutput(), 'should return linked node res') +}) + +t.test('global', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + global: true, + }, + // This is a global dir that works in both windows and non-windows, that's + // why it has two node_modules folders + globalPrefixDir: { + node_modules: { + lorem: { + 'package.json': JSON.stringify({ + name: 'lorem', + version: '2.0.0', + }), + }, + }, + lib: { + node_modules: { + lorem: { + 'package.json': JSON.stringify({ + name: 'lorem', + version: '2.0.0', + }), + }, + }, + }, + }, + }) + await npm.exec('query', ['[name=lorem]']) + t.matchSnapshot(joinedOutput(), 'should return global package') +}) diff --git a/deps/npm/test/lib/utils/open-url-prompt.js b/deps/npm/test/lib/utils/open-url-prompt.js index 6908e36b7c81e3..03f6b596d7643e 100644 --- a/deps/npm/test/lib/utils/open-url-prompt.js +++ b/deps/npm/test/lib/utils/open-url-prompt.js @@ -28,6 +28,8 @@ const opener = (url, opts, cb) => { } let questionShouldResolve = true +let openUrlPromptInterrupted = false + const readline = { createInterface: () => ({ question: (_q, cb) => { @@ -36,6 +38,11 @@ const readline = { } }, close: () => {}, + on: (_signal, cb) => { + if (openUrlPromptInterrupted && _signal === 'SIGINT') { + cb() + } + }, }), } @@ -148,3 +155,25 @@ t.test('returns error when opener errors', async t => { ) t.equal(openerUrl, 'https://www.npmjs.com', 'did not open') }) + +t.test('throws "canceled" error on SIGINT', async t => { + t.teardown(() => { + openerUrl = null + openerOpts = null + OUTPUT.length = 0 + questionShouldResolve = true + openUrlPromptInterrupted = false + }) + + questionShouldResolve = false + openUrlPromptInterrupted = true + const emitter = new EventEmitter() + + const open = openUrlPrompt(npm, 'https://www.npmjs.com', 'npm home', 'prompt', emitter) + + try { + await open + } catch (err) { + t.equal(err.message, 'canceled') + } +})