feat(nx): add presets to simplify the creation of workspaces with angular and fullstack apps
This commit is contained in:
parent
a6fd16d00e
commit
7f2c16f3a3
@ -6,3 +6,4 @@ node_modules
|
|||||||
packages/schematics/src/collection/**/files/*.json
|
packages/schematics/src/collection/**/files/*.json
|
||||||
/.vscode
|
/.vscode
|
||||||
/.idea
|
/.idea
|
||||||
|
/.github
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { toClassName } from '@nrwl/schematics/src/utils/name-utils';
|
import { toClassName } from '@nrwl/schematics/src/utils/name-utils';
|
||||||
|
|
||||||
describe('Nrwl Workspace', () => {
|
describe('Nrwl Workspace', () => {
|
||||||
fit('should work', async () => {
|
it('should work', async () => {
|
||||||
ensureProject();
|
ensureProject();
|
||||||
const myapp = uniq('myapp');
|
const myapp = uniq('myapp');
|
||||||
const mylib = uniq('mylib');
|
const mylib = uniq('mylib');
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import * as http from 'http';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as treeKill from 'tree-kill';
|
import * as treeKill from 'tree-kill';
|
||||||
|
|
||||||
function getData() {
|
function getData(): Promise<any> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
http.get('http://localhost:3333/api', res => {
|
http.get('http://localhost:3333/api', res => {
|
||||||
expect(res.statusCode).toEqual(200);
|
expect(res.statusCode).toEqual(200);
|
||||||
@ -23,7 +23,7 @@ function getData() {
|
|||||||
data += chunk;
|
data += chunk;
|
||||||
});
|
});
|
||||||
res.once('end', () => {
|
res.once('end', () => {
|
||||||
resolve(data);
|
resolve(JSON.parse(data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -77,7 +77,7 @@ describe('Node Applications', () => {
|
|||||||
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
|
|
||||||
expect(result).toEqual(`Welcome to ${nodeapp}!`);
|
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
||||||
treeKill(server.pid, 'SIGTERM', err => {
|
treeKill(server.pid, 'SIGTERM', err => {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
resolve();
|
resolve();
|
||||||
@ -118,7 +118,7 @@ describe('Node Applications', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
expect(result).toEqual(`Welcome to ${nodeapp}!`);
|
expect(result.message).toEqual(`Welcome to ${nodeapp}!`);
|
||||||
treeKill(process.pid, 'SIGTERM', err => {
|
treeKill(process.pid, 'SIGTERM', err => {
|
||||||
expect(collectedOutput.startsWith('DONE')).toBeTruthy();
|
expect(collectedOutput.startsWith('DONE')).toBeTruthy();
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
@ -164,7 +164,7 @@ describe('Node Applications', () => {
|
|||||||
if (message.includes('Listening at http://localhost:3333')) {
|
if (message.includes('Listening at http://localhost:3333')) {
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
|
|
||||||
expect(result).toEqual(`Welcome to ${nestapp}!`);
|
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
||||||
treeKill(server.pid, 'SIGTERM', err => {
|
treeKill(server.pid, 'SIGTERM', err => {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
resolve();
|
resolve();
|
||||||
@ -186,7 +186,7 @@ describe('Node Applications', () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
expect(result).toEqual(`Welcome to ${nestapp}!`);
|
expect(result.message).toEqual(`Welcome to ${nestapp}!`);
|
||||||
treeKill(process.pid, 'SIGTERM', err => {
|
treeKill(process.pid, 'SIGTERM', err => {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
done();
|
done();
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
"tmp": "0.0.33",
|
"tmp": "0.0.33",
|
||||||
"viz.js": "^1.8.1",
|
"viz.js": "^1.8.1",
|
||||||
"yargs-parser": "10.0.0",
|
"yargs-parser": "10.0.0",
|
||||||
"yargs": "^11.0.0"
|
"yargs": "^11.0.0",
|
||||||
|
"prettier": "1.15.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,14 @@
|
|||||||
"ng-new": {
|
"ng-new": {
|
||||||
"factory": "./collection/ng-new",
|
"factory": "./collection/ng-new",
|
||||||
"schema": "./collection/ng-new/schema.json",
|
"schema": "./collection/ng-new/schema.json",
|
||||||
"description": "Create an empty workspace"
|
"description": "Create a workspace"
|
||||||
|
},
|
||||||
|
|
||||||
|
"workspace": {
|
||||||
|
"factory": "./collection/workspace",
|
||||||
|
"schema": "./collection/workspace/schema.json",
|
||||||
|
"description": "Create an empty workspace",
|
||||||
|
"hidden": true
|
||||||
},
|
},
|
||||||
|
|
||||||
"application": {
|
"application": {
|
||||||
|
|||||||
@ -1,57 +1,200 @@
|
|||||||
import {
|
import {
|
||||||
apply,
|
|
||||||
branchAndMerge,
|
|
||||||
chain,
|
chain,
|
||||||
mergeWith,
|
move,
|
||||||
|
noop,
|
||||||
Rule,
|
Rule,
|
||||||
|
schematic,
|
||||||
SchematicContext,
|
SchematicContext,
|
||||||
template,
|
Tree
|
||||||
Tree,
|
|
||||||
url
|
|
||||||
} from '@angular-devkit/schematics';
|
} from '@angular-devkit/schematics';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
import { strings } from '@angular-devkit/core';
|
import { addImportToModule, insert } from '../../utils/ast-utils';
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
import { insertImport } from '@schematics/angular/utility/ast-utils';
|
||||||
import {
|
import {
|
||||||
NodePackageInstallTask,
|
NodePackageInstallTask,
|
||||||
RepositoryInitializerTask
|
RepositoryInitializerTask
|
||||||
} from '@angular-devkit/schematics/tasks';
|
} from '@angular-devkit/schematics/tasks';
|
||||||
import { libVersions } from '../../lib-versions';
|
|
||||||
import { DEFAULT_NRWL_PRETTIER_CONFIG } from '../../utils/common';
|
|
||||||
|
|
||||||
export default function(options: Schema): Rule {
|
export default function(options: Schema): Rule {
|
||||||
if (!options.name) {
|
|
||||||
throw new Error(`Invalid options, "name" is required.`);
|
|
||||||
}
|
|
||||||
if (!options.directory) {
|
if (!options.directory) {
|
||||||
options.directory = options.name;
|
options.directory = options.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const workspaceOpts = { ...options, preset: undefined };
|
||||||
return (host: Tree, context: SchematicContext) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
addTasks(options, context);
|
return chain([
|
||||||
const npmScope = options.npmScope ? options.npmScope : options.name;
|
schematic('workspace', workspaceOpts),
|
||||||
const templateSource = apply(url('./files'), [
|
createPreset(options),
|
||||||
template({
|
move('/', options.directory),
|
||||||
utils: strings,
|
addTasks(options)
|
||||||
dot: '.',
|
])(Tree.empty(), context);
|
||||||
tmpl: '',
|
};
|
||||||
...libVersions,
|
}
|
||||||
...(options as object),
|
|
||||||
npmScope,
|
function createPreset(options: Schema): Rule {
|
||||||
defaultNrwlPrettierConfig: JSON.stringify(
|
if (options.preset === 'empty') {
|
||||||
DEFAULT_NRWL_PRETTIER_CONFIG,
|
return noop();
|
||||||
null,
|
} else if (options.preset === 'angular') {
|
||||||
2
|
return chain([
|
||||||
|
schematic(
|
||||||
|
'application',
|
||||||
|
{ name: options.name, style: options.style },
|
||||||
|
{ interactive: false }
|
||||||
)
|
)
|
||||||
})
|
|
||||||
]);
|
]);
|
||||||
return chain([branchAndMerge(chain([mergeWith(templateSource)]))])(
|
} else {
|
||||||
host,
|
return chain([
|
||||||
context
|
schematic(
|
||||||
|
'application',
|
||||||
|
{ name: options.name, style: options.style },
|
||||||
|
{ interactive: false }
|
||||||
|
),
|
||||||
|
schematic(
|
||||||
|
'node-application',
|
||||||
|
{
|
||||||
|
name: 'api',
|
||||||
|
frontendProject: options.name
|
||||||
|
},
|
||||||
|
{ interactive: false }
|
||||||
|
),
|
||||||
|
schematic(
|
||||||
|
'library',
|
||||||
|
{ name: 'api-interface', framework: 'none' },
|
||||||
|
{ interactive: false }
|
||||||
|
),
|
||||||
|
connectFrontendAndApi(options)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectFrontendAndApi(options: Schema) {
|
||||||
|
return (host: Tree) => {
|
||||||
|
host.create(
|
||||||
|
'libs/api-interface/src/lib/interfaces.ts',
|
||||||
|
`export interface Message { message: string }`
|
||||||
|
);
|
||||||
|
host.overwrite(
|
||||||
|
'libs/api-interface/src/index.ts',
|
||||||
|
`export * from './lib/interfaces';`
|
||||||
|
);
|
||||||
|
|
||||||
|
const modulePath = `apps/${options.name}/src/app/app.module.ts`;
|
||||||
|
const moduleFile = ts.createSourceFile(
|
||||||
|
modulePath,
|
||||||
|
host.read(modulePath).toString(),
|
||||||
|
ts.ScriptTarget.Latest,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
insert(host, modulePath, [
|
||||||
|
insertImport(
|
||||||
|
moduleFile,
|
||||||
|
modulePath,
|
||||||
|
'HttpClientModule',
|
||||||
|
`@angular/common/http`
|
||||||
|
),
|
||||||
|
...addImportToModule(
|
||||||
|
moduleFile,
|
||||||
|
`@angular/common/http`,
|
||||||
|
`HttpClientModule`
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
|
const scope = options.npmScope ? options.npmScope : options.name;
|
||||||
|
const style = options.style ? options.style : 'css';
|
||||||
|
host.overwrite(
|
||||||
|
`apps/${options.name}/src/app/app.component.ts`,
|
||||||
|
`import { Component } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Message } from '@${scope}/api-interface';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: '${scope}-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.${style}']
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
hello$ = this.http.get<Message>('/api/hello')
|
||||||
|
constructor(private http: HttpClient) {}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
host.overwrite(
|
||||||
|
`apps/${options.name}/src/app/app.component.spec.ts`,
|
||||||
|
`import { Component } from '@angular/core';
|
||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [AppComponent],
|
||||||
|
imports: [HttpClientModule]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create the app', () => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
host.overwrite(
|
||||||
|
`apps/${options.name}/src/app/app.component.html`,
|
||||||
|
`<div style="text-align:center">
|
||||||
|
<h1>Welcome to ${options.name}!</h1>
|
||||||
|
<img
|
||||||
|
width="300"
|
||||||
|
src="https://raw.githubusercontent.com/nrwl/nx/master/nx-logo.png"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>Message: {{ (hello$|async)|json }}</div>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
host.overwrite(
|
||||||
|
`apps/api/src/app/app.controller.ts`,
|
||||||
|
`import { Controller, Get } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { Message } from '@${scope}/api-interface';
|
||||||
|
|
||||||
|
import { AppService } from './app.service';
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
export class AppController {
|
||||||
|
constructor(private readonly appService: AppService) {}
|
||||||
|
|
||||||
|
@Get('hello')
|
||||||
|
getData(): Message {
|
||||||
|
return this.appService.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
host.overwrite(
|
||||||
|
`apps/api/src/app/app.service.ts`,
|
||||||
|
`import { Injectable } from '@nestjs/common';
|
||||||
|
import { Message } from '@${scope}/api-interface';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AppService {
|
||||||
|
getData(): Message {
|
||||||
|
return { message: 'Welcome to api!' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTasks(options: Schema, context: SchematicContext) {
|
function addTasks(options: Schema) {
|
||||||
|
return (host: Tree, context: SchematicContext) => {
|
||||||
let packageTask;
|
let packageTask;
|
||||||
if (!options.skipInstall) {
|
if (!options.skipInstall) {
|
||||||
packageTask = context.addTask(
|
packageTask = context.addTask(
|
||||||
@ -70,4 +213,5 @@ function addTasks(options: Schema, context: SchematicContext) {
|
|||||||
packageTask ? [packageTask] : []
|
packageTask ? [packageTask] : []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { Tree } from '@angular-devkit/schematics';
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
import { readJsonInTree } from '../../utils/ast-utils';
|
|
||||||
import { NxJson } from '../../command-line/shared';
|
|
||||||
|
|
||||||
describe('app', () => {
|
describe('ng-new', () => {
|
||||||
const schematicRunner = new SchematicTestRunner(
|
const schematicRunner = new SchematicTestRunner(
|
||||||
'@nrwl/schematics',
|
'@nrwl/schematics',
|
||||||
path.join(__dirname, '../../collection.json')
|
path.join(__dirname, '../../collection.json')
|
||||||
@ -16,80 +14,29 @@ describe('app', () => {
|
|||||||
projectTree = Tree.empty();
|
projectTree = Tree.empty();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update angular.json', () => {
|
it('should create files (preset = angular)', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ng-new',
|
'ng-new',
|
||||||
{ name: 'proj' },
|
{ name: 'proj', preset: 'angular' },
|
||||||
projectTree
|
projectTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
expect(tree.exists('/proj/apps/proj/src/app/app.component.ts')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create files', () => {
|
it('should create files (preset = fullstack)', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ng-new',
|
'ng-new',
|
||||||
{ name: 'proj' },
|
{ name: 'proj', preset: 'fullstack' },
|
||||||
projectTree
|
projectTree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
expect(tree.exists('/proj/apps/proj/src/app/app.component.ts')).toBe(true);
|
||||||
|
expect(tree.exists('/proj/apps/api/src/app/app.controller.ts')).toBe(true);
|
||||||
|
expect(tree.exists('/proj/libs/api-interface/src/lib/interfaces.ts')).toBe(
|
||||||
|
true
|
||||||
);
|
);
|
||||||
expect(tree.exists('/proj/nx.json')).toBe(true);
|
|
||||||
expect(tree.exists('/proj/angular.json')).toBe(true);
|
|
||||||
expect(tree.exists('/proj/.prettierrc')).toBe(true);
|
|
||||||
expect(tree.exists('/proj/.prettierignore')).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create nx.json', () => {
|
|
||||||
const tree = schematicRunner.runSchematic(
|
|
||||||
'ng-new',
|
|
||||||
{ name: 'proj' },
|
|
||||||
projectTree
|
|
||||||
);
|
|
||||||
const nxJson = readJsonInTree<NxJson>(tree, '/proj/nx.json');
|
|
||||||
expect(nxJson).toEqual({
|
|
||||||
npmScope: 'proj',
|
|
||||||
implicitDependencies: {
|
|
||||||
'angular.json': '*',
|
|
||||||
'package.json': '*',
|
|
||||||
'tsconfig.json': '*',
|
|
||||||
'tslint.json': '*',
|
|
||||||
'nx.json': '*'
|
|
||||||
},
|
|
||||||
projects: {}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should recommend vscode extensions', () => {
|
|
||||||
const tree = schematicRunner.runSchematic(
|
|
||||||
'ng-new',
|
|
||||||
{ name: 'proj' },
|
|
||||||
projectTree
|
|
||||||
);
|
|
||||||
const recommendations = readJsonInTree<{ recommendations: string[] }>(
|
|
||||||
tree,
|
|
||||||
'/proj/.vscode/extensions.json'
|
|
||||||
).recommendations;
|
|
||||||
|
|
||||||
expect(recommendations).toEqual([
|
|
||||||
'nrwl.angular-console',
|
|
||||||
'angular.ng-template',
|
|
||||||
'ms-vscode.vscode-typescript-tslint-plugin',
|
|
||||||
'esbenp.prettier-vscode'
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should configure the project to use style argument', () => {
|
|
||||||
const tree = schematicRunner.runSchematic(
|
|
||||||
'ng-new',
|
|
||||||
{ name: 'proj', style: 'scss' },
|
|
||||||
projectTree
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
JSON.parse(tree.readContent('/proj/angular.json')).schematics
|
|
||||||
).toEqual({
|
|
||||||
'@nrwl/schematics:application': {
|
|
||||||
style: 'scss'
|
|
||||||
},
|
|
||||||
'@nrwl/schematics:library': {
|
|
||||||
style: 'scss'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { UnitTestRunner } from '../../utils/test-runners';
|
|
||||||
|
|
||||||
export interface Schema {
|
export interface Schema {
|
||||||
directory: string;
|
directory: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -7,5 +5,6 @@ export interface Schema {
|
|||||||
skipInstall?: boolean;
|
skipInstall?: boolean;
|
||||||
skipGit?: boolean;
|
skipGit?: boolean;
|
||||||
style?: string;
|
style?: string;
|
||||||
|
preset: 'empty' | 'angular' | 'fullstack';
|
||||||
commit?: { name: string; email: string; message?: string };
|
commit?: { name: string; email: string; message?: string };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,6 +74,29 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default": true
|
"default": true
|
||||||
|
},
|
||||||
|
"preset": {
|
||||||
|
"description": "What to create in the new workspace",
|
||||||
|
"enum": ["empty", "angular", "fullstack"],
|
||||||
|
"default": "empty",
|
||||||
|
"x-prompt": {
|
||||||
|
"message": "What to create in the new workspace (You can create other applications and libraries at any point using 'ng g')",
|
||||||
|
"type": "list",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"value": "empty",
|
||||||
|
"label": "empty [an empty workspace]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "angular",
|
||||||
|
"label": "angular [a workspace with a single Angular application]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "fullstack",
|
||||||
|
"label": "full-stack [a workspace with a full stack application (NestJS + Angular)]"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import * as express from 'express';
|
|||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
app.get('/api', (req, res) => {
|
app.get('/api', (req, res) => {
|
||||||
res.send(`Welcome to <%= name %>!`);
|
res.send({message: `Welcome to <%= name %>!`});
|
||||||
});
|
});
|
||||||
|
|
||||||
const port = process.env.port || 3333;
|
const port = process.env.port || 3333;
|
||||||
|
|||||||
@ -16,7 +16,7 @@ describe('AppController', () => {
|
|||||||
describe('getData', () => {
|
describe('getData', () => {
|
||||||
it('should return "Welcome to <%= name %>!"', () => {
|
it('should return "Welcome to <%= name %>!"', () => {
|
||||||
const appController = app.get<AppController>(AppController);
|
const appController = app.get<AppController>(AppController);
|
||||||
expect(appController.getData()).toBe('Welcome to <%= name %>!');
|
expect(appController.getData()).toEqual({message: 'Welcome to <%= name %>!'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export class AppController {
|
|||||||
constructor(private readonly appService: AppService) {}
|
constructor(private readonly appService: AppService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
getData(): string {
|
getData() {
|
||||||
return this.appService.getData();
|
return this.appService.getData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ describe('AppService', () => {
|
|||||||
|
|
||||||
describe('getData', () => {
|
describe('getData', () => {
|
||||||
it('should return "Welcome to <%= name %>!"', () => {
|
it('should return "Welcome to <%= name %>!"', () => {
|
||||||
expect(service.getData()).toBe('Welcome to <%= name %>!');
|
expect(service.getData()).toEqual({message: 'Welcome to <%= name %>!'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
getData(): string {
|
getData(): { message: string } {
|
||||||
return 'Welcome to <%= name %>!';
|
return ({ message: 'Welcome to <%= name %>!' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ describe('node-app', () => {
|
|||||||
'const app = express();'
|
'const app = express();'
|
||||||
);
|
);
|
||||||
expect(tree.readContent('apps/my-node-app/src/main.ts')).toContain(
|
expect(tree.readContent('apps/my-node-app/src/main.ts')).toContain(
|
||||||
'res.send(`Welcome to my-node-app!`);'
|
'res.send({message: `Welcome to my-node-app!`});'
|
||||||
);
|
);
|
||||||
|
|
||||||
const tsconfig = readJsonInTree(tree, 'apps/my-node-app/tsconfig.json');
|
const tsconfig = readJsonInTree(tree, 'apps/my-node-app/tsconfig.json');
|
||||||
|
|||||||
@ -5,11 +5,7 @@
|
|||||||
"rootDir": ".",
|
"rootDir": ".",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"types": [
|
"types": ["node"]
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["**/*.ts"]
|
||||||
"**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
44
packages/schematics/src/collection/workspace/index.ts
Normal file
44
packages/schematics/src/collection/workspace/index.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import {
|
||||||
|
apply,
|
||||||
|
branchAndMerge,
|
||||||
|
chain,
|
||||||
|
mergeWith,
|
||||||
|
Rule,
|
||||||
|
SchematicContext,
|
||||||
|
template,
|
||||||
|
Tree,
|
||||||
|
url
|
||||||
|
} from '@angular-devkit/schematics';
|
||||||
|
import { Schema } from './schema';
|
||||||
|
import { strings } from '@angular-devkit/core';
|
||||||
|
import { libVersions } from '../../lib-versions';
|
||||||
|
import { DEFAULT_NRWL_PRETTIER_CONFIG } from '../../utils/common';
|
||||||
|
|
||||||
|
export default function(options: Schema): Rule {
|
||||||
|
if (!options.name) {
|
||||||
|
throw new Error(`Invalid options, "name" is required.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (host: Tree, context: SchematicContext) => {
|
||||||
|
const npmScope = options.npmScope ? options.npmScope : options.name;
|
||||||
|
const templateSource = apply(url('./files'), [
|
||||||
|
template({
|
||||||
|
utils: strings,
|
||||||
|
dot: '.',
|
||||||
|
tmpl: '',
|
||||||
|
...libVersions,
|
||||||
|
...(options as object),
|
||||||
|
npmScope,
|
||||||
|
defaultNrwlPrettierConfig: JSON.stringify(
|
||||||
|
DEFAULT_NRWL_PRETTIER_CONFIG,
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
return chain([branchAndMerge(chain([mergeWith(templateSource)]))])(
|
||||||
|
host,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
11
packages/schematics/src/collection/workspace/schema.d.ts
vendored
Normal file
11
packages/schematics/src/collection/workspace/schema.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { UnitTestRunner } from '../../utils/test-runners';
|
||||||
|
|
||||||
|
export interface Schema {
|
||||||
|
directory: string;
|
||||||
|
name: string;
|
||||||
|
npmScope?: string;
|
||||||
|
skipInstall?: boolean;
|
||||||
|
skipGit?: boolean;
|
||||||
|
style?: string;
|
||||||
|
commit?: { name: string; email: string; message?: string };
|
||||||
|
}
|
||||||
79
packages/schematics/src/collection/workspace/schema.json
Normal file
79
packages/schematics/src/collection/workspace/schema.json
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"id": "SchematicsNxNgNew",
|
||||||
|
"title": "Create an empty workspace",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"description": "The name of the workspace.",
|
||||||
|
"type": "string",
|
||||||
|
"format": "html-selector",
|
||||||
|
"$default": {
|
||||||
|
"$source": "argv",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
"x-prompt": "What name would you like to use for the workspace?"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"description": "The file extension to be used for style files.",
|
||||||
|
"type": "string",
|
||||||
|
"default": "css",
|
||||||
|
"x-prompt": {
|
||||||
|
"message": "Which stylesheet format would you like to use?",
|
||||||
|
"type": "list",
|
||||||
|
"items": [
|
||||||
|
{ "value": "css", "label": "CSS" },
|
||||||
|
{ "value": "scss", "label": "SCSS [ http://sass-lang.com ]" },
|
||||||
|
{ "value": "sass", "label": "SASS [ http://sass-lang.com ]" },
|
||||||
|
{ "value": "less", "label": "LESS [ http://lesscss.org ]" },
|
||||||
|
{ "value": "styl", "label": "Stylus [ http://stylus-lang.com ]" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"directory": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "path",
|
||||||
|
"description": "The directory name to create the workspace in.",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"npmScope": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Npm scope for importing libs.",
|
||||||
|
"x-prompt": "What is the npm scope you would like to use for your Nx Workspace?"
|
||||||
|
},
|
||||||
|
"skipInstall": {
|
||||||
|
"description": "Skip installing dependency packages.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"skipGit": {
|
||||||
|
"description": "Skip initializing a git repository.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"alias": "g"
|
||||||
|
},
|
||||||
|
"commit": {
|
||||||
|
"description": "Initial repository commit information.",
|
||||||
|
"oneOf": [
|
||||||
|
{ "type": "boolean" },
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name", "email"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
|
import { readJsonInTree } from '../../utils/ast-utils';
|
||||||
|
import { NxJson } from '../../command-line/shared';
|
||||||
|
|
||||||
|
describe('workspace', () => {
|
||||||
|
const schematicRunner = new SchematicTestRunner(
|
||||||
|
'@nrwl/schematics',
|
||||||
|
path.join(__dirname, '../../collection.json')
|
||||||
|
);
|
||||||
|
|
||||||
|
let projectTree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
projectTree = Tree.empty();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update angular.json', () => {
|
||||||
|
const tree = schematicRunner.runSchematic(
|
||||||
|
'workspace',
|
||||||
|
{ name: 'proj' },
|
||||||
|
projectTree
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create files', () => {
|
||||||
|
const tree = schematicRunner.runSchematic(
|
||||||
|
'workspace',
|
||||||
|
{ name: 'proj' },
|
||||||
|
projectTree
|
||||||
|
);
|
||||||
|
expect(tree.exists('/nx.json')).toBe(true);
|
||||||
|
expect(tree.exists('/angular.json')).toBe(true);
|
||||||
|
expect(tree.exists('/.prettierrc')).toBe(true);
|
||||||
|
expect(tree.exists('/.prettierignore')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create nx.json', () => {
|
||||||
|
const tree = schematicRunner.runSchematic(
|
||||||
|
'workspace',
|
||||||
|
{ name: 'proj' },
|
||||||
|
projectTree
|
||||||
|
);
|
||||||
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
|
expect(nxJson).toEqual({
|
||||||
|
npmScope: 'proj',
|
||||||
|
implicitDependencies: {
|
||||||
|
'angular.json': '*',
|
||||||
|
'package.json': '*',
|
||||||
|
'tsconfig.json': '*',
|
||||||
|
'tslint.json': '*',
|
||||||
|
'nx.json': '*'
|
||||||
|
},
|
||||||
|
projects: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recommend vscode extensions', () => {
|
||||||
|
const tree = schematicRunner.runSchematic(
|
||||||
|
'workspace',
|
||||||
|
{ name: 'proj' },
|
||||||
|
projectTree
|
||||||
|
);
|
||||||
|
const recommendations = readJsonInTree<{ recommendations: string[] }>(
|
||||||
|
tree,
|
||||||
|
'/.vscode/extensions.json'
|
||||||
|
).recommendations;
|
||||||
|
|
||||||
|
expect(recommendations).toEqual([
|
||||||
|
'nrwl.angular-console',
|
||||||
|
'angular.ng-template',
|
||||||
|
'ms-vscode.vscode-typescript-tslint-plugin',
|
||||||
|
'esbenp.prettier-vscode'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should configure the project to use style argument', () => {
|
||||||
|
const tree = schematicRunner.runSchematic(
|
||||||
|
'workspace',
|
||||||
|
{ name: 'proj', style: 'scss' },
|
||||||
|
projectTree
|
||||||
|
);
|
||||||
|
expect(JSON.parse(tree.readContent('/angular.json')).schematics).toEqual({
|
||||||
|
'@nrwl/schematics:application': {
|
||||||
|
style: 'scss'
|
||||||
|
},
|
||||||
|
'@nrwl/schematics:library': {
|
||||||
|
style: 'scss'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
50
yarn.lock
50
yarn.lock
@ -2,7 +2,7 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@angular-devkit/architect@0.13.1", "@angular-devkit/architect@~0.13.1":
|
"@angular-devkit/architect@0.13.1":
|
||||||
version "0.13.1"
|
version "0.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.13.1.tgz#39597ce94f72d89bdd89ee567cb937cff4c13b98"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.13.1.tgz#39597ce94f72d89bdd89ee567cb937cff4c13b98"
|
||||||
integrity sha512-QDmIbqde75ZZSEFbw6Q6kQWq4cY6C7D67yujXw6XTyubDNAs1tyXJyxTIB8vjSlEKwRizTTDd/B0ZXVcke3Mvw==
|
integrity sha512-QDmIbqde75ZZSEFbw6Q6kQWq4cY6C7D67yujXw6XTyubDNAs1tyXJyxTIB8vjSlEKwRizTTDd/B0ZXVcke3Mvw==
|
||||||
@ -10,7 +10,7 @@
|
|||||||
"@angular-devkit/core" "7.3.1"
|
"@angular-devkit/core" "7.3.1"
|
||||||
rxjs "6.3.3"
|
rxjs "6.3.3"
|
||||||
|
|
||||||
"@angular-devkit/build-angular@~0.13.1":
|
"@angular-devkit/build-angular@0.13.1":
|
||||||
version "0.13.1"
|
version "0.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.13.1.tgz#369febda48dd40e47a4f0077064e792612a8e1c1"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.13.1.tgz#369febda48dd40e47a4f0077064e792612a8e1c1"
|
||||||
integrity sha512-vkKwMVQ+NNCcVR3HFMffS+Mq4b2afXeUjI+02N38hBuFTppnC83uivUB6Uu2NUk5NTSQA4BnJlG5CbMs6N4QYg==
|
integrity sha512-vkKwMVQ+NNCcVR3HFMffS+Mq4b2afXeUjI+02N38hBuFTppnC83uivUB6Uu2NUk5NTSQA4BnJlG5CbMs6N4QYg==
|
||||||
@ -62,7 +62,7 @@
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
node-sass "4.11.0"
|
node-sass "4.11.0"
|
||||||
|
|
||||||
"@angular-devkit/build-ng-packagr@^0.13.1":
|
"@angular-devkit/build-ng-packagr@0.13.1":
|
||||||
version "0.13.1"
|
version "0.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.13.1.tgz#3508523a039f71ccff1364db553a904e4db2c8ea"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/build-ng-packagr/-/build-ng-packagr-0.13.1.tgz#3508523a039f71ccff1364db553a904e4db2c8ea"
|
||||||
integrity sha512-9qvdNvtlgJ3WDppbzwD9fOQzAsVogBlDeLE5zUH1ap+zcoyZEGjS1BKluiYSJ1u5Q5Nlfb3FSI/D1r9LuDQS/A==
|
integrity sha512-9qvdNvtlgJ3WDppbzwD9fOQzAsVogBlDeLE5zUH1ap+zcoyZEGjS1BKluiYSJ1u5Q5Nlfb3FSI/D1r9LuDQS/A==
|
||||||
@ -82,7 +82,7 @@
|
|||||||
typescript "3.2.4"
|
typescript "3.2.4"
|
||||||
webpack-sources "1.3.0"
|
webpack-sources "1.3.0"
|
||||||
|
|
||||||
"@angular-devkit/build-webpack@0.13.1", "@angular-devkit/build-webpack@~0.13.1":
|
"@angular-devkit/build-webpack@0.13.1":
|
||||||
version "0.13.1"
|
version "0.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.13.1.tgz#98d666765705e9379c9b2e0a3b6dfcd0347a2a32"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.13.1.tgz#98d666765705e9379c9b2e0a3b6dfcd0347a2a32"
|
||||||
integrity sha512-OGwC7bAl3u+w7Glw+OqIrN7OD1BkDXgrWbeQSpKAmsx6VdNPCnI4NPS+JldWNp70LVlE2nQlJUhtEqMVfBMnlg==
|
integrity sha512-OGwC7bAl3u+w7Glw+OqIrN7OD1BkDXgrWbeQSpKAmsx6VdNPCnI4NPS+JldWNp70LVlE2nQlJUhtEqMVfBMnlg==
|
||||||
@ -102,10 +102,10 @@
|
|||||||
rxjs "6.3.3"
|
rxjs "6.3.3"
|
||||||
source-map "0.7.3"
|
source-map "0.7.3"
|
||||||
|
|
||||||
"@angular-devkit/core@7.2.4":
|
"@angular-devkit/core@7.2.2":
|
||||||
version "7.2.4"
|
version "7.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.4.tgz#4464d536f4838e5c61ab4bc1ff6b7f221fd43056"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.2.tgz#f0daf3e24f0ce8105341118f4505c1db4e284ab0"
|
||||||
integrity sha512-XHF59tIHg2qEM1Wd415xhykBLjjfOK6yMB7CjNk1bToUMX2QDT87izJF4y1Vwa0lIw9G0jdgP/4/M/OqXcbYmA==
|
integrity sha512-gDF8iXiPN870WuBMl7bCQ5+Qz5SjGL/qMcvP4hli5hkn+kMAhgG38ligUK1bbhPQUJ+Z/nSOEmyv8gLHO09SZg==
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "6.6.2"
|
ajv "6.6.2"
|
||||||
chokidar "2.0.4"
|
chokidar "2.0.4"
|
||||||
@ -132,12 +132,12 @@
|
|||||||
"@angular-devkit/core" "7.1.2"
|
"@angular-devkit/core" "7.1.2"
|
||||||
rxjs "6.3.3"
|
rxjs "6.3.3"
|
||||||
|
|
||||||
"@angular-devkit/schematics@7.2.4":
|
"@angular-devkit/schematics@7.2.2":
|
||||||
version "7.2.4"
|
version "7.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.2.4.tgz#d92b2b8b9114135806d593ea6a2b376c777354dc"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.2.2.tgz#d8d667684603e1debcc4598d88a254560e787f87"
|
||||||
integrity sha512-ObIDnIxXRpts+Jzs0PQ7JVuK4d5vWEh9K+Ow8nMO5/LmYJQ8/2nMEQo/9lhdKPMiXmhbuvB7qZL5J+cxwwijhw==
|
integrity sha512-3qONTeqe+bUJ967PNDeITuD4F+3huTEs3u89zZLV+yvaxoK9XJlvaRoQXAkNAMUkij37BoFrGgBfGNijserd6A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/core" "7.2.4"
|
"@angular-devkit/core" "7.2.2"
|
||||||
rxjs "6.3.3"
|
rxjs "6.3.3"
|
||||||
|
|
||||||
"@angular-devkit/schematics@7.3.1", "@angular-devkit/schematics@~7.3.1":
|
"@angular-devkit/schematics@7.3.1", "@angular-devkit/schematics@~7.3.1":
|
||||||
@ -148,7 +148,7 @@
|
|||||||
"@angular-devkit/core" "7.3.1"
|
"@angular-devkit/core" "7.3.1"
|
||||||
rxjs "6.3.3"
|
rxjs "6.3.3"
|
||||||
|
|
||||||
"@angular/cli@~7.3.1":
|
"@angular/cli@7.3.1":
|
||||||
version "7.3.1"
|
version "7.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.3.1.tgz#a18acdec84deb03a1fae79cae415bbc8f9c87ffa"
|
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.3.1.tgz#a18acdec84deb03a1fae79cae415bbc8f9c87ffa"
|
||||||
integrity sha512-8EvXYRhTqTaTk5PKv7VZxIWJiyG51R9RC9gtpRFx4bbnurqBHdEUxGMmaRsGT8QDbfvVsWnuakE0eeW1CrfZAQ==
|
integrity sha512-8EvXYRhTqTaTk5PKv7VZxIWJiyG51R9RC9gtpRFx4bbnurqBHdEUxGMmaRsGT8QDbfvVsWnuakE0eeW1CrfZAQ==
|
||||||
@ -461,6 +461,15 @@
|
|||||||
universal-user-agent "^2.0.0"
|
universal-user-agent "^2.0.0"
|
||||||
url-template "^2.0.8"
|
url-template "^2.0.8"
|
||||||
|
|
||||||
|
"@schematics/angular@7.2.2":
|
||||||
|
version "7.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.2.2.tgz#5a466ebbbd7e1fbb13851f26446ec308b822d1dc"
|
||||||
|
integrity sha512-Yonddct1XBG1H5rTikagFTIT2/RhszJnNa2Iz+rvc26ffAl1mmYPB4sQb7gkOaZQSzK6SE7bT2QW32PVjYFoSQ==
|
||||||
|
dependencies:
|
||||||
|
"@angular-devkit/core" "7.2.2"
|
||||||
|
"@angular-devkit/schematics" "7.2.2"
|
||||||
|
typescript "3.2.2"
|
||||||
|
|
||||||
"@schematics/angular@7.3.1":
|
"@schematics/angular@7.3.1":
|
||||||
version "7.3.1"
|
version "7.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.3.1.tgz#6fcd7004210fa9305310c3109c084df5c5521776"
|
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.3.1.tgz#6fcd7004210fa9305310c3109c084df5c5521776"
|
||||||
@ -470,15 +479,6 @@
|
|||||||
"@angular-devkit/schematics" "7.3.1"
|
"@angular-devkit/schematics" "7.3.1"
|
||||||
typescript "3.2.4"
|
typescript "3.2.4"
|
||||||
|
|
||||||
"@schematics/angular@~7.2.2":
|
|
||||||
version "7.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.2.4.tgz#4c3c942e2fd0c32e177602a20f8fa16a88552fca"
|
|
||||||
integrity sha512-aflQwIX4E9tDhp6ZASuQCm8CzxLxdkuOe6qN1FbCxpxMUc9E+iK9jhOjw+Xnl3boJpWHAA+k9JO1sYe3wrh3Ng==
|
|
||||||
dependencies:
|
|
||||||
"@angular-devkit/core" "7.2.4"
|
|
||||||
"@angular-devkit/schematics" "7.2.4"
|
|
||||||
typescript "3.2.2"
|
|
||||||
|
|
||||||
"@schematics/update@0.13.1":
|
"@schematics/update@0.13.1":
|
||||||
version "0.13.1"
|
version "0.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.13.1.tgz#481475aee18b4a9472a06512b2e4d6429af68231"
|
resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.13.1.tgz#481475aee18b4a9472a06512b2e4d6429af68231"
|
||||||
@ -3650,7 +3650,7 @@ cyclist@~0.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
|
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
|
||||||
integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
|
integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=
|
||||||
|
|
||||||
cypress@^3.1.0:
|
cypress@3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.1.0.tgz#b718ba64289b887c7ab7a7f09245d871a4a409ba"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.1.0.tgz#b718ba64289b887c7ab7a7f09245d871a4a409ba"
|
||||||
integrity sha512-UqLbXgHvM8Y6Y+roHrepZMWcyMN5u4KcjpTbJTZi0d5O2Prvtqmnpoky7a4C65q4oRQXeSc6cBZUhxJkhU4pbQ==
|
integrity sha512-UqLbXgHvM8Y6Y+roHrepZMWcyMN5u4KcjpTbJTZi0d5O2Prvtqmnpoky7a4C65q4oRQXeSc6cBZUhxJkhU4pbQ==
|
||||||
@ -12090,7 +12090,7 @@ typedarray@^0.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typescript@3.2.2, typescript@~3.2.2:
|
typescript@3.2.2:
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
|
||||||
integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
|
integrity sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user