Extending the Aliases System
ts-pkgx includes a built-in aliases system that maps common package names to their full domain names. You can extend this system to customize it for your specific needs.
Understanding the Aliases System
The aliases system is a simple mapping from shorthand names to full domain names:
import { PACKAGE_ALIASES } from 'ts-pkgx/fetch'
// Examine the built-in aliases
console.log(PACKAGE_ALIASES)
The default aliases include mappings like:
const PACKAGE_ALIASES: Record<string, string> = {
node: 'nodejs.org',
python: 'python.org',
go: 'go.dev',
rust: 'rust-lang.org',
ruby: 'ruby-lang.org',
php: 'php.net',
perl: 'perl.org',
deno: 'deno.land',
bun: 'bun.sh',
// ... and many more
}
Adding Custom Aliases
You can add your own aliases to the system:
import { PACKAGE_ALIASES } from 'ts-pkgx/fetch'
// Add custom aliases
function extendAliases(customAliases: Record<string, string>): void {
Object.entries(customAliases).forEach(([alias, domain]) => {
if (!PACKAGE_ALIASES[alias]) {
PACKAGE_ALIASES[alias] = domain
console.log(`Added alias: ${alias} -> ${domain}`)
}
})
}
// Usage
extendAliases({
js: 'nodejs.org',
py: 'python.org',
rs: 'rust-lang.org',
bunjs: 'bun.sh',
})
This allows you to use your preferred shorthand names when fetching packages.
Organization-Specific Aliases
For teams or organizations, you might want to create a set of standardized aliases:
// Organization-specific aliases for a team
const ORGANIZATION_ALIASES: Record<string, string> = {
'web-server': 'nginx.org',
'db': 'postgresql.org',
'cache': 'redis.io',
'mq': 'rabbitmq.com',
'search': 'elastic.co',
'frontend': 'reactjs.org',
}
// Extend the standard aliases with organization-specific ones
extendAliases(ORGANIZATION_ALIASES)
Creating Category Aliases
You can create aliases that represent categories of packages:
// Map categories to their representative package
const CATEGORY_ALIASES: Record<string, string> = {
'js-runtime': 'nodejs.org',
'py-runtime': 'python.org',
'database': 'postgresql.org',
'container': 'docker.com',
'orchestration': 'kubernetes.io',
}
extendAliases(CATEGORY_ALIASES)
Aliases for Nested Paths
For packages with nested paths, you can create aliases for easier access:
// Aliases for nested paths
const NESTED_PATH_ALIASES: Record<string, string> = {
'git-crypt': 'agwa.name/git-crypt',
'bun-create': 'github.com/oven-sh/create-bun',
'cargo-generate': 'github.com/cargo-generate/cargo-generate',
}
extendAliases(NESTED_PATH_ALIASES)
Version-Specific Aliases
You can create aliases for specific versions of packages:
// Aliases for specific versions
const VERSION_ALIASES: Record<string, string> = {
'node16': 'nodejs.org@16',
'node18': 'nodejs.org@18',
'node20': 'nodejs.org@20',
'python3.9': 'python.org@3.9',
'python3.10': 'python.org@3.10',
}
// You would need to modify the resolver to handle the version part
function resolveVersionedAlias(alias: string): { domain: string, version?: string } {
if (VERSION_ALIASES[alias]) {
const [domain, version] = VERSION_ALIASES[alias].split('@')
return { domain, version }
}
if (PACKAGE_ALIASES[alias]) {
return { domain: PACKAGE_ALIASES[alias] }
}
return { domain: alias }
}
Persisting Custom Aliases
For persistent customization, you can save and load your aliases:
import fs from 'node:fs'
import path from 'node:path'
const ALIASES_FILE = path.join(process.cwd(), 'pkgx-aliases.json')
// Save aliases to a file
function saveAliases(): void {
fs.writeFileSync(ALIASES_FILE, JSON.stringify(PACKAGE_ALIASES, null, 2))
console.log(`Saved aliases to ${ALIASES_FILE}`)
}
// Load aliases from a file
function loadAliases(): void {
if (fs.existsSync(ALIASES_FILE)) {
try {
const aliases = JSON.parse(fs.readFileSync(ALIASES_FILE, 'utf8'))
extendAliases(aliases)
console.log(`Loaded aliases from ${ALIASES_FILE}`)
}
catch (error) {
console.error('Error loading aliases:', error)
}
}
}
// Initialize aliases when your application starts
loadAliases()
// Save aliases when your application exits
process.on('exit', saveAliases)
Generating Aliases Automatically
You can generate aliases automatically based on domain patterns:
import { pantry } from 'ts-pkgx'
// Generate aliases for all packages
function generateAliases(): Record<string, string> {
const generatedAliases: Record<string, string> = {}
for (const [domain, pkg] of Object.entries(pantry)) {
// Basic name alias (remove spaces and lowercase)
const nameAlias = pkg.name.toLowerCase().replace(/\s+/g, '')
if (!PACKAGE_ALIASES[nameAlias] && nameAlias !== domain) {
generatedAliases[nameAlias] = domain
}
// First word of the domain (before the dot)
const domainFirstPart = domain.split('.')[0]
if (!PACKAGE_ALIASES[domainFirstPart] && domainFirstPart !== domain) {
generatedAliases[domainFirstPart] = domain
}
// For packages with programs, use the main program name as an alias
if (pkg.programs.length > 0) {
const mainProgram = pkg.programs[0]
if (!PACKAGE_ALIASES[mainProgram] && mainProgram !== domain) {
generatedAliases[mainProgram] = domain
}
}
}
return generatedAliases
}
// Generate and extend aliases
const autoAliases = generateAliases()
extendAliases(autoAliases)
CLI for Alias Management
You can add CLI commands to manage aliases:
cli
.command('alias <name> <domain>', 'Add a package alias')
.action((name, domain) => {
PACKAGE_ALIASES[name] = domain
console.log(`Added alias: ${name} -> ${domain}`)
saveAliases()
})
cli
.command('aliases', 'List all package aliases')
.action(() => {
console.log('Package aliases:')
Object.entries(PACKAGE_ALIASES)
.sort(([a], [b]) => a.localeCompare(b))
.forEach(([alias, domain]) => {
console.log(` ${alias.padEnd(15)} -> ${domain}`)
})
})
cli
.command('remove-alias <name>', 'Remove a package alias')
.action((name) => {
if (PACKAGE_ALIASES[name]) {
const domain = PACKAGE_ALIASES[name]
delete PACKAGE_ALIASES[name]
console.log(`Removed alias: ${name} -> ${domain}`)
saveAliases()
}
else {
console.error(`Alias not found: ${name}`)
}
})
These extensions to the aliases system allow you to customize ts-pkgx to fit your specific workflow and preferences.