wip library to store cold objects in s3, warm objects on disk, and hot objects in memory
nodejs
typescript
1/**
2 * Encode a key to be safe for use as a filesystem path.
3 *
4 * @param key - The key to encode
5 * @returns Filesystem-safe encoded key
6 *
7 * @remarks
8 * Encodes characters that are problematic in filenames:
9 * - Forward slash (/) → %2F
10 * - Backslash (\) → %5C
11 * - Colon (:) → %3A
12 * - Asterisk (*) → %2A
13 * - Question mark (?) → %3F
14 * - Quote (") → %22
15 * - Less than (<) → %3C
16 * - Greater than (>) → %3E
17 * - Pipe (|) → %7C
18 * - Percent (%) → %25
19 * - Null byte → %00
20 *
21 * @example
22 * ```typescript
23 * const key = 'user:123/profile.json';
24 * const encoded = encodeKey(key);
25 * // Result: 'user%3A123%2Fprofile.json'
26 * ```
27 */
28export function encodeKey(key: string): string {
29 return key
30 .replace(/%/g, '%25') // Must be first!
31 .replace(/\//g, '%2F')
32 .replace(/\\/g, '%5C')
33 .replace(/:/g, '%3A')
34 .replace(/\*/g, '%2A')
35 .replace(/\?/g, '%3F')
36 .replace(/"/g, '%22')
37 .replace(/</g, '%3C')
38 .replace(/>/g, '%3E')
39 .replace(/\|/g, '%7C')
40 .replace(/\0/g, '%00');
41}
42
43/**
44 * Decode a filesystem-safe key back to original form.
45 *
46 * @param encoded - The encoded key
47 * @returns Original key
48 *
49 * @example
50 * ```typescript
51 * const encoded = 'user%3A123%2Fprofile.json';
52 * const key = decodeKey(encoded);
53 * // Result: 'user:123/profile.json'
54 * ```
55 */
56export function decodeKey(encoded: string): string {
57 return encoded
58 .replace(/%2F/g, '/')
59 .replace(/%5C/g, '\\')
60 .replace(/%3A/g, ':')
61 .replace(/%2A/g, '*')
62 .replace(/%3F/g, '?')
63 .replace(/%22/g, '"')
64 .replace(/%3C/g, '<')
65 .replace(/%3E/g, '>')
66 .replace(/%7C/g, '|')
67 .replace(/%00/g, '\0')
68 .replace(/%25/g, '%'); // Must be last!
69}