-
Notifications
You must be signed in to change notification settings - Fork 27k
/
find-config.ts
50 lines (45 loc) · 1.45 KB
/
find-config.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
import findUp from 'next/dist/compiled/find-up'
import fs from 'fs'
import JSON5 from 'next/dist/compiled/json5'
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>
}
// We'll allow configuration to be typed, but we force everything provided to
// become optional. We do not perform any schema validation. We should maybe
// force all the types to be `unknown` as well.
export async function findConfig<T>(
directory: string,
key: string
): Promise<RecursivePartial<T> | null> {
// `package.json` configuration always wins. Let's check that first.
const packageJsonPath = await findUp('package.json', { cwd: directory })
if (packageJsonPath) {
const packageJson = require(packageJsonPath)
if (packageJson[key] != null && typeof packageJson[key] === 'object') {
return packageJson[key]
}
}
// If we didn't find the configuration in `package.json`, we should look for
// known filenames.
const filePath = await findUp(
[
`.${key}rc.json`,
`${key}.config.json`,
`.${key}rc.js`,
`${key}.config.js`,
],
{
cwd: directory,
}
)
if (filePath) {
if (filePath.endsWith('.js')) {
return require(filePath)
}
// We load JSON contents with JSON5 to allow users to comment in their
// configuration file. This pattern was popularized by TypeScript.
const fileContents = fs.readFileSync(filePath, 'utf8')
return JSON5.parse(fileContents)
}
return null
}