Skip to content

Instantly share code, notes, and snippets.

@RareScrap
Last active August 25, 2025 13:20
Show Gist options
  • Select an option

  • Save RareScrap/0ba9e5aba0f996a31538f2b7869d57ac to your computer and use it in GitHub Desktop.

Select an option

Save RareScrap/0ba9e5aba0f996a31538f2b7869d57ac to your computer and use it in GitHub Desktop.
import os from 'node:os';
export function getOsPlatformUsingPlatform(): NodeJS.Platform | undefined {
const sanitizedOsType = os.type().toLowerCase()
switch (sanitizedOsType) {
// Значения, представленные в документации os.type():
case "windows_nt": return "win32"
case "darwin": return "darwin"
case "linux": return "linux"
}
return undefined
}
export function getOsArchitectureUsingPlatform(osPlatform: NodeJS.Platform | undefined): NodeJS.Architecture | undefined {
const sanitizedOsMachine = os.machine().toLowerCase()
switch (sanitizedOsMachine) {
// Значения, представленные в документации os.machine():
case "arm": return "arm"
case "arm64": return "arm64"
case "aarch64": return "arm64"
case "mips": return "mips"
case "mips64": return "mips"
case "ppc64": return "ppc64"
case "ppc64le": return "ppc"
case "s390": return "s390"
case "s390x": return "s390x"
case "i386": return "ia32"
// Значение "i686" используется для обозначения x86 приложений, запущенных на x86_64 операционной системе:
// https://github.com/nodejs/node/issues/56975#issuecomment-2650606500
// https://github.com/nodejs/node/blob/b07ff551db152ccb507e71160ce077e235206b16/deps/uv/src/win/util.c#L1685
case "i686": {
// NodeJS имеет баг, не позволяющий в сборке под x86 точно определить разрядность операционной системы средствами его API
// https://github.com/nodejs/node/issues/58493
const isWindows = osPlatform === "win32"
if (isWindows) {
const windowsOsArchitecture = getWindowsOsArchitectureUsingPlatform()
return windowsOsArchitecture
}
return "x64"
}
case "x86_64": {
// Экспериментально подтверждено, что os.machine() на Windows для arm64 для сборок под x86_64
// Возвращает значение x86_64, не соответствующее фактической архитектуре операционной системы
const isWindows = osPlatform === "win32"
if (isWindows) {
const windowsOsArchitecture = getWindowsOsArchitectureUsingPlatform()
return windowsOsArchitecture
}
return "x64"
}
// Остальные значения, возвращаемые реализацией NodeJS:
// https://github.com/nodejs/node/blob/b07ff551db152ccb507e71160ce077e235206b16/deps/uv/src/win/util.c#L1667
// Неподдерживаемые значения:
// 1) DEC Aplha: "alpha"
// https://github.com/nodejs/node/blob/b07ff551db152ccb507e71160ce077e235206b16/deps/uv/src/win/util.c#L1692
// 2) SuperH: "shx"
// https://github.com/nodejs/node/blob/b07ff551db152ccb507e71160ce077e235206b16/deps/uv/src/win/util.c#L1698
case "ia64": return "x64"
case "powerpc": return "ppc"
// Значения, оставшиеся в NodeJS.Architecture (включено на всякий случай):
case "loong64": return "loong64"
case "mipsel": return "mipsel"
case "ppc": return "ppc"
case "riscv64": return "riscv64"
// Значения, выявленные экспериментально:
// Значение "unknown" может использоваться виртуализированными системами (пр. на Windows 11 под arm64 в Parallels Desktop на MacOS под arm64)
case "unknown": {
const isWindows = osPlatform === "win32"
if (isWindows) {
const windowsOsArchitecture = getWindowsOsArchitectureUsingPlatform()
return windowsOsArchitecture
}
return undefined
}
}
return undefined
}
export function getOsArchitectureEnvVar(osPlatform: NodeJS.Platform | undefined): string | undefined {
// Для лучшей точности в случае неопределенной платформы следует сначала обрабатывать переменные
// среды, специфичные для каждой операционной системы, и только после переходить к общим навроде HOSTTYPE
const isWindows = osPlatform === "win32"
if (isWindows || !osPlatform) {
const rawOsArchitecture = getWindowsOsArchitectureEnvVar()
if (isWindows) return rawOsArchitecture
const isMostLikelyWindows = !osPlatform && rawOsArchitecture
if (isMostLikelyWindows) return rawOsArchitecture
}
const osTypeEnvVar = process.env["OSTYPE"]
const isMacOs = osPlatform === "darwin" || (osTypeEnvVar?.startsWith("darwin") ?? false)
if (isMacOs || !osPlatform) {
// Экспериментально подтверждено, что MACHTYPE на MacOS для arm64 без использования Rosetta
// возвращает значение x86_64, не соответствующее фактической архитектуре операционной системы
const machTypeEnvVar = process.env["MACHTYPE"]
const cpuTypeEnvVar = process.env["CPUTYPE"]
const isValuesExpected = machTypeEnvVar && cpuTypeEnvVar && machTypeEnvVar.toLocaleLowerCase() === cpuTypeEnvVar.toLocaleLowerCase()
const rawOsArchitecture = isValuesExpected ? machTypeEnvVar : cpuTypeEnvVar
if (isMacOs) return rawOsArchitecture
const isMostLikelyMacOs = !osPlatform && rawOsArchitecture
if (isMostLikelyMacOs) return rawOsArchitecture
}
const isLinux = osPlatform === "linux"
if (isLinux || !osPlatform) {
const rawOsArchitecture = process.env["HOSTTYPE"] ?? process.env["MACHTYPE"]
if (isLinux) return rawOsArchitecture
const isMostLikelyLinux = !osPlatform && rawOsArchitecture
if (isMostLikelyLinux) return rawOsArchitecture
}
return undefined
}
function getWindowsOsArchitectureUsingPlatform(): NodeJS.Architecture | undefined {
const windowsOsArchitectureEnvVar = getWindowsOsArchitectureEnvVar()
if (windowsOsArchitectureEnvVar === undefined) return undefined
const sanitizedOsArchitectureEnvVar = windowsOsArchitectureEnvVar.toLowerCase()
switch (sanitizedOsArchitectureEnvVar) {
// Значения, представленные в документации win32:
// https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details#environment-variables
case "amd64": {
// Экспериментально подтверждено, что переменная PROCESSOR_ARCHITECTURE на Windows для arm64 для сборок под x86_64
// имеет значение AMD64, не соответствующее фактической архитектуре операционной системы
const programFilesArmEnvVar = process.env["ProgramFiles(Arm)"]
const isArm64 = programFilesArmEnvVar !== undefined
if (isArm64) return "arm64"
return "x64"
}
case "ia64": return "x64"
case "arm64": return "arm64"
case "x86": return "ia32"
}
return undefined
}
function getWindowsOsArchitectureEnvVar(): string | undefined {
// Несмотря на название, переменная среды PROCESSOR_ARCHITECTURE хранит архитектуру операционной системы, а не
// самого процессора (пр. на Windows на x86 на процессоре x86_64 переменная имеет значение `x86`)
const osArchitectureEnvVar = process.env["PROCESSOR_ARCHITECTURE"]
if (osArchitectureEnvVar === undefined) return undefined
const sanitizedOsArchitectureEnvVar = osArchitectureEnvVar.toLowerCase()
// При запуске 32-битного процесса (x86) на 64-битной операционной системе (x86_64, arm64)
// реальное содержимое PROCESSOR_ARCHITECTURE содержится в PROCESSOR_ARCHITEW6432
// https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details#environment-variables
const is32BitProcess = sanitizedOsArchitectureEnvVar === "x86"
if (is32BitProcess) {
const wowCpuArchitectureEnvVar = process.env["PROCESSOR_ARCHITEW6432"]
if (wowCpuArchitectureEnvVar) return wowCpuArchitectureEnvVar
}
return osArchitectureEnvVar
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment