Buddy Class API
On this page 38
The Buddy class is the main entry point for programmatic dependency management. It provides methods for scanning dependencies across multiple file formats (package.json, Launchpad/pkgx dependency files), creating pull requests, and managing updates.
Constructor
interface BuddyConstructor {
new(config: BuddyConfig, projectPath?: string): Buddy
}
Parameters
- config (
BuddyConfig): Configuration object - projectPath (
string, optional): Project root path (defaults toprocess.cwd())
Example
import { Buddy } from '@buddysh/buddy'
const buddy = new Buddy({
verbose: true,
repository: {
provider: 'github',
owner: 'your-org',
name: 'your-repo'
},
packages: {
strategy: 'patch',
ignore: ['@types/node']
}
}, '/path/to/project')
Core Methods
scanForUpdates()
Scans the project for available dependency updates.
interface BuddyMethods {
scanForUpdates: () => Promise<UpdateScanResult>
}
Returns
UpdateScanResult object containing:
interface UpdateScanResult {
updates: PackageUpdate[]
groups: UpdateGroup[]
metadata: {
scanTime: Date
strategy: string
packageCount: number
}
}
Example
const buddy = new Buddy(config)
const scanResult = await buddy.scanForUpdates()
console.log(`Found ${scanResult.updates.length} updates`)
scanResult.groups.forEach((group) => {
console.log(`${group.name}: ${group.updates.length} packages`)
})
createPullRequests()
Creates pull requests for dependency updates.
interface BuddyPRMethods {
createPullRequests: (scanResult: UpdateScanResult) => Promise<void>
}
Parameters
- scanResult (
UpdateScanResult): Result fromscanForUpdates()
Example
const scanResult = await buddy.scanForUpdates()
if (scanResult.updates.length > 0) {
await buddy.createPullRequests(scanResult)
console.log('Pull requests created successfully')
}
run()
Runs the complete update process (scan + create PRs).
interface BuddyRunMethod {
run: () => Promise<UpdateScanResult>
}
Returns
UpdateScanResult with the scan results
Example
const buddy = new Buddy(config)
const result = await buddy.run()
if (result.updates.length === 0) {
console.log('No updates available!')
}
else {
console.log(`Created PRs for ${result.groups.length} update groups`)
}
checkPackages()
Checks specific packages for updates.
interface BuddyCheckMethods {
checkPackages: (packageNames: string[]) => Promise<PackageUpdate[]>
}
Parameters
- packageNames (
string[]): Array of package names to check
Returns
Array of PackageUpdate objects
Example
const updates = await buddy.checkPackages(['react', 'typescript'])
updates.forEach((update) => {
console.log(`${update.name}: ${update.currentVersion} → ${update.newVersion}`)
})
Utility Methods
generateAllFileUpdates()
Generates file changes for all update types (package.json, dependency files, GitHub Actions).
interface FileChange {
path: string
content: string
type: 'update'
}
interface BuddyUtilityMethods {
generateAllFileUpdates: (updates: PackageUpdate[]) => Promise<FileChange[]>
}
Parameters
- updates (
PackageUpdate[]): Array of package updates
Returns
Array of file change objects
Example
const updates = await buddy.scanForUpdates()
const fileChanges = await buddy.generateAllFileUpdates(updates.updates)
fileChanges.forEach((change) => {
console.log(`Updated ${change.path}`)
// change.content contains the new file content
})
getConfig()
Returns the current configuration.
interface BuddyConfigMethods {
getConfig: () => BuddyConfig
}
Returns
The current BuddyConfig object
Example
const config = buddy.getConfig()
console.log(`Strategy: ${config.packages?.strategy}`)
Types
BuddyConfig
Main configuration interface:
interface BuddyConfig {
verbose?: boolean
repository?: {
provider: 'github' | 'gitlab' | 'bitbucket'
owner: string
name: string
baseBranch?: string
token?: string
}
packages?: {
strategy: 'major' | 'minor' | 'patch' | 'all'
ignore?: string[]
pin?: Record<string, string>
groups?: PackageGroup[]
}
pullRequest?: {
commitMessageFormat?: string
titleFormat?: string
bodyTemplate?: string
autoMerge?: {
enabled: boolean
strategy: 'merge' | 'squash' | 'rebase'
conditions?: string[]
}
reviewers?: string[]
assignees?: string[]
labels?: string[]
}
schedule?: {
cron?: string
timezone?: string
}
}
PackageUpdate
Represents a single package update:
interface PackageUpdate {
name: string
currentVersion: string
newVersion: string
updateType: 'major' | 'minor' | 'patch'
dependencyType: 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies'
repository?: string
homepage?: string
description?: string
changelog?: string
}
UpdateGroup
Groups related package updates:
interface UpdateGroup {
name: string
title: string
updates: PackageUpdate[]
strategy: string
}
UpdateScanResult
Result of scanning for updates:
interface UpdateScanResult {
updates: PackageUpdate[]
groups: UpdateGroup[]
metadata: {
scanTime: Date
strategy: string
packageCount: number
ignoredCount: number
}
}
Error Handling
The Buddy class throws errors for various failure scenarios:
Configuration Errors
try {
const buddy = new Buddy(invalidConfig)
}
catch (error) {
if (error.message.includes('Repository configuration required')) {
// Handle missing repository config
}
}
GitHub Token Errors
try {
await buddy.createPullRequests(scanResult)
}
catch (error) {
if (error.message.includes('GITHUB_TOKEN')) {
// Handle missing or invalid GitHub token
}
}
Network Errors
try {
const scanResult = await buddy.scanForUpdates()
}
catch (error) {
if (error.code === 'ENOTFOUND') {
// Handle network connectivity issues
}
}
Advanced Usage
Custom Package Groups
const buddy = new Buddy({
packages: {
strategy: 'all',
groups: [
{
name: 'React Ecosystem',
patterns: ['react', 'react-dom', '@types/react'],
strategy: 'minor'
},
{
name: 'Testing Tools',
patterns: ['jest', '@types/jest', 'testing-library/*'],
strategy: 'patch'
}
]
}
})
Conditional Updates
const scanResult = await buddy.scanForUpdates()
// Only create PRs for patch updates
const patchUpdates = scanResult.updates.filter(u => u.updateType === 'patch')
if (patchUpdates.length > 0) {
const patchScanResult = {
...scanResult,
updates: patchUpdates,
groups: scanResult.groups.map(g => ({
...g,
updates: g.updates.filter(u => u.updateType === 'patch')
})).filter(g => g.updates.length > 0)
}
await buddy.createPullRequests(patchScanResult)
}
Integration with CI/CD
import { Buddy } from '@buddysh/buddy'
async function updateDependencies() {
const buddy = new Buddy({
verbose: process.env.NODE_ENV === 'development',
repository: {
provider: 'github',
owner: process.env.GITHUB_OWNER!,
name: process.env.GITHUB_REPO!,
},
packages: {
strategy: process.env.UPDATE_STRATEGY as any || 'patch'
}
})
try {
const result = await buddy.run()
if (result.updates.length === 0) {
console.log('✅ All dependencies are up to date')
process.exit(0)
}
console.log(`✅ Created ${result.groups.length} PR(s) for ${result.updates.length} updates`)
}
catch (error) {
console.error('❌ Update failed:', error)
process.exit(1)
}
}
// Run in CI environment
if (process.env.CI) {
updateDependencies()
}