diff --git a/lib/config/__snapshots__/validation.spec.ts.snap b/lib/config/__snapshots__/validation.spec.ts.snap index fc5d501d847f2c..782e160bdcbf75 100644 --- a/lib/config/__snapshots__/validation.spec.ts.snap +++ b/lib/config/__snapshots__/validation.spec.ts.snap @@ -88,6 +88,24 @@ Array [ ] `; +exports[`config/validation validateConfig(config) errors if aliases depth is more than 1 1`] = ` +Array [ + Object { + "depName": "Configuration Error", + "message": "Invalid alias object configuration", + }, +] +`; + +exports[`config/validation validateConfig(config) errors if aliases have invalid url 1`] = ` +Array [ + Object { + "depName": "Configuration Error", + "message": "Invalid alias object configuration", + }, +] +`; + exports[`config/validation validateConfig(config) errors if regexManager fields are missing 1`] = ` Array [ Object { @@ -150,3 +168,5 @@ Array [ }, ] `; + +exports[`config/validation validateConfig(config) validates valid alias objects 1`] = `Array []`; diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index 5c0c219b9e51be..73a9088b2effe0 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -336,5 +336,51 @@ describe('config/validation', () => { expect(warnings).toHaveLength(0); expect(errors).toHaveLength(0); }); + + it('validates valid alias objects', async () => { + const config = { + aliases: { + example1: 'http://www.example.com', + example2: 'https://www.example2.com/example', + }, + }; + const { warnings, errors } = await configValidation.validateConfig( + config + ); + expect(warnings).toHaveLength(0); + expect(errors).toHaveLength(0); + expect(errors).toMatchSnapshot(); + }); + + it('errors if aliases depth is more than 1', async () => { + const config = { + aliases: { + sample: { + example1: 'http://www.example.com', + }, + }, + }; + const { warnings, errors } = await configValidation.validateConfig( + config + ); + expect(warnings).toHaveLength(0); + expect(errors).toHaveLength(1); + expect(errors).toMatchSnapshot(); + }); + + it('errors if aliases have invalid url', async () => { + const config = { + aliases: { + example1: 'noturl', + example2: 'http://www.example.com', + }, + }; + const { warnings, errors } = await configValidation.validateConfig( + config + ); + expect(warnings).toHaveLength(0); + expect(errors).toHaveLength(1); + expect(errors).toMatchSnapshot(); + }); }); }); diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 773f908ccd7c42..db3eb7baec4517 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -56,6 +56,17 @@ export async function validateConfig( return ignoredNodes.includes(key); } + function validateAliasObject(key: string, val: object): boolean { + if (key === 'aliases') { + for (const value of Object.values(val)) { + if (!is.urlString(value)) { + return false; + } + } + } + return true; + } + for (const [key, val] of Object.entries(config)) { const currentPath = parentPath ? `${parentPath}.${key}` : key; if ( @@ -346,17 +357,26 @@ export async function validateConfig( } } else if (type === 'object' && currentPath !== 'compatibility') { if (is.object(val)) { - const ignoredObjects = options - .filter((option) => option.freeChoice) - .map((option) => option.name); - if (!ignoredObjects.includes(key)) { - const subValidation = await module.exports.validateConfig( - val, - isPreset, - currentPath - ); - warnings = warnings.concat(subValidation.warnings); - errors = errors.concat(subValidation.errors); + if (key === 'aliases') { + if (!validateAliasObject(key, val)) { + errors.push({ + depName: 'Configuration Error', + message: `Invalid alias object configuration`, + }); + } + } else { + const ignoredObjects = options + .filter((option) => option.freeChoice) + .map((option) => option.name); + if (!ignoredObjects.includes(key)) { + const subValidation = await module.exports.validateConfig( + val, + isPreset, + currentPath + ); + warnings = warnings.concat(subValidation.warnings); + errors = errors.concat(subValidation.errors); + } } } else { errors.push({