feat(angular): add scam generator for pipes and directives (#8144)
ISSUES CLOSED: #8122
This commit is contained in:
parent
bc8dda6c44
commit
4bb109e175
86
docs/angular/api-angular/generators/scam-directive.md
Normal file
86
docs/angular/api-angular/generators/scam-directive.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-directive generator'
|
||||
description: 'Generate a directive with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-directive
|
||||
|
||||
Generate a directive with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-directive ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-directive` in the default collection provisioned in `angular.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-directive ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-directive ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the directive.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Directive.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the directive file, relative to the current workspace. Default is a folder with the same name as the directive in the project root.
|
||||
|
||||
### prefix
|
||||
|
||||
Alias(es): p
|
||||
|
||||
Type: `string`
|
||||
|
||||
The prefix to apply to the generated directive selector.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### selector
|
||||
|
||||
Type: `string`
|
||||
|
||||
The HTML selector to use for this directive.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new directive.
|
||||
72
docs/angular/api-angular/generators/scam-pipe.md
Normal file
72
docs/angular/api-angular/generators/scam-pipe.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-pipe generator'
|
||||
description: 'Generate a pipe with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-pipe
|
||||
|
||||
Generate a pipe with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-pipe ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-pipe` in the default collection provisioned in `angular.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-pipe ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-pipe ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the pipe.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Pipe.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the pipe file, relative to the current workspace. Default is a folder with the same name as the pipe in the project root.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new pipe.
|
||||
@ -473,6 +473,16 @@
|
||||
"id": "scam",
|
||||
"file": "angular/api-angular/generators/scam"
|
||||
},
|
||||
{
|
||||
"name": "scam-directive generator",
|
||||
"id": "scam-directive",
|
||||
"file": "angular/api-angular/generators/scam-directive"
|
||||
},
|
||||
{
|
||||
"name": "scam-pipe generator",
|
||||
"id": "scam-pipe",
|
||||
"file": "angular/api-angular/generators/scam-pipe"
|
||||
},
|
||||
{
|
||||
"name": "setup-mfe generator",
|
||||
"id": "setup-mfe",
|
||||
@ -1812,6 +1822,16 @@
|
||||
"id": "scam",
|
||||
"file": "react/api-angular/generators/scam"
|
||||
},
|
||||
{
|
||||
"name": "scam-directive generator",
|
||||
"id": "scam-directive",
|
||||
"file": "react/api-angular/generators/scam-directive"
|
||||
},
|
||||
{
|
||||
"name": "scam-pipe generator",
|
||||
"id": "scam-pipe",
|
||||
"file": "react/api-angular/generators/scam-pipe"
|
||||
},
|
||||
{
|
||||
"name": "setup-mfe generator",
|
||||
"id": "setup-mfe",
|
||||
@ -3115,6 +3135,16 @@
|
||||
"id": "scam",
|
||||
"file": "node/api-angular/generators/scam"
|
||||
},
|
||||
{
|
||||
"name": "scam-directive generator",
|
||||
"id": "scam-directive",
|
||||
"file": "node/api-angular/generators/scam-directive"
|
||||
},
|
||||
{
|
||||
"name": "scam-pipe generator",
|
||||
"id": "scam-pipe",
|
||||
"file": "node/api-angular/generators/scam-pipe"
|
||||
},
|
||||
{
|
||||
"name": "setup-mfe generator",
|
||||
"id": "setup-mfe",
|
||||
|
||||
86
docs/node/api-angular/generators/scam-directive.md
Normal file
86
docs/node/api-angular/generators/scam-directive.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-directive generator'
|
||||
description: 'Generate a directive with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-directive
|
||||
|
||||
Generate a directive with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-directive ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-directive` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-directive ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-directive ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the directive.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Directive.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the directive file, relative to the current workspace. Default is a folder with the same name as the directive in the project root.
|
||||
|
||||
### prefix
|
||||
|
||||
Alias(es): p
|
||||
|
||||
Type: `string`
|
||||
|
||||
The prefix to apply to the generated directive selector.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### selector
|
||||
|
||||
Type: `string`
|
||||
|
||||
The HTML selector to use for this directive.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new directive.
|
||||
72
docs/node/api-angular/generators/scam-pipe.md
Normal file
72
docs/node/api-angular/generators/scam-pipe.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-pipe generator'
|
||||
description: 'Generate a pipe with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-pipe
|
||||
|
||||
Generate a pipe with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-pipe ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-pipe` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-pipe ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-pipe ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the pipe.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Pipe.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the pipe file, relative to the current workspace. Default is a folder with the same name as the pipe in the project root.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new pipe.
|
||||
86
docs/react/api-angular/generators/scam-directive.md
Normal file
86
docs/react/api-angular/generators/scam-directive.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-directive generator'
|
||||
description: 'Generate a directive with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-directive
|
||||
|
||||
Generate a directive with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-directive ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-directive` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-directive ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-directive ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the directive.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Directive.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the directive file, relative to the current workspace. Default is a folder with the same name as the directive in the project root.
|
||||
|
||||
### prefix
|
||||
|
||||
Alias(es): p
|
||||
|
||||
Type: `string`
|
||||
|
||||
The prefix to apply to the generated directive selector.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### selector
|
||||
|
||||
Type: `string`
|
||||
|
||||
The HTML selector to use for this directive.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new directive.
|
||||
72
docs/react/api-angular/generators/scam-pipe.md
Normal file
72
docs/react/api-angular/generators/scam-pipe.md
Normal file
@ -0,0 +1,72 @@
|
||||
---
|
||||
title: '@nrwl/angular:scam-pipe generator'
|
||||
description: 'Generate a pipe with an accompanying Single Component Angular Module (SCAM).'
|
||||
---
|
||||
|
||||
# @nrwl/angular:scam-pipe
|
||||
|
||||
Generate a pipe with an accompanying Single Component Angular Module (SCAM).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate scam-pipe ...
|
||||
```
|
||||
|
||||
By default, Nx will search for `scam-pipe` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/angular:scam-pipe ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g scam-pipe ... --dry-run
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### name (_**required**_)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the pipe.
|
||||
|
||||
### flat
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the new files at the top level of the current project.
|
||||
|
||||
### inlineScam
|
||||
|
||||
Default: `true`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create the NgModule in the same file as the Pipe.
|
||||
|
||||
### path (**hidden**)
|
||||
|
||||
Type: `string`
|
||||
|
||||
The path at which to create the pipe file, relative to the current workspace. Default is a folder with the same name as the pipe in the project root.
|
||||
|
||||
### project
|
||||
|
||||
Type: `string`
|
||||
|
||||
The name of the project.
|
||||
|
||||
### skipTests
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not create "spec.ts" test files for the new pipe.
|
||||
@ -115,6 +115,16 @@
|
||||
"schema": "./src/generators/scam/schema.json",
|
||||
"description": "Generate a component with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
"scam-directive": {
|
||||
"factory": "./src/generators/scam-directive/scam-directive.compat",
|
||||
"schema": "./src/generators/scam-directive/schema.json",
|
||||
"description": "Generate a directive with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
"scam-pipe": {
|
||||
"factory": "./src/generators/scam-pipe/scam-pipe.compat",
|
||||
"schema": "./src/generators/scam-pipe/schema.json",
|
||||
"description": "Generate a pipe with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
|
||||
"web-worker": {
|
||||
"factory": "./src/generators/web-worker/compat",
|
||||
@ -209,6 +219,16 @@
|
||||
"schema": "./src/generators/scam/schema.json",
|
||||
"description": "Generate a component with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
"scam-directive": {
|
||||
"factory": "./src/generators/scam-directive/scam-directive",
|
||||
"schema": "./src/generators/scam-directive/schema.json",
|
||||
"description": "Generate a directive with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
"scam-pipe": {
|
||||
"factory": "./src/generators/scam-pipe/scam-pipe",
|
||||
"schema": "./src/generators/scam-pipe/schema.json",
|
||||
"description": "Generate a pipe with an accompanying Single Component Angular Module (SCAM)."
|
||||
},
|
||||
"stories": {
|
||||
"factory": "./src/generators/stories/stories",
|
||||
"schema": "./src/generators/stories/schema.json",
|
||||
|
||||
@ -15,3 +15,5 @@ export * from './src/generators/storybook-migrate-stories-to-6-2/migrate-stories
|
||||
export * from './src/generators/upgrade-module/upgrade-module';
|
||||
export * from './src/generators/setup-mfe/setup-mfe';
|
||||
export * from './src/generators/scam/scam';
|
||||
export * from './src/generators/scam-directive/scam-directive';
|
||||
export * from './src/generators/scam-pipe/scam-pipe';
|
||||
|
||||
@ -0,0 +1,331 @@
|
||||
import { addProjectConfiguration } from '@nrwl/devkit';
|
||||
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { createScamDirective } from './create-module';
|
||||
|
||||
describe('Create module in the tree', () => {
|
||||
it('should create the scam directive inline correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveSource = tree.read(
|
||||
'apps/app1/src/app/example/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
expect(directiveSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam directive separately correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveModuleSource = tree.read(
|
||||
'apps/app1/src/app/example/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExampleDirective } from './example.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam directive inline correctly when --flat', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveSource = tree.read(
|
||||
'apps/app1/src/app/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam directive separately correctly when --flat', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveModuleSource = tree.read(
|
||||
'apps/app1/src/app/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExampleDirective } from './example.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should place the directive and scam in the correct folder when --path is used', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
path: 'apps/app1/src/app/random',
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
flat: false,
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveModuleSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveModuleSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should place the directive and scam in the correct folder when --path and --flat is used', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
path: 'apps/app1/src/app/random',
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamDirective(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
flat: true,
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveModuleSource = tree.read(
|
||||
'apps/app1/src/app/random/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveModuleSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,117 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import type { Schema } from '../schema';
|
||||
|
||||
import {
|
||||
readProjectConfiguration,
|
||||
joinPathFragments,
|
||||
names,
|
||||
readWorkspaceConfiguration,
|
||||
normalizePath,
|
||||
} from '@nrwl/devkit';
|
||||
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
|
||||
import { createSourceFile, ScriptTarget } from 'typescript';
|
||||
|
||||
export function createScamDirective(tree: Tree, schema: Schema) {
|
||||
const project =
|
||||
schema.project ?? readWorkspaceConfiguration(tree).defaultProject;
|
||||
const projectConfig = readProjectConfiguration(tree, project);
|
||||
|
||||
const directiveNames = names(schema.name);
|
||||
const typeNames = names('directive');
|
||||
|
||||
const directiveFileName = `${directiveNames.fileName}.directive`;
|
||||
|
||||
let directiveDirectory = schema.flat
|
||||
? joinPathFragments(
|
||||
projectConfig.sourceRoot,
|
||||
projectConfig.projectType === 'application' ? 'app' : 'lib'
|
||||
)
|
||||
: joinPathFragments(
|
||||
projectConfig.sourceRoot,
|
||||
projectConfig.projectType === 'application' ? 'app' : 'lib',
|
||||
directiveNames.fileName
|
||||
);
|
||||
|
||||
if (schema.path) {
|
||||
directiveDirectory = schema.flat
|
||||
? normalizePath(schema.path)
|
||||
: joinPathFragments(schema.path, directiveNames.fileName);
|
||||
}
|
||||
|
||||
const directiveFilePath = joinPathFragments(
|
||||
directiveDirectory,
|
||||
`${directiveFileName}.ts`
|
||||
);
|
||||
|
||||
if (!tree.exists(directiveFilePath)) {
|
||||
throw new Error(
|
||||
`Couldn't find directive at path ${directiveFilePath} to add SCAM setup.`
|
||||
);
|
||||
}
|
||||
|
||||
if (schema.inlineScam) {
|
||||
const currentDirectiveContents = tree.read(directiveFilePath, 'utf-8');
|
||||
let source = createSourceFile(
|
||||
directiveFilePath,
|
||||
currentDirectiveContents,
|
||||
ScriptTarget.Latest,
|
||||
true
|
||||
);
|
||||
|
||||
source = insertImport(
|
||||
tree,
|
||||
source,
|
||||
directiveFilePath,
|
||||
'NgModule',
|
||||
'@angular/core'
|
||||
);
|
||||
|
||||
source = insertImport(
|
||||
tree,
|
||||
source,
|
||||
directiveFilePath,
|
||||
'CommonModule',
|
||||
'@angular/common'
|
||||
);
|
||||
|
||||
let updatedDirectiveSource = source.getText();
|
||||
|
||||
updatedDirectiveSource = `${updatedDirectiveSource}${createAngularDirectiveModule(
|
||||
`${directiveNames.className}${typeNames.className}`
|
||||
)}`;
|
||||
|
||||
tree.write(directiveFilePath, updatedDirectiveSource);
|
||||
return;
|
||||
}
|
||||
|
||||
tree.write(
|
||||
joinPathFragments(
|
||||
directiveDirectory,
|
||||
`${directiveNames.fileName}.module.ts`
|
||||
),
|
||||
createSeparateAngularDirectiveModuleFile(
|
||||
`${directiveNames.className}${typeNames.className}`,
|
||||
directiveFileName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function createAngularDirectiveModule(name: string) {
|
||||
return `
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [${name}],
|
||||
exports: [${name}],
|
||||
})
|
||||
export class ${name}Module {}`;
|
||||
}
|
||||
|
||||
function createSeparateAngularDirectiveModuleFile(
|
||||
name: string,
|
||||
directiveFileName: string
|
||||
) {
|
||||
return `import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ${name} } from './${directiveFileName}';
|
||||
${createAngularDirectiveModule(name)}`;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
import scamGenerator from './scam-directive';
|
||||
import { convertNxGenerator } from '@nrwl/devkit';
|
||||
|
||||
export default convertNxGenerator(scamGenerator);
|
||||
@ -0,0 +1,203 @@
|
||||
import { addProjectConfiguration } from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import scamDirectiveGenerator from './scam-directive';
|
||||
|
||||
describe('SCAM Directive Generator', () => {
|
||||
it('should create the inline scam directive correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamDirectiveGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveSource = tree.read(
|
||||
'apps/app1/src/app/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the separate scam directive correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamDirectiveGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveModuleSource = tree.read(
|
||||
'apps/app1/src/app/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExampleDirective } from './example.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
describe('--path', () => {
|
||||
it('should not throw when the path does not exist under project', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamDirectiveGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not matter if the path starts with a slash', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamDirectiveGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
path: '/apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const directiveSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.directive.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(directiveSource).toMatchInlineSnapshot(`
|
||||
"import { Directive, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Directive({
|
||||
selector: '[example]'
|
||||
})
|
||||
export class ExampleDirective {
|
||||
|
||||
constructor() { }
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExampleDirective],
|
||||
exports: [ExampleDirective],
|
||||
})
|
||||
export class ExampleDirectiveModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should throw when the path does not exist under project', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
try {
|
||||
await 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).]`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,54 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import type { Schema } from './schema';
|
||||
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
||||
import {
|
||||
formatFiles,
|
||||
readWorkspaceConfiguration,
|
||||
readProjectConfiguration,
|
||||
normalizePath,
|
||||
} from '@nrwl/devkit';
|
||||
import { createScamDirective } from './lib/create-module';
|
||||
import { normalize } from 'path';
|
||||
|
||||
export async function scamDirectiveGenerator(tree: Tree, schema: Schema) {
|
||||
const { inlineScam, ...options } = schema;
|
||||
|
||||
checkPathUnderProjectRoot(tree, options);
|
||||
|
||||
const angularDirectiveSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'directive'
|
||||
);
|
||||
await angularDirectiveSchematic(tree, {
|
||||
...options,
|
||||
skipImport: true,
|
||||
export: false,
|
||||
});
|
||||
|
||||
createScamDirective(tree, schema);
|
||||
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
function checkPathUnderProjectRoot(tree: Tree, options: Partial<Schema>) {
|
||||
if (!options.path) {
|
||||
return;
|
||||
}
|
||||
|
||||
const project =
|
||||
options.project ?? readWorkspaceConfiguration(tree).defaultProject;
|
||||
const { root } = readProjectConfiguration(tree, project);
|
||||
|
||||
let pathToDirective = normalizePath(options.path);
|
||||
pathToDirective = pathToDirective.startsWith('/')
|
||||
? pathToDirective.slice(1)
|
||||
: pathToDirective;
|
||||
|
||||
if (!pathToDirective.startsWith(normalize(root))) {
|
||||
throw new Error(
|
||||
`The path provided for the SCAM (${options.path}) does not exist under the project root (${root}).`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default scamDirectiveGenerator;
|
||||
10
packages/angular/src/generators/scam-directive/schema.d.ts
vendored
Normal file
10
packages/angular/src/generators/scam-directive/schema.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
export interface Schema {
|
||||
name: string;
|
||||
path?: string;
|
||||
project?: string;
|
||||
skipTests?: boolean;
|
||||
inlineScam?: boolean;
|
||||
flat?: boolean;
|
||||
prefix?: string;
|
||||
selector?: string;
|
||||
}
|
||||
68
packages/angular/src/generators/scam-directive/schema.json
Normal file
68
packages/angular/src/generators/scam-directive/schema.json
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "SCAMDirectiveGenerator",
|
||||
"cli": "nx",
|
||||
"title": "SCAM Directive Generator Options Schema",
|
||||
"type": "object",
|
||||
"description": "Creates a new, generic directive definition in the given or default project.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The path at which to create the directive file, relative to the current workspace. Default is a folder with the same name as the directive in the project root.",
|
||||
"visible": false
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": {
|
||||
"$source": "projectName"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the directive.",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-prompt": "What name would you like to use for the directive?"
|
||||
},
|
||||
"skipTests": {
|
||||
"type": "boolean",
|
||||
"description": "Do not create \"spec.ts\" test files for the new directive.",
|
||||
"default": false
|
||||
},
|
||||
"inlineScam": {
|
||||
"type": "boolean",
|
||||
"description": "Create the NgModule in the same file as the Directive.",
|
||||
"default": true
|
||||
},
|
||||
"flat": {
|
||||
"type": "boolean",
|
||||
"description": "Create the new files at the top level of the current project.",
|
||||
"default": true
|
||||
},
|
||||
"selector": {
|
||||
"type": "string",
|
||||
"format": "html-selector",
|
||||
"description": "The HTML selector to use for this directive."
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "The prefix to apply to the generated directive selector.",
|
||||
"alias": "p",
|
||||
"oneOf": [
|
||||
{
|
||||
"maxLength": 0
|
||||
},
|
||||
{
|
||||
"minLength": 1,
|
||||
"format": "html-selector"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
}
|
||||
@ -0,0 +1,335 @@
|
||||
import { addProjectConfiguration } from '@nrwl/devkit';
|
||||
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import { createScamPipe } from './create-module';
|
||||
|
||||
describe('Create module in the tree', () => {
|
||||
it('should create the scam pipe inline correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeSource = tree.read(
|
||||
'apps/app1/src/app/example/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam pipe separately correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeModuleSource = tree.read(
|
||||
'apps/app1/src/app/example/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExamplePipe } from './example.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam pipe inline correctly when --flat', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeSource = tree.read('apps/app1/src/app/example.pipe.ts', 'utf-8');
|
||||
expect(pipeSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the scam pipe separately correctly when --flat', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeModuleSource = tree.read(
|
||||
'apps/app1/src/app/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExamplePipe } from './example.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should place the pipe and scam pipe in the correct folder when --path is used', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: false,
|
||||
path: 'apps/app1/src/app/random',
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
flat: false,
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeModuleSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeModuleSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should place the pipe and scam pipe in the correct folder when --path and --flat is used', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
const angularComponentSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularComponentSchematic(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
skipImport: true,
|
||||
export: false,
|
||||
flat: true,
|
||||
path: 'apps/app1/src/app/random',
|
||||
});
|
||||
|
||||
// ACT
|
||||
createScamPipe(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
flat: true,
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeModuleSource = tree.read(
|
||||
'apps/app1/src/app/random/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeModuleSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
111
packages/angular/src/generators/scam-pipe/lib/create-module.ts
Normal file
111
packages/angular/src/generators/scam-pipe/lib/create-module.ts
Normal file
@ -0,0 +1,111 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import type { Schema } from '../schema';
|
||||
|
||||
import {
|
||||
readProjectConfiguration,
|
||||
joinPathFragments,
|
||||
names,
|
||||
readWorkspaceConfiguration,
|
||||
normalizePath,
|
||||
} from '@nrwl/devkit';
|
||||
import { insertImport } from '@nrwl/workspace/src/utilities/ast-utils';
|
||||
import { createSourceFile, ScriptTarget } from 'typescript';
|
||||
|
||||
export function createScamPipe(tree: Tree, schema: Schema) {
|
||||
const project =
|
||||
schema.project ?? readWorkspaceConfiguration(tree).defaultProject;
|
||||
const projectConfig = readProjectConfiguration(tree, project);
|
||||
|
||||
const pipeNames = names(schema.name);
|
||||
const typeNames = names('pipe');
|
||||
|
||||
const pipeFileName = `${pipeNames.fileName}.pipe`;
|
||||
|
||||
let pipeDirectory = schema.flat
|
||||
? joinPathFragments(
|
||||
projectConfig.sourceRoot,
|
||||
projectConfig.projectType === 'application' ? 'app' : 'lib'
|
||||
)
|
||||
: joinPathFragments(
|
||||
projectConfig.sourceRoot,
|
||||
projectConfig.projectType === 'application' ? 'app' : 'lib',
|
||||
pipeNames.fileName
|
||||
);
|
||||
|
||||
if (schema.path) {
|
||||
pipeDirectory = schema.flat
|
||||
? normalizePath(schema.path)
|
||||
: joinPathFragments(schema.path, pipeNames.fileName);
|
||||
}
|
||||
|
||||
const pipeFilePath = joinPathFragments(pipeDirectory, `${pipeFileName}.ts`);
|
||||
|
||||
if (!tree.exists(pipeFilePath)) {
|
||||
throw new Error(
|
||||
`Couldn't find pipe at path ${pipeFilePath} to add SCAM setup.`
|
||||
);
|
||||
}
|
||||
|
||||
if (schema.inlineScam) {
|
||||
const currentPipeContents = tree.read(pipeFilePath, 'utf-8');
|
||||
let source = createSourceFile(
|
||||
pipeFilePath,
|
||||
currentPipeContents,
|
||||
ScriptTarget.Latest,
|
||||
true
|
||||
);
|
||||
|
||||
source = insertImport(
|
||||
tree,
|
||||
source,
|
||||
pipeFilePath,
|
||||
'NgModule',
|
||||
'@angular/core'
|
||||
);
|
||||
|
||||
source = insertImport(
|
||||
tree,
|
||||
source,
|
||||
pipeFilePath,
|
||||
'CommonModule',
|
||||
'@angular/common'
|
||||
);
|
||||
|
||||
let updatedPipeSource = source.getText();
|
||||
|
||||
updatedPipeSource = `${updatedPipeSource}${createAngularPipeModule(
|
||||
`${pipeNames.className}${typeNames.className}`
|
||||
)}`;
|
||||
|
||||
tree.write(pipeFilePath, updatedPipeSource);
|
||||
return;
|
||||
}
|
||||
|
||||
tree.write(
|
||||
joinPathFragments(pipeDirectory, `${pipeNames.fileName}.module.ts`),
|
||||
createSeparateAngularPipeModuleFile(
|
||||
`${pipeNames.className}${typeNames.className}`,
|
||||
pipeFileName
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function createAngularPipeModule(name: string) {
|
||||
return `
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [${name}],
|
||||
exports: [${name}],
|
||||
})
|
||||
export class ${name}Module {}`;
|
||||
}
|
||||
|
||||
function createSeparateAngularPipeModuleFile(
|
||||
name: string,
|
||||
pipeFileName: string
|
||||
) {
|
||||
return `import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ${name} } from './${pipeFileName}';
|
||||
${createAngularPipeModule(name)}`;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
import scamPipeGenerator from './scam-pipe';
|
||||
import { convertNxGenerator } from '@nrwl/devkit';
|
||||
|
||||
export default convertNxGenerator(scamPipeGenerator);
|
||||
208
packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts
Normal file
208
packages/angular/src/generators/scam-pipe/scam-pipe.spec.ts
Normal file
@ -0,0 +1,208 @@
|
||||
import { addProjectConfiguration } from '@nrwl/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
||||
import scamPipeGenerator from './scam-pipe';
|
||||
|
||||
describe('SCAM Pipe Generator', () => {
|
||||
it('should create the inline scam pipe correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamPipeGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeSource = tree.read(
|
||||
'apps/app1/src/app/example/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create the separate scam pipe correctly', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamPipeGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
inlineScam: false,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeModuleSource = tree.read(
|
||||
'apps/app1/src/app/example/example.module.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeModuleSource).toMatchInlineSnapshot(`
|
||||
"import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ExamplePipe } from './example.pipe';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
describe('--path', () => {
|
||||
it('should not throw when the path does not exist under project', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamPipeGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
path: 'apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not matter if the path starts with a slash', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
await scamPipeGenerator(tree, {
|
||||
name: 'example',
|
||||
project: 'app1',
|
||||
path: '/apps/app1/src/app/random',
|
||||
inlineScam: true,
|
||||
flat: false,
|
||||
});
|
||||
|
||||
// ASSERT
|
||||
const pipeSource = tree.read(
|
||||
'apps/app1/src/app/random/example/example.pipe.ts',
|
||||
'utf-8'
|
||||
);
|
||||
expect(pipeSource).toMatchInlineSnapshot(`
|
||||
"import { Pipe, PipeTransform, NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Pipe({
|
||||
name: 'example'
|
||||
})
|
||||
export class ExamplePipe implements PipeTransform {
|
||||
|
||||
transform(value: unknown, ...args: unknown[]): unknown {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [ExamplePipe],
|
||||
exports: [ExamplePipe],
|
||||
})
|
||||
export class ExamplePipeModule {}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should throw when the path does not exist under project', async () => {
|
||||
// ARRANGE
|
||||
const tree = createTreeWithEmptyWorkspace(2);
|
||||
addProjectConfiguration(tree, 'app1', {
|
||||
projectType: 'application',
|
||||
sourceRoot: 'apps/app1/src',
|
||||
root: 'apps/app1',
|
||||
});
|
||||
|
||||
// ACT
|
||||
try {
|
||||
await 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).]`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
52
packages/angular/src/generators/scam-pipe/scam-pipe.ts
Normal file
52
packages/angular/src/generators/scam-pipe/scam-pipe.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import type { Tree } from '@nrwl/devkit';
|
||||
import type { Schema } from './schema';
|
||||
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
|
||||
import {
|
||||
formatFiles,
|
||||
readWorkspaceConfiguration,
|
||||
readProjectConfiguration,
|
||||
normalizePath,
|
||||
} from '@nrwl/devkit';
|
||||
import { createScamPipe } from './lib/create-module';
|
||||
import { normalize } from 'path';
|
||||
|
||||
export async function scamPipeGenerator(tree: Tree, schema: Schema) {
|
||||
const { inlineScam, ...options } = schema;
|
||||
|
||||
checkPathUnderProjectRoot(tree, options);
|
||||
|
||||
const angularPipeSchematic = wrapAngularDevkitSchematic(
|
||||
'@schematics/angular',
|
||||
'pipe'
|
||||
);
|
||||
await angularPipeSchematic(tree, {
|
||||
...options,
|
||||
skipImport: true,
|
||||
export: false,
|
||||
});
|
||||
|
||||
createScamPipe(tree, schema);
|
||||
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
function checkPathUnderProjectRoot(tree: Tree, options: Partial<Schema>) {
|
||||
if (!options.path) {
|
||||
return;
|
||||
}
|
||||
|
||||
const project =
|
||||
options.project ?? readWorkspaceConfiguration(tree).defaultProject;
|
||||
const { root } = readProjectConfiguration(tree, project);
|
||||
|
||||
let pathToPipe = normalizePath(options.path);
|
||||
pathToPipe = pathToPipe.startsWith('/') ? pathToPipe.slice(1) : pathToPipe;
|
||||
|
||||
if (!pathToPipe.startsWith(normalize(root))) {
|
||||
throw new Error(
|
||||
`The path provided for the SCAM (${options.path}) does not exist under the project root (${root}).`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default scamPipeGenerator;
|
||||
8
packages/angular/src/generators/scam-pipe/schema.d.ts
vendored
Normal file
8
packages/angular/src/generators/scam-pipe/schema.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
export interface Schema {
|
||||
name: string;
|
||||
path?: string;
|
||||
project?: string;
|
||||
skipTests?: boolean;
|
||||
inlineScam?: boolean;
|
||||
flat?: boolean;
|
||||
}
|
||||
49
packages/angular/src/generators/scam-pipe/schema.json
Normal file
49
packages/angular/src/generators/scam-pipe/schema.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "SCAMPipeGenerator",
|
||||
"cli": "nx",
|
||||
"title": "SCAM Pipe Generator Options Schema",
|
||||
"type": "object",
|
||||
"description": "Creates a new, generic pipe definition in the given or default project.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "The path at which to create the pipe file, relative to the current workspace. Default is a folder with the same name as the pipe in the project root.",
|
||||
"visible": false
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"description": "The name of the project.",
|
||||
"$default": {
|
||||
"$source": "projectName"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the pipe.",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-prompt": "What name would you like to use for the pipe?"
|
||||
},
|
||||
"skipTests": {
|
||||
"type": "boolean",
|
||||
"description": "Do not create \"spec.ts\" test files for the new pipe.",
|
||||
"default": false
|
||||
},
|
||||
"inlineScam": {
|
||||
"type": "boolean",
|
||||
"description": "Create the NgModule in the same file as the Pipe.",
|
||||
"default": true
|
||||
},
|
||||
"flat": {
|
||||
"type": "boolean",
|
||||
"description": "Create the new files at the top level of the current project.",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user