wip library to store cold objects in s3, warm objects on disk, and hot objects in memory
nodejs typescript
at main 1.5 kB view raw
1/** 2 * Simple glob pattern matching for key placement rules. 3 * 4 * Supports: 5 * - `*` matches any characters except `/` 6 * - `**` matches any characters including `/` (including empty string) 7 * - `{a,b,c}` matches any of the alternatives 8 * - Exact strings match exactly 9 */ 10export function matchGlob(pattern: string, key: string): boolean { 11 // Handle exact match 12 if (!pattern.includes('*') && !pattern.includes('{')) { 13 return pattern === key; 14 } 15 16 // Escape regex special chars (except * and {}) 17 let regex = pattern.replace(/[.+^$|\\()[\]]/g, '\\$&'); 18 19 // Handle {a,b,c} alternation 20 regex = regex.replace(/\{([^}]+)\}/g, (_, alts) => `(${alts.split(',').join('|')})`); 21 22 // Use placeholder to avoid double-processing 23 const DOUBLE = '\x00DOUBLE\x00'; 24 const SINGLE = '\x00SINGLE\x00'; 25 26 // Mark ** and * with placeholders 27 regex = regex.replace(/\*\*/g, DOUBLE); 28 regex = regex.replace(/\*/g, SINGLE); 29 30 // Replace placeholders with regex patterns 31 // ** matches anything (including /) 32 // When followed by /, it's optional (matches zero or more path segments) 33 regex = regex 34 .replace(new RegExp(`${DOUBLE}/`, 'g'), '(?:.*/)?') // **/ -> optional path prefix 35 .replace(new RegExp(`/${DOUBLE}`, 'g'), '(?:/.*)?') // /** -> optional path suffix 36 .replace(new RegExp(DOUBLE, 'g'), '.*') // ** alone -> match anything 37 .replace(new RegExp(SINGLE, 'g'), '[^/]*'); // * -> match non-slash 38 39 return new RegExp(`^${regex}$`).test(key); 40}