The ParseLockfile class provides functionality to parse npm and yarn lockfiles into a unified format for validation. It supports multiple lockfile formats including npm v1/v2/v3, npm-shrinkwrap.json, yarn classic (v1), and Yarn Berry (v2+).
Creates a new lockfile parser instance.
/**
* Creates a new lockfile parser
* @param {Object} options - Parser configuration
* @param {string} [options.lockfilePath] - Path to the lockfile (absolute or relative)
* @param {string} [options.lockfileText] - UTF-8 string content of the lockfile
* @param {string} [options.lockfileType] - Package manager type: 'npm', 'npmjs', 'yarn', or 'yarnpkg'
* @throws {ParsingError} If neither lockfilePath nor lockfileText is provided
*/
class ParseLockfile {
constructor(options: {
lockfilePath?: string;
lockfileText?: string;
lockfileType?: string;
});
}Requirements: Either lockfilePath or lockfileText must be provided. If neither is provided, a ParsingError with type NO_LOCKFILE will be thrown.
Usage Examples:
const { ParseLockfile } = require('lockfile-lint-api');
// Parse from file path
const parser1 = new ParseLockfile({
lockfilePath: './package-lock.json'
});
// Parse from string content
const fs = require('fs');
const content = fs.readFileSync('./yarn.lock', 'utf-8');
const parser2 = new ParseLockfile({
lockfileText: content
});
// Specify lockfile type explicitly
const parser3 = new ParseLockfile({
lockfilePath: './custom.lock',
lockfileType: 'yarn'
});
// Error: Missing both options
try {
const parser4 = new ParseLockfile({});
} catch (error) {
// error.name === 'ParsingError'
// error.message includes 'NO_LOCKFILE'
}Parses the lockfile synchronously and returns the parsed result.
/**
* Synchronously parses the lockfile
* @returns {Object} Parsed lockfile with type and object properties
* @throws {ParsingError} If parsing fails or file cannot be read
*/
parseSync(): {
type: 'success';
object: {
[packageKey: string]: {
version: string;
resolved?: string;
integrity?: string;
requires?: Object;
};
};
}The returned object has the following structure:
type: Always 'success' if parsing succeedsobject: A map of package keys to package metadataPackage keys are formatted as: package-name@version-hash for npm lockfiles, or package-name@version-range for yarn lockfiles.
Usage Examples:
const { ParseLockfile } = require('lockfile-lint-api');
try {
const parser = new ParseLockfile({
lockfilePath: './package-lock.json'
});
const result = parser.parseSync();
console.log(result.type); // 'success'
console.log(Object.keys(result.object).length); // Number of packages
// Iterate through packages
for (const [packageKey, metadata] of Object.entries(result.object)) {
console.log(`Package: ${packageKey}`);
console.log(` Version: ${metadata.version}`);
console.log(` Resolved: ${metadata.resolved}`);
console.log(` Integrity: ${metadata.integrity}`);
}
} catch (error) {
if (error.name === 'ParsingError') {
console.error('Failed to parse lockfile:', error.message);
}
}Helper method to check if lockfile type was explicitly provided.
/**
* Checks if lockfileType option was provided
* @returns {boolean} True if lockfileType was specified
*/
isLockfileTypeGiven(): boolean;Usage:
const parser = new ParseLockfile({ lockfilePath: './package-lock.json' });
if (parser.isLockfileTypeGiven()) {
console.log('Lockfile type was explicitly set');
} else {
console.log('Lockfile type will be auto-detected');
}Determines the appropriate parser based on lockfile type or filename.
/**
* Resolves the appropriate parser for the lockfile
* @returns {Function} Parser function for the detected lockfile type
* @throws {ParsingError} If parser cannot be determined
*/
resolvePkgMgrForLockfile(): Function;Determines parser based solely on filename.
/**
* Determines parser based on filename
* @returns {Function} Parser function or undefined if not recognized
*/
resolvePkgMgrByFilename(): Function | undefined;Recognized filenames:
package-lock.json → npm parseryarn.lock → yarn parserNote: npm-shrinkwrap.json files are NOT auto-detected by filename. To parse npm-shrinkwrap.json files, you must explicitly specify lockfileType: 'npm' in the constructor options.
Parses a Yarn lockfile (both classic and Berry formats).
/**
* Parses Yarn lockfile format
* @param {string|Buffer} lockfileBuffer - The lockfile contents
* @returns {Object} Parsed lockfile result
* @throws {ParsingError} If parsing fails
*/
parseYarnLockfile(lockfileBuffer: string | Buffer): {
type: 'success';
object: Object;
}Parses an npm lockfile (v1, v2, or v3 format).
/**
* Parses npm lockfile format (package-lock.json or npm-shrinkwrap.json)
* @param {string|Buffer} lockfileBuffer - The lockfile contents
* @returns {Object} Parsed lockfile result
* @throws {ParsingError} If parsing fails
*/
parseNpmLockfile(lockfileBuffer: string | Buffer): {
type: 'success';
object: Object;
}Extracts clean package name from node_modules path.
/**
* Extracts package name from full path
* @param {string} packageName - Full package path (may include node_modules/)
* @returns {string} Clean package name
*/
extractedPackageName(packageName: string): string;Usage Examples:
const parser = new ParseLockfile({ lockfilePath: './package-lock.json' });
// Extract clean package names
console.log(parser.extractedPackageName('node_modules/lodash'));
// Output: 'lodash'
console.log(parser.extractedPackageName('node_modules/@babel/core'));
// Output: '@babel/core'
console.log(parser.extractedPackageName('packages/app/node_modules/react'));
// Output: 'react'The parser handles multiple npm lockfile formats:
dependencies field with nested structurepackages field with flat structurelockfileType: 'npm' parameter)__metadata field and resolution syntaxYarn Berry lockfiles are automatically normalized to match the classic format's structure for consistent validation.
The parser throws ParsingError for critical failures:
class ParsingError extends Error {
constructor(errorFn: Function, relatedValue?: string, error?: Error);
name: 'ParsingError';
message: string;
stack: string;
}Error Types:
NO_OPTIONS: Constructor called without options objectNO_LOCKFILE: Neither lockfilePath nor lockfileText providedNO_PARSER_FOR_TYPE: Unsupported lockfile type specifiedNO_PARSER_FOR_PATH: Cannot determine lockfile type from filenameREAD_FAILED: Cannot read lockfile from filesystemPARSE_NPMLOCKFILE_FAILED: npm lockfile parsing failed (invalid JSON or format)PARSE_YARNLOCKFILE_FAILED: yarn lockfile parsing failed (invalid SYML or format)Usage Examples:
const { ParseLockfile } = require('lockfile-lint-api');
try {
const parser = new ParseLockfile({
lockfilePath: './unknown.lock'
});
const result = parser.parseSync();
} catch (error) {
if (error.name === 'ParsingError') {
console.error('Parsing error:', error.message);
// Example messages:
// "Unable to find relevant lockfile parser for "unknown.lock", consider passing the --type option."
// "Unable to parse npm lockfile "./package-lock.json""
} else {
console.error('Unexpected error:', error);
}
}After parsing, each package entry contains:
interface PackageMetadata {
version: string; // Exact version installed
resolved?: string; // URL where package was downloaded from
integrity?: string; // Integrity hash (usually sha512-...)
requires?: Object; // Map of dependency names to version ranges
}Notes:
resolved field may be missing for packages installed from local filesystemintegrity field may be missing for older lockfile formats or git dependenciesWhen lockfileType is not specified, the parser uses this auto-detection logic:
lockfilePath ends with package-lock.json → npm parserlockfilePath ends with yarn.lock → yarn parserlockfileType is 'npm' or 'npmjs' → npm parserlockfileType is 'yarn' or 'yarnpkg' → yarn parserParsingError with type NO_PARSER_FOR_PATHBest Practice: For non-standard filenames, always specify lockfileType explicitly.
// Packages without resolved field (local filesystem)
{
'local-package@1.0.0': {
version: '1.0.0'
// No resolved field
}
}
// Packages without integrity (git dependencies, old lockfiles)
{
'git-package@1.0.0': {
version: '1.0.0',
resolved: 'git+https://github.com/user/repo.git'
// No integrity field
}
}// npm v1/v2 format detection
const parser = new ParseLockfile({
lockfilePath: './package-lock.json',
lockfileType: 'npm'
});
// Automatically detects v1/v2 vs v3 format
// Yarn Berry detection
const parser = new ParseLockfile({
lockfilePath: './yarn.lock',
lockfileType: 'yarn'
});
// Automatically detects classic vs Berry formatfunction safeParseLockfile(path, type) {
try {
const parser = new ParseLockfile({
lockfilePath: path,
lockfileType: type
});
return parser.parseSync();
} catch (error) {
if (error.name === 'ParsingError') {
// Handle parsing-specific errors
if (error.message.includes('NO_PARSER_FOR_PATH')) {
// Try with explicit type
return safeParseLockfile(path, 'npm');
}
}
throw error;
}
}