@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
@@ -17,10 +17,10 @@ try {
17
17
  var analytics = require('../../src/analytics/analytics');
18
18
 
19
19
  analytics
20
- .hasGlobalAnalyticsConfiguration()
20
+ .getAnalytics('global')
21
21
  .then((hasGlobalConfig) => {
22
22
  if (!hasGlobalConfig) {
23
- return analytics.promptGlobalAnalytics();
23
+ return analytics.promptAnalytics(true /** global */);
24
24
  }
25
25
  })
26
26
  .catch(() => {});
@@ -586,7 +586,7 @@
586
586
  "SchematicsAngularApplicationSchema": {
587
587
  "title": "Angular Application Options Schema",
588
588
  "type": "object",
589
- "description": "Generates a new basic app definition in the \"projects\" subfolder of the workspace.",
589
+ "description": "Generates a new basic application definition in the \"projects\" subfolder of the workspace.",
590
590
  "additionalProperties": false,
591
591
  "properties": {
592
592
  "projectRoot": {
@@ -1524,12 +1524,12 @@
1524
1524
  "properties": {
1525
1525
  "browserTarget": {
1526
1526
  "type": "string",
1527
- "description": "A browser builder target use for rendering the app shell in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
1527
+ "description": "A browser builder target use for rendering the application shell in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
1528
1528
  "pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
1529
1529
  },
1530
1530
  "serverTarget": {
1531
1531
  "type": "string",
1532
- "description": "A server builder target use for rendering the app shell in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
1532
+ "description": "A server builder target use for rendering the application shell in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
1533
1533
  "pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
1534
1534
  },
1535
1535
  "appModuleBundle": {
@@ -2183,7 +2183,7 @@
2183
2183
  },
2184
2184
  "servePath": {
2185
2185
  "type": "string",
2186
- "description": "The pathname where the app will be served."
2186
+ "description": "The pathname where the application will be served."
2187
2187
  },
2188
2188
  "disableHostCheck": {
2189
2189
  "type": "boolean",
@@ -114,7 +114,7 @@ export interface SchematicOptions {
114
114
  "@schematics/angular:web-worker"?: AngularWebWorkerOptionsSchema;
115
115
  }
116
116
  /**
117
- * Generates a new basic app definition in the "projects" subfolder of the workspace.
117
+ * Generates a new basic application definition in the "projects" subfolder of the workspace.
118
118
  */
119
119
  export interface AngularApplicationOptionsSchema {
120
120
  /**
package/lib/init.js CHANGED
@@ -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];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/cli",
3
- "version": "14.0.0-next.5",
3
+ "version": "14.0.0-next.6",
4
4
  "description": "CLI tool for Angular",
5
5
  "main": "lib/cli/index.js",
6
6
  "bin": {
@@ -28,21 +28,21 @@
28
28
  },
29
29
  "homepage": "https://github.com/angular/angular-cli",
30
30
  "dependencies": {
31
- "@angular-devkit/architect": "0.1400.0-next.5",
32
- "@angular-devkit/core": "14.0.0-next.5",
33
- "@angular-devkit/schematics": "14.0.0-next.5",
34
- "@schematics/angular": "14.0.0-next.5",
31
+ "@angular-devkit/architect": "0.1400.0-next.6",
32
+ "@angular-devkit/core": "14.0.0-next.6",
33
+ "@angular-devkit/schematics": "14.0.0-next.6",
34
+ "@schematics/angular": "14.0.0-next.6",
35
35
  "@yarnpkg/lockfile": "1.1.0",
36
36
  "ansi-colors": "4.1.1",
37
37
  "debug": "4.3.3",
38
38
  "ini": "2.0.0",
39
39
  "inquirer": "8.2.1",
40
40
  "jsonc-parser": "3.0.0",
41
- "npm-package-arg": "9.0.0",
41
+ "npm-package-arg": "9.0.1",
42
42
  "npm-pick-manifest": "7.0.0",
43
43
  "open": "8.4.0",
44
44
  "ora": "5.4.1",
45
- "pacote": "13.0.3",
45
+ "pacote": "13.0.5",
46
46
  "resolve": "1.22.0",
47
47
  "semver": "7.3.5",
48
48
  "symbol-observable": "4.0.0",
@@ -52,12 +52,12 @@
52
52
  "ng-update": {
53
53
  "migrations": "@schematics/angular/migrations/migration-collection.json",
54
54
  "packageGroup": {
55
- "@angular/cli": "14.0.0-next.5",
56
- "@angular-devkit/architect": "0.1400.0-next.5",
57
- "@angular-devkit/build-angular": "14.0.0-next.5",
58
- "@angular-devkit/build-webpack": "0.1400.0-next.5",
59
- "@angular-devkit/core": "14.0.0-next.5",
60
- "@angular-devkit/schematics": "14.0.0-next.5"
55
+ "@angular/cli": "14.0.0-next.6",
56
+ "@angular-devkit/architect": "0.1400.0-next.6",
57
+ "@angular-devkit/build-angular": "14.0.0-next.6",
58
+ "@angular-devkit/build-webpack": "0.1400.0-next.6",
59
+ "@angular-devkit/core": "14.0.0-next.6",
60
+ "@angular-devkit/schematics": "14.0.0-next.6"
61
61
  }
62
62
  },
63
63
  "engines": {
@@ -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];
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * @license
4
3
  * Copyright Google LLC All Rights Reserved.
@@ -6,4 +5,5 @@
6
5
  * Use of this source code is governed by an MIT-style license that can be
7
6
  * found in the LICENSE file at https://angular.io/license
8
7
  */
9
- Object.defineProperty(exports, "__esModule", { value: true });
8
+ export declare const analyticsDisabled: boolean;
9
+ export declare const analyticsShareDisabled: boolean;
@@ -0,0 +1,20 @@
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.analyticsShareDisabled = exports.analyticsDisabled = void 0;
11
+ function isDisabled(variable) {
12
+ return variable === '0' || variable.toLowerCase() === 'false';
13
+ }
14
+ function isPresent(variable) {
15
+ return typeof variable === 'string' && variable !== '';
16
+ }
17
+ const analyticsVariable = process.env['NG_CLI_ANALYTICS'];
18
+ exports.analyticsDisabled = isPresent(analyticsVariable) && isDisabled(analyticsVariable);
19
+ const analyticsShareVariable = process.env['NG_CLI_ANALYTICS_SHARE'];
20
+ exports.analyticsShareDisabled = isPresent(analyticsShareVariable) && isDisabled(analyticsShareVariable);
@@ -19,42 +19,29 @@ export declare const analyticsPackageSafelist: (string | RegExp)[];
19
19
  export declare function isPackageNameSafeForAnalytics(name: string): boolean;
20
20
  /**
21
21
  * Set analytics settings. This does not work if the user is not inside a project.
22
- * @param level Which config to use. "global" for user-level, and "local" for project-level.
22
+ * @param global Which config to use. "global" for user-level, and "local" for project-level.
23
23
  * @param value Either a user ID, true to generate a new User ID, or false to disable analytics.
24
24
  */
25
- export declare function setAnalyticsConfig(level: 'global' | 'local', value: string | boolean): void;
25
+ export declare function setAnalyticsConfig(global: boolean, value: string | boolean): void;
26
26
  /**
27
27
  * Prompt the user for usage gathering permission.
28
28
  * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
29
29
  * @return Whether or not the user was shown a prompt.
30
30
  */
31
- export declare function promptGlobalAnalytics(force?: boolean): Promise<boolean>;
31
+ export declare function promptAnalytics(global: boolean, force?: boolean): Promise<boolean>;
32
32
  /**
33
- * Prompt the user for usage gathering permission for the local project. Fails if there is no
34
- * local workspace.
35
- * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
36
- * @return Whether or not the user was shown a prompt.
37
- */
38
- export declare function promptProjectAnalytics(force?: boolean): Promise<boolean>;
39
- export declare function hasGlobalAnalyticsConfiguration(): Promise<boolean>;
40
- /**
41
- * Get the global analytics object for the user. This returns an instance of UniversalAnalytics,
42
- * or undefined if analytics are disabled.
43
- *
44
- * If any problem happens, it is considered the user has been opting out of analytics.
45
- */
46
- export declare function getGlobalAnalytics(): Promise<AnalyticsCollector | undefined>;
47
- export declare function hasWorkspaceAnalyticsConfiguration(): Promise<boolean>;
48
- /**
49
- * Get the workspace analytics object for the user. This returns an instance of AnalyticsCollector,
50
- * or undefined if analytics are disabled.
33
+ * Get the analytics object for the user.
51
34
  *
52
- * If any problem happens, it is considered the user has been opting out of analytics.
35
+ * @returns
36
+ * - `AnalyticsCollector` when enabled.
37
+ * - `analytics.NoopAnalytics` when disabled.
38
+ * - `undefined` when not configured.
53
39
  */
54
- export declare function getWorkspaceAnalytics(): Promise<AnalyticsCollector | undefined>;
40
+ export declare function getAnalytics(level: 'local' | 'global'): Promise<AnalyticsCollector | analytics.NoopAnalytics | undefined>;
55
41
  /**
56
42
  * Return the usage analytics sharing setting, which is either a property string (GA-XXXXXXX-XX),
57
43
  * or undefined if no sharing.
58
44
  */
59
45
  export declare function getSharedAnalytics(): Promise<AnalyticsCollector | undefined>;
60
46
  export declare function createAnalytics(workspace: boolean, skipPrompt?: boolean): Promise<analytics.Analytics>;
47
+ export declare function getAnalyticsInfoString(): Promise<string>;
@@ -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];
@@ -29,7 +33,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
33
  return (mod && mod.__esModule) ? mod : { "default": mod };
30
34
  };
31
35
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.createAnalytics = exports.getSharedAnalytics = exports.getWorkspaceAnalytics = exports.hasWorkspaceAnalyticsConfiguration = exports.getGlobalAnalytics = exports.hasGlobalAnalyticsConfiguration = exports.promptProjectAnalytics = exports.promptGlobalAnalytics = exports.setAnalyticsConfig = exports.isPackageNameSafeForAnalytics = exports.analyticsPackageSafelist = exports.AnalyticsProperties = void 0;
36
+ exports.getAnalyticsInfoString = exports.createAnalytics = exports.getSharedAnalytics = exports.getAnalytics = exports.promptAnalytics = exports.setAnalyticsConfig = exports.isPackageNameSafeForAnalytics = exports.analyticsPackageSafelist = exports.AnalyticsProperties = void 0;
33
37
  const core_1 = require("@angular-devkit/core");
34
38
  const debug_1 = __importDefault(require("debug"));
35
39
  const inquirer = __importStar(require("inquirer"));
@@ -39,6 +43,7 @@ const config_1 = require("../utilities/config");
39
43
  const tty_1 = require("../utilities/tty");
40
44
  const version_1 = require("../utilities/version");
41
45
  const analytics_collector_1 = require("./analytics-collector");
46
+ const analytics_environment_options_1 = require("./analytics-environment-options");
42
47
  /* eslint-disable no-console */
43
48
  const analyticsDebug = (0, debug_1.default)('ng:analytics'); // Generate analytics, including settings and users.
44
49
  let _defaultAngularCliPropertyCache;
@@ -51,12 +56,10 @@ exports.AnalyticsProperties = {
51
56
  }
52
57
  const v = version_1.VERSION.full;
53
58
  // The logic is if it's a full version then we should use the prod GA property.
54
- if (/^\d+\.\d+\.\d+$/.test(v) && v !== '0.0.0') {
55
- _defaultAngularCliPropertyCache = exports.AnalyticsProperties.AngularCliProd;
56
- }
57
- else {
58
- _defaultAngularCliPropertyCache = exports.AnalyticsProperties.AngularCliStaging;
59
- }
59
+ _defaultAngularCliPropertyCache =
60
+ /^\d+\.\d+\.\d+$/.test(v) && v !== '0.0.0'
61
+ ? exports.AnalyticsProperties.AngularCliProd
62
+ : exports.AnalyticsProperties.AngularCliStaging;
60
63
  return _defaultAngularCliPropertyCache;
61
64
  },
62
65
  };
@@ -82,10 +85,11 @@ function isPackageNameSafeForAnalytics(name) {
82
85
  exports.isPackageNameSafeForAnalytics = isPackageNameSafeForAnalytics;
83
86
  /**
84
87
  * Set analytics settings. This does not work if the user is not inside a project.
85
- * @param level Which config to use. "global" for user-level, and "local" for project-level.
88
+ * @param global Which config to use. "global" for user-level, and "local" for project-level.
86
89
  * @param value Either a user ID, true to generate a new User ID, or false to disable analytics.
87
90
  */
88
- function setAnalyticsConfig(level, value) {
91
+ function setAnalyticsConfig(global, value) {
92
+ const level = global ? 'global' : 'local';
89
93
  analyticsDebug('setting %s level analytics to: %s', level, value);
90
94
  const [config, configPath] = (0, config_1.getWorkspaceRaw)(level);
91
95
  if (!config || !configPath) {
@@ -108,61 +112,12 @@ exports.setAnalyticsConfig = setAnalyticsConfig;
108
112
  * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
109
113
  * @return Whether or not the user was shown a prompt.
110
114
  */
111
- async function promptGlobalAnalytics(force = false) {
112
- analyticsDebug('prompting global analytics.');
113
- if (force || (0, tty_1.isTTY)()) {
114
- const answers = await inquirer.prompt([
115
- {
116
- type: 'confirm',
117
- name: 'analytics',
118
- message: core_1.tags.stripIndents `
119
- Would you like to share anonymous usage data with the Angular Team at Google under
120
- Google’s Privacy Policy at https://policies.google.com/privacy? For more details and
121
- how to change this setting, see https://angular.io/analytics.
122
- `,
123
- default: false,
124
- },
125
- ]);
126
- setAnalyticsConfig('global', answers.analytics);
127
- if (answers.analytics) {
128
- console.log('');
129
- console.log(core_1.tags.stripIndent `
130
- Thank you for sharing anonymous usage data. If you change your mind, the following
131
- command will disable this feature entirely:
132
-
133
- ${color_1.colors.yellow('ng analytics off')}
134
- `);
135
- console.log('');
136
- // Send back a ping with the user `optin`.
137
- const ua = new analytics_collector_1.AnalyticsCollector(exports.AnalyticsProperties.AngularCliDefault, 'optin');
138
- ua.pageview('/telemetry/optin');
139
- await ua.flush();
140
- }
141
- else {
142
- // Send back a ping with the user `optout`. This is the only thing we send.
143
- const ua = new analytics_collector_1.AnalyticsCollector(exports.AnalyticsProperties.AngularCliDefault, 'optout');
144
- ua.pageview('/telemetry/optout');
145
- await ua.flush();
146
- }
147
- return true;
148
- }
149
- else {
150
- analyticsDebug('Either STDOUT or STDIN are not TTY and we skipped the prompt.');
151
- }
152
- return false;
153
- }
154
- exports.promptGlobalAnalytics = promptGlobalAnalytics;
155
- /**
156
- * Prompt the user for usage gathering permission for the local project. Fails if there is no
157
- * local workspace.
158
- * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
159
- * @return Whether or not the user was shown a prompt.
160
- */
161
- async function promptProjectAnalytics(force = false) {
115
+ async function promptAnalytics(global, force = false) {
162
116
  analyticsDebug('prompting user');
163
- const [config, configPath] = (0, config_1.getWorkspaceRaw)('local');
117
+ const level = global ? 'global' : 'local';
118
+ const [config, configPath] = (0, config_1.getWorkspaceRaw)(level);
164
119
  if (!config || !configPath) {
165
- throw new Error(`Could not find a local workspace. Are you in a project?`);
120
+ throw new Error(`Could not find a ${level} workspace. Are you in a project?`);
166
121
  }
167
122
  if (force || (0, tty_1.isTTY)()) {
168
123
  const answers = await inquirer.prompt([
@@ -171,21 +126,21 @@ async function promptProjectAnalytics(force = false) {
171
126
  name: 'analytics',
172
127
  message: core_1.tags.stripIndents `
173
128
  Would you like to share anonymous usage data about this project with the Angular Team at
174
- Google under Google’s Privacy Policy at https://policies.google.com/privacy? For more
129
+ Google under Google’s Privacy Policy at https://policies.google.com/privacy. For more
175
130
  details and how to change this setting, see https://angular.io/analytics.
176
131
 
177
132
  `,
178
133
  default: false,
179
134
  },
180
135
  ]);
181
- setAnalyticsConfig('local', answers.analytics);
136
+ setAnalyticsConfig(global, answers.analytics);
182
137
  if (answers.analytics) {
183
138
  console.log('');
184
139
  console.log(core_1.tags.stripIndent `
185
140
  Thank you for sharing anonymous usage data. Should you change your mind, the following
186
141
  command will disable this feature entirely:
187
142
 
188
- ${color_1.colors.yellow('ng analytics project off')}
143
+ ${color_1.colors.yellow(`ng analytics disable${global ? ' --global' : ''}`)}
189
144
  `);
190
145
  console.log('');
191
146
  // Send back a ping with the user `optin`.
@@ -199,109 +154,34 @@ async function promptProjectAnalytics(force = false) {
199
154
  ua.pageview('/telemetry/project/optout');
200
155
  await ua.flush();
201
156
  }
157
+ process.stderr.write(await getAnalyticsInfoString());
202
158
  return true;
203
159
  }
204
160
  return false;
205
161
  }
206
- exports.promptProjectAnalytics = promptProjectAnalytics;
207
- async function hasGlobalAnalyticsConfiguration() {
208
- try {
209
- const globalWorkspace = await (0, config_1.getWorkspace)('global');
210
- const analyticsConfig = globalWorkspace && globalWorkspace.getCli() && globalWorkspace.getCli()['analytics'];
211
- if (analyticsConfig !== null && analyticsConfig !== undefined) {
212
- return true;
213
- }
214
- }
215
- catch { }
216
- return false;
217
- }
218
- exports.hasGlobalAnalyticsConfiguration = hasGlobalAnalyticsConfiguration;
162
+ exports.promptAnalytics = promptAnalytics;
219
163
  /**
220
- * Get the global analytics object for the user. This returns an instance of UniversalAnalytics,
221
- * or undefined if analytics are disabled.
164
+ * Get the analytics object for the user.
222
165
  *
223
- * If any problem happens, it is considered the user has been opting out of analytics.
166
+ * @returns
167
+ * - `AnalyticsCollector` when enabled.
168
+ * - `analytics.NoopAnalytics` when disabled.
169
+ * - `undefined` when not configured.
224
170
  */
225
- async function getGlobalAnalytics() {
226
- analyticsDebug('getGlobalAnalytics');
227
- const propertyId = exports.AnalyticsProperties.AngularCliDefault;
228
- if ('NG_CLI_ANALYTICS' in process.env) {
229
- if (process.env['NG_CLI_ANALYTICS'] == 'false' || process.env['NG_CLI_ANALYTICS'] == '') {
230
- analyticsDebug('NG_CLI_ANALYTICS is false');
231
- return undefined;
232
- }
233
- if (process.env['NG_CLI_ANALYTICS'] === 'ci') {
234
- analyticsDebug('Running in CI mode');
235
- return new analytics_collector_1.AnalyticsCollector(propertyId, 'ci');
236
- }
237
- }
238
- // If anything happens we just keep the NOOP analytics.
239
- try {
240
- const globalWorkspace = await (0, config_1.getWorkspace)('global');
241
- const analyticsConfig = globalWorkspace && globalWorkspace.getCli() && globalWorkspace.getCli()['analytics'];
242
- analyticsDebug('Client Analytics config found: %j', analyticsConfig);
243
- if (analyticsConfig === false) {
244
- analyticsDebug('Analytics disabled. Ignoring all analytics.');
245
- return undefined;
246
- }
247
- else if (analyticsConfig === undefined || analyticsConfig === null) {
248
- analyticsDebug('Analytics settings not found. Ignoring all analytics.');
249
- // globalWorkspace can be null if there is no file. analyticsConfig would be null in this
250
- // case. Since there is no file, the user hasn't answered and the expected return value is
251
- // undefined.
252
- return undefined;
253
- }
254
- else {
255
- let uid = undefined;
256
- if (typeof analyticsConfig == 'string') {
257
- uid = analyticsConfig;
258
- }
259
- else if (typeof analyticsConfig == 'object' && typeof analyticsConfig['uid'] == 'string') {
260
- uid = analyticsConfig['uid'];
261
- }
262
- analyticsDebug('client id: %j', uid);
263
- if (uid == undefined) {
264
- return undefined;
265
- }
266
- return new analytics_collector_1.AnalyticsCollector(propertyId, uid);
267
- }
268
- }
269
- catch (err) {
270
- analyticsDebug('Error happened during reading of analytics config: %s', err.message);
271
- return undefined;
171
+ async function getAnalytics(level) {
172
+ analyticsDebug('getAnalytics');
173
+ if (analytics_environment_options_1.analyticsDisabled) {
174
+ analyticsDebug('NG_CLI_ANALYTICS is false');
175
+ return new core_1.analytics.NoopAnalytics();
272
176
  }
273
- }
274
- exports.getGlobalAnalytics = getGlobalAnalytics;
275
- async function hasWorkspaceAnalyticsConfiguration() {
276
177
  try {
277
- const globalWorkspace = await (0, config_1.getWorkspace)('local');
278
- const analyticsConfig = globalWorkspace && globalWorkspace.getCli() && globalWorkspace.getCli()['analytics'];
279
- if (analyticsConfig !== undefined) {
280
- return true;
281
- }
282
- }
283
- catch { }
284
- return false;
285
- }
286
- exports.hasWorkspaceAnalyticsConfiguration = hasWorkspaceAnalyticsConfiguration;
287
- /**
288
- * Get the workspace analytics object for the user. This returns an instance of AnalyticsCollector,
289
- * or undefined if analytics are disabled.
290
- *
291
- * If any problem happens, it is considered the user has been opting out of analytics.
292
- */
293
- async function getWorkspaceAnalytics() {
294
- analyticsDebug('getWorkspaceAnalytics');
295
- try {
296
- const globalWorkspace = await (0, config_1.getWorkspace)('local');
297
- const analyticsConfig = globalWorkspace === null || globalWorkspace === void 0 ? void 0 : globalWorkspace.getCli()['analytics'];
178
+ const workspace = await (0, config_1.getWorkspace)(level);
179
+ const analyticsConfig = workspace === null || workspace === void 0 ? void 0 : workspace.getCli()['analytics'];
298
180
  analyticsDebug('Workspace Analytics config found: %j', analyticsConfig);
299
181
  if (analyticsConfig === false) {
300
- analyticsDebug('Analytics disabled. Ignoring all analytics.');
301
- return undefined;
182
+ return new core_1.analytics.NoopAnalytics();
302
183
  }
303
184
  else if (analyticsConfig === undefined || analyticsConfig === null) {
304
- analyticsDebug('Analytics settings not found. Ignoring all analytics.');
305
185
  return undefined;
306
186
  }
307
187
  else {
@@ -324,19 +204,16 @@ async function getWorkspaceAnalytics() {
324
204
  return undefined;
325
205
  }
326
206
  }
327
- exports.getWorkspaceAnalytics = getWorkspaceAnalytics;
207
+ exports.getAnalytics = getAnalytics;
328
208
  /**
329
209
  * Return the usage analytics sharing setting, which is either a property string (GA-XXXXXXX-XX),
330
210
  * or undefined if no sharing.
331
211
  */
332
212
  async function getSharedAnalytics() {
333
213
  analyticsDebug('getSharedAnalytics');
334
- const envVarName = 'NG_CLI_ANALYTICS_SHARE';
335
- if (envVarName in process.env) {
336
- if (process.env[envVarName] == 'false' || process.env[envVarName] == '') {
337
- analyticsDebug('NG_CLI_ANALYTICS is false');
338
- return undefined;
339
- }
214
+ if (analytics_environment_options_1.analyticsShareDisabled) {
215
+ analyticsDebug('NG_CLI_ANALYTICS is false');
216
+ return undefined;
340
217
  }
341
218
  // If anything happens we just keep the NOOP analytics.
342
219
  try {
@@ -357,33 +234,70 @@ async function getSharedAnalytics() {
357
234
  }
358
235
  exports.getSharedAnalytics = getSharedAnalytics;
359
236
  async function createAnalytics(workspace, skipPrompt = false) {
360
- let config = await getGlobalAnalytics();
361
- // If in workspace and global analytics is enabled, defer to workspace level
362
- if (workspace && config) {
363
- const skipAnalytics = skipPrompt ||
364
- (process.env['NG_CLI_ANALYTICS'] &&
365
- (process.env['NG_CLI_ANALYTICS'].toLowerCase() === 'false' ||
366
- process.env['NG_CLI_ANALYTICS'] === '0'));
367
- // TODO: This should honor the `no-interactive` option.
368
- // It is currently not an `ng` option but rather only an option for specific commands.
369
- // The concept of `ng`-wide options are needed to cleanly handle this.
370
- if (!skipAnalytics && !(await hasWorkspaceAnalyticsConfiguration())) {
371
- await promptProjectAnalytics();
237
+ // Global config takes precedence over local config only for the disabled check.
238
+ // IE:
239
+ // global: disabled & local: enabled = disabled
240
+ // global: id: 123 & local: id: 456 = 456
241
+ var _a;
242
+ // check global
243
+ const globalConfig = await getAnalytics('global');
244
+ if (globalConfig instanceof core_1.analytics.NoopAnalytics) {
245
+ return globalConfig;
246
+ }
247
+ let config = globalConfig;
248
+ // Not disabled globally, check locally.
249
+ if (workspace) {
250
+ let localConfig = await getAnalytics('local');
251
+ if (localConfig === undefined) {
252
+ if (!skipPrompt) {
253
+ // local is not unset, prompt user.
254
+ // TODO: This should honor the `no-interactive` option.
255
+ // It is currently not an `ng` option but rather only an option for specific commands.
256
+ // The concept of `ng`-wide options are needed to cleanly handle this.
257
+ await promptAnalytics(false);
258
+ localConfig = await getAnalytics('local');
259
+ }
260
+ }
261
+ if (localConfig instanceof core_1.analytics.NoopAnalytics) {
262
+ return localConfig;
263
+ }
264
+ else if (localConfig) {
265
+ // Favor local settings over global when defined.
266
+ config = localConfig;
372
267
  }
373
- config = await getWorkspaceAnalytics();
374
268
  }
269
+ // Get shared analytics
270
+ // TODO: evalute if this should be completly removed.
375
271
  const maybeSharedAnalytics = await getSharedAnalytics();
376
272
  if (config && maybeSharedAnalytics) {
377
273
  return new core_1.analytics.MultiAnalytics([config, maybeSharedAnalytics]);
378
274
  }
379
- else if (config) {
380
- return config;
275
+ return (_a = config !== null && config !== void 0 ? config : maybeSharedAnalytics) !== null && _a !== void 0 ? _a : new core_1.analytics.NoopAnalytics();
276
+ }
277
+ exports.createAnalytics = createAnalytics;
278
+ function analyticsConfigValueToHumanFormat(value) {
279
+ if (value === false) {
280
+ return 'disabled';
381
281
  }
382
- else if (maybeSharedAnalytics) {
383
- return maybeSharedAnalytics;
282
+ else if (typeof value === 'string' || value === true) {
283
+ return 'enabled';
384
284
  }
385
285
  else {
386
- return new core_1.analytics.NoopAnalytics();
286
+ return 'not set';
387
287
  }
388
288
  }
389
- exports.createAnalytics = createAnalytics;
289
+ async function getAnalyticsInfoString() {
290
+ const [globalWorkspace] = (0, config_1.getWorkspaceRaw)('global');
291
+ const [localWorkspace] = (0, config_1.getWorkspaceRaw)('local');
292
+ const globalSetting = globalWorkspace === null || globalWorkspace === void 0 ? void 0 : globalWorkspace.get(['cli', 'analytics']);
293
+ const localSetting = localWorkspace === null || localWorkspace === void 0 ? void 0 : localWorkspace.get(['cli', 'analytics']);
294
+ const analyticsInstance = await createAnalytics(!!localWorkspace /** workspace */, true /** skipPrompt */);
295
+ return (core_1.tags.stripIndents `
296
+ Global setting: ${analyticsConfigValueToHumanFormat(globalSetting)}
297
+ Local setting: ${localWorkspace
298
+ ? analyticsConfigValueToHumanFormat(localSetting)
299
+ : 'No local workspace configuration file.'}
300
+ Effective status: ${analyticsInstance instanceof core_1.analytics.NoopAnalytics ? 'disabled' : 'enabled'}
301
+ ` + '\n');
302
+ }
303
+ exports.getAnalyticsInfoString = getAnalyticsInfoString;
@@ -14,7 +14,6 @@ const core_1 = require("@angular-devkit/core");
14
14
  const fs_1 = require("fs");
15
15
  const path_1 = require("path");
16
16
  const analytics_1 = require("../analytics/analytics");
17
- const package_manager_1 = require("../utilities/package-manager");
18
17
  const command_module_1 = require("./command-module");
19
18
  const json_schema_1 = require("./utilities/json-schema");
20
19
  class ArchitectBaseCommandModule extends command_module_1.CommandModule {
@@ -74,14 +73,14 @@ class ArchitectBaseCommandModule extends command_module_1.CommandModule {
74
73
  }
75
74
  catch (e) {
76
75
  if (e.code === 'MODULE_NOT_FOUND') {
77
- await this.warnOnMissingNodeModules();
76
+ this.warnOnMissingNodeModules();
78
77
  throw new command_module_1.CommandModuleError(`Could not find the '${builderConf}' builder's node package.`);
79
78
  }
80
79
  throw e;
81
80
  }
82
81
  return (0, json_schema_1.parseJsonSchemaToOptions)(new core_1.json.schema.CoreSchemaRegistry(), builderDesc.optionSchema, true);
83
82
  }
84
- async warnOnMissingNodeModules() {
83
+ warnOnMissingNodeModules() {
85
84
  var _a;
86
85
  const basePath = (_a = this.context.workspace) === null || _a === void 0 ? void 0 : _a.basePath;
87
86
  if (!basePath) {
@@ -97,8 +96,7 @@ class ArchitectBaseCommandModule extends command_module_1.CommandModule {
97
96
  (0, fs_1.existsSync)((0, path_1.resolve)(basePath, '.pnp.mjs'))) {
98
97
  return;
99
98
  }
100
- const packageManager = await (0, package_manager_1.getPackageManager)(basePath);
101
- this.context.logger.warn(`Node packages may not be installed. Try installing with '${packageManager} install'.`);
99
+ this.context.logger.warn(`Node packages may not be installed. Try installing with '${this.context.packageManager} install'.`);
102
100
  }
103
101
  }
104
102
  exports.ArchitectBaseCommandModule = ArchitectBaseCommandModule;