UNPKG

@twocaretcat/astro-snapshot

Version:

An Astro integration for generating screenshots of your pages automatically at build time. Perfect for creating social images, content previews, dynamic icons, and more!

113 lines (112 loc) 3.62 kB
/** * Utility functions for the Astro Snapshot integration. * * @module */ import { access } from 'node:fs/promises'; import { styleText } from 'node:util'; /** * Extracts and normalizes the image format from a given file path. * * Determines the file extension following the last period (".") in the path, * ensuring it is part of the filename (not a directory). The function * normalizes certain extensions (e.g., `"jpg"` → `"jpeg"`) and validates * that the format is supported. * * @param path - The file path to extract the format from. * @returns The normalized image format as a {@link Format}. * * @throws {Error} If no valid file extension is found or the extension is unsupported. * * @example * ```ts * getFormat('/images/photo.jpg'); // 'jpeg' * getFormat('C:\\assets\\icon.webp'); // 'webp' * getFormat('file.png'); // 'png' * ``` */ export function getFormat(path) { const lastDot = path.lastIndexOf('.'); const lastSlash = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')); // No dot, or dot is part of a directory (e.g., ".config/file") if (lastDot <= lastSlash) { throw new Error('No file extension found'); } const extension = path.slice(lastDot + 1); if (extension === 'jpg' || extension === 'jpeg') { return 'jpeg'; } if (extension === 'png' || extension === 'webp') { return extension; } throw new Error('Unsupported extension'); } /** * Checks if a file exists at the given path. * * @param path - The file path to check. * @returns A promise that resolves to `true` if the file exists, `false` otherwise. * * @example * ```ts * if (await fileExists('/path/to/file.png')) { * console.log('File exists'); * } * ``` */ export async function fileExists(path) { try { await access(path); return true; } catch { return false; } } /** * Logs a status message showing input/output file paths with optional warning. * * @param logger - The Astro integration logger instance to use for output * @param inputPath - The source file path to display * @param outputPath - The destination file path to display * @param warningLabel - Optional warning text to append. If provided, logs as warning in yellow; otherwise logs as info in green * * @example * ```ts * logStatus(logger, 'src/input.ts', 'dist/output.js'); * // Outputs (green): ▶ src/input.ts → dist/output.js * * logStatus(logger, 'src/input.ts', 'dist/output.js', 'skipped'); * // Outputs (yellow): ▶ src/input.ts → dist/output.js (skipped) * ``` */ export function logStatus(logger, inputPath, outputPath, warningLabel) { const [method, color, status] = warningLabel ? ['warn', 'yellow', ` ${styleText('dim', `(${warningLabel})`)}`] : ['info', 'green', '']; const bullet = styleText(color, '▶'); const io = `${inputPath}${outputPath}`; logger[method](` ${bullet} ${io}${status}`); } /** * Formats a duration in milliseconds as a human-readable string. * * Values under 1000ms are displayed as whole milliseconds (e.g., "53ms"). * Values 1000ms and above are displayed as seconds with one decimal place (e.g., "1.4s"). * * @param ms - The duration in milliseconds to format * @returns A formatted duration string with appropriate unit suffix * * @example * ```ts * formatDuration(53); // "53ms" * formatDuration(1400); // "1.4s" * formatDuration(5230); // "5.2s" * ``` */ export function formatDuration(ms) { if (ms < 1000) { return `${Math.round(ms)}ms`; } return `${(ms / 1000).toFixed(1)}s`; }