meta_package_manager.managers.npm module¶

class meta_package_manager.managers.npm.NPM[source]¶

Bases: PackageManager

The Node.js package manager.

mpm drives npm in global mode: every call forces --global so packages land in the shared prefix instead of the current working directory. Per-scope targeting and multi-binary discovery (several node versions through nvm) are tracked in #1725. Command equivalences with the sibling JS managers are listed in antfu-collective/ni.

Queries parse npm’s --json output. Mutating operations are marked privileged so --sudo can escalate writes into a root-owned global prefix, though escalation stays dormant unless requested.

Note

npm enforces a supply-chain cooldown through its min-release-age resolver option, refusing to resolve any release younger than the configured age. The version floor exists for it: min-release-age first shipped in 11.10.0, and older releases silently ignore the setting.

Caution

A fatal npm error (usually a local node version out of sync) is reported both on <stderr> and as a JSON blob on <stdout>. The run_cli override blanks that JSON so the failure surfaces once, through <stderr>, rather than being parsed as a package listing.

Initialize cli_errors list.

name: str = 'Node npm'¶

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.npmjs.com'¶

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'npm'¶

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})¶

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=11.10.0'¶

11.10.0 is the first version to ship min-release-age, the purpose-built release-age gate mpm uses for the supply-chain cooldown (see cooldown_env_var). Older npm releases silently ignore the env var, so the floor avoids advertising a gate that does nothing.

cooldown_env_var: ClassVar[str | None] = 'npm_config_min-release-age'¶

npm honors a release-age cooldown through its min-release-age resolver option.

npm maps any npm_config_<key> environment variable to a config setting, so npm_config_min-release-age sets min-release-age without touching the user’s .npmrc. Once set, npm refuses to resolve any package version younger than the configured age, which covers install and update along with their transitive dependencies. The hyphenated env var passes cleanly through Python’s subprocess.Popen env= mapping (shells that reject export foo-bar=baz are not involved).

The cooldown_env_value() method below is overridden to emit an integer number of days, the unit min-release-age expects.

See npm’s min-release-age config.

pre_args: tuple[str, ...] = ('--global', '--no-progress', '--no-update-notifier', '--no-fund', '--no-audit')¶
$ npm --version
6.13.7
cooldown_env_value()[source]¶

Render meta_package_manager.execution.CLIExecutor.cooldown as an integer day count for npm’s min-release-age.

Sub-day cooldowns round up so the gate over-protects rather than silently collapses to 0 (the “no cooldown” sentinel).

Return type:

str

run_cli(*args, **kwargs)[source]¶

Like the common run_cli helper, but silence NPM’s JSON output on error.

NPM is prone to breakage if local node version is not in sync:

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json outdated
{
  "error": {
    "code": "ERR_OUT_OF_RANGE",
    "summary": "The value of "err" is out of range. Received 536870212",
    "detail": ""
  }
}
Return type:

str

property installed: Iterator[Package]¶

Fetch installed packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json --depth 0 list
{
  "name": "lib",
  "dependencies": {
    "@eslint/json": {
      "version": "0.9.0",
      "overridden": false
    },
    "@mermaid-js/mermaid-cli": {
      "version": "10.8.0",
      "overridden": false
    },
    "corepack": {
      "version": "0.30.0",
      "overridden": false
    },
    "google-closure-compiler": {
      "version": "20240317.0.0",
      "overridden": false
    },
    "npm": {
      "version": "10.9.2",
      "overridden": false
    },
    "raven": {
      "version": "2.6.4",
      "overridden": false
    },
    "wrangler": {
      "version": "3.51.2",
      "overridden": false
    }
  }
}
property outdated: Iterator[Package]¶

Fetch outdated packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json outdated
{
  "my-linked-package": {
    "current": "0.0.0-development",
    "wanted": "linked",
    "latest": "linked",
    "location": "/Users/kev/dev/my-linked-package"
  },
  "npm": {
    "current": "3.10.3",
    "wanted": "3.10.5",
    "latest": "3.10.5",
    "location": "/opt/homebrew/lib/node_modules/npm"
  }
}
search(query, extended, exact)[source]¶

Fetch matching packages.

Doc: npm search.

Caution

Search does not supports exact matching.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             search --json python | jq
[
  {
    "name": "python",
    "description": "Interact with a python child process",
    "maintainers": [
      {
        "username": "drderidder",
        "email": "[email protected]"
      }
    ],
    "version": "0.0.4",
    "date": "2015-01-25T02:48:07.820Z"
  },
  {
    "name": "raven",
    "description": "A standalone (Node.js) client for Sentry",
    "maintainers": [
      {
        "username": "benvinegar",
        "email": "[email protected]"
      },
      {
        "username": "lewisjellis",
        "email": "[email protected]"
      },
      {
        "username": "mattrobenolt",
        "email": "[email protected]"
      },
      {
        "username": "zeeg",
        "email": "[email protected]"
      }
    ],
    "keywords": [
      "raven",
      "sentry",
      "python",
      "errors",
      "debugging",
      "exceptions"
    ],
    "version": "1.1.2",
    "date": "2017-02-09T02:54:07.723Z"
  },
  {
    "name": "brush-python",
    "description": "Python brush module for SyntaxHighlighter.",
    "maintainers": [
      {
        "username": "alexgorbatchev",
        "email": "[email protected]"
      }
    ],
    "keywords": [
      "syntaxhighlighter",
      "brush",
      "python"
    ],
    "version": "4.0.0",
    "date": "2016-02-07T21:32:39.597Z"
  },
  (...)
]
$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             search --json --no-description python | jq
Return type:

Iterator[Package]

install(package_id, version=None)[source]¶

Install one package.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             install markdown

added 3 packages in 3s
Return type:

str

upgrade_all_cli()[source]¶

Generates the CLI to upgrade all outdated packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]¶

Generates the CLI to upgrade the package provided as parameter.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             upgrade raven
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('npm',)¶

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'npm'¶

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]¶

Remove one package and one only.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             uninstall raven
Return type:

str

virtual: bool = False¶

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]¶

Removes things we don’t need anymore.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             cache clean --force
Return type:

None

doctor_cli()[source]¶

Generates the CLI running the native self-diagnosis.

doctor checks the registry connectivity, the node and npm versions, the ownership of the global folders and the cache checksums, exiting non-zero when any check fails.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             doctor
Return type:

tuple[str, ...]