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