/* * This file is part of the xPack project (http://xpack.github.io). * Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software * for any purpose is hereby granted, under the terms of the MIT license. * * If a copy of the license was not distributed with this file, it can * be obtained from https://opensource.org/license/mit. */ // ---------------------------------------------------------------------------- /** * Platform information structure for runtime environment detection. * * @remarks * This interface encapsulates operating system and architecture information * used throughout the xPack library for platform-specific behaviour, * path filtering, and binary distribution selection. */ export interface PlatformInfo { /** * The operating system platform identifier. * * @remarks * Common values include: * *
darwin (macOS)linux (Linux)win32 (Windows)process.platform from Node.js.
*/
platform: string
/**
* The CPU architecture identifier.
*
* @remarks
* Common values include:
*
* x64 (64-bit Intel/AMD)arm64 (64-bit ARM)ia32 (32-bit Intel/AMD)arm (32-bit ARM)process.arch from Node.js.
*/
arch: string
}
/**
* Options for platform information retrieval.
*
* @remarks
* This interface defines configuration options that control how platform
* information is retrieved and processed, particularly for architecture
* coercion scenarios.
*/
export interface PlatformInfoOptions {
/**
* Whether to coerce 64-bit architectures to their 32-bit equivalents.
*
* @remarks
* When true, applies the following architecture mappings:
*
* x64 → ia32arm64 → armprocess.platform and
* process.arch access in business logic, making platform-specific
* code paths testable via mocked platform information.
*
* @example
* Default usage with actual runtime platform:
* ```typescript
* const detector = new PlatformDetector()
* const info = detector.getPlatformInfo()
* console.log(info.platform) // 'darwin', 'linux', or 'win32'
* console.log(info.arch) // 'x64', 'arm64', etc.
* ```
*
* @example
* Testing with mocked platform:
* ```typescript
* const mockProcess = {
* platform: 'darwin',
* arch: 'arm64'
* } as NodeJS.Process
*
* const detector = new PlatformDetector(mockProcess)
* const info = detector.getPlatformInfo({ doForce32bit: true })
* // info.platform === 'darwin'
* // info.arch === 'arm' (coerced from arm64)
* ```
*/
export class PlatformDetector {
// --------------------------------------------------------------------------
// Private Members.
/**
* The Node.js process object for accessing platform information.
*/
private readonly process: NodeJS.Process
// --------------------------------------------------------------------------
// Constructor.
/**
* Constructs a platform detector instance.
*
* @remarks
* This constructor accepts an optional process object parameter, enabling
* dependency injection for testing scenarios. When no process object is
* provided, the global Node.js process is used automatically.
*
* The injected process object must implement the platform and
* arch properties from the NodeJS.Process
* interface.
*
* @param _process - The Node.js process object providing platform and
* architecture information. Defaults to the global process
* object.
*/
constructor(_process: NodeJS.Process = globalThis.process) {
this.process = _process
}
// --------------------------------------------------------------------------
// Public Methods.
/**
* Retrieves current platform and architecture information.
*
* @remarks
* This method returns a {@link PlatformInfo} object containing the
* operating system platform and CPU architecture. When the
* doForce32bit option is enabled, 64-bit architectures
* are coerced to their 32-bit equivalents.
*
* Architecture coercion rules (when doForce32bit is
* true):
*
* darwin, linux,
* win32).
*
* @param options - Configuration options controlling platform information
* retrieval.
* @returns Platform and architecture information.
*/
getPlatformInfo(options: PlatformInfoOptions = {}): PlatformInfo {
const { doForce32bit = false } = options
let arch = this.process.arch
if (doForce32bit) {
// https://nodejs.org/docs/latest/api/process.html#processarch
if (arch === 'x64') {
arch = 'ia32'
} else if (arch === 'arm64') {
arch = 'arm'
}
}
return {
platform: this.process.platform,
arch,
}
}
/**
* Checks whether the current platform is Windows.
*
* @remarks
* This convenience method provides a simple boolean check for Windows
* platform detection, commonly used for path handling and command
* formatting decisions.
*
* Equivalent to checking platform === 'win32'.
*
* @returns true if running on Windows,
* false otherwise.
*/
isWindows(): boolean {
return this.process.platform === 'win32'
}
}
// ----------------------------------------------------------------------------