-
-
Notifications
You must be signed in to change notification settings - Fork 135
/
ExplorerSync.ts
129 lines (118 loc) · 3.53 KB
/
ExplorerSync.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import fs from 'fs';
import path from 'path';
import { isDirectorySync } from 'path-type';
import { ExplorerBase, getExtensionDescription } from './ExplorerBase.js';
import { loadJson } from './loaders.js';
import { Config, CosmiconfigResult, InternalOptionsSync } from './types.js';
import { emplace, getPropertyByPath } from './util.js';
/**
* @internal
*/
export class ExplorerSync extends ExplorerBase<InternalOptionsSync> {
public load(filepath: string): CosmiconfigResult {
filepath = path.resolve(filepath);
const load = (): CosmiconfigResult => {
return this.config.transform(this.#readConfiguration(filepath));
};
if (this.loadCache) {
return emplace(this.loadCache, filepath, load);
}
return load();
}
public search(from = ''): CosmiconfigResult {
if (this.config.metaConfigFilePath) {
this.loadingMetaConfig = true;
const config = this.load(this.config.metaConfigFilePath);
this.loadingMetaConfig = false;
if (config && !config.isEmpty) {
return config;
}
}
const stopDir = path.resolve(this.config.stopDir);
from = path.resolve(from);
const search = (): CosmiconfigResult => {
/* istanbul ignore if -- @preserve */
if (isDirectorySync(from)) {
for (const place of this.config.searchPlaces) {
const filepath = path.join(from, place);
try {
const result = this.#readConfiguration(filepath);
if (
result !== null &&
!(result.isEmpty && this.config.ignoreEmptySearchPlaces)
) {
return this.config.transform(result);
}
} catch (error) {
if (error.code === 'ENOENT' || error.code === 'EISDIR') {
continue;
}
throw error;
}
}
}
const dir = path.dirname(from);
if (from !== stopDir && from !== dir) {
from = dir;
if (this.searchCache) {
return emplace(this.searchCache, from, search);
}
return search();
}
return null;
};
if (this.searchCache) {
return emplace(this.searchCache, from, search);
}
return search();
}
#readConfiguration(filepath: string): CosmiconfigResult {
const contents = fs.readFileSync(filepath, 'utf8');
return this.toCosmiconfigResult(
filepath,
this.#loadConfiguration(filepath, contents),
);
}
#loadConfiguration(filepath: string, contents: string): Config {
if (contents.trim() === '') {
return;
}
if (path.basename(filepath) === 'package.json') {
return (
getPropertyByPath(
loadJson(filepath, contents),
this.config.packageProp,
) ?? null
);
}
const extension = path.extname(filepath);
try {
const loader =
this.config.loaders[extension || 'noExt'] ??
this.config.loaders['default'];
if (loader !== undefined) {
return loader(filepath, contents);
}
} catch (error) {
error.filepath = filepath;
throw error;
}
throw new Error(
`No loader specified for ${getExtensionDescription(extension)}`,
);
}
/**
* @deprecated Use {@link ExplorerSync.prototype.load}.
*/
/* istanbul ignore next */
public loadSync(filepath: string): CosmiconfigResult {
return this.load(filepath);
}
/**
* @deprecated Use {@link ExplorerSync.prototype.search}.
*/
/* istanbul ignore next */
public searchSync(from = ''): CosmiconfigResult {
return this.search(from);
}
}