(store: string)
| 85 | } |
| 86 | |
| 87 | function validateStoreName(store: string): void { |
| 88 | if (!store) { |
| 89 | throw new Error('Invalid store name: store name must not be empty.') |
| 90 | } |
| 91 | if (store.length > MAX_STORE_NAME_LENGTH) { |
| 92 | throw new Error( |
| 93 | `Invalid store name: "${store.slice(0, 20)}…" is too long (max ${MAX_STORE_NAME_LENGTH} chars).`, |
| 94 | ) |
| 95 | } |
| 96 | // Reject path separators (forward slash, backslash), Windows drive colons. |
| 97 | // Null bytes checked separately to avoid biome noControlCharactersInRegex warning. |
| 98 | if (/[/\\:]/.test(store) || store.includes('\0')) { |
| 99 | throw new Error( |
| 100 | `Invalid store name: "${store}" contains illegal characters (path separators, null byte, or colon).`, |
| 101 | ) |
| 102 | } |
| 103 | // Reject names starting with "." — covers ".." and hidden names |
| 104 | if (store.startsWith('.')) { |
| 105 | throw new Error(`Invalid store name: "${store}" must not start with ".".`) |
| 106 | } |
| 107 | // Guard: resolved basename must equal the store name itself. |
| 108 | // This catches any path-like names that slipped through the above checks. |
| 109 | if (basename(store) !== store) { |
| 110 | throw new Error( |
| 111 | `Invalid store name: "${store}" is path-like and would escape the base directory.`, |
| 112 | ) |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | // validateKey is now imported from src/utils/localValidate.ts (shared with PR-1/2) |
| 117 |
no outgoing calls
no test coverage detected