or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-npm-package-arg

Parse the things that can be arguments to `npm install`

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/npm-package-arg@13.0.x

To install, run

npx @tessl/cli install tessl/npm-npm-package-arg@13.0.0

index.mddocs/

npm-package-arg

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.

Package Information

  • Package Name: npm-package-arg
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install npm-package-arg

Core Imports

const npa = require('npm-package-arg');

For ES modules:

import npa from 'npm-package-arg';

Basic Usage

const npa = require('npm-package-arg');

// Parse a package specifier string
const result = npa('@scope/package@^1.2.3');
console.log(result.name);      // '@scope/package'
console.log(result.type);      // 'range'
console.log(result.fetchSpec); // '^1.2.3'

// Parse with explicit name and spec
const resolved = npa.resolve('lodash', '>=4.0.0');
console.log(resolved.name);      // 'lodash'
console.log(resolved.type);      // 'range'
console.log(resolved.fetchSpec); // '>=4.0.0'

// Convert to PURL format
const purl = npa.toPurl('express@4.18.2');
console.log(purl); // 'pkg:npm/express@4.18.2'

Architecture

npm-package-arg is built around several key components:

  • Main Parser: The npa() function that intelligently detects specifier types and routes to appropriate parsers
  • Specifier Types: Supports registry packages, git repositories, URLs, files, directories, and aliases
  • Result Object: Standardized output format with type, name, specs, and metadata
  • Validation Layer: Package name and tag validation with specific error codes
  • Platform Handling: Cross-platform path resolution and URL encoding

Capabilities

Package Argument Parsing

Parses package specifier strings into structured Result objects, automatically detecting the specifier type and extracting relevant information.

/**
 * Parse a package specifier string or Result object
 * @param arg - Package specifier string or existing Result object
 * @param where - Optional path to resolve file paths relative to (defaults to process.cwd())
 * @returns Result object with parsed package information
 * @throws Error for invalid package names, tags, or unsupported protocols
 */
function npa(arg, where);

Explicit Package Resolution

Resolves a package name and specifier separately, useful when you have the name and version/range as separate values.

/**
 * Parse package name and specifier separately
 * @param name - Package name (e.g., 'lodash' or '@scope/package')
 * @param spec - Version specifier (e.g., '1.2.3', '^1.0.0', 'latest')
 * @param where - Optional path to resolve file paths relative to (defaults to process.cwd())
 * @returns Result object with parsed package information
 * @throws Error for invalid package names, tags, or unsupported protocols
 */
npa.resolve = function(name, spec, where);

PURL Conversion

Converts package arguments to Package URL (PURL) format, useful for package identification and registry operations.

/**
 * Convert package argument to PURL (Package URL) format
 * @param arg - Package specifier string (must resolve to 'version' type)
 * @param reg - Optional registry URL (defaults to https://registry.npmjs.org)
 * @returns String in PURL format
 * @throws Error for non-version types or invalid package names
 */
npa.toPurl = function(arg, reg);

Result Object Constructor

Creates Result objects for representing parsed package specifiers with all relevant metadata.

/**
 * Result object constructor for parsed package specifiers
 * @param opts - Configuration object with parsing options
 */
npa.Result = function Result(opts);

Types

Result Object

The core data structure returned by all parsing operations, containing comprehensive package information.

class Result {
  constructor(opts);
  
  /** Package specifier type: 'git', 'tag', 'version', 'range', 'file', 'directory', 'remote', 'alias' */
  type;
  
  /** True if specifier refers to a registry resource (tag, version, range types) */
  registry;
  
  /** Package name (e.g., 'lodash', '@scope/package') */
  name;
  
  /** Scope for scoped packages (e.g., '@scope') or null */
  scope;
  
  /** URL-encoded version of name for registry requests */
  escapedName;
  
  /** Original specifier part from input */
  rawSpec;
  
  /** Normalized specifier for package.json (null for registry deps) */
  saveSpec;
  
  /** Specifier for fetching the resource (null for hosted git shortcuts) */
  fetchSpec;
  
  /** Original unmodified input string */
  raw;
  
  /** Base path for relative file resolution */
  where;
  
  /** Semver specifier for git tags */
  gitRange;
  
  /** Specific commit/branch/tag for git dependencies */
  gitCommittish;
  
  /** Subdirectory path for git repositories */
  gitSubdir;
  
  /** hosted-git-info object for hosted git dependencies */
  hosted;
  
  /** For alias type, contains the target specifier Result */
  subSpec;
  
  /**
   * Set and validate package name
   * @param name - Package name to set
   * @returns this (for chaining)
   * @throws Error for invalid package names
   */
  setName(name);
  
  /**
   * Convert Result to string representation
   * @returns String representation of the package specifier
   */
  toString();
  
  /**
   * Convert Result to JSON-serializable object
   * @returns Plain object (excludes hosted property)
   */
  toJSON();
}

Error Types

Custom error objects with specific error codes for different validation failures.

/** Error codes thrown by npm-package-arg */
const ERROR_CODES = {
  /** Invalid package name */
  EINVALIDPACKAGENAME: 'EINVALIDPACKAGENAME',
  /** Invalid tag name */
  EINVALIDTAGNAME: 'EINVALIDTAGNAME', 
  /** Invalid PURL type */
  EINVALIDPURLTYPE: 'EINVALIDPURLTYPE',
  /** Unsupported URL protocol */
  EUNSUPPORTEDPROTOCOL: 'EUNSUPPORTEDPROTOCOL'
};

Supported Specifier Types

npm-package-arg recognizes and parses the following package specifier formats:

Registry Packages

  • Version: foo@1.2.3 - Exact version number
  • Range: foo@^1.2.0, foo@~1.2.0 - Semantic version ranges
  • Tag: foo@latest, foo@beta - Distribution tags

Git Repositories

  • HTTPS: git+https://github.com/user/repo.git#branch
  • SSH: git+ssh://git@github.com/user/repo.git#tag
  • Hosted shortcuts: github:user/repo, bitbucket:user/repo, gitlab:user/repo

URLs and Files

  • Remote URLs: https://example.com/package.tgz
  • Local files: file:./package.tgz, ./local-package.tar.gz
  • Local directories: file:../my-package, ./packages/utils

Scoped Packages

  • Registry: @scope/package@1.0.0
  • Git: @scope/package@github:user/repo

Aliases

  • Format: alias@npm:real-package@1.0.0
  • Usage: Create alternate names for packages

Error Handling

All parsing functions can throw errors with specific error codes:

try {
  const result = npa('invalid-package-name-@#$');
} catch (error) {
  if (error.code === 'EINVALIDPACKAGENAME') {
    console.log('Invalid package name:', error.message);
  }
}

// Error codes:
// EINVALIDPACKAGENAME - Invalid package name format
// EINVALIDTAGNAME - Invalid distribution tag  
// EINVALIDPURLTYPE - PURL generation only works with version types
// EUNSUPPORTEDPROTOCOL - Unsupported URL protocol

Usage Examples

Parsing Different Specifier Types

const npa = require('npm-package-arg');

// Registry package with version range
const semverRange = npa('lodash@^4.17.0');
console.log(semverRange.type);      // 'range'
console.log(semverRange.fetchSpec); // '^4.17.0'

// Scoped package
const scoped = npa('@babel/core@7.20.0');
console.log(scoped.scope);      // '@babel'
console.log(scoped.name);       // '@babel/core'
console.log(scoped.type);       // 'version'

// Git repository
const gitRepo = npa('git+https://github.com/lodash/lodash.git#4.17.21');
console.log(gitRepo.type);           // 'git'
console.log(gitRepo.gitCommittish);  // '4.17.21'

// Local file
const localFile = npa('./packages/my-util-1.0.0.tgz');
console.log(localFile.type);      // 'file'
console.log(localFile.fetchSpec); // Absolute path to file

// Alias
const alias = npa('my-lodash@npm:lodash@4.17.21');
console.log(alias.type);              // 'alias'
console.log(alias.subSpec.name);      // 'lodash'
console.log(alias.subSpec.fetchSpec); // '4.17.21'

Working with Result Objects

const npa = require('npm-package-arg');

const result = npa('@vue/cli@latest');

// Check if it's a registry package
if (result.registry) {
  console.log('Registry package:', result.name);
}

// Get string representation
console.log('String form:', result.toString()); // '@vue/cli@latest'

// Convert to JSON
const json = result.toJSON();
console.log('JSON:', JSON.stringify(json, null, 2));

// Generate PURL (only works with version types)
try {
  const purl = npa.toPurl('express@4.18.2');
  console.log('PURL:', purl); // 'pkg:npm/express@4.18.2'
} catch (error) {
  console.log('Cannot generate PURL:', error.message);
}

File Path Resolution

const path = require('path');
const npa = require('npm-package-arg');

// Resolve relative to specific directory
const basePath = '/project/root';
const result = npa('./packages/utils', basePath);

console.log('Resolved path:', result.fetchSpec);
console.log('Save spec:', result.saveSpec); // Relative path for package.json