import { PackageManager } from "./node-resolution-result"; import { Json, JsonVisitor } from "../json"; import { YamlVisitor } from "../yaml"; import { SourceFile } from "../tree"; import { TreeVisitor } from "../visitor"; import { ExecutionContext } from "../execution"; /** * Configuration for lock file detection. */ export interface LockFileDetectionConfig { /** The lock file name */ filename: string; /** The package manager, or a function to detect it from file content */ packageManager: PackageManager | ((content: string) => PackageManager); /** If true, prefer walking node_modules over parsing lock file (lock file may omit details) */ preferNodeModules?: boolean; } /** * Lock file names that should be parsed as JSON/JSONC format. */ export declare const JSON_LOCK_FILE_NAMES: readonly ["bun.lock", "package-lock.json"]; /** * Lock file names that should be parsed as YAML format. */ export declare const YAML_LOCK_FILE_NAMES: readonly ["pnpm-lock.yaml"]; /** * Lock file names that should be parsed as plain text (custom formats like yarn.lock v1). * Note: yarn.lock for Yarn Berry (v2+) is actually YAML format and should be parsed as such. * Use `getLockFileFormat` with content to determine the correct format for yarn.lock. */ export declare const TEXT_LOCK_FILE_NAMES: readonly ["yarn.lock"]; /** * Detects if a yarn.lock file is Yarn Berry (v2+) format based on content. * Yarn Berry lock files contain a `__metadata:` key which is not present in Classic. * * @param content The yarn.lock file content * @returns true if this is a Yarn Berry lock file (YAML format), false for Classic */ export declare function isYarnBerryLockFile(content: string): boolean; /** * Detects the package manager used in a directory by checking for lock files. * * @param dir The directory to check * @returns The detected package manager, or undefined if none found */ export declare function detectPackageManager(dir: string): PackageManager | undefined; /** * Gets the lock file detection configuration. * Returns the array of lock file configs in priority order. */ export declare function getLockFileDetectionConfig(): ReadonlyArray; /** * Gets the lock file name for a package manager. */ export declare function getLockFileName(pm: PackageManager): string; /** * Gets all supported lock file names. */ export declare function getAllLockFileNames(): string[]; /** * Runs a package manager list command to get dependency information. * * @param pm The package manager to use * @param cwd Working directory * @param timeout Timeout in milliseconds * @returns The JSON output, or undefined if failed */ export declare function runList(pm: PackageManager, cwd: string, timeout?: number): string | undefined; /** * Result of running install in a temporary directory. */ export interface TempInstallResult { /** Whether the install succeeded */ success: boolean; /** The updated lock file content (if successful and lock file exists) */ lockFileContent?: string; /** Error message (if failed) */ error?: string; } /** * Generic accumulator for dependency recipes that run package manager operations. * Used by scanning recipes to track state across scanning and editing phases. * * @typeParam T The recipe-specific project update info type */ export interface DependencyRecipeAccumulator { /** Projects that need updating: packageJsonPath -> update info */ projectsToUpdate: Map; /** After running package manager, store the updated lock file content */ updatedLockFiles: Map; /** Updated package.json content (after npm install may have modified it) */ updatedPackageJsons: Map; /** Track which projects have been processed (npm install has run) */ processedProjects: Set; /** Track projects where npm install failed: packageJsonPath -> error message */ failedProjects: Map; } /** * Creates a new empty accumulator for dependency recipes. */ export declare function createDependencyRecipeAccumulator(): DependencyRecipeAccumulator; /** * Checks if a source path is a lock file and returns the updated content if available. * This is a helper for dependency recipes that need to update lock files. * * @param sourcePath The source path to check * @param acc The recipe accumulator containing updated lock file content * @returns The updated lock file content if this is a lock file that was updated, undefined otherwise */ export declare function getUpdatedLockFileContent(sourcePath: string, acc: DependencyRecipeAccumulator): string | undefined; /** * Determines the appropriate parser for a lock file based on its filename and optionally content. * * For yarn.lock files, the format depends on the Yarn version: * - Yarn Classic (v1): Custom plain text format * - Yarn Berry (v2+): YAML format * * If content is provided for yarn.lock, it will be used to detect the format. * Otherwise, defaults to 'text' (Yarn Classic). * * @param lockFileName The lock file name (e.g., "pnpm-lock.yaml", "package-lock.json", "yarn.lock") * @param content Optional file content (used for yarn.lock format detection) * @returns 'yaml' for YAML lock files, 'json' for JSON lock files, 'text' for plain text */ export declare function getLockFileFormat(lockFileName: string, content?: string): 'yaml' | 'json' | 'text'; /** * Re-parses updated lock file content using the appropriate parser. * This is used by dependency recipes to create the updated lock file SourceFile. * * For yarn.lock files, the content is used to detect whether it's Yarn Berry (YAML) * or Yarn Classic (plain text) format. * * @param content The updated lock file content * @param sourcePath The source path of the lock file * @param lockFileName The lock file name (e.g., "pnpm-lock.yaml", "yarn.lock") * @returns The parsed SourceFile (Json.Document, Yaml.Documents, or PlainText) */ export declare function parseLockFileContent(content: string, sourcePath: string, lockFileName: string): Promise; /** * Base interface for project update info used by dependency recipes. * Recipes extend this with additional fields specific to their needs. */ export interface BaseProjectUpdateInfo { /** Relative path to package.json (from source root) */ packageJsonPath: string; /** The package manager used by this project */ packageManager: PackageManager; } /** * Stores the result of a package manager install into the accumulator. * This handles the common pattern of storing updated lock files and tracking failures. * * @param result The result from runInstallInTempDir * @param acc The recipe accumulator * @param updateInfo The project update info (must have packageJsonPath and packageManager) * @param modifiedPackageJson The modified package.json content that was used for install */ export declare function storeInstallResult(result: TempInstallResult, acc: DependencyRecipeAccumulator, updateInfo: T, modifiedPackageJson: string): void; /** * Runs the package manager install for a project if it hasn't been processed yet. * Updates the accumulator's processedProjects set after running. * * @param sourcePath The source path (package.json path) being processed * @param acc The recipe accumulator * @param runInstall Function that performs the actual install (recipe-specific) * @returns The failure message if install failed, undefined otherwise */ export declare function runInstallIfNeeded(sourcePath: string, acc: DependencyRecipeAccumulator, runInstall: () => Promise): Promise; /** * Updates the NodeResolutionResult marker on a JSON document after a package manager operation. * This recreates the marker based on the updated package.json and lock file content. * * @param doc The JSON document containing the marker * @param updateInfo Project update info with paths and package manager * @param acc The recipe accumulator containing updated content * @returns The document with the updated marker, or unchanged if no existing marker */ export declare function updateNodeResolutionMarker(doc: Json.Document, updateInfo: T & { originalPackageJson: string; }, acc: DependencyRecipeAccumulator): Promise; /** * Options for running install in a temporary directory. */ export interface TempInstallOptions { /** Timeout in milliseconds (default: 120000 = 2 minutes) */ timeout?: number; /** * If true, only update the lock file without installing node_modules. * If false, perform a full install which creates node_modules in the temp dir. * Default: true (lock-only is faster and sufficient for most cases) */ lockOnly?: boolean; /** * Original lock file content to use. If provided, this content will be written * to the temp directory instead of copying from projectDir. * This allows recipes to work with in-memory SourceFiles without filesystem access. */ originalLockFileContent?: string; /** * Config file contents to use. Keys are filenames (e.g., '.npmrc'), values are content. * If provided, these will be written to the temp directory instead of copying from projectDir. */ configFiles?: Record; } /** * Options for running install in a temporary directory with workspace support. */ export interface WorkspaceTempInstallOptions extends TempInstallOptions { /** * Workspace package.json files. Keys are relative paths from the project root * (e.g., "packages/foo/package.json"), values are the package.json content. * The root package.json should have a "workspaces" field pointing to these packages. */ workspacePackages?: Record; } /** * Runs package manager install in a temporary directory. * * This function: * 1. Creates a temp directory * 2. Writes the provided package.json content * 3. Writes the lock file content (if provided) * 4. Writes config files (if provided) * 5. Runs the package manager install * 6. Returns the updated lock file content * 7. Cleans up the temp directory * * @param pm The package manager to use * @param modifiedPackageJson The modified package.json content to use * @param options Optional settings for timeout, lock-only mode, and file contents * @returns Result containing success status and lock file content or error */ export declare function runInstallInTempDir(pm: PackageManager, modifiedPackageJson: string, options?: TempInstallOptions): Promise; /** * Runs package manager install in a temporary directory with workspace support. * * This function: * 1. Creates a temp directory * 2. Writes the root package.json content * 3. Writes workspace package.json files (creating subdirectories as needed) * 4. Writes the lock file content (if provided) * 5. Writes config files (if provided) * 6. Runs the package manager install at the root * 7. Returns the updated lock file content * 8. Cleans up the temp directory * * @param pm The package manager to use * @param rootPackageJson The root package.json content (should contain "workspaces" field) * @param options Optional settings including workspace packages, timeout, lock-only mode, and file contents * @returns Result containing success status and lock file content or error */ export declare function runWorkspaceInstallInTempDir(pm: PackageManager, rootPackageJson: string, options?: WorkspaceTempInstallOptions): Promise; /** * Creates a lock file visitor that handles updating YAML lock files (pnpm-lock.yaml). * This is a reusable component for dependency recipes. * * @param acc The recipe accumulator containing updated lock file content * @returns A YamlVisitor that updates YAML lock files */ export declare function createYamlLockFileVisitor(acc: DependencyRecipeAccumulator): YamlVisitor; /** * Creates a composite visitor that delegates to the appropriate editor based on tree type. * This handles both JSON (package-lock.json, bun.lock) and YAML (pnpm-lock.yaml) lock files. * * @param jsonEditor The JSON visitor for handling JSON files * @param acc The recipe accumulator for YAML lock file handling * @returns A TreeVisitor that handles both JSON and YAML files */ export declare function createLockFileEditor(jsonEditor: JsonVisitor, acc: DependencyRecipeAccumulator): TreeVisitor; //# sourceMappingURL=package-manager.d.ts.map