npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vltpkg/spec

v0.0.0-0.1730724342581

Published

Package specifier library

Downloads

9

Readme

spec

@vltpkg/spec

This is a library for parsing package specifiers.

Namings · Specifiers · Usage · Properties

Overview

Specifiers are primarily used in the following cases:

  • On the command line, like vlt add [email protected]
  • In manifests (such as package.json) where dependencies are listed, like "dependencies": { "foo": "1.x" }
  • Internally within vlt, such as lockfiles and so on.

Named vs Unnamed

A "named" specifier is one with the full name included, separated from the specifier by a @ character, such as [email protected] or @vltpkg/[email protected]. The name in these cases would be foo and @vltpkg/spec, respectively.

Note that it does not always correspond to the "name" in the manifest of the resolved package! For example, foo@npm:react@latest would resolve to the latest version of react, but would be named foo in the dependency graph, and loaded as import('foo').

Types of Specifiers

The following specifier types are supported:

  • workspace:... - Provide a semver range, or one of ~, *, or ^ to match against a dependency that exists in a workspace project of a monorepo. The package name must exist as a workspace project in the monorepo. If a semver range is provided, then it must match the referenced workspace package version. Otherwise:

    • * - Fill in whatever version is in the workspace, without any prefix. So, if ./packages/foo depends on bar@workspace*, and bar is version 1.2.3, then foo will be published with { "dependencies": { "bar": "1.2.3" }}
    • ~ or ^ - Publish with the version found in the monorepo, prefixed by the character. So in the example above, it'd be bar@~1.2.3 or bar@^1.2.3, respectively.
  • semver range - A valid semver range (including the empty string or a single semver version). This is resolved against the default registry. If the spec is a valid semver range, then no further parsing is done.

  • git+ssh://<url>[selector] or git+https://<url>[selector] - A git+ssh or git+https url will be checked out by git. If no 'git selector' is provided, then it will attempt to install from the default version. The git selector can be:

    • #committish Any valid committish value will be checked out. So, shasum, branch, tag, etc., would all work.
    • #semver:<range> If a semver range is provided, it will select over all the tags that are valid semver versions, and pick the highest version number that satisfies the range.
    • Additional fields can be specified by a ::-separated series of key:value pairs. Currently only path:<path in repo> is supported, for referencing packages living below the root of the repository, as in a monorepo. For example, tcompare@github:tapjs/tapjs#bf457f24::path:src/tcompare
  • https://some-host.com/path/to/file.tgz - An https or http URL to a tarball will resolve to itself.

  • file:///path/to/file - A file URL will resolve to itself. If it is a directory, it will be reified as a symbolic link to the folder specified. If it is a file, it will be treated as a tarball that gets unpacked into place. Relative paths are resolved from the package with the dependency.

  • registry:<registry url>#<name>[@version range or dist-tag] - This will use the specified registry url, and look up the name and version on that registry.

  • If a registry shorthand is defined in the options, then you can use it as an alias for that registry. Currently, the only shorthand that is enabled by default is npm:<name>[@version-range] as a shorthand for registry:https://registry.npmjs.org/#<name>[@version-range].

  • If a git repository shorthand is defined in the options, then you can use that shorthand prefix as an alias for that git host. Currently, github:, bitbucket:, gitlab:, and gist: are supported by default.

  • Anything else will be treated as a dist-tag in the registry packument. For example, foo@latest or blah@legacy-v2

Usage

import { Spec, type SpecOptions } from '@vltpkg/spec'

// optional: create some registry shorthands
const opts: SpecOptions = {
  registries: {
    // internal company registry or something
    acmereg: 'https://dev.acme.internal/npm',
  },
  gitHosts: {
    github: 'git+ssh://[email protected]:$1/$2',
    // the $# pieces here are replaced by the path-separated
    // portions, so eg `github:user/project#whatever
    acmegit: 'git+ssh://[email protected]/git/$1/$2/$3',
  }
}

const lodash = Spec.parse('lodash@latest')
// which is the same as:
const lodash = Spec.parse('lodash@npm:lodash@latest')
// which is the same as:
const lodash = Spec.parse(
  'lodash@registry:https://registry.npmjs.org/#lodash@latest'
)

// pull from github
const ghProject = Spec.parse('abbrev@github:npm/abbrev-js#main', opts)

// pull from our internal hosts using the acme shorthand names
const fooFromAcmeReg = Spec.parse('foo@acmereg:[email protected]', opts)
const fooFromAcmeReg = Spec.parse(
  'foo@acmegit:department/team/monorepo#main;directory:packages/foo',
  opts,
)

Properties

  • type - the type of spec that this is. One of 'registry', 'git', 'file', or 'remote'.
  • spec - the full named specifier passed to the constructor
  • options - options passed to the constructor, plus defaults
  • name - the name portion, so foo in [email protected]
  • bareSpec - just the part AFTER the name, so 1.x in [email protected]
  • when type === 'git':
    • gitRemote - git remote url
    • gitSelector - the ::-separated set of key:value fields
    • gitSelectorParsed - the gitSelector parsed into a Record object
    • gitCommittish - the commit sha, branch, or tag
    • namedGitHost - github, gitlab, bitbucket, etc.
    • remoteURL - when using a named git host with an archive url template, and a committish is provided, this is the url to download a tarball archive
    • semver - the semver range, if provided in the gitSelector
    • range - the parsed semver range, if valid
  • when type === 'registry':
    • registry - the registry to look up data from
    • namedRegistry - in the case of alias specs, the named registry
    • registrySpec - the semver range or dist-tag
    • semver - the semver range, if valid
    • range - the parsed semver range, if valid
    • distTag - the registrySpec when it is not a semver range
    • subspec - the parsed spec to to be resolved against the registry in question, if the spec is a named registry like npm:[email protected] or an explicit registry url like registry:https://registry.npmjs.org#[email protected].
  • when type === 'file':
    • file - the path on disk to find the package
  • when type === 'remote':
    • remoteURL - the url to the remote archive