fix(schematics): ensure project "style" and "skipTests" options are respected (#15513)

With https://github.com/angular/angular-cli/commit/a12a4e02a4689b5bdbc6e740c0d9865afb55671a, the CLI made the
option naming consistent. Since the default schematic are therefore named differently, we need to update our logic
to work with the old option name and the new option name.

Fixes #15502
This commit is contained in:
Paul Gschwendtner
2019-03-22 18:45:40 +01:00
committed by Andrew Seguin
parent 345cd8c7d0
commit fe6629a519
35 changed files with 161 additions and 98 deletions
+3 -3
View File
@@ -47,8 +47,8 @@
"zone.js": "^0.8.29"
},
"devDependencies": {
"@angular-devkit/core": "7.1.2",
"@angular-devkit/schematics": "7.1.2",
"@angular-devkit/core": "7.3.6",
"@angular-devkit/schematics": "7.3.6",
"@angular/bazel": "8.0.0-beta.6",
"@angular/compiler-cli": "8.0.0-beta.6",
"@angular/http": "8.0.0-beta.6",
@@ -62,7 +62,7 @@
"@bazel/typescript": "0.26.0",
"@firebase/app-types": "^0.3.2",
"@octokit/rest": "^15.9.4",
"@schematics/angular": "7.1.2",
"@schematics/angular": "7.3.6",
"@types/browser-sync": "^0.0.42",
"@types/chalk": "^0.4.31",
"@types/fs-extra": "^4.0.3",
@@ -10,7 +10,7 @@ import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/dr
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`],<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>'],<% } %><% if(!!viewEncapsulation) { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'],<% } %><% if(!!viewEncapsulation) { %>
encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } if (changeDetection !== 'Default') { %>
changeDetection: ChangeDetectionStrategy.<%= changeDetection %>,<% } %>
})
@@ -1,4 +1,7 @@
import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
import {getProjectFromWorkspace} from '@angular/cdk/schematics';
import {getWorkspace} from '@schematics/angular/utility/config';
import {getProject} from '@schematics/angular/utility/project';
import {createTestApp, getFileContent} from '../../testing';
import {Schema} from './schema';
@@ -38,17 +41,34 @@ describe('CDK drag-drop schematic', () => {
expect(moduleContent).toContain('DragDropModule');
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'drag-drop', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'drag-drop', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
it('should respect the deprecated "styleext" option value', () => {
let tree = createTestApp(runner);
const workspace = getWorkspace(tree);
const project = getProjectFromWorkspace(workspace);
// We need to specify the default component options by overwriting
// the existing workspace configuration because passing the "styleext"
// option is no longer supported. Though we want to verify that we
// properly handle old CLI projects which still use the "styleext" option.
project.schematics!['@schematics/angular:component'] = {styleext: 'scss'};
tree.overwrite('angular.json', JSON.stringify(workspace));
tree = runner.runSchematic('drag-drop', baseOptions, tree);
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
it('should not generate invalid stylesheets', () => {
const tree = runner.runSchematic(
'drag-drop', {styleext: 'styl', ...baseOptions}, createTestApp(runner));
'drag-drop', {style: 'styl', ...baseOptions}, createTestApp(runner));
// In this case we expect the schematic to generate a plain "css" file because
// the component schematics are using CSS style templates which are not compatible
@@ -99,10 +119,27 @@ describe('CDK drag-drop schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'drag-drop', {spec: false, ...baseOptions}, createTestApp(runner));
'drag-drop', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
it('should respect the deprecated global "spec" option value', () => {
let tree = createTestApp(runner);
const workspace = getWorkspace(tree);
const project = getProjectFromWorkspace(workspace);
// We need to specify the default component options by overwriting
// the existing workspace configuration because passing the "spec"
// option is no longer supported. Though we want to verify that we
// properly handle old CLI projects which still use the "spec" option.
project.schematics!['@schematics/angular:component'] = {spec: false};
tree.overwrite('angular.json', JSON.stringify(workspace));
tree = runner.runSchematic('drag-drop', baseOptions, tree);
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
@@ -15,7 +15,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
}),
options.skipImport ? noop() : addDragDropModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
+3 -1
View File
@@ -51,7 +51,9 @@ export function addModuleImportToModule(host: Tree, modulePath: string, moduleNa
throw new SchematicsException(`Module not found: ${modulePath}`);
}
const changes = addImportToModule(moduleSource, modulePath, moduleName, src);
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
// than Material. Cast to any to avoid the type assignment failure.
const changes = addImportToModule(moduleSource as any, modulePath, moduleName, src);
const recorder = host.beginUpdate(modulePath);
changes.forEach((change) => {
+16 -8
View File
@@ -22,7 +22,7 @@ import {
url,
} from '@angular-devkit/schematics';
import {FileSystemSchematicContext} from '@angular-devkit/schematics/tools';
import {Schema as ComponentOptions} from '@schematics/angular/component/schema';
import {Schema as ComponentOptions, Style} from '@schematics/angular/component/schema';
import {
addDeclarationToModule,
addEntryComponentToModule,
@@ -72,7 +72,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const classifiedName = strings.classify(`${options.name}Component`);
const declarationChanges = addDeclarationToModule(
source,
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
// than Material. Cast to any to avoid the type assignment failure.
source as any,
modulePath,
classifiedName,
relativePath);
@@ -91,7 +93,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const exportRecorder = host.beginUpdate(modulePath);
const exportChanges = addExportToModule(
source,
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
// than Material. Cast to any to avoid the type assignment failure.
source as any,
modulePath,
strings.classify(`${options.name}Component`),
relativePath);
@@ -110,7 +114,9 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
const entryComponentRecorder = host.beginUpdate(modulePath);
const entryComponentChanges = addEntryComponentToModule(
source,
// TODO: TypeScript version mismatch due to @schematics/angular using a different version
// than Material. Cast to any to avoid the type assignment failure.
source as any,
modulePath,
strings.classify(`${options.name}Component`),
relativePath);
@@ -205,8 +211,10 @@ export function buildComponent(options: ComponentOptions,
// we generate the stylesheets with the "css" extension. This ensures that we don't
// accidentally generate invalid stylesheets (e.g. drag-drop-comp.styl) which will
// break the Angular CLI project. See: https://github.com/angular/material2/issues/15164
if (!supportedCssExtensions.includes(options.styleext!)) {
options.styleext = 'css';
if (!supportedCssExtensions.includes(options.style!)) {
// TODO: Cast is necessary as we can't use the Style enum which has been introduced
// within CLI v7.3.0-rc.0. This would break the schematic for older CLI versions.
options.style = 'css' as Style;
}
// Object that will be used as context for the EJS templates.
@@ -230,8 +238,8 @@ export function buildComponent(options: ComponentOptions,
}
const templateSource = apply(url(schematicFilesUrl), [
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
options.inlineStyle ? filter(path => !path.endsWith('.__styleext__')) : noop(),
options.skipTests ? filter(path => !path.endsWith('.spec.ts')) : noop(),
options.inlineStyle ? filter(path => !path.endsWith('.__style__')) : noop(),
options.inlineTemplate ? filter(path => !path.endsWith('.html')) : noop(),
// Treat the template options as any, because the type definition for the template options
// is made unnecessarily explicit. Every type of object can be used in the EJS template.
+21 -10
View File
@@ -20,11 +20,20 @@ export function getDefaultComponentOptions(project: WorkspaceProject) {
// Note: Not all options which are available when running "ng new" will be stored in the
// workspace config. List of options which will be available in the configuration:
// angular/angular-cli/blob/master/packages/schematics/angular/application/index.ts#L109-L131
let skipTests = getDefaultComponentOption<boolean|null>(project, ['skipTests'], null);
// In case "skipTests" is not set explicitly, also look for the "spec" option. The "spec"
// option has been deprecated but can be still used in older Angular CLI projects.
// See: https://github.com/angular/angular-cli/commit/a12a4e02a4689b5bdbc6e740c0d9865afb55671a
if (skipTests === null) {
skipTests = !getDefaultComponentOption(project, ['spec'], true);
}
return {
styleext: getDefaultComponentOption(project, 'styleext', 'css'),
inlineStyle: getDefaultComponentOption(project, 'inlineStyle', false),
inlineTemplate: getDefaultComponentOption(project, 'inlineTemplate', false),
spec: getDefaultComponentOption(project, 'spec', true),
style: getDefaultComponentOption(project, ['style', 'styleext'], 'css'),
inlineStyle: getDefaultComponentOption(project, ['inlineStyle'], false),
inlineTemplate: getDefaultComponentOption(project, ['inlineTemplate'], false),
skipTests: skipTests,
};
}
@@ -33,13 +42,15 @@ export function getDefaultComponentOptions(project: WorkspaceProject) {
* by looking at the stored schematic options for `@schematics/angular:component` in the
* CLI workspace configuration.
*/
function getDefaultComponentOption<T>(project: WorkspaceProject, optionName: string,
fallbackValue: T): T | null {
if (project.schematics &&
project.schematics['@schematics/angular:component'] &&
project.schematics['@schematics/angular:component'][optionName] != null) {
function getDefaultComponentOption<T>(project: WorkspaceProject, optionNames: string[],
fallbackValue: T): T {
for (let optionName of optionNames) {
if (project.schematics &&
project.schematics['@schematics/angular:component'] &&
project.schematics['@schematics/angular:component'][optionName] != null) {
return project.schematics['@schematics/angular:component'][optionName];
return project.schematics['@schematics/angular:component'][optionName];
}
}
return fallbackValue;
@@ -10,7 +10,7 @@ import { FormBuilder, Validators } from '@angular/forms';
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`]<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>,
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
@@ -45,10 +45,10 @@ describe('Material address-form schematic', () => {
}).toThrowError(/required property 'name'/);
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'address-form', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'address-form', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
@@ -93,10 +93,10 @@ describe('Material address-form schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'address-form', {spec: false, ...baseOptions}, createTestApp(runner));
'address-form', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
@@ -22,7 +22,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
}),
options.skipImport ? noop() : addFormModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
@@ -11,7 +11,7 @@ import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`]<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>,
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
@@ -49,10 +49,10 @@ describe('material-dashboard-schematic', () => {
}).toThrowError(/required property 'name'/);
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'dashboard', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'dashboard', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
@@ -97,10 +97,10 @@ describe('material-dashboard-schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'dashboard', {spec: false, ...baseOptions}, createTestApp(runner));
'dashboard', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
@@ -22,7 +22,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
}),
options.skipImport ? noop() : addNavModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
@@ -12,7 +12,7 @@ import { map } from 'rxjs/operators';
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`]<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>,
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
@@ -51,10 +51,10 @@ describe('material-nav-schematic', () => {
}).toThrowError(/required property 'name'/);
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'nav', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'nav', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
@@ -99,10 +99,10 @@ describe('material-nav-schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'nav', {spec: false, ...baseOptions}, createTestApp(runner));
'nav', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
+1 -1
View File
@@ -22,7 +22,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
}),
options.skipImport ? noop() : addNavModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
@@ -11,7 +11,7 @@ import { <%= classify(name) %>DataSource } from './<%= dasherize(name) %>-dataso
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`]<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>,
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
@@ -58,10 +58,10 @@ describe('material-table-schematic', () => {
}).toThrowError(/required property 'name'/);
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'table', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'table', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
@@ -106,10 +106,10 @@ describe('material-table-schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'table', {spec: false, ...baseOptions}, createTestApp(runner));
'table', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
@@ -22,7 +22,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__'
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__'
}),
options.skipImport ? noop() : addTableModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
@@ -31,7 +31,7 @@ export interface FlatTreeNode {
styles: [`
<%= indentTextContent(resolvedFiles.stylesheet, 4) %>
`]<% } else { %>
styleUrls: ['./<%= dasherize(name) %>.component.<%= styleext %>']<% } %><% if(!!viewEncapsulation) { %>,
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
})
@@ -43,10 +43,10 @@ describe('Material tree schematic', () => {
}).toThrowError(/required property 'name'/);
});
describe('styleext option', () => {
describe('style option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'tree', {styleext: 'scss', ...baseOptions}, createTestApp(runner));
'tree', {style: 'scss', ...baseOptions}, createTestApp(runner));
expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss');
});
@@ -91,10 +91,10 @@ describe('Material tree schematic', () => {
});
});
describe('spec option', () => {
describe('skipTests option', () => {
it('should respect the option value', () => {
const tree = runner.runSchematic(
'tree', {spec: false, ...baseOptions}, createTestApp(runner));
'tree', {skipTests: true, ...baseOptions}, createTestApp(runner));
expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.spec.ts');
});
+1 -1
View File
@@ -22,7 +22,7 @@ export default function(options: Schema): Rule {
return chain([
buildComponent({...options}, {
template: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.html',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__styleext__',
stylesheet: './__path__/__name@dasherize@if-flat__/__name@dasherize__.component.__style__',
}),
options.skipImport ? noop() : addTreeModulesToModule(options)
]);
@@ -55,13 +55,13 @@
"description": "The prefix to apply to generated selectors.",
"alias": "p"
},
"styleext": {
"style": {
"description": "The file extension to be used for style files.",
"type": "string"
},
"spec": {
"skipTests": {
"type": "boolean",
"description": "Specifies if a spec file is generated."
"description": "When true, does not generate a test file."
},
"flat": {
"type": "boolean",
+26 -21
View File
@@ -32,21 +32,21 @@
rxjs "6.3.3"
source-map "0.7.3"
"@angular-devkit/core@7.1.2":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.1.2.tgz#86b0e5a4cdeaa3198f6b1b50e7e114fac403e57c"
integrity sha512-LyjHGuLnLWrgX7SYDkKmc3eW4H5uuaoC+CXYjRfgx3qundrLfvTCRgNGC6FPjhQNnVXH9qar+j9P1aMmKFb4Lw==
"@angular-devkit/core@7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.3.3.tgz#cd6d5a8eca25ef07b6394bc2b08133d90d08d39f"
integrity sha512-fosULDtMoDWrOyUzTmBkJccOy7zodo02kENyKai7vOv9EWfv9jytkVdNc+jl0ys9OE2QadvSYBo49jhnZxFXfQ==
dependencies:
ajv "6.5.3"
ajv "6.9.1"
chokidar "2.0.4"
fast-json-stable-stringify "2.0.0"
rxjs "6.3.3"
source-map "0.7.3"
"@angular-devkit/core@7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.3.3.tgz#cd6d5a8eca25ef07b6394bc2b08133d90d08d39f"
integrity sha512-fosULDtMoDWrOyUzTmBkJccOy7zodo02kENyKai7vOv9EWfv9jytkVdNc+jl0ys9OE2QadvSYBo49jhnZxFXfQ==
"@angular-devkit/core@7.3.6":
version "7.3.6"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.3.6.tgz#bc11ca571187f0f0ce9df012332794907e0b8133"
integrity sha512-aoarMK0DJIdwjVA0OuQIN7b8nKPcF9n5vSMF7MFmhKpTw5/uV3SynQZbm3YCgylu/2CMuiTzKuAunnWWdli//g==
dependencies:
ajv "6.9.1"
chokidar "2.0.4"
@@ -62,12 +62,12 @@
"@angular-devkit/core" "7.1.1"
rxjs "6.3.3"
"@angular-devkit/schematics@7.1.2":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.1.2.tgz#847639044417d044bf1bc87f64508a0c3f99fae2"
integrity sha512-NFhHLYWf9gpGQm0s19lq+nAw3CZ0udBpoBLzCm8Crlmu6+7aAXgw7Fv5P4ukWJ/e1m7NDGVids+B6kBGXaY6Ig==
"@angular-devkit/schematics@7.3.6":
version "7.3.6"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.3.6.tgz#5580b730b1bae5397f5860cfb0d7270fec6e6deb"
integrity sha512-YXF7QusmMy3D9H0vNczc1n5BkuEHLwt7cW33euNeGNgTIsD0n6DrUhgClurXicnr2GNPSDYE5+3115lmJkhyrg==
dependencies:
"@angular-devkit/core" "7.1.2"
"@angular-devkit/core" "7.3.6"
rxjs "6.3.3"
"@angular-devkit/schematics@^7.3.0-rc.0":
@@ -520,14 +520,14 @@
universal-user-agent "^2.0.0"
url-template "^2.0.8"
"@schematics/angular@7.1.2":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.1.2.tgz#b3eefbc81d12b0b53816896f6172eb613885826c"
integrity sha512-coypNxjRjCExCbkJ8Vser4iZbdksl3cNqgdokDlEtpXnnph3ZYvNDhDD9TBWYQ+cwDhCHAOzT3U3IjN4R2MCgQ==
"@schematics/angular@7.3.6":
version "7.3.6"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.3.6.tgz#e827111e7d3cdf950efcca504389cbade3c9c59a"
integrity sha512-Q4VXAjVaCDb2zXFXoIdOfNPsn+EQjqDBHK4a97omytnSNAmu1erl3l2FkEMi6x/VuzK2mQSzBbmHJIgauMmOAA==
dependencies:
"@angular-devkit/core" "7.1.2"
"@angular-devkit/schematics" "7.1.2"
typescript "3.1.6"
"@angular-devkit/core" "7.3.6"
"@angular-devkit/schematics" "7.3.6"
typescript "3.2.4"
"@schematics/angular@^7.0.4":
version "7.1.1"
@@ -10504,6 +10504,11 @@ typescript@3.1.6, typescript@~3.1.1, typescript@~3.1.6:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
typescript@3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.4.tgz#c585cb952912263d915b462726ce244ba510ef3d"
integrity sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==
typescript@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"