mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
117616: Created custom sort-standalone-imports rule
This commit is contained in:
@@ -295,6 +295,15 @@
|
|||||||
"listableObjectComponent"
|
"listableObjectComponent"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"dspace-angular-ts/sort-standalone-imports": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"locale": "en-US",
|
||||||
|
"maxItems": 0,
|
||||||
|
"indent": 2,
|
||||||
|
"trailingComma": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
_______
|
_______
|
||||||
|
|
||||||
- [`dspace-angular-ts/alias-imports`](./rules/alias-imports.md): Unclear imports should be aliased for clarity
|
- [`dspace-angular-ts/alias-imports`](./rules/alias-imports.md): Unclear imports should be aliased for clarity
|
||||||
|
- [`dspace-angular-ts/sort-standalone-imports`](./rules/sort-standalone-imports.md): Sorts the standalone `@Component` imports alphabetically
|
||||||
- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
|
- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
|
||||||
- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
|
- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
|
||||||
- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class
|
- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class
|
||||||
|
214
docs/lint/ts/rules/sort-standalone-imports.md
Normal file
214
docs/lint/ts/rules/sort-standalone-imports.md
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/sort-standalone-imports`
|
||||||
|
_______
|
||||||
|
|
||||||
|
Sorts the standalone `@Component` imports alphabetically
|
||||||
|
|
||||||
|
_______
|
||||||
|
|
||||||
|
[Source code](../../../../lint/src/rules/ts/sort-standalone-imports.ts)
|
||||||
|
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
#### `locale`
|
||||||
|
|
||||||
|
The locale used to sort the imports.,
|
||||||
|
#### `maxItems`
|
||||||
|
|
||||||
|
The maximum number of imports that should be displayed before each import is separated onto its own line.,
|
||||||
|
#### `indent`
|
||||||
|
|
||||||
|
The indent used for the project.,
|
||||||
|
#### `trailingComma`
|
||||||
|
|
||||||
|
Whether the last import should have a trailing comma (only applicable for multiline imports).
|
||||||
|
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
|
||||||
|
#### Valid code
|
||||||
|
|
||||||
|
##### should sort multiple imports on separate lines
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### should not inlines singular imports when maxItems is 0
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### should inline singular imports when maxItems is 1
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Invalid code & automatic fixes
|
||||||
|
|
||||||
|
##### should sort multiple imports alphabetically
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
Standalone imports should be sorted alphabetically
|
||||||
|
```
|
||||||
|
|
||||||
|
Result of `yarn lint --fix`:
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
##### should not put singular imports on one line when maxItems is 0
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
Standalone imports should be sorted alphabetically
|
||||||
|
```
|
||||||
|
|
||||||
|
Result of `yarn lint --fix`:
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
##### should not put singular imports on a separate line when maxItems is 1
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
Standalone imports should be sorted alphabetically
|
||||||
|
```
|
||||||
|
|
||||||
|
Result of `yarn lint --fix`:
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
##### should not display multiple imports on the same line
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [AsyncPipe, RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
Standalone imports should be sorted alphabetically
|
||||||
|
```
|
||||||
|
|
||||||
|
Result of `yarn lint --fix`:
|
||||||
|
```typescript
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -11,6 +11,7 @@ import {
|
|||||||
} from '../../util/structure';
|
} from '../../util/structure';
|
||||||
/* eslint-disable import/no-namespace */
|
/* eslint-disable import/no-namespace */
|
||||||
import * as aliasImports from './alias-imports';
|
import * as aliasImports from './alias-imports';
|
||||||
|
import * as sortStandaloneImports from './sort-standalone-imports';
|
||||||
import * as themedComponentClasses from './themed-component-classes';
|
import * as themedComponentClasses from './themed-component-classes';
|
||||||
import * as themedComponentSelectors from './themed-component-selectors';
|
import * as themedComponentSelectors from './themed-component-selectors';
|
||||||
import * as themedComponentUsages from './themed-component-usages';
|
import * as themedComponentUsages from './themed-component-usages';
|
||||||
@@ -20,6 +21,7 @@ import * as uniqueDecorators from './unique-decorators';
|
|||||||
|
|
||||||
const index = [
|
const index = [
|
||||||
aliasImports,
|
aliasImports,
|
||||||
|
sortStandaloneImports,
|
||||||
themedComponentClasses,
|
themedComponentClasses,
|
||||||
themedComponentSelectors,
|
themedComponentSelectors,
|
||||||
themedComponentUsages,
|
themedComponentUsages,
|
||||||
|
306
lint/src/rules/ts/sort-standalone-imports.ts
Normal file
306
lint/src/rules/ts/sort-standalone-imports.ts
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
import {
|
||||||
|
ASTUtils as TSESLintASTUtils,
|
||||||
|
ESLintUtils,
|
||||||
|
TSESLint,
|
||||||
|
TSESTree,
|
||||||
|
} from '@typescript-eslint/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
DSpaceESLintRuleInfo,
|
||||||
|
NamedTests,
|
||||||
|
OptionDoc,
|
||||||
|
} from '../../util/structure';
|
||||||
|
|
||||||
|
const DEFAULT_LOCALE = 'en-US';
|
||||||
|
const DEFAULT_MAX_SIZE = 0;
|
||||||
|
const DEFAULT_SPACE_INDENT_AMOUNT = 2;
|
||||||
|
const DEFAULT_TRAILING_COMMA = true;
|
||||||
|
|
||||||
|
export enum Message {
|
||||||
|
SORT_STANDALONE_IMPORTS_ARRAYS = 'sortStandaloneImportsArrays',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UniqueDecoratorsOptions {
|
||||||
|
locale: string;
|
||||||
|
maxItems: number;
|
||||||
|
indent: number;
|
||||||
|
trailingComma: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UniqueDecoratorsDocOptions {
|
||||||
|
locale: OptionDoc;
|
||||||
|
maxItems: OptionDoc;
|
||||||
|
indent: OptionDoc;
|
||||||
|
trailingComma: OptionDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const info: DSpaceESLintRuleInfo<[UniqueDecoratorsOptions], [UniqueDecoratorsDocOptions]> = {
|
||||||
|
name: 'sort-standalone-imports',
|
||||||
|
meta: {
|
||||||
|
docs: {
|
||||||
|
description: 'Sorts the standalone `@Component` imports alphabetically',
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
[Message.SORT_STANDALONE_IMPORTS_ARRAYS]: 'Standalone imports should be sorted alphabetically',
|
||||||
|
},
|
||||||
|
fixable: 'code',
|
||||||
|
type: 'problem',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
locale: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
maxItems: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
indent: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
trailingComma: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
optionDocs: [
|
||||||
|
{
|
||||||
|
locale: {
|
||||||
|
title: '`locale`',
|
||||||
|
description: 'The locale used to sort the imports.',
|
||||||
|
},
|
||||||
|
maxItems: {
|
||||||
|
title: '`maxItems`',
|
||||||
|
description: 'The maximum number of imports that should be displayed before each import is separated onto its own line.',
|
||||||
|
},
|
||||||
|
indent: {
|
||||||
|
title: '`indent`',
|
||||||
|
description: 'The indent used for the project.',
|
||||||
|
},
|
||||||
|
trailingComma: {
|
||||||
|
title: '`trailingComma`',
|
||||||
|
description: 'Whether the last import should have a trailing comma (only applicable for multiline imports).',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
defaultOptions: [
|
||||||
|
{
|
||||||
|
locale: DEFAULT_LOCALE,
|
||||||
|
maxItems: DEFAULT_MAX_SIZE,
|
||||||
|
indent: DEFAULT_SPACE_INDENT_AMOUNT,
|
||||||
|
trailingComma: DEFAULT_TRAILING_COMMA,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rule = ESLintUtils.RuleCreator.withoutDocs({
|
||||||
|
...info,
|
||||||
|
create(context: TSESLint.RuleContext<Message, unknown[]>, [{ locale, maxItems, indent, trailingComma }]: any) {
|
||||||
|
return {
|
||||||
|
['ClassDeclaration > Decorator > CallExpression[callee.name="Component"] > ObjectExpression > Property[key.name="imports"] > ArrayExpression']: (node: TSESTree.ArrayExpression) => {
|
||||||
|
const identifiers = node.elements.filter(TSESLintASTUtils.isIdentifier);
|
||||||
|
const sortedNames: string[] = identifiers
|
||||||
|
.map((identifier) => identifier.name)
|
||||||
|
.sort((a: string, b: string) => a.localeCompare(b, locale));
|
||||||
|
|
||||||
|
const isSorted: boolean = identifiers.every((identifier, index) => identifier.name === sortedNames[index]);
|
||||||
|
|
||||||
|
const requiresMultiline: boolean = maxItems < node.elements.length;
|
||||||
|
const isMultiline: boolean = /\n/.test(context.sourceCode.getText(node));
|
||||||
|
|
||||||
|
const incorrectFormat: boolean = requiresMultiline !== isMultiline;
|
||||||
|
|
||||||
|
if (isSorted && !incorrectFormat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.report({
|
||||||
|
node: node.parent,
|
||||||
|
messageId: Message.SORT_STANDALONE_IMPORTS_ARRAYS,
|
||||||
|
fix: (fixer: TSESLint.RuleFixer) => {
|
||||||
|
if (requiresMultiline) {
|
||||||
|
const multilineImports: string = sortedNames
|
||||||
|
.map((name: string) => `${' '.repeat(2 * indent)}${name}${trailingComma ? ',' : ''}`)
|
||||||
|
.join(trailingComma ? '\n' : ',\n');
|
||||||
|
|
||||||
|
return fixer.replaceText(node, `[\n${multilineImports}\n${' '.repeat(indent)}]`);
|
||||||
|
} else {
|
||||||
|
return fixer.replaceText(node, `[${sortedNames.join(', ')}]`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const tests: NamedTests = {
|
||||||
|
plugin: info.name,
|
||||||
|
valid: [
|
||||||
|
{
|
||||||
|
name: 'should sort multiple imports on separate lines',
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'should not inlines singular imports when maxItems is 0',
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'should inline singular imports when maxItems is 1',
|
||||||
|
options: [{ maxItems: 1 }],
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
{
|
||||||
|
name: 'should sort multiple imports alphabetically',
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
AsyncPipe,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: Message.SORT_STANDALONE_IMPORTS_ARRAYS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'should not put singular imports on one line when maxItems is 0',
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: Message.SORT_STANDALONE_IMPORTS_ARRAYS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'should not put singular imports on a separate line when maxItems is 1',
|
||||||
|
options: [{ maxItems: 1 }],
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: Message.SORT_STANDALONE_IMPORTS_ARRAYS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'should not display multiple imports on the same line',
|
||||||
|
code: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [AsyncPipe, RootComponent],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: Message.SORT_STANDALONE_IMPORTS_ARRAYS,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
output: `
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-app',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
AsyncPipe,
|
||||||
|
RootComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
Reference in New Issue
Block a user