cspell-lib 8.17.2 → 8.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,35 @@
1
1
  import type { VFileSystem } from '../../../fileSystem.js';
2
2
  export declare class ConfigSearch {
3
- readonly searchPlaces: readonly string[];
3
+ #private;
4
+ /**
5
+ * @param searchPlaces - The list of file names to search for.
6
+ * @param allowedExtensionsByProtocol - Map of allowed extensions by protocol, '*' is used to match all protocols.
7
+ * @param fs - The file system to use.
8
+ */
9
+ constructor(searchPlaces: readonly string[], allowedExtensionsByProtocol: Map<string, readonly string[]>, fs: VFileSystem);
10
+ searchForConfig(searchFromURL: URL): Promise<URL | undefined>;
11
+ clearCache(): void;
12
+ }
13
+ /**
14
+ * A Scanner that searches for a config file in a directory. It caches the results to speed up future requests.
15
+ */
16
+ export declare class DirConfigScanner {
17
+ #private;
4
18
  readonly allowedExtensionsByProtocol: Map<string, readonly string[]>;
5
19
  private fs;
6
- private searchCache;
7
- private searchDirCache;
8
- private searchPlacesByProtocol;
9
20
  /**
10
21
  * @param searchPlaces - The list of file names to search for.
11
22
  * @param allowedExtensionsByProtocol - Map of allowed extensions by protocol, '*' is used to match all protocols.
12
23
  * @param fs - The file system to use.
13
24
  */
14
25
  constructor(searchPlaces: readonly string[], allowedExtensionsByProtocol: Map<string, readonly string[]>, fs: VFileSystem);
15
- searchForConfig(searchFromURL: URL): Promise<URL | undefined>;
16
26
  clearCache(): void;
17
- private findUpConfigPath;
18
- private hasConfig;
19
- private createHasFileDirSearch;
20
- private readDir;
21
- private createHasFileStatCheck;
22
- private hasConfigDir;
27
+ /**
28
+ *
29
+ * @param dir - the directory to search for a config file.
30
+ * @param visited - a callback to be called for each directory visited.
31
+ * @returns A promise that resolves to the url of the config file or `undefined`.
32
+ */
33
+ scanDirForConfigFile(dir: URL): Promise<URL | undefined>;
23
34
  }
24
35
  //# sourceMappingURL=configSearch.d.ts.map
@@ -3,77 +3,101 @@ import { urlBasename } from 'cspell-io';
3
3
  import { createAutoResolveCache } from '../../../util/AutoResolve.js';
4
4
  import { findUpFromUrl } from '../../../util/findUpFromUrl.js';
5
5
  export class ConfigSearch {
6
- searchPlaces;
7
- allowedExtensionsByProtocol;
8
- fs;
9
- searchCache = new Map();
10
- searchDirCache = new Map();
11
- searchPlacesByProtocol;
6
+ /**
7
+ * Cache of search results.
8
+ */
9
+ #searchCache = new Map();
10
+ /**
11
+ * The scanner to use to search for config files.
12
+ */
13
+ #scanner;
12
14
  /**
13
15
  * @param searchPlaces - The list of file names to search for.
14
16
  * @param allowedExtensionsByProtocol - Map of allowed extensions by protocol, '*' is used to match all protocols.
15
17
  * @param fs - The file system to use.
16
18
  */
17
19
  constructor(searchPlaces, allowedExtensionsByProtocol, fs) {
18
- this.searchPlaces = searchPlaces;
19
- this.allowedExtensionsByProtocol = allowedExtensionsByProtocol;
20
- this.fs = fs;
21
- this.searchPlacesByProtocol = setupSearchPlacesByProtocol(searchPlaces, allowedExtensionsByProtocol);
22
- this.searchPlaces = this.searchPlacesByProtocol.get('*') || searchPlaces;
20
+ this.#scanner = new DirConfigScanner(searchPlaces, allowedExtensionsByProtocol, fs);
23
21
  }
24
22
  searchForConfig(searchFromURL) {
25
- const dirUrl = new URL('.', searchFromURL);
26
- const searchHref = dirUrl.href;
27
- const searchCache = this.searchCache;
28
- const cached = searchCache.get(searchHref);
23
+ const dirUrl = searchFromURL.pathname.endsWith('/') ? searchFromURL : new URL('.', searchFromURL);
24
+ return this.#findUp(dirUrl);
25
+ }
26
+ clearCache() {
27
+ this.#searchCache.clear();
28
+ this.#scanner.clearCache();
29
+ }
30
+ #findUp(fromDir) {
31
+ const searchDirCache = this.#searchCache;
32
+ const cached = searchDirCache.get(fromDir.href);
29
33
  if (cached) {
30
34
  return cached;
31
35
  }
32
- const toPatchCache = [];
33
- const pFoundUrl = this.findUpConfigPath(dirUrl, storeVisit);
34
- this.searchCache.set(searchHref, pFoundUrl);
35
- const searchDirCache = this.searchDirCache;
36
- const patch = async () => {
37
- try {
38
- await pFoundUrl;
39
- for (const dir of toPatchCache) {
40
- searchDirCache.set(dir.href, searchDirCache.get(dir.href) || pFoundUrl);
41
- searchCache.set(dir.href, searchCache.get(dir.href) || pFoundUrl);
42
- }
43
- const result = searchCache.get(searchHref) || pFoundUrl;
44
- searchCache.set(searchHref, result);
45
- }
46
- catch {
47
- // ignore
48
- }
36
+ const visited = [];
37
+ let result = undefined;
38
+ const predicate = (dir) => {
39
+ visit(dir);
40
+ return this.#scanner.scanDirForConfigFile(dir);
49
41
  };
50
- patch();
51
- return pFoundUrl;
52
- function storeVisit(dir) {
53
- toPatchCache.push(dir);
42
+ result = findUpFromUrl(predicate, fromDir, { type: 'file' });
43
+ searchDirCache.set(fromDir.href, result);
44
+ visited.forEach((dir) => searchDirCache.set(dir.href, result));
45
+ return result;
46
+ /**
47
+ * Record directories that are visited while walking up the directory tree.
48
+ * This will help speed up future searches.
49
+ * @param dir - the directory that was visited.
50
+ */
51
+ function visit(dir) {
52
+ if (!result) {
53
+ visited.push(dir);
54
+ return;
55
+ }
56
+ searchDirCache.set(dir.href, searchDirCache.get(dir.href) || result);
54
57
  }
55
58
  }
56
- clearCache() {
57
- this.searchCache.clear();
58
- this.searchDirCache.clear();
59
+ }
60
+ /**
61
+ * A Scanner that searches for a config file in a directory. It caches the results to speed up future requests.
62
+ */
63
+ export class DirConfigScanner {
64
+ allowedExtensionsByProtocol;
65
+ fs;
66
+ #searchDirCache = new Map();
67
+ #searchPlacesByProtocol;
68
+ #searchPlaces;
69
+ /**
70
+ * @param searchPlaces - The list of file names to search for.
71
+ * @param allowedExtensionsByProtocol - Map of allowed extensions by protocol, '*' is used to match all protocols.
72
+ * @param fs - The file system to use.
73
+ */
74
+ constructor(searchPlaces, allowedExtensionsByProtocol, fs) {
75
+ this.allowedExtensionsByProtocol = allowedExtensionsByProtocol;
76
+ this.fs = fs;
77
+ this.#searchPlacesByProtocol = setupSearchPlacesByProtocol(searchPlaces, allowedExtensionsByProtocol);
78
+ this.#searchPlaces = this.#searchPlacesByProtocol.get('*') || searchPlaces;
59
79
  }
60
- findUpConfigPath(cwd, visit) {
61
- const searchDirCache = this.searchDirCache;
62
- const cached = searchDirCache.get(cwd.href);
63
- if (cached)
64
- return cached;
65
- return findUpFromUrl((dir) => this.hasConfig(dir, visit), cwd, { type: 'file' });
80
+ clearCache() {
81
+ this.#searchDirCache.clear();
66
82
  }
67
- hasConfig(dir, visited) {
68
- const cached = this.searchDirCache.get(dir.href);
69
- if (cached)
83
+ /**
84
+ *
85
+ * @param dir - the directory to search for a config file.
86
+ * @param visited - a callback to be called for each directory visited.
87
+ * @returns A promise that resolves to the url of the config file or `undefined`.
88
+ */
89
+ scanDirForConfigFile(dir) {
90
+ const searchDirCache = this.#searchDirCache;
91
+ const href = dir.href;
92
+ const cached = searchDirCache.get(href);
93
+ if (cached) {
70
94
  return cached;
71
- visited(dir);
72
- const result = this.hasConfigDir(dir);
73
- this.searchDirCache.set(dir.href, result);
95
+ }
96
+ const result = this.#scanDirForConfig(dir);
97
+ searchDirCache.set(href, result);
74
98
  return result;
75
99
  }
76
- createHasFileDirSearch() {
100
+ #createHasFileDirSearch() {
77
101
  const dirInfoCache = createAutoResolveCache();
78
102
  const hasFile = async (filename) => {
79
103
  const dir = new URL('.', filename);
@@ -88,14 +112,14 @@ export class ConfigSearch {
88
112
  return false;
89
113
  }
90
114
  const dirUrlHref = dir.href;
91
- const dirInfo = await dirInfoCache.get(dirUrlHref, async () => await this.readDir(dir));
115
+ const dirInfo = await dirInfoCache.get(dirUrlHref, async () => await this.#readDir(dir));
92
116
  const name = urlBasename(filename);
93
117
  const found = dirInfo.get(name);
94
118
  return found?.isFile() || found?.isSymbolicLink() || false;
95
119
  };
96
120
  return hasFile;
97
121
  }
98
- async readDir(dir) {
122
+ async #readDir(dir) {
99
123
  try {
100
124
  const dirInfo = await this.fs.readDirectory(dir);
101
125
  return new Map(dirInfo.map((ent) => [ent.name, ent]));
@@ -104,18 +128,23 @@ export class ConfigSearch {
104
128
  return new Map();
105
129
  }
106
130
  }
107
- createHasFileStatCheck() {
131
+ #createHasFileStatCheck() {
108
132
  const hasFile = async (filename) => {
109
133
  const stat = await this.fs.stat(filename).catch(() => undefined);
110
134
  return !!stat?.isFile();
111
135
  };
112
136
  return hasFile;
113
137
  }
114
- async hasConfigDir(dir) {
138
+ /**
139
+ * Scan the directory for the first matching config file.
140
+ * @param dir - url of the directory to scan.
141
+ * @returns A promise that resolves to the url of the config file or `undefined`.
142
+ */
143
+ async #scanDirForConfig(dir) {
115
144
  const hasFile = this.fs.getCapabilities(dir).readDirectory
116
- ? this.createHasFileDirSearch()
117
- : this.createHasFileStatCheck();
118
- const searchPlaces = this.searchPlacesByProtocol.get(dir.protocol) || this.searchPlaces;
145
+ ? this.#createHasFileDirSearch()
146
+ : this.#createHasFileStatCheck();
147
+ const searchPlaces = this.#searchPlacesByProtocol.get(dir.protocol) || this.#searchPlaces;
119
148
  for (const searchPlace of searchPlaces) {
120
149
  const file = new URL(searchPlace, dir);
121
150
  const found = await hasFile(file);
@@ -6,7 +6,7 @@ export interface FindUpURLOptions {
6
6
  stopAt?: URL;
7
7
  fs?: FindUpFileSystem;
8
8
  }
9
- type FindUpPredicate = (dir: URL) => URL | undefined | Promise<URL | undefined>;
9
+ export type FindUpPredicate = (dir: URL) => URL | undefined | Promise<URL | undefined>;
10
10
  export declare function findUpFromUrl(name: string | string[] | FindUpPredicate, from: URL, options?: FindUpURLOptions): Promise<URL | undefined>;
11
11
  export {};
12
12
  //# sourceMappingURL=findUpFromUrl.d.ts.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "provenance": true
6
6
  },
7
- "version": "8.17.2",
7
+ "version": "8.17.4",
8
8
  "description": "A library of useful functions used across various cspell tools.",
9
9
  "type": "module",
10
10
  "sideEffects": false,
@@ -64,29 +64,29 @@
64
64
  },
65
65
  "homepage": "https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-lib#readme",
66
66
  "dependencies": {
67
- "@cspell/cspell-bundled-dicts": "8.17.2",
68
- "@cspell/cspell-pipe": "8.17.2",
69
- "@cspell/cspell-resolver": "8.17.2",
70
- "@cspell/cspell-types": "8.17.2",
71
- "@cspell/dynamic-import": "8.17.2",
72
- "@cspell/filetypes": "8.17.2",
73
- "@cspell/strong-weak-map": "8.17.2",
74
- "@cspell/url": "8.17.2",
67
+ "@cspell/cspell-bundled-dicts": "8.17.4",
68
+ "@cspell/cspell-pipe": "8.17.4",
69
+ "@cspell/cspell-resolver": "8.17.4",
70
+ "@cspell/cspell-types": "8.17.4",
71
+ "@cspell/dynamic-import": "8.17.4",
72
+ "@cspell/filetypes": "8.17.4",
73
+ "@cspell/strong-weak-map": "8.17.4",
74
+ "@cspell/url": "8.17.4",
75
75
  "clear-module": "^4.1.2",
76
76
  "comment-json": "^4.2.5",
77
- "cspell-config-lib": "8.17.2",
78
- "cspell-dictionary": "8.17.2",
79
- "cspell-glob": "8.17.2",
80
- "cspell-grammar": "8.17.2",
81
- "cspell-io": "8.17.2",
82
- "cspell-trie-lib": "8.17.2",
77
+ "cspell-config-lib": "8.17.4",
78
+ "cspell-dictionary": "8.17.4",
79
+ "cspell-glob": "8.17.4",
80
+ "cspell-grammar": "8.17.4",
81
+ "cspell-io": "8.17.4",
82
+ "cspell-trie-lib": "8.17.4",
83
83
  "env-paths": "^3.0.0",
84
84
  "fast-equals": "^5.2.2",
85
85
  "gensequence": "^7.0.0",
86
- "import-fresh": "^3.3.0",
86
+ "import-fresh": "^3.3.1",
87
87
  "resolve-from": "^5.0.0",
88
88
  "vscode-languageserver-textdocument": "^1.0.12",
89
- "vscode-uri": "^3.0.8",
89
+ "vscode-uri": "^3.1.0",
90
90
  "xdg-basedir": "^5.1.0"
91
91
  },
92
92
  "engines": {
@@ -100,7 +100,7 @@
100
100
  "@cspell/dict-fr-fr": "^2.2.5",
101
101
  "@cspell/dict-html": "^4.0.11",
102
102
  "@cspell/dict-nl-nl": "^2.3.3",
103
- "@cspell/dict-python": "^4.2.14",
103
+ "@cspell/dict-python": "^4.2.15",
104
104
  "@types/configstore": "^6.0.2",
105
105
  "configstore": "^7.0.0",
106
106
  "cspell-dict-nl-nl": "^1.1.2",
@@ -108,5 +108,5 @@
108
108
  "lorem-ipsum": "^2.0.8",
109
109
  "perf-insight": "^1.2.0"
110
110
  },
111
- "gitHead": "160c982e8d1e3b4951acb6fc003d013f3b0597e0"
111
+ "gitHead": "59b6876dd77fedc84fca3433b13ad9baa653c77d"
112
112
  }