Skip to content

Commit

Permalink
feat(angular): add isStandalone util to check for standalone decorato…
Browse files Browse the repository at this point in the history
…rs (#14129)
  • Loading branch information
Coly010 committed Jan 4, 2023
1 parent 58b1c40 commit 762c9ee
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 1 deletion.
109 changes: 109 additions & 0 deletions packages/angular/src/utils/nx-devkit/ast-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
addImportToDirective,
addImportToModule,
addImportToPipe,
isStandalone,
} from './ast-utils';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { createSourceFile, ScriptTarget } from 'typescript';
Expand Down Expand Up @@ -151,4 +152,112 @@ describe('Angular AST Utils', () => {
"
`);
});

it('should allow checking if a component is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.component.ts`;
const originalContents = `import { Component } from '@angular/core';
@Component({
standalone: true
})
export class MyComponent {}
`;

tree.write(pathToFile, originalContents);

const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);

// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Component')).toBeTruthy();
});

it('should allow checking if a component is standalone and return false if not', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.component.ts`;
const originalContents = `import { Component } from '@angular/core';
@Component({
standalone: false
})
export class MyComponent {}
`;

tree.write(pathToFile, originalContents);

const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);

// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Component')).not.toBeTruthy();
});

it('should allow checking if a directive is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.directive.ts`;
const originalContents = `import { Directive } from '@angular/core';
@Directive({
standalone: true
})
export class MyDirective {}
`;

tree.write(pathToFile, originalContents);

const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);

// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Directive')).toBeTruthy();
});

it('should allow checking if a pipe is standalone and return true if so', () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
const pathToFile = `my.pipe.ts`;
const originalContents = `import { Pipe } from '@angular/core';
@Pipe({
standalone: true
})
export class MyPipe {}
`;

tree.write(pathToFile, originalContents);

const sourceText = tree.read(pathToFile, 'utf-8');
const tsSourceFile = createSourceFile(
pathToFile,
sourceText,
ScriptTarget.Latest,
true
);

// ACT
// ASSERT
expect(isStandalone(tsSourceFile, 'Pipe')).toBeTruthy();
});
});
18 changes: 17 additions & 1 deletion packages/angular/src/utils/nx-devkit/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
replaceChange,
} from '@nrwl/workspace/src/utilities/ast-utils';

type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';

function _angularImportsFromNode(
node: ts.ImportDeclaration,
_sourceFile: ts.SourceFile
Expand Down Expand Up @@ -62,6 +64,20 @@ function _angularImportsFromNode(
}
}

export function isStandalone(
sourceFile: ts.SourceFile,
decoratorName: DecoratorName
) {
const decoratorMetadata = getDecoratorMetadata(
sourceFile,
decoratorName,
'@angular/core'
);
return decoratorMetadata.some((node) =>
node.getText().includes('standalone: true')
);
}

export function getDecoratorMetadata(
source: ts.SourceFile,
identifier: string,
Expand Down Expand Up @@ -134,7 +150,7 @@ function _addSymbolToDecoratorMetadata(
filePath: string,
metadataField: string,
expression: string,
decoratorName: 'Component' | 'Directive' | 'NgModule' | 'Pipe'
decoratorName: DecoratorName
): ts.SourceFile {
const nodes = getDecoratorMetadata(source, decoratorName, '@angular/core');
let node: any = nodes[0]; // tslint:disable-line:no-any
Expand Down

0 comments on commit 762c9ee

Please sign in to comment.