@angular/cli 14.0.0-next.6 → 14.0.0-next.9

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.
Files changed (85) hide show
  1. package/lib/cli/index.d.ts +0 -1
  2. package/lib/cli/index.js +3 -30
  3. package/lib/config/schema.json +22 -3
  4. package/lib/config/workspace-schema.d.ts +5 -0
  5. package/lib/init.js +2 -5
  6. package/package.json +19 -22
  7. package/src/analytics/analytics-collector.js +2 -0
  8. package/src/analytics/analytics.d.ts +1 -1
  9. package/src/analytics/analytics.js +39 -36
  10. package/src/command-builder/architect-base-command-module.d.ts +8 -1
  11. package/src/command-builder/architect-base-command-module.js +65 -3
  12. package/src/command-builder/architect-command-module.d.ts +4 -1
  13. package/src/command-builder/architect-command-module.js +40 -14
  14. package/src/command-builder/command-module.d.ts +4 -3
  15. package/src/command-builder/command-module.js +14 -7
  16. package/src/command-builder/command-runner.d.ts +1 -2
  17. package/src/command-builder/command-runner.js +69 -36
  18. package/src/command-builder/schematics-command-module.d.ts +3 -4
  19. package/src/command-builder/schematics-command-module.js +88 -48
  20. package/src/command-builder/utilities/normalize-options-middleware.d.ts +18 -0
  21. package/src/command-builder/utilities/normalize-options-middleware.js +59 -0
  22. package/src/command-builder/utilities/schematic-engine-host.d.ts +2 -2
  23. package/src/command-builder/utilities/schematic-engine-host.js +30 -17
  24. package/src/commands/add/cli.js +14 -14
  25. package/src/commands/add/long-description.md +1 -4
  26. package/src/commands/analytics/cli.d.ts +1 -1
  27. package/src/commands/analytics/info/cli.d.ts +1 -1
  28. package/src/commands/analytics/settings/cli.d.ts +1 -1
  29. package/src/commands/analytics/settings/cli.js +2 -2
  30. package/src/commands/cache/clean/cli.d.ts +17 -0
  31. package/src/commands/cache/clean/cli.js +32 -0
  32. package/src/commands/cache/cli.d.ts +17 -0
  33. package/src/commands/cache/cli.js +38 -0
  34. package/src/commands/cache/info/cli.d.ts +20 -0
  35. package/src/commands/cache/info/cli.js +82 -0
  36. package/src/commands/cache/long-description.md +53 -0
  37. package/src/commands/cache/settings/cli.d.ts +27 -0
  38. package/src/commands/cache/settings/cli.js +42 -0
  39. package/src/commands/cache/utilities.d.ts +11 -0
  40. package/src/commands/cache/utilities.js +49 -0
  41. package/src/commands/completion/cli.d.ts +16 -0
  42. package/src/commands/completion/cli.js +31 -0
  43. package/src/commands/completion/long-description.md +1 -0
  44. package/src/commands/config/cli.d.ts +1 -1
  45. package/src/commands/config/cli.js +15 -15
  46. package/src/commands/deploy/cli.d.ts +2 -1
  47. package/src/commands/deploy/cli.js +27 -13
  48. package/src/commands/doc/cli.d.ts +1 -1
  49. package/src/commands/e2e/cli.d.ts +3 -2
  50. package/src/commands/e2e/cli.js +14 -13
  51. package/src/commands/generate/cli.d.ts +11 -1
  52. package/src/commands/generate/cli.js +54 -23
  53. package/src/commands/lint/cli.d.ts +2 -1
  54. package/src/commands/lint/cli.js +6 -9
  55. package/src/commands/new/cli.d.ts +2 -0
  56. package/src/commands/new/cli.js +22 -6
  57. package/src/commands/run/cli.d.ts +2 -0
  58. package/src/commands/run/cli.js +24 -0
  59. package/src/commands/update/cli.d.ts +1 -0
  60. package/src/commands/update/cli.js +53 -23
  61. package/src/commands/update/schematic/index.js +27 -18
  62. package/src/commands/version/cli.d.ts +0 -1
  63. package/src/commands/version/cli.js +4 -23
  64. package/src/typings-bazel.d.ts +14 -0
  65. package/src/typings.d.ts +0 -13
  66. package/src/utilities/config.d.ts +5 -5
  67. package/src/utilities/config.js +27 -44
  68. package/src/{analytics/analytics-environment-options.d.ts → utilities/environment-options.d.ts} +3 -0
  69. package/src/utilities/environment-options.js +24 -0
  70. package/src/utilities/memoize.d.ts +15 -0
  71. package/src/utilities/memoize.js +69 -0
  72. package/src/utilities/package-manager.d.ts +33 -5
  73. package/src/utilities/package-manager.js +252 -71
  74. package/src/utilities/package-metadata.d.ts +15 -37
  75. package/src/utilities/package-metadata.js +10 -26
  76. package/src/utilities/package-tree.d.ts +2 -2
  77. package/src/utilities/prompt.d.ts +2 -0
  78. package/src/utilities/prompt.js +20 -3
  79. package/bin/postinstall/analytics-prompt.js +0 -27
  80. package/bin/postinstall/script.js +0 -16
  81. package/src/analytics/analytics-environment-options.js +0 -20
  82. package/src/utilities/install-package.d.ts +0 -16
  83. package/src/utilities/install-package.js +0 -193
  84. package/src/utilities/package-json.d.ts +0 -249
  85. package/src/utilities/package-json.js +0 -9
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC 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.getCacheConfig = exports.updateCacheConfig = void 0;
11
+ const core_1 = require("@angular-devkit/core");
12
+ const path_1 = require("path");
13
+ const workspace_schema_1 = require("../../../lib/config/workspace-schema");
14
+ function updateCacheConfig(workspace, key, value) {
15
+ var _a, _b;
16
+ var _c;
17
+ const cli = ((_a = (_c = workspace.extensions)['cli']) !== null && _a !== void 0 ? _a : (_c['cli'] = {}));
18
+ const cache = ((_b = cli['cache']) !== null && _b !== void 0 ? _b : (cli['cache'] = {}));
19
+ cache[key] = value;
20
+ return workspace.save();
21
+ }
22
+ exports.updateCacheConfig = updateCacheConfig;
23
+ function getCacheConfig(workspace) {
24
+ if (!workspace) {
25
+ throw new Error(`Cannot retrieve cache configuration as workspace is not defined.`);
26
+ }
27
+ const defaultSettings = {
28
+ path: (0, path_1.resolve)(workspace.basePath, '.angular/cache'),
29
+ environment: workspace_schema_1.Environment.Local,
30
+ enabled: true,
31
+ };
32
+ const cliSetting = workspace.extensions['cli'];
33
+ if (!cliSetting || !(0, core_1.isJsonObject)(cliSetting)) {
34
+ return defaultSettings;
35
+ }
36
+ const cacheSettings = cliSetting['cache'];
37
+ if (!(0, core_1.isJsonObject)(cacheSettings)) {
38
+ return defaultSettings;
39
+ }
40
+ const { path = defaultSettings.path, environment = defaultSettings.environment, enabled = defaultSettings.enabled,
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ } = cacheSettings;
43
+ return {
44
+ path: (0, path_1.resolve)(workspace.basePath, path),
45
+ environment,
46
+ enabled,
47
+ };
48
+ }
49
+ exports.getCacheConfig = getCacheConfig;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC 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 { Argv } from 'yargs';
9
+ import { CommandModule, CommandModuleImplementation } from '../../command-builder/command-module';
10
+ export declare class CompletionCommandModule extends CommandModule implements CommandModuleImplementation {
11
+ command: string;
12
+ describe: string;
13
+ longDescriptionPath: string;
14
+ builder(localYargs: Argv): Argv;
15
+ run(): void;
16
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC 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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CompletionCommandModule = void 0;
14
+ const path_1 = require("path");
15
+ const yargs_1 = __importDefault(require("yargs"));
16
+ const command_module_1 = require("../../command-builder/command-module");
17
+ class CompletionCommandModule extends command_module_1.CommandModule {
18
+ constructor() {
19
+ super(...arguments);
20
+ this.command = 'completion';
21
+ this.describe = 'Generate a bash and zsh real-time type-ahead autocompletion script.';
22
+ this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
23
+ }
24
+ builder(localYargs) {
25
+ return localYargs;
26
+ }
27
+ run() {
28
+ yargs_1.default.showCompletionScript();
29
+ }
30
+ }
31
+ exports.CompletionCommandModule = CompletionCommandModule;
@@ -0,0 +1 @@
1
+ To enable bash and zsh real-time type-ahead autocompletion, copy and paste the generated script to your `.bashrc`, `.bash_profile`, `.zshrc` or `.zsh_profile`.
@@ -8,7 +8,7 @@
8
8
  import { Argv } from 'yargs';
9
9
  import { CommandModule, CommandModuleImplementation, Options } from '../../command-builder/command-module';
10
10
  interface ConfigCommandArgs {
11
- 'json-path': string;
11
+ 'json-path'?: string;
12
12
  value?: string;
13
13
  global?: boolean;
14
14
  }
@@ -16,7 +16,7 @@ const json_file_1 = require("../../utilities/json-file");
16
16
  class ConfigCommandModule extends command_module_1.CommandModule {
17
17
  constructor() {
18
18
  super(...arguments);
19
- this.command = 'config <json-path> [value]';
19
+ this.command = 'config [json-path] [value]';
20
20
  this.describe = 'Retrieves or sets Angular configuration values in the angular.json file for the workspace.';
21
21
  this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
22
22
  }
@@ -26,7 +26,6 @@ class ConfigCommandModule extends command_module_1.CommandModule {
26
26
  description: `The configuration key to set or query, in JSON path format. ` +
27
27
  `For example: "a[3].foo.bar[2]". If no new value is provided, returns the current value of this key.`,
28
28
  type: 'string',
29
- demandOption: true,
30
29
  })
31
30
  .positional('value', {
32
31
  description: 'If provided, a new value for the given configuration key.',
@@ -72,24 +71,22 @@ class ConfigCommandModule extends command_module_1.CommandModule {
72
71
  return 0;
73
72
  }
74
73
  async set(options) {
75
- var _a, _b, _c;
74
+ var _a;
76
75
  if (!((_a = options.jsonPath) === null || _a === void 0 ? void 0 : _a.trim())) {
77
76
  throw new command_module_1.CommandModuleError('Invalid Path.');
78
77
  }
79
- const validCliPaths = new Map([
80
- ['cli.warnings.versionMismatch', undefined],
81
- ['cli.defaultCollection', undefined],
82
- ['cli.packageManager', undefined],
83
- ['cli.analytics', undefined],
84
- ['cli.analyticsSharing.tracking', undefined],
85
- ['cli.analyticsSharing.uuid', (v) => (v === '' ? (0, uuid_1.v4)() : `${v}`)],
86
- ['cli.cache.enabled', undefined],
87
- ['cli.cache.environment', undefined],
88
- ['cli.cache.path', undefined],
78
+ const validGlobalCliPaths = new Set([
79
+ 'cli.warnings.versionMismatch',
80
+ 'cli.defaultCollection',
81
+ 'cli.schematicCollections',
82
+ 'cli.packageManager',
83
+ 'cli.analytics',
84
+ 'cli.analyticsSharing.tracking',
85
+ 'cli.analyticsSharing.uuid',
89
86
  ]);
90
87
  if (options.global &&
91
88
  !options.jsonPath.startsWith('schematics.') &&
92
- !validCliPaths.has(options.jsonPath)) {
89
+ !validGlobalCliPaths.has(options.jsonPath)) {
93
90
  throw new command_module_1.CommandModuleError('Invalid Path.');
94
91
  }
95
92
  const [config, configPath] = (0, config_1.getWorkspaceRaw)(options.global ? 'global' : 'local');
@@ -97,7 +94,10 @@ class ConfigCommandModule extends command_module_1.CommandModule {
97
94
  if (!config || !configPath) {
98
95
  throw new command_module_1.CommandModuleError('Confguration file cannot be found.');
99
96
  }
100
- const value = (_c = (_b = validCliPaths.get(options.jsonPath)) === null || _b === void 0 ? void 0 : _b(options.value)) !== null && _c !== void 0 ? _c : options.value;
97
+ const normalizeUUIDValue = (v) => (v === '' ? (0, uuid_1.v4)() : `${v}`);
98
+ const value = options.jsonPath === 'cli.analyticsSharing.uuid'
99
+ ? normalizeUUIDValue(options.value)
100
+ : options.value;
101
101
  const modified = config.modify(parseJsonPath(options.jsonPath), normalizeValue(value));
102
102
  if (!modified) {
103
103
  logger.error('Value cannot be found.');
@@ -5,10 +5,11 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { MissingTargetChoice } from '../../command-builder/architect-base-command-module';
8
9
  import { ArchitectCommandModule } from '../../command-builder/architect-command-module';
9
10
  import { CommandModuleImplementation } from '../../command-builder/command-module';
10
11
  export declare class DeployCommandModule extends ArchitectCommandModule implements CommandModuleImplementation {
11
- missingErrorTarget: string;
12
+ missingTargetChoices: MissingTargetChoice[];
12
13
  multiTarget: boolean;
13
14
  command: string;
14
15
  longDescriptionPath: string;
@@ -8,24 +8,38 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.DeployCommandModule = void 0;
11
- const core_1 = require("@angular-devkit/core");
12
11
  const path_1 = require("path");
13
12
  const architect_command_module_1 = require("../../command-builder/architect-command-module");
14
13
  class DeployCommandModule extends architect_command_module_1.ArchitectCommandModule {
15
14
  constructor() {
16
15
  super(...arguments);
17
- this.missingErrorTarget = core_1.tags.stripIndents `
18
- Cannot find "deploy" target for the specified project.
19
-
20
- You should add a package that implements deployment capabilities for your
21
- favorite platform.
22
-
23
- For example:
24
- ng add @angular/fire
25
- ng add @azure/ng-deploy
26
-
27
- Find more packages on npm https://www.npmjs.com/search?q=ng%20deploy
28
- `;
16
+ // The below choices should be kept in sync with the list in https://angular.io/guide/deployment
17
+ this.missingTargetChoices = [
18
+ {
19
+ name: 'Amazon S3',
20
+ value: '@jefiozie/ngx-aws-deploy',
21
+ },
22
+ {
23
+ name: 'Azure',
24
+ value: '@azure/ng-deploy',
25
+ },
26
+ {
27
+ name: 'Firebase',
28
+ value: '@angular/fire',
29
+ },
30
+ {
31
+ name: 'Netlify',
32
+ value: '@netlify-builder/deploy',
33
+ },
34
+ {
35
+ name: 'NPM',
36
+ value: 'ngx-deploy-npm',
37
+ },
38
+ {
39
+ name: 'GitHub Pages',
40
+ value: 'angular-cli-ghpages',
41
+ },
42
+ ];
29
43
  this.multiTarget = false;
30
44
  this.command = 'deploy [project]';
31
45
  this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
@@ -16,7 +16,7 @@ export declare class DocCommandModule extends CommandModule<DocCommandArgs> impl
16
16
  command: string;
17
17
  aliases: string[];
18
18
  describe: string;
19
- longDescriptionPath?: string | undefined;
19
+ longDescriptionPath?: string;
20
20
  builder(localYargs: Argv): Argv<DocCommandArgs>;
21
21
  run(options: Options<DocCommandArgs>): Promise<number | void>;
22
22
  }
@@ -5,13 +5,14 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { MissingTargetChoice } from '../../command-builder/architect-base-command-module';
8
9
  import { ArchitectCommandModule } from '../../command-builder/architect-command-module';
9
10
  import { CommandModuleImplementation } from '../../command-builder/command-module';
10
11
  export declare class E2eCommandModule extends ArchitectCommandModule implements CommandModuleImplementation {
12
+ missingTargetChoices: MissingTargetChoice[];
11
13
  multiTarget: boolean;
12
- missingErrorTarget: string;
13
14
  command: string;
14
15
  aliases: string[];
15
16
  describe: string;
16
- longDescriptionPath?: string | undefined;
17
+ longDescriptionPath?: string;
17
18
  }
@@ -8,24 +8,25 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.E2eCommandModule = void 0;
11
- const core_1 = require("@angular-devkit/core");
12
11
  const architect_command_module_1 = require("../../command-builder/architect-command-module");
13
12
  class E2eCommandModule extends architect_command_module_1.ArchitectCommandModule {
14
13
  constructor() {
15
14
  super(...arguments);
15
+ this.missingTargetChoices = [
16
+ {
17
+ name: 'Cypress',
18
+ value: '@cypress/schematic',
19
+ },
20
+ {
21
+ name: 'Nightwatch',
22
+ value: '@nightwatch/schematics',
23
+ },
24
+ {
25
+ name: 'WebdriverIO',
26
+ value: '@wdio/schematics',
27
+ },
28
+ ];
16
29
  this.multiTarget = true;
17
- this.missingErrorTarget = core_1.tags.stripIndents `
18
- Cannot find "e2e" target for the specified project.
19
-
20
- You should add a package that implements end-to-end testing capabilities.
21
-
22
- For example:
23
- Cypress: ng add @cypress/schematic
24
- Nightwatch: ng add @nightwatch/schematics
25
- WebdriverIO: ng add @wdio/schematics
26
-
27
- More options will be added to the list as they become available.
28
- `;
29
30
  this.command = 'e2e [project]';
30
31
  this.aliases = ['e'];
31
32
  this.describe = 'Builds and serves an Angular application, then runs end-to-end tests.';
@@ -18,12 +18,22 @@ export declare class GenerateCommandModule extends SchematicsCommandModule imple
18
18
  longDescriptionPath?: string | undefined;
19
19
  builder(argv: Argv): Promise<Argv<GenerateCommandArgs>>;
20
20
  run(options: Options<GenerateCommandArgs> & OtherOptions): Promise<number | void>;
21
- private getCollectionName;
21
+ private getCollectionNames;
22
22
  /**
23
23
  * Generate a command string to be passed to the command builder.
24
24
  *
25
25
  * @example `component [name]` or `@schematics/angular:component [name]`.
26
26
  */
27
27
  private generateCommandString;
28
+ /**
29
+ * Get schematics that can to be registered as subcommands.
30
+ */
31
+ private getSchematics;
32
+ /**
33
+ * Get schematics that should to be registered as subcommands.
34
+ *
35
+ * @returns a sorted list of schematic that needs to be registered as subcommands.
36
+ */
37
+ private getSchematicsToRegister;
28
38
  }
29
39
  export {};
@@ -9,6 +9,7 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.GenerateCommandModule = void 0;
11
11
  const core_1 = require("@angular-devkit/core");
12
+ const command_module_1 = require("../../command-builder/command-module");
12
13
  const schematics_command_module_1 = require("../../command-builder/schematics-command-module");
13
14
  const command_1 = require("../../command-builder/utilities/command");
14
15
  class GenerateCommandModule extends schematics_command_module_1.SchematicsCommandModule {
@@ -31,26 +32,14 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
31
32
  .strict(),
32
33
  handler: (options) => this.handler(options),
33
34
  });
34
- const collectionName = await this.getCollectionName();
35
- const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
36
- const collection = workflow.engine.createCollection(collectionName);
37
- const schematicsInCollection = collection.description.schematics;
38
- // We cannot use `collection.listSchematicNames()` as this doesn't return hidden schematics.
39
- const schematicNames = new Set(Object.keys(schematicsInCollection).sort());
40
- const [, schematicNameFromArgs] = this.parseSchematicInfo(
41
- // positional = [generate, component] or [generate]
42
- this.context.args.positional[1]);
43
- if (schematicNameFromArgs && schematicNames.has(schematicNameFromArgs)) {
44
- // No need to process all schematics since we know which one the user invoked.
45
- schematicNames.clear();
46
- schematicNames.add(schematicNameFromArgs);
47
- }
48
- for (const schematicName of schematicNames) {
49
- const { description: { schemaJson, aliases: schematicAliases, hidden: schematicHidden }, } = collection.createSchematic(schematicName, true);
35
+ for (const [schematicName, collectionName] of await this.getSchematicsToRegister()) {
36
+ const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
37
+ const collection = workflow.engine.createCollection(collectionName);
38
+ const { description: { schemaJson, aliases: schematicAliases, hidden: schematicHidden, description: schematicDescription, }, } = collection.createSchematic(schematicName, true);
50
39
  if (!schemaJson) {
51
40
  continue;
52
41
  }
53
- const { description, 'x-deprecated': xDeprecated, aliases = schematicAliases, hidden = schematicHidden, } = schemaJson;
42
+ const { 'x-deprecated': xDeprecated, description = schematicDescription, aliases = schematicAliases, hidden = schematicHidden, } = schemaJson;
54
43
  const options = await this.getSchematicOptions(collection, schematicName, workflow);
55
44
  localYargs = localYargs.command({
56
45
  command: await this.generateCommandString(collectionName, schematicName, options),
@@ -66,7 +55,10 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
66
55
  }
67
56
  async run(options) {
68
57
  const { dryRun, schematic, defaults, force, interactive, ...schematicOptions } = options;
69
- const [collectionName = await this.getCollectionName(), schematicName = ''] = this.parseSchematicInfo(schematic);
58
+ const [collectionName, schematicName] = this.parseSchematicInfo(schematic);
59
+ if (!collectionName || !schematicName) {
60
+ throw new command_module_1.CommandModuleError('A collection and schematic is required during execution.');
61
+ }
70
62
  return this.runSchematic({
71
63
  collectionName,
72
64
  schematicName,
@@ -79,11 +71,11 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
79
71
  },
80
72
  });
81
73
  }
82
- async getCollectionName() {
83
- const [collectionName = await this.getDefaultSchematicCollection()] = this.parseSchematicInfo(
74
+ async getCollectionNames() {
75
+ const [collectionName] = this.parseSchematicInfo(
84
76
  // positional = [generate, component] or [generate]
85
77
  this.context.args.positional[1]);
86
- return collectionName;
78
+ return collectionName ? [collectionName] : [...(await this.getSchematicCollections())];
87
79
  }
88
80
  /**
89
81
  * Generate a command string to be passed to the command builder.
@@ -95,10 +87,13 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
95
87
  // positional = [generate, component] or [generate]
96
88
  this.context.args.positional[1]);
97
89
  const dasherizedSchematicName = core_1.strings.dasherize(schematicName);
98
- // Only add the collection name as part of the command when it's not the default collection or when it has been provided via the CLI.
90
+ const schematicCollectionsFromConfig = await this.getSchematicCollections();
91
+ const collectionNames = await this.getCollectionNames();
92
+ // Only add the collection name as part of the command when it's not a known
93
+ // schematics collection or when it has been provided via the CLI.
99
94
  // Ex:`ng generate @schematics/angular:component`
100
95
  const commandName = !!collectionNameFromArgs ||
101
- (await this.getDefaultSchematicCollection()) !== (await this.getCollectionName())
96
+ !collectionNames.some((c) => schematicCollectionsFromConfig.has(c))
102
97
  ? collectionName + ':' + dasherizedSchematicName
103
98
  : dasherizedSchematicName;
104
99
  const positionalArgs = options
@@ -110,5 +105,41 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
110
105
  .join(' ');
111
106
  return `${commandName}${positionalArgs ? ' ' + positionalArgs : ''}`;
112
107
  }
108
+ /**
109
+ * Get schematics that can to be registered as subcommands.
110
+ */
111
+ async *getSchematics() {
112
+ const seenNames = new Set();
113
+ for (const collectionName of await this.getCollectionNames()) {
114
+ const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
115
+ const collection = workflow.engine.createCollection(collectionName);
116
+ for (const schematicName of collection.listSchematicNames(true /** includeHidden */)) {
117
+ // If a schematic with this same name is already registered skip.
118
+ if (!seenNames.has(schematicName)) {
119
+ seenNames.add(schematicName);
120
+ yield { schematicName, collectionName };
121
+ }
122
+ }
123
+ }
124
+ }
125
+ /**
126
+ * Get schematics that should to be registered as subcommands.
127
+ *
128
+ * @returns a sorted list of schematic that needs to be registered as subcommands.
129
+ */
130
+ async getSchematicsToRegister() {
131
+ const schematicsToRegister = [];
132
+ const [, schematicNameFromArgs] = this.parseSchematicInfo(
133
+ // positional = [generate, component] or [generate]
134
+ this.context.args.positional[1]);
135
+ for await (const { schematicName, collectionName } of this.getSchematics()) {
136
+ if (schematicName === schematicNameFromArgs) {
137
+ return [[schematicName, collectionName]];
138
+ }
139
+ schematicsToRegister.push([schematicName, collectionName]);
140
+ }
141
+ // Didn't find the schematic or no schematic name was provided Ex: `ng generate --help`.
142
+ return schematicsToRegister.sort(([nameA], [nameB]) => nameA.localeCompare(nameB, undefined, { sensitivity: 'accent' }));
143
+ }
113
144
  }
114
145
  exports.GenerateCommandModule = GenerateCommandModule;
@@ -5,10 +5,11 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { MissingTargetChoice } from '../../command-builder/architect-base-command-module';
8
9
  import { ArchitectCommandModule } from '../../command-builder/architect-command-module';
9
10
  import { CommandModuleImplementation } from '../../command-builder/command-module';
10
11
  export declare class LintCommandModule extends ArchitectCommandModule implements CommandModuleImplementation {
11
- missingErrorTarget: string;
12
+ missingTargetChoices: MissingTargetChoice[];
12
13
  multiTarget: boolean;
13
14
  command: string;
14
15
  longDescriptionPath: string;
@@ -8,20 +8,17 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.LintCommandModule = void 0;
11
- const core_1 = require("@angular-devkit/core");
12
11
  const path_1 = require("path");
13
12
  const architect_command_module_1 = require("../../command-builder/architect-command-module");
14
13
  class LintCommandModule extends architect_command_module_1.ArchitectCommandModule {
15
14
  constructor() {
16
15
  super(...arguments);
17
- this.missingErrorTarget = core_1.tags.stripIndents `
18
- Cannot find "lint" target for the specified project.
19
-
20
- You should add a package that implements linting capabilities.
21
-
22
- For example:
23
- ng add @angular-eslint/schematics
24
- `;
16
+ this.missingTargetChoices = [
17
+ {
18
+ name: 'ESLint',
19
+ value: '@angular-eslint/schematics',
20
+ },
21
+ ];
25
22
  this.multiTarget = true;
26
23
  this.command = 'lint [project]';
27
24
  this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
@@ -21,5 +21,7 @@ export declare class NewCommandModule extends SchematicsCommandModule implements
21
21
  longDescriptionPath?: string | undefined;
22
22
  builder(argv: Argv): Promise<Argv<NewCommandArgs>>;
23
23
  run(options: Options<NewCommandArgs> & OtherOptions): Promise<number | void>;
24
+ /** Find a collection from config that has an `ng-new` schematic. */
25
+ private getCollectionFromConfig;
24
26
  }
25
27
  export {};
@@ -10,7 +10,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.NewCommandModule = void 0;
11
11
  const command_module_1 = require("../../command-builder/command-module");
12
12
  const schematics_command_module_1 = require("../../command-builder/schematics-command-module");
13
- const package_manager_1 = require("../../utilities/package-manager");
14
13
  const version_1 = require("../../utilities/version");
15
14
  class NewCommandModule extends schematics_command_module_1.SchematicsCommandModule {
16
15
  constructor() {
@@ -30,7 +29,7 @@ class NewCommandModule extends schematics_command_module_1.SchematicsCommandModu
30
29
  const { options: { collectionNameFromArgs }, } = this.context.args;
31
30
  const collectionName = typeof collectionNameFromArgs === 'string'
32
31
  ? collectionNameFromArgs
33
- : await this.getDefaultSchematicCollection();
32
+ : await this.getCollectionFromConfig();
34
33
  const workflow = await this.getOrCreateWorkflowForBuilder(collectionName);
35
34
  const collection = workflow.engine.createCollection(collectionName);
36
35
  const options = await this.getSchematicOptions(collection, this.schematicName, workflow);
@@ -39,15 +38,20 @@ class NewCommandModule extends schematics_command_module_1.SchematicsCommandModu
39
38
  async run(options) {
40
39
  var _a;
41
40
  // Register the version of the CLI in the registry.
42
- const collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : (await this.getDefaultSchematicCollection());
43
- const workflow = await this.getOrCreateWorkflowForExecution(collectionName, options);
44
- workflow.registry.addSmartDefaultProvider('ng-cli-version', () => version_1.VERSION.full);
41
+ const collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : (await this.getCollectionFromConfig());
45
42
  const { dryRun, force, interactive, defaults, collection, ...schematicOptions } = options;
43
+ const workflow = await this.getOrCreateWorkflowForExecution(collectionName, {
44
+ dryRun,
45
+ force,
46
+ interactive,
47
+ defaults,
48
+ });
49
+ workflow.registry.addSmartDefaultProvider('ng-cli-version', () => version_1.VERSION.full);
46
50
  // Compatibility check for NPM 7
47
51
  if (collectionName === '@schematics/angular' &&
48
52
  !schematicOptions.skipInstall &&
49
53
  (schematicOptions.packageManager === undefined || schematicOptions.packageManager === 'npm')) {
50
- await (0, package_manager_1.ensureCompatibleNpm)(this.context.root);
54
+ this.context.packageManager.ensureCompatibility();
51
55
  }
52
56
  return this.runSchematic({
53
57
  collectionName,
@@ -61,6 +65,18 @@ class NewCommandModule extends schematics_command_module_1.SchematicsCommandModu
61
65
  },
62
66
  });
63
67
  }
68
+ /** Find a collection from config that has an `ng-new` schematic. */
69
+ async getCollectionFromConfig() {
70
+ for (const collectionName of await this.getSchematicCollections()) {
71
+ const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
72
+ const collection = workflow.engine.createCollection(collectionName);
73
+ const schematicsInCollection = collection.description.schematics;
74
+ if (Object.keys(schematicsInCollection).includes(this.schematicName)) {
75
+ return collectionName;
76
+ }
77
+ }
78
+ return schematics_command_module_1.DEFAULT_SCHEMATICS_COLLECTION;
79
+ }
64
80
  }
65
81
  exports.NewCommandModule = NewCommandModule;
66
82
  NewCommandModule.scope = command_module_1.CommandScope.Out;
@@ -20,4 +20,6 @@ export declare class RunCommandModule extends ArchitectBaseCommandModule<RunComm
20
20
  builder(argv: Argv): Promise<Argv<RunCommandArgs>>;
21
21
  run(options: Options<RunCommandArgs> & OtherOptions): Promise<number>;
22
22
  protected makeTargetSpecifier(options?: Options<RunCommandArgs>): Target | undefined;
23
+ /** @returns a sorted list of target specifiers to be used for auto completion. */
24
+ private getTargetChoices;
23
25
  }
@@ -19,11 +19,15 @@ class RunCommandModule extends architect_base_command_module_1.ArchitectBaseComm
19
19
  this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
20
20
  }
21
21
  async builder(argv) {
22
+ const { jsonHelp, getYargsCompletions, help } = this.context.args.options;
22
23
  const localYargs = argv
23
24
  .positional('target', {
24
25
  describe: 'The Architect target to run.',
25
26
  type: 'string',
26
27
  demandOption: true,
28
+ // Show only in when using --help and auto completion because otherwise comma seperated configuration values will be invalid.
29
+ // Also, hide choices from JSON help so that we don't display them in AIO.
30
+ choices: (getYargsCompletions || help) && !jsonHelp ? this.getTargetChoices() : undefined,
27
31
  })
28
32
  .strict();
29
33
  const target = this.makeTargetSpecifier();
@@ -54,6 +58,26 @@ class RunCommandModule extends architect_base_command_module_1.ArchitectBaseComm
54
58
  configuration,
55
59
  };
56
60
  }
61
+ /** @returns a sorted list of target specifiers to be used for auto completion. */
62
+ getTargetChoices() {
63
+ if (!this.context.workspace) {
64
+ return;
65
+ }
66
+ const targets = [];
67
+ for (const [projectName, project] of this.context.workspace.projects) {
68
+ for (const [targetName, target] of project.targets) {
69
+ const currentTarget = `${projectName}:${targetName}`;
70
+ targets.push(currentTarget);
71
+ if (!target.configurations) {
72
+ continue;
73
+ }
74
+ for (const configName of Object.keys(target.configurations)) {
75
+ targets.push(`${currentTarget}:${configName}`);
76
+ }
77
+ }
78
+ }
79
+ return targets.sort();
80
+ }
57
81
  }
58
82
  exports.RunCommandModule = RunCommandModule;
59
83
  RunCommandModule.scope = command_module_1.CommandScope.In;
@@ -50,5 +50,6 @@ export declare class UpdateCommandModule extends CommandModule<UpdateCommandArgs
50
50
  */
51
51
  private checkCLIVersion;
52
52
  private getCLIUpdateRunnerVersion;
53
+ private runTempBinary;
53
54
  }
54
55
  export {};