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/foodepends onbar@workspace*, andbaris version1.2.3, thenfoowill 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 bebar@~1.2.3orbar@^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]orgit+https://<url>[selector]- Agit+sshorgit+httpsurl 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:#committishAny validcommittishvalue 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 ofkey:valuepairs. Currently onlypath:<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 forregistry: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:, andgist:are supported by default. -
Anything else will be treated as a
dist-tagin the registry packument. For example,foo@latestorblah@legacy-v2
Usage
import { Spec, type SpecOptions } from '@vltpkg/spec'
// optional: create some registry shorthandsconst opts: SpecOptions = { registries: { // internal company registry or something acmereg: 'https://dev.acme.internal/npm', }, gitHosts: { // the $# pieces here are replaced by the path-separated // portions, so eg `github:user/project#whatever }}
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 githubconst ghProject = Spec.parse('abbrev@github:npm/abbrev-js#main', opts)
// pull from GitHub package registryconst ghPackage = Spec.parse( '@octocat/hello-world', opts,)
// pull from our internal hosts using the acme shorthand namesconst 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
fooin[email protected] - bareSpec - just the part AFTER the name, so
1.xin[email protected] - when
type==='git':- gitRemote - git remote url
- gitSelector - the
::-separated set ofkey:valuefields - gitSelectorParsed - the
gitSelectorparsed 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 likeregistry: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