• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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