diff --git a/docs/generated/packages/angular/generators/component.json b/docs/generated/packages/angular/generators/component.json index 5e2812ab3f..28214facb3 100644 --- a/docs/generated/packages/angular/generators/component.json +++ b/docs/generated/packages/angular/generators/component.json @@ -52,7 +52,7 @@ "alias": "t" }, "standalone": { - "description": "Whether the generated component is standalone. _Note: This is only supported in Angular versions >= 14.1.0_", + "description": "Whether the generated component is standalone. _Note: This is only supported in Angular versions >= 14.1.0_.", "type": "boolean", "default": false, "x-priority": "important" diff --git a/packages/angular/src/generators/application/lib/create-project.ts b/packages/angular/src/generators/application/lib/create-project.ts index 4916905b86..36db9fac1f 100644 --- a/packages/angular/src/generators/application/lib/create-project.ts +++ b/packages/angular/src/generators/application/lib/create-project.ts @@ -1,11 +1,12 @@ -import { NormalizedSchema } from './normalized-schema'; -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; +import type { Tree } from '@nrwl/devkit'; import { addProjectConfiguration } from '@nrwl/devkit'; +import type { AngularProjectConfiguration } from '../../../utils/types'; import { getInstalledAngularVersionInfo } from '../../utils/version-utils'; +import type { NormalizedSchema } from './normalized-schema'; export function createProject(tree: Tree, options: NormalizedSchema) { const installedAngularInfo = getInstalledAngularVersionInfo(tree); - const project: ProjectConfiguration & { prefix: string } = { + const project: AngularProjectConfiguration = { name: options.name, projectType: 'application', prefix: options.prefix, diff --git a/packages/angular/src/generators/component/component.compat.ts b/packages/angular/src/generators/component/component.compat.ts index 85d23ed319..aed6eb3be4 100644 --- a/packages/angular/src/generators/component/component.compat.ts +++ b/packages/angular/src/generators/component/component.compat.ts @@ -1,5 +1,5 @@ -import componentGenerator from './component'; -import { warnForSchematicUsage } from '../utils/warn-for-schematic-usage'; import { convertNxGenerator } from '@nrwl/devkit'; +import { warnForSchematicUsage } from '../utils/warn-for-schematic-usage'; +import { componentGenerator } from './component'; export default warnForSchematicUsage(convertNxGenerator(componentGenerator)); diff --git a/packages/angular/src/generators/component/component.spec.ts b/packages/angular/src/generators/component/component.spec.ts index d2240416ff..7ee706d56b 100644 --- a/packages/angular/src/generators/component/component.spec.ts +++ b/packages/angular/src/generators/component/component.spec.ts @@ -5,7 +5,7 @@ import { writeJson, } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; -import componentGenerator from './component'; +import { componentGenerator } from './component'; describe('component Generator', () => { it('should create the component correctly and export it in the entry point when "export=true"', async () => { @@ -686,7 +686,7 @@ describe('component Generator', () => { standalone: true, }) ).rejects - .toThrow(stripIndents`The "standalone" option is only supported in Angular >= 14.1.0. You are currently using 14.0.0. + .toThrow(stripIndents`The "standalone" option is only supported in Angular >= 14.1.0. You are currently using "14.0.0". You can resolve this error by removing the "standalone" option or by migrating to Angular 14.1.0.`); }); }); diff --git a/packages/angular/src/generators/component/component.ts b/packages/angular/src/generators/component/component.ts index d6966c4c06..131ece96c0 100644 --- a/packages/angular/src/generators/component/component.ts +++ b/packages/angular/src/generators/component/component.ts @@ -4,32 +4,19 @@ import { generateFiles, joinPathFragments, names, - readNxJson, - stripIndents, } from '@nrwl/devkit'; -import { lt } from 'semver'; -import { checkPathUnderProjectRoot } from '../utils/path'; -import { getInstalledAngularVersionInfo } from '../utils/version-utils'; -import { exportComponentInEntryPoint } from './lib/component'; -import { normalizeOptions } from './lib/normalize-options'; -import type { Schema } from './schema'; import { addToNgModule } from '../utils'; -import { findModuleFromOptions } from './lib/module'; +import { + exportComponentInEntryPoint, + findModuleFromOptions, + normalizeOptions, + validateOptions, +} from './lib'; +import type { Schema } from './schema'; export async function componentGenerator(tree: Tree, rawOptions: Schema) { - const installedAngularVersionInfo = getInstalledAngularVersionInfo(tree); - - if ( - lt(installedAngularVersionInfo.version, '14.1.0') && - rawOptions.standalone - ) { - throw new Error(stripIndents`The "standalone" option is only supported in Angular >= 14.1.0. You are currently using ${installedAngularVersionInfo.version}. - You can resolve this error by removing the "standalone" option or by migrating to Angular 14.1.0.`); - } - - const options = await normalizeOptions(tree, rawOptions); - - checkPathUnderProjectRoot(tree, options.project, options.path); + validateOptions(tree, rawOptions); + const options = normalizeOptions(tree, rawOptions); const pathToGenerate = options.flat ? joinPathFragments(__dirname, './files/__fileName__') @@ -38,10 +25,6 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { const componentNames = names(options.name); const typeNames = names(options.type); - const selector = - options.selector || - buildSelector(tree, componentNames.fileName, options.prefix); - generateFiles(tree, pathToGenerate, options.path, { fileName: componentNames.fileName, className: componentNames.className, @@ -55,7 +38,7 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { changeDetection: options.changeDetection, viewEncapsulation: options.viewEncapsulation, displayBlock: options.displayBlock, - selector, + selector: options.selector, tpl: '', }); @@ -123,12 +106,4 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { } } -function buildSelector(tree: Tree, name: string, prefix: string) { - const selectorPrefix = names( - prefix ?? readNxJson(tree).npmScope ?? 'app' - ).fileName; - - return names(`${selectorPrefix}-${name}`).fileName; -} - export default componentGenerator; diff --git a/packages/angular/src/generators/component/lib/component.ts b/packages/angular/src/generators/component/lib/component.ts index 036309bc28..e6584328a9 100644 --- a/packages/angular/src/generators/component/lib/component.ts +++ b/packages/angular/src/generators/component/lib/component.ts @@ -1,10 +1,11 @@ import type { Tree } from '@nrwl/devkit'; import { logger, readProjectConfiguration, stripIndents } from '@nrwl/devkit'; -import { getComponentFileInfo } from '../../utils/file-info'; +import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; +import type { StringLiteral } from 'typescript'; import { locateLibraryEntryPointFromDirectory } from '../../utils/entry-point'; +import { getComponentFileInfo } from '../../utils/file-info'; import { getRelativeImportToFile } from '../../utils/path'; import type { NormalizedSchema } from '../schema'; -import { shouldExportInEntryPoint } from './entry-point'; import { findModuleFromOptions } from './module'; export function exportComponentInEntryPoint( @@ -57,3 +58,26 @@ export function exportComponentInEntryPoint( tree.write(entryPointPath, updateEntryPointContent); } + +function shouldExportInEntryPoint( + tree: Tree, + entryPoint: string, + modulePath: string +): boolean { + if (!modulePath) { + return false; + } + + ensureTypescript(); + const { tsquery } = require('@phenomnomnominal/tsquery'); + const moduleImportPath = getRelativeImportToFile(entryPoint, modulePath); + const entryPointContent = tree.read(entryPoint, 'utf-8'); + const entryPointAst = tsquery.ast(entryPointContent); + const moduleExport = tsquery( + entryPointAst, + `ExportDeclaration StringLiteral[value='${moduleImportPath}']`, + { visitAllChildren: true } + )[0] as StringLiteral; + + return Boolean(moduleExport); +} diff --git a/packages/angular/src/generators/component/lib/entry-point.ts b/packages/angular/src/generators/component/lib/entry-point.ts deleted file mode 100644 index 0914922c20..0000000000 --- a/packages/angular/src/generators/component/lib/entry-point.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { Tree } from '@nrwl/devkit'; -import type { StringLiteral } from 'typescript'; -import { getRelativeImportToFile } from '../../utils/path'; -import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; - -export function shouldExportInEntryPoint( - tree: Tree, - entryPoint: string, - modulePath: string -): boolean { - if (!modulePath) { - return false; - } - - ensureTypescript(); - const { tsquery } = require('@phenomnomnominal/tsquery'); - const moduleImportPath = getRelativeImportToFile(entryPoint, modulePath); - const entryPointContent = tree.read(entryPoint, 'utf-8'); - const entryPointAst = tsquery.ast(entryPointContent); - const moduleExport = tsquery( - entryPointAst, - `ExportDeclaration StringLiteral[value='${moduleImportPath}']`, - { visitAllChildren: true } - )[0] as StringLiteral; - - return Boolean(moduleExport); -} diff --git a/packages/angular/src/generators/component/lib/index.ts b/packages/angular/src/generators/component/lib/index.ts new file mode 100644 index 0000000000..46e96e2292 --- /dev/null +++ b/packages/angular/src/generators/component/lib/index.ts @@ -0,0 +1,4 @@ +export * from './component'; +export * from './module'; +export * from './normalize-options'; +export * from './validate-options'; diff --git a/packages/angular/src/generators/component/lib/normalize-options.ts b/packages/angular/src/generators/component/lib/normalize-options.ts index e30a844324..b79bb5d467 100644 --- a/packages/angular/src/generators/component/lib/normalize-options.ts +++ b/packages/angular/src/generators/component/lib/normalize-options.ts @@ -1,29 +1,34 @@ import type { Tree } from '@nrwl/devkit'; import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import type { AngularProjectConfiguration } from '../../../utils/types'; +import { parseNameWithPath } from '../../utils/names'; +import { buildSelector } from '../../utils/selector'; import type { NormalizedSchema, Schema } from '../schema'; -export async function normalizeOptions( +export function normalizeOptions( tree: Tree, options: Schema -): Promise { - const { projectType, root, sourceRoot } = readProjectConfiguration( +): NormalizedSchema { + const { prefix, projectType, root, sourceRoot } = readProjectConfiguration( tree, options.project - ); - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); + ) as AngularProjectConfiguration; - const parsedName = options.name.split('/'); - const name = parsedName.pop(); - const namedPath = parsedName.join('/'); + const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); + const { name, path: namePath } = parseNameWithPath(options.name); const path = options.path ?? joinPathFragments( projectSourceRoot, projectType === 'application' ? 'app' : 'lib', - namedPath + namePath ); + const selector = + options.selector ?? + buildSelector(tree, name, options.prefix, prefix, 'fileName'); + return { ...options, name, @@ -33,5 +38,6 @@ export async function normalizeOptions( path, projectSourceRoot, projectRoot: root, + selector, }; } diff --git a/packages/angular/src/generators/component/lib/validate-options.ts b/packages/angular/src/generators/component/lib/validate-options.ts new file mode 100644 index 0000000000..55cfe46bfa --- /dev/null +++ b/packages/angular/src/generators/component/lib/validate-options.ts @@ -0,0 +1,13 @@ +import type { Tree } from '@nrwl/devkit'; +import { checkPathUnderProjectRoot } from '../../utils/path'; +import { + validateProject, + validateStandaloneOption, +} from '../../utils/validations'; +import type { Schema } from '../schema'; + +export function validateOptions(tree: Tree, options: Schema): void { + validateProject(tree, options.project); + checkPathUnderProjectRoot(tree, options.project, options.path); + validateStandaloneOption(tree, options.standalone); +} diff --git a/packages/angular/src/generators/component/schema.d.ts b/packages/angular/src/generators/component/schema.d.ts index c09034a39e..c02f0d6478 100644 --- a/packages/angular/src/generators/component/schema.d.ts +++ b/packages/angular/src/generators/component/schema.d.ts @@ -25,4 +25,5 @@ export interface NormalizedSchema extends Schema { path: string; projectSourceRoot: string; projectRoot: string; + selector: string; } diff --git a/packages/angular/src/generators/component/schema.json b/packages/angular/src/generators/component/schema.json index 2702c652c5..03823ac4d8 100644 --- a/packages/angular/src/generators/component/schema.json +++ b/packages/angular/src/generators/component/schema.json @@ -54,7 +54,7 @@ "alias": "t" }, "standalone": { - "description": "Whether the generated component is standalone. _Note: This is only supported in Angular versions >= 14.1.0_", + "description": "Whether the generated component is standalone. _Note: This is only supported in Angular versions >= 14.1.0_.", "type": "boolean", "default": false, "x-priority": "important" diff --git a/packages/angular/src/generators/convert-tslint-to-eslint/convert-tslint-to-eslint.ts b/packages/angular/src/generators/convert-tslint-to-eslint/convert-tslint-to-eslint.ts index ef9e192369..76c729fd16 100755 --- a/packages/angular/src/generators/convert-tslint-to-eslint/convert-tslint-to-eslint.ts +++ b/packages/angular/src/generators/convert-tslint-to-eslint/convert-tslint-to-eslint.ts @@ -6,10 +6,11 @@ import { logger, Tree, } from '@nrwl/devkit'; -import { warnForSchematicUsage } from '../utils/warn-for-schematic-usage'; import { ConvertTSLintToESLintSchema, ProjectConverter } from '@nrwl/linter'; import type { Linter } from 'eslint'; +import type { AngularProjectConfiguration } from '../../utils/types'; import { addLintingGenerator } from '../add-linting/add-linting'; +import { warnForSchematicUsage } from '../utils/warn-for-schematic-usage'; export async function conversionGenerator( host: Tree, @@ -33,7 +34,7 @@ export async function conversionGenerator( await addLintingGenerator(host, { projectName, projectRoot: projectConfig.root, - prefix: (projectConfig as any).prefix || 'app', + prefix: (projectConfig as AngularProjectConfiguration).prefix || 'app', /** * We set the parserOptions.project config just in case the converted config uses * rules which require type-checking. Later in the conversion we check if it actually diff --git a/packages/angular/src/generators/directive/lib/normalize-options.ts b/packages/angular/src/generators/directive/lib/normalize-options.ts index 0de3c9bfed..143b0d52f6 100644 --- a/packages/angular/src/generators/directive/lib/normalize-options.ts +++ b/packages/angular/src/generators/directive/lib/normalize-options.ts @@ -1,21 +1,18 @@ -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; -import { - joinPathFragments, - names, - readNxJson, - readProjectConfiguration, -} from '@nrwl/devkit'; -import { parseName } from '../../utils/names'; +import type { Tree } from '@nrwl/devkit'; +import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import type { AngularProjectConfiguration } from '../../../utils/types'; +import { parseNameWithPath } from '../../utils/names'; +import { buildSelector } from '../../utils/selector'; import type { Schema } from '../schema'; export function normalizeOptions(tree: Tree, options: Schema) { const { prefix, projectType, root, sourceRoot } = readProjectConfiguration( tree, options.project - ) as ProjectConfiguration & { prefix?: string }; + ) as AngularProjectConfiguration; const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const { name, path: namePath } = parseName(options.name); + const { name, path: namePath } = parseNameWithPath(options.name); const path = options.path ?? @@ -26,7 +23,8 @@ export function normalizeOptions(tree: Tree, options: Schema) { ); const selector = - options.selector ?? buildSelector(tree, name, options.prefix, prefix); + options.selector ?? + buildSelector(tree, name, options.prefix, prefix, 'propertyName'); return { ...options, @@ -37,18 +35,3 @@ export function normalizeOptions(tree: Tree, options: Schema) { selector, }; } - -function buildSelector( - tree: Tree, - name: string, - prefix: string, - projectPrefix: string -): string { - let selector = name; - prefix ??= projectPrefix ?? readNxJson(tree).npmScope; - if (prefix) { - selector = `${prefix}-${selector}`; - } - - return names(selector).propertyName; -} diff --git a/packages/angular/src/generators/directive/lib/validate-options.ts b/packages/angular/src/generators/directive/lib/validate-options.ts index 7af9476ea0..55cfe46bfa 100644 --- a/packages/angular/src/generators/directive/lib/validate-options.ts +++ b/packages/angular/src/generators/directive/lib/validate-options.ts @@ -1,21 +1,13 @@ import type { Tree } from '@nrwl/devkit'; -import { getProjects, stripIndents } from '@nrwl/devkit'; -import { lt } from 'semver'; import { checkPathUnderProjectRoot } from '../../utils/path'; -import { getInstalledAngularVersionInfo } from '../../utils/version-utils'; +import { + validateProject, + validateStandaloneOption, +} from '../../utils/validations'; import type { Schema } from '../schema'; export function validateOptions(tree: Tree, options: Schema): void { - const projects = getProjects(tree); - if (!projects.has(options.project)) { - throw new Error(`Project "${options.project}" does not exist!`); - } - + validateProject(tree, options.project); checkPathUnderProjectRoot(tree, options.project, options.path); - - const installedAngularVersionInfo = getInstalledAngularVersionInfo(tree); - if (lt(installedAngularVersionInfo.version, '14.1.0') && options.standalone) { - throw new Error(stripIndents`The "standalone" option is only supported in Angular >= 14.1.0. You are currently using "${installedAngularVersionInfo.version}". - You can resolve this error by removing the "standalone" option or by migrating to Angular 14.1.0.`); - } + validateStandaloneOption(tree, options.standalone); } diff --git a/packages/angular/src/generators/library/lib/add-project.ts b/packages/angular/src/generators/library/lib/add-project.ts index 3ea3e3be1b..a3ccbf31d6 100644 --- a/packages/angular/src/generators/library/lib/add-project.ts +++ b/packages/angular/src/generators/library/lib/add-project.ts @@ -1,12 +1,13 @@ -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; +import type { Tree } from '@nrwl/devkit'; import { addProjectConfiguration, joinPathFragments } from '@nrwl/devkit'; -import { NormalizedSchema } from './normalized-schema'; +import type { AngularProjectConfiguration } from '../../../utils/types'; +import type { NormalizedSchema } from './normalized-schema'; export function addProject( tree: Tree, libraryOptions: NormalizedSchema['libraryOptions'] ) { - const project: ProjectConfiguration & { prefix: string } = { + const project: AngularProjectConfiguration = { name: libraryOptions.name, root: libraryOptions.projectRoot, sourceRoot: joinPathFragments(libraryOptions.projectRoot, 'src'), diff --git a/packages/angular/src/generators/library/lib/create-files.ts b/packages/angular/src/generators/library/lib/create-files.ts index 81b782817d..bfe6bb511f 100644 --- a/packages/angular/src/generators/library/lib/create-files.ts +++ b/packages/angular/src/generators/library/lib/create-files.ts @@ -1,4 +1,4 @@ -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; +import type { Tree } from '@nrwl/devkit'; import { generateFiles, getWorkspaceLayout, @@ -6,14 +6,15 @@ import { names, offsetFromRoot, } from '@nrwl/devkit'; -import { NormalizedSchema } from './normalized-schema'; -import { UnitTestRunner } from '../../../utils/test-runners'; import { getRootTsConfigFileName } from '@nrwl/js'; +import { UnitTestRunner } from '../../../utils/test-runners'; +import type { AngularProjectConfiguration } from '../../../utils/types'; +import type { NormalizedSchema } from './normalized-schema'; export function createFiles( tree: Tree, options: NormalizedSchema, - project: ProjectConfiguration & { prefix: string } + project: AngularProjectConfiguration ) { const { npmScope } = getWorkspaceLayout(tree); const rootOffset = offsetFromRoot(options.libraryOptions.projectRoot); diff --git a/packages/angular/src/generators/pipe/pipe.ts b/packages/angular/src/generators/pipe/pipe.ts index 80cab7808c..e20c293e7f 100644 --- a/packages/angular/src/generators/pipe/pipe.ts +++ b/packages/angular/src/generators/pipe/pipe.ts @@ -1,4 +1,4 @@ -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; +import type { Tree } from '@nrwl/devkit'; import { formatFiles, generateFiles, @@ -7,9 +7,10 @@ import { names, readProjectConfiguration, } from '@nrwl/devkit'; -import type { Schema } from './schema'; -import { checkPathUnderProjectRoot } from '../utils/path'; +import type { AngularProjectConfiguration } from '../../utils/types'; import { addToNgModule, findModule } from '../utils'; +import { checkPathUnderProjectRoot } from '../utils/path'; +import type { Schema } from './schema'; let tsModule: typeof import('typescript'); @@ -24,7 +25,7 @@ export async function pipeGenerator(tree: Tree, schema: Schema) { const project = readProjectConfiguration( tree, schema.project - ) as ProjectConfiguration & { prefix?: string }; + ) as AngularProjectConfiguration; const path = schema.path ?? `${project.sourceRoot}`; const pipeNames = names(schema.name); diff --git a/packages/angular/src/generators/setup-mf/lib/add-remote-entry.ts b/packages/angular/src/generators/setup-mf/lib/add-remote-entry.ts index ccae5b760d..696311d55e 100644 --- a/packages/angular/src/generators/setup-mf/lib/add-remote-entry.ts +++ b/packages/angular/src/generators/setup-mf/lib/add-remote-entry.ts @@ -1,25 +1,23 @@ -import type { ProjectConfiguration, Tree } from '@nrwl/devkit'; +import type { Tree } from '@nrwl/devkit'; import { generateFiles, joinPathFragments, readNxJson, readProjectConfiguration, } from '@nrwl/devkit'; -import type { Schema } from '../schema'; import { addRoute } from '../../../utils/nx-devkit/route-utils'; +import type { AngularProjectConfiguration } from '../../../utils/types'; +import type { Schema } from '../schema'; export function addRemoteEntry( tree: Tree, - { appName, routing, mfType, prefix, standalone }: Schema, + { appName, routing, prefix, standalone }: Schema, appRoot: string ) { prefix = prefix ?? - ( - readProjectConfiguration(tree, appName) as ProjectConfiguration & { - prefix?: string; - } - )?.prefix ?? + (readProjectConfiguration(tree, appName) as AngularProjectConfiguration) + ?.prefix ?? readNxJson(tree).npmScope; generateFiles( tree, diff --git a/packages/angular/src/generators/utils/names.ts b/packages/angular/src/generators/utils/names.ts index ec0afe5f72..838e3e5682 100644 --- a/packages/angular/src/generators/utils/names.ts +++ b/packages/angular/src/generators/utils/names.ts @@ -2,7 +2,7 @@ import { normalizePath } from '@nrwl/devkit'; export type NameInfo = { name: string; path: string }; -export function parseName(rawName: string): NameInfo { +export function parseNameWithPath(rawName: string): NameInfo { const parsedName = normalizePath(rawName).split('/'); const name = parsedName.pop(); const path = parsedName.join('/'); diff --git a/packages/angular/src/generators/utils/selector.ts b/packages/angular/src/generators/utils/selector.ts new file mode 100644 index 0000000000..ec4011af00 --- /dev/null +++ b/packages/angular/src/generators/utils/selector.ts @@ -0,0 +1,18 @@ +import type { Tree } from '@nrwl/devkit'; +import { names, readNxJson } from '@nrwl/devkit'; + +export function buildSelector( + tree: Tree, + name: string, + prefix: string | undefined, + projectPrefix: string | undefined, + casing: keyof Pick, 'fileName' | 'propertyName'> +): string { + let selector = name; + prefix ??= projectPrefix ?? readNxJson(tree)?.npmScope; + if (prefix) { + selector = `${prefix}-${selector}`; + } + + return names(selector)[casing]; +} diff --git a/packages/angular/src/generators/utils/validations.ts b/packages/angular/src/generators/utils/validations.ts new file mode 100644 index 0000000000..4495aab516 --- /dev/null +++ b/packages/angular/src/generators/utils/validations.ts @@ -0,0 +1,32 @@ +import type { Tree } from '@nrwl/devkit'; +import { getProjects, stripIndents } from '@nrwl/devkit'; +import { lt } from 'semver'; +import { getInstalledAngularVersionInfo } from './version-utils'; + +export function validateProject(tree: Tree, projectName: string): void { + const projects = getProjects(tree); + + if (!projects.has(projectName)) { + throw new Error( + `Project "${projectName}" does not exist! Please provide an existing project name.` + ); + } +} + +export function validateStandaloneOption( + tree: Tree, + standalone: boolean | undefined, + angularVersion?: string +): void { + if (!standalone) { + return; + } + + const installedAngularVersion = + angularVersion ?? getInstalledAngularVersionInfo(tree).version; + + if (lt(installedAngularVersion, '14.1.0')) { + throw new Error(stripIndents`The "standalone" option is only supported in Angular >= 14.1.0. You are currently using "${installedAngularVersion}". + You can resolve this error by removing the "standalone" option or by migrating to Angular 14.1.0.`); + } +} diff --git a/packages/angular/src/utils/types.ts b/packages/angular/src/utils/types.ts new file mode 100644 index 0000000000..1eaf0ac0f6 --- /dev/null +++ b/packages/angular/src/utils/types.ts @@ -0,0 +1,5 @@ +import type { ProjectConfiguration } from '@nrwl/devkit'; + +export type AngularProjectConfiguration = ProjectConfiguration & { + prefix?: string; +};