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

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 (68) hide show
  1. package/bin/postinstall/analytics-prompt.js +2 -2
  2. package/lib/config/schema.json +4 -4
  3. package/lib/config/workspace-schema.d.ts +1 -1
  4. package/lib/init.js +5 -1
  5. package/package.json +13 -13
  6. package/src/analytics/analytics-collector.js +5 -1
  7. package/{models/interface.js → src/analytics/analytics-environment-options.d.ts} +2 -2
  8. package/src/analytics/analytics-environment-options.js +20 -0
  9. package/src/analytics/analytics.d.ts +10 -23
  10. package/src/analytics/analytics.js +96 -182
  11. package/src/command-builder/architect-base-command-module.js +3 -5
  12. package/src/command-builder/architect-command-module.js +4 -6
  13. package/src/command-builder/command-module.d.ts +4 -1
  14. package/src/command-builder/command-module.js +9 -3
  15. package/src/command-builder/command-runner.js +9 -20
  16. package/src/command-builder/schematics-command-module.d.ts +18 -5
  17. package/src/command-builder/schematics-command-module.js +207 -29
  18. package/src/command-builder/utilities/command.d.ts +13 -0
  19. package/src/command-builder/utilities/command.js +27 -0
  20. package/src/command-builder/utilities/json-help.d.ts +16 -14
  21. package/src/command-builder/utilities/json-help.js +26 -22
  22. package/{models → src/command-builder/utilities}/schematic-engine-host.d.ts +0 -0
  23. package/{models → src/command-builder/utilities}/schematic-engine-host.js +0 -0
  24. package/src/command-builder/utilities/schematic-workflow.d.ts +14 -0
  25. package/src/command-builder/utilities/schematic-workflow.js +68 -0
  26. package/src/commands/add/cli.d.ts +11 -1
  27. package/src/commands/add/cli.js +325 -6
  28. package/src/commands/analytics/cli.d.ts +5 -10
  29. package/src/commands/analytics/cli.js +15 -50
  30. package/src/commands/analytics/info/cli.d.ts +16 -0
  31. package/src/commands/analytics/info/cli.js +26 -0
  32. package/src/commands/analytics/settings/cli.d.ts +35 -0
  33. package/src/commands/analytics/settings/cli.js +61 -0
  34. package/src/commands/config/cli.d.ts +4 -1
  35. package/src/commands/config/cli.js +126 -4
  36. package/src/commands/doc/cli.js +5 -1
  37. package/src/commands/generate/cli.d.ts +4 -2
  38. package/src/commands/generate/cli.js +37 -21
  39. package/src/commands/new/cli.d.ts +5 -3
  40. package/src/commands/new/cli.js +36 -6
  41. package/src/commands/update/cli.d.ts +30 -5
  42. package/src/commands/update/cli.js +680 -9
  43. package/src/commands/update/schematic/index.js +5 -1
  44. package/src/commands/version/cli.js +18 -23
  45. package/src/utilities/color.js +5 -1
  46. package/src/utilities/config.d.ts +1 -0
  47. package/src/utilities/config.js +36 -2
  48. package/src/utilities/find-up.js +5 -1
  49. package/src/utilities/package-metadata.js +5 -1
  50. package/src/utilities/package-tree.js +5 -1
  51. package/src/utilities/project.js +5 -1
  52. package/src/utilities/prompt.js +5 -1
  53. package/models/command.d.ts +0 -29
  54. package/models/command.js +0 -50
  55. package/models/interface.d.ts +0 -19
  56. package/models/schematic-command.d.ts +0 -43
  57. package/models/schematic-command.js +0 -378
  58. package/src/commands/add/add-impl.d.ts +0 -22
  59. package/src/commands/add/add-impl.js +0 -331
  60. package/src/commands/analytics/long-description.md +0 -10
  61. package/src/commands/config/config-impl.d.ts +0 -17
  62. package/src/commands/config/config-impl.js +0 -151
  63. package/src/commands/generate/generate-impl.d.ts +0 -19
  64. package/src/commands/generate/generate-impl.js +0 -49
  65. package/src/commands/new/new-impl.d.ts +0 -18
  66. package/src/commands/new/new-impl.js +0 -38
  67. package/src/commands/update/update-impl.d.ts +0 -40
  68. package/src/commands/update/update-impl.js +0 -728
@@ -8,6 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.ArchitectCommandModule = void 0;
11
+ const config_1 = require("../utilities/config");
11
12
  const architect_base_command_module_1 = require("./architect-base-command-module");
12
13
  const command_module_1 = require("./command-module");
13
14
  class ArchitectCommandModule extends architect_base_command_module_1.ArchitectBaseCommandModule {
@@ -93,12 +94,9 @@ class ArchitectCommandModule extends architect_base_command_module_1.ArchitectBa
93
94
  return allProjectsForTargetName;
94
95
  }
95
96
  else {
96
- // For single target commands, we try the default project first,
97
- // then the full list if it has a single project, then error out.
98
- const maybeDefaultProject = workspace.extensions['defaultProject'];
99
- if (typeof maybeDefaultProject === 'string' &&
100
- allProjectsForTargetName.includes(maybeDefaultProject)) {
101
- return [maybeDefaultProject];
97
+ const maybeProject = (0, config_1.getProjectByCwd)(workspace);
98
+ if (maybeProject && allProjectsForTargetName.includes(maybeProject)) {
99
+ return [maybeProject];
102
100
  }
103
101
  if (allProjectsForTargetName.length === 1) {
104
102
  return allProjectsForTargetName;
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { analytics, logging } from '@angular-devkit/core';
9
9
  import { ArgumentsCamelCase, Argv, CamelCaseKey, CommandModule as YargsCommandModule } from 'yargs';
10
+ import { PackageManager } from '../../lib/config/workspace-schema';
10
11
  import { AngularWorkspace } from '../utilities/config';
11
12
  import { Option } from './utilities/json-schema';
12
13
  export declare type Options<T> = {
@@ -25,11 +26,13 @@ export interface CommandContext {
25
26
  root: string;
26
27
  workspace?: AngularWorkspace;
27
28
  logger: logging.Logger;
29
+ packageManager: PackageManager;
28
30
  /** Arguments parsed in free-from without parser configuration. */
29
31
  args: {
30
32
  positional: string[];
31
33
  options: {
32
34
  help: boolean;
35
+ jsonHelp: boolean;
33
36
  } & Record<string, unknown>;
34
37
  };
35
38
  }
@@ -52,7 +55,7 @@ export declare abstract class CommandModule<T extends {} = {}> implements Comman
52
55
  abstract readonly command: string;
53
56
  abstract readonly describe: string | false;
54
57
  abstract readonly longDescriptionPath?: string;
55
- protected shouldReportAnalytics: boolean;
58
+ protected readonly shouldReportAnalytics: boolean;
56
59
  static scope: CommandScope;
57
60
  private readonly optionsWithAnalytics;
58
61
  constructor(context: CommandContext);
@@ -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];
@@ -63,7 +67,7 @@ class CommandModule {
63
67
  longDescriptionRelativePath: path
64
68
  .relative(path.join(__dirname, '../../../../'), this.longDescriptionPath)
65
69
  .replace(/\\/g, path.posix.sep),
66
- longDescription: (0, fs_1.readFileSync)(this.longDescriptionPath, 'utf8'),
70
+ longDescription: (0, fs_1.readFileSync)(this.longDescriptionPath, 'utf8').replace(/\r\n/g, '\n'),
67
71
  }
68
72
  : {}),
69
73
  };
@@ -124,7 +128,9 @@ class CommandModule {
124
128
  if (this._analytics) {
125
129
  return this._analytics;
126
130
  }
127
- return (this._analytics = await (0, analytics_1.createAnalytics)(!!this.context.workspace, this.commandName === 'update'));
131
+ return (this._analytics = await (0, analytics_1.createAnalytics)(!!this.context.workspace,
132
+ // Don't prompt for `ng update` and `ng analytics` commands.
133
+ ['update', 'analytics'].includes(this.commandName)));
128
134
  }
129
135
  /**
130
136
  * Adds schema options to a command also this keeps track of options that are required for analytics.
@@ -31,7 +31,9 @@ const cli_15 = require("../commands/test/cli");
31
31
  const cli_16 = require("../commands/update/cli");
32
32
  const cli_17 = require("../commands/version/cli");
33
33
  const color_1 = require("../utilities/color");
34
+ const package_manager_1 = require("../utilities/package-manager");
34
35
  const command_module_1 = require("./command-module");
36
+ const command_1 = require("./utilities/command");
35
37
  const json_help_1 = require("./utilities/json-help");
36
38
  const COMMANDS = [
37
39
  cli_17.VersionCommandModule,
@@ -51,20 +53,22 @@ const COMMANDS = [
51
53
  cli_12.NewCommandModule,
52
54
  cli_16.UpdateCommandModule,
53
55
  cli_13.RunCommandModule,
54
- ];
56
+ ].sort(); // Will be sorted by class name.
55
57
  const yargsParser = helpers_1.Parser;
56
58
  async function runCommand(args, logger, workspace) {
57
- var _a, _b;
59
+ var _a, _b, _c;
58
60
  const { $0, _: positional, help = false, jsonHelp = false, ...rest } = yargsParser(args, { boolean: ['help', 'json-help'], alias: { 'collection': 'c' } });
59
61
  const context = {
60
62
  workspace,
61
63
  logger,
62
64
  currentDirectory: process.cwd(),
63
65
  root: (_a = workspace === null || workspace === void 0 ? void 0 : workspace.basePath) !== null && _a !== void 0 ? _a : process.cwd(),
66
+ packageManager: await (0, package_manager_1.getPackageManager)((_b = workspace === null || workspace === void 0 ? void 0 : workspace.basePath) !== null && _b !== void 0 ? _b : process.cwd()),
64
67
  args: {
65
68
  positional: positional.map((v) => v.toString()),
66
69
  options: {
67
70
  help,
71
+ jsonHelp,
68
72
  ...rest,
69
73
  },
70
74
  },
@@ -78,22 +82,7 @@ async function runCommand(args, logger, workspace) {
78
82
  continue;
79
83
  }
80
84
  }
81
- const commandModule = new CommandModule(context);
82
- const describe = jsonHelp ? commandModule.fullDescribe : commandModule.describe;
83
- localYargs = localYargs.command({
84
- command: commandModule.command,
85
- aliases: 'aliases' in commandModule ? commandModule.aliases : undefined,
86
- describe:
87
- // We cannot add custom fields in help, such as long command description which is used in AIO.
88
- // Therefore, we get around this by adding a complex object as a string which we later parse when generating the help files.
89
- describe !== undefined && typeof describe === 'object'
90
- ? JSON.stringify(describe)
91
- : describe,
92
- deprecated: 'deprecated' in commandModule ? commandModule.deprecated : undefined,
93
- builder: (argv) => commandModule.builder(argv),
94
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
- handler: (args) => commandModule.handler(args),
96
- });
85
+ localYargs = (0, command_1.addCommandModuleToYargs)(localYargs, CommandModule, context);
97
86
  }
98
87
  if (jsonHelp) {
99
88
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -127,7 +116,7 @@ async function runCommand(args, logger, workspace) {
127
116
  'deprecated: %s': color_1.colors.yellow('deprecated:') + ' %s',
128
117
  'Did you mean %s?': 'Unknown command. Did you mean %s?',
129
118
  })
130
- .demandCommand()
119
+ .demandCommand(1, command_1.demandCommandFailureMessage)
131
120
  .recommendCommands()
132
121
  .version(false)
133
122
  .showHelpOnFail(false)
@@ -141,6 +130,6 @@ async function runCommand(args, logger, workspace) {
141
130
  })
142
131
  .wrap(yargs_1.default.terminalWidth())
143
132
  .parseAsync();
144
- return (_b = process.exitCode) !== null && _b !== void 0 ? _b : 0;
133
+ return (_c = process.exitCode) !== null && _c !== void 0 ? _c : 0;
145
134
  }
146
135
  exports.runCommand = runCommand;
@@ -8,7 +8,7 @@
8
8
  import { Collection } from '@angular-devkit/schematics';
9
9
  import { FileSystemCollectionDescription, FileSystemSchematicDescription, NodeWorkflow } from '@angular-devkit/schematics/tools';
10
10
  import { Argv } from 'yargs';
11
- import { CommandModule, CommandModuleImplementation, CommandScope } from './command-module';
11
+ import { CommandModule, CommandModuleImplementation, CommandScope, Options, OtherOptions } from './command-module';
12
12
  import { Option } from './utilities/json-schema';
13
13
  export interface SchematicsCommandArgs {
14
14
  interactive: boolean;
@@ -16,16 +16,29 @@ export interface SchematicsCommandArgs {
16
16
  'dry-run': boolean;
17
17
  defaults: boolean;
18
18
  }
19
+ export interface SchematicsExecutionOptions extends Options<SchematicsCommandArgs> {
20
+ packageRegistry?: string;
21
+ }
19
22
  export declare abstract class SchematicsCommandModule extends CommandModule<SchematicsCommandArgs> implements CommandModuleImplementation<SchematicsCommandArgs> {
20
23
  static scope: CommandScope;
21
- protected readonly schematicName: string | undefined;
24
+ protected readonly allowPrivateSchematics: boolean;
25
+ protected readonly shouldReportAnalytics = false;
22
26
  builder(argv: Argv): Promise<Argv<SchematicsCommandArgs>>;
23
27
  /** Get schematic schema options.*/
24
28
  protected getSchematicOptions(collection: Collection<FileSystemCollectionDescription, FileSystemSchematicDescription>, schematicName: string, workflow: NodeWorkflow): Promise<Option[]>;
25
- protected getCollectionName(): Promise<string>;
26
- private _workflow;
27
- protected getOrCreateWorkflow(collectionName: string): NodeWorkflow;
29
+ private _workflowForBuilder;
30
+ protected getOrCreateWorkflowForBuilder(collectionName: string): NodeWorkflow;
31
+ private _workflowForExecution;
32
+ protected getOrCreateWorkflowForExecution(collectionName: string, options: SchematicsExecutionOptions): Promise<NodeWorkflow>;
28
33
  private _defaultSchematicCollection;
29
34
  protected getDefaultSchematicCollection(): Promise<string>;
30
35
  protected parseSchematicInfo(schematic: string | undefined): [collectionName: string | undefined, schematicName: string | undefined];
36
+ protected runSchematic(options: {
37
+ executionOptions: SchematicsExecutionOptions;
38
+ schematicOptions: OtherOptions;
39
+ collectionName: string;
40
+ schematicName: string;
41
+ }): Promise<number>;
42
+ private getProjectName;
43
+ private getResolvePaths;
31
44
  }
@@ -6,17 +6,30 @@
6
6
  * Use of this source code is governed by an MIT-style license that can be
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
9
12
  Object.defineProperty(exports, "__esModule", { value: true });
10
13
  exports.SchematicsCommandModule = void 0;
14
+ const core_1 = require("@angular-devkit/core");
15
+ const schematics_1 = require("@angular-devkit/schematics");
11
16
  const tools_1 = require("@angular-devkit/schematics/tools");
12
- const schematic_engine_host_1 = require("../../models/schematic-engine-host");
17
+ const inquirer_1 = __importDefault(require("inquirer"));
13
18
  const config_1 = require("../utilities/config");
19
+ const tty_1 = require("../utilities/tty");
14
20
  const command_module_1 = require("./command-module");
15
21
  const json_schema_1 = require("./utilities/json-schema");
22
+ const schematic_engine_host_1 = require("./utilities/schematic-engine-host");
23
+ const schematic_workflow_1 = require("./utilities/schematic-workflow");
16
24
  const DEFAULT_SCHEMATICS_COLLECTION = '@schematics/angular';
17
25
  class SchematicsCommandModule extends command_module_1.CommandModule {
26
+ constructor() {
27
+ super(...arguments);
28
+ this.allowPrivateSchematics = false;
29
+ this.shouldReportAnalytics = false;
30
+ }
18
31
  async builder(argv) {
19
- const localYargs = argv
32
+ return argv
20
33
  .option('interactive', {
21
34
  describe: 'Enable interactive input prompts.',
22
35
  type: 'boolean',
@@ -38,14 +51,6 @@ class SchematicsCommandModule extends command_module_1.CommandModule {
38
51
  default: false,
39
52
  })
40
53
  .strict();
41
- if (this.schematicName) {
42
- const collectionName = await this.getCollectionName();
43
- const workflow = this.getOrCreateWorkflow(collectionName);
44
- const collection = workflow.engine.createCollection(collectionName);
45
- const options = await this.getSchematicOptions(collection, this.schematicName, workflow);
46
- return this.addSchemaOptionsToCommand(localYargs, options);
47
- }
48
- return localYargs;
49
54
  }
50
55
  /** Get schematic schema options.*/
51
56
  async getSchematicOptions(collection, schematicName, workflow) {
@@ -56,29 +61,126 @@ class SchematicsCommandModule extends command_module_1.CommandModule {
56
61
  }
57
62
  return (0, json_schema_1.parseJsonSchemaToOptions)(workflow.registry, schemaJson);
58
63
  }
59
- async getCollectionName() {
60
- var _a, _b;
61
- const { options: { collection }, positional, } = this.context.args;
62
- return ((_b = (_a = (typeof collection === 'string' ? collection : undefined)) !== null && _a !== void 0 ? _a :
63
- // positional = [generate, lint] or [new, collection-package]
64
- this.parseSchematicInfo(positional[1])[0]) !== null && _b !== void 0 ? _b : (await this.getDefaultSchematicCollection()));
64
+ getOrCreateWorkflowForBuilder(collectionName) {
65
+ if (this._workflowForBuilder) {
66
+ return this._workflowForBuilder;
67
+ }
68
+ return (this._workflowForBuilder = new tools_1.NodeWorkflow(this.context.root, {
69
+ resolvePaths: this.getResolvePaths(collectionName),
70
+ engineHostCreator: (options) => new schematic_engine_host_1.SchematicEngineHost(options.resolvePaths),
71
+ }));
65
72
  }
66
- getOrCreateWorkflow(collectionName) {
67
- if (this._workflow) {
68
- return this._workflow;
73
+ async getOrCreateWorkflowForExecution(collectionName, options) {
74
+ if (this._workflowForExecution) {
75
+ return this._workflowForExecution;
69
76
  }
70
- const { root, workspace } = this.context;
71
- return new tools_1.NodeWorkflow(root, {
72
- resolvePaths: workspace
73
- ? // Workspace
74
- collectionName === DEFAULT_SCHEMATICS_COLLECTION
75
- ? // Favor __dirname for @schematics/angular to use the build-in version
76
- [__dirname, process.cwd(), root]
77
- : [process.cwd(), root, __dirname]
78
- : // Global
79
- [__dirname, process.cwd()],
77
+ const { logger, root, packageManager } = this.context;
78
+ const { force, dryRun, packageRegistry } = options;
79
+ const workflow = new tools_1.NodeWorkflow(root, {
80
+ force,
81
+ dryRun,
82
+ packageManager,
83
+ // A schema registry is required to allow customizing addUndefinedDefaults
84
+ registry: new core_1.schema.CoreSchemaRegistry(schematics_1.formats.standardFormats),
85
+ packageRegistry,
86
+ resolvePaths: this.getResolvePaths(collectionName),
87
+ schemaValidation: true,
88
+ optionTransforms: [
89
+ // Add configuration file defaults
90
+ async (schematic, current) => {
91
+ const projectName = typeof current.project === 'string'
92
+ ? current.project
93
+ : this.getProjectName();
94
+ return {
95
+ ...(await (0, config_1.getSchematicDefaults)(schematic.collection.name, schematic.name, projectName)),
96
+ ...current,
97
+ };
98
+ },
99
+ ],
80
100
  engineHostCreator: (options) => new schematic_engine_host_1.SchematicEngineHost(options.resolvePaths),
81
101
  });
102
+ workflow.registry.addPostTransform(core_1.schema.transforms.addUndefinedDefaults);
103
+ workflow.registry.addSmartDefaultProvider('projectName', () => this.getProjectName());
104
+ workflow.registry.useXDeprecatedProvider((msg) => logger.warn(msg));
105
+ let shouldReportAnalytics = true;
106
+ workflow.engineHost.registerOptionsTransform(async (schematic, options) => {
107
+ var _a;
108
+ if (shouldReportAnalytics) {
109
+ shouldReportAnalytics = false;
110
+ // ng generate lib -> ng generate
111
+ const commandName = (_a = this.command) === null || _a === void 0 ? void 0 : _a.split(' ', 1)[0];
112
+ await this.reportAnalytics(options, [
113
+ commandName,
114
+ schematic.collection.name.replace(/\//g, '_'),
115
+ schematic.name.replace(/\//g, '_'),
116
+ ]);
117
+ }
118
+ return options;
119
+ });
120
+ if (options.interactive !== false && (0, tty_1.isTTY)()) {
121
+ workflow.registry.usePromptProvider((definitions) => {
122
+ const questions = definitions
123
+ .filter((definition) => !options.defaults || definition.default === undefined)
124
+ .map((definition) => {
125
+ var _a;
126
+ const question = {
127
+ name: definition.id,
128
+ message: definition.message,
129
+ default: definition.default,
130
+ };
131
+ const validator = definition.validator;
132
+ if (validator) {
133
+ question.validate = (input) => validator(input);
134
+ // Filter allows transformation of the value prior to validation
135
+ question.filter = async (input) => {
136
+ for (const type of definition.propertyTypes) {
137
+ let value;
138
+ switch (type) {
139
+ case 'string':
140
+ value = String(input);
141
+ break;
142
+ case 'integer':
143
+ case 'number':
144
+ value = Number(input);
145
+ break;
146
+ default:
147
+ value = input;
148
+ break;
149
+ }
150
+ // Can be a string if validation fails
151
+ const isValid = (await validator(value)) === true;
152
+ if (isValid) {
153
+ return value;
154
+ }
155
+ }
156
+ return input;
157
+ };
158
+ }
159
+ switch (definition.type) {
160
+ case 'confirmation':
161
+ question.type = 'confirm';
162
+ break;
163
+ case 'list':
164
+ question.type = definition.multiselect ? 'checkbox' : 'list';
165
+ question.choices = (_a = definition.items) === null || _a === void 0 ? void 0 : _a.map((item) => {
166
+ return typeof item == 'string'
167
+ ? item
168
+ : {
169
+ name: item.label,
170
+ value: item.value,
171
+ };
172
+ });
173
+ break;
174
+ default:
175
+ question.type = definition.type;
176
+ break;
177
+ }
178
+ return question;
179
+ });
180
+ return inquirer_1.default.prompt(questions);
181
+ });
182
+ }
183
+ return (this._workflowForExecution = workflow);
82
184
  }
83
185
  async getDefaultSchematicCollection() {
84
186
  if (this._defaultSchematicCollection) {
@@ -112,6 +214,82 @@ class SchematicsCommandModule extends command_module_1.CommandModule {
112
214
  }
113
215
  return [undefined, schematic];
114
216
  }
217
+ async runSchematic(options) {
218
+ const { logger } = this.context;
219
+ const { schematicOptions, executionOptions, collectionName, schematicName } = options;
220
+ const workflow = await this.getOrCreateWorkflowForExecution(collectionName, executionOptions);
221
+ if (!schematicName) {
222
+ throw new Error('schematicName cannot be undefined.');
223
+ }
224
+ const { unsubscribe, files } = (0, schematic_workflow_1.subscribeToWorkflow)(workflow, logger);
225
+ try {
226
+ await workflow
227
+ .execute({
228
+ collection: collectionName,
229
+ schematic: schematicName,
230
+ options: schematicOptions,
231
+ logger,
232
+ allowPrivate: this.allowPrivateSchematics,
233
+ })
234
+ .toPromise();
235
+ if (!files.size) {
236
+ logger.info('Nothing to be done.');
237
+ }
238
+ if (executionOptions.dryRun) {
239
+ logger.warn(`\nNOTE: The "--dry-run" option means no changes were made.`);
240
+ }
241
+ }
242
+ catch (err) {
243
+ // In case the workflow was not successful, show an appropriate error message.
244
+ if (err instanceof schematics_1.UnsuccessfulWorkflowExecution) {
245
+ // "See above" because we already printed the error.
246
+ logger.fatal('The Schematic workflow failed. See above.');
247
+ return 1;
248
+ }
249
+ else {
250
+ throw err;
251
+ }
252
+ }
253
+ finally {
254
+ unsubscribe();
255
+ }
256
+ return 0;
257
+ }
258
+ getProjectName() {
259
+ const { workspace, logger } = this.context;
260
+ if (!workspace) {
261
+ return undefined;
262
+ }
263
+ const projectNames = (0, config_1.getProjectsByPath)(workspace, process.cwd(), workspace.basePath);
264
+ if (projectNames.length === 1) {
265
+ return projectNames[0];
266
+ }
267
+ else {
268
+ if (projectNames.length > 1) {
269
+ logger.warn(core_1.tags.oneLine `
270
+ Two or more projects are using identical roots.
271
+ Unable to determine project using current working directory.
272
+ Using default workspace project instead.
273
+ `);
274
+ }
275
+ const defaultProjectName = workspace.extensions['defaultProject'];
276
+ if (typeof defaultProjectName === 'string' && defaultProjectName) {
277
+ return defaultProjectName;
278
+ }
279
+ }
280
+ return undefined;
281
+ }
282
+ getResolvePaths(collectionName) {
283
+ const { workspace, root } = this.context;
284
+ return workspace
285
+ ? // Workspace
286
+ collectionName === DEFAULT_SCHEMATICS_COLLECTION
287
+ ? // Favor __dirname for @schematics/angular to use the build-in version
288
+ [__dirname, process.cwd(), root]
289
+ : [process.cwd(), root, __dirname]
290
+ : // Global
291
+ [__dirname, process.cwd()];
292
+ }
115
293
  }
116
294
  exports.SchematicsCommandModule = SchematicsCommandModule;
117
295
  SchematicsCommandModule.scope = command_module_1.CommandScope.In;
@@ -0,0 +1,13 @@
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 { CommandContext, CommandModule, CommandModuleImplementation } from '../command-module';
10
+ export declare const demandCommandFailureMessage = "You need to specify a command before moving on. Use '--help' to view the available commands.";
11
+ export declare function addCommandModuleToYargs<T, U extends Partial<CommandModuleImplementation> & {
12
+ new (context: CommandContext): Partial<CommandModuleImplementation> & CommandModule;
13
+ }>(localYargs: Argv<T>, commandModule: U, context: CommandContext): Argv<T>;
@@ -0,0 +1,27 @@
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.addCommandModuleToYargs = exports.demandCommandFailureMessage = void 0;
11
+ exports.demandCommandFailureMessage = `You need to specify a command before moving on. Use '--help' to view the available commands.`;
12
+ function addCommandModuleToYargs(localYargs, commandModule, context) {
13
+ const cmd = new commandModule(context);
14
+ const describe = context.args.options.jsonHelp ? cmd.fullDescribe : cmd.describe;
15
+ return localYargs.command({
16
+ command: cmd.command,
17
+ aliases: cmd.aliases,
18
+ describe:
19
+ // We cannot add custom fields in help, such as long command description which is used in AIO.
20
+ // Therefore, we get around this by adding a complex object as a string which we later parse when generating the help files.
21
+ typeof describe === 'object' ? JSON.stringify(describe) : describe,
22
+ deprecated: cmd.deprecated,
23
+ builder: (argv) => cmd.builder(argv),
24
+ handler: (args) => cmd.handler(args),
25
+ });
26
+ }
27
+ exports.addCommandModuleToYargs = addCommandModuleToYargs;
@@ -5,20 +5,6 @@
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
- export interface JsonHelp {
9
- name: string;
10
- shortDescription?: string;
11
- command: string;
12
- longDescription?: string;
13
- longDescriptionRelativePath?: string;
14
- options: JsonHelpOption[];
15
- subcommands?: {
16
- name: string;
17
- description: string;
18
- aliases: string[];
19
- deprecated: string | boolean;
20
- }[];
21
- }
22
8
  interface JsonHelpOption {
23
9
  name: string;
24
10
  type?: string;
@@ -30,5 +16,21 @@ interface JsonHelpOption {
30
16
  enum?: string[];
31
17
  description?: string;
32
18
  }
19
+ interface JsonHelpDescription {
20
+ shortDescription?: string;
21
+ longDescription?: string;
22
+ longDescriptionRelativePath?: string;
23
+ }
24
+ interface JsonHelpSubcommand extends JsonHelpDescription {
25
+ name: string;
26
+ aliases: string[];
27
+ deprecated: string | boolean;
28
+ }
29
+ export interface JsonHelp extends JsonHelpDescription {
30
+ name: string;
31
+ command: string;
32
+ options: JsonHelpOption[];
33
+ subcommands?: JsonHelpSubcommand[];
34
+ }
33
35
  export declare function jsonHelpUsage(): string;
34
36
  export {};
@@ -12,8 +12,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.jsonHelpUsage = void 0;
14
14
  const yargs_1 = __importDefault(require("yargs"));
15
+ const yargsDefaultCommandRegExp = /^\$0|\*/;
15
16
  function jsonHelpUsage() {
16
- var _a, _b, _c;
17
+ var _a, _b, _c, _d, _e;
17
18
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
19
  const localYargs = yargs_1.default;
19
20
  const { deprecatedOptions, alias: aliases, array, string, boolean, number, choices, demandedOptions, default: defaultVal, hiddenOptions = [], } = localYargs.getOptions();
@@ -54,37 +55,40 @@ function jsonHelpUsage() {
54
55
  }
55
56
  // https://github.com/yargs/yargs/blob/00e4ebbe3acd438e73fdb101e75b4f879eb6d345/lib/usage.ts#L124
56
57
  const subcommands = usageInstance.getCommands()
57
- .map(([name, description, _, aliases, deprecated]) => ({
58
- name: name.split(' ', 1)[0],
59
- command: name,
60
- description,
58
+ .map(([name, rawDescription, isDefault, aliases, deprecated]) => ({
59
+ name: name.split(' ', 1)[0].replace(yargsDefaultCommandRegExp, ''),
60
+ command: name.replace(yargsDefaultCommandRegExp, ''),
61
+ default: isDefault || undefined,
62
+ ...parseDescription(rawDescription),
61
63
  aliases,
62
64
  deprecated,
63
65
  }))
64
66
  .sort((a, b) => a.name.localeCompare(b.name));
65
- const parseDescription = (rawDescription) => {
66
- try {
67
- const { longDescription, describe: shortDescription, longDescriptionRelativePath, } = JSON.parse(rawDescription);
68
- return {
69
- shortDescription,
70
- longDescriptionRelativePath,
71
- longDescription,
72
- };
73
- }
74
- catch {
75
- return {
76
- shortDescription: rawDescription,
77
- };
78
- }
79
- };
80
67
  const [command, rawDescription] = (_c = usageInstance.getUsage()[0]) !== null && _c !== void 0 ? _c : [];
68
+ const defaultSubCommand = (_e = (_d = subcommands.find((x) => x.default)) === null || _d === void 0 ? void 0 : _d.command) !== null && _e !== void 0 ? _e : '';
69
+ const otherSubcommands = subcommands.filter((s) => !s.default);
81
70
  const output = {
82
71
  name: [...context.commands].pop(),
83
- command: command === null || command === void 0 ? void 0 : command.replace('$0', localYargs['$0']),
72
+ command: `${command === null || command === void 0 ? void 0 : command.replace(yargsDefaultCommandRegExp, localYargs['$0'])}${defaultSubCommand}`,
84
73
  ...parseDescription(rawDescription),
85
74
  options: normalizeOptions.sort((a, b) => a.name.localeCompare(b.name)),
86
- subcommands: subcommands.length ? subcommands : undefined,
75
+ subcommands: otherSubcommands.length ? otherSubcommands : undefined,
87
76
  };
88
77
  return JSON.stringify(output, undefined, 2);
89
78
  }
90
79
  exports.jsonHelpUsage = jsonHelpUsage;
80
+ function parseDescription(rawDescription) {
81
+ try {
82
+ const { longDescription, describe: shortDescription, longDescriptionRelativePath, } = JSON.parse(rawDescription);
83
+ return {
84
+ shortDescription,
85
+ longDescriptionRelativePath,
86
+ longDescription,
87
+ };
88
+ }
89
+ catch {
90
+ return {
91
+ shortDescription: rawDescription,
92
+ };
93
+ }
94
+ }
@@ -0,0 +1,14 @@
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 { logging } from '@angular-devkit/core';
9
+ import { NodeWorkflow } from '@angular-devkit/schematics/tools';
10
+ export declare function subscribeToWorkflow(workflow: NodeWorkflow, logger: logging.LoggerApi): {
11
+ files: Set<string>;
12
+ error: boolean;
13
+ unsubscribe: () => void;
14
+ };