/*
* 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.
*/
// ----------------------------------------------------------------------------
import { PlatformDetector } from '../classes/platform-detector.js'
// ============================================================================
/**
* Extracts an error message string from an unknown error value.
*
* @remarks
* This utility handles error values of any type, extracting the message
* property from `Error` instances or converting other types to strings.
* Useful for consistent error reporting when the error type is unknown.
*
* TypeScript's catch clause types errors as `unknown` for safety, since
* JavaScript allows throwing any value (not just `Error` instances). This
* function provides a type-safe way to extract a message string:
*
*
* - For Error instances: Returns the
message
* property.
* - For other types: Converts to string using
String(),
* which handles
* primitives, objects with toString(), null,
* and undefined gracefully.
*
*
* Common usage pattern:
* ```typescript
* try {
* // code that might throw
* } catch (error) {
* const message = getErrorMessage(error);
* log.error(message);
* }
* ```
*
* @param error - The error value to convert.
* @returns The error message string.
*/
export function getErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message
}
return String(error)
}
// ----------------------------------------------------------------------------
/**
* Builds a unique key using the current platform and architecture.
*
* @remarks
* Generates a platform identifier string used for matching binary packages
* to the current system or for platform-specific configuration.
*
* Platform key format: `-`
*
* Examples:
*
*
* darwin-x64 (macOS on Intel)
* darwin-arm64 (macOS on Apple Silicon)
* linux-x64 (Linux on 64-bit Intel/AMD)
* win32-x64 (Windows on 64-bit)
*
*
* Architecture coercion rules (when doForce32bit is true):
*
*
* - x64 → ia32: Coerces 64-bit Intel/AMD architecture to 32-bit
* on all platforms.
* - arm64 → arm: Coerces 64-bit ARM architecture to 32-bit
* on all platforms.
*
*
* This coercion is useful for backward compatibility scenarios where only
* 32-bit binaries are available but can run on 64-bit systems. The
* platform key matches the naming conventions used in binary xPack
* distributions.
*
* @param doForce32bit - Whether to coerce 64-bit architectures to
* their 32-bit equivalents.
* @param platformDetector - The platform detector instance to use. Defaults
* to a new {@link PlatformDetector} instance.
* @returns The platform key in the form `platform-arch`.
*/
export function getPlatformKey({
doForce32bit = false,
platformDetector = new PlatformDetector(),
}: {
doForce32bit?: boolean
platformDetector?: PlatformDetector
} = {}): string {
const { platform, arch } = platformDetector.getPlatformInfo({ doForce32bit })
const key = `${platform}-${arch}`
return key
}
// ----------------------------------------------------------------------------
/**
* Checks whether a string contains Liquid template syntax.
*
* @remarks
* This utility function detects the presence of Liquid template markers
* in a string, indicating that the string requires template processing.
*
* Liquid syntax patterns detected:
*
*
* - Variable output:
\{\{ marks the start of a variable
* interpolation (e.g., \{\{ package.name \}\}).
* - Control flow:
\{% marks the start of a tag
* for logic or iteration (e.g., \{% if condition %\},
* \{% for item in array %\}).
*
*
* The function uses a regular expression to efficiently scan the string
* for these markers without needing to check for both patterns separately.
* This is more efficient than calling includes() twice and
* provides a single point of maintenance for Liquid syntax detection logic.
*
* Common usage:
*
*
* - Determine whether to process a value through the Liquid engine.
* - Skip unnecessary template evaluation for static strings.
* - Validate configuration values for template content.
*
*
* @param value - The string to check for Liquid syntax.
* @returns true if the string contains Liquid syntax markers,
* false otherwise.
*/
export function hasLiquidSyntax(value: string): boolean {
return /\{\{|\{%/.test(value)
}
// ----------------------------------------------------------------------------