# `key-sanitizer` _(no submodules)_ ## Purpose Validates and normalises every caller-supplied storage key before any filesystem call. The sanitiser is the security boundary that prevents a caller-controlled key (`../../etc/passwd`) from escaping the configured `rootDir`. Every public method on `NodeFsStorage` passes its key through `sanitizeKey` before resolving any path or issuing any `node:fs` call. Failing the sanitiser is unrecoverable from the caller's perspective — it always reflects a programming error or a malicious input. ## Features - Rejects empty strings, `..` traversal segments, POSIX absolute paths (`/foo`), Windows drive-letter prefixed paths (`C:\foo`, `c:/foo`). - Rejects null bytes (`\x00`) and any control char in the C0 range (`0x00`–`0x1F`) plus DEL (`0x7F`). - Enforces a maximum length of `MAX_KEY_LENGTH` (1024) characters; over-length keys surface as `STORAGE_FILE.KEY_TOO_LONG` (a distinct code from `INVALID_KEY` so callers can hint at the truncation). - Normalises Windows `\` separators to POSIX `/` so the same key resolves identically on every platform. - Pure function — no allocation beyond the normalised string return; safe to call on every operation. ## Usage: Basic Example ```ts import { sanitizeKey } from "@suaveplan/storage-file"; const safe = sanitizeKey("orders/2026/05/12.json"); // → "orders/2026/05/12.json" ``` ## Usage: Advanced Example ```ts import { sanitizeKey, StorageFileError, STORAGE_FILE_CODES } from "@suaveplan/storage-file"; function safeKey(input: string): string | null { try { return sanitizeKey(input); } catch (err) { if (err instanceof StorageFileError && (err.code === STORAGE_FILE_CODES.INVALID_KEY || err.code === STORAGE_FILE_CODES.KEY_TOO_LONG)) { return null; } throw err; } } const normalised = sanitizeKey("orders\\2026\\05\\12.json"); // → "orders/2026/05/12.json" ``` ## API Reference - `sanitizeKey(key: string): string` — returns the normalised POSIX-separator form on success. - Throws `StorageFileError` with code `STORAGE_FILE.INVALID_KEY` on empty input, control chars, absolute paths, drive-letter prefix, or `..` traversal. - Throws `StorageFileError` with code `STORAGE_FILE.KEY_TOO_LONG` when input length exceeds `MAX_KEY_LENGTH` (1024). ## Implementation Notes - The control-char check iterates the string code unit by code unit rather than using a regex with a control-char range. This keeps biome's `noControlCharactersInRegex` lint happy without a suppression comment and is also marginally faster on short keys. - `..` is rejected segment-by-segment after `\\` normalisation, so both `foo\\..\\bar` and `foo/../bar` are caught. - Empty segments produced by consecutive separators (`foo//bar`) are NOT rejected — they are allowed for caller convenience and resolve to the same path. The host filesystem normalises them internally. - The key argument is not constrained beyond the rules above; arbitrary Unicode (including emoji and CJK) is permitted because `node:fs` accepts them and most modern filesystems do too.