diff --git a/docs/generated/packages/angular/generators/scam.json b/docs/generated/packages/angular/generators/scam.json index 71e7e01b80708..030d961b9cde9 100644 --- a/docs/generated/packages/angular/generators/scam.json +++ b/docs/generated/packages/angular/generators/scam.json @@ -116,6 +116,12 @@ "description": "Specifies if the SCAM should be exported from the project's entry point (normally `index.ts`). It only applies to libraries.", "default": true, "x-priority": "important" + }, + "skipFormat": { + "type": "boolean", + "description": "Skip formatting files.", + "default": false, + "x-priority": "internal" } }, "required": ["name", "project"], diff --git a/packages/angular/src/generators/component/__snapshots__/component.spec.ts.snap b/packages/angular/src/generators/component/__snapshots__/component.spec.ts.snap index 0f57ec8cc61ec..254b2d0251781 100644 --- a/packages/angular/src/generators/component/__snapshots__/component.spec.ts.snap +++ b/packages/angular/src/generators/component/__snapshots__/component.spec.ts.snap @@ -54,6 +54,55 @@ export * from './lib/example/example.component'; " `; +exports[`component Generator should create component files correctly: component 1`] = ` +"import { Component } from '@angular/core'; + +@Component({ + selector: 'proj-example', + templateUrl: './example.component.html', + styleUrls: ['./example.component.css'], +}) +export class ExampleComponent {} +" +`; + +exports[`component Generator should create component files correctly: component test file 1`] = ` +"import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ExampleComponent } from './example.component'; + +describe('ExampleComponent', () => { + let component: ExampleComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ExampleComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ExampleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); +" +`; + +exports[`component Generator should create component files correctly: entry point file 1`] = ` +"export * from './lib/lib.module'; +" +`; + +exports[`component Generator should create component files correctly: stylesheet 1`] = `""`; + +exports[`component Generator should create component files correctly: template 1`] = ` +"

example works!

+" +`; + exports[`component Generator should create the component correctly and export it in the entry point when "export=true" 1`] = ` "import { Component } from '@angular/core'; @@ -137,3 +186,27 @@ exports[`component Generator should create the component correctly but not expor export class ExampleComponent {} " `; + +exports[`component Generator should inline styles when --inline-style=true 1`] = ` +"import { Component } from '@angular/core'; + +@Component({ + selector: 'proj-example', + templateUrl: './example.component.html', + styles: [], +}) +export class ExampleComponent {} +" +`; + +exports[`component Generator should inline template when --inline-template=true 1`] = ` +"import { Component } from '@angular/core'; + +@Component({ + selector: 'proj-example', + template: \`

example works!

\`, + styleUrls: ['./example.component.css'], +}) +export class ExampleComponent {} +" +`; diff --git a/packages/angular/src/generators/component/component.spec.ts b/packages/angular/src/generators/component/component.spec.ts index 7ee706d56b613..0213dd5b248e8 100644 --- a/packages/angular/src/generators/component/component.spec.ts +++ b/packages/angular/src/generators/component/component.spec.ts @@ -8,6 +8,159 @@ import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { componentGenerator } from './component'; describe('component Generator', () => { + it('should create component files correctly', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + addProjectConfiguration(tree, 'lib1', { + projectType: 'library', + sourceRoot: 'libs/lib1/src', + root: 'libs/lib1', + }); + tree.write( + 'libs/lib1/src/lib/lib.module.ts', + ` + import { NgModule } from '@angular/core'; + + @NgModule({ + declarations: [], + exports: [] + }) + export class LibModule {}` + ); + tree.write('libs/lib1/src/index.ts', 'export * from "./lib/lib.module";'); + + // ACT + await componentGenerator(tree, { + name: 'example', + project: 'lib1', + }); + + // ASSERT + expect( + tree.read('libs/lib1/src/lib/example/example.component.ts', 'utf-8') + ).toMatchSnapshot('component'); + expect( + tree.read('libs/lib1/src/lib/example/example.component.html', 'utf-8') + ).toMatchSnapshot('template'); + expect( + tree.read('libs/lib1/src/lib/example/example.component.css', 'utf-8') + ).toMatchSnapshot('stylesheet'); + expect( + tree.read('libs/lib1/src/lib/example/example.component.spec.ts', 'utf-8') + ).toMatchSnapshot('component test file'); + expect(tree.read('libs/lib1/src/index.ts', 'utf-8')).toMatchSnapshot( + 'entry point file' + ); + }); + + it('should not generate test file when --skip-tests=true', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + addProjectConfiguration(tree, 'lib1', { + projectType: 'library', + sourceRoot: 'libs/lib1/src', + root: 'libs/lib1', + }); + tree.write( + 'libs/lib1/src/lib/lib.module.ts', + ` + import { NgModule } from '@angular/core'; + + @NgModule({ + declarations: [], + exports: [] + }) + export class LibModule {}` + ); + tree.write('libs/lib1/src/index.ts', ''); + + // ACT + await componentGenerator(tree, { + name: 'example', + project: 'lib1', + skipTests: true, + }); + + // ASSERT + expect( + tree.exists('libs/lib1/src/lib/example/example.component.spec.ts') + ).toBe(false); + }); + + it('should inline template when --inline-template=true', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + addProjectConfiguration(tree, 'lib1', { + projectType: 'library', + sourceRoot: 'libs/lib1/src', + root: 'libs/lib1', + }); + tree.write( + 'libs/lib1/src/lib/lib.module.ts', + ` + import { NgModule } from '@angular/core'; + + @NgModule({ + declarations: [], + exports: [] + }) + export class LibModule {}` + ); + tree.write('libs/lib1/src/index.ts', ''); + + // ACT + await componentGenerator(tree, { + name: 'example', + project: 'lib1', + inlineTemplate: true, + }); + + // ASSERT + expect( + tree.read('libs/lib1/src/lib/example/example.component.ts', 'utf-8') + ).toMatchSnapshot(); + expect( + tree.exists('libs/lib1/src/lib/example/example.component.html') + ).toBe(false); + }); + + it('should inline styles when --inline-style=true', async () => { + // ARRANGE + const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + addProjectConfiguration(tree, 'lib1', { + projectType: 'library', + sourceRoot: 'libs/lib1/src', + root: 'libs/lib1', + }); + tree.write( + 'libs/lib1/src/lib/lib.module.ts', + ` + import { NgModule } from '@angular/core'; + + @NgModule({ + declarations: [], + exports: [] + }) + export class LibModule {}` + ); + tree.write('libs/lib1/src/index.ts', ''); + + // ACT + await componentGenerator(tree, { + name: 'example', + project: 'lib1', + inlineStyle: true, + }); + + // ASSERT + expect( + tree.read('libs/lib1/src/lib/example/example.component.ts', 'utf-8') + ).toMatchSnapshot(); + expect(tree.exists('libs/lib1/src/lib/example/example.component.css')).toBe( + false + ); + }); + it('should create the component correctly and export it in the entry point when "export=true"', async () => { // ARRANGE const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); diff --git a/packages/angular/src/generators/component/component.ts b/packages/angular/src/generators/component/component.ts index 131ece96c060c..e46fd892d2b19 100644 --- a/packages/angular/src/generators/component/component.ts +++ b/packages/angular/src/generators/component/component.ts @@ -18,36 +18,35 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { validateOptions(tree, rawOptions); const options = normalizeOptions(tree, rawOptions); - const pathToGenerate = options.flat - ? joinPathFragments(__dirname, './files/__fileName__') - : joinPathFragments(__dirname, './files'); - const componentNames = names(options.name); const typeNames = names(options.type); - generateFiles(tree, pathToGenerate, options.path, { - fileName: componentNames.fileName, - className: componentNames.className, - type: typeNames.fileName, - typeClassName: typeNames.className, - style: options.style, - inlineStyle: options.inlineStyle, - inlineTemplate: options.inlineTemplate, - standalone: options.standalone, - skipSelector: options.skipSelector, - changeDetection: options.changeDetection, - viewEncapsulation: options.viewEncapsulation, - displayBlock: options.displayBlock, - selector: options.selector, - tpl: '', - }); + generateFiles( + tree, + joinPathFragments(__dirname, 'files'), + options.directory, + { + fileName: componentNames.fileName, + className: componentNames.className, + type: typeNames.fileName, + typeClassName: typeNames.className, + style: options.style, + inlineStyle: options.inlineStyle, + inlineTemplate: options.inlineTemplate, + standalone: options.standalone, + skipSelector: options.skipSelector, + changeDetection: options.changeDetection, + viewEncapsulation: options.viewEncapsulation, + displayBlock: options.displayBlock, + selector: options.selector, + tpl: '', + } + ); if (options.skipTests) { const pathToSpecFile = joinPathFragments( - options.path, - `${!options.flat ? `${componentNames.fileName}/` : ``}${ - componentNames.fileName - }.${typeNames.fileName}.spec.ts` + options.directory, + `${componentNames.fileName}.${typeNames.fileName}.spec.ts` ); tree.delete(pathToSpecFile); @@ -55,10 +54,8 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { if (options.inlineTemplate) { const pathToTemplateFile = joinPathFragments( - options.path, - `${!options.flat ? `${componentNames.fileName}/` : ``}${ - componentNames.fileName - }.${typeNames.fileName}.html` + options.directory, + `${componentNames.fileName}.${typeNames.fileName}.html` ); tree.delete(pathToTemplateFile); @@ -66,10 +63,8 @@ export async function componentGenerator(tree: Tree, rawOptions: Schema) { if (options.inlineStyle) { const pathToStyleFile = joinPathFragments( - options.path, - `${!options.flat ? `${componentNames.fileName}/` : ``}${ - componentNames.fileName - }.${typeNames.fileName}.${options.style}` + options.directory, + `${componentNames.fileName}.${typeNames.fileName}.${options.style}` ); tree.delete(pathToStyleFile); diff --git a/packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.__style__ b/packages/angular/src/generators/component/files/__fileName__.__type__.__style__ similarity index 100% rename from packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.__style__ rename to packages/angular/src/generators/component/files/__fileName__.__type__.__style__ diff --git a/packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.html__tpl__ b/packages/angular/src/generators/component/files/__fileName__.__type__.html__tpl__ similarity index 100% rename from packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.html__tpl__ rename to packages/angular/src/generators/component/files/__fileName__.__type__.html__tpl__ diff --git a/packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.spec.ts__tpl__ b/packages/angular/src/generators/component/files/__fileName__.__type__.spec.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.spec.ts__tpl__ rename to packages/angular/src/generators/component/files/__fileName__.__type__.spec.ts__tpl__ diff --git a/packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.ts__tpl__ b/packages/angular/src/generators/component/files/__fileName__.__type__.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/component/files/__fileName__/__fileName__.__type__.ts__tpl__ rename to packages/angular/src/generators/component/files/__fileName__.__type__.ts__tpl__ diff --git a/packages/angular/src/generators/component/lib/component.ts b/packages/angular/src/generators/component/lib/component.ts index e6584328a9d2e..70623930a7815 100644 --- a/packages/angular/src/generators/component/lib/component.ts +++ b/packages/angular/src/generators/component/lib/component.ts @@ -3,7 +3,6 @@ import { logger, readProjectConfiguration, stripIndents } from '@nrwl/devkit'; 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 { findModuleFromOptions } from './module'; @@ -22,11 +21,9 @@ export function exportComponentInEntryPoint( return; } - const { directory, filePath } = getComponentFileInfo(tree, schema); - const entryPointPath = locateLibraryEntryPointFromDirectory( tree, - directory, + schema.directory, root, schema.projectSourceRoot ); @@ -48,7 +45,7 @@ export function exportComponentInEntryPoint( const relativePathFromEntryPoint = getRelativeImportToFile( entryPointPath, - filePath + schema.filePath ); const updateEntryPointContent = stripIndents`${tree.read( entryPointPath, diff --git a/packages/angular/src/generators/component/lib/module.ts b/packages/angular/src/generators/component/lib/module.ts index 7d94ef37cfdeb..63eca6af7f4f9 100644 --- a/packages/angular/src/generators/component/lib/module.ts +++ b/packages/angular/src/generators/component/lib/module.ts @@ -15,12 +15,10 @@ export function findModuleFromOptions( projectRoot: string ): string | null { if (!options.module) { - const pathToCheck = joinPathFragments(options.path, options.name); - - return normalizePath(findModule(tree, pathToCheck, projectRoot)); + return normalizePath(findModule(tree, options.directory, projectRoot)); } else { const modulePath = joinPathFragments(options.path, options.module); - const componentPath = joinPathFragments(options.path, options.name); + const componentPath = options.directory; const moduleBaseName = basename(modulePath); const candidateSet = new Set([options.path]); diff --git a/packages/angular/src/generators/component/lib/normalize-options.ts b/packages/angular/src/generators/component/lib/normalize-options.ts index b79bb5d467103..b46391db2b5cf 100644 --- a/packages/angular/src/generators/component/lib/normalize-options.ts +++ b/packages/angular/src/generators/component/lib/normalize-options.ts @@ -1,7 +1,7 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import { readProjectConfiguration } from '@nrwl/devkit'; import type { AngularProjectConfiguration } from '../../../utils/types'; -import { parseNameWithPath } from '../../utils/names'; +import { normalizeNameAndPaths } from '../../utils/path'; import { buildSelector } from '../../utils/selector'; import type { NormalizedSchema, Schema } from '../schema'; @@ -9,22 +9,15 @@ export function normalizeOptions( tree: Tree, options: Schema ): NormalizedSchema { - const { prefix, projectType, root, sourceRoot } = readProjectConfiguration( + options.type ??= 'component'; + const { directory, filePath, name, path, root, sourceRoot } = + normalizeNameAndPaths(tree, options); + + const { prefix } = readProjectConfiguration( tree, options.project ) as AngularProjectConfiguration; - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const { name, path: namePath } = parseNameWithPath(options.name); - - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib', - namePath - ); - const selector = options.selector ?? buildSelector(tree, name, options.prefix, prefix, 'fileName'); @@ -32,11 +25,12 @@ export function normalizeOptions( return { ...options, name, - type: options.type ?? 'component', changeDetection: options.changeDetection ?? 'Default', style: options.style ?? 'css', + directory, + filePath, path, - projectSourceRoot, + projectSourceRoot: sourceRoot, projectRoot: root, selector, }; diff --git a/packages/angular/src/generators/component/schema.d.ts b/packages/angular/src/generators/component/schema.d.ts index c02f0d6478d92..510d1c099bf70 100644 --- a/packages/angular/src/generators/component/schema.d.ts +++ b/packages/angular/src/generators/component/schema.d.ts @@ -22,7 +22,8 @@ export interface Schema { } export interface NormalizedSchema extends Schema { - path: string; + directory: string; + filePath: string; projectSourceRoot: string; projectRoot: string; selector: string; diff --git a/packages/angular/src/generators/directive/directive.ts b/packages/angular/src/generators/directive/directive.ts index ddf161cbb14b3..1082fa76bdcb1 100644 --- a/packages/angular/src/generators/directive/directive.ts +++ b/packages/angular/src/generators/directive/directive.ts @@ -15,13 +15,10 @@ export async function directiveGenerator(tree: Tree, schema: Schema) { const directiveNames = names(options.name); - const pathToGenerateFiles = options.flat - ? './files/__directiveFileName__' - : './files'; generateFiles( tree, - joinPathFragments(__dirname, pathToGenerateFiles), - options.path, + joinPathFragments(__dirname, 'files'), + options.directory, { selector: options.selector, directiveClassName: directiveNames.className, @@ -33,10 +30,8 @@ export async function directiveGenerator(tree: Tree, schema: Schema) { if (options.skipTests) { const pathToSpecFile = joinPathFragments( - options.path, - `${!options.flat ? `${directiveNames.fileName}/` : ``}${ - directiveNames.fileName - }.directive.spec.ts` + options.directory, + `${directiveNames.fileName}.directive.spec.ts` ); tree.delete(pathToSpecFile); diff --git a/packages/angular/src/generators/directive/files/__directiveFileName__/__directiveFileName__.directive.spec.ts__tpl__ b/packages/angular/src/generators/directive/files/__directiveFileName__.directive.spec.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/directive/files/__directiveFileName__/__directiveFileName__.directive.spec.ts__tpl__ rename to packages/angular/src/generators/directive/files/__directiveFileName__.directive.spec.ts__tpl__ diff --git a/packages/angular/src/generators/directive/files/__directiveFileName__/__directiveFileName__.directive.ts__tpl__ b/packages/angular/src/generators/directive/files/__directiveFileName__.directive.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/directive/files/__directiveFileName__/__directiveFileName__.directive.ts__tpl__ rename to packages/angular/src/generators/directive/files/__directiveFileName__.directive.ts__tpl__ diff --git a/packages/angular/src/generators/directive/lib/normalize-options.ts b/packages/angular/src/generators/directive/lib/normalize-options.ts index 143b0d52f6af9..fd85ec5b222e5 100644 --- a/packages/angular/src/generators/directive/lib/normalize-options.ts +++ b/packages/angular/src/generators/directive/lib/normalize-options.ts @@ -1,37 +1,33 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import { readProjectConfiguration } from '@nrwl/devkit'; import type { AngularProjectConfiguration } from '../../../utils/types'; -import { parseNameWithPath } from '../../utils/names'; +import { normalizeNameAndPaths } from '../../utils/path'; import { buildSelector } from '../../utils/selector'; -import type { Schema } from '../schema'; +import type { NormalizedSchema, Schema } from '../schema'; -export function normalizeOptions(tree: Tree, options: Schema) { - const { prefix, projectType, root, sourceRoot } = readProjectConfiguration( +export function normalizeOptions( + tree: Tree, + options: Schema +): NormalizedSchema { + const { directory, name, path } = normalizeNameAndPaths(tree, { + ...options, + type: 'directive', + }); + + const { prefix } = readProjectConfiguration( tree, options.project ) as AngularProjectConfiguration; - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const { name, path: namePath } = parseNameWithPath(options.name); - - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib', - namePath - ); - const selector = options.selector ?? buildSelector(tree, name, options.prefix, prefix, 'propertyName'); return { ...options, + directory, name, path, - projectRoot: root, - projectSourceRoot, selector, }; } diff --git a/packages/angular/src/generators/directive/schema.d.ts b/packages/angular/src/generators/directive/schema.d.ts index 554dbcfdf6500..5e70ed24e30ac 100644 --- a/packages/angular/src/generators/directive/schema.d.ts +++ b/packages/angular/src/generators/directive/schema.d.ts @@ -12,3 +12,8 @@ export interface Schema { export?: boolean; skipFormat?: boolean; } + +export interface NormalizedSchema extends Schema { + directory: string; + path: string; +} diff --git a/packages/angular/src/generators/pipe/files/__pipeFileName__/__pipeFileName__.pipe.spec.ts__tpl__ b/packages/angular/src/generators/pipe/files/__pipeFileName__.pipe.spec.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/pipe/files/__pipeFileName__/__pipeFileName__.pipe.spec.ts__tpl__ rename to packages/angular/src/generators/pipe/files/__pipeFileName__.pipe.spec.ts__tpl__ diff --git a/packages/angular/src/generators/pipe/files/__pipeFileName__/__pipeFileName__.pipe.ts__tpl__ b/packages/angular/src/generators/pipe/files/__pipeFileName__.pipe.ts__tpl__ similarity index 100% rename from packages/angular/src/generators/pipe/files/__pipeFileName__/__pipeFileName__.pipe.ts__tpl__ rename to packages/angular/src/generators/pipe/files/__pipeFileName__.pipe.ts__tpl__ diff --git a/packages/angular/src/generators/pipe/lib/normalize-options.ts b/packages/angular/src/generators/pipe/lib/normalize-options.ts index 4b82efa55c4f6..5b0010299714f 100644 --- a/packages/angular/src/generators/pipe/lib/normalize-options.ts +++ b/packages/angular/src/generators/pipe/lib/normalize-options.ts @@ -1,27 +1,20 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; -import { parseNameWithPath } from '../../utils/names'; +import { normalizeNameAndPaths } from '../../utils/path'; import type { NormalizedSchema, Schema } from '../schema'; export function normalizeOptions( tree: Tree, options: Schema ): NormalizedSchema { - const { projectType, root, sourceRoot } = readProjectConfiguration( - tree, - options.project - ); + const { directory, name, path } = normalizeNameAndPaths(tree, { + ...options, + type: 'pipe', + }); - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const { name, path: namePath } = parseNameWithPath(options.name); - - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib', - namePath - ); - - return { ...options, name, path }; + return { + ...options, + directory, + name, + path, + }; } diff --git a/packages/angular/src/generators/pipe/pipe.ts b/packages/angular/src/generators/pipe/pipe.ts index 7037b0bcd877b..e229db12c8dc2 100644 --- a/packages/angular/src/generators/pipe/pipe.ts +++ b/packages/angular/src/generators/pipe/pipe.ts @@ -13,15 +13,12 @@ export async function pipeGenerator(tree: Tree, rawOptions: Schema) { validateOptions(tree, rawOptions); const options = normalizeOptions(tree, rawOptions); - const pathToGenerateFiles = options.flat - ? './files/__pipeFileName__' - : './files'; const pipeNames = names(options.name); generateFiles( tree, - joinPathFragments(__dirname, pathToGenerateFiles), - options.path, + joinPathFragments(__dirname, 'files'), + options.directory, { pipeClassName: pipeNames.className, pipeFileName: pipeNames.fileName, @@ -33,10 +30,8 @@ export async function pipeGenerator(tree: Tree, rawOptions: Schema) { if (options.skipTests) { const pathToSpecFile = joinPathFragments( - options.path, - `${!options.flat ? `${pipeNames.fileName}/` : ``}${ - pipeNames.fileName - }.pipe.spec.ts` + options.directory, + `${pipeNames.fileName}.pipe.spec.ts` ); tree.delete(pathToSpecFile); diff --git a/packages/angular/src/generators/pipe/schema.d.ts b/packages/angular/src/generators/pipe/schema.d.ts index 8eeb84e5bd66c..87c13019442be 100644 --- a/packages/angular/src/generators/pipe/schema.d.ts +++ b/packages/angular/src/generators/pipe/schema.d.ts @@ -12,5 +12,6 @@ export interface Schema { } export interface NormalizedSchema extends Schema { + directory: string; path: string; } diff --git a/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.spec.ts b/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.spec.ts index dd3d425aa3d5d..d8aeea7977adb 100644 --- a/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.spec.ts +++ b/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.spec.ts @@ -22,23 +22,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/example/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/example/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: true, + path: 'apps/app1/src/app', + }); // ASSERT const directiveSource = tree.read( @@ -83,23 +77,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/example/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: false, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/example/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: false, + path: 'apps/app1/src/app', + }); // ASSERT const directiveModuleSource = tree.read( @@ -138,23 +126,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: true, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: true, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const directiveSource = tree.read( @@ -199,23 +181,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: false, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: false, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const directiveModuleSource = tree.read( @@ -255,23 +231,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app/random/example', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/random/example/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app/random/example', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/random/example/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const directiveModuleSource = tree.read( @@ -317,23 +287,17 @@ describe('convertDirectiveToScam', () => { }); // ACT - convertDirectiveToScam( - tree, - { - directory: 'apps/app1/src/app/random', - fileName: 'example.directive', - filePath: 'apps/app1/src/app/random/example.directive.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: true, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertDirectiveToScam(tree, { + directory: 'apps/app1/src/app/random', + fileName: 'example.directive', + filePath: 'apps/app1/src/app/random/example.directive.ts', + name: 'example', + project: 'app1', + export: false, + flat: true, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const directiveModuleSource = tree.read( diff --git a/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.ts b/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.ts index 664a9953065f1..db98feb18bbae 100644 --- a/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.ts +++ b/packages/angular/src/generators/scam-directive/lib/convert-directive-to-scam.ts @@ -1,20 +1,18 @@ import type { Tree } from '@nrwl/devkit'; import { joinPathFragments, names } from '@nrwl/devkit'; -import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import { insertImport } from '@nrwl/js'; -import type { FileInfo } from '../../utils/file-info'; +import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import type { NormalizedSchema } from '../schema'; let tsModule: typeof import('typescript'); export function convertDirectiveToScam( tree: Tree, - directiveFileInfo: FileInfo, options: NormalizedSchema ): void { - if (!tree.exists(directiveFileInfo.filePath)) { + if (!tree.exists(options.filePath)) { throw new Error( - `Couldn't find directive at path ${directiveFileInfo.filePath} to add SCAM setup.` + `Couldn't find directive at path ${options.filePath} to add SCAM setup.` ); } if (!tsModule) { @@ -26,12 +24,9 @@ export function convertDirectiveToScam( const directiveClassName = `${directiveNames.className}${typeNames.className}`; if (options.inlineScam) { - const currentDirectiveContents = tree.read( - directiveFileInfo.filePath, - 'utf-8' - ); + const currentDirectiveContents = tree.read(options.filePath, 'utf-8'); let source = tsModule.createSourceFile( - directiveFileInfo.filePath, + options.filePath, currentDirectiveContents, tsModule.ScriptTarget.Latest, true @@ -40,14 +35,14 @@ export function convertDirectiveToScam( source = insertImport( tree, source, - directiveFileInfo.filePath, + options.filePath, 'NgModule', '@angular/core' ); source = insertImport( tree, source, - directiveFileInfo.filePath, + options.filePath, 'CommonModule', '@angular/common' ); @@ -57,18 +52,18 @@ export function convertDirectiveToScam( directiveClassName )}`; - tree.write(directiveFileInfo.filePath, updatedDirectiveSource); + tree.write(options.filePath, updatedDirectiveSource); return; } const scamFilePath = joinPathFragments( - directiveFileInfo.directory, + options.directory, `${directiveNames.fileName}.module.ts` ); tree.write( scamFilePath, - getModuleFileContent(directiveClassName, directiveFileInfo.fileName) + getModuleFileContent(directiveClassName, options.fileName) ); } diff --git a/packages/angular/src/generators/scam-directive/lib/index.ts b/packages/angular/src/generators/scam-directive/lib/index.ts index c4d863c804bb6..841f566be5f16 100644 --- a/packages/angular/src/generators/scam-directive/lib/index.ts +++ b/packages/angular/src/generators/scam-directive/lib/index.ts @@ -1,2 +1,3 @@ export * from './convert-directive-to-scam'; export * from './normalize-options'; +export * from './validate-options'; diff --git a/packages/angular/src/generators/scam-directive/lib/normalize-options.ts b/packages/angular/src/generators/scam-directive/lib/normalize-options.ts index 60484bbef2e9f..7775d643f9cb4 100644 --- a/packages/angular/src/generators/scam-directive/lib/normalize-options.ts +++ b/packages/angular/src/generators/scam-directive/lib/normalize-options.ts @@ -1,29 +1,28 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import { normalizeNameAndPaths } from '../../utils/path'; import type { NormalizedSchema, Schema } from '../schema'; export function normalizeOptions( tree: Tree, options: Schema ): NormalizedSchema { - const { projectType, root, sourceRoot } = readProjectConfiguration( + const { directory, fileName, filePath, name, path } = normalizeNameAndPaths( tree, - options.project + { + ...options, + type: 'directive', + } ); - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib' - ); return { ...options, export: options.export ?? true, flat: options.flat ?? true, inlineScam: options.inlineScam ?? true, + directory, + fileName, + filePath, path, - projectSourceRoot, + name, }; } diff --git a/packages/angular/src/generators/scam-directive/lib/validate-options.ts b/packages/angular/src/generators/scam-directive/lib/validate-options.ts new file mode 100644 index 0000000000000..0dfcdeee1ecdf --- /dev/null +++ b/packages/angular/src/generators/scam-directive/lib/validate-options.ts @@ -0,0 +1,9 @@ +import type { Tree } from '@nrwl/devkit'; +import { checkPathUnderProjectRoot } from '../../utils/path'; +import { validateProject } 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); +} diff --git a/packages/angular/src/generators/scam-directive/scam-directive.spec.ts b/packages/angular/src/generators/scam-directive/scam-directive.spec.ts index aa57aff56859d..f868ed17fc037 100644 --- a/packages/angular/src/generators/scam-directive/scam-directive.spec.ts +++ b/packages/angular/src/generators/scam-directive/scam-directive.spec.ts @@ -1,6 +1,6 @@ import { addProjectConfiguration, writeJson } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; -import scamDirectiveGenerator from './scam-directive'; +import { scamDirectiveGenerator } from './scam-directive'; describe('SCAM Directive Generator', () => { it('should create the inline scam directive correctly', async () => { @@ -107,7 +107,7 @@ describe('SCAM Directive Generator', () => { // ASSERT const directiveModuleSource = tree.read( - 'libs/lib1/feature/src/lib/example.module.ts', + 'libs/lib1/feature/src/lib/example/example.module.ts', 'utf-8' ); expect(directiveModuleSource).toMatchInlineSnapshot(` @@ -128,8 +128,8 @@ describe('SCAM Directive Generator', () => { 'utf-8' ); expect(secondaryEntryPointSource).toMatchInlineSnapshot(` - "export * from './lib/example.directive'; - export * from './lib/example.module'; + "export * from './lib/example/example.directive'; + export * from './lib/example/example.module'; " `); }); @@ -232,21 +232,18 @@ describe('SCAM Directive Generator', () => { root: 'apps/app1', }); - // ACT - try { - await scamDirectiveGenerator(tree, { + // ACT & ASSERT + expect( + scamDirectiveGenerator(tree, { name: 'example', project: 'app1', path: 'libs/proj/src/lib/random', inlineScam: true, flat: false, - }); - } catch (error) { - // ASSERT - expect(error).toMatchInlineSnapshot( - `[Error: The path provided for the SCAM (libs/proj/src/lib/random) does not exist under the project root (apps/app1).]` - ); - } + }) + ).rejects.toThrow( + 'The path provided (libs/proj/src/lib/random) does not exist under the project root (apps/app1).' + ); }); }); }); diff --git a/packages/angular/src/generators/scam-directive/scam-directive.ts b/packages/angular/src/generators/scam-directive/scam-directive.ts index 61ffaed1fc0fa..e3035e5eaa4cd 100644 --- a/packages/angular/src/generators/scam-directive/scam-directive.ts +++ b/packages/angular/src/generators/scam-directive/scam-directive.ts @@ -1,22 +1,18 @@ import type { Tree } from '@nrwl/devkit'; -import { - formatFiles, - normalizePath, - readProjectConfiguration, -} from '@nrwl/devkit'; +import { formatFiles } from '@nrwl/devkit'; +import { directiveGenerator } from '../directive/directive'; import { exportScam } from '../utils/export-scam'; -import { getDirectiveFileInfo } from '../utils/file-info'; -import { pathStartsWith } from '../utils/path'; -import { convertDirectiveToScam, normalizeOptions } from './lib'; +import { + convertDirectiveToScam, + normalizeOptions, + validateOptions, +} from './lib'; import type { Schema } from './schema'; -import directiveGenerator from '../directive/directive'; export async function scamDirectiveGenerator(tree: Tree, rawOptions: Schema) { - const options = normalizeOptions(tree, rawOptions); - const { inlineScam, projectSourceRoot, ...directiveOptions } = options; - - checkPathUnderProjectRoot(tree, options); + validateOptions(tree, rawOptions); + const { inlineScam, ...directiveOptions } = rawOptions; await directiveGenerator(tree, { ...directiveOptions, skipImport: true, @@ -25,30 +21,11 @@ export async function scamDirectiveGenerator(tree: Tree, rawOptions: Schema) { skipFormat: true, }); - const pipeFileInfo = getDirectiveFileInfo(tree, options); - convertDirectiveToScam(tree, pipeFileInfo, options); - exportScam(tree, pipeFileInfo, options); + const options = normalizeOptions(tree, rawOptions); + convertDirectiveToScam(tree, options); + exportScam(tree, options); await formatFiles(tree); } -function checkPathUnderProjectRoot(tree: Tree, options: Partial) { - if (!options.path) { - return; - } - - const { root } = readProjectConfiguration(tree, options.project); - - let pathToDirective = normalizePath(options.path); - pathToDirective = pathToDirective.startsWith('/') - ? pathToDirective.slice(1) - : pathToDirective; - - if (!pathStartsWith(pathToDirective, root)) { - throw new Error( - `The path provided for the SCAM (${options.path}) does not exist under the project root (${root}).` - ); - } -} - export default scamDirectiveGenerator; diff --git a/packages/angular/src/generators/scam-directive/schema.d.ts b/packages/angular/src/generators/scam-directive/schema.d.ts index 873c61a9c50f2..bae6bcb67d77c 100644 --- a/packages/angular/src/generators/scam-directive/schema.d.ts +++ b/packages/angular/src/generators/scam-directive/schema.d.ts @@ -11,9 +11,11 @@ export interface Schema { } export interface NormalizedSchema extends Schema { + directory: string; export: boolean; + fileName: string; + filePath: string; flat: boolean; inlineScam: boolean; path: string; - projectSourceRoot: string; } diff --git a/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.spec.ts b/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.spec.ts index 66d35fcd43c5e..0536474d04885 100644 --- a/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.spec.ts +++ b/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.spec.ts @@ -22,23 +22,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/example/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/example/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: true, + path: 'apps/app1/src/app', + }); // ASSERT const pipeSource = tree.read( @@ -85,23 +79,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/example/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: false, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/example/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: false, + path: 'apps/app1/src/app', + }); // ASSERT const pipeModuleSource = tree.read( @@ -140,23 +128,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: true, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: true, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const pipeSource = tree.read('apps/app1/src/app/example.pipe.ts', 'utf-8'); @@ -200,23 +182,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: false, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: false, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const pipeModuleSource = tree.read( @@ -256,23 +232,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app/random/example', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/random/example/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app/random/example', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/random/example/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const pipeModuleSource = tree.read( @@ -320,23 +290,17 @@ describe('convertPipeToScam', () => { }); // ACT - convertPipeToScam( - tree, - { - directory: 'apps/app1/src/app/random', - fileName: 'example.pipe', - filePath: 'apps/app1/src/app/random/example.pipe.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: true, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertPipeToScam(tree, { + directory: 'apps/app1/src/app/random', + fileName: 'example.pipe', + filePath: 'apps/app1/src/app/random/example.pipe.ts', + name: 'example', + project: 'app1', + export: false, + flat: true, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const pipeModuleSource = tree.read( diff --git a/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.ts b/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.ts index 52222c7fa48fa..4006eaad97922 100644 --- a/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.ts +++ b/packages/angular/src/generators/scam-pipe/lib/convert-pipe-to-scam.ts @@ -1,20 +1,15 @@ import type { Tree } from '@nrwl/devkit'; import { joinPathFragments, names } from '@nrwl/devkit'; -import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import { insertImport } from '@nrwl/js'; -import type { FileInfo } from '../../utils/file-info'; +import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import type { NormalizedSchema } from '../schema'; let tsModule: typeof import('typescript'); -export function convertPipeToScam( - tree: Tree, - pipeFileInfo: FileInfo, - options: NormalizedSchema -) { - if (!tree.exists(pipeFileInfo.filePath)) { +export function convertPipeToScam(tree: Tree, options: NormalizedSchema) { + if (!tree.exists(options.filePath)) { throw new Error( - `Couldn't find pipe at path ${pipeFileInfo.filePath} to add SCAM setup.` + `Couldn't find pipe at path ${options.filePath} to add SCAM setup.` ); } if (!tsModule) { @@ -26,9 +21,9 @@ export function convertPipeToScam( const pipeClassName = `${pipeNames.className}${typeNames.className}`; if (options.inlineScam) { - const currentPipeContents = tree.read(pipeFileInfo.filePath, 'utf-8'); + const currentPipeContents = tree.read(options.filePath, 'utf-8'); let source = tsModule.createSourceFile( - pipeFileInfo.filePath, + options.filePath, currentPipeContents, tsModule.ScriptTarget.Latest, true @@ -37,14 +32,14 @@ export function convertPipeToScam( source = insertImport( tree, source, - pipeFileInfo.filePath, + options.filePath, 'NgModule', '@angular/core' ); source = insertImport( tree, source, - pipeFileInfo.filePath, + options.filePath, 'CommonModule', '@angular/common' ); @@ -54,18 +49,18 @@ export function convertPipeToScam( pipeClassName )}`; - tree.write(pipeFileInfo.filePath, updatedPipeSource); + tree.write(options.filePath, updatedPipeSource); return; } const scamFilePath = joinPathFragments( - pipeFileInfo.directory, + options.directory, `${pipeNames.fileName}.module.ts` ); tree.write( scamFilePath, - getModuleFileContent(pipeClassName, pipeFileInfo.fileName) + getModuleFileContent(pipeClassName, options.fileName) ); } diff --git a/packages/angular/src/generators/scam-pipe/lib/index.ts b/packages/angular/src/generators/scam-pipe/lib/index.ts index 1f987ecbd1642..73b9703c45d77 100644 --- a/packages/angular/src/generators/scam-pipe/lib/index.ts +++ b/packages/angular/src/generators/scam-pipe/lib/index.ts @@ -1,2 +1,3 @@ export * from './convert-pipe-to-scam'; export * from './normalize-options'; +export * from './validate-options'; diff --git a/packages/angular/src/generators/scam-pipe/lib/normalize-options.ts b/packages/angular/src/generators/scam-pipe/lib/normalize-options.ts index 60484bbef2e9f..a3db58f0bc83f 100644 --- a/packages/angular/src/generators/scam-pipe/lib/normalize-options.ts +++ b/packages/angular/src/generators/scam-pipe/lib/normalize-options.ts @@ -1,29 +1,28 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import { normalizeNameAndPaths } from '../../utils/path'; import type { NormalizedSchema, Schema } from '../schema'; export function normalizeOptions( tree: Tree, options: Schema ): NormalizedSchema { - const { projectType, root, sourceRoot } = readProjectConfiguration( + const { directory, fileName, filePath, name, path } = normalizeNameAndPaths( tree, - options.project + { + ...options, + type: 'pipe', + } ); - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib' - ); return { ...options, export: options.export ?? true, flat: options.flat ?? true, inlineScam: options.inlineScam ?? true, + directory, + fileName, + filePath, + name, path, - projectSourceRoot, }; } diff --git a/packages/angular/src/generators/scam-pipe/lib/validate-options.ts b/packages/angular/src/generators/scam-pipe/lib/validate-options.ts new file mode 100644 index 0000000000000..0dfcdeee1ecdf --- /dev/null +++ b/packages/angular/src/generators/scam-pipe/lib/validate-options.ts @@ -0,0 +1,9 @@ +import type { Tree } from '@nrwl/devkit'; +import { checkPathUnderProjectRoot } from '../../utils/path'; +import { validateProject } 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); +} diff --git a/packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts b/packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts index f03b0d82edb4f..a7430a77201af 100644 --- a/packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts +++ b/packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts @@ -1,6 +1,6 @@ import { addProjectConfiguration, writeJson } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; -import scamPipeGenerator from './scam-pipe'; +import { scamPipeGenerator } from './scam-pipe'; describe('SCAM Pipe Generator', () => { it('should create the inline scam pipe correctly', async () => { @@ -109,7 +109,7 @@ describe('SCAM Pipe Generator', () => { // ASSERT const pipeModuleSource = tree.read( - 'libs/lib1/feature/src/lib/example.module.ts', + 'libs/lib1/feature/src/lib/example/example.module.ts', 'utf-8' ); expect(pipeModuleSource).toMatchInlineSnapshot(` @@ -130,8 +130,8 @@ describe('SCAM Pipe Generator', () => { 'utf-8' ); expect(secondaryEntryPointSource).toMatchInlineSnapshot(` - "export * from './lib/example.pipe'; - export * from './lib/example.module'; + "export * from './lib/example/example.pipe'; + export * from './lib/example/example.module'; " `); }); @@ -238,20 +238,17 @@ describe('SCAM Pipe Generator', () => { root: 'apps/app1', }); - // ACT - try { - await scamPipeGenerator(tree, { + // ACT & ASSERT + expect( + scamPipeGenerator(tree, { name: 'example', project: 'app1', path: 'libs/proj/src/lib/random', inlineScam: true, - }); - } catch (error) { - // ASSERT - expect(error).toMatchInlineSnapshot( - `[Error: The path provided for the SCAM (libs/proj/src/lib/random) does not exist under the project root (apps/app1).]` - ); - } + }) + ).rejects.toThrow( + 'The path provided (libs/proj/src/lib/random) does not exist under the project root (apps/app1).' + ); }); }); }); diff --git a/packages/angular/src/generators/scam-pipe/scam-pipe.ts b/packages/angular/src/generators/scam-pipe/scam-pipe.ts index 7d81c8eb056c2..b77c9ce314c00 100644 --- a/packages/angular/src/generators/scam-pipe/scam-pipe.ts +++ b/packages/angular/src/generators/scam-pipe/scam-pipe.ts @@ -1,22 +1,14 @@ import type { Tree } from '@nrwl/devkit'; -import { - formatFiles, - normalizePath, - readProjectConfiguration, -} from '@nrwl/devkit'; +import { formatFiles } from '@nrwl/devkit'; +import { pipeGenerator } from '../pipe/pipe'; import { exportScam } from '../utils/export-scam'; -import { getPipeFileInfo } from '../utils/file-info'; -import { pathStartsWith } from '../utils/path'; -import { convertPipeToScam, normalizeOptions } from './lib'; +import { convertPipeToScam, normalizeOptions, validateOptions } from './lib'; import type { Schema } from './schema'; -import { pipeGenerator } from '../pipe/pipe'; export async function scamPipeGenerator(tree: Tree, rawOptions: Schema) { - const options = normalizeOptions(tree, rawOptions); - const { inlineScam, projectSourceRoot, ...pipeOptions } = options; - - checkPathUnderProjectRoot(tree, options); + validateOptions(tree, rawOptions); + const { inlineScam, ...pipeOptions } = rawOptions; await pipeGenerator(tree, { ...pipeOptions, skipImport: true, @@ -25,28 +17,11 @@ export async function scamPipeGenerator(tree: Tree, rawOptions: Schema) { skipFormat: true, }); - const pipeFileInfo = getPipeFileInfo(tree, options); - convertPipeToScam(tree, pipeFileInfo, options); - exportScam(tree, pipeFileInfo, options); + const options = normalizeOptions(tree, rawOptions); + convertPipeToScam(tree, options); + exportScam(tree, options); await formatFiles(tree); } -function checkPathUnderProjectRoot(tree: Tree, options: Partial) { - if (!options.path) { - return; - } - - const { root } = readProjectConfiguration(tree, options.project); - - let pathToPipe = normalizePath(options.path); - pathToPipe = pathToPipe.startsWith('/') ? pathToPipe.slice(1) : pathToPipe; - - if (!pathStartsWith(pathToPipe, root)) { - throw new Error( - `The path provided for the SCAM (${options.path}) does not exist under the project root (${root}).` - ); - } -} - export default scamPipeGenerator; diff --git a/packages/angular/src/generators/scam-pipe/schema.d.ts b/packages/angular/src/generators/scam-pipe/schema.d.ts index 3eb461913d94b..29ff79a5311de 100644 --- a/packages/angular/src/generators/scam-pipe/schema.d.ts +++ b/packages/angular/src/generators/scam-pipe/schema.d.ts @@ -9,9 +9,11 @@ export interface Schema { } export interface NormalizedSchema extends Schema { + directory: string; export: boolean; + fileName: string; + filePath: string; flat: boolean; inlineScam: boolean; path: string; - projectSourceRoot: string; } diff --git a/packages/angular/src/generators/scam/lib/convert-component-to-scam.spec.ts b/packages/angular/src/generators/scam/lib/convert-component-to-scam.spec.ts index 89ae0624750f9..e93693c84509e 100644 --- a/packages/angular/src/generators/scam/lib/convert-component-to-scam.spec.ts +++ b/packages/angular/src/generators/scam/lib/convert-component-to-scam.spec.ts @@ -21,22 +21,16 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.component', - filePath: 'apps/app1/src/app/example/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.component', + filePath: 'apps/app1/src/app/example/example.component.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: true, + path: 'apps/app1/src/app', + }); // ASSERT const componentSource = tree.read( @@ -80,22 +74,16 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.component', - filePath: 'apps/app1/src/app/example/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: false, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app/example', + fileName: 'example.component', + filePath: 'apps/app1/src/app/example/example.component.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: false, + path: 'apps/app1/src/app', + }); // ASSERT const componentModuleSource = tree.read( @@ -134,23 +122,17 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.component', - filePath: 'apps/app1/src/app/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: true, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.component', + filePath: 'apps/app1/src/app/example.component.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: true, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const componentSource = tree.read( @@ -195,23 +177,17 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.component', - filePath: 'apps/app1/src/app/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: false, - flat: true, - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.component', + filePath: 'apps/app1/src/app/example.component.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: false, + flat: true, + path: 'apps/app1/src/app', + }); // ASSERT const componentModuleSource = tree.read( @@ -251,24 +227,18 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.random', - filePath: 'apps/app1/src/app/example.random.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: true, - flat: true, - type: 'random', - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.random', + filePath: 'apps/app1/src/app/example.random.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: true, + flat: true, + type: 'random', + path: 'apps/app1/src/app', + }); // ASSERT const componentSource = tree.read( @@ -314,24 +284,18 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app', - fileName: 'example.random', - filePath: 'apps/app1/src/app/example.random.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - inlineScam: false, - flat: true, - type: 'random', - path: 'apps/app1/src/app', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app', + fileName: 'example.random', + filePath: 'apps/app1/src/app/example.random.ts', + name: 'example', + project: 'app1', + export: false, + inlineScam: false, + flat: true, + type: 'random', + path: 'apps/app1/src/app', + }); // ASSERT const componentModuleSource = tree.read( @@ -371,23 +335,17 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app/random/example', - fileName: 'example.component', - filePath: 'apps/app1/src/app/random/example/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: false, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app/random/example', + fileName: 'example.component', + filePath: 'apps/app1/src/app/random/example/example.component.ts', + name: 'example', + project: 'app1', + export: false, + flat: false, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const componentModuleSource = tree.read( @@ -433,23 +391,17 @@ describe('convertComponentToScam', () => { }); // ACT - convertComponentToScam( - tree, - { - directory: 'apps/app1/src/app/random', - fileName: 'example.component', - filePath: 'apps/app1/src/app/random/example.component.ts', - }, - { - name: 'example', - project: 'app1', - export: false, - flat: true, - inlineScam: true, - path: 'apps/app1/src/app/random', - projectSourceRoot: 'apps/app1/src', - } - ); + convertComponentToScam(tree, { + directory: 'apps/app1/src/app/random', + fileName: 'example.component', + filePath: 'apps/app1/src/app/random/example.component.ts', + name: 'example', + project: 'app1', + export: false, + flat: true, + inlineScam: true, + path: 'apps/app1/src/app/random', + }); // ASSERT const componentModuleSource = tree.read( diff --git a/packages/angular/src/generators/scam/lib/convert-component-to-scam.ts b/packages/angular/src/generators/scam/lib/convert-component-to-scam.ts index 664ec7e184749..33a564631a272 100644 --- a/packages/angular/src/generators/scam/lib/convert-component-to-scam.ts +++ b/packages/angular/src/generators/scam/lib/convert-component-to-scam.ts @@ -1,20 +1,15 @@ import type { Tree } from '@nrwl/devkit'; import { joinPathFragments, names } from '@nrwl/devkit'; -import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import { insertImport } from '@nrwl/js'; -import type { FileInfo } from '../../utils/file-info'; +import { ensureTypescript } from '@nrwl/js/src/utils/typescript/ensure-typescript'; import type { NormalizedSchema } from '../schema'; let tsModule: typeof import('typescript'); -export function convertComponentToScam( - tree: Tree, - componentFileInfo: FileInfo, - options: NormalizedSchema -) { - if (!tree.exists(componentFileInfo.filePath)) { +export function convertComponentToScam(tree: Tree, options: NormalizedSchema) { + if (!tree.exists(options.filePath)) { throw new Error( - `Couldn't find component at path ${componentFileInfo.filePath} to add SCAM setup.` + `Couldn't find component at path ${options.filePath} to add SCAM setup.` ); } @@ -27,12 +22,9 @@ export function convertComponentToScam( } if (options.inlineScam) { - const currentComponentContents = tree.read( - componentFileInfo.filePath, - 'utf-8' - ); + const currentComponentContents = tree.read(options.filePath, 'utf-8'); let source = tsModule.createSourceFile( - componentFileInfo.filePath, + options.filePath, currentComponentContents, tsModule.ScriptTarget.Latest, true @@ -41,14 +33,14 @@ export function convertComponentToScam( source = insertImport( tree, source, - componentFileInfo.filePath, + options.filePath, 'NgModule', '@angular/core' ); source = insertImport( tree, source, - componentFileInfo.filePath, + options.filePath, 'CommonModule', '@angular/common' ); @@ -58,18 +50,18 @@ export function convertComponentToScam( componentClassName )}`; - tree.write(componentFileInfo.filePath, updatedComponentSource); + tree.write(options.filePath, updatedComponentSource); return; } const moduleFilePath = joinPathFragments( - componentFileInfo.directory, + options.directory, `${componentNames.fileName}.module.ts` ); tree.write( moduleFilePath, - getModuleFileContent(componentClassName, componentFileInfo.fileName) + getModuleFileContent(componentClassName, options.fileName) ); } diff --git a/packages/angular/src/generators/scam/lib/index.ts b/packages/angular/src/generators/scam/lib/index.ts index 5f76390664919..f11034b8e073c 100644 --- a/packages/angular/src/generators/scam/lib/index.ts +++ b/packages/angular/src/generators/scam/lib/index.ts @@ -1,2 +1,3 @@ export * from './convert-component-to-scam'; export * from './normalize-options'; +export * from './validate-options'; diff --git a/packages/angular/src/generators/scam/lib/normalize-options.ts b/packages/angular/src/generators/scam/lib/normalize-options.ts index adb4ad1e12806..15174a901e203 100644 --- a/packages/angular/src/generators/scam/lib/normalize-options.ts +++ b/packages/angular/src/generators/scam/lib/normalize-options.ts @@ -1,28 +1,23 @@ import type { Tree } from '@nrwl/devkit'; -import { joinPathFragments, readProjectConfiguration } from '@nrwl/devkit'; +import { normalizeNameAndPaths } from '../../utils/path'; import type { NormalizedSchema, Schema } from '../schema'; export function normalizeOptions( tree: Tree, options: Schema ): NormalizedSchema { - const { projectType, root, sourceRoot } = readProjectConfiguration( - tree, - options.project - ); - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib' - ); + const { directory, fileName, filePath, name } = normalizeNameAndPaths(tree, { + ...options, + type: options.type ?? 'component', + }); return { ...options, export: options.export ?? true, inlineScam: options.inlineScam ?? true, - path, - projectSourceRoot, + directory, + fileName, + filePath, + name, }; } diff --git a/packages/angular/src/generators/scam/lib/validate-options.ts b/packages/angular/src/generators/scam/lib/validate-options.ts new file mode 100644 index 0000000000000..0dfcdeee1ecdf --- /dev/null +++ b/packages/angular/src/generators/scam/lib/validate-options.ts @@ -0,0 +1,9 @@ +import type { Tree } from '@nrwl/devkit'; +import { checkPathUnderProjectRoot } from '../../utils/path'; +import { validateProject } 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); +} diff --git a/packages/angular/src/generators/scam/scam.spec.ts b/packages/angular/src/generators/scam/scam.spec.ts index d7b4e8e7c66c9..bfb4f3b93878d 100644 --- a/packages/angular/src/generators/scam/scam.spec.ts +++ b/packages/angular/src/generators/scam/scam.spec.ts @@ -228,20 +228,17 @@ describe('SCAM Generator', () => { root: 'apps/app1', }); - // ACT - try { - await scamGenerator(tree, { + // ACT & ASSERT + expect( + scamGenerator(tree, { name: 'example', project: 'app1', path: 'libs/proj/src/lib/random', inlineScam: true, - }); - } catch (error) { - // ASSERT - expect(error).toMatchInlineSnapshot( - `[Error: The path provided for the SCAM (libs/proj/src/lib/random) does not exist under the project root (apps/app1).]` - ); - } + }) + ).rejects.toThrow( + 'The path provided (libs/proj/src/lib/random) does not exist under the project root (apps/app1).' + ); }); }); }); diff --git a/packages/angular/src/generators/scam/scam.ts b/packages/angular/src/generators/scam/scam.ts index ab427aa82be6f..78647b78b258f 100644 --- a/packages/angular/src/generators/scam/scam.ts +++ b/packages/angular/src/generators/scam/scam.ts @@ -1,52 +1,32 @@ import type { Tree } from '@nrwl/devkit'; -import { - formatFiles, - normalizePath, - readProjectConfiguration, -} from '@nrwl/devkit'; -import componentGenerator from '../component/component'; +import { formatFiles } from '@nrwl/devkit'; +import { componentGenerator } from '../component/component'; import { exportScam } from '../utils/export-scam'; -import { getComponentFileInfo } from '../utils/file-info'; -import { pathStartsWith } from '../utils/path'; -import { convertComponentToScam, normalizeOptions } from './lib'; +import { + convertComponentToScam, + normalizeOptions, + validateOptions, +} from './lib'; import type { Schema } from './schema'; export async function scamGenerator(tree: Tree, rawOptions: Schema) { - const options = normalizeOptions(tree, rawOptions); - const { inlineScam, projectSourceRoot, ...schematicOptions } = options; - - checkPathUnderProjectRoot(tree, options); + validateOptions(tree, rawOptions); + const { inlineScam, ...generatorOptions } = rawOptions; await componentGenerator(tree, { - ...schematicOptions, + ...generatorOptions, skipImport: true, export: false, standalone: false, + skipFormat: true, }); - const componentFileInfo = getComponentFileInfo(tree, options); - convertComponentToScam(tree, componentFileInfo, options); - exportScam(tree, componentFileInfo, options); - - await formatFiles(tree); -} - -function checkPathUnderProjectRoot(tree: Tree, options: Partial) { - if (!options.path) { - return; - } - - const { root } = readProjectConfiguration(tree, options.project); - - let pathToComponent = normalizePath(options.path); - pathToComponent = pathToComponent.startsWith('/') - ? pathToComponent.slice(1) - : pathToComponent; + const options = normalizeOptions(tree, rawOptions); + convertComponentToScam(tree, options); + exportScam(tree, options); - if (!pathStartsWith(pathToComponent, root)) { - throw new Error( - `The path provided for the SCAM (${options.path}) does not exist under the project root (${root}).` - ); + if (!options.skipFormat) { + await formatFiles(tree); } } diff --git a/packages/angular/src/generators/scam/schema.d.ts b/packages/angular/src/generators/scam/schema.d.ts index 992d9c57b5366..05e4c0fbd7c35 100644 --- a/packages/angular/src/generators/scam/schema.d.ts +++ b/packages/angular/src/generators/scam/schema.d.ts @@ -16,11 +16,13 @@ export interface Schema { selector?: string; skipSelector?: boolean; export?: boolean; + skipFormat?: boolean; } export interface NormalizedSchema extends Schema { + directory: string; + fileName: string; + filePath: string; export: boolean; inlineScam: boolean; - path: string; - projectSourceRoot: string; } diff --git a/packages/angular/src/generators/scam/schema.json b/packages/angular/src/generators/scam/schema.json index 561d009a398d2..fa45935e2e64b 100644 --- a/packages/angular/src/generators/scam/schema.json +++ b/packages/angular/src/generators/scam/schema.json @@ -123,6 +123,12 @@ "description": "Specifies if the SCAM should be exported from the project's entry point (normally `index.ts`). It only applies to libraries.", "default": true, "x-priority": "important" + }, + "skipFormat": { + "type": "boolean", + "description": "Skip formatting files.", + "default": false, + "x-priority": "internal" } }, "required": ["name", "project"] diff --git a/packages/angular/src/generators/utils/export-scam.spec.ts b/packages/angular/src/generators/utils/export-scam.spec.ts index 53e439411abb9..71d5ef18b69ae 100644 --- a/packages/angular/src/generators/utils/export-scam.spec.ts +++ b/packages/angular/src/generators/utils/export-scam.spec.ts @@ -14,20 +14,14 @@ describe('exportScam', () => { // ACT & ASSERT expect(() => - exportScam( - tree, - { - directory: 'apps/app1/src/app/example', - fileName: 'example.component', - filePath: 'apps/app1/src/example/example.component.ts', - }, - { - name: 'example', - project: 'app1', - inlineScam: true, - export: true, - } - ) + exportScam(tree, { + directory: 'apps/app1/src/app/example', + filePath: 'apps/app1/src/example/example.component.ts', + name: 'example', + project: 'app1', + inlineScam: true, + export: true, + }) ).not.toThrow(); }); @@ -42,20 +36,14 @@ describe('exportScam', () => { tree.write('libs/lib1/src/index.ts', ''); // ACT - exportScam( - tree, - { - directory: 'libs/lib1/src/lib/example', - fileName: 'example.component', - filePath: 'libs/lib1/src/lib/example/example.component.ts', - }, - { - name: 'example', - project: 'lib1', - inlineScam: true, - export: true, - } - ); + exportScam(tree, { + directory: 'libs/lib1/src/lib/example', + filePath: 'libs/lib1/src/lib/example/example.component.ts', + name: 'example', + project: 'lib1', + inlineScam: true, + export: true, + }); // ASSERT const entryPointSource = tree.read(`libs/lib1/src/index.ts`, 'utf-8'); @@ -75,20 +63,14 @@ describe('exportScam', () => { tree.write('libs/lib1/src/index.ts', ''); // ACT - exportScam( - tree, - { - directory: 'libs/lib1/src/lib/example', - fileName: 'example.component', - filePath: 'libs/lib1/src/lib/example/example.component.ts', - }, - { - name: 'example', - project: 'lib1', - inlineScam: false, - export: true, - } - ); + exportScam(tree, { + directory: 'libs/lib1/src/lib/example', + filePath: 'libs/lib1/src/lib/example/example.component.ts', + name: 'example', + project: 'lib1', + inlineScam: false, + export: true, + }); // ASSERT const entryPointSource = tree.read(`libs/lib1/src/index.ts`, 'utf-8'); @@ -113,20 +95,14 @@ describe('exportScam', () => { }); // ACT - exportScam( - tree, - { - directory: 'libs/lib1/feature/src/lib/example', - fileName: 'example.component', - filePath: 'libs/lib1/feature/src/lib/example/example.component.ts', - }, - { - name: 'example', - project: 'lib1', - inlineScam: true, - export: true, - } - ); + exportScam(tree, { + directory: 'libs/lib1/feature/src/lib/example', + filePath: 'libs/lib1/feature/src/lib/example/example.component.ts', + name: 'example', + project: 'lib1', + inlineScam: true, + export: true, + }); // ASSERT const entryPointSource = tree.read( diff --git a/packages/angular/src/generators/utils/export-scam.ts b/packages/angular/src/generators/utils/export-scam.ts index c3e62ba730ba5..7f20dd9bc2b05 100644 --- a/packages/angular/src/generators/utils/export-scam.ts +++ b/packages/angular/src/generators/utils/export-scam.ts @@ -7,21 +7,18 @@ import { stripIndents, } from '@nrwl/devkit'; import { locateLibraryEntryPointFromDirectory } from './entry-point'; -import type { FileInfo } from './file-info'; import { getRelativeImportToFile } from './path'; export type GenerationOptions = { + directory: string; + filePath: string; name: string; project: string; export?: boolean; inlineScam?: boolean; }; -export function exportScam( - tree: Tree, - fileInfo: FileInfo, - options: GenerationOptions -): void { +export function exportScam(tree: Tree, options: GenerationOptions): void { if (!options.export) { return; } @@ -42,7 +39,7 @@ export function exportScam( const entryPointPath = locateLibraryEntryPointFromDirectory( tree, - fileInfo.directory, + options.directory, root, projectSourceRoot ); @@ -59,7 +56,7 @@ export function exportScam( const relativePathFromEntryPoint = getRelativeImportToFile( entryPointPath, - fileInfo.filePath + options.filePath ); const entryPointContent = tree.read(entryPointPath, 'utf-8'); let updatedEntryPointContent = stripIndents`${entryPointContent} @@ -67,7 +64,7 @@ export function exportScam( if (!options.inlineScam) { const moduleFilePath = joinPathFragments( - fileInfo.directory, + options.directory, `${names(options.name).fileName}.module.ts` ); const relativePathFromModule = getRelativeImportToFile( diff --git a/packages/angular/src/generators/utils/file-info.ts b/packages/angular/src/generators/utils/file-info.ts deleted file mode 100644 index e6cd7c7ab66b4..0000000000000 --- a/packages/angular/src/generators/utils/file-info.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - joinPathFragments, - names, - normalizePath, - readProjectConfiguration, - Tree, -} from '@nrwl/devkit'; - -export type GenerationOptions = { - name: string; - project: string; - flat?: boolean; - path?: string; - type?: string; -}; -export type FileInfo = { - directory: string; - fileName: string; - filePath: string; -}; - -export function getComponentFileInfo( - tree: Tree, - options: GenerationOptions -): FileInfo { - return getFileInfo(tree, options, 'component'); -} - -export function getDirectiveFileInfo( - tree: Tree, - options: GenerationOptions -): FileInfo { - return getFileInfo(tree, options, 'directive'); -} - -export function getPipeFileInfo( - tree: Tree, - options: GenerationOptions -): FileInfo { - return getFileInfo(tree, options, 'pipe'); -} - -function getFileInfo( - tree: Tree, - options: GenerationOptions, - defaultType: string -): FileInfo { - const { root, sourceRoot, projectType } = readProjectConfiguration( - tree, - options.project - ); - const { fileName: normalizedName } = names(options.name); - - const fileName = `${normalizedName}.${ - options.type ? names(options.type).fileName : defaultType - }`; - - const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); - const path = - options.path ?? - joinPathFragments( - projectSourceRoot, - projectType === 'application' ? 'app' : 'lib' - ); - const directory = options.flat - ? normalizePath(path) - : joinPathFragments(path, normalizedName); - - const filePath = joinPathFragments(directory, `${fileName}.ts`); - - return { directory, fileName, filePath }; -} diff --git a/packages/angular/src/generators/utils/path.ts b/packages/angular/src/generators/utils/path.ts index ab56cbd17e00b..c12702c91de29 100644 --- a/packages/angular/src/generators/utils/path.ts +++ b/packages/angular/src/generators/utils/path.ts @@ -1,12 +1,13 @@ +import type { Tree } from '@nrwl/devkit'; import { joinPathFragments, + names, normalizePath, - readNxJson, readProjectConfiguration, - Tree, workspaceRoot, } from '@nrwl/devkit'; import { basename, dirname, relative } from 'path'; +import { parseNameWithPath } from './names'; export function pathStartsWith(path1: string, path2: string): boolean { const normalizedPath1 = joinPathFragments(workspaceRoot, path1); @@ -53,3 +54,62 @@ export function checkPathUnderProjectRoot( ); } } + +export type PathGenerationOptions = { + name: string; + project: string; + flat?: boolean; + path?: string; + type?: string; +}; + +export type GenerationPaths = { + directory: string; + fileName: string; + filePath: string; + name: string; + path: string; + root: string; + sourceRoot: string; +}; + +export function normalizeNameAndPaths( + tree: Tree, + options: PathGenerationOptions +): GenerationPaths { + const { root, sourceRoot, projectType } = readProjectConfiguration( + tree, + options.project + ); + + const projectSourceRoot = sourceRoot ?? joinPathFragments(root, 'src'); + const { name, path: namePath } = parseNameWithPath(options.name); + + const path = + options.path ?? + joinPathFragments( + projectSourceRoot, + projectType === 'application' ? 'app' : 'lib', + namePath + ); + + const directory = options.flat + ? normalizePath(path) + : joinPathFragments(path, name); + + const fileName = options.type + ? `${name}.${names(options.type).fileName}` + : name; + + const filePath = joinPathFragments(directory, `${fileName}.ts`); + + return { + directory, + fileName, + filePath, + name, + path, + root, + sourceRoot, + }; +}