-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocket-btm-binary-naming.ts
More file actions
186 lines (174 loc) · 6.46 KB
/
socket-btm-binary-naming.ts
File metadata and controls
186 lines (174 loc) · 6.46 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/**
* @file Socket-btm binary asset/platform-arch naming helpers.
*/
import type { Arch, Libc, Platform } from '../constants/platform'
import { ErrorCtor } from '../primordials/error'
/**
* Map Node.js platform to socket-btm asset platform naming. Identity mapping:
* asset names use `process.platform` verbatim (`darwin`, `linux`, `win32`) to
* align with pnpm's pack-app, the `--os` / `supportedArchitectures.os` config
* keys, and the `@pnpm/exe.<os>-<arch>` package convention.
*/
const PLATFORM_MAP = {
__proto__: null,
darwin: 'darwin',
linux: 'linux',
win32: 'win32',
} as unknown as Record<string, string>
/**
* Map Node.js arch to socket-btm asset arch naming.
*/
const ARCH_MAP = {
__proto__: null,
arm64: 'arm64',
x64: 'x64',
} as unknown as Record<string, string>
/**
* Get asset name for a socket-btm binary.
*
* @example
* ;```typescript
* getBinaryAssetName('lief', 'linux', 'x64', 'musl')
* // 'lief-linux-x64-musl'
* ```
*
* @param binaryBaseName - Binary basename (e.g., 'binject', 'node')
* @param platform - Target platform.
* @param arch - Target architecture.
* @param libc - Linux libc variant (optional)
*
* @returns Asset name (e.g., 'binject-darwin-arm64', 'node-linux-x64-musl')
*/
export function getBinaryAssetName(
binaryBaseName: string,
platform: Platform,
arch: Arch,
libc?: Libc | undefined,
): string {
const mappedArch = ARCH_MAP[arch]
if (!mappedArch) {
throw new ErrorCtor(`Unsupported architecture: ${arch}`)
}
const muslSuffix = platform === 'linux' && libc === 'musl' ? '-musl' : ''
const ext = platform === 'win32' ? '.exe' : ''
if (platform === 'darwin') {
return `${binaryBaseName}-darwin-${mappedArch}${ext}`
}
if (platform === 'linux') {
return `${binaryBaseName}-linux-${mappedArch}${muslSuffix}${ext}`
}
if (platform === 'win32') {
return `${binaryBaseName}-win32-${mappedArch}${ext}`
}
throw new ErrorCtor(`Unsupported platform: ${platform}`)
}
/**
* Get binary filename for output.
*
* @example
* ;```typescript
* getBinaryName('node', 'win32') // 'node.exe'
* getBinaryName('node', 'linux') // 'node'
* ```
*
* @param binaryBaseName - Binary basename (e.g., 'node', 'binject')
* @param platform - Target platform.
*
* @returns Binary filename (e.g., 'node', 'node.exe')
*/
export function getBinaryName(
binaryBaseName: string,
platform: Platform,
): string {
return platform === 'win32' ? `${binaryBaseName}.exe` : binaryBaseName
}
/**
* Get platform-arch identifier for directory structure and asset names.
*
* # Format: `<os>-<arch>[-<libc>]`
*
* The OS segment is `process.platform` verbatim: `darwin` / `linux` / `win32`.
* The arch segment is `process.arch` verbatim: `x64` / `arm64`. The optional
* libc suffix is `-musl` (Linux only; the glibc default is unsuffixed to match
* Node.js's own linuxstatic convention).
*
* # Why these specific conventions
*
* ## Why `win32`, not `win`
*
* `win32` is what `process.platform` returns on every Windows host. Every npm
* package whose install-time platform filter uses the standard `os` / `cpu` /
* `libc` manifest fields must match `process.platform` strings exactly (npm
* compares them verbatim — there's no shorthand layer). Using `win` internally
* here would have forced a translation every time we constructed an install
* filter or a target triple, and reviewers would have to remember "we
* abbreviate on disk but not in package filters." Since the two now match,
* there's no translation step to get wrong.
*
* Pnpm's pack-app (v11+) accepts `<os>-<arch>[-<libc>]` target strings and its
* shards are `@pnpm/exe.<os>-<arch>` (with `win32`, not `win` — see
* pnpm#11314). Our naming matches so asset names we emit can flow directly into
* pack-app's `--target` arg, `pnpm.app.targets` config, and
* sibling-package-name construction without a translation map.
*
* ## Why `-musl` is the suffix (and glibc is unsuffixed)
*
* Node.js's own linuxstatic tarballs historically used the unqualified `linux`
* for glibc and a separate download channel for musl. The pnpm ecosystem
* codified that as `linux-<arch>` (glibc, default) and `linux-<arch>-musl` (the
* libc outlier), matching the asymmetric reality of Linux distros — glibc is
* the majority case, musl is Alpine-and-similar. Adding `-glibc` for the
* default would be redundant noise in the name.
*
* ## Why libc is only appended for Linux
*
* MacOS and Windows have exactly one system libc each (Apple libSystem,
* Microsoft UCRT). A hypothetical `darwin-arm64-libsystem` conveys no
* information. Node.js, npm, and pnpm all treat libc as a Linux-only axis; we
* follow the same convention so callers don't have to special- case
* `'darwin-arm64'.startsWith('darwin-arm64')` style matches.
*
* ## Why this function exists at all (vs. inlining)
*
* Two upstream APIs that socket-btm consumers end up calling — the npm manifest
* filter (`os`/`cpu`/`libc`) and pnpm's pack-app `--target` — both need the
* exact same triple format. Centralizing the construction here means a future
* schema change (e.g. Node introducing `riscv64`) gets one edit, and the error
* message for an unsupported platform is uniform across downloaders, pack-app
* invocations, and the `@socketbin/*` resolver logic.
*
* @example
* ;```typescript
* getPlatformArch('linux', 'x64', 'musl') // 'linux-x64-musl'
* getPlatformArch('darwin', 'arm64') // 'darwin-arm64'
* getPlatformArch('win32', 'x64') // 'win32-x64'
* getPlatformArch('darwin', 'x64', 'musl') // 'darwin-x64' — libc ignored
* ```
*
* @param platform - Target platform.
* @param arch - Target architecture.
* @param libc - Linux libc variant (optional; non-linux platforms ignore)
*
* @returns Platform-arch identifier (e.g., 'darwin-arm64', 'linux-x64-musl',
* 'win32-x64')
*/
export function getPlatformArch(
platform: Platform,
arch: Arch,
libc?: Libc | undefined,
): string {
/* c8 ignore start - Unsupported-platform/arch arms fire only on inputs
outside the PLATFORM_MAP / ARCH_MAP keysets; the musl-suffix arm fires
only on linux+musl combos. */
const mappedPlatform = PLATFORM_MAP[platform]
if (!mappedPlatform) {
throw new ErrorCtor(`Unsupported platform: ${platform}`)
}
const mappedArch = ARCH_MAP[arch]
if (!mappedArch) {
throw new ErrorCtor(`Unsupported architecture: ${arch}`)
}
const muslSuffix = platform === 'linux' && libc === 'musl' ? '-musl' : ''
return `${mappedPlatform}-${mappedArch}${muslSuffix}`
/* c8 ignore stop */
}