(
paths: Iterable<string>,
options: ResolveImagesDirOptions = {}
)
| 217 | } |
| 218 | |
| 219 | export function resolveImagesDir( |
| 220 | paths: Iterable<string>, |
| 221 | options: ResolveImagesDirOptions = {} |
| 222 | ): string | null { |
| 223 | const counts = new Map<string, number>(); |
| 224 | for (const rawPath of paths) { |
| 225 | if (!isImageFilename(getBasename(rawPath))) { |
| 226 | continue; |
| 227 | } |
| 228 | // Prefer the canonical `images` root (images may be nested in per-camera |
| 229 | // subdirs); fall back to the immediate parent for non-conventional layouts. |
| 230 | const dir = findImagesRootDir(rawPath) ?? getParentDir(rawPath); |
| 231 | counts.set(dir, (counts.get(dir) ?? 0) + 1); |
| 232 | } |
| 233 | if (counts.size === 0) { |
| 234 | return null; |
| 235 | } |
| 236 | |
| 237 | let best: { dir: string; count: number; score: number } | null = null; |
| 238 | for (const [dir, count] of counts) { |
| 239 | const score = getImagesDirScore(dir, options.modelDir); |
| 240 | const better = |
| 241 | !best || |
| 242 | score > best.score || |
| 243 | (score === best.score && count > best.count) || |
| 244 | (score === best.score && count === best.count && dir.localeCompare(best.dir) < 0); |
| 245 | if (better) { |
| 246 | best = { dir, count, score }; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | return best?.dir ?? null; |
| 251 | } |
no test coverage detected