@schematics/angular 8.1.0-beta.3 → 8.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ module.exports = function (config) {
17
17
  },
18
18
  coverageIstanbulReporter: {
19
19
  dir: require('path').join(__dirname, '<%= relativePathToWorkspaceRoot %>/coverage/<%= folderName %>'),
20
- reports: ['html', 'lcovonly'],
20
+ reports: ['html', 'lcovonly', 'text-summary'],
21
21
  fixWebpackSourcePaths: true
22
22
  },
23
23
  reporters: ['progress', 'kjhtml'],
package/library/index.js CHANGED
@@ -181,7 +181,7 @@ function default_1(options) {
181
181
  commonModule: false,
182
182
  flat: true,
183
183
  path: sourceDir,
184
- project: projectName,
184
+ project: options.name,
185
185
  }),
186
186
  schematics_1.schematic('component', {
187
187
  name: options.name,
@@ -191,13 +191,13 @@ function default_1(options) {
191
191
  flat: true,
192
192
  path: sourceDir,
193
193
  export: true,
194
- project: projectName,
194
+ project: options.name,
195
195
  }),
196
196
  schematics_1.schematic('service', {
197
197
  name: options.name,
198
198
  flat: true,
199
199
  path: sourceDir,
200
- project: projectName,
200
+ project: options.name,
201
201
  }),
202
202
  options.lintFix ? lint_fix_1.applyLintFix(sourceDir) : schematics_1.noop(),
203
203
  (_tree, context) => {
@@ -39,6 +39,11 @@
39
39
  "version": "8.0.0-beta.14",
40
40
  "factory": "./update-8/#updateLazyModulePaths",
41
41
  "description": "Update an Angular CLI project to version 8."
42
+ },
43
+ "migration-09": {
44
+ "version": "9.0.0-beta.0",
45
+ "factory": "./update-9",
46
+ "description": "Update an Angular CLI project to version 9."
42
47
  }
43
48
  }
44
49
  }
@@ -5,14 +5,14 @@ const latest_versions_1 = require("../../utility/latest-versions");
5
5
  function updateDependencies() {
6
6
  return (host) => {
7
7
  const dependenciesToUpdate = {
8
+ '@angular/pwa': latest_versions_1.latestVersions.AngularPWA,
8
9
  '@angular-devkit/build-angular': latest_versions_1.latestVersions.DevkitBuildAngular,
9
10
  '@angular-devkit/build-ng-packagr': latest_versions_1.latestVersions.DevkitBuildNgPackagr,
10
11
  '@angular-devkit/build-webpack': latest_versions_1.latestVersions.DevkitBuildWebpack,
11
12
  'zone.js': latest_versions_1.latestVersions.ZoneJs,
12
- 'tsickle': latest_versions_1.latestVersions.tsickle,
13
+ tsickle: latest_versions_1.latestVersions.tsickle,
13
14
  'ng-packagr': latest_versions_1.latestVersions.ngPackagr,
14
- // FIXME: change to ^2.3.2 as soon as it's released with the pr208 fix
15
- 'web-animations-js': 'github:angular/web-animations-js#release_pr208',
15
+ 'web-animations-js': '^2.3.2',
16
16
  };
17
17
  for (const [name, version] of Object.entries(dependenciesToUpdate)) {
18
18
  const current = dependencies_1.getPackageJsonDependency(host, name);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google Inc. All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import { Rule } from '@angular-devkit/schematics';
9
+ export default function (): Rule;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google Inc. All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.io/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const schematics_1 = require("@angular-devkit/schematics");
11
+ const update_workspace_config_1 = require("./update-workspace-config");
12
+ function default_1() {
13
+ return () => {
14
+ return schematics_1.chain([
15
+ update_workspace_config_1.UpdateWorkspaceConfig(),
16
+ ]);
17
+ };
18
+ }
19
+ exports.default = default_1;
@@ -0,0 +1,2 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ export declare function UpdateWorkspaceConfig(): Rule;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * @license
5
+ * Copyright Google Inc. All Rights Reserved.
6
+ *
7
+ * Use of this source code is governed by an MIT-style license that can be
8
+ * found in the LICENSE file at https://angular.io/license
9
+ */
10
+ const core_1 = require("@angular-devkit/core");
11
+ const json_utils_1 = require("../../utility/json-utils");
12
+ function UpdateWorkspaceConfig() {
13
+ return (tree) => {
14
+ let workspaceConfigPath = 'angular.json';
15
+ let angularConfigContent = tree.read(workspaceConfigPath);
16
+ if (!angularConfigContent) {
17
+ workspaceConfigPath = '.angular.json';
18
+ angularConfigContent = tree.read(workspaceConfigPath);
19
+ if (!angularConfigContent) {
20
+ return;
21
+ }
22
+ }
23
+ const angularJson = core_1.parseJsonAst(angularConfigContent.toString(), core_1.JsonParseMode.Loose);
24
+ if (angularJson.kind !== 'object') {
25
+ return;
26
+ }
27
+ const projects = json_utils_1.findPropertyInAstObject(angularJson, 'projects');
28
+ if (!projects || projects.kind !== 'object') {
29
+ return;
30
+ }
31
+ // For all projects
32
+ const recorder = tree.beginUpdate(workspaceConfigPath);
33
+ for (const project of projects.properties) {
34
+ const projectConfig = project.value;
35
+ if (projectConfig.kind !== 'object') {
36
+ break;
37
+ }
38
+ const architect = json_utils_1.findPropertyInAstObject(projectConfig, 'architect');
39
+ if (!architect || architect.kind !== 'object') {
40
+ break;
41
+ }
42
+ const buildTarget = json_utils_1.findPropertyInAstObject(architect, 'build');
43
+ if (buildTarget && buildTarget.kind === 'object') {
44
+ const builder = json_utils_1.findPropertyInAstObject(buildTarget, 'builder');
45
+ // Projects who's build builder is not build-angular:browser
46
+ if (builder && builder.kind === 'string' && builder.value === '@angular-devkit/build-angular:browser') {
47
+ updateOption('styles', recorder, buildTarget);
48
+ updateOption('scripts', recorder, buildTarget);
49
+ }
50
+ }
51
+ const testTarget = json_utils_1.findPropertyInAstObject(architect, 'test');
52
+ if (testTarget && testTarget.kind === 'object') {
53
+ const builder = json_utils_1.findPropertyInAstObject(testTarget, 'builder');
54
+ // Projects who's build builder is not build-angular:browser
55
+ if (builder && builder.kind === 'string' && builder.value === '@angular-devkit/build-angular:karma') {
56
+ updateOption('styles', recorder, testTarget);
57
+ updateOption('scripts', recorder, testTarget);
58
+ }
59
+ }
60
+ }
61
+ tree.commitUpdate(recorder);
62
+ return tree;
63
+ };
64
+ }
65
+ exports.UpdateWorkspaceConfig = UpdateWorkspaceConfig;
66
+ /**
67
+ * Helper to retreive all the options in various configurations
68
+ */
69
+ function getAllOptions(builderConfig) {
70
+ const options = [];
71
+ const configurations = json_utils_1.findPropertyInAstObject(builderConfig, 'configurations');
72
+ if (configurations && configurations.kind === 'object') {
73
+ options.push(...configurations.properties.map(x => x.value));
74
+ }
75
+ options.push(json_utils_1.findPropertyInAstObject(builderConfig, 'options'));
76
+ return options.filter(o => o && o.kind === 'object');
77
+ }
78
+ function updateOption(property, recorder, builderConfig) {
79
+ const options = getAllOptions(builderConfig);
80
+ for (const option of options) {
81
+ const propertyOption = json_utils_1.findPropertyInAstObject(option, property);
82
+ if (!propertyOption || propertyOption.kind !== 'array') {
83
+ continue;
84
+ }
85
+ for (const node of propertyOption.elements) {
86
+ if (!node || node.kind !== 'object') {
87
+ // skip non complex objects
88
+ continue;
89
+ }
90
+ const lazy = json_utils_1.findPropertyInAstObject(node, 'lazy');
91
+ json_utils_1.removePropertyInAstObject(recorder, node, 'lazy');
92
+ // if lazy was not true, it is redundant hence, don't add it
93
+ if (lazy && lazy.kind === 'true') {
94
+ json_utils_1.insertPropertyInAstObjectInOrder(recorder, node, 'inject', false, 0);
95
+ }
96
+ }
97
+ }
98
+ }
@@ -1,7 +1,9 @@
1
1
  import { NgModule } from '@angular/core';
2
2
  import { Routes, RouterModule } from '@angular/router';
3
+ <% if (lazyRoute) { %>
4
+ import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% } %>
3
5
 
4
- const routes: Routes = [];
6
+ const routes: Routes = [<% if (lazyRoute) { %>{ path: '', component: <%= classify(name) %>Component }<% } %>];
5
7
 
6
8
  @NgModule({
7
9
  imports: [RouterModule.for<%= routingScope %>(routes)],
@@ -1,13 +1,19 @@
1
1
  import { NgModule } from '@angular/core';<% if (commonModule) { %>
2
- import { CommonModule } from '@angular/common';<% } %><% if (routing) { %>
3
-
2
+ import { CommonModule } from '@angular/common';<% } %><% if (lazyRouteWithoutRouteModule) { %>
3
+ import { Routes, RouterModule } from '@angular/router';<% } %>
4
+ <% if (routing || lazyRouteWithRouteModule) { %>
4
5
  import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %>
6
+ <% if (lazyRouteWithoutRouteModule) { %>
7
+ const routes: Routes = [
8
+ { path: '', component: <%= classify(name) %>Component }
9
+ ];<% } %>
5
10
 
6
11
  @NgModule({
7
12
  declarations: [],
8
13
  imports: [<% if (commonModule) { %>
9
- CommonModule<%= routing ? ',' : '' %><% } %><% if (routing) { %>
10
- <%= classify(name) %>RoutingModule<% } %>
14
+ CommonModule<%= routing || lazyRouteWithRouteModule ? ',' : '' %><% } %><% if (routing || lazyRouteWithRouteModule) { %>
15
+ <%= classify(name) %>RoutingModule<% } %><%= lazyRouteWithoutRouteModule ? ',' : '' %><% if (lazyRouteWithoutRouteModule) { %>
16
+ RouterModule.forChild(routes)<% } %>
11
17
  ]
12
18
  })
13
19
  export class <%= classify(name) %>Module { }
package/module/index.js CHANGED
@@ -16,6 +16,14 @@ const find_module_1 = require("../utility/find-module");
16
16
  const lint_fix_1 = require("../utility/lint-fix");
17
17
  const parse_name_1 = require("../utility/parse-name");
18
18
  const workspace_1 = require("../utility/workspace");
19
+ const schema_1 = require("./schema");
20
+ function buildRelativeModulePath(options, modulePath) {
21
+ const importModulePath = core_1.normalize(`/${options.path}/`
22
+ + (options.flat ? '' : core_1.strings.dasherize(options.name) + '/')
23
+ + core_1.strings.dasherize(options.name)
24
+ + '.module');
25
+ return find_module_1.buildRelativePath(modulePath, importModulePath);
26
+ }
19
27
  function addDeclarationToNgModule(options) {
20
28
  return (host) => {
21
29
  if (!options.module) {
@@ -26,13 +34,9 @@ function addDeclarationToNgModule(options) {
26
34
  if (text === null) {
27
35
  throw new schematics_1.SchematicsException(`File ${modulePath} does not exist.`);
28
36
  }
29
- const sourceText = text.toString('utf-8');
37
+ const sourceText = text.toString();
30
38
  const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
31
- const importModulePath = core_1.normalize(`/${options.path}/`
32
- + (options.flat ? '' : core_1.strings.dasherize(options.name) + '/')
33
- + core_1.strings.dasherize(options.name)
34
- + '.module');
35
- const relativePath = find_module_1.buildRelativePath(modulePath, importModulePath);
39
+ const relativePath = buildRelativeModulePath(options, modulePath);
36
40
  const changes = ast_utils_1.addImportToModule(source, modulePath, core_1.strings.classify(`${options.name}Module`), relativePath);
37
41
  const recorder = host.beginUpdate(modulePath);
38
42
  for (const change of changes) {
@@ -44,6 +48,50 @@ function addDeclarationToNgModule(options) {
44
48
  return host;
45
49
  };
46
50
  }
51
+ function addRouteDeclarationToNgModule(options, routingModulePath) {
52
+ return (host) => {
53
+ if (!options.route) {
54
+ return host;
55
+ }
56
+ if (!options.module) {
57
+ throw new Error('Module option required when creating a lazy loaded routing module.');
58
+ }
59
+ let path;
60
+ if (routingModulePath) {
61
+ path = routingModulePath;
62
+ }
63
+ else {
64
+ path = options.module;
65
+ }
66
+ const text = host.read(path);
67
+ if (!text) {
68
+ throw new Error(`Couldn't find the module nor its routing module.`);
69
+ }
70
+ const sourceText = text.toString();
71
+ const addDeclaration = ast_utils_1.addRouteDeclarationToModule(ts.createSourceFile(path, sourceText, ts.ScriptTarget.Latest, true), path, buildRoute(options, options.module));
72
+ const recorder = host.beginUpdate(path);
73
+ recorder.insertLeft(addDeclaration.pos, addDeclaration.toAdd);
74
+ host.commitUpdate(recorder);
75
+ return host;
76
+ };
77
+ }
78
+ function getRoutingModulePath(host, options) {
79
+ let path;
80
+ const modulePath = options.module;
81
+ const routingModuleName = modulePath.split('.')[0] + '-routing';
82
+ const { module, ...rest } = options;
83
+ try {
84
+ path = find_module_1.findModuleFromOptions(host, { module: routingModuleName, ...rest });
85
+ }
86
+ catch (_a) { }
87
+ return path;
88
+ }
89
+ function buildRoute(options, modulePath) {
90
+ const relativeModulePath = buildRelativeModulePath(options, modulePath);
91
+ const moduleName = `${core_1.strings.classify(options.name)}Module`;
92
+ const loadChildren = `() => import('${relativeModulePath}').then(m => m.${moduleName})`;
93
+ return `{ path: '${options.route}', loadChildren: ${loadChildren} }`;
94
+ }
47
95
  function default_1(options) {
48
96
  return async (host) => {
49
97
  if (options.path === undefined) {
@@ -55,18 +103,38 @@ function default_1(options) {
55
103
  const parsedPath = parse_name_1.parseName(options.path, options.name);
56
104
  options.name = parsedPath.name;
57
105
  options.path = parsedPath.path;
106
+ let routingModulePath;
107
+ const isLazyLoadedModuleGen = options.route && options.module;
108
+ if (isLazyLoadedModuleGen) {
109
+ options.routingScope = schema_1.RoutingScope.Child;
110
+ routingModulePath = getRoutingModulePath(host, options);
111
+ }
58
112
  const templateSource = schematics_1.apply(schematics_1.url('./files'), [
59
- options.routing ? schematics_1.noop() : schematics_1.filter(path => !path.endsWith('-routing.module.ts.template')),
113
+ options.routing || isLazyLoadedModuleGen && !!routingModulePath
114
+ ? schematics_1.noop()
115
+ : schematics_1.filter(path => !path.endsWith('-routing.module.ts.template')),
60
116
  schematics_1.applyTemplates({
61
117
  ...core_1.strings,
62
118
  'if-flat': (s) => options.flat ? '' : s,
119
+ lazyRoute: isLazyLoadedModuleGen,
120
+ lazyRouteWithoutRouteModule: isLazyLoadedModuleGen && !routingModulePath,
121
+ lazyRouteWithRouteModule: isLazyLoadedModuleGen && routingModulePath,
63
122
  ...options,
64
123
  }),
65
124
  schematics_1.move(parsedPath.path),
66
125
  ]);
126
+ const moduleDasherized = core_1.strings.dasherize(options.name);
127
+ const modulePath = `${!options.flat ? moduleDasherized + '/' : ''}${moduleDasherized}.module.ts`;
67
128
  return schematics_1.chain([
68
- addDeclarationToNgModule(options),
129
+ !isLazyLoadedModuleGen ? addDeclarationToNgModule(options) : schematics_1.noop(),
130
+ addRouteDeclarationToNgModule(options, routingModulePath),
69
131
  schematics_1.mergeWith(templateSource),
132
+ isLazyLoadedModuleGen
133
+ ? schematics_1.schematic('component', {
134
+ ...options,
135
+ module: modulePath,
136
+ })
137
+ : schematics_1.noop(),
70
138
  options.lintFix ? lint_fix_1.applyLintFix(options.path) : schematics_1.noop(),
71
139
  ]);
72
140
  };
@@ -30,6 +30,10 @@ export interface Schema {
30
30
  * The name of the project.
31
31
  */
32
32
  project?: string;
33
+ /**
34
+ * Creates lazy loaded routing module. Requires --module option.
35
+ */
36
+ route?: string;
33
37
  /**
34
38
  * When true, creates a routing module.
35
39
  */
@@ -39,6 +39,10 @@
39
39
  "description": "The scope for the new routing module.",
40
40
  "default": "Child"
41
41
  },
42
+ "route": {
43
+ "type": "string",
44
+ "description": "Creates lazy loaded routing module. Requires --module option."
45
+ },
42
46
  "flat": {
43
47
  "type": "boolean",
44
48
  "description": "When true, creates the new files at the top level of the current project root. ",
@@ -130,10 +130,10 @@
130
130
  "type": "list",
131
131
  "items": [
132
132
  { "value": "css", "label": "CSS" },
133
- { "value": "scss", "label": "SCSS [ http://sass-lang.com/documentation/file.SASS_REFERENCE.html#syntax ]" },
134
- { "value": "sass", "label": "Sass [ http://sass-lang.com/documentation/file.INDENTED_SYNTAX.html ]" },
135
- { "value": "less", "label": "Less [ http://lesscss.org ]" },
136
- { "value": "styl", "label": "Stylus [ http://stylus-lang.com ] " }
133
+ { "value": "scss", "label": "SCSS [ https://sass-lang.com/documentation/syntax#scss ]" },
134
+ { "value": "sass", "label": "Sass [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]" },
135
+ { "value": "less", "label": "Less [ http://lesscss.org ]" },
136
+ { "value": "styl", "label": "Stylus [ http://stylus-lang.com ]" }
137
137
  ]
138
138
  },
139
139
  "x-user-analytics": 5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "8.1.0-beta.3",
3
+ "version": "8.1.2",
4
4
  "description": "Schematics specific to Angular",
5
5
  "keywords": [
6
6
  "angular",
@@ -14,8 +14,8 @@
14
14
  ],
15
15
  "schematics": "./collection.json",
16
16
  "dependencies": {
17
- "@angular-devkit/core": "8.1.0-beta.3",
18
- "@angular-devkit/schematics": "8.1.0-beta.3"
17
+ "@angular-devkit/core": "8.1.2",
18
+ "@angular-devkit/schematics": "8.1.2"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
@@ -33,7 +33,6 @@
33
33
  "homepage": "https://github.com/angular/angular-cli",
34
34
  "husky": {
35
35
  "hooks": {
36
- "pre-commit": "lint-staged",
37
36
  "pre-push": "node ./bin/devkit-admin hooks/pre-push"
38
37
  }
39
38
  }
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "./<%= tsConfigExtends %>",
3
3
  "compilerOptions": {
4
- "outDir": "<%= outDir %>-server"
4
+ "outDir": "<%= outDir %>-server",
5
+ "module": "commonjs"
5
6
  },
6
7
  "angularCompilerOptions": {
7
8
  "entryModule": "./<%= rootInSrc ? '' : 'src/' %><%= appDir %>/<%= stripTsExtension(rootModuleFileName) %>#<%= rootModuleClassName %>"
@@ -55,6 +55,7 @@ export declare function getDecoratorMetadata(source: ts.SourceFile, identifier:
55
55
  * @returns the name of the first @NgModule, or `undefined` if none is found
56
56
  */
57
57
  export declare function getFirstNgModuleName(source: ts.SourceFile): string | undefined;
58
+ export declare function getMetadataField(node: ts.ObjectLiteralExpression, metadataField: string): ts.ObjectLiteralElement[];
58
59
  export declare function addSymbolToNgModuleMetadata(source: ts.SourceFile, ngModulePath: string, metadataField: string, symbolName: string, importPath?: string | null): Change[];
59
60
  /**
60
61
  * Custom function to insert a declaration (component, pipe, directive)
@@ -85,3 +86,11 @@ export declare function addEntryComponentToModule(source: ts.SourceFile, moduleP
85
86
  * Determine if an import already exists.
86
87
  */
87
88
  export declare function isImported(source: ts.SourceFile, classifiedName: string, importPath: string): boolean;
89
+ /**
90
+ * Returns the RouterModule declaration from NgModule metadata, if any.
91
+ */
92
+ export declare function getRouterModuleDeclaration(source: ts.SourceFile): ts.Expression | undefined;
93
+ /**
94
+ * Adds a new route declaration to a router module (i.e. has a RouterModule declaration)
95
+ */
96
+ export declare function addRouteDeclarationToModule(source: ts.SourceFile, fileToAdd: string, routeLiteral: string): Change;
@@ -292,6 +292,17 @@ function getFirstNgModuleName(source) {
292
292
  return moduleClass.name.text;
293
293
  }
294
294
  exports.getFirstNgModuleName = getFirstNgModuleName;
295
+ function getMetadataField(node, metadataField) {
296
+ return node.properties
297
+ .filter(prop => ts.isPropertyAssignment(prop))
298
+ // Filter out every fields that's not "metadataField". Also handles string literals
299
+ // (but not expressions).
300
+ .filter(({ name }) => {
301
+ return (ts.isIdentifier(name) || ts.isStringLiteral(name))
302
+ && name.getText() === metadataField;
303
+ });
304
+ }
305
+ exports.getMetadataField = getMetadataField;
295
306
  function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbolName, importPath = null) {
296
307
  const nodes = getDecoratorMetadata(source, 'NgModule', '@angular/core');
297
308
  let node = nodes[0]; // tslint:disable-line:no-any
@@ -300,20 +311,7 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
300
311
  return [];
301
312
  }
302
313
  // Get all the children property assignment of object literals.
303
- const matchingProperties = node.properties
304
- .filter(prop => prop.kind == ts.SyntaxKind.PropertyAssignment)
305
- // Filter out every fields that's not "metadataField". Also handles string literals
306
- // (but not expressions).
307
- .filter((prop) => {
308
- const name = prop.name;
309
- switch (name.kind) {
310
- case ts.SyntaxKind.Identifier:
311
- return name.getText(source) == metadataField;
312
- case ts.SyntaxKind.StringLiteral:
313
- return name.text == metadataField;
314
- }
315
- return false;
316
- });
314
+ const matchingProperties = getMetadataField(node, metadataField);
317
315
  // Get the last node of the array literal.
318
316
  if (!matchingProperties) {
319
317
  return [];
@@ -364,6 +362,7 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
364
362
  node = arrLiteral.elements;
365
363
  }
366
364
  if (!node) {
365
+ // tslint:disable-next-line: no-console
367
366
  console.error('No app module found. Please add your new class to your component.');
368
367
  return [];
369
368
  }
@@ -485,3 +484,71 @@ function isImported(source, classifiedName, importPath) {
485
484
  return matchingNodes.length > 0;
486
485
  }
487
486
  exports.isImported = isImported;
487
+ /**
488
+ * Returns the RouterModule declaration from NgModule metadata, if any.
489
+ */
490
+ function getRouterModuleDeclaration(source) {
491
+ const result = getDecoratorMetadata(source, 'NgModule', '@angular/core');
492
+ const node = result[0];
493
+ const matchingProperties = getMetadataField(node, 'imports');
494
+ if (!matchingProperties) {
495
+ return;
496
+ }
497
+ const assignment = matchingProperties[0];
498
+ if (assignment.initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
499
+ return;
500
+ }
501
+ const arrLiteral = assignment.initializer;
502
+ return arrLiteral.elements
503
+ .filter(el => el.kind === ts.SyntaxKind.CallExpression)
504
+ .find(el => el.getText().startsWith('RouterModule'));
505
+ }
506
+ exports.getRouterModuleDeclaration = getRouterModuleDeclaration;
507
+ /**
508
+ * Adds a new route declaration to a router module (i.e. has a RouterModule declaration)
509
+ */
510
+ function addRouteDeclarationToModule(source, fileToAdd, routeLiteral) {
511
+ const routerModuleExpr = getRouterModuleDeclaration(source);
512
+ if (!routerModuleExpr) {
513
+ throw new Error(`Couldn't find a route declaration in ${fileToAdd}.`);
514
+ }
515
+ const scopeConfigMethodArgs = routerModuleExpr.arguments;
516
+ if (!scopeConfigMethodArgs.length) {
517
+ const { line } = source.getLineAndCharacterOfPosition(routerModuleExpr.getStart());
518
+ throw new Error(`The router module method doesn't have arguments ` +
519
+ `at line ${line} in ${fileToAdd}`);
520
+ }
521
+ let routesArr;
522
+ const routesArg = scopeConfigMethodArgs[0];
523
+ // Check if the route declarations array is
524
+ // an inlined argument of RouterModule or a standalone variable
525
+ if (ts.isArrayLiteralExpression(routesArg)) {
526
+ routesArr = routesArg;
527
+ }
528
+ else {
529
+ const routesVarName = routesArg.getText();
530
+ let routesVar;
531
+ if (routesArg.kind === ts.SyntaxKind.Identifier) {
532
+ routesVar = source.statements
533
+ .filter((s) => s.kind === ts.SyntaxKind.VariableStatement)
534
+ .find((v) => {
535
+ return v.declarationList.declarations[0].name.getText() === routesVarName;
536
+ });
537
+ }
538
+ if (!routesVar) {
539
+ const { line } = source.getLineAndCharacterOfPosition(routesArg.getStart());
540
+ throw new Error(`No route declaration array was found that corresponds ` +
541
+ `to router module at line ${line} in ${fileToAdd}`);
542
+ }
543
+ routesArr = findNodes(routesVar, ts.SyntaxKind.ArrayLiteralExpression, 1)[0];
544
+ }
545
+ const occurencesCount = routesArr.elements.length;
546
+ const text = routesArr.getFullText(source);
547
+ let route = routeLiteral;
548
+ if (occurencesCount > 0) {
549
+ const identation = text.match(/\r?\n(\r?)\s*/) || [];
550
+ route = `,${identation[0] || ' '}${routeLiteral}`;
551
+ }
552
+ return insertAfterLastOccurrence(routesArr.elements, route, fileToAdd, routesArr.elements.pos, ts.SyntaxKind.ObjectLiteralExpression);
553
+ }
554
+ exports.addRouteDeclarationToModule = addRouteDeclarationToModule;
@@ -14,6 +14,7 @@ export declare const latestVersions: {
14
14
  DevkitBuildAngular: string;
15
15
  DevkitBuildNgPackagr: string;
16
16
  DevkitBuildWebpack: string;
17
+ AngularPWA: string;
17
18
  tsickle: string;
18
19
  ngPackagr: string;
19
20
  };
@@ -9,15 +9,16 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.latestVersions = {
11
11
  // These versions should be kept up to date with latest Angular peer dependencies.
12
- Angular: '~8.1.0-next.2',
12
+ Angular: '~8.1.2',
13
13
  RxJs: '~6.4.0',
14
14
  ZoneJs: '~0.9.1',
15
15
  TypeScript: '~3.4.3',
16
16
  TsLib: '^1.9.0',
17
17
  // The versions below must be manually updated when making a new devkit release.
18
- DevkitBuildAngular: '~0.801.0-beta.2',
19
- DevkitBuildNgPackagr: '~0.801.0-beta.2',
20
- DevkitBuildWebpack: '~0.801.0-beta.2',
18
+ DevkitBuildAngular: '~0.801.2',
19
+ DevkitBuildNgPackagr: '~0.801.2',
20
+ DevkitBuildWebpack: '~0.801.2',
21
+ AngularPWA: '~0.801.2',
21
22
  tsickle: '^0.35.0',
22
23
  ngPackagr: '^5.1.0',
23
24
  };
@@ -7,7 +7,7 @@
7
7
  "array-type": false,
8
8
  "arrow-parens": false,
9
9
  "deprecation": {
10
- "severity": "warn"
10
+ "severity": "warning"
11
11
  },
12
12
  "import-blacklist": [
13
13
  true,
@@ -77,4 +77,4 @@
77
77
  "use-lifecycle-interface": true,
78
78
  "use-pipe-transform-interface": true
79
79
  }
80
- }
80
+ }