feat: make PAYLOAD_CONFIG_PATH optional (#2839)

* feat: make PAYLOAD_CONFIG_PATH optional

* hardcode common search paths

* docs: update docs regarding PAYLOAD_CONFIG_PATH

* make the tsConfig parser less prone to errors
This commit is contained in:
Alessio Gravili
2023-08-14 16:46:10 +02:00
committed by GitHub
parent 8a6cbf8a4d
commit 5744de7ec6
2 changed files with 89 additions and 17 deletions

View File

@@ -1,6 +1,43 @@
import path from 'path';
import findUp from 'find-up';
import fs from 'fs';
/**
* Returns the source and output paths from the nearest tsconfig.json file.
* If no tsconfig.json file is found, returns the current working directory.
* @returns An object containing the source and output paths.
*/
const getTSConfigPaths = (): { srcPath: string, outPath: string } => {
const tsConfigPath = findUp.sync('tsconfig.json');
if (!tsConfigPath) {
return { srcPath: process.cwd(), outPath: process.cwd() };
}
try {
// Read the file as a string and remove trailing commas
const rawTsConfig = fs.readFileSync(tsConfigPath, 'utf-8')
.replace(/,\s*]/g, ']')
.replace(/,\s*}/g, '}');
const tsConfig = JSON.parse(rawTsConfig);
const srcPath = tsConfig.compilerOptions?.rootDir || process.cwd();
const outPath = tsConfig.compilerOptions?.outDir || process.cwd();
return { srcPath, outPath };
} catch (error) {
console.error(`Error parsing tsconfig.json: ${error}`); // Do not throw the error, as we can still continue with the other config path finding methods
return { srcPath: process.cwd(), outPath: process.cwd() };
}
};
/**
* Searches for a Payload configuration file.
* @returns The absolute path to the Payload configuration file.
* @throws An error if no configuration file is found.
*/
const findConfig = (): string => {
// If the developer has specified a config path,
// format it if relative and use it directly if absolute
@@ -12,21 +49,46 @@ const findConfig = (): string => {
return path.resolve(process.cwd(), process.env.PAYLOAD_CONFIG_PATH);
}
const configPath = findUp.sync((dir) => {
const tsPath = path.join(dir, 'payload.config.ts');
const hasTS = findUp.sync.exists(tsPath);
const { srcPath, outPath } = getTSConfigPaths();
if (hasTS) return tsPath;
const searchPaths = process.env.NODE_ENV === 'production' ? [outPath, srcPath] : [srcPath];
const jsPath = path.join(dir, 'payload.config.js');
const hasJS = findUp.sync.exists(jsPath);
// eslint-disable-next-line no-restricted-syntax
for (const searchPath of searchPaths) {
const configPath = findUp.sync((dir) => {
const tsPath = path.join(dir, 'payload.config.ts');
const hasTS = findUp.sync.exists(tsPath);
if (hasJS) return jsPath;
if (hasTS) {
return tsPath;
}
return undefined;
});
const jsPath = path.join(dir, 'payload.config.js');
const hasJS = findUp.sync.exists(jsPath);
if (configPath) return configPath;
if (hasJS) {
return jsPath;
}
return undefined;
}, { cwd: searchPath });
if (configPath) {
return configPath;
}
}
// If no config file is found in the directories defined by tsconfig.json,
// try searching in the 'src' and 'dist' directory as a last resort, as they are most commonly used
if (process.env.NODE_ENV === 'production') {
const distConfigPath = findUp.sync(['payload.config.js', 'payload.config.ts'], { cwd: path.resolve(process.cwd(), 'dist') });
if (distConfigPath) return distConfigPath;
} else {
const srcConfigPath = findUp.sync(['payload.config.js', 'payload.config.ts'], { cwd: path.resolve(process.cwd(), 'src') });
if (srcConfigPath) return srcConfigPath;
}
throw new Error('Error: cannot find Payload config. Please create a configuration file located at the root of your current working directory called "payload.config.js" or "payload.config.ts".');
};