import { PackageJson } from '../../_dependencies/@hyperfrontend/project-scope/project/package/index.js'; import { Project, Workspace, WorkspaceConfig } from '../models'; import { Tree } from '../../_dependencies/@hyperfrontend/project-scope/vfs/index.js'; import { Tree as Tree$1 } from '../../_dependencies/@hyperfrontend/project-scope/index.js'; /** * Dependency graph structure. * Maps package name to list of packages that depend on it. */ type DependencyGraph = ReadonlyMap; /** * Dependency relation type. */ type DependencyType = 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies'; /** * A single dependency edge in the graph. */ interface DependencyEdge { /** Package that has the dependency */ readonly from: string; /** Package being depended on */ readonly to: string; /** Type of dependency relationship */ readonly type: DependencyType; /** Version range specified */ readonly versionRange: string; } /** * Result of dependency graph analysis. */ interface DependencyGraphAnalysis { /** Forward graph: package -> dependents */ readonly dependencyGraph: DependencyGraph; /** Reverse graph: package -> dependencies */ readonly reverseDependencyGraph: DependencyGraph; /** All dependency edges */ readonly edges: readonly DependencyEdge[]; /** Packages with no dependents (leaf nodes) */ readonly leafPackages: readonly string[]; /** Packages with no dependencies (root nodes) */ readonly rootPackages: readonly string[]; /** Whether the graph has circular dependencies */ readonly hasCircularDependencies: boolean; /** Detected circular dependency chains */ readonly circularDependencies: readonly string[][]; } /** * Finds internal dependencies in a package.json. * Returns names of workspace packages that this package depends on. * * @param packageJson - Parsed package.json content * @param workspacePackageNames - Set of all package names in the workspace * @returns Array of internal dependency names * * @example Find internal dependencies in a package * ```typescript * const internalDeps = findInternalDependencies(packageJson, allPackageNames) * // ['@scope/lib-a', '@scope/lib-b'] * ``` */ declare function findInternalDependencies(packageJson: PackageJson, workspacePackageNames: Set): string[]; /** * Finds internal dependencies with type information. * * @param packageName - Name of the package being analyzed * @param packageJson - Parsed package.json content * @param workspacePackageNames - Set of all package names in the workspace * @returns Array of dependency edges with type information * * @example Find internal dependencies with type information * ```typescript * import { findInternalDependenciesWithTypes, readPackageJson } from '@hyperfrontend/versioning' * * const packageJson = readPackageJson('./libs/my-lib/package.json') * const workspacePackages = new Set(['@myorg/utils', '@myorg/core']) * * const edges = findInternalDependenciesWithTypes('@myorg/my-lib', packageJson, workspacePackages) * for (const edge of edges) { * console.log(`${edge.from} -> ${edge.to} (${edge.type})`) * } * ``` */ declare function findInternalDependenciesWithTypes(packageName: string, packageJson: PackageJson, workspacePackageNames: Set): DependencyEdge[]; /** * Builds a complete dependency graph from a list of projects. * * @param projects - List of projects to analyze * @returns Dependency graph analysis result * * @example Build a complete dependency graph * ```typescript * import { buildDependencyGraph, discoverPackages } from '@hyperfrontend/versioning' * * const { projects } = discoverPackages() * const analysis = buildDependencyGraph(projects) * * // Get packages that depend on 'lib-utils' * const dependents = analysis.dependencyGraph.get('lib-utils') ?? [] * * // Get packages in topological order for building * const buildOrder = getTopologicalOrder(analysis) * ``` */ declare function buildDependencyGraph(projects: readonly Project[]): DependencyGraphAnalysis; /** * Gets a topological ordering of packages for building. * Packages with no dependencies come first. * * @param analysis - Dependency graph analysis result * @returns Array of package names in build order * @throws {Error} If circular dependencies exist * * @example Get packages in topological order for building * ```typescript * const buildOrder = getTopologicalOrder(analysis) * for (const pkg of buildOrder) { * await build(pkg) * } * ``` */ declare function getTopologicalOrder(analysis: DependencyGraphAnalysis): readonly string[]; /** * Gets all transitive dependents of a package (direct and indirect). * * @param workspace - The workspace containing projects * @param packageName - Name of the package to analyze * @returns Set of all packages that depend on this package * * @example Get all transitive dependents of a package * ```typescript * // If lib-a depends on lib-utils and app-main depends on lib-a * // Then getTransitiveDependents('lib-utils') returns ['lib-a', 'app-main'] * ``` */ declare function getTransitiveDependents(workspace: Workspace, packageName: string): Set; /** * Gets all transitive dependencies of a package (direct and indirect). * * @param workspace - The workspace containing projects * @param packageName - Name of the package to analyze * @returns Set of all packages this package depends on * * @example Get all transitive dependencies of a package * ```typescript * import { discoverWorkspace, getTransitiveDependencies } from '@hyperfrontend/versioning' * * const workspace = discoverWorkspace() * const allDeps = getTransitiveDependencies(workspace, '@myorg/app') * * console.log(`@myorg/app transitively depends on ${allDeps.size} packages`) * for (const dep of allDeps) { * console.log(` - ${dep}`) * } * ``` */ declare function getTransitiveDependencies(workspace: Workspace, packageName: string): Set; /** * Checks if package A transitively depends on package B. * * @param workspace - The workspace containing projects * @param packageA - Name of the potentially dependent package * @param packageB - Name of the potential dependency * @returns True if packageA transitively depends on packageB * * @example Check if one package transitively depends on another * ```typescript * import { discoverWorkspace, transitivelyDependsOn } from '@hyperfrontend/versioning' * * const workspace = discoverWorkspace() * * if (transitivelyDependsOn(workspace, '@myorg/app', '@myorg/utils')) { * console.log('Bumping @myorg/utils will affect @myorg/app') * } * ``` */ declare function transitivelyDependsOn(workspace: Workspace, packageA: string, packageB: string): boolean; /** * Common changelog file names in priority order. */ declare const CHANGELOG_NAMES: readonly string[]; /** * Represents a discovered changelog file. */ interface DiscoveredChangelog { /** Absolute path to the changelog file */ readonly path: string; /** Relative path from project root */ readonly relativePath: string; /** Path to the project containing this changelog */ readonly projectPath: string; /** Name of the changelog file */ readonly filename: string; } /** * Package info for changelog lookup. */ interface PackageInfo { /** Absolute path to the package directory */ path: string; /** Package name from package.json */ name: string; } /** * Finds changelog files for a list of packages. * Returns a map of project path to changelog absolute path. * * @param workspaceRoot - Workspace root path * @param packages - List of packages to find changelogs for * @returns Map of project path to changelog path * * @example Find changelog files for all packages * ```typescript * import { findChangelogs, discoverPackages } from '@hyperfrontend/versioning' * * const { packages } = discoverPackages() * const changelogs = findChangelogs('/workspace', packages) * * for (const [projectPath, changelogPath] of changelogs) { * console.log(`${projectPath} -> ${changelogPath}`) * } * ``` */ declare function findChangelogs(workspaceRoot: string, packages: readonly PackageInfo[]): Map; /** * Finds the changelog file for a single project. * Checks for common changelog names in order of priority. * * @param projectPath - Path to project directory * @returns Absolute path to changelog or null if not found * * @example Find the changelog for a single project * ```typescript * import { findProjectChangelog } from '@hyperfrontend/versioning' * * const changelogPath = findProjectChangelog('./libs/my-lib') * if (changelogPath) { * console.log('Found changelog:', changelogPath) * } * ``` */ declare function findProjectChangelog(projectPath: string): string | null; /** * Finds changelog files for a list of packages using VFS tree. * Returns a map of project path to changelog absolute path. * * @param tree - VFS tree instance * @param packages - List of packages to find changelogs for * @returns Map of project path to changelog path * * @example Find changelogs using VFS tree * ```typescript * import { findChangelogsInTree, discoverPackages } from '@hyperfrontend/versioning' * * // Inside an Nx generator * export default function myGenerator(tree: Tree) { * const { packages } = discoverPackages() * const changelogs = findChangelogsInTree(tree, packages) * * for (const [projectPath, changelogPath] of changelogs) { * console.log(`Found changelog at ${changelogPath}`) * } * } * ``` */ declare function findChangelogsInTree(tree: Tree, packages: readonly PackageInfo[]): Map; /** * Finds the changelog file for a single project using VFS tree. * Checks for common changelog names in order of priority. * * @param tree - VFS tree instance * @param projectPath - Path to project directory * @returns Absolute path to changelog or null if not found * * @example Find project changelog using VFS tree * ```typescript * import { findProjectChangelogInTree } from '@hyperfrontend/versioning' * * // Inside an Nx generator * export default function myGenerator(tree: Tree) { * const changelogPath = findProjectChangelogInTree(tree, 'libs/my-lib') * if (changelogPath) { * const content = tree.read(changelogPath, 'utf-8') * // Process changelog content * } * } * ``` */ declare function findProjectChangelogInTree(tree: Tree, projectPath: string): string | null; /** * Discovers all changelog files within a workspace. * * @param workspaceRoot - Workspace root path * @param patterns - Glob patterns for finding changelogs (default: all CHANGELOGs) * @returns Array of discovered changelog information * * @example Discover all changelog files within a workspace * ```typescript * import { discoverAllChangelogs } from '@hyperfrontend/versioning' * * const changelogs = discoverAllChangelogs('/path/to/workspace') * for (const changelog of changelogs) { * console.log(`${changelog.projectPath} -> ${changelog.path}`) * } * ``` */ declare function discoverAllChangelogs(workspaceRoot: string, patterns?: readonly string[]): readonly DiscoveredChangelog[]; /** * Options for package discovery. */ interface DiscoveryOptions { /** Workspace root (auto-detected if not provided) */ workspaceRoot?: string; /** Glob patterns for finding package.json files */ patterns?: readonly string[]; /** Patterns to exclude */ exclude?: readonly string[]; /** Include changelogs in discovery */ includeChangelogs?: boolean; /** Track internal dependencies */ trackDependencies?: boolean; /** Optional VFS tree for VFS-aware discovery */ tree?: Tree$1; } /** * Result of package discovery. */ interface DiscoveryResult { /** All discovered projects */ readonly projects: readonly Project[]; /** Projects indexed by name */ readonly projectMap: ReadonlyMap; /** All discovered package names */ readonly packageNames: ReadonlySet; /** Workspace root path */ readonly workspaceRoot: string; /** Configuration used for discovery */ readonly config: WorkspaceConfig; } /** * Discovers all packages within a workspace. * Finds package.json files, parses them, and optionally discovers * changelogs and internal dependencies. * * @param options - Discovery options * @returns Discovery result with all found packages * @throws {Error} If workspace root cannot be found * * @example Discover all packages within a workspace * ```typescript * import { discoverPackages } from '@hyperfrontend/versioning' * * // Discover all packages in current workspace * const result = discoverPackages() * * // Discover with custom patterns * const result = discoverPackages({ * patterns: ['packages/*\/package.json'], * includeChangelogs: true * }) * * // Access discovered projects * for (const project of result.projects) { * console.log(`${project.name}@${project.version}`) * } * ``` */ declare function discoverPackages(options?: DiscoveryOptions): DiscoveryResult; /** * Discovers a single project by path. * * @param projectPath - Path to project directory or package.json * @returns The discovered project or null if not found * * @example Discover a single project by path * ```typescript * import { discoverProject } from '@hyperfrontend/versioning' * * const project = discoverProject('./libs/utils') * if (project) { * console.log(`Found ${project.name}@${project.version}`) * } * * // Also accepts direct package.json path * const project2 = discoverProject('./libs/utils/package.json') * ``` */ declare function discoverProject(projectPath: string): Project | null; /** * Discovers a project by name within a workspace. * * @param projectName - Name of the project to find * @param options - Discovery options * @returns The project or null if not found * * @example Discover a project by name within a workspace * ```typescript * import { discoverProjectByName } from '@hyperfrontend/versioning' * * const project = discoverProjectByName('@myorg/utils') * if (project) { * console.log(`Found at ${project.path}`) * } * * // With custom workspace root * const project2 = discoverProjectByName('@myorg/core', { workspaceRoot: '/custom/path' }) * ``` */ declare function discoverProjectByName(projectName: string, options?: DiscoveryOptions): Project | null; /** * Checks if a project has a changelog file. * * @param projectPath - Directory containing the project to check * @returns True if changelog exists * * @example Check if a project has a changelog * ```typescript * import { hasChangelog } from '@hyperfrontend/versioning' * * if (hasChangelog('./libs/my-lib')) { * console.log('Project has a changelog') * } * ``` */ declare function hasChangelog(projectPath: string): boolean; /** * Gets the expected changelog path for a project. * Returns the standard CHANGELOG.md path regardless of whether it exists. * * @param projectPath - Directory containing the project files * @param fileName - Changelog filename to use (default: 'CHANGELOG.md') * @returns Absolute path to changelog file in the project directory * * @example Get expected changelog path for a project * ```typescript * import { getExpectedChangelogPath } from '@hyperfrontend/versioning' * * const changelogPath = getExpectedChangelogPath('./libs/my-lib') * // => '/workspace/libs/my-lib/CHANGELOG.md' * * const customPath = getExpectedChangelogPath('./libs/my-lib', 'HISTORY.md') * // => '/workspace/libs/my-lib/HISTORY.md' * ``` */ declare function getExpectedChangelogPath(projectPath: string, fileName?: string): string; export { CHANGELOG_NAMES, buildDependencyGraph, discoverAllChangelogs, discoverPackages, discoverProject, discoverProjectByName, findChangelogs, findChangelogsInTree, findInternalDependencies, findInternalDependenciesWithTypes, findProjectChangelog, findProjectChangelogInTree, getExpectedChangelogPath, getTopologicalOrder, getTransitiveDependencies, getTransitiveDependents, hasChangelog, transitivelyDependsOn }; export type { DependencyEdge, DependencyGraph, DependencyGraphAnalysis, DependencyType, DiscoveredChangelog, DiscoveryOptions, DiscoveryResult };