Parse the things that can be arguments to `npm install`
npx @tessl/cli install tessl/npm-npm-package-arg@13.0.00
# npm-package-arg
1
2
npm-package-arg is a JavaScript library that parses package specifier strings used in npm commands like `npm install`. It supports various package specifier formats including version ranges, git repositories, URLs, local files and directories, scoped packages, and aliases, providing a standardized way to understand and manipulate npm package arguments.
3
4
## Package Information
5
6
- **Package Name**: npm-package-arg
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install npm-package-arg`
10
11
## Core Imports
12
13
```javascript
14
const npa = require('npm-package-arg');
15
```
16
17
For ES modules:
18
19
```javascript
20
import npa from 'npm-package-arg';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const npa = require('npm-package-arg');
27
28
// Parse a package specifier string
29
const result = npa('@scope/package@^1.2.3');
30
console.log(result.name); // '@scope/package'
31
console.log(result.type); // 'range'
32
console.log(result.fetchSpec); // '^1.2.3'
33
34
// Parse with explicit name and spec
35
const resolved = npa.resolve('lodash', '>=4.0.0');
36
console.log(resolved.name); // 'lodash'
37
console.log(resolved.type); // 'range'
38
console.log(resolved.fetchSpec); // '>=4.0.0'
39
40
// Convert to PURL format
41
const purl = npa.toPurl('express@4.18.2');
42
console.log(purl); // 'pkg:npm/express@4.18.2'
43
```
44
45
## Architecture
46
47
npm-package-arg is built around several key components:
48
49
- **Main Parser**: The `npa()` function that intelligently detects specifier types and routes to appropriate parsers
50
- **Specifier Types**: Supports registry packages, git repositories, URLs, files, directories, and aliases
51
- **Result Object**: Standardized output format with type, name, specs, and metadata
52
- **Validation Layer**: Package name and tag validation with specific error codes
53
- **Platform Handling**: Cross-platform path resolution and URL encoding
54
55
## Capabilities
56
57
### Package Argument Parsing
58
59
Parses package specifier strings into structured Result objects, automatically detecting the specifier type and extracting relevant information.
60
61
```javascript { .api }
62
/**
63
* Parse a package specifier string or Result object
64
* @param arg - Package specifier string or existing Result object
65
* @param where - Optional path to resolve file paths relative to (defaults to process.cwd())
66
* @returns Result object with parsed package information
67
* @throws Error for invalid package names, tags, or unsupported protocols
68
*/
69
function npa(arg, where);
70
```
71
72
### Explicit Package Resolution
73
74
Resolves a package name and specifier separately, useful when you have the name and version/range as separate values.
75
76
```javascript { .api }
77
/**
78
* Parse package name and specifier separately
79
* @param name - Package name (e.g., 'lodash' or '@scope/package')
80
* @param spec - Version specifier (e.g., '1.2.3', '^1.0.0', 'latest')
81
* @param where - Optional path to resolve file paths relative to (defaults to process.cwd())
82
* @returns Result object with parsed package information
83
* @throws Error for invalid package names, tags, or unsupported protocols
84
*/
85
npa.resolve = function(name, spec, where);
86
```
87
88
### PURL Conversion
89
90
Converts package arguments to Package URL (PURL) format, useful for package identification and registry operations.
91
92
```javascript { .api }
93
/**
94
* Convert package argument to PURL (Package URL) format
95
* @param arg - Package specifier string (must resolve to 'version' type)
96
* @param reg - Optional registry URL (defaults to https://registry.npmjs.org)
97
* @returns String in PURL format
98
* @throws Error for non-version types or invalid package names
99
*/
100
npa.toPurl = function(arg, reg);
101
```
102
103
### Result Object Constructor
104
105
Creates Result objects for representing parsed package specifiers with all relevant metadata.
106
107
```javascript { .api }
108
/**
109
* Result object constructor for parsed package specifiers
110
* @param opts - Configuration object with parsing options
111
*/
112
npa.Result = function Result(opts);
113
```
114
115
## Types
116
117
### Result Object
118
119
The core data structure returned by all parsing operations, containing comprehensive package information.
120
121
```javascript { .api }
122
class Result {
123
constructor(opts);
124
125
/** Package specifier type: 'git', 'tag', 'version', 'range', 'file', 'directory', 'remote', 'alias' */
126
type;
127
128
/** True if specifier refers to a registry resource (tag, version, range types) */
129
registry;
130
131
/** Package name (e.g., 'lodash', '@scope/package') */
132
name;
133
134
/** Scope for scoped packages (e.g., '@scope') or null */
135
scope;
136
137
/** URL-encoded version of name for registry requests */
138
escapedName;
139
140
/** Original specifier part from input */
141
rawSpec;
142
143
/** Normalized specifier for package.json (null for registry deps) */
144
saveSpec;
145
146
/** Specifier for fetching the resource (null for hosted git shortcuts) */
147
fetchSpec;
148
149
/** Original unmodified input string */
150
raw;
151
152
/** Base path for relative file resolution */
153
where;
154
155
/** Semver specifier for git tags */
156
gitRange;
157
158
/** Specific commit/branch/tag for git dependencies */
159
gitCommittish;
160
161
/** Subdirectory path for git repositories */
162
gitSubdir;
163
164
/** hosted-git-info object for hosted git dependencies */
165
hosted;
166
167
/** For alias type, contains the target specifier Result */
168
subSpec;
169
170
/**
171
* Set and validate package name
172
* @param name - Package name to set
173
* @returns this (for chaining)
174
* @throws Error for invalid package names
175
*/
176
setName(name);
177
178
/**
179
* Convert Result to string representation
180
* @returns String representation of the package specifier
181
*/
182
toString();
183
184
/**
185
* Convert Result to JSON-serializable object
186
* @returns Plain object (excludes hosted property)
187
*/
188
toJSON();
189
}
190
```
191
192
### Error Types
193
194
Custom error objects with specific error codes for different validation failures.
195
196
```javascript { .api }
197
/** Error codes thrown by npm-package-arg */
198
const ERROR_CODES = {
199
/** Invalid package name */
200
EINVALIDPACKAGENAME: 'EINVALIDPACKAGENAME',
201
/** Invalid tag name */
202
EINVALIDTAGNAME: 'EINVALIDTAGNAME',
203
/** Invalid PURL type */
204
EINVALIDPURLTYPE: 'EINVALIDPURLTYPE',
205
/** Unsupported URL protocol */
206
EUNSUPPORTEDPROTOCOL: 'EUNSUPPORTEDPROTOCOL'
207
};
208
```
209
210
## Supported Specifier Types
211
212
npm-package-arg recognizes and parses the following package specifier formats:
213
214
### Registry Packages
215
- **Version**: `foo@1.2.3` - Exact version number
216
- **Range**: `foo@^1.2.0`, `foo@~1.2.0` - Semantic version ranges
217
- **Tag**: `foo@latest`, `foo@beta` - Distribution tags
218
219
### Git Repositories
220
- **HTTPS**: `git+https://github.com/user/repo.git#branch`
221
- **SSH**: `git+ssh://git@github.com/user/repo.git#tag`
222
- **Hosted shortcuts**: `github:user/repo`, `bitbucket:user/repo`, `gitlab:user/repo`
223
224
### URLs and Files
225
- **Remote URLs**: `https://example.com/package.tgz`
226
- **Local files**: `file:./package.tgz`, `./local-package.tar.gz`
227
- **Local directories**: `file:../my-package`, `./packages/utils`
228
229
### Scoped Packages
230
- **Registry**: `@scope/package@1.0.0`
231
- **Git**: `@scope/package@github:user/repo`
232
233
### Aliases
234
- **Format**: `alias@npm:real-package@1.0.0`
235
- **Usage**: Create alternate names for packages
236
237
## Error Handling
238
239
All parsing functions can throw errors with specific error codes:
240
241
```javascript
242
try {
243
const result = npa('invalid-package-name-@#$');
244
} catch (error) {
245
if (error.code === 'EINVALIDPACKAGENAME') {
246
console.log('Invalid package name:', error.message);
247
}
248
}
249
250
// Error codes:
251
// EINVALIDPACKAGENAME - Invalid package name format
252
// EINVALIDTAGNAME - Invalid distribution tag
253
// EINVALIDPURLTYPE - PURL generation only works with version types
254
// EUNSUPPORTEDPROTOCOL - Unsupported URL protocol
255
```
256
257
## Usage Examples
258
259
### Parsing Different Specifier Types
260
261
```javascript
262
const npa = require('npm-package-arg');
263
264
// Registry package with version range
265
const semverRange = npa('lodash@^4.17.0');
266
console.log(semverRange.type); // 'range'
267
console.log(semverRange.fetchSpec); // '^4.17.0'
268
269
// Scoped package
270
const scoped = npa('@babel/core@7.20.0');
271
console.log(scoped.scope); // '@babel'
272
console.log(scoped.name); // '@babel/core'
273
console.log(scoped.type); // 'version'
274
275
// Git repository
276
const gitRepo = npa('git+https://github.com/lodash/lodash.git#4.17.21');
277
console.log(gitRepo.type); // 'git'
278
console.log(gitRepo.gitCommittish); // '4.17.21'
279
280
// Local file
281
const localFile = npa('./packages/my-util-1.0.0.tgz');
282
console.log(localFile.type); // 'file'
283
console.log(localFile.fetchSpec); // Absolute path to file
284
285
// Alias
286
const alias = npa('my-lodash@npm:lodash@4.17.21');
287
console.log(alias.type); // 'alias'
288
console.log(alias.subSpec.name); // 'lodash'
289
console.log(alias.subSpec.fetchSpec); // '4.17.21'
290
```
291
292
### Working with Result Objects
293
294
```javascript
295
const npa = require('npm-package-arg');
296
297
const result = npa('@vue/cli@latest');
298
299
// Check if it's a registry package
300
if (result.registry) {
301
console.log('Registry package:', result.name);
302
}
303
304
// Get string representation
305
console.log('String form:', result.toString()); // '@vue/cli@latest'
306
307
// Convert to JSON
308
const json = result.toJSON();
309
console.log('JSON:', JSON.stringify(json, null, 2));
310
311
// Generate PURL (only works with version types)
312
try {
313
const purl = npa.toPurl('express@4.18.2');
314
console.log('PURL:', purl); // 'pkg:npm/express@4.18.2'
315
} catch (error) {
316
console.log('Cannot generate PURL:', error.message);
317
}
318
```
319
320
### File Path Resolution
321
322
```javascript
323
const path = require('path');
324
const npa = require('npm-package-arg');
325
326
// Resolve relative to specific directory
327
const basePath = '/project/root';
328
const result = npa('./packages/utils', basePath);
329
330
console.log('Resolved path:', result.fetchSpec);
331
console.log('Save spec:', result.saveSpec); // Relative path for package.json
332
```