@vltpkg/spec
v0.0.0-0.1730724342581
Published
Package specifier library
Downloads
9
Keywords
Readme
@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 onbar@workspace*
, andbar
is version1.2.3
, thenfoo
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 bebar@~1.2.3
orbar@^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+ssh
orgit+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 validcommittish
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 ofkey:value
pairs. 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-tag
in the registry packument. For example,foo@latest
orblah@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 ofkey: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 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