@hyperfrontend/versioning/workspace/discoverydiscovery
Monorepo discovery: finds packages, locates their changelogs, and builds the internal-dependency graph.
The package-discovery half (DiscoveryOptions, DiscoveryResult) walks the workspace looking for package.json files and produces a normalized list of projects. The changelog half (hasChangelog, getExpectedChangelogPath, DiscoveredChangelog) reports which packages have a CHANGELOG.md and where it's expected to live. The dependency-graph half (findInternalDependencies, findInternalDependenciesWithTypes, buildDependencyGraph, getTopologicalOrder, getTransitiveDependents) computes the per-package dependency edges (DependencyEdge, DependencyType) and the topological order needed to drive cascade bumps and batch updates safely.
API Reference
ƒ Functions
Parameters
| Name | Type | Description |
|---|---|---|
§projects | unknown | List of projects to analyze |
Returns
DependencyGraphAnalysisExample
Build a complete dependency graph
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)Parameters
Returns
unknownExample
Discover all changelog files within a workspace
import { discoverAllChangelogs } from '@hyperfrontend/versioning'
const changelogs = discoverAllChangelogs('/path/to/workspace')
for (const changelog of changelogs) {
console.log(`${changelog.projectPath} -> ${changelog.path}`)
}Parameters
| Name | Type | Description |
|---|---|---|
§options | DiscoveryOptions | Discovery options (default: {}) |
Returns
DiscoveryResultExample
Discover all packages within a workspace
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}`)
}Parameters
| Name | Type | Description |
|---|---|---|
§projectPath | string | Path to project directory or package.json |
Returns
ProjectExample
Discover a single project by path
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')Parameters
Returns
ProjectExample
Discover a project by name within a workspace
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' })Parameters
Returns
Map<string, string>Example
Find changelog files for all packages
import { findChangelogs, discoverPackages } from '@hyperfrontend/versioning'
const { packages } = discoverPackages()
const changelogs = findChangelogs('/workspace', packages)
for (const [projectPath, changelogPath] of changelogs) {
console.log(`${projectPath} -> ${changelogPath}`)
}Parameters
Returns
Map<string, string>Example
Find changelogs using VFS tree
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}`)
}
}findInternalDependencies(packageJson: PackageJson, workspacePackageNames: Set<string>): string[]
Parameters
Returns
string[]Example
Find internal dependencies in a package
const internalDeps = findInternalDependencies(packageJson, allPackageNames)
// ['@scope/lib-a', '@scope/lib-b']findInternalDependenciesWithTypes(packageName: string, packageJson: PackageJson, workspacePackageNames: Set<string>): DependencyEdge[]
Parameters
Returns
DependencyEdge[]Example
Find internal dependencies with type information
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})`)
}Parameters
| Name | Type | Description |
|---|---|---|
§projectPath | string | Path to project directory |
Returns
stringExample
Find the changelog for a single project
import { findProjectChangelog } from '@hyperfrontend/versioning'
const changelogPath = findProjectChangelog('./libs/my-lib')
if (changelogPath) {
console.log('Found changelog:', changelogPath)
}Returns
stringExample
Find project changelog using VFS tree
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
}
}Parameters
Returns
stringExample
Get expected changelog path for a project
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'Parameters
| Name | Type | Description |
|---|---|---|
§analysis | DependencyGraphAnalysis | Dependency graph analysis result |
Returns
unknownExample
Get packages in topological order for building
const buildOrder = getTopologicalOrder(analysis)
for (const pkg of buildOrder) {
await build(pkg)
}Parameters
Returns
Set<string>Example
Get all transitive dependencies of a package
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}`)
}Parameters
Returns
Set<string>Example
Get all transitive dependents of a package
// If lib-a depends on lib-utils and app-main depends on lib-a
// Then getTransitiveDependents('lib-utils') returns ['lib-a', 'app-main']Parameters
| Name | Type | Description |
|---|---|---|
§projectPath | string | Directory containing the project to check |
Returns
booleanExample
Check if a project has a changelog
import { hasChangelog } from '@hyperfrontend/versioning'
if (hasChangelog('./libs/my-lib')) {
console.log('Project has a changelog')
}Parameters
Returns
booleanExample
Check if one package transitively depends on another
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')
}◈ Interfaces
Properties
Properties
Properties
◆ Types
type DependencyGraph = ReadonlyMap<string, unknown>type DependencyType = "dependencies" | "devDependencies" | "peerDependencies" | "optionalDependencies"