[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at eac8537f4da5f46fc166b0e041d492d8091dfbca 141 lines 3.9 kB view raw
1import type { JsrPackageInfo } from '#shared/types/jsr' 2import { getCreateShortName } from '#shared/utils/package-analysis' 3 4// @unocss-include 5export const packageManagers = [ 6 { 7 id: 'npm', 8 label: 'npm', 9 action: 'install', 10 executeLocal: 'npx', 11 executeRemote: 'npx', 12 create: 'npm create', 13 icon: 'i-simple-icons:npm', 14 }, 15 { 16 id: 'pnpm', 17 label: 'pnpm', 18 action: 'add', 19 executeLocal: 'pnpm exec', 20 executeRemote: 'pnpm dlx', 21 create: 'pnpm create', 22 icon: 'i-simple-icons:pnpm', 23 }, 24 { 25 id: 'yarn', 26 label: 'yarn', 27 action: 'add', 28 // For both yarn v1 and v2+ support 29 // local exec defers to npx instead 30 executeLocal: 'npx', 31 executeRemote: 'yarn dlx', 32 create: 'yarn create', 33 icon: 'i-simple-icons:yarn', 34 }, 35 { 36 id: 'bun', 37 label: 'bun', 38 action: 'add', 39 executeLocal: 'bunx', 40 executeRemote: 'bunx', 41 create: 'bun create', 42 icon: 'i-simple-icons:bun', 43 }, 44 { 45 id: 'deno', 46 label: 'deno', 47 action: 'add', 48 executeLocal: 'deno run', 49 executeRemote: 'deno run', 50 create: 'deno run', 51 icon: 'i-simple-icons:deno', 52 }, 53 { 54 id: 'vlt', 55 label: 'vlt', 56 action: 'install', 57 executeLocal: 'vlx', 58 executeRemote: 'vlx', 59 create: 'vlx', 60 icon: 'i-custom-vlt', 61 }, 62] as const 63 64export type PackageManagerId = (typeof packageManagers)[number]['id'] 65 66export interface InstallCommandOptions { 67 packageName: string 68 packageManager: PackageManagerId 69 version?: string | null 70 jsrInfo?: JsrPackageInfo | null 71} 72 73/** 74 * Get the package specifier for a given package manager. 75 * Handles jsr: prefix for deno (when available on JSR). 76 */ 77export function getPackageSpecifier(options: InstallCommandOptions): string { 78 const { packageName, packageManager, jsrInfo } = options 79 80 if (packageManager === 'deno') { 81 if (jsrInfo?.exists && jsrInfo.scope && jsrInfo.name) { 82 // Native JSR package: jsr:@scope/name 83 return `jsr:@${jsrInfo.scope}/${jsrInfo.name}` 84 } 85 // npm compatibility: npm:package 86 return `npm:${packageName}` 87 } 88 89 // Standard package managers (npm, pnpm, yarn, bun, vlt) 90 return packageName 91} 92 93/** 94 * Generate the full install command for a package. 95 */ 96export function getInstallCommand(options: InstallCommandOptions): string { 97 return getInstallCommandParts(options).join(' ') 98} 99 100/** 101 * Generate install command as an array of parts. 102 * First element is the command (e.g., "npm"), rest are arguments. 103 * Useful for rendering with different styling for command vs args. 104 */ 105export function getInstallCommandParts(options: InstallCommandOptions): string[] { 106 const pm = packageManagers.find(p => p.id === options.packageManager) 107 if (!pm) return [] 108 109 const spec = getPackageSpecifier(options) 110 const version = options.version ? `@${options.version}` : '' 111 112 return [pm.label, pm.action, `${spec}${version}`] 113} 114 115export interface ExecuteCommandOptions extends InstallCommandOptions { 116 /** Whether this is a binary-only package (download & run vs local run) */ 117 isBinaryOnly?: boolean 118 /** Whether this is a create-* package (uses shorthand create command) */ 119 isCreatePackage?: boolean 120} 121 122export function getExecuteCommand(options: ExecuteCommandOptions): string { 123 return getExecuteCommandParts(options).join(' ') 124} 125 126export function getExecuteCommandParts(options: ExecuteCommandOptions): string[] { 127 const pm = packageManagers.find(p => p.id === options.packageManager) 128 if (!pm) return [] 129 130 // For create-* packages, use the shorthand create command 131 if (options.isCreatePackage) { 132 const shortName = getCreateShortName(options.packageName) 133 if (shortName !== options.packageName) { 134 return [...pm.create.split(' '), shortName] 135 } 136 } 137 138 // Choose remote or local execute based on package type 139 const executeCmd = options.isBinaryOnly ? pm.executeRemote : pm.executeLocal 140 return [...executeCmd.split(' '), getPackageSpecifier(options)] 141}