diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index 136704947e69..dd186c46b397 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -16,6 +16,7 @@ import npa from 'npm-package-arg'; import semver, { Range, compare, intersects, prerelease, satisfies, valid } from 'semver'; import { Argv } from 'yargs'; import { + CommandModuleError, CommandModuleImplementation, Options, OtherOptions, @@ -131,6 +132,17 @@ export default class AddCommandModule type: 'boolean', default: false, }) + .check(({ registry }) => { + if (registry === undefined) { + return true; + } + + if (typeof registry === 'string' && URL.canParse(registry)) { + return true; + } + + throw new CommandModuleError('Option --registry must be a valid URL.'); + }) // Prior to downloading we don't know the full schema and therefore we cannot be strict on the options. // Possibly in the future update the logic to use the following syntax: // `ng add @angular/localize -- --package-options`. diff --git a/tests/e2e/tests/commands/add/registry-option.ts b/tests/e2e/tests/commands/add/registry-option.ts index dc336cdd5b30..1343cebf4dd1 100644 --- a/tests/e2e/tests/commands/add/registry-option.ts +++ b/tests/e2e/tests/commands/add/registry-option.ts @@ -1,11 +1,37 @@ import { getGlobalVariable } from '../../../utils/env'; import { expectFileToExist } from '../../../utils/fs'; -import { ng } from '../../../utils/process'; +import { execAndCaptureError, ng } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; export default async function () { const testRegistry = getGlobalVariable('package-registry'); + // Validate that a non-URL registry string fails with a validation error + const error = await execAndCaptureError('ng', [ + 'add', + '--registry=not-a-valid-url', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!error.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error, but got different error: ${error.message}`, + ); + } + + // Validate that an empty registry string fails with a validation error + const errorEmpty = await execAndCaptureError('ng', [ + 'add', + '--registry=', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!errorEmpty.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error for empty string, but got: ${errorEmpty.message}`, + ); + } + // Set an invalid registry process.env['NPM_CONFIG_REGISTRY'] = 'http://127.0.0.1:9999';