Skip to content

Commit

Permalink
chore: Misc. cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
darkobits committed Jun 28, 2023
1 parent e778360 commit 6545874
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 265 deletions.
65 changes: 51 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@
"node-version": "^3.0.0",
"read-pkg-up": "^9.1.0",
"resolve-pkg": "^2.0.0",
"ts-import": "^5.0.0-beta.0",
"ts-node": "^10.9.1",
"tsconfck": "^2.1.1",
"tsconfig-paths": "^4.2.0",
"yargs": "^17.7.2"
},
"devDependencies": {
Expand Down
24 changes: 19 additions & 5 deletions src/lib/configuration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,41 @@ import ConfigurationLoader from 'lib/configuration/loader';
export default async function loadConfiguration<C>(options: SaffronCosmiconfigOptions) {
const { fileName, key, searchFrom, ...cosmicOptions } = validators.cosmiconfigOptions(options);

const configResult = await cosmiconfig(fileName, merge({
const mergedOptions = merge({
loaders: {
...defaultLoaders,

'.ts': ConfigurationLoader,
'.cts': ConfigurationLoader,
'.tsx': ConfigurationLoader,
'.mts': ConfigurationLoader,
'.cts': ConfigurationLoader,

'.js': ConfigurationLoader,
'.cjs': ConfigurationLoader,
'.mjs': ConfigurationLoader
'.jsx': ConfigurationLoader,
'.mjs': ConfigurationLoader,
'.cjs': ConfigurationLoader
},
searchPlaces: [
`${fileName}.config.ts`,
`${fileName}.config.tsx`,
`${fileName}.config.mts`,
`${fileName}.config.cts`,

`${fileName}.config.js`,
`${fileName}.config.jsx`,
`${fileName}.config.mjs`,
`${fileName}.config.cjs`,

`${fileName}rc.ts`,
`${fileName}rc.tsx`,
`${fileName}rc.mts`,
`${fileName}rc.cts`,

`${fileName}rc.js`,
`${fileName}rc.jsx`,
`${fileName}rc.mjs`,
`${fileName}rc.cjs`,

`.${fileName}.json`,
`.${fileName}.yaml`,
`.${fileName}.yml`,
Expand All @@ -52,7 +64,9 @@ export default async function loadConfiguration<C>(options: SaffronCosmiconfigOp
// our value.
return [...source, ...target];
}
})).search(searchFrom);
});

const configResult = await cosmiconfig(fileName, mergedOptions).search(searchFrom);

// If we loaded a non-empty file and the user specified a sub-key that they
// want to drill-down into, ensure that the root configuration object has that
Expand Down
69 changes: 19 additions & 50 deletions src/lib/configuration/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@ import path from 'path';

import { babelRegisterStrategy } from 'lib/configuration/strategies/babel-register';
import { esbuildStrategy } from 'lib/configuration/strategies/esbuild';
// import { tsImportStrategy } from 'lib/configuration/strategies/ts-import';
// import { TypeScriptLoader } from 'lib/configuration/strategies/ts-node';
import log from 'lib/log';
import { getPackageInfo } from 'lib/package';


/**
* Cosmiconfig custom loader that supports ESM syntax. It allows host
* applications to be written in ESM or CJS, and for the consumers of those
* applications to write configuration files as ESM or CJS.
* Cosmiconfig custom loader. It is designed to work with with dependents that
* are written in ESM or CJS, and for the consumers of those applications to be
* written in ESM or CJS with configuration files written in either ESM or CJS.
*/
export default async function configurationLoader(filePath: string /* , content: string */) {
const prefix = log.prefix('config');
const errors: Array<Error> = [];

log.verbose(log.prefix('configurationLoader'), `Using configuration file: ${log.chalk.green(filePath)}`);
log.verbose(prefix, `Found configuration file: ${log.chalk.green(filePath)}`);

const pkgInfo = getPackageInfo({ cwd: path.dirname(filePath) });
if (!pkgInfo?.root) throw new Error(`${log.prefix('configurationLoader')} Unable to compute host package root directory.`);
if (!pkgInfo?.root) throw new Error(`${prefix} Unable to compute host package root directory.`);


/**
Expand All @@ -31,10 +30,10 @@ export default async function configurationLoader(filePath: string /* , content:
*/
try {
const config = await import(filePath);
log.verbose(log.prefix('configurationLoader'), 'Used strategy:', log.chalk.bold('import()'));
log.verbose(prefix, 'Used strategy:', log.chalk.bold('import()'));
return config?.default ?? config;
} catch (err: any) {
errors.push(new Error(`${log.prefix('configurationLoader')} Failed to load configuration with ${log.chalk.bold('dynamic import')}: ${err}`));
errors.push(new Error(`${prefix} Failed to load file with ${log.chalk.bold('import()')}: ${err}`));
}


Expand All @@ -43,59 +42,29 @@ export default async function configurationLoader(filePath: string /* , content:
*/
try {
const config = await esbuildStrategy(filePath, pkgInfo);
log.verbose(log.prefix('configurationLoader'), 'Used strategy:', log.chalk.bold('esbuild'));
log.verbose(prefix, 'Used strategy:', log.chalk.bold('esbuild'));
return config.default ?? config;
} catch (err: any) {
errors.push(new Error(`${log.prefix('configurationLoader')} Failed to load configuration with ${log.chalk.bold('esbuild')}: ${err}`));
errors.push(new Error(`${prefix} Failed to load file with ${log.chalk.bold('esbuild')}: ${err}`));
}


/**
* Strategy 3: ts-import
*/
// try {
// const config = await tsImportStrategy(filePath);
// log.verbose(log.prefix('configurationLoader'), 'Used strategy:', log.chalk.bold('ts-import'));
// return config?.default ?? config;
// } catch (err: any) {
// errors.push(new Error(`${log.prefix('configurationLoader')} Failed to load configuration with ${log.chalk.bold('ts-import')}: ${err}`));
// }


/**
* Strategy 4: ts-node
*
* This strategy is in place in the event that @babel/register did not work
* for some reason, but it is not ideal for reasons explained above.
*/
// try {
// const tsLoader = TypeScriptLoader();
// const config = await tsLoader(filePath, content, pkgInfo);
// log.verbose(log.prefix('configurationLoader'), 'Used strategy:', log.chalk.bold('ts-node'));
// return config;
// } catch (err: any) {
// errors.push(new Error(`${log.prefix('configurationLoader')} Failed to load configuration with ${log.chalk.bold('TypeScriptLoader')}: ${err}`));
// }


/**
* Strategy 5: @babel/register
* Strategy 3: @babel/register
*
* This strategy uses a custom loader that uses @babel/register to transpile
* code. The loader will work with TypeScript configuration files, and it will
* additionally configure Babel to use path mappings defined in tsconfig.json.
* The host project need not have a Babel configuration file in place for this
* strategy to work. If the first strategy failed, this one should work for
* the majority of cases. We try this before ts-node because TypeScript does
* not have any mechanism that allows us to preserve dynamic import statements
* when transpiling to CommonJS.
* This strategy creates a custom loader that uses @babel/register to
* transpile code. The loader will work with TypeScript configuration files,
* and it will additionally configure Babel to use path mappings defined in
* tsconfig.json. The host project need not have a Babel configuration file in
* place for this strategy to work. If the previous strategies failed, this
* one should work for the majority of remaining cases.
*/
try {
const config = await babelRegisterStrategy(filePath, pkgInfo);
log.verbose(log.prefix('configurationLoader'), 'Used strategy:', log.chalk.bold('@babel/register'));
log.verbose(prefix, 'Used strategy:', log.chalk.bold('@babel/register'));
return config?.default ?? config;
} catch (err: any) {
errors.push(err);
errors.push(new Error(`${prefix} Failed to load file with ${log.chalk.bold('@babel/register')}: ${err}`));
}

if (errors.length > 0) throw new AggregateError(
Expand Down
Loading

0 comments on commit 6545874

Please sign in to comment.