feat(nest): implement nest lib schematic (#2540)
This commit is contained in:
parent
ff6b434548
commit
a39587a350
@ -20,6 +20,7 @@ module.exports = {
|
||||
{ name: 'core', description: 'anything Nx core specific' },
|
||||
{ name: 'docs', description: 'anything related to docs infrastructure' },
|
||||
{ name: 'nextjs', description: 'anything Next specific' },
|
||||
{ name: 'nest', description: 'anything Nest specific' },
|
||||
{ name: 'node', description: 'anything Node specific' },
|
||||
{ name: 'nx-plugin', description: 'anything Nx Plugin specific' },
|
||||
{ name: 'react', description: 'anything React specific' },
|
||||
|
||||
@ -181,6 +181,7 @@ The scope must be one of the following:
|
||||
- core - anything Nx core specific
|
||||
- docs - anything related to docs infrastructure
|
||||
- nextjs - anything Next specific
|
||||
- nest - anything Nest specific
|
||||
- node - anything Node specific
|
||||
- linter - anything Linter specific
|
||||
- react - anything React specific
|
||||
|
||||
145
docs/angular/api-nest/schematics/library.md
Normal file
145
docs/angular/api-nest/schematics/library.md
Normal file
@ -0,0 +1,145 @@
|
||||
# library
|
||||
|
||||
Create a new nest library
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ng generate library ...
|
||||
```
|
||||
|
||||
```bash
|
||||
ng g lib ... # same
|
||||
```
|
||||
|
||||
By default, Nx will search for `library` in the default collection provisioned in `angular.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
ng g @nrwl/nest:library ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
ng g library ... --dry-run
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Generate libs/myapp/mylib:
|
||||
|
||||
```bash
|
||||
ng g lib mylib --directory=myapp
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### controller
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a controller with the library
|
||||
|
||||
### directory
|
||||
|
||||
Alias(es): d
|
||||
|
||||
Type: `string`
|
||||
|
||||
A directory where the app is placed
|
||||
|
||||
### global
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Add the Global decorator to the generated module.
|
||||
|
||||
### linter
|
||||
|
||||
Default: `tslint`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `eslint`, `tslint`
|
||||
|
||||
The tool to use for running lint checks.
|
||||
|
||||
### name
|
||||
|
||||
Type: `string`
|
||||
|
||||
Library name
|
||||
|
||||
### publishable
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create a publishable library. A "build" architect will be added for this project the workspace configuration.
|
||||
|
||||
### service
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a service with the library.
|
||||
|
||||
### skipFormat
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Skip formatting files
|
||||
|
||||
### skipTsConfig
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not update tsconfig.json for development experience.
|
||||
|
||||
### tags
|
||||
|
||||
Alias(es): t
|
||||
|
||||
Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### target
|
||||
|
||||
Default: `es6`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `es5`, `es6`, `esnext`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020`
|
||||
|
||||
The es target, Nest suggest using es6 or higher.
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `node`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment for jest, for node applications this should stay as node unless doing DOM testing.
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jest`, `none`
|
||||
|
||||
Test runner to use for unit tests
|
||||
@ -90,6 +90,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
@ -80,6 +80,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
145
docs/react/api-nest/schematics/library.md
Normal file
145
docs/react/api-nest/schematics/library.md
Normal file
@ -0,0 +1,145 @@
|
||||
# library
|
||||
|
||||
Create a new nest library
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate library ...
|
||||
```
|
||||
|
||||
```bash
|
||||
nx g lib ... # same
|
||||
```
|
||||
|
||||
By default, Nx will search for `library` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/nest:library ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g library ... --dry-run
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Generate libs/myapp/mylib:
|
||||
|
||||
```bash
|
||||
nx g lib mylib --directory=myapp
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### controller
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a controller with the library
|
||||
|
||||
### directory
|
||||
|
||||
Alias(es): d
|
||||
|
||||
Type: `string`
|
||||
|
||||
A directory where the app is placed
|
||||
|
||||
### global
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Add the Global decorator to the generated module.
|
||||
|
||||
### linter
|
||||
|
||||
Default: `tslint`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `eslint`, `tslint`
|
||||
|
||||
The tool to use for running lint checks.
|
||||
|
||||
### name
|
||||
|
||||
Type: `string`
|
||||
|
||||
Library name
|
||||
|
||||
### publishable
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create a publishable library. A "build" architect will be added for this project the workspace configuration.
|
||||
|
||||
### service
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a service with the library.
|
||||
|
||||
### skipFormat
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Skip formatting files
|
||||
|
||||
### skipTsConfig
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not update tsconfig.json for development experience.
|
||||
|
||||
### tags
|
||||
|
||||
Alias(es): t
|
||||
|
||||
Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### target
|
||||
|
||||
Default: `es6`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `es5`, `es6`, `esnext`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020`
|
||||
|
||||
The es target, Nest suggest using es6 or higher.
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `node`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment for jest, for node applications this should stay as node unless doing DOM testing.
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jest`, `none`
|
||||
|
||||
Test runner to use for unit tests
|
||||
@ -90,6 +90,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
@ -80,6 +80,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
145
docs/web/api-nest/schematics/library.md
Normal file
145
docs/web/api-nest/schematics/library.md
Normal file
@ -0,0 +1,145 @@
|
||||
# library
|
||||
|
||||
Create a new nest library
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
nx generate library ...
|
||||
```
|
||||
|
||||
```bash
|
||||
nx g lib ... # same
|
||||
```
|
||||
|
||||
By default, Nx will search for `library` in the default collection provisioned in `workspace.json`.
|
||||
|
||||
You can specify the collection explicitly as follows:
|
||||
|
||||
```bash
|
||||
nx g @nrwl/nest:library ...
|
||||
```
|
||||
|
||||
Show what will be generated without writing to disk:
|
||||
|
||||
```bash
|
||||
nx g library ... --dry-run
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Generate libs/myapp/mylib:
|
||||
|
||||
```bash
|
||||
nx g lib mylib --directory=myapp
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### controller
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a controller with the library
|
||||
|
||||
### directory
|
||||
|
||||
Alias(es): d
|
||||
|
||||
Type: `string`
|
||||
|
||||
A directory where the app is placed
|
||||
|
||||
### global
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Add the Global decorator to the generated module.
|
||||
|
||||
### linter
|
||||
|
||||
Default: `tslint`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `eslint`, `tslint`
|
||||
|
||||
The tool to use for running lint checks.
|
||||
|
||||
### name
|
||||
|
||||
Type: `string`
|
||||
|
||||
Library name
|
||||
|
||||
### publishable
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Create a publishable library. A "build" architect will be added for this project the workspace configuration.
|
||||
|
||||
### service
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Include a service with the library.
|
||||
|
||||
### skipFormat
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Skip formatting files
|
||||
|
||||
### skipTsConfig
|
||||
|
||||
Default: `false`
|
||||
|
||||
Type: `boolean`
|
||||
|
||||
Do not update tsconfig.json for development experience.
|
||||
|
||||
### tags
|
||||
|
||||
Alias(es): t
|
||||
|
||||
Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### target
|
||||
|
||||
Default: `es6`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `es5`, `es6`, `esnext`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020`
|
||||
|
||||
The es target, Nest suggest using es6 or higher.
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `node`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment for jest, for node applications this should stay as node unless doing DOM testing.
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jest`, `none`
|
||||
|
||||
Test runner to use for unit tests
|
||||
@ -90,6 +90,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
@ -80,6 +80,16 @@ Type: `string`
|
||||
|
||||
Add tags to the library (used for linting)
|
||||
|
||||
### testEnvironment
|
||||
|
||||
Default: `jsdom`
|
||||
|
||||
Type: `string`
|
||||
|
||||
Possible values: `jsdom`, `node`
|
||||
|
||||
The test environment to use if unitTestRunner is set to jest
|
||||
|
||||
### unitTestRunner
|
||||
|
||||
Default: `jest`
|
||||
|
||||
@ -21,6 +21,8 @@ import {
|
||||
setMaxWorkers,
|
||||
newProject
|
||||
} from './utils';
|
||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||
import { readFile } from './utils';
|
||||
|
||||
function getData(): Promise<any> {
|
||||
return new Promise(resolve => {
|
||||
@ -226,6 +228,73 @@ forEachCli(currentCLIName => {
|
||||
});
|
||||
}, 120000);
|
||||
|
||||
describe('nest libraries', function() {
|
||||
it('should be able to generate a nest library', async () => {
|
||||
ensureProject();
|
||||
const nestlib = uniq('nestlib');
|
||||
|
||||
runCLI(`generate @nrwl/nest:lib ${nestlib}`);
|
||||
|
||||
const jestConfigContent = readFile(`libs/${nestlib}/jest.config.js`);
|
||||
|
||||
expect(stripIndents`${jestConfigContent}`).toEqual(
|
||||
stripIndents`module.exports = {
|
||||
name: '${nestlib}',
|
||||
preset: '../../jest.config.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest'
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
coverageDirectory: '../../coverage/libs/${nestlib}'
|
||||
};
|
||||
`
|
||||
);
|
||||
|
||||
const lintResults = runCLI(`lint ${nestlib}`);
|
||||
expect(lintResults).toContain('All files pass linting.');
|
||||
}, 60000);
|
||||
|
||||
it('should be able to generate a nest library w/ service', async () => {
|
||||
ensureProject();
|
||||
const nestlib = uniq('nestlib');
|
||||
|
||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --service`);
|
||||
|
||||
const lintResults = runCLI(`lint ${nestlib}`);
|
||||
expect(lintResults).toContain('All files pass linting.');
|
||||
|
||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||
}, 60000);
|
||||
|
||||
it('should be able to generate a nest library w/ controller', async () => {
|
||||
ensureProject();
|
||||
const nestlib = uniq('nestlib');
|
||||
|
||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller`);
|
||||
|
||||
const lintResults = runCLI(`lint ${nestlib}`);
|
||||
expect(lintResults).toContain('All files pass linting.');
|
||||
|
||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||
}, 60000);
|
||||
|
||||
it('should be able to generate a nest library w/ controller and service', async () => {
|
||||
ensureProject();
|
||||
const nestlib = uniq('nestlib');
|
||||
|
||||
runCLI(`generate @nrwl/nest:lib ${nestlib} --controller --service`);
|
||||
|
||||
const lintResults = runCLI(`lint ${nestlib}`);
|
||||
expect(lintResults).toContain('All files pass linting.');
|
||||
|
||||
const jestResult = await runCLIAsync(`test ${nestlib}`);
|
||||
expect(jestResult.stderr).toContain('Test Suites: 2 passed, 2 total');
|
||||
}, 60000);
|
||||
});
|
||||
|
||||
it('should be able to generate an empty application', async () => {
|
||||
ensureProject();
|
||||
const nodeapp = uniq('nodeapp');
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
name: '<%= project %>',
|
||||
preset: '<%= offsetFromRoot %>jest.config.js',<% if (supportTsx) { %>
|
||||
preset: '<%= offsetFromRoot %>jest.config.js',<% if(testEnvironment) { %>
|
||||
testEnvironment: '<%= testEnvironment %>',<% } %><% if (supportTsx) { %>
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest'
|
||||
},
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
import {
|
||||
Rule,
|
||||
Tree,
|
||||
mergeWith,
|
||||
chain,
|
||||
url,
|
||||
apply,
|
||||
SchematicContext,
|
||||
chain,
|
||||
filter,
|
||||
mergeWith,
|
||||
move,
|
||||
template,
|
||||
noop,
|
||||
filter
|
||||
Rule,
|
||||
SchematicContext,
|
||||
template,
|
||||
Tree,
|
||||
url
|
||||
} from '@angular-devkit/schematics';
|
||||
import {
|
||||
readJsonInTree,
|
||||
getProjectConfig,
|
||||
offsetFromRoot,
|
||||
updateJsonInTree,
|
||||
updateWorkspaceInTree
|
||||
} from '@nrwl/workspace';
|
||||
import { getProjectConfig, addDepsToPackageJson } from '@nrwl/workspace';
|
||||
import { offsetFromRoot } from '@nrwl/workspace';
|
||||
import { join, normalize } from '@angular-devkit/core';
|
||||
import init from '../init/init';
|
||||
|
||||
@ -27,6 +26,7 @@ export interface JestProjectSchema {
|
||||
skipSetupFile: boolean;
|
||||
setupFile: 'angular' | 'web-components' | 'none';
|
||||
skipSerializers: boolean;
|
||||
testEnvironment: 'node' | 'jsdom' | '';
|
||||
}
|
||||
|
||||
function generateFiles(options: JestProjectSchema): Rule {
|
||||
@ -114,6 +114,10 @@ function check(options: JestProjectSchema): Rule {
|
||||
}
|
||||
|
||||
function normalizeOptions(options: JestProjectSchema): JestProjectSchema {
|
||||
if (options.testEnvironment === 'jsdom') {
|
||||
options.testEnvironment = '';
|
||||
}
|
||||
|
||||
if (!options.skipSetupFile) {
|
||||
return options;
|
||||
}
|
||||
|
||||
@ -32,6 +32,12 @@
|
||||
"type": "boolean",
|
||||
"description": "Setup tsx support",
|
||||
"default": false
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"description": "The test environment for jest",
|
||||
"default": "jsdom"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@ -16,6 +16,13 @@
|
||||
"schema": "./src/schematics/application/schema.json",
|
||||
"aliases": ["app"],
|
||||
"description": "Create a nest application"
|
||||
},
|
||||
|
||||
"library": {
|
||||
"factory": "./src/schematics/library/library",
|
||||
"schema": "./src/schematics/library/schema.json",
|
||||
"aliases": ["lib"],
|
||||
"description": "Create a new nest library"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { <%= className %>Controller } from './<%= fileName %>.controller';
|
||||
<% if(service) { %>import { <%= className %>Service } from './<%= fileName %>.service';<% } %>
|
||||
|
||||
describe('<%= className %>Controller', () => {
|
||||
|
||||
let controller: <%= className %>Controller;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
providers: [
|
||||
<% if(service) { %><%= className %>Service<% } %>
|
||||
],
|
||||
controllers: [
|
||||
<%= className %>Controller
|
||||
]
|
||||
}).compile();
|
||||
|
||||
controller = module.get(<%= className %>Controller);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeTruthy();
|
||||
});
|
||||
|
||||
})
|
||||
@ -0,0 +1,7 @@
|
||||
import { Controller } from '@nestjs/common';
|
||||
<% if(service) { %>import { <%= className %>Service } from './<%= fileName %>.service';<% } %>
|
||||
|
||||
@Controller('<%= fileName %>')
|
||||
export class <%= className %>Controller {
|
||||
constructor(<% if(service) { %>private <%= propertyName %>Service: <%= className %>Service<% } %>) {}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
import { Module<% if(global) { %>, Global<% } %> } from '@nestjs/common';
|
||||
<% if(service) { %>import { <%= className %>Service } from './<%= fileName %>.service';<% } %>
|
||||
<% if(controller) { %>import { <%= className %>Controller } from './<%= fileName %>.controller';<% } %>
|
||||
|
||||
<% if(global) { %>@Global()<% } %>
|
||||
@Module({
|
||||
controllers: [
|
||||
<% if(controller) { %><%= className %>Controller<% } %>
|
||||
],
|
||||
providers: [
|
||||
<% if(service) { %><%= className %>Service<% } %>
|
||||
],
|
||||
exports: [
|
||||
<% if(service) { %><%= className %>Service<% } %>
|
||||
]
|
||||
})
|
||||
export class <%= className %>Module {
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { <%= className %>Service } from './<%= fileName %>.service';
|
||||
|
||||
describe('<%= className %>Service', () => {
|
||||
|
||||
let service: <%= className %>Service;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module = await Test.createTestingModule({
|
||||
providers: [
|
||||
<%= className %>Service
|
||||
]
|
||||
}).compile();
|
||||
|
||||
service = module.get(<%= className %>Service);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
})
|
||||
@ -0,0 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class <%= className %>Service {
|
||||
constructor() {}
|
||||
}
|
||||
409
packages/nest/src/schematics/library/library.spec.ts
Normal file
409
packages/nest/src/schematics/library/library.spec.ts
Normal file
@ -0,0 +1,409 @@
|
||||
import { Tree } from '@angular-devkit/schematics';
|
||||
import { NxJson, readJsonInTree } from '@nrwl/workspace';
|
||||
import { createEmptyWorkspace, getFileContent } from '@nrwl/workspace/testing';
|
||||
import { runSchematic } from '../../utils/testing';
|
||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||
|
||||
describe('lib', () => {
|
||||
let appTree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
appTree = Tree.empty();
|
||||
appTree = createEmptyWorkspace(appTree);
|
||||
});
|
||||
|
||||
describe('not nested', () => {
|
||||
it('should update workspace.json', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
||||
expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
||||
expect(workspaceJson.projects['my-lib'].architect.build).toBeUndefined();
|
||||
expect(workspaceJson.projects['my-lib'].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
exclude: ['**/node_modules/**', '!libs/my-lib/**'],
|
||||
tsConfig: [
|
||||
'libs/my-lib/tsconfig.lib.json',
|
||||
'libs/my-lib/tsconfig.spec.json'
|
||||
]
|
||||
}
|
||||
});
|
||||
expect(workspaceJson.projects['my-lib'].architect.test).toEqual({
|
||||
builder: '@nrwl/jest:jest',
|
||||
options: {
|
||||
jestConfig: 'libs/my-lib/jest.config.js',
|
||||
tsConfig: 'libs/my-lib/tsconfig.spec.json',
|
||||
passWithNoTests: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should include a controller', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', controller: true },
|
||||
appTree
|
||||
);
|
||||
const service = getFileContent(
|
||||
tree,
|
||||
'libs/my-lib/src/lib/my-lib.controller.ts'
|
||||
);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should include a service', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', service: true },
|
||||
appTree
|
||||
);
|
||||
const service = getFileContent(
|
||||
tree,
|
||||
'libs/my-lib/src/lib/my-lib.service.ts'
|
||||
);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add the @Global decorator', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', global: true },
|
||||
appTree
|
||||
);
|
||||
const module = getFileContent(
|
||||
tree,
|
||||
'libs/my-lib/src/lib/my-lib.module.ts'
|
||||
);
|
||||
expect(stripIndents`${module}`).toEqual(
|
||||
stripIndents`import { Module, Global } from '@nestjs/common';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
controllers: [],
|
||||
providers: [],
|
||||
exports: []
|
||||
})
|
||||
export class MyLibModule {}`
|
||||
);
|
||||
});
|
||||
|
||||
it('should provide the controller and service', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', service: true, controller: true },
|
||||
appTree
|
||||
);
|
||||
const module = getFileContent(
|
||||
tree,
|
||||
'libs/my-lib/src/lib/my-lib.module.ts'
|
||||
);
|
||||
expect(stripIndents`${module}`).toEqual(
|
||||
stripIndents`import { Module } from '@nestjs/common';
|
||||
import { MyLibService } from './my-lib.service';
|
||||
import { MyLibController } from './my-lib.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [MyLibController],
|
||||
providers: [MyLibService],
|
||||
exports: [MyLibService]
|
||||
})
|
||||
export class MyLibModule {}`
|
||||
);
|
||||
|
||||
const controller = getFileContent(
|
||||
tree,
|
||||
'libs/my-lib/src/lib/my-lib.controller.ts'
|
||||
);
|
||||
expect(stripIndents`${controller}`).toEqual(
|
||||
stripIndents`import { Controller } from '@nestjs/common';
|
||||
import { MyLibService } from './my-lib.service';
|
||||
|
||||
@Controller('my-lib')
|
||||
export class MyLibController {
|
||||
constructor(private myLibService: MyLibService) {}
|
||||
}`
|
||||
);
|
||||
|
||||
const barrel = getFileContent(tree, 'libs/my-lib/src/index.ts');
|
||||
expect(stripIndents`${barrel}`).toEqual(
|
||||
stripIndents`export * from './lib/my-lib.module';
|
||||
export * from './lib/my-lib.service';
|
||||
export * from './lib/my-lib.controller';`
|
||||
);
|
||||
});
|
||||
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', tags: 'one,two' },
|
||||
appTree
|
||||
);
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
projects: {
|
||||
'my-lib': {
|
||||
tags: ['one', 'two']
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should update root tsconfig.json', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||
'libs/my-lib/src/index.ts'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create a local tsconfig.json', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
const tsconfigJson = readJsonInTree(tree, 'libs/my-lib/tsconfig.json');
|
||||
expect(tsconfigJson).toEqual({
|
||||
extends: '../../tsconfig.json',
|
||||
compilerOptions: {
|
||||
types: ['node', 'jest'],
|
||||
target: 'es6'
|
||||
},
|
||||
include: ['**/*.ts']
|
||||
});
|
||||
});
|
||||
|
||||
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'libs/my-lib/tsconfig.spec.json'
|
||||
);
|
||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'libs/my-lib/tsconfig.lib.json'
|
||||
);
|
||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy();
|
||||
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
|
||||
expect(tree.exists(`libs/my-lib/src/lib/my-lib.spec.ts`)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('nested', () => {
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib',
|
||||
directory: 'myDir',
|
||||
tags: 'one'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
projects: {
|
||||
'my-dir-my-lib': {
|
||||
tags: ['one']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const tree2 = await runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
tags: 'one,two'
|
||||
},
|
||||
tree
|
||||
);
|
||||
const nxJson2 = readJsonInTree<NxJson>(tree2, '/nx.json');
|
||||
expect(nxJson2).toEqual({
|
||||
npmScope: 'proj',
|
||||
projects: {
|
||||
'my-dir-my-lib': {
|
||||
tags: ['one']
|
||||
},
|
||||
'my-dir-my-lib2': {
|
||||
tags: ['one', 'two']
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate files', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy();
|
||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||
expect(
|
||||
tree.exists(`libs/my-dir/my-lib/src/lib/my-lib.spec.ts`)
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update workspace.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
const workspaceJson = readJsonInTree(tree, '/workspace.json');
|
||||
|
||||
expect(workspaceJson.projects['my-dir-my-lib'].root).toEqual(
|
||||
'libs/my-dir/my-lib'
|
||||
);
|
||||
expect(workspaceJson.projects['my-dir-my-lib'].architect.lint).toEqual({
|
||||
builder: '@angular-devkit/build-angular:tslint',
|
||||
options: {
|
||||
exclude: ['**/node_modules/**', '!libs/my-dir/my-lib/**'],
|
||||
tsConfig: [
|
||||
'libs/my-dir/my-lib/tsconfig.lib.json',
|
||||
'libs/my-dir/my-lib/tsconfig.spec.json'
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should update tsconfig.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
|
||||
['libs/my-dir/my-lib/src/index.ts']
|
||||
);
|
||||
expect(
|
||||
tsconfigJson.compilerOptions.paths['my-dir-my-lib/*']
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should create a local tsconfig.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'libs/my-dir/my-lib/tsconfig.json'
|
||||
);
|
||||
expect(tsconfigJson).toEqual({
|
||||
extends: '../../../tsconfig.json',
|
||||
compilerOptions: {
|
||||
types: ['node', 'jest'],
|
||||
target: 'es6'
|
||||
},
|
||||
include: ['**/*.ts']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('--unit-test-runner none', () => {
|
||||
it('should not generate test configuration', async () => {
|
||||
const resultTree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'none' },
|
||||
appTree
|
||||
);
|
||||
expect(resultTree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/jest.config.js')).toBeFalsy();
|
||||
expect(resultTree.exists('libs/my-lib/lib/my-lib.spec.ts')).toBeFalsy();
|
||||
const workspaceJson = readJsonInTree(resultTree, 'workspace.json');
|
||||
expect(workspaceJson.projects['my-lib'].architect.test).toBeUndefined();
|
||||
const tsconfigJson = readJsonInTree(
|
||||
resultTree,
|
||||
'libs/my-lib/tsconfig.json'
|
||||
);
|
||||
expect(tsconfigJson).toEqual({
|
||||
extends: '../../tsconfig.json',
|
||||
compilerOptions: {
|
||||
types: ['node'],
|
||||
target: 'es6'
|
||||
},
|
||||
include: ['**/*.ts']
|
||||
});
|
||||
expect(
|
||||
workspaceJson.projects['my-lib'].architect.lint.options.tsConfig
|
||||
).toEqual(['libs/my-lib/tsconfig.lib.json']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('publishable package', () => {
|
||||
it('should update package.json', async () => {
|
||||
const publishableTree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'mylib', publishable: true },
|
||||
appTree
|
||||
);
|
||||
|
||||
let packageJsonContent = readJsonInTree(
|
||||
publishableTree,
|
||||
'libs/mylib/package.json'
|
||||
);
|
||||
|
||||
expect(packageJsonContent.name).toEqual('@proj/mylib');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compiler options target', () => {
|
||||
it('should set target to es6 in tsconfig.json by default', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'libs/my-dir/my-lib/tsconfig.json'
|
||||
);
|
||||
expect(tsconfigJson.compilerOptions.target).toEqual('es6');
|
||||
});
|
||||
|
||||
it('should set target to es2020 in tsconfig.json', async () => {
|
||||
const tree = await runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', target: 'es2020' },
|
||||
appTree
|
||||
);
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'libs/my-dir/my-lib/tsconfig.json'
|
||||
);
|
||||
expect(tsconfigJson.compilerOptions.target).toEqual('es2020');
|
||||
});
|
||||
|
||||
it('should set target jest testEnvironment to node', async () => {
|
||||
const tree = await runSchematic('lib', { name: 'myLib' }, appTree);
|
||||
|
||||
const jestConfig = getFileContent(tree, 'libs/my-lib/jest.config.js');
|
||||
expect(stripIndents`${jestConfig}`)
|
||||
.toEqual(stripIndents`module.exports = {
|
||||
name: 'my-lib',
|
||||
preset: '../../jest.config.js',
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest'
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||
coverageDirectory: '../../coverage/libs/my-lib'
|
||||
};`);
|
||||
});
|
||||
});
|
||||
});
|
||||
192
packages/nest/src/schematics/library/library.ts
Normal file
192
packages/nest/src/schematics/library/library.ts
Normal file
@ -0,0 +1,192 @@
|
||||
import { normalize, Path } from '@angular-devkit/core';
|
||||
import {
|
||||
apply,
|
||||
chain,
|
||||
externalSchematic,
|
||||
filter,
|
||||
MergeStrategy,
|
||||
mergeWith,
|
||||
move,
|
||||
noop,
|
||||
Rule,
|
||||
SchematicContext,
|
||||
template,
|
||||
Tree,
|
||||
url
|
||||
} from '@angular-devkit/schematics';
|
||||
import {
|
||||
addGlobal,
|
||||
deleteFile,
|
||||
formatFiles,
|
||||
getNpmScope,
|
||||
getProjectConfig,
|
||||
insert,
|
||||
names,
|
||||
offsetFromRoot,
|
||||
toFileName,
|
||||
updateJsonInTree,
|
||||
updateWorkspaceInTree
|
||||
} from '@nrwl/workspace';
|
||||
import { Schema } from './schema';
|
||||
import * as ts from 'typescript';
|
||||
import { RemoveChange } from '@nrwl/workspace/src/utils/ast-utils';
|
||||
|
||||
export interface NormalizedSchema extends Schema {
|
||||
name: string;
|
||||
prefix: string;
|
||||
fileName: string;
|
||||
projectRoot: Path;
|
||||
projectDirectory: string;
|
||||
parsedTags: string[];
|
||||
}
|
||||
|
||||
export default function(schema: NormalizedSchema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const options = normalizeOptions(host, schema);
|
||||
|
||||
return chain([
|
||||
externalSchematic('@nrwl/node', 'lib', schema),
|
||||
createFiles(options),
|
||||
addExportsToBarrelFile(options),
|
||||
updateTsConfig(options),
|
||||
addProject(options),
|
||||
formatFiles(options),
|
||||
deleteFile(`/${options.projectRoot}/src/lib/${options.fileName}.spec.ts`)
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
|
||||
const defaultPrefix = getNpmScope(host);
|
||||
const name = toFileName(options.name);
|
||||
const projectDirectory = options.directory
|
||||
? `${toFileName(options.directory)}/${name}`
|
||||
: name;
|
||||
|
||||
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
|
||||
const fileName = projectName;
|
||||
const projectRoot = normalize(`libs/${projectDirectory}`);
|
||||
|
||||
const parsedTags = options.tags
|
||||
? options.tags.split(',').map(s => s.trim())
|
||||
: [];
|
||||
|
||||
const normalized: NormalizedSchema = {
|
||||
...options,
|
||||
prefix: defaultPrefix, // we could also allow customizing this
|
||||
fileName,
|
||||
name: projectName,
|
||||
projectRoot,
|
||||
projectDirectory,
|
||||
parsedTags
|
||||
};
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function addExportsToBarrelFile(options: NormalizedSchema): Rule {
|
||||
return (host: Tree) => {
|
||||
const indexFilePath = `${options.projectRoot}/src/index.ts`;
|
||||
const buffer = host.read(indexFilePath);
|
||||
if (!!buffer) {
|
||||
const indexSource = buffer!.toString('utf-8');
|
||||
const indexSourceFile = ts.createSourceFile(
|
||||
indexFilePath,
|
||||
indexSource,
|
||||
ts.ScriptTarget.Latest,
|
||||
true
|
||||
);
|
||||
|
||||
insert(host, indexFilePath, [
|
||||
new RemoveChange(
|
||||
indexFilePath,
|
||||
0,
|
||||
`export * from './lib/${options.fileName}';`
|
||||
),
|
||||
...addGlobal(
|
||||
indexSourceFile,
|
||||
indexFilePath,
|
||||
`export * from './lib/${options.fileName}.module';`
|
||||
),
|
||||
...(options.service
|
||||
? addGlobal(
|
||||
indexSourceFile,
|
||||
indexFilePath,
|
||||
`export * from './lib/${options.fileName}.service';`
|
||||
)
|
||||
: []),
|
||||
...(options.controller
|
||||
? addGlobal(
|
||||
indexSourceFile,
|
||||
indexFilePath,
|
||||
`export * from './lib/${options.fileName}.controller';`
|
||||
)
|
||||
: [])
|
||||
]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createFiles(options: NormalizedSchema): Rule {
|
||||
return mergeWith(
|
||||
apply(url(`./files/lib`), [
|
||||
template({
|
||||
...options,
|
||||
...names(options.name),
|
||||
tmpl: '',
|
||||
offsetFromRoot: offsetFromRoot(options.projectRoot)
|
||||
}),
|
||||
move(options.projectRoot),
|
||||
options.unitTestRunner === 'none'
|
||||
? filter(file => !file.endsWith('spec.ts'))
|
||||
: noop(),
|
||||
options.publishable
|
||||
? noop()
|
||||
: filter(file => !file.endsWith('package.json')),
|
||||
options.service ? noop() : filter(file => !file.endsWith('.service.ts')),
|
||||
options.controller
|
||||
? noop()
|
||||
: filter(file => !file.endsWith('.controller.ts')),
|
||||
!options.controller || options.unitTestRunner === 'none'
|
||||
? filter(file => !file.endsWith('.controller.spec.ts'))
|
||||
: noop(),
|
||||
!options.service || options.unitTestRunner === 'none'
|
||||
? filter(file => !file.endsWith('.service.spec.ts'))
|
||||
: noop()
|
||||
]),
|
||||
MergeStrategy.Overwrite
|
||||
);
|
||||
}
|
||||
|
||||
function updateTsConfig(options: NormalizedSchema): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const projectConfig = getProjectConfig(host, options.name);
|
||||
return updateJsonInTree(`${projectConfig.root}/tsconfig.json`, json => {
|
||||
json.compilerOptions.target = options.target;
|
||||
return json;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function addProject(options: NormalizedSchema): Rule {
|
||||
if (!options.publishable) {
|
||||
return noop();
|
||||
}
|
||||
|
||||
return updateWorkspaceInTree(json => {
|
||||
const architect = json.projects[options.name].architect;
|
||||
if (architect) {
|
||||
architect.build = {
|
||||
builder: '@nrwl/node:package',
|
||||
options: {
|
||||
outputPath: `dist/libs/${options.projectDirectory}`,
|
||||
tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
|
||||
packageJson: `${options.projectRoot}/package.json`,
|
||||
main: `${options.projectRoot}/src/index.ts`,
|
||||
assets: [`${options.projectRoot}/*.md`]
|
||||
}
|
||||
};
|
||||
}
|
||||
return json;
|
||||
});
|
||||
}
|
||||
26
packages/nest/src/schematics/library/schema.d.ts
vendored
Normal file
26
packages/nest/src/schematics/library/schema.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { Linter } from '@nrwl/workspace';
|
||||
|
||||
export interface Schema {
|
||||
name: string;
|
||||
directory?: string;
|
||||
skipTsConfig: boolean;
|
||||
skipFormat: boolean;
|
||||
tags?: string;
|
||||
unitTestRunner: 'jest' | 'none';
|
||||
linter: Linter;
|
||||
publishable?: boolean;
|
||||
global?: boolean;
|
||||
service?: boolean;
|
||||
controller?: boolean;
|
||||
target?:
|
||||
| 'es5'
|
||||
| 'es6'
|
||||
| 'esnext'
|
||||
| 'es2015'
|
||||
| 'es2016'
|
||||
| 'es2017'
|
||||
| 'es2018'
|
||||
| 'es2019'
|
||||
| 'es2020';
|
||||
testEnvironment: 'jsdom' | 'node';
|
||||
}
|
||||
97
packages/nest/src/schematics/library/schema.json
Normal file
97
packages/nest/src/schematics/library/schema.json
Normal file
@ -0,0 +1,97 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"id": "NxNestLibrary",
|
||||
"title": "Create a Nest Library for Nx",
|
||||
"type": "object",
|
||||
"examples": [
|
||||
{
|
||||
"command": "g lib mylib --directory=myapp",
|
||||
"description": "Generate libs/myapp/mylib"
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Library name",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-prompt": "What name would you like to use for the library?"
|
||||
},
|
||||
"directory": {
|
||||
"type": "string",
|
||||
"description": "A directory where the app is placed",
|
||||
"alias": "d"
|
||||
},
|
||||
"linter": {
|
||||
"description": "The tool to use for running lint checks.",
|
||||
"type": "string",
|
||||
"enum": ["eslint", "tslint"],
|
||||
"default": "tslint"
|
||||
},
|
||||
"unitTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["jest", "none"],
|
||||
"description": "Test runner to use for unit tests",
|
||||
"default": "jest"
|
||||
},
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"description": "Add tags to the library (used for linting)",
|
||||
"alias": "t"
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"skipTsConfig": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Do not update tsconfig.json for development experience."
|
||||
},
|
||||
"publishable": {
|
||||
"type": "boolean",
|
||||
"description": "Create a publishable library. A \"build\" architect will be added for this project the workspace configuration."
|
||||
},
|
||||
"global": {
|
||||
"type": "boolean",
|
||||
"description": "Add the Global decorator to the generated module.",
|
||||
"default": false
|
||||
},
|
||||
"service": {
|
||||
"type": "boolean",
|
||||
"description": "Include a service with the library.",
|
||||
"default": false
|
||||
},
|
||||
"controller": {
|
||||
"type": "boolean",
|
||||
"description": "Include a controller with the library",
|
||||
"default": false
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"description": "The test environment for jest, for node applications this should stay as node unless doing DOM testing.",
|
||||
"default": "node"
|
||||
},
|
||||
"target": {
|
||||
"type": "string",
|
||||
"description": "The es target, Nest suggest using es6 or higher.",
|
||||
"default": "es6",
|
||||
"enum": [
|
||||
"es5",
|
||||
"es6",
|
||||
"esnext",
|
||||
"es2015",
|
||||
"es2016",
|
||||
"es2017",
|
||||
"es2018",
|
||||
"es2019",
|
||||
"es2020"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
}
|
||||
@ -9,4 +9,5 @@ export interface Schema {
|
||||
unitTestRunner: 'jest' | 'none';
|
||||
linter: Linter;
|
||||
publishable?: boolean;
|
||||
testEnvironment: 'jsdom' | 'node';
|
||||
}
|
||||
|
||||
@ -54,6 +54,12 @@
|
||||
"publishable": {
|
||||
"type": "boolean",
|
||||
"description": "Create a publishable library. A \"build\" architect will be added for this project the workspace configuration."
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"description": "The test environment to use if unitTestRunner is set to jest",
|
||||
"default": "jsdom"
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
|
||||
@ -100,7 +100,8 @@ export default function(schema: Schema): Rule {
|
||||
project: options.name,
|
||||
setupFile: 'none',
|
||||
supportTsx: true,
|
||||
skipSerializers: true
|
||||
skipSerializers: true,
|
||||
testEnvironment: options.testEnvironment
|
||||
})
|
||||
: noop(),
|
||||
formatFiles(options)
|
||||
|
||||
@ -9,4 +9,5 @@ export interface Schema {
|
||||
simpleModuleName: boolean;
|
||||
unitTestRunner: 'jest' | 'none';
|
||||
linter: Linter;
|
||||
testEnvironment: 'jsdom' | 'node';
|
||||
}
|
||||
|
||||
@ -48,6 +48,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Do not update tsconfig.json for development experience."
|
||||
},
|
||||
"testEnvironment": {
|
||||
"type": "string",
|
||||
"enum": ["jsdom", "node"],
|
||||
"description": "The test environment to use if unitTestRunner is set to jest",
|
||||
"default": "jsdom"
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
|
||||
@ -253,7 +253,10 @@ function setDefaultLinter(linter: string) {
|
||||
plugin: { linter }
|
||||
};
|
||||
json.schematics['@nrwl/nest'] = { application: { linter } };
|
||||
json.schematics['@nrwl/express'] = { application: { linter } };
|
||||
json.schematics['@nrwl/express'] = {
|
||||
application: { linter },
|
||||
library: { linter }
|
||||
};
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ const gitMessage = require('child_process')
|
||||
.toString()
|
||||
.trim();
|
||||
|
||||
const matchCommit = /(chore|feat|fix|cleanup|docs)\((angular|bazel|core|docs|nextjs|linter|node|nx-plugin|react|storybook|testing|repo|misc)\):\s(([a-z0-9:\-\s])+)/g.test(
|
||||
const matchCommit = /(chore|feat|fix|cleanup|docs)\((angular|bazel|core|docs|nextjs|nest|linter|node|nx-plugin|react|storybook|testing|repo|misc)\):\s(([a-z0-9:\-\s])+)/g.test(
|
||||
gitMessage
|
||||
);
|
||||
const matchRevert = /Revert/gi.test(gitMessage);
|
||||
@ -27,7 +27,7 @@ if (exitCode === 0) {
|
||||
console.log('\n');
|
||||
console.log('possible types: chore|build|feat|fix|cleanup|docs');
|
||||
console.log(
|
||||
'possible scopes: angular|bazel|core|docs|nextjs|linter|node|react|storybook|testing|repo|misc (if unsure use "core")'
|
||||
'possible scopes: angular|bazel|core|docs|nextjs|nest|linter|linter|node|react|storybook|testing|repo|misc (if unsure use "core")'
|
||||
);
|
||||
console.log(
|
||||
'\nEXAMPLE: \n' +
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user