import { Parser, ParserInput, ParserOptions } from "../parser"; import { SourceFile } from "../tree"; export interface PackageJsonParserOptions extends ParserOptions { /** * If true, skips reading and parsing lock files for dependency resolution. * The NodeResolutionResult marker will still be created, but without resolved dependencies. */ skipDependencyResolution?: boolean; } /** * A parser for package.json files that wraps the JsonParser. * * Similar to how MavenParser wraps XmlParser in Java, this parser: * - Parses package.json files as JSON documents * - Attaches NodeResolutionResult markers with dependency information * - Optionally reads corresponding lock files (package-lock.json, yarn.lock, etc.) * to provide resolved dependency versions */ export declare class PackageJsonParser extends Parser { private readonly jsonParser; private readonly skipDependencyResolution; /** Fields to copy from package.json that contain dependency maps */ private static readonly DEPENDENCY_FIELDS; constructor(options?: PackageJsonParserOptions); /** * Extracts package metadata from a package.json object into a lock file entry format. * Copies version, dependency fields, engines, and license. */ private static extractPackageMetadata; /** * Normalizes the license field from package.json. * Older packages may have license in legacy formats: * - Array: ["MIT", "Apache2"] -> "(MIT OR Apache2)" * - Object: { type: "MIT", url: "..." } -> "MIT" */ private static normalizeLicense; /** * Accepts package.json files. */ accept(sourcePath: string): boolean; parse(...inputs: ParserInput[]): AsyncGenerator; /** * Creates a NodeResolutionResult marker from the package.json content and optional lock file. */ private createMarker; /** * Resolves workspace glob patterns to actual package.json paths. * * Workspaces can be specified as: * - Array of globs: ["packages/*", "apps/*", "packages/**", "{apps,libs}/*"] * - Object with packages array: { packages: ["packages/*"] } * - Negation patterns: ["packages/*", "!packages/internal"] * * @param workspaces The workspaces field from package.json * @param projectDir The absolute path to the project directory * @param relativeTo Optional base path for creating relative paths * @returns Array of relative paths to workspace member package.json files */ private resolveWorkspacePackagePaths; /** * Collects candidate directories that might match workspace patterns. * Uses the patterns to determine how deep to scan. */ private collectCandidateWorkspaceDirs; /** * Extracts base directory paths from a glob pattern. * Handles brace expansion like "{apps,libs}/*" -> ["apps", "libs"] */ private extractBaseDirs; /** * Reads workspace patterns from pnpm-workspace.yaml file. * * pnpm-workspace.yaml format: * ```yaml * packages: * - 'packages/*' * - 'apps/*' * - '!packages/excluded' * ``` * * @param projectDir The absolute path to the project directory * @returns Array of workspace patterns, or undefined if file doesn't exist */ private readPnpmWorkspacePatterns; /** * Attempts to find and read a lock file by walking up the directory tree. * Starts from the directory containing the package.json and walks up toward * the root directory (or relativeTo if specified). * * This handles both standalone projects (lock file next to package.json) and * workspace scenarios (lock file at workspace root). * * @param startDir The directory containing the package.json being parsed * @param rootDir Optional root directory to stop walking at (e.g., relativeTo/git root) * @returns Object with parsed lock file content and detected package manager, or undefined if none found */ private tryReadLockFileWithWalkUp; /** * Attempts to read and parse a lock file from the given directory. * Supports npm (package-lock.json), bun (bun.lock), pnpm, and yarn. * * @returns Object with parsed lock file content and detected package manager, or undefined if no lock file found */ private tryReadLockFile; /** * Parses lock file content based on the lock file type. */ private parseLockFileContent; /** * Parses JSONC (JSON with Comments and trailing commas) content. */ private parseJsonc; /** * Walks the node_modules directory to build an npm-format packages structure. * This provides 100% accurate resolution for all package managers since it reads * the actual installed packages rather than trying to interpret lock file formats. * * @param dir The project directory containing node_modules * @returns npm package-lock.json format with packages map, or undefined if node_modules doesn't exist */ private walkNodeModules; /** * Walks pnpm's .pnpm directory structure to build packages map. * pnpm stores packages in .pnpm/@/node_modules// */ private walkPnpmNodeModules; /** * Recursively walks a node_modules directory, reading package.json files * and building the packages map. * * @param nodeModulesPath Absolute path to the node_modules directory * @param relativePath Relative path from project root (e.g., "node_modules" or "node_modules/foo/node_modules") * @param packages The packages map to populate */ private walkNodeModulesRecursive; /** * Processes a single package directory, reading its package.json and * recursively processing nested node_modules. */ private processPackage; /** * Converts bun.lock format to npm package-lock.json format for unified processing. * * bun.lock format (v1): * - Keys are package names or paths like "is-even/is-odd" for nested deps * - Values are arrays: [name@version, url, metadata, integrity] * - metadata can have: { dependencies: {...}, devDependencies: {...}, ... } */ private convertBunLockToNpmFormat; /** * Gets dependency information from pnpm using its CLI. * Uses `pnpm list --json --depth=Infinity` to get the full dependency tree. */ private getPnpmDependencies; /** * Converts pnpm list --json output to npm package-lock.json format. */ private convertPnpmListToNpmFormat; /** * Recursively extracts dependencies from pnpm list output. * Uses name@version as key to handle multiple versions of the same package. */ private extractPnpmDependencies; /** * Parses yarn.lock file and returns npm-format content. * Detects whether it's Yarn Classic (v1) or Yarn Berry (v2+) format. */ private parseYarnLock; /** * Parses Yarn Berry (v2+) yarn.lock file directly. * Format is standard YAML with package entries like: * "is-odd@npm:^3.0.1": * version: 3.0.1 * resolution: "is-odd@npm:3.0.1" * dependencies: * is-number: "npm:^6.0.0" */ private parseYarnBerryLock; /** * Parses Yarn Classic (v1) yarn.lock file directly. * Format is a custom format (not standard YAML): * * is-odd@^3.0.1: * version "3.0.1" * resolved "https://..." * integrity sha512-... * dependencies: * is-number "^6.0.0" */ private parseYarnClassicLock; } //# sourceMappingURL=package-json-parser.d.ts.map