( sourceLocale: string, include: BucketItem[], exclude?: BucketItem[], )
| 98 | } |
| 99 | |
| 100 | function extractPathPatterns( |
| 101 | sourceLocale: string, |
| 102 | include: BucketItem[], |
| 103 | exclude?: BucketItem[], |
| 104 | ) { |
| 105 | // WHY: with recursive ** support a broad pattern can subsume narrower ones |
| 106 | // (e.g. "src/**/[locale].json" + "src/[locale].json"), so we dedupe by the |
| 107 | // (pathPattern, delimiter) pair before returning. |
| 108 | const uniqKey = (item: { |
| 109 | pathPattern: string; |
| 110 | delimiter?: LocaleDelimiter; |
| 111 | }) => `${item.pathPattern}::${item.delimiter ?? ""}`; |
| 112 | const includedPatterns = _.uniqBy( |
| 113 | include.flatMap((pattern) => |
| 114 | expandPlaceholderedGlob( |
| 115 | pattern.path, |
| 116 | resolveOverriddenLocale(sourceLocale, pattern.delimiter), |
| 117 | ).map((pathPattern) => ({ |
| 118 | pathPattern, |
| 119 | delimiter: pattern.delimiter, |
| 120 | })), |
| 121 | ), |
| 122 | uniqKey, |
| 123 | ); |
| 124 | const excludedPatterns = exclude?.flatMap((pattern) => |
| 125 | expandPlaceholderedGlob( |
| 126 | pattern.path, |
| 127 | resolveOverriddenLocale(sourceLocale, pattern.delimiter), |
| 128 | ).map((pathPattern) => ({ |
| 129 | pathPattern, |
| 130 | delimiter: pattern.delimiter, |
| 131 | })), |
| 132 | ); |
| 133 | // WHY: exclude semantics are about path subtraction, not delimiter matching. |
| 134 | // Pre-PR `differenceBy` keyed on `item.pathPattern` only, so an exclude entry |
| 135 | // with a different (or missing) delimiter still cancelled a matching include. |
| 136 | // Keep that contract — only `uniqBy` above needs to distinguish delimiters, |
| 137 | // because there a different delimiter means a genuinely different bucket |
| 138 | // entry, not a redundant duplicate. |
| 139 | const result = _.differenceBy( |
| 140 | includedPatterns, |
| 141 | excludedPatterns ?? [], |
| 142 | (item) => item.pathPattern, |
| 143 | ); |
| 144 | return result; |
| 145 | } |
| 146 | |
| 147 | // Windows path normalization helper function |
| 148 | function normalizePath(filepath: string): string { |
no test coverage detected