Skip to content

Commit

Permalink
fix: improve config validation
Browse files Browse the repository at this point in the history
  • Loading branch information
armano2 committed Jan 10, 2021
1 parent a7f92d8 commit ea26a8e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 22 deletions.
12 changes: 9 additions & 3 deletions @commitlint/load/src/load.ts
Expand Up @@ -38,9 +38,6 @@ export default async function load(
extends: [],
plugins: [],
rules: {},
formatter: '@commitlint/format',
helpUrl:
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint',
},
loaded ? loaded.config : null,
seed
Expand All @@ -67,6 +64,15 @@ export default async function load(

validateConfig(extended);

if (!extended.formatter) {
extended.formatter = '@commitlint/format';
}

if (!extended.helpUrl) {
extended.helpUrl =
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint';
}

let plugins: PluginRecords = {};
uniq(extended.plugins || []).forEach((plugin) => {
if (typeof plugin === 'string') {
Expand Down
13 changes: 8 additions & 5 deletions @commitlint/load/src/utils/load-parser-opts.ts
@@ -1,5 +1,10 @@
import {ParserPreset} from '@commitlint/types';
import {isObjectLike, isParserOptsFunction, isPromiseLike} from './validators';
import {
isObjectLike,
isParserOptsFunction,
isPromiseLike,
validateParser,
} from './validators';

export async function loadParser(
pendingParser: unknown
Expand All @@ -10,9 +15,7 @@ export async function loadParser(
// Await for the module, loaded with require
const parser = await pendingParser;

if (!isObjectLike(parser)) {
throw new Error('Invalid configuration, `parserPreset` must be an object');
}
validateParser(parser);

// Await parser opts if applicable
if (isPromiseLike(parser.parserOpts)) {
Expand All @@ -23,7 +26,7 @@ export async function loadParser(
// Create parser opts from factory
if (
isParserOptsFunction(parser) &&
typeof parser.name === 'string' &&
parser.name &&
parser.name.startsWith('conventional-changelog-')
) {
return new Promise((resolve) => {
Expand Down
47 changes: 33 additions & 14 deletions @commitlint/load/src/utils/validators.ts
@@ -1,4 +1,4 @@
import {Plugin, RulesConfig} from '@commitlint/types';
import {UserConfig} from '@commitlint/types';

export function isObjectLike(obj: unknown): obj is Record<string, unknown> {
return Boolean(obj) && typeof obj === 'object'; // typeof null === 'object'
Expand All @@ -21,21 +21,22 @@ export function isParserOptsFunction<T extends Record<string, unknown>>(
return typeof obj.parserOpts === 'function';
}

export function validateConfig(
config: Record<string, unknown>
): asserts config is {
formatter: string;
ignores?: ((commit: string) => boolean)[];
defaultIgnores?: boolean;
plugins?: (Plugin | string)[];
rules: Partial<RulesConfig>;
helpUrl: string;
[key: string]: unknown;
} {
export function validateConfig<T extends Record<string, unknown>>(
config: T
): asserts config is Omit<UserConfig, 'parserPreset'> & T {
if (!isObjectLike(config)) {
throw new Error('Invalid configuration, `parserPreset` must be an object');
}
if (typeof config.formatter !== 'string') {
if (
config.extends &&
typeof config.extends !== 'string' &&
!Array.isArray(config.extends)
) {
throw new Error(
'Invalid configuration, `extends` must be a array or string'
);
}
if (config.formatter && typeof config.formatter !== 'string') {
throw new Error('Invalid configuration, `formatter` must be a string');
}
if (config.ignores && !Array.isArray(config.ignores)) {
Expand All @@ -44,15 +45,33 @@ export function validateConfig(
if (config.plugins && !Array.isArray(config.plugins)) {
throw new Error('Invalid configuration, `plugins` must ba an array');
}
if (config.rules && typeof config.rules !== 'object') {
throw new Error('Invalid configuration, `rules` must ba an object');
}
if (
config.defaultIgnores &&
typeof config.defaultIgnores !== 'boolean' &&
typeof config.defaultIgnores !== 'undefined'
) {
throw new Error(
'Invalid configuration, `defaultIgnores` must ba true/false'
);
}
if (typeof config.helpUrl !== 'string') {
if (config.helpUrl && typeof config.helpUrl !== 'string') {
throw new Error('Invalid configuration, `helpUrl` must be a string');
}
}

export function validateParser(
parser: unknown
): asserts parser is {name?: string; path?: string; [key: string]: unknown} {
if (!isObjectLike(parser)) {
throw new Error('Invalid configuration, `parserPreset` must be an object');
}
if (parser.name && typeof parser.name !== 'string') {
throw new Error('Invalid configuration, `parserPreset` must have a name');
}
if (parser.path && typeof parser.path !== 'string') {
throw new Error('Invalid configuration, `parserPreset` must have a name');
}
}

0 comments on commit ea26a8e

Please sign in to comment.