/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict * @format */ 'use strict'; const {dirname, join, parse} = require('path'); module.exports = class HasteFS { directories: Set<string>; directoryEntries: Map<string, Array<string>>; files: Set<string>; constructor(files: Array<string>) { this.directories = buildDirectorySet(files); this.directoryEntries = buildDirectoryEntries(files.map(parse)); this.files = new Set(files); } closest(path: string, fileName: string): ?string { const parsedPath = parse(path); const root = parsedPath.root; let dir = parsedPath.dir; do { const candidate = join(dir, fileName); if (this.files.has(candidate)) { return candidate; } dir = dirname(dir); } while (dir !== '.' && dir !== root); return null; } dirExists(path: string) { return this.directories.has(path); } exists(path: string) { return this.files.has(path); } getAllFiles() { /* $FlowFixMe(>=0.70.0 site=react_native_fb) This comment suppresses an * error found when Flow v0.70 was deployed. To see the error delete this * comment and run Flow. */ return Array.from(this.files.keys()); } matchFiles() { throw new Error('HasteFS.matchFiles is not implemented yet.'); } matches(directory: string, pattern: RegExp) { const entries = this.directoryEntries.get(directory); /* $FlowFixMe(>=0.70.0 site=react_native_fb) This comment suppresses an * error found when Flow v0.70 was deployed. To see the error delete this * comment and run Flow. */ return entries ? entries.filter(pattern.test, pattern) : []; } }; function buildDirectorySet(files) { const directories = new Set(); files.forEach(path => { const parsedPath = parse(path); const root = parsedPath.root; let dir = parsedPath.dir; while (dir !== '.' && dir !== root && !directories.has(dir)) { directories.add(dir); dir = dirname(dir); } }); return directories; } function buildDirectoryEntries(files) { const directoryEntries = new Map(); files.forEach(({base, dir}) => { const entries = directoryEntries.get(dir); if (entries) { entries.push(base); } else { directoryEntries.set(dir, [base]); } }); return directoryEntries; }