2020-03-29 18:21:53 +02:00
|
|
|
import findUp from 'next/dist/compiled/find-up'
|
2019-11-25 22:52:29 +01:00
|
|
|
import fs from 'fs'
|
2020-03-29 01:36:15 +01:00
|
|
|
import JSON5 from 'next/dist/compiled/json5'
|
2019-11-25 22:52:29 +01:00
|
|
|
|
|
|
|
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
|
2019-12-11 22:56:47 +01:00
|
|
|
// known filenames.
|
|
|
|
const filePath = await findUp(
|
|
|
|
[
|
|
|
|
`.${key}rc.json`,
|
|
|
|
`${key}.config.json`,
|
|
|
|
`.${key}rc.js`,
|
|
|
|
`${key}.config.js`,
|
|
|
|
],
|
|
|
|
{
|
|
|
|
cwd: directory,
|
|
|
|
}
|
|
|
|
)
|
2019-11-25 22:52:29 +01:00
|
|
|
if (filePath) {
|
2019-12-11 22:56:47 +01:00
|
|
|
if (filePath.endsWith('.js')) {
|
|
|
|
return require(filePath)
|
|
|
|
}
|
|
|
|
|
2019-11-25 22:52:29 +01:00
|
|
|
// 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
|
|
|
|
}
|