Files
orca/src/shared/node-dist-mirror.ts
T
Neil 66d37178da feat(ssh): let a nodejs.org mirror serve the pinned Node on this computer and the host (#30981)
* feat(ssh): let a nodejs.org mirror serve the pinned Node on both machines

* fix(ssh): share one deadline across every host download URL

* fix(ssh): give each host download URL its share of the deadline and cap its size

* refactor(ssh): one tool per host, labelled sources and a portable wget watchdog

* fix(ssh): quote this computer's short download reason in the combined error

* fix(ssh): fetch only validated mirror URLs on the host

* fix(ssh): drop an empty query or fragment from the mirror URL

* fix(ssh): keep a cancel or a local error as it is after the mirror fails
2026-10-19 20:52:44 -07:00

61 lines
2.4 KiB
TypeScript

/**
* A mirror of nodejs.org/dist (an internal artifact proxy, or a regional mirror) for the pinned
* Node runtime. It only changes where bytes come from: the SHA-256 pin decides what is accepted.
*/
/** The variables Node tooling already reads for the same mirror; read on this computer only. */
export const NODE_DIST_MIRROR_ENV_KEYS = ['NODEJS_ORG_MIRROR', 'NVM_NODEJS_ORG_MIRROR'] as const
export type NodeDistMirrorValidationResult =
| { ok: true; value: string; message?: undefined }
| { ok: false; value: ''; message: string }
const NODE_DIST_MIRROR_MAX_LENGTH = 2048
/** An http(s) base URL with no query or fragment and no trailing slash; empty means none. */
export function normalizeNodeDistMirrorUrl(value: unknown): NodeDistMirrorValidationResult {
const trimmed = typeof value === 'string' ? value.trim() : ''
if (!trimmed) {
return { ok: true, value: '' }
}
if (trimmed.length > NODE_DIST_MIRROR_MAX_LENGTH) {
return { ok: false, value: '', message: 'Mirror URL is too long.' }
}
let parsed: URL
try {
parsed = new URL(trimmed)
} catch {
return { ok: false, value: '', message: 'Enter a valid mirror URL.' }
}
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
return { ok: false, value: '', message: 'Use an http or https mirror URL.' }
}
// Why: the URL reaches SSH hosts and error text; credentials belong in the proxy setting.
if (parsed.username || parsed.password) {
return { ok: false, value: '', message: 'Mirror URL cannot contain a user name or password.' }
}
if (parsed.search || parsed.hash) {
return { ok: false, value: '', message: 'Mirror URL cannot have a query or fragment.' }
}
// Why origin + pathname: href keeps an empty `?` or `#`, which would swallow the archive path.
return { ok: true, value: `${parsed.origin}${parsed.pathname}`.replace(/\/+$/u, '') }
}
/** The first valid mirror among Orca's setting and the conventional environment variables. */
export function resolveNodeDistMirror(
setting: string | undefined,
env: Record<string, string | undefined>
): string | null {
for (const candidate of [setting, ...NODE_DIST_MIRROR_ENV_KEYS.map((key) => env[key])]) {
const normalized = normalizeNodeDistMirrorUrl(candidate)
if (normalized.ok && normalized.value) {
return normalized.value
}
}
return null
}
export function nodeDistMirrorUrl(mirror: string, version: string, file: string): string {
return `${mirror}/v${version}/${file}`
}