1import { 2 combinePaths, createPackageJsonInfo, Debug, forEachAncestorDirectory, getDirectoryPath, Map, Path, 3 ProjectPackageJsonInfo, Ternary, tryFileExists, 4} from "./_namespaces/ts"; 5import { ProjectService } from "./_namespaces/ts.server"; 6 7/** @internal */ 8export interface PackageJsonCache { 9 addOrUpdate(fileName: Path): void; 10 forEach(action: (info: ProjectPackageJsonInfo, fileName: Path) => void): void; 11 delete(fileName: Path): void; 12 get(fileName: Path): ProjectPackageJsonInfo | false | undefined; 13 getInDirectory(directory: Path): ProjectPackageJsonInfo | undefined; 14 directoryHasPackageJson(directory: Path): Ternary; 15 searchDirectoryAndAncestors(directory: Path): void; 16} 17 18/** @internal */ 19export function createPackageJsonCache(host: ProjectService): PackageJsonCache { 20 const packageJsons = new Map<string, ProjectPackageJsonInfo>(); 21 const directoriesWithoutPackageJson = new Map<string, true>(); 22 return { 23 addOrUpdate, 24 forEach: packageJsons.forEach.bind(packageJsons), 25 get: packageJsons.get.bind(packageJsons), 26 delete: fileName => { 27 packageJsons.delete(fileName); 28 directoriesWithoutPackageJson.set(getDirectoryPath(fileName), true); 29 }, 30 getInDirectory: directory => { 31 return packageJsons.get(combinePaths(directory, "package.json")) || undefined; 32 }, 33 directoryHasPackageJson, 34 searchDirectoryAndAncestors: directory => { 35 forEachAncestorDirectory(directory, ancestor => { 36 if (directoryHasPackageJson(ancestor) !== Ternary.Maybe) { 37 return true; 38 } 39 const packageJsonFileName = host.toPath(combinePaths(ancestor, "package.json")); 40 if (tryFileExists(host, packageJsonFileName)) { 41 addOrUpdate(packageJsonFileName); 42 } 43 else { 44 directoriesWithoutPackageJson.set(ancestor, true); 45 } 46 }); 47 }, 48 }; 49 50 function addOrUpdate(fileName: Path) { 51 const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host)); 52 packageJsons.set(fileName, packageJsonInfo); 53 directoriesWithoutPackageJson.delete(getDirectoryPath(fileName)); 54 } 55 56 function directoryHasPackageJson(directory: Path) { 57 return packageJsons.has(combinePaths(directory, "package.json")) ? Ternary.True : 58 directoriesWithoutPackageJson.has(directory) ? Ternary.False : 59 Ternary.Maybe; 60 } 61} 62