/**
 * Filename validation utilities.
 * Rejects invalid characters and reserved names (Windows compatibility).
 */
import { ErrorCode } from "@pocketcoder/shared/constants";
import { AppError } from "../errors/index.js";
/** Characters forbidden in filenames across platforms. */
// eslint-disable-next-line no-control-regex
const INVALID_CHARS = /[<>:"|?*\x00-\x1f]/;
/** Windows reserved device names (case-insensitive). */
const RESERVED_NAMES = new Set([
    "con",
    "prn",
    "aux",
    "nul",
    "com1",
    "com2",
    "com3",
    "com4",
    "com5",
    "com6",
    "com7",
    "com8",
    "com9",
    "lpt1",
    "lpt2",
    "lpt3",
    "lpt4",
    "lpt5",
    "lpt6",
    "lpt7",
    "lpt8",
    "lpt9",
]);
/**
 * Validates a filename (not a path — just the final component).
 * Throws AppError with INVALID_FILENAME on failure.
 */
export function validateFilename(filename) {
    if (!filename || filename.trim() === "") {
        throw new AppError(ErrorCode.INVALID_FILENAME, "Filename cannot be empty");
    }
    if (filename === "." || filename === "..") {
        throw new AppError(ErrorCode.INVALID_FILENAME, `"${filename}" is not a valid filename`);
    }
    if (INVALID_CHARS.test(filename)) {
        throw new AppError(ErrorCode.INVALID_FILENAME, "Filename contains invalid characters");
    }
    // Check reserved names (with or without extension, e.g. "con" and "con.txt")
    const nameWithoutExt = filename.split(".")[0].toLowerCase();
    if (RESERVED_NAMES.has(nameWithoutExt)) {
        throw new AppError(ErrorCode.INVALID_FILENAME, `"${filename}" is a reserved name`);
    }
}
//# sourceMappingURL=filename-validation.js.map