@angular/cli 10.2.0 → 10.2.4

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.
@@ -35,6 +35,7 @@ class AddCommand extends schematic_command_1.SchematicCommand {
35
35
  }
36
36
  async run(options) {
37
37
  var _a;
38
+ await package_manager_1.ensureCompatibleNpm(this.workspace.root);
38
39
  if (!options.collection) {
39
40
  this.logger.fatal(`The "ng add" command requires a name argument to be specified eg. ` +
40
41
  `${color_1.colors.yellow('ng add [name] ')}. For more details, use "ng help".`);
@@ -23,8 +23,9 @@ export declare class UpdateCommand extends Command<UpdateCommandSchema> {
23
23
  private commit;
24
24
  private checkCleanGit;
25
25
  /**
26
- * Checks if the current installed CLI version is older than the latest version.
27
- * @returns `true` when the installed version is older.
28
- */
29
- private checkCLILatestVersion;
26
+ * Checks if the current installed CLI version is older or newer than a compatible version.
27
+ * @returns the version to install or null when there is no update to install.
28
+ */
29
+ private checkCLIVersion;
30
+ private getCLIUpdateRunnerVersion;
30
31
  }
@@ -16,6 +16,7 @@ const child_process_1 = require("child_process");
16
16
  const fs = require("fs");
17
17
  const path = require("path");
18
18
  const semver = require("semver");
19
+ const cli_1 = require("../lib/cli");
19
20
  const schema_1 = require("../lib/config/schema");
20
21
  const command_1 = require("../models/command");
21
22
  const install_package_1 = require("../tasks/install-package");
@@ -27,8 +28,6 @@ const package_tree_1 = require("../utilities/package-tree");
27
28
  const npa = require('npm-package-arg');
28
29
  const pickManifest = require('npm-pick-manifest');
29
30
  const oldConfigFileNames = ['.angular-cli.json', 'angular-cli.json'];
30
- const NG_VERSION_9_POST_MSG = color_1.colors.cyan('\nYour project has been updated to Angular version 9!\n' +
31
- 'For more info, please see: https://v9.angular.io/guide/updating-to-version-9');
32
31
  /**
33
32
  * Disable CLI version mismatch checks and forces usage of the invoked CLI
34
33
  * instead of invoking the local installed version.
@@ -37,6 +36,7 @@ const disableVersionCheckEnv = process.env['NG_DISABLE_VERSION_CHECK'];
37
36
  const disableVersionCheck = disableVersionCheckEnv !== undefined &&
38
37
  disableVersionCheckEnv !== '0' &&
39
38
  disableVersionCheckEnv.toLowerCase() !== 'false';
39
+ const ANGULAR_PACKAGES_REGEXP = /^@(?:angular|nguniversal)\//;
40
40
  class UpdateCommand extends command_1.Command {
41
41
  constructor() {
42
42
  super(...arguments);
@@ -58,7 +58,7 @@ class UpdateCommand extends command_1.Command {
58
58
  let error = false;
59
59
  let logs = [];
60
60
  const files = new Set();
61
- const reporterSubscription = this.workflow.reporter.subscribe(event => {
61
+ const reporterSubscription = this.workflow.reporter.subscribe((event) => {
62
62
  // Strip leading slash to prevent confusion.
63
63
  const eventPath = event.path.startsWith('/') ? event.path.substr(1) : event.path;
64
64
  switch (event.kind) {
@@ -86,11 +86,11 @@ class UpdateCommand extends command_1.Command {
86
86
  break;
87
87
  }
88
88
  });
89
- const lifecycleSubscription = this.workflow.lifeCycle.subscribe(event => {
89
+ const lifecycleSubscription = this.workflow.lifeCycle.subscribe((event) => {
90
90
  if (event.kind == 'end' || event.kind == 'post-tasks-start') {
91
91
  if (!error) {
92
92
  // Output the logging queue, no error happened.
93
- logs.forEach(log => this.logger.info(log));
93
+ logs.forEach((log) => this.logger.info(log));
94
94
  logs = [];
95
95
  }
96
96
  }
@@ -126,7 +126,7 @@ class UpdateCommand extends command_1.Command {
126
126
  */
127
127
  async executeMigration(packageName, collectionPath, migrationName, commit) {
128
128
  const collection = this.workflow.engine.createCollection(collectionPath);
129
- const name = collection.listSchematicNames().find(name => name === migrationName);
129
+ const name = collection.listSchematicNames().find((name) => name === migrationName);
130
130
  if (!name) {
131
131
  this.logger.error(`Cannot find migration '${migrationName}' in '${packageName}'.`);
132
132
  return false;
@@ -185,6 +185,8 @@ class UpdateCommand extends command_1.Command {
185
185
  }
186
186
  // tslint:disable-next-line:no-big-function
187
187
  async run(options) {
188
+ var _a;
189
+ await package_manager_1.ensureCompatibleNpm(this.workspace.root);
188
190
  // Check if the @angular-devkit/schematics package can be resolved from the workspace root
189
191
  // This works around issues with packages containing migrations that cannot directly depend on the package
190
192
  // This check can be removed once the schematic runtime handles this situation
@@ -203,11 +205,14 @@ class UpdateCommand extends command_1.Command {
203
205
  }
204
206
  throw e;
205
207
  }
206
- // Check if the current installed CLI version is older than the latest version.
207
- if (!disableVersionCheck && await this.checkCLILatestVersion(options.verbose, options.next)) {
208
- this.logger.warn(`The installed local Angular CLI version is older than the latest ${options.next ? 'pre-release' : 'stable'} version.\n` +
209
- 'Installing a temporary version to perform the update.');
210
- return install_package_1.runTempPackageBin(`@angular/cli@${options.next ? 'next' : 'latest'}`, this.logger, this.packageManager, process.argv.slice(2));
208
+ // Check if the current installed CLI version is older than the latest compatible version.
209
+ if (!disableVersionCheck) {
210
+ const cliVersionToInstall = await this.checkCLIVersion(options['--'], options.verbose, options.next);
211
+ if (cliVersionToInstall) {
212
+ this.logger.warn('The installed Angular CLI version is outdated.\n' +
213
+ `Installing a temporary Angular CLI versioned ${cliVersionToInstall} to perform the update.`);
214
+ return install_package_1.runTempPackageBin(`@angular/cli@${cliVersionToInstall}`, this.logger, this.packageManager, process.argv.slice(2));
215
+ }
211
216
  }
212
217
  const packages = [];
213
218
  for (const request of options['--'] || []) {
@@ -218,7 +223,7 @@ class UpdateCommand extends command_1.Command {
218
223
  this.logger.error(`Package '${request}' is not a registry package identifer.`);
219
224
  return 1;
220
225
  }
221
- if (packages.some(v => v.name === packageIdentifier.name)) {
226
+ if (packages.some((v) => v.name === packageIdentifier.name)) {
222
227
  this.logger.error(`Duplicate package '${packageIdentifier.name}' specified.`);
223
228
  return 1;
224
229
  }
@@ -321,7 +326,7 @@ class UpdateCommand extends command_1.Command {
321
326
  // Allow running migrations on transitively installed dependencies
322
327
  // There can technically be nested multiple versions
323
328
  // TODO: If multiple, this should find all versions and ask which one to use
324
- const child = packageTree.children.find(c => c.name === packageName);
329
+ const child = packageTree.children.find((c) => c.name === packageName);
325
330
  if (child) {
326
331
  packageNode = child;
327
332
  }
@@ -347,8 +352,7 @@ class UpdateCommand extends command_1.Command {
347
352
  // Normalize slashes
348
353
  migrations = migrations.replace(/\\/g, '/');
349
354
  if (migrations.startsWith('../')) {
350
- this.logger.error('Package contains an invalid migrations field. ' +
351
- 'Paths outside the package root are not permitted.');
355
+ this.logger.error('Package contains an invalid migrations field. Paths outside the package root are not permitted.');
352
356
  return 1;
353
357
  }
354
358
  // Check if it is a package-local location
@@ -372,9 +376,9 @@ class UpdateCommand extends command_1.Command {
372
376
  return 1;
373
377
  }
374
378
  }
375
- let success = false;
379
+ let result;
376
380
  if (typeof options.migrateOnly == 'string') {
377
- success = await this.executeMigration(packageName, migrations, options.migrateOnly, options.createCommits);
381
+ result = await this.executeMigration(packageName, migrations, options.migrateOnly, options.createCommits);
378
382
  }
379
383
  else {
380
384
  const from = coerceVersionNumber(options.from);
@@ -383,18 +387,9 @@ class UpdateCommand extends command_1.Command {
383
387
  return 1;
384
388
  }
385
389
  const migrationRange = new semver.Range('>' + from + ' <=' + (options.to || packageNode.package.version));
386
- success = await this.executeMigrations(packageName, migrations, migrationRange, options.createCommits);
387
- }
388
- if (success) {
389
- if (packageName === '@angular/core'
390
- && options.from
391
- && +options.from.split('.')[0] < 9
392
- && (options.to || packageNode.package.version).split('.')[0] === '9') {
393
- this.logger.info(NG_VERSION_9_POST_MSG);
394
- }
395
- return 0;
390
+ result = await this.executeMigrations(packageName, migrations, migrationRange, options.createCommits);
396
391
  }
397
- return 1;
392
+ return result ? 0 : 1;
398
393
  }
399
394
  const requests = [];
400
395
  // Validate packages actually are part of the workspace
@@ -465,10 +460,32 @@ class UpdateCommand extends command_1.Command {
465
460
  this.logger.error(`Package specified by '${requestIdentifier.raw}' does not exist within the registry.`);
466
461
  return 1;
467
462
  }
468
- if (manifest.version === node.package.version) {
463
+ if (manifest.version === ((_a = node.package) === null || _a === void 0 ? void 0 : _a.version)) {
469
464
  this.logger.info(`Package '${packageName}' is already up to date.`);
470
465
  continue;
471
466
  }
467
+ if (node.package && ANGULAR_PACKAGES_REGEXP.test(node.package.name)) {
468
+ const { name, version } = node.package;
469
+ const toBeInstalledMajorVersion = +manifest.version.split('.')[0];
470
+ const currentMajorVersion = +version.split('.')[0];
471
+ if (toBeInstalledMajorVersion - currentMajorVersion > 1) {
472
+ // Only allow updating a single version at a time.
473
+ if (currentMajorVersion < 6) {
474
+ // Before version 6, the major versions were not always sequential.
475
+ // Example @angular/core skipped version 3, @angular/cli skipped versions 2-5.
476
+ this.logger.error(`Updating multiple major versions of '${name}' at once is not supported. Please migrate each major version individually.\n` +
477
+ `For more information about the update process, see https://update.angular.io/.`);
478
+ }
479
+ else {
480
+ const nextMajorVersionFromCurrent = currentMajorVersion + 1;
481
+ this.logger.error(`Updating multiple major versions of '${name}' at once is not supported. Please migrate each major version individually.\n` +
482
+ `Run 'ng update ${name}@${nextMajorVersionFromCurrent}' in your workspace directory ` +
483
+ `to update to latest '${nextMajorVersionFromCurrent}.x' version of '${name}'.\n\n` +
484
+ `For more information about the update process, see https://update.angular.io/?v=${currentMajorVersion}.0-${nextMajorVersionFromCurrent}.0`);
485
+ }
486
+ return 1;
487
+ }
488
+ }
472
489
  packagesToUpdate.push(requestIdentifier.toString());
473
490
  }
474
491
  if (packagesToUpdate.length === 0) {
@@ -501,9 +518,6 @@ class UpdateCommand extends command_1.Command {
501
518
  return 0;
502
519
  }
503
520
  }
504
- if (migrations.some(m => m.package === '@angular/core' && m.to.split('.')[0] === '9' && +m.from.split('.')[0] < 9)) {
505
- this.logger.info(NG_VERSION_9_POST_MSG);
506
- }
507
521
  }
508
522
  return success ? 0 : 1;
509
523
  }
@@ -548,7 +562,10 @@ class UpdateCommand extends command_1.Command {
548
562
  }
549
563
  checkCleanGit() {
550
564
  try {
551
- const topLevel = child_process_1.execSync('git rev-parse --show-toplevel', { encoding: 'utf8', stdio: 'pipe' });
565
+ const topLevel = child_process_1.execSync('git rev-parse --show-toplevel', {
566
+ encoding: 'utf8',
567
+ stdio: 'pipe',
568
+ });
552
569
  const result = child_process_1.execSync('git status --porcelain', { encoding: 'utf8', stdio: 'pipe' });
553
570
  if (result.trim().length === 0) {
554
571
  return true;
@@ -565,16 +582,38 @@ class UpdateCommand extends command_1.Command {
565
582
  return true;
566
583
  }
567
584
  /**
568
- * Checks if the current installed CLI version is older than the latest version.
569
- * @returns `true` when the installed version is older.
570
- */
571
- async checkCLILatestVersion(verbose = false, next = false) {
572
- const { version: installedCLIVersion } = require('../package.json');
573
- const LatestCLIManifest = await package_metadata_1.fetchPackageManifest(`@angular/cli@${next ? 'next' : 'latest'}`, this.logger, {
585
+ * Checks if the current installed CLI version is older or newer than a compatible version.
586
+ * @returns the version to install or null when there is no update to install.
587
+ */
588
+ async checkCLIVersion(packagesToUpdate, verbose = false, next = false) {
589
+ const { version } = await package_metadata_1.fetchPackageManifest(`@angular/cli@${this.getCLIUpdateRunnerVersion(packagesToUpdate, next)}`, this.logger, {
574
590
  verbose,
575
591
  usingYarn: this.packageManager === schema_1.PackageManager.Yarn,
576
592
  });
577
- return semver.lt(installedCLIVersion, LatestCLIManifest.version);
593
+ return cli_1.VERSION.full === version ? null : version;
594
+ }
595
+ getCLIUpdateRunnerVersion(packagesToUpdate, next) {
596
+ var _a, _b;
597
+ if (next) {
598
+ return 'next';
599
+ }
600
+ const updatingAngularPackage = packagesToUpdate === null || packagesToUpdate === void 0 ? void 0 : packagesToUpdate.find((r) => ANGULAR_PACKAGES_REGEXP.test(r));
601
+ if (updatingAngularPackage) {
602
+ // If we are updating any Angular package we can update the CLI to the target version because
603
+ // migrations for @angular/core@13 can be executed using Angular/cli@13.
604
+ // This is same behaviour as `npx @angular/cli@13 update @angular/core@13`.
605
+ // `@angular/cli@13` -> ['', 'angular/cli', '13']
606
+ // `@angular/cli` -> ['', 'angular/cli']
607
+ const tempVersion = coerceVersionNumber(updatingAngularPackage.split('@')[2]);
608
+ return (_b = (_a = semver.parse(tempVersion)) === null || _a === void 0 ? void 0 : _a.major) !== null && _b !== void 0 ? _b : 'latest';
609
+ }
610
+ // When not updating an Angular package we cannot determine which schematic runtime the migration should to be executed in.
611
+ // Typically, we can assume that the `@angular/cli` was updated previously.
612
+ // Example: Angular official packages are typically updated prior to NGRX etc...
613
+ // Therefore, we only update to the latest patch version of the installed major version of the Angular CLI.
614
+ // This is important because we might end up in a scenario where locally Angular v12 is installed, updating NGRX from 11 to 12.
615
+ // We end up using Angular ClI v13 to run the migrations if we run the migrations using the CLI installed major version + 1 logic.
616
+ return cli_1.VERSION.major;
578
617
  }
579
618
  }
580
619
  exports.UpdateCommand = UpdateCommand;
@@ -1,3 +1,4 @@
1
+ export { VERSION, Version } from '../../models/version';
1
2
  export default function (options: {
2
3
  testing?: boolean;
3
4
  cliArgs: string[];
package/lib/cli/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Version = exports.VERSION = void 0;
3
4
  /**
4
5
  * @license
5
6
  * Copyright Google Inc. All Rights Reserved.
@@ -14,6 +15,9 @@ const color_1 = require("../../utilities/color");
14
15
  const config_1 = require("../../utilities/config");
15
16
  const log_file_1 = require("../../utilities/log-file");
16
17
  const project_1 = require("../../utilities/project");
18
+ var version_1 = require("../../models/version");
19
+ Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return version_1.VERSION; } });
20
+ Object.defineProperty(exports, "Version", { enumerable: true, get: function () { return version_1.Version; } });
17
21
  const debugEnv = process.env['NG_DEBUG'];
18
22
  const isDebug = debugEnv !== undefined &&
19
23
  debugEnv !== '0' &&
package/lib/init.js CHANGED
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
2
  /**
4
3
  * @license
5
4
  * Copyright Google Inc. All Rights Reserved.
@@ -7,34 +6,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
6
  * Use of this source code is governed by an MIT-style license that can be
8
7
  * found in the LICENSE file at https://angular.io/license
9
8
  */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  require("symbol-observable");
11
11
  // symbol polyfill must go first
12
12
  // tslint:disable-next-line:ordered-imports import-groups
13
- const core_1 = require("@angular-devkit/core");
14
13
  const fs = require("fs");
15
14
  const path = require("path");
16
15
  const semver_1 = require("semver");
17
- const stream_1 = require("stream");
18
16
  const color_1 = require("../utilities/color");
19
17
  const config_1 = require("../utilities/config");
20
- const packageJson = require('../package.json');
21
- function _fromPackageJson(cwd = process.cwd()) {
22
- do {
23
- const packageJsonPath = path.join(cwd, 'node_modules/@angular/cli/package.json');
24
- if (fs.existsSync(packageJsonPath)) {
25
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
26
- if (content) {
27
- const { version } = JSON.parse(content);
28
- if (version) {
29
- return new semver_1.SemVer(version);
30
- }
31
- }
32
- }
33
- // Check the parent.
34
- cwd = path.dirname(cwd);
35
- } while (cwd != path.dirname(cwd));
36
- return null;
37
- }
18
+ const cli_1 = require("./cli");
38
19
  // Check if we need to profile this CLI run.
39
20
  if (process.env['NG_CLI_PROFILING']) {
40
21
  let profiler;
@@ -60,6 +41,7 @@ if (process.env['NG_CLI_PROFILING']) {
60
41
  process.on('uncaughtException', () => exitHandler({ exit: true }));
61
42
  }
62
43
  (async () => {
44
+ var _a;
63
45
  /**
64
46
  * Disable Browserslist old data warning as otherwise with every release we'd need to update this dependency
65
47
  * which is cumbersome considering we pin versions and the warning is not user actionable.
@@ -80,43 +62,50 @@ if (process.env['NG_CLI_PROFILING']) {
80
62
  }
81
63
  let cli;
82
64
  try {
65
+ // No error implies a projectLocalCli, which will load whatever
66
+ // version of ng-cli you have installed in a local package.json
83
67
  const projectLocalCli = require.resolve('@angular/cli', { paths: [process.cwd()] });
84
- // This was run from a global, check local version.
85
- const globalVersion = new semver_1.SemVer(packageJson['version']);
86
- let localVersion;
87
- let shouldWarn = false;
68
+ cli = await Promise.resolve().then(() => require(projectLocalCli));
69
+ const globalVersion = new semver_1.SemVer(cli_1.VERSION.full);
70
+ // Older versions might not have the VERSION export
71
+ let localVersion = (_a = cli.VERSION) === null || _a === void 0 ? void 0 : _a.full;
72
+ if (!localVersion) {
73
+ try {
74
+ const localPackageJson = fs.readFileSync(path.join(path.dirname(projectLocalCli), '../../package.json'), 'utf-8');
75
+ localVersion = JSON.parse(localPackageJson).version;
76
+ }
77
+ catch (error) {
78
+ // tslint:disable-next-line:no-console
79
+ console.error('Version mismatch check skipped. Unable to retrieve local version: ' + error);
80
+ }
81
+ }
82
+ let isGlobalGreater = false;
88
83
  try {
89
- localVersion = _fromPackageJson();
90
- shouldWarn = localVersion != null && globalVersion.compare(localVersion) > 0;
84
+ isGlobalGreater = !!localVersion && globalVersion.compare(localVersion) > 0;
91
85
  }
92
- catch (e) {
93
- // tslint:disable-next-line no-console
94
- console.error(e);
95
- shouldWarn = true;
86
+ catch (error) {
87
+ // tslint:disable-next-line:no-console
88
+ console.error('Version mismatch check skipped. Unable to compare local version: ' + error);
96
89
  }
97
- if (shouldWarn && await config_1.isWarningEnabled('versionMismatch')) {
98
- const warning = color_1.colors.yellow(core_1.tags.stripIndents `
99
- Your global Angular CLI version (${globalVersion}) is greater than your local
100
- version (${localVersion}). The local Angular CLI version is used.
101
-
102
- To disable this warning use "ng config -g cli.warnings.versionMismatch false".
103
- `);
104
- // Don't show warning colorised on `ng completion`
105
- if (process.argv[2] !== 'completion') {
106
- // tslint:disable-next-line no-console
107
- console.error(warning);
90
+ if (isGlobalGreater) {
91
+ // If using the update command and the global version is greater, use the newer update command
92
+ // This allows improvements in update to be used in older versions that do not have bootstrapping
93
+ if (process.argv[2] === 'update' &&
94
+ cli.VERSION &&
95
+ cli.VERSION.major - globalVersion.major <= 1) {
96
+ cli = await Promise.resolve().then(() => require('./cli'));
108
97
  }
109
- else {
110
- // tslint:disable-next-line no-console
111
- console.error(warning);
112
- process.exit(1);
98
+ else if (await config_1.isWarningEnabled('versionMismatch')) {
99
+ // Otherwise, use local version and warn if global is newer than local
100
+ const warning = `Your global Angular CLI version (${globalVersion}) is greater than your local ` +
101
+ `version (${localVersion}). The local Angular CLI version is used.\n\n` +
102
+ 'To disable this warning use "ng config -g cli.warnings.versionMismatch false".';
103
+ // tslint:disable-next-line:no-console
104
+ console.error(color_1.colors.yellow(warning));
113
105
  }
114
106
  }
115
- // No error implies a projectLocalCli, which will load whatever
116
- // version of ng-cli you have installed in a local package.json
117
- cli = await Promise.resolve().then(() => require(projectLocalCli));
118
107
  }
119
- catch (_a) {
108
+ catch (_b) {
120
109
  // If there is an error, resolve could not find the ng-cli
121
110
  // library from a package.json. Instead, include it from a relative
122
111
  // path to this script file (which is likely a globally installed
@@ -127,26 +116,19 @@ if (process.env['NG_CLI_PROFILING']) {
127
116
  cli = cli['default'];
128
117
  }
129
118
  return cli;
130
- })().then(cli => {
131
- // This is required to support 1.x local versions with a 6+ global
132
- let standardInput;
133
- try {
134
- standardInput = process.stdin;
135
- }
136
- catch (e) {
137
- process.stdin = new stream_1.Duplex();
138
- standardInput = process.stdin;
139
- }
119
+ })()
120
+ .then((cli) => {
140
121
  return cli({
141
122
  cliArgs: process.argv.slice(2),
142
- inputStream: standardInput,
123
+ inputStream: process.stdin,
143
124
  outputStream: process.stdout,
144
125
  });
145
- }).then((exitCode) => {
126
+ })
127
+ .then((exitCode) => {
146
128
  process.exit(exitCode);
147
129
  })
148
130
  .catch((err) => {
149
- // tslint:disable-next-line no-console
131
+ // tslint:disable-next-line:no-console
150
132
  console.error('Unknown error: ' + err.toString());
151
133
  process.exit(127);
152
134
  });
@@ -398,6 +398,13 @@ class SchematicCommand extends command_1.Command {
398
398
  error = false;
399
399
  }
400
400
  });
401
+ // Temporary compatibility check for NPM 7
402
+ if (collectionName === '@schematics/angular' && schematicName === 'ng-new') {
403
+ if (!input.skipInstall &&
404
+ (input.packageManager === undefined || input.packageManager === 'npm')) {
405
+ await package_manager_1.ensureCompatibleNpm(this.workspace.root);
406
+ }
407
+ }
401
408
  return new Promise(resolve => {
402
409
  workflow
403
410
  .execute({
@@ -0,0 +1,15 @@
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
+ export declare class Version {
9
+ readonly full: string;
10
+ readonly major: string;
11
+ readonly minor: string;
12
+ readonly patch: string;
13
+ constructor(full: string);
14
+ }
15
+ export declare const VERSION: Version;
@@ -0,0 +1,24 @@
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
+ exports.VERSION = exports.Version = void 0;
11
+ const fs_1 = require("fs");
12
+ const path_1 = require("path");
13
+ // Same structure as used in framework packages
14
+ class Version {
15
+ constructor(full) {
16
+ this.full = full;
17
+ this.major = full.split('.')[0];
18
+ this.minor = full.split('.')[1];
19
+ this.patch = full.split('.').slice(2).join('.');
20
+ }
21
+ }
22
+ exports.Version = Version;
23
+ // TODO: Convert this to use build-time version stamping once implemented in the build system
24
+ exports.VERSION = new Version(JSON.parse(fs_1.readFileSync(path_1.resolve(__dirname, '../package.json'), 'utf-8')).version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/cli",
3
- "version": "10.2.0",
3
+ "version": "10.2.4",
4
4
  "description": "CLI tool for Angular",
5
5
  "main": "lib/cli/index.js",
6
6
  "bin": {
@@ -28,15 +28,15 @@
28
28
  },
29
29
  "homepage": "https://github.com/angular/angular-cli",
30
30
  "dependencies": {
31
- "@angular-devkit/architect": "0.1002.0",
32
- "@angular-devkit/core": "10.2.0",
33
- "@angular-devkit/schematics": "10.2.0",
34
- "@schematics/angular": "10.2.0",
35
- "@schematics/update": "0.1002.0",
31
+ "@angular-devkit/architect": "0.1002.4",
32
+ "@angular-devkit/core": "10.2.4",
33
+ "@angular-devkit/schematics": "10.2.4",
34
+ "@schematics/angular": "10.2.4",
35
+ "@schematics/update": "0.1002.4",
36
36
  "@yarnpkg/lockfile": "1.1.0",
37
37
  "ansi-colors": "4.1.1",
38
38
  "debug": "4.1.1",
39
- "ini": "1.3.5",
39
+ "ini": "1.3.6",
40
40
  "inquirer": "7.3.3",
41
41
  "npm-package-arg": "8.0.1",
42
42
  "npm-pick-manifest": "6.1.0",
@@ -52,17 +52,17 @@
52
52
  "ng-update": {
53
53
  "migrations": "@schematics/angular/migrations/migration-collection.json",
54
54
  "packageGroup": {
55
- "@angular/cli": "10.2.0",
56
- "@angular-devkit/build-angular": "0.1002.0",
57
- "@angular-devkit/build-ng-packagr": "0.1002.0",
58
- "@angular-devkit/build-webpack": "0.1002.0",
59
- "@angular-devkit/core": "10.2.0",
60
- "@angular-devkit/schematics": "10.2.0"
55
+ "@angular/cli": "10.2.4",
56
+ "@angular-devkit/build-angular": "0.1002.4",
57
+ "@angular-devkit/build-ng-packagr": "0.1002.4",
58
+ "@angular-devkit/build-webpack": "0.1002.4",
59
+ "@angular-devkit/core": "10.2.4",
60
+ "@angular-devkit/schematics": "10.2.4"
61
61
  }
62
62
  },
63
63
  "engines": {
64
64
  "node": ">= 10.13.0",
65
- "npm": ">= 6.11.0",
65
+ "npm": "^6.11.0 || ^7.5.6",
66
66
  "yarn": ">= 1.13.0"
67
67
  },
68
68
  "husky": {
@@ -2,3 +2,7 @@ import { PackageManager } from '../lib/config/schema';
2
2
  export declare function supportsYarn(): boolean;
3
3
  export declare function supportsNpm(): boolean;
4
4
  export declare function getPackageManager(root: string): Promise<PackageManager>;
5
+ /**
6
+ * Checks if the npm version is a supported 7.x version. If not, display a warning.
7
+ */
8
+ export declare function ensureCompatibleNpm(root: string): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPackageManager = exports.supportsNpm = exports.supportsYarn = void 0;
3
+ exports.ensureCompatibleNpm = exports.getPackageManager = exports.supportsNpm = exports.supportsYarn = void 0;
4
4
  /**
5
5
  * @license
6
6
  * Copyright Google Inc. All Rights Reserved.
@@ -11,6 +11,7 @@ exports.getPackageManager = exports.supportsNpm = exports.supportsYarn = void 0;
11
11
  const child_process_1 = require("child_process");
12
12
  const fs_1 = require("fs");
13
13
  const path_1 = require("path");
14
+ const semver_1 = require("semver");
14
15
  const schema_1 = require("../lib/config/schema");
15
16
  const config_1 = require("./config");
16
17
  function supports(name) {
@@ -56,3 +57,27 @@ async function getPackageManager(root) {
56
57
  return packageManager || schema_1.PackageManager.Npm;
57
58
  }
58
59
  exports.getPackageManager = getPackageManager;
60
+ /**
61
+ * Checks if the npm version is a supported 7.x version. If not, display a warning.
62
+ */
63
+ async function ensureCompatibleNpm(root) {
64
+ if ((await getPackageManager(root)) !== schema_1.PackageManager.Npm) {
65
+ return;
66
+ }
67
+ try {
68
+ const versionText = child_process_1.execSync('npm --version', { encoding: 'utf8', stdio: 'pipe' }).trim();
69
+ const version = semver_1.valid(versionText);
70
+ if (!version) {
71
+ return;
72
+ }
73
+ if (semver_1.satisfies(version, '>=7 <7.5.6')) {
74
+ // tslint:disable-next-line: no-console
75
+ console.warn(`npm version ${version} detected.` +
76
+ ' When using npm 7 with the Angular CLI, npm version 7.5.6 or higher is recommended.');
77
+ }
78
+ }
79
+ catch (_a) {
80
+ // npm is not installed
81
+ }
82
+ }
83
+ exports.ensureCompatibleNpm = ensureCompatibleNpm;