( superblocks: Filterable[], target?: Filter )
| 197 | } |
| 198 | |
| 199 | export function closestFilters( |
| 200 | superblocks: Filterable[], |
| 201 | target?: Filter |
| 202 | ): Filter | undefined { |
| 203 | // This is subjective, but should allow through typos while rejecting overly vague or unrelated filters. |
| 204 | const diceSorensenThreshold = 0.7; |
| 205 | |
| 206 | if (target?.superBlock) { |
| 207 | const superblockNames = superblocks.map(({ name }) => name); |
| 208 | |
| 209 | // If there are multiple superblocks, do not attempt to find a closest match. |
| 210 | if (target.superBlock.includes(',')) { |
| 211 | return target; |
| 212 | } |
| 213 | |
| 214 | const { closest, score } = closestMatch(target.superBlock, superblockNames); |
| 215 | |
| 216 | if (score < diceSorensenThreshold) { |
| 217 | throw Error( |
| 218 | `No close match found for superBlock: ${target.superBlock}. Found "${closest}", is that what you meant?` |
| 219 | ); |
| 220 | } |
| 221 | |
| 222 | return { |
| 223 | ...target, |
| 224 | superBlock: closest |
| 225 | }; |
| 226 | } |
| 227 | |
| 228 | if (target?.block) { |
| 229 | const blocks = superblocks.flatMap(({ blocks }) => |
| 230 | blocks.map(({ dashedName }) => dashedName) |
| 231 | ); |
| 232 | |
| 233 | const { closest, score } = closestMatch(target.block, blocks); |
| 234 | |
| 235 | if (score < diceSorensenThreshold) { |
| 236 | throw Error( |
| 237 | `No close match found for block: ${target.block}. Found "${closest}", is that what you meant?` |
| 238 | ); |
| 239 | } |
| 240 | |
| 241 | return { |
| 242 | ...target, |
| 243 | block: closest |
| 244 | }; |
| 245 | } |
| 246 | |
| 247 | return target; |
| 248 | } |
no test coverage detected