feat(angular): add isStandalone util to check for standalone decorators (#14129)
This commit is contained in:
parent
58b1c40e52
commit
762c9ee50d
@ -3,6 +3,7 @@ import {
|
|||||||
addImportToDirective,
|
addImportToDirective,
|
||||||
addImportToModule,
|
addImportToModule,
|
||||||
addImportToPipe,
|
addImportToPipe,
|
||||||
|
isStandalone,
|
||||||
} from './ast-utils';
|
} from './ast-utils';
|
||||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||||
import { createSourceFile, ScriptTarget } from 'typescript';
|
import { createSourceFile, ScriptTarget } from 'typescript';
|
||||||
@ -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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import {
|
|||||||
replaceChange,
|
replaceChange,
|
||||||
} from '@nrwl/workspace/src/utilities/ast-utils';
|
} from '@nrwl/workspace/src/utilities/ast-utils';
|
||||||
|
|
||||||
|
type DecoratorName = 'Component' | 'Directive' | 'NgModule' | 'Pipe';
|
||||||
|
|
||||||
function _angularImportsFromNode(
|
function _angularImportsFromNode(
|
||||||
node: ts.ImportDeclaration,
|
node: ts.ImportDeclaration,
|
||||||
_sourceFile: ts.SourceFile
|
_sourceFile: ts.SourceFile
|
||||||
@ -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(
|
export function getDecoratorMetadata(
|
||||||
source: ts.SourceFile,
|
source: ts.SourceFile,
|
||||||
identifier: string,
|
identifier: string,
|
||||||
@ -134,7 +150,7 @@ function _addSymbolToDecoratorMetadata(
|
|||||||
filePath: string,
|
filePath: string,
|
||||||
metadataField: string,
|
metadataField: string,
|
||||||
expression: string,
|
expression: string,
|
||||||
decoratorName: 'Component' | 'Directive' | 'NgModule' | 'Pipe'
|
decoratorName: DecoratorName
|
||||||
): ts.SourceFile {
|
): ts.SourceFile {
|
||||||
const nodes = getDecoratorMetadata(source, decoratorName, '@angular/core');
|
const nodes = getDecoratorMetadata(source, decoratorName, '@angular/core');
|
||||||
let node: any = nodes[0]; // tslint:disable-line:no-any
|
let node: any = nodes[0]; // tslint:disable-line:no-any
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user