Skip to content

Commit da3c596

Browse files
committed
fix: improve config validation
1 parent a7f92d8 commit da3c596

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

@commitlint/load/src/load.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ export default async function load(
3838
extends: [],
3939
plugins: [],
4040
rules: {},
41-
formatter: '@commitlint/format',
42-
helpUrl:
43-
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint',
4441
},
4542
loaded ? loaded.config : null,
4643
seed
@@ -67,6 +64,15 @@ export default async function load(
6764

6865
validateConfig(extended);
6966

67+
if (!extended.formatter) {
68+
extended.formatter = '@commitlint/format';
69+
}
70+
71+
if (!extended.helpUrl) {
72+
extended.helpUrl =
73+
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint';
74+
}
75+
7076
let plugins: PluginRecords = {};
7177
uniq(extended.plugins || []).forEach((plugin) => {
7278
if (typeof plugin === 'string') {

@commitlint/load/src/utils/load-parser-opts.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import {ParserPreset} from '@commitlint/types';
2-
import {isObjectLike, isParserOptsFunction, isPromiseLike} from './validators';
2+
import {
3+
isObjectLike,
4+
isParserOptsFunction,
5+
isPromiseLike,
6+
validateParser,
7+
} from './validators';
38

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

13-
if (!isObjectLike(parser)) {
14-
throw new Error('Invalid configuration, `parserPreset` must be an object');
15-
}
18+
validateParser(parser);
1619

1720
// Await parser opts if applicable
1821
if (isPromiseLike(parser.parserOpts)) {
@@ -23,7 +26,7 @@ export async function loadParser(
2326
// Create parser opts from factory
2427
if (
2528
isParserOptsFunction(parser) &&
26-
typeof parser.name === 'string' &&
29+
parser.name &&
2730
parser.name.startsWith('conventional-changelog-')
2831
) {
2932
return new Promise((resolve) => {

@commitlint/load/src/utils/validators.ts

+32-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Plugin, RulesConfig} from '@commitlint/types';
1+
import {UserConfig} from '@commitlint/types';
22

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

24-
export function validateConfig(
25-
config: Record<string, unknown>
26-
): asserts config is {
27-
formatter: string;
28-
ignores?: ((commit: string) => boolean)[];
29-
defaultIgnores?: boolean;
30-
plugins?: (Plugin | string)[];
31-
rules: Partial<RulesConfig>;
32-
helpUrl: string;
33-
[key: string]: unknown;
34-
} {
24+
export function validateConfig<T extends Record<string, unknown>>(
25+
config: T
26+
): asserts config is Omit<UserConfig, 'parserPreset'> & T {
3527
if (!isObjectLike(config)) {
3628
throw new Error('Invalid configuration, `parserPreset` must be an object');
3729
}
38-
if (typeof config.formatter !== 'string') {
30+
if (
31+
config.extends &&
32+
typeof config.extends !== 'string' &&
33+
!Array.isArray(config.extends)
34+
) {
35+
throw new Error(
36+
'Invalid configuration, `extends` must be a array or string'
37+
);
38+
}
39+
if (config.formatter && typeof config.formatter !== 'string') {
3940
throw new Error('Invalid configuration, `formatter` must be a string');
4041
}
4142
if (config.ignores && !Array.isArray(config.ignores)) {
@@ -44,7 +45,11 @@ export function validateConfig(
4445
if (config.plugins && !Array.isArray(config.plugins)) {
4546
throw new Error('Invalid configuration, `plugins` must ba an array');
4647
}
48+
if (config.rules && typeof config.rules !== 'object') {
49+
throw new Error('Invalid configuration, `rules` must ba an object');
50+
}
4751
if (
52+
config.defaultIgnores &&
4853
typeof config.defaultIgnores !== 'boolean' &&
4954
typeof config.defaultIgnores !== 'undefined'
5055
) {
@@ -56,3 +61,17 @@ export function validateConfig(
5661
throw new Error('Invalid configuration, `helpUrl` must be a string');
5762
}
5863
}
64+
65+
export function validateParser(
66+
parser: unknown
67+
): asserts parser is {name?: string; path?: string; [key: string]: unknown} {
68+
if (!isObjectLike(parser)) {
69+
throw new Error('Invalid configuration, `parserPreset` must be an object');
70+
}
71+
if (parser.name && typeof parser.name !== 'string') {
72+
throw new Error('Invalid configuration, `parserPreset` must have a name');
73+
}
74+
if (parser.path && typeof parser.path !== 'string') {
75+
throw new Error('Invalid configuration, `parserPreset` must have a name');
76+
}
77+
}

0 commit comments

Comments
 (0)