UNPKG

2.11 kBJavaScriptView Raw
1// @flow
2
3import type {Config, File, FilePath} from '@parcel/types';
4import type {FileSystem} from '@parcel/fs';
5import path from 'path';
6import clone from 'clone';
7
8type ConfigOutput = {|
9 config: Config,
10 files: Array<File>
11|};
12
13type ConfigOptions = {|
14 parse?: boolean
15|};
16
17const PARSERS = {
18 json: require('json5').parse,
19 toml: require('@iarna/toml').parse
20};
21
22const existsCache = new Map();
23
24export async function resolveConfig(
25 fs: FileSystem,
26 filepath: FilePath,
27 filenames: Array<FilePath>,
28 opts: ?ConfigOptions,
29 root: FilePath = path.parse(filepath).root
30): Promise<FilePath | null> {
31 filepath = path.dirname(filepath);
32
33 // Don't traverse above the module root
34 if (filepath === root || path.basename(filepath) === 'node_modules') {
35 return null;
36 }
37
38 for (const filename of filenames) {
39 let file = path.join(filepath, filename);
40 if (await fs.exists(file)) {
41 return file;
42 }
43 }
44
45 return resolveConfig(fs, filepath, filenames, opts);
46}
47
48export async function loadConfig(
49 fs: FileSystem,
50 filepath: FilePath,
51 filenames: Array<FilePath>,
52 opts: ?ConfigOptions
53): Promise<ConfigOutput | null> {
54 let configFile = await resolveConfig(fs, filepath, filenames, opts);
55 if (configFile) {
56 try {
57 let extname = path.extname(configFile).slice(1);
58 if (extname === 'js') {
59 return {
60 // $FlowFixMe
61 config: clone(require(configFile)),
62 files: [{filePath: configFile}]
63 };
64 }
65
66 let configContent = await fs.readFile(configFile, 'utf8');
67 if (!configContent) {
68 return null;
69 }
70
71 let config;
72 if (opts && opts.parse === false) {
73 config = configContent;
74 } else {
75 let parse = PARSERS[extname] || PARSERS.json;
76 config = parse(configContent);
77 }
78
79 return {
80 config: config,
81 files: [{filePath: configFile}]
82 };
83 } catch (err) {
84 if (err.code === 'MODULE_NOT_FOUND' || err.code === 'ENOENT') {
85 existsCache.delete(configFile);
86 return null;
87 }
88
89 throw err;
90 }
91 }
92
93 return null;
94}