@angular/cli 14.0.0-next.5 → 14.0.0-next.8

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 (108) 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 +26 -7
  4. package/lib/config/workspace-schema.d.ts +6 -1
  5. package/lib/init.js +7 -6
  6. package/package.json +17 -20
  7. package/src/analytics/analytics-collector.js +7 -1
  8. package/src/analytics/analytics.d.ts +10 -23
  9. package/src/analytics/analytics.js +99 -184
  10. package/src/command-builder/architect-base-command-module.d.ts +8 -1
  11. package/src/command-builder/architect-base-command-module.js +61 -7
  12. package/src/command-builder/architect-command-module.d.ts +0 -1
  13. package/src/command-builder/architect-command-module.js +16 -12
  14. package/src/command-builder/command-module.d.ts +5 -2
  15. package/src/command-builder/command-module.js +21 -8
  16. package/src/command-builder/command-runner.d.ts +1 -2
  17. package/src/command-builder/command-runner.js +54 -48
  18. package/src/command-builder/schematics-command-module.d.ts +19 -7
  19. package/src/command-builder/schematics-command-module.js +268 -50
  20. package/src/command-builder/utilities/command.d.ts +13 -0
  21. package/src/command-builder/utilities/command.js +27 -0
  22. package/src/command-builder/utilities/json-help.d.ts +16 -14
  23. package/src/command-builder/utilities/json-help.js +26 -22
  24. package/{models → src/command-builder/utilities}/schematic-engine-host.d.ts +0 -0
  25. package/{models → src/command-builder/utilities}/schematic-engine-host.js +0 -0
  26. package/src/command-builder/utilities/schematic-workflow.d.ts +14 -0
  27. package/src/command-builder/utilities/schematic-workflow.js +68 -0
  28. package/src/commands/add/cli.d.ts +11 -1
  29. package/src/commands/add/cli.js +325 -6
  30. package/src/commands/add/long-description.md +1 -4
  31. package/src/commands/analytics/cli.d.ts +5 -10
  32. package/src/commands/analytics/cli.js +15 -50
  33. package/src/commands/analytics/info/cli.d.ts +16 -0
  34. package/src/commands/analytics/info/cli.js +26 -0
  35. package/src/commands/analytics/settings/cli.d.ts +35 -0
  36. package/src/commands/analytics/settings/cli.js +61 -0
  37. package/src/commands/cache/clean/cli.d.ts +17 -0
  38. package/src/commands/cache/clean/cli.js +32 -0
  39. package/src/commands/cache/cli.d.ts +17 -0
  40. package/src/commands/cache/cli.js +38 -0
  41. package/src/commands/cache/info/cli.d.ts +20 -0
  42. package/src/commands/cache/info/cli.js +82 -0
  43. package/src/commands/cache/long-description.md +53 -0
  44. package/src/commands/cache/settings/cli.d.ts +27 -0
  45. package/src/commands/cache/settings/cli.js +42 -0
  46. package/src/commands/cache/utilities.d.ts +11 -0
  47. package/src/commands/cache/utilities.js +50 -0
  48. package/src/commands/config/cli.d.ts +5 -2
  49. package/src/commands/config/cli.js +128 -6
  50. package/src/commands/deploy/cli.d.ts +2 -1
  51. package/src/commands/deploy/cli.js +27 -13
  52. package/src/commands/doc/cli.d.ts +1 -1
  53. package/src/commands/doc/cli.js +5 -1
  54. package/src/commands/e2e/cli.d.ts +3 -2
  55. package/src/commands/e2e/cli.js +14 -13
  56. package/src/commands/generate/cli.d.ts +14 -2
  57. package/src/commands/generate/cli.js +83 -36
  58. package/src/commands/lint/cli.d.ts +2 -1
  59. package/src/commands/lint/cli.js +6 -9
  60. package/src/commands/new/cli.d.ts +7 -3
  61. package/src/commands/new/cli.js +52 -6
  62. package/src/commands/update/cli.d.ts +31 -5
  63. package/src/commands/update/cli.js +709 -8
  64. package/src/commands/update/schematic/index.js +32 -19
  65. package/src/commands/version/cli.d.ts +0 -1
  66. package/src/commands/version/cli.js +19 -43
  67. package/src/typings-bazel.d.ts +14 -0
  68. package/src/typings.d.ts +0 -13
  69. package/src/utilities/color.js +5 -1
  70. package/src/utilities/config.d.ts +1 -1
  71. package/src/utilities/config.js +22 -11
  72. package/src/utilities/environment-options.d.ts +12 -0
  73. package/src/utilities/environment-options.js +24 -0
  74. package/src/utilities/find-up.js +5 -1
  75. package/src/utilities/memoize.d.ts +15 -0
  76. package/src/utilities/memoize.js +69 -0
  77. package/src/utilities/package-manager.d.ts +33 -5
  78. package/src/utilities/package-manager.js +252 -71
  79. package/src/utilities/package-metadata.d.ts +15 -37
  80. package/src/utilities/package-metadata.js +15 -27
  81. package/src/utilities/package-tree.d.ts +2 -2
  82. package/src/utilities/package-tree.js +5 -1
  83. package/src/utilities/project.js +5 -1
  84. package/src/utilities/prompt.d.ts +2 -0
  85. package/src/utilities/prompt.js +25 -4
  86. package/bin/postinstall/analytics-prompt.js +0 -27
  87. package/bin/postinstall/script.js +0 -16
  88. package/models/command.d.ts +0 -29
  89. package/models/command.js +0 -50
  90. package/models/interface.d.ts +0 -19
  91. package/models/interface.js +0 -9
  92. package/models/schematic-command.d.ts +0 -43
  93. package/models/schematic-command.js +0 -378
  94. package/src/commands/add/add-impl.d.ts +0 -22
  95. package/src/commands/add/add-impl.js +0 -331
  96. package/src/commands/analytics/long-description.md +0 -10
  97. package/src/commands/config/config-impl.d.ts +0 -17
  98. package/src/commands/config/config-impl.js +0 -151
  99. package/src/commands/generate/generate-impl.d.ts +0 -19
  100. package/src/commands/generate/generate-impl.js +0 -49
  101. package/src/commands/new/new-impl.d.ts +0 -18
  102. package/src/commands/new/new-impl.js +0 -38
  103. package/src/commands/update/update-impl.d.ts +0 -40
  104. package/src/commands/update/update-impl.js +0 -728
  105. package/src/utilities/install-package.d.ts +0 -16
  106. package/src/utilities/install-package.js +0 -193
  107. package/src/utilities/package-json.d.ts +0 -249
  108. package/src/utilities/package-json.js +0 -9
@@ -9,12 +9,14 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.ConfigCommandModule = void 0;
11
11
  const path_1 = require("path");
12
+ const uuid_1 = require("uuid");
12
13
  const command_module_1 = require("../../command-builder/command-module");
13
- const config_impl_1 = require("./config-impl");
14
+ const config_1 = require("../../utilities/config");
15
+ const json_file_1 = require("../../utilities/json-file");
14
16
  class ConfigCommandModule extends command_module_1.CommandModule {
15
17
  constructor() {
16
18
  super(...arguments);
17
- this.command = 'config <json-path> [value]';
19
+ this.command = 'config [json-path] [value]';
18
20
  this.describe = 'Retrieves or sets Angular configuration values in the angular.json file for the workspace.';
19
21
  this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
20
22
  }
@@ -24,7 +26,6 @@ class ConfigCommandModule extends command_module_1.CommandModule {
24
26
  description: `The configuration key to set or query, in JSON path format. ` +
25
27
  `For example: "a[3].foo.bar[2]". If no new value is provided, returns the current value of this key.`,
26
28
  type: 'string',
27
- demandOption: true,
28
29
  })
29
30
  .positional('value', {
30
31
  description: 'If provided, a new value for the given configuration key.',
@@ -38,9 +39,130 @@ class ConfigCommandModule extends command_module_1.CommandModule {
38
39
  })
39
40
  .strict();
40
41
  }
41
- run(options) {
42
- const command = new config_impl_1.ConfigCommand(this.context, 'config');
43
- return command.validateAndRun(options);
42
+ async run(options) {
43
+ const level = options.global ? 'global' : 'local';
44
+ const [config] = (0, config_1.getWorkspaceRaw)(level);
45
+ if (options.value == undefined) {
46
+ if (!config) {
47
+ this.context.logger.error('No config found.');
48
+ return 1;
49
+ }
50
+ return this.get(config, options);
51
+ }
52
+ else {
53
+ return this.set(options);
54
+ }
55
+ }
56
+ get(jsonFile, options) {
57
+ const { logger } = this.context;
58
+ const value = options.jsonPath
59
+ ? jsonFile.get(parseJsonPath(options.jsonPath))
60
+ : jsonFile.content;
61
+ if (value === undefined) {
62
+ logger.error('Value cannot be found.');
63
+ return 1;
64
+ }
65
+ else if (typeof value === 'string') {
66
+ logger.info(value);
67
+ }
68
+ else {
69
+ logger.info(JSON.stringify(value, null, 2));
70
+ }
71
+ return 0;
72
+ }
73
+ async set(options) {
74
+ var _a, _b, _c;
75
+ if (!((_a = options.jsonPath) === null || _a === void 0 ? void 0 : _a.trim())) {
76
+ throw new command_module_1.CommandModuleError('Invalid Path.');
77
+ }
78
+ const validCliPaths = new Map([
79
+ ['cli.warnings.versionMismatch', undefined],
80
+ ['cli.defaultCollection', undefined],
81
+ ['cli.schematicCollections', 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],
89
+ ]);
90
+ if (options.global &&
91
+ !options.jsonPath.startsWith('schematics.') &&
92
+ !validCliPaths.has(options.jsonPath)) {
93
+ throw new command_module_1.CommandModuleError('Invalid Path.');
94
+ }
95
+ const [config, configPath] = (0, config_1.getWorkspaceRaw)(options.global ? 'global' : 'local');
96
+ const { logger } = this.context;
97
+ if (!config || !configPath) {
98
+ throw new command_module_1.CommandModuleError('Confguration file cannot be found.');
99
+ }
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;
101
+ const modified = config.modify(parseJsonPath(options.jsonPath), normalizeValue(value));
102
+ if (!modified) {
103
+ logger.error('Value cannot be found.');
104
+ return 1;
105
+ }
106
+ await (0, config_1.validateWorkspace)((0, json_file_1.parseJson)(config.content));
107
+ config.save();
108
+ return 0;
44
109
  }
45
110
  }
46
111
  exports.ConfigCommandModule = ConfigCommandModule;
112
+ /**
113
+ * Splits a JSON path string into fragments. Fragments can be used to get the value referenced
114
+ * by the path. For example, a path of "a[3].foo.bar[2]" would give you a fragment array of
115
+ * ["a", 3, "foo", "bar", 2].
116
+ * @param path The JSON string to parse.
117
+ * @returns {(string|number)[]} The fragments for the string.
118
+ * @private
119
+ */
120
+ function parseJsonPath(path) {
121
+ const fragments = (path || '').split(/\./g);
122
+ const result = [];
123
+ while (fragments.length > 0) {
124
+ const fragment = fragments.shift();
125
+ if (fragment == undefined) {
126
+ break;
127
+ }
128
+ const match = fragment.match(/([^[]+)((\[.*\])*)/);
129
+ if (!match) {
130
+ throw new command_module_1.CommandModuleError('Invalid JSON path.');
131
+ }
132
+ result.push(match[1]);
133
+ if (match[2]) {
134
+ const indices = match[2]
135
+ .slice(1, -1)
136
+ .split('][')
137
+ .map((x) => (/^\d$/.test(x) ? +x : x.replace(/"|'/g, '')));
138
+ result.push(...indices);
139
+ }
140
+ }
141
+ return result.filter((fragment) => fragment != null);
142
+ }
143
+ function normalizeValue(value) {
144
+ const valueString = `${value}`.trim();
145
+ switch (valueString) {
146
+ case 'true':
147
+ return true;
148
+ case 'false':
149
+ return false;
150
+ case 'null':
151
+ return null;
152
+ case 'undefined':
153
+ return undefined;
154
+ }
155
+ if (isFinite(+valueString)) {
156
+ return +valueString;
157
+ }
158
+ try {
159
+ // We use `JSON.parse` instead of `parseJson` because the latter will parse UUIDs
160
+ // and convert them into a numberic entities.
161
+ // Example: 73b61974-182c-48e4-b4c6-30ddf08c5c98 -> 73.
162
+ // These values should never contain comments, therefore using `JSON.parse` is safe.
163
+ return JSON.parse(valueString);
164
+ }
165
+ catch {
166
+ return value;
167
+ }
168
+ }
@@ -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
  }
@@ -8,7 +8,11 @@
8
8
  */
9
9
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
10
  if (k2 === undefined) k2 = k;
11
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
12
16
  }) : (function(o, m, k, k2) {
13
17
  if (k2 === undefined) k2 = k;
14
18
  o[k2] = m[k];
@@ -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.';
@@ -8,7 +8,7 @@
8
8
  import { Argv } from 'yargs';
9
9
  import { CommandModuleImplementation, Options, OtherOptions } from '../../command-builder/command-module';
10
10
  import { SchematicsCommandArgs, SchematicsCommandModule } from '../../command-builder/schematics-command-module';
11
- export interface GenerateCommandArgs extends SchematicsCommandArgs {
11
+ interface GenerateCommandArgs extends SchematicsCommandArgs {
12
12
  schematic?: string;
13
13
  }
14
14
  export declare class GenerateCommandModule extends SchematicsCommandModule implements CommandModuleImplementation<GenerateCommandArgs> {
@@ -17,11 +17,23 @@ export declare class GenerateCommandModule extends SchematicsCommandModule imple
17
17
  describe: string;
18
18
  longDescriptionPath?: string | undefined;
19
19
  builder(argv: Argv): Promise<Argv<GenerateCommandArgs>>;
20
- run(options: Options<GenerateCommandArgs> & OtherOptions): number | void | Promise<number | void>;
20
+ run(options: Options<GenerateCommandArgs> & OtherOptions): Promise<number | void>;
21
+ private getCollectionNames;
21
22
  /**
22
23
  * Generate a command string to be passed to the command builder.
23
24
  *
24
25
  * @example `component [name]` or `@schematics/angular:component [name]`.
25
26
  */
26
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;
27
38
  }
39
+ export {};
@@ -9,49 +9,37 @@
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
- const generate_impl_1 = require("./generate-impl");
14
+ const command_1 = require("../../command-builder/utilities/command");
14
15
  class GenerateCommandModule extends schematics_command_module_1.SchematicsCommandModule {
15
16
  constructor() {
16
17
  super(...arguments);
17
- this.command = 'generate [schematic]';
18
+ this.command = 'generate';
18
19
  this.aliases = 'g';
19
20
  this.describe = 'Generates and/or modifies files based on a schematic.';
20
21
  }
21
22
  async builder(argv) {
22
- const [, schematicNameFromArgs] = this.parseSchematicInfo(
23
- // positional = [generate, component] or [generate]
24
- this.context.args.positional[1]);
25
- const baseYargs = await super.builder(argv);
26
- if (this.schematicName) {
27
- return baseYargs;
28
- }
29
- // When we do know the schematic name we need to add the 'schematic'
30
- // positional option as the schematic will be accessable as a subcommand.
31
- let localYargs = schematicNameFromArgs
32
- ? baseYargs
33
- : baseYargs.positional('schematic', {
34
- describe: 'The schematic or collection:schematic to generate.',
23
+ let localYargs = (await super.builder(argv)).command({
24
+ command: '$0 <schematic>',
25
+ describe: 'Run the provided schematic.',
26
+ builder: (localYargs) => localYargs
27
+ .positional('schematic', {
28
+ describe: 'The [collection:schematic] to run.',
35
29
  type: 'string',
36
30
  demandOption: true,
37
- });
38
- const collectionName = await this.getCollectionName();
39
- const workflow = this.getOrCreateWorkflow(collectionName);
40
- const collection = workflow.engine.createCollection(collectionName);
41
- const schematicsInCollection = collection.description.schematics;
42
- // We cannot use `collection.listSchematicNames()` as this doesn't return hidden schematics.
43
- const schematicNames = new Set(Object.keys(schematicsInCollection).sort());
44
- if (schematicNameFromArgs && schematicNames.has(schematicNameFromArgs)) {
45
- // No need to process all schematics since we know which one the user invoked.
46
- schematicNames.clear();
47
- schematicNames.add(schematicNameFromArgs);
48
- }
49
- for (const schematicName of schematicNames) {
50
- const { description: { schemaJson, aliases: schematicAliases, hidden: schematicHidden }, } = collection.createSchematic(schematicName, true);
31
+ })
32
+ .strict(),
33
+ handler: (options) => this.handler(options),
34
+ });
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);
51
39
  if (!schemaJson) {
52
40
  continue;
53
41
  }
54
- const { description, 'x-deprecated': xDeprecated, aliases = schematicAliases, hidden = schematicHidden, } = schemaJson;
42
+ const { 'x-deprecated': xDeprecated, description = schematicDescription, aliases = schematicAliases, hidden = schematicHidden, } = schemaJson;
55
43
  const options = await this.getSchematicOptions(collection, schematicName, workflow);
56
44
  localYargs = localYargs.command({
57
45
  command: await this.generateCommandString(collectionName, schematicName, options),
@@ -63,11 +51,31 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
63
51
  handler: (options) => this.handler({ ...options, schematic: `${collectionName}:${schematicName}` }),
64
52
  });
65
53
  }
66
- return localYargs;
54
+ return localYargs.demandCommand(1, command_1.demandCommandFailureMessage);
67
55
  }
68
- run(options) {
69
- const command = new generate_impl_1.GenerateCommand(this.context, 'generate');
70
- return command.validateAndRun(options);
56
+ async run(options) {
57
+ const { dryRun, schematic, defaults, force, interactive, ...schematicOptions } = options;
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
+ }
62
+ return this.runSchematic({
63
+ collectionName,
64
+ schematicName,
65
+ schematicOptions,
66
+ executionOptions: {
67
+ dryRun,
68
+ defaults,
69
+ force,
70
+ interactive,
71
+ },
72
+ });
73
+ }
74
+ async getCollectionNames() {
75
+ const [collectionName] = this.parseSchematicInfo(
76
+ // positional = [generate, component] or [generate]
77
+ this.context.args.positional[1]);
78
+ return collectionName ? [collectionName] : [...(await this.getSchematicCollections())];
71
79
  }
72
80
  /**
73
81
  * Generate a command string to be passed to the command builder.
@@ -79,10 +87,13 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
79
87
  // positional = [generate, component] or [generate]
80
88
  this.context.args.positional[1]);
81
89
  const dasherizedSchematicName = core_1.strings.dasherize(schematicName);
82
- // 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.
83
94
  // Ex:`ng generate @schematics/angular:component`
84
95
  const commandName = !!collectionNameFromArgs ||
85
- (await this.getDefaultSchematicCollection()) !== (await this.getCollectionName())
96
+ !collectionNames.some((c) => schematicCollectionsFromConfig.has(c))
86
97
  ? collectionName + ':' + dasherizedSchematicName
87
98
  : dasherizedSchematicName;
88
99
  const positionalArgs = options
@@ -94,5 +105,41 @@ class GenerateCommandModule extends schematics_command_module_1.SchematicsComman
94
105
  .join(' ');
95
106
  return `${commandName}${positionalArgs ? ' ' + positionalArgs : ''}`;
96
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
+ }
97
144
  }
98
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');
@@ -8,16 +8,20 @@
8
8
  import { Argv } from 'yargs';
9
9
  import { CommandModuleImplementation, CommandScope, Options, OtherOptions } from '../../command-builder/command-module';
10
10
  import { SchematicsCommandArgs, SchematicsCommandModule } from '../../command-builder/schematics-command-module';
11
- export interface NewCommandArgs extends SchematicsCommandArgs {
11
+ interface NewCommandArgs extends SchematicsCommandArgs {
12
12
  collection?: string;
13
13
  }
14
14
  export declare class NewCommandModule extends SchematicsCommandModule implements CommandModuleImplementation<NewCommandArgs> {
15
- protected schematicName: string;
15
+ private readonly schematicName;
16
16
  static scope: CommandScope;
17
+ protected allowPrivateSchematics: boolean;
17
18
  command: string;
18
19
  aliases: string;
19
20
  describe: string;
20
21
  longDescriptionPath?: string | undefined;
21
22
  builder(argv: Argv): Promise<Argv<NewCommandArgs>>;
22
- run(options: Options<NewCommandArgs> & OtherOptions): number | void | Promise<number | void>;
23
+ run(options: Options<NewCommandArgs> & OtherOptions): Promise<number | void>;
24
+ /** Find a collection from config that has an `ng-new` schematic. */
25
+ private getCollectionFromConfig;
23
26
  }
27
+ export {};
@@ -10,26 +10,72 @@ 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 new_impl_1 = require("./new-impl");
13
+ const version_1 = require("../../utilities/version");
14
14
  class NewCommandModule extends schematics_command_module_1.SchematicsCommandModule {
15
15
  constructor() {
16
16
  super(...arguments);
17
17
  this.schematicName = 'ng-new';
18
+ this.allowPrivateSchematics = true;
18
19
  this.command = 'new [name]';
19
20
  this.aliases = 'n';
20
21
  this.describe = 'Creates a new Angular workspace.';
21
22
  }
22
23
  async builder(argv) {
23
- const baseYargs = await super.builder(argv);
24
- return baseYargs.option('collection', {
24
+ const localYargs = (await super.builder(argv)).option('collection', {
25
25
  alias: 'c',
26
26
  describe: 'A collection of schematics to use in generating the initial application.',
27
27
  type: 'string',
28
28
  });
29
+ const { options: { collectionNameFromArgs }, } = this.context.args;
30
+ const collectionName = typeof collectionNameFromArgs === 'string'
31
+ ? collectionNameFromArgs
32
+ : await this.getCollectionFromConfig();
33
+ const workflow = await this.getOrCreateWorkflowForBuilder(collectionName);
34
+ const collection = workflow.engine.createCollection(collectionName);
35
+ const options = await this.getSchematicOptions(collection, this.schematicName, workflow);
36
+ return this.addSchemaOptionsToCommand(localYargs, options);
29
37
  }
30
- run(options) {
31
- const command = new new_impl_1.NewCommand(this.context, 'new');
32
- return command.validateAndRun(options);
38
+ async run(options) {
39
+ var _a;
40
+ // Register the version of the CLI in the registry.
41
+ const collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : (await this.getCollectionFromConfig());
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);
50
+ // Compatibility check for NPM 7
51
+ if (collectionName === '@schematics/angular' &&
52
+ !schematicOptions.skipInstall &&
53
+ (schematicOptions.packageManager === undefined || schematicOptions.packageManager === 'npm')) {
54
+ this.context.packageManager.ensureCompatibility();
55
+ }
56
+ return this.runSchematic({
57
+ collectionName,
58
+ schematicName: this.schematicName,
59
+ schematicOptions,
60
+ executionOptions: {
61
+ dryRun,
62
+ force,
63
+ interactive,
64
+ defaults,
65
+ },
66
+ });
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;
33
79
  }
34
80
  }
35
81
  exports.NewCommandModule = NewCommandModule;