@angular/cli 15.0.0-next.3 → 15.0.0-next.5

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 (31) hide show
  1. package/bin/ng.js +6 -6
  2. package/lib/config/schema.json +7 -36
  3. package/lib/config/workspace-schema.d.ts +6 -13
  4. package/package.json +16 -18
  5. package/src/analytics/analytics-collector.d.ts +20 -18
  6. package/src/analytics/analytics-collector.js +93 -170
  7. package/src/analytics/analytics-parameters.d.ts +95 -0
  8. package/src/analytics/analytics-parameters.js +101 -0
  9. package/src/analytics/analytics.d.ts +4 -24
  10. package/src/analytics/analytics.js +51 -144
  11. package/src/command-builder/architect-base-command-module.d.ts +1 -1
  12. package/src/command-builder/architect-base-command-module.js +53 -11
  13. package/src/command-builder/command-module.d.ts +5 -4
  14. package/src/command-builder/command-module.js +40 -33
  15. package/src/command-builder/schematics-command-module.d.ts +0 -1
  16. package/src/command-builder/schematics-command-module.js +12 -19
  17. package/src/command-builder/utilities/json-schema.d.ts +1 -1
  18. package/src/command-builder/utilities/json-schema.js +1 -1
  19. package/src/commands/add/cli.d.ts +0 -1
  20. package/src/commands/add/cli.js +0 -10
  21. package/src/commands/analytics/info/cli.js +1 -1
  22. package/src/commands/analytics/settings/cli.js +3 -3
  23. package/src/commands/completion/long-description.md +2 -5
  24. package/src/commands/config/cli.js +2 -2
  25. package/src/commands/update/cli.js +5 -4
  26. package/src/commands/version/cli.js +2 -2
  27. package/src/utilities/completion.d.ts +2 -2
  28. package/src/utilities/completion.js +18 -30
  29. package/src/utilities/environment-options.d.ts +0 -1
  30. package/src/utilities/environment-options.js +1 -2
  31. package/src/utilities/package-metadata.js +1 -6
@@ -0,0 +1,95 @@
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
+ export declare type PrimitiveTypes = string | number | boolean;
9
+ /**
10
+ * GA built-in request parameters
11
+ * @see https://www.thyngster.com/ga4-measurement-protocol-cheatsheet
12
+ * @see http://go/depot/google3/analytics/container_tag/templates/common/gold/mpv2_schema.js
13
+ */
14
+ export declare enum RequestParameter {
15
+ ClientId = "cid",
16
+ DebugView = "_dbg",
17
+ GtmVersion = "gtm",
18
+ Language = "ul",
19
+ NewToSite = "_nsi",
20
+ NonInteraction = "ni",
21
+ PageLocation = "dl",
22
+ PageTitle = "dt",
23
+ ProtocolVersion = "v",
24
+ SessionEngaged = "seg",
25
+ SessionId = "sid",
26
+ SessionNumber = "sct",
27
+ SessionStart = "_ss",
28
+ TrackingId = "tid",
29
+ TrafficType = "tt",
30
+ UserAgentArchitecture = "uaa",
31
+ UserAgentBitness = "uab",
32
+ UserAgentFullVersionList = "uafvl",
33
+ UserAgentMobile = "uamb",
34
+ UserAgentModel = "uam",
35
+ UserAgentPlatform = "uap",
36
+ UserAgentPlatformVersion = "uapv",
37
+ UserId = "uid"
38
+ }
39
+ /**
40
+ * User scoped custom dimensions.
41
+ * @notes
42
+ * - User custom dimensions limit is 25.
43
+ * - `up.*` string type.
44
+ * - `upn.*` number type.
45
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
46
+ */
47
+ export declare enum UserCustomDimension {
48
+ OsArchitecture = "up.ng_os_architecture",
49
+ NodeVersion = "up.ng_node_version",
50
+ NodeMajorVersion = "upn.ng_node_major_version",
51
+ AngularCLIVersion = "up.ng_cli_version",
52
+ AngularCLIMajorVersion = "upn.ng_cli_major_version",
53
+ PackageManager = "up.ng_package_manager",
54
+ PackageManagerVersion = "up.ng_pkg_manager_version",
55
+ PackageManagerMajorVersion = "upn.ng_pkg_manager_major_v"
56
+ }
57
+ /**
58
+ * Event scoped custom dimensions.
59
+ * @notes
60
+ * - Event custom dimensions limit is 50.
61
+ * - `ep.*` string type.
62
+ * - `epn.*` number type.
63
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
64
+ */
65
+ export declare enum EventCustomDimension {
66
+ Command = "ep.ng_command",
67
+ SchematicCollectionName = "ep.ng_schematic_collection_name",
68
+ SchematicName = "ep.ng_schematic_name",
69
+ Standalone = "ep.ng_standalone",
70
+ Style = "ep.ng_style",
71
+ Routing = "ep.ng_routing",
72
+ InlineTemplate = "ep.ng_inline_template",
73
+ InlineStyle = "ep.ng_inline_style",
74
+ BuilderTarget = "ep.ng_builder_target",
75
+ Aot = "ep.ng_aot",
76
+ Optimization = "ep.ng_optimization"
77
+ }
78
+ /**
79
+ * Event scoped custom mertics.
80
+ * @notes
81
+ * - Event scoped custom mertics limit is 50.
82
+ * - `ep.*` string type.
83
+ * - `epn.*` number type.
84
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
85
+ */
86
+ export declare enum EventCustomMetric {
87
+ AllChunksCount = "epn.ng_all_chunks_count",
88
+ LazyChunksCount = "epn.ng_lazy_chunks_count",
89
+ InitialChunksCount = "epn.ng_initial_chunks_count",
90
+ ChangedChunksCount = "epn.ng_changed_chunks_count",
91
+ DurationInMs = "epn.ng_duration_ms",
92
+ CssSizeInBytes = "epn.ng_css_size_bytes",
93
+ JsSizeInBytes = "epn.ng_js_size_bytes",
94
+ NgComponentCount = "epn.ng_component_count"
95
+ }
@@ -0,0 +1,101 @@
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.EventCustomMetric = exports.EventCustomDimension = exports.UserCustomDimension = exports.RequestParameter = void 0;
11
+ /**
12
+ * GA built-in request parameters
13
+ * @see https://www.thyngster.com/ga4-measurement-protocol-cheatsheet
14
+ * @see http://go/depot/google3/analytics/container_tag/templates/common/gold/mpv2_schema.js
15
+ */
16
+ var RequestParameter;
17
+ (function (RequestParameter) {
18
+ RequestParameter["ClientId"] = "cid";
19
+ RequestParameter["DebugView"] = "_dbg";
20
+ RequestParameter["GtmVersion"] = "gtm";
21
+ RequestParameter["Language"] = "ul";
22
+ RequestParameter["NewToSite"] = "_nsi";
23
+ RequestParameter["NonInteraction"] = "ni";
24
+ RequestParameter["PageLocation"] = "dl";
25
+ RequestParameter["PageTitle"] = "dt";
26
+ RequestParameter["ProtocolVersion"] = "v";
27
+ RequestParameter["SessionEngaged"] = "seg";
28
+ RequestParameter["SessionId"] = "sid";
29
+ RequestParameter["SessionNumber"] = "sct";
30
+ RequestParameter["SessionStart"] = "_ss";
31
+ RequestParameter["TrackingId"] = "tid";
32
+ RequestParameter["TrafficType"] = "tt";
33
+ RequestParameter["UserAgentArchitecture"] = "uaa";
34
+ RequestParameter["UserAgentBitness"] = "uab";
35
+ RequestParameter["UserAgentFullVersionList"] = "uafvl";
36
+ RequestParameter["UserAgentMobile"] = "uamb";
37
+ RequestParameter["UserAgentModel"] = "uam";
38
+ RequestParameter["UserAgentPlatform"] = "uap";
39
+ RequestParameter["UserAgentPlatformVersion"] = "uapv";
40
+ RequestParameter["UserId"] = "uid";
41
+ })(RequestParameter = exports.RequestParameter || (exports.RequestParameter = {}));
42
+ /**
43
+ * User scoped custom dimensions.
44
+ * @notes
45
+ * - User custom dimensions limit is 25.
46
+ * - `up.*` string type.
47
+ * - `upn.*` number type.
48
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
49
+ */
50
+ var UserCustomDimension;
51
+ (function (UserCustomDimension) {
52
+ UserCustomDimension["OsArchitecture"] = "up.ng_os_architecture";
53
+ UserCustomDimension["NodeVersion"] = "up.ng_node_version";
54
+ UserCustomDimension["NodeMajorVersion"] = "upn.ng_node_major_version";
55
+ UserCustomDimension["AngularCLIVersion"] = "up.ng_cli_version";
56
+ UserCustomDimension["AngularCLIMajorVersion"] = "upn.ng_cli_major_version";
57
+ UserCustomDimension["PackageManager"] = "up.ng_package_manager";
58
+ UserCustomDimension["PackageManagerVersion"] = "up.ng_pkg_manager_version";
59
+ UserCustomDimension["PackageManagerMajorVersion"] = "upn.ng_pkg_manager_major_v";
60
+ })(UserCustomDimension = exports.UserCustomDimension || (exports.UserCustomDimension = {}));
61
+ /**
62
+ * Event scoped custom dimensions.
63
+ * @notes
64
+ * - Event custom dimensions limit is 50.
65
+ * - `ep.*` string type.
66
+ * - `epn.*` number type.
67
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
68
+ */
69
+ var EventCustomDimension;
70
+ (function (EventCustomDimension) {
71
+ EventCustomDimension["Command"] = "ep.ng_command";
72
+ EventCustomDimension["SchematicCollectionName"] = "ep.ng_schematic_collection_name";
73
+ EventCustomDimension["SchematicName"] = "ep.ng_schematic_name";
74
+ EventCustomDimension["Standalone"] = "ep.ng_standalone";
75
+ EventCustomDimension["Style"] = "ep.ng_style";
76
+ EventCustomDimension["Routing"] = "ep.ng_routing";
77
+ EventCustomDimension["InlineTemplate"] = "ep.ng_inline_template";
78
+ EventCustomDimension["InlineStyle"] = "ep.ng_inline_style";
79
+ EventCustomDimension["BuilderTarget"] = "ep.ng_builder_target";
80
+ EventCustomDimension["Aot"] = "ep.ng_aot";
81
+ EventCustomDimension["Optimization"] = "ep.ng_optimization";
82
+ })(EventCustomDimension = exports.EventCustomDimension || (exports.EventCustomDimension = {}));
83
+ /**
84
+ * Event scoped custom mertics.
85
+ * @notes
86
+ * - Event scoped custom mertics limit is 50.
87
+ * - `ep.*` string type.
88
+ * - `epn.*` number type.
89
+ * @see https://support.google.com/analytics/answer/10075209?hl=en
90
+ */
91
+ var EventCustomMetric;
92
+ (function (EventCustomMetric) {
93
+ EventCustomMetric["AllChunksCount"] = "epn.ng_all_chunks_count";
94
+ EventCustomMetric["LazyChunksCount"] = "epn.ng_lazy_chunks_count";
95
+ EventCustomMetric["InitialChunksCount"] = "epn.ng_initial_chunks_count";
96
+ EventCustomMetric["ChangedChunksCount"] = "epn.ng_changed_chunks_count";
97
+ EventCustomMetric["DurationInMs"] = "epn.ng_duration_ms";
98
+ EventCustomMetric["CssSizeInBytes"] = "epn.ng_css_size_bytes";
99
+ EventCustomMetric["JsSizeInBytes"] = "epn.ng_js_size_bytes";
100
+ EventCustomMetric["NgComponentCount"] = "epn.ng_component_count";
101
+ })(EventCustomMetric = exports.EventCustomMetric || (exports.EventCustomMetric = {}));
@@ -5,13 +5,7 @@
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 { analytics } from '@angular-devkit/core';
9
- import { AnalyticsCollector } from './analytics-collector';
10
- export declare const AnalyticsProperties: {
11
- AngularCliProd: string;
12
- AngularCliStaging: string;
13
- readonly AngularCliDefault: string;
14
- };
8
+ import type { CommandContext } from '../command-builder/command-module';
15
9
  /**
16
10
  * This is the ultimate safelist for checking if a package name is safe to report to analytics.
17
11
  */
@@ -28,20 +22,6 @@ export declare function setAnalyticsConfig(global: boolean, value: string | bool
28
22
  * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
29
23
  * @return Whether or not the user was shown a prompt.
30
24
  */
31
- export declare function promptAnalytics(global: boolean, force?: boolean): Promise<boolean>;
32
- /**
33
- * Get the analytics object for the user.
34
- *
35
- * @returns
36
- * - `AnalyticsCollector` when enabled.
37
- * - `analytics.NoopAnalytics` when disabled.
38
- * - `undefined` when not configured.
39
- */
40
- export declare function getAnalytics(level: 'local' | 'global'): Promise<AnalyticsCollector | analytics.NoopAnalytics | undefined>;
41
- /**
42
- * Return the usage analytics sharing setting, which is either a property string (GA-XXXXXXX-XX),
43
- * or undefined if no sharing.
44
- */
45
- export declare function getSharedAnalytics(): Promise<AnalyticsCollector | undefined>;
46
- export declare function createAnalytics(workspace: boolean, skipPrompt?: boolean): Promise<analytics.Analytics>;
47
- export declare function getAnalyticsInfoString(): Promise<string>;
25
+ export declare function promptAnalytics(context: CommandContext, global: boolean, force?: boolean): Promise<boolean>;
26
+ export declare function getAnalyticsUserId(context: CommandContext, skipPrompt?: boolean): Promise<string | undefined>;
27
+ export declare function getAnalyticsInfoString(context: CommandContext): Promise<string>;
@@ -29,47 +29,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
29
29
  __setModuleDefault(result, mod);
30
30
  return result;
31
31
  };
32
- var __importDefault = (this && this.__importDefault) || function (mod) {
33
- return (mod && mod.__esModule) ? mod : { "default": mod };
34
- };
35
32
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.getAnalyticsInfoString = exports.createAnalytics = exports.getSharedAnalytics = exports.getAnalytics = exports.promptAnalytics = exports.setAnalyticsConfig = exports.isPackageNameSafeForAnalytics = exports.analyticsPackageSafelist = exports.AnalyticsProperties = void 0;
33
+ exports.getAnalyticsInfoString = exports.getAnalyticsUserId = exports.promptAnalytics = exports.setAnalyticsConfig = exports.isPackageNameSafeForAnalytics = exports.analyticsPackageSafelist = void 0;
37
34
  const core_1 = require("@angular-devkit/core");
38
- const debug_1 = __importDefault(require("debug"));
39
- const uuid_1 = require("uuid");
35
+ const crypto_1 = require("crypto");
40
36
  const color_1 = require("../utilities/color");
41
37
  const config_1 = require("../utilities/config");
42
38
  const environment_options_1 = require("../utilities/environment-options");
43
- const error_1 = require("../utilities/error");
44
39
  const tty_1 = require("../utilities/tty");
45
- const version_1 = require("../utilities/version");
46
- const analytics_collector_1 = require("./analytics-collector");
47
40
  /* eslint-disable no-console */
48
- const analyticsDebug = (0, debug_1.default)('ng:analytics'); // Generate analytics, including settings and users.
49
- let _defaultAngularCliPropertyCache;
50
- exports.AnalyticsProperties = {
51
- AngularCliProd: 'UA-8594346-29',
52
- AngularCliStaging: 'UA-8594346-32',
53
- get AngularCliDefault() {
54
- if (_defaultAngularCliPropertyCache) {
55
- return _defaultAngularCliPropertyCache;
56
- }
57
- const v = version_1.VERSION.full;
58
- // The logic is if it's a full version then we should use the prod GA property.
59
- _defaultAngularCliPropertyCache =
60
- /^\d+\.\d+\.\d+$/.test(v) && v !== '0.0.0'
61
- ? exports.AnalyticsProperties.AngularCliProd
62
- : exports.AnalyticsProperties.AngularCliStaging;
63
- return _defaultAngularCliPropertyCache;
64
- },
65
- };
66
41
  /**
67
42
  * This is the ultimate safelist for checking if a package name is safe to report to analytics.
68
43
  */
69
44
  exports.analyticsPackageSafelist = [
70
45
  /^@angular\//,
71
46
  /^@angular-devkit\//,
72
- /^@ngtools\//,
47
+ /^@nguniversal\//,
73
48
  '@schematics/angular',
74
49
  ];
75
50
  function isPackageNameSafeForAnalytics(name) {
@@ -92,7 +67,6 @@ async function setAnalyticsConfig(global, value) {
92
67
  var _a;
93
68
  var _b;
94
69
  const level = global ? 'global' : 'local';
95
- analyticsDebug('setting %s level analytics to: %s', level, value);
96
70
  const workspace = await (0, config_1.getWorkspace)(level);
97
71
  if (!workspace) {
98
72
  throw new Error(`Could not find ${level} workspace.`);
@@ -101,9 +75,8 @@ async function setAnalyticsConfig(global, value) {
101
75
  if (!workspace || !core_1.json.isJsonObject(cli)) {
102
76
  throw new Error(`Invalid config found at ${workspace.filePath}. CLI should be an object.`);
103
77
  }
104
- cli.analytics = value === true ? (0, uuid_1.v4)() : value;
78
+ cli.analytics = value === true ? (0, crypto_1.randomUUID)() : value;
105
79
  await workspace.save();
106
- analyticsDebug('done');
107
80
  }
108
81
  exports.setAnalyticsConfig = setAnalyticsConfig;
109
82
  /**
@@ -111,8 +84,7 @@ exports.setAnalyticsConfig = setAnalyticsConfig;
111
84
  * @param force Whether to ask regardless of whether or not the user is using an interactive shell.
112
85
  * @return Whether or not the user was shown a prompt.
113
86
  */
114
- async function promptAnalytics(global, force = false) {
115
- analyticsDebug('prompting user');
87
+ async function promptAnalytics(context, global, force = false) {
116
88
  const level = global ? 'global' : 'local';
117
89
  const workspace = await (0, config_1.getWorkspace)(level);
118
90
  if (!workspace) {
@@ -125,11 +97,11 @@ async function promptAnalytics(global, force = false) {
125
97
  type: 'confirm',
126
98
  name: 'analytics',
127
99
  message: core_1.tags.stripIndents `
128
- Would you like to share pseudonymous usage data about this project with the Angular Team
129
- at Google under Google's Privacy Policy at https://policies.google.com/privacy. For more
130
- details and how to change this setting, see https://angular.io/analytics.
100
+ Would you like to share pseudonymous usage data about this project with the Angular Team
101
+ at Google under Google's Privacy Policy at https://policies.google.com/privacy. For more
102
+ details and how to change this setting, see https://angular.io/analytics.
131
103
 
132
- `,
104
+ `,
133
105
  default: false,
134
106
  },
135
107
  ]);
@@ -137,149 +109,85 @@ async function promptAnalytics(global, force = false) {
137
109
  if (answers.analytics) {
138
110
  console.log('');
139
111
  console.log(core_1.tags.stripIndent `
140
- Thank you for sharing pseudonymous usage data. Should you change your mind, the following
141
- command will disable this feature entirely:
112
+ Thank you for sharing pseudonymous usage data. Should you change your mind, the following
113
+ command will disable this feature entirely:
142
114
 
143
- ${color_1.colors.yellow(`ng analytics disable${global ? ' --global' : ''}`)}
144
- `);
115
+ ${color_1.colors.yellow(`ng analytics disable${global ? ' --global' : ''}`)}
116
+ `);
145
117
  console.log('');
146
- // Send back a ping with the user `optin`.
147
- const ua = new analytics_collector_1.AnalyticsCollector(exports.AnalyticsProperties.AngularCliDefault, 'optin');
148
- ua.pageview('/telemetry/project/optin');
149
- await ua.flush();
150
- }
151
- else {
152
- // Send back a ping with the user `optout`. This is the only thing we send.
153
- const ua = new analytics_collector_1.AnalyticsCollector(exports.AnalyticsProperties.AngularCliDefault, 'optout');
154
- ua.pageview('/telemetry/project/optout');
155
- await ua.flush();
156
118
  }
157
- process.stderr.write(await getAnalyticsInfoString());
119
+ process.stderr.write(await getAnalyticsInfoString(context));
158
120
  return true;
159
121
  }
160
122
  return false;
161
123
  }
162
124
  exports.promptAnalytics = promptAnalytics;
163
125
  /**
164
- * Get the analytics object for the user.
126
+ * Get the analytics user id.
165
127
  *
166
128
  * @returns
167
- * - `AnalyticsCollector` when enabled.
168
- * - `analytics.NoopAnalytics` when disabled.
129
+ * - `string` user id.
130
+ * - `false` when disabled.
169
131
  * - `undefined` when not configured.
170
132
  */
171
- async function getAnalytics(level) {
133
+ async function getAnalyticsUserIdForLevel(level) {
172
134
  var _a;
173
- analyticsDebug('getAnalytics');
174
135
  if (environment_options_1.analyticsDisabled) {
175
- analyticsDebug('NG_CLI_ANALYTICS is false');
176
- return new core_1.analytics.NoopAnalytics();
136
+ return false;
177
137
  }
178
- try {
179
- const workspace = await (0, config_1.getWorkspace)(level);
180
- const analyticsConfig = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.getCli()) === null || _a === void 0 ? void 0 : _a['analytics'];
181
- analyticsDebug('Workspace Analytics config found: %j', analyticsConfig);
182
- if (analyticsConfig === false) {
183
- return new core_1.analytics.NoopAnalytics();
184
- }
185
- else if (analyticsConfig === undefined || analyticsConfig === null) {
186
- return undefined;
187
- }
188
- else {
189
- let uid = undefined;
190
- if (typeof analyticsConfig == 'string') {
191
- uid = analyticsConfig;
192
- }
193
- else if (typeof analyticsConfig == 'object' && typeof analyticsConfig['uid'] == 'string') {
194
- uid = analyticsConfig['uid'];
195
- }
196
- analyticsDebug('client id: %j', uid);
197
- if (uid == undefined) {
198
- return undefined;
199
- }
200
- return new analytics_collector_1.AnalyticsCollector(exports.AnalyticsProperties.AngularCliDefault, uid);
201
- }
202
- }
203
- catch (err) {
204
- (0, error_1.assertIsError)(err);
205
- analyticsDebug('Error happened during reading of analytics config: %s', err.message);
206
- return undefined;
138
+ const workspace = await (0, config_1.getWorkspace)(level);
139
+ const analyticsConfig = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.getCli()) === null || _a === void 0 ? void 0 : _a['analytics'];
140
+ if (analyticsConfig === false) {
141
+ return false;
207
142
  }
208
- }
209
- exports.getAnalytics = getAnalytics;
210
- /**
211
- * Return the usage analytics sharing setting, which is either a property string (GA-XXXXXXX-XX),
212
- * or undefined if no sharing.
213
- */
214
- async function getSharedAnalytics() {
215
- var _a;
216
- analyticsDebug('getSharedAnalytics');
217
- if (environment_options_1.analyticsShareDisabled) {
218
- analyticsDebug('NG_CLI_ANALYTICS is false');
143
+ else if (analyticsConfig === undefined || analyticsConfig === null) {
219
144
  return undefined;
220
145
  }
221
- // If anything happens we just keep the NOOP analytics.
222
- try {
223
- const globalWorkspace = await (0, config_1.getWorkspace)('global');
224
- const analyticsConfig = (_a = globalWorkspace === null || globalWorkspace === void 0 ? void 0 : globalWorkspace.getCli()) === null || _a === void 0 ? void 0 : _a['analyticsSharing'];
225
- if (!analyticsConfig || !analyticsConfig.tracking || !analyticsConfig.uuid) {
226
- return undefined;
146
+ else {
147
+ if (typeof analyticsConfig == 'string') {
148
+ return analyticsConfig;
227
149
  }
228
- else {
229
- analyticsDebug('Analytics sharing info: %j', analyticsConfig);
230
- return new analytics_collector_1.AnalyticsCollector(analyticsConfig.tracking, analyticsConfig.uuid);
150
+ else if (typeof analyticsConfig == 'object' && typeof analyticsConfig['uid'] == 'string') {
151
+ return analyticsConfig['uid'];
231
152
  }
232
- }
233
- catch (err) {
234
- (0, error_1.assertIsError)(err);
235
- analyticsDebug('Error happened during reading of analytics sharing config: %s', err.message);
236
153
  return undefined;
237
154
  }
238
155
  }
239
- exports.getSharedAnalytics = getSharedAnalytics;
240
- async function createAnalytics(workspace, skipPrompt = false) {
156
+ async function getAnalyticsUserId(context, skipPrompt = false) {
157
+ const { workspace } = context;
241
158
  // Global config takes precedence over local config only for the disabled check.
242
159
  // IE:
243
160
  // global: disabled & local: enabled = disabled
244
161
  // global: id: 123 & local: id: 456 = 456
245
- var _a;
246
162
  // check global
247
- const globalConfig = await getAnalytics('global');
248
- if (globalConfig instanceof core_1.analytics.NoopAnalytics) {
249
- return globalConfig;
163
+ const globalConfig = await getAnalyticsUserIdForLevel('global');
164
+ if (globalConfig === false) {
165
+ return undefined;
250
166
  }
251
- let config = globalConfig;
252
167
  // Not disabled globally, check locally or not set globally and command is run outside of workspace example: `ng new`
253
168
  if (workspace || globalConfig === undefined) {
254
169
  const level = workspace ? 'local' : 'global';
255
- let localOrGlobalConfig = await getAnalytics(level);
170
+ let localOrGlobalConfig = await getAnalyticsUserIdForLevel(level);
256
171
  if (localOrGlobalConfig === undefined) {
257
172
  if (!skipPrompt) {
258
173
  // config is unset, prompt user.
259
174
  // TODO: This should honor the `no-interactive` option.
260
175
  // It is currently not an `ng` option but rather only an option for specific commands.
261
176
  // The concept of `ng`-wide options are needed to cleanly handle this.
262
- await promptAnalytics(!workspace /** global */);
263
- localOrGlobalConfig = await getAnalytics(level);
177
+ await promptAnalytics(context, !workspace /** global */);
178
+ localOrGlobalConfig = await getAnalyticsUserIdForLevel(level);
264
179
  }
265
180
  }
266
- if (localOrGlobalConfig instanceof core_1.analytics.NoopAnalytics) {
267
- return localOrGlobalConfig;
181
+ if (localOrGlobalConfig === false) {
182
+ return undefined;
268
183
  }
269
- else if (localOrGlobalConfig) {
270
- // Favor local settings over global when defined.
271
- config = localOrGlobalConfig;
184
+ else if (typeof localOrGlobalConfig === 'string') {
185
+ return localOrGlobalConfig;
272
186
  }
273
187
  }
274
- // Get shared analytics
275
- // TODO: evalute if this should be completly removed.
276
- const maybeSharedAnalytics = await getSharedAnalytics();
277
- if (config && maybeSharedAnalytics) {
278
- return new core_1.analytics.MultiAnalytics([config, maybeSharedAnalytics]);
279
- }
280
- return (_a = config !== null && config !== void 0 ? config : maybeSharedAnalytics) !== null && _a !== void 0 ? _a : new core_1.analytics.NoopAnalytics();
188
+ return globalConfig || (0, crypto_1.randomUUID)();
281
189
  }
282
- exports.createAnalytics = createAnalytics;
190
+ exports.getAnalyticsUserId = getAnalyticsUserId;
283
191
  function analyticsConfigValueToHumanFormat(value) {
284
192
  if (value === false) {
285
193
  return 'disabled';
@@ -291,19 +199,18 @@ function analyticsConfigValueToHumanFormat(value) {
291
199
  return 'not set';
292
200
  }
293
201
  }
294
- async function getAnalyticsInfoString() {
202
+ async function getAnalyticsInfoString(context) {
295
203
  var _a, _b;
296
- const globalWorkspace = await (0, config_1.getWorkspace)('global');
297
- const localWorkspace = await (0, config_1.getWorkspace)('local');
298
- const globalSetting = (_a = globalWorkspace === null || globalWorkspace === void 0 ? void 0 : globalWorkspace.getCli()) === null || _a === void 0 ? void 0 : _a['analytics'];
204
+ const analyticsInstance = await getAnalyticsUserId(context, true /** skipPrompt */);
205
+ const { globalConfiguration, workspace: localWorkspace } = context;
206
+ const globalSetting = (_a = globalConfiguration === null || globalConfiguration === void 0 ? void 0 : globalConfiguration.getCli()) === null || _a === void 0 ? void 0 : _a['analytics'];
299
207
  const localSetting = (_b = localWorkspace === null || localWorkspace === void 0 ? void 0 : localWorkspace.getCli()) === null || _b === void 0 ? void 0 : _b['analytics'];
300
- const analyticsInstance = await createAnalytics(!!localWorkspace /** workspace */, true /** skipPrompt */);
301
208
  return (core_1.tags.stripIndents `
302
- Global setting: ${analyticsConfigValueToHumanFormat(globalSetting)}
303
- Local setting: ${localWorkspace
209
+ Global setting: ${analyticsConfigValueToHumanFormat(globalSetting)}
210
+ Local setting: ${localWorkspace
304
211
  ? analyticsConfigValueToHumanFormat(localSetting)
305
212
  : 'No local workspace configuration file.'}
306
- Effective status: ${analyticsInstance instanceof core_1.analytics.NoopAnalytics ? 'disabled' : 'enabled'}
307
- ` + '\n');
213
+ Effective status: ${analyticsInstance ? 'enabled' : 'disabled'}
214
+ ` + '\n');
308
215
  }
309
216
  exports.getAnalyticsInfoString = getAnalyticsInfoString;
@@ -15,9 +15,9 @@ export interface MissingTargetChoice {
15
15
  }
16
16
  export declare abstract class ArchitectBaseCommandModule<T extends object> extends CommandModule<T> implements CommandModuleImplementation<T> {
17
17
  scope: CommandScope;
18
- protected shouldReportAnalytics: boolean;
19
18
  protected readonly missingTargetChoices: MissingTargetChoice[] | undefined;
20
19
  protected runSingleTarget(target: Target, options: OtherOptions): Promise<number>;
20
+ private builderStatsToAnalyticsParameters;
21
21
  private _architectHost;
22
22
  protected getArchitectHost(): WorkspaceNodeModulesArchitectHost;
23
23
  private _architect;
@@ -15,6 +15,7 @@ const child_process_1 = require("child_process");
15
15
  const fs_1 = require("fs");
16
16
  const path_1 = require("path");
17
17
  const analytics_1 = require("../analytics/analytics");
18
+ const analytics_parameters_1 = require("../analytics/analytics-parameters");
18
19
  const error_1 = require("../utilities/error");
19
20
  const prompt_1 = require("../utilities/prompt");
20
21
  const tty_1 = require("../utilities/tty");
@@ -24,7 +25,6 @@ class ArchitectBaseCommandModule extends command_module_1.CommandModule {
24
25
  constructor() {
25
26
  super(...arguments);
26
27
  this.scope = command_module_1.CommandScope.In;
27
- this.shouldReportAnalytics = false;
28
28
  }
29
29
  async runSingleTarget(target, options) {
30
30
  const architectHost = await this.getArchitectHost();
@@ -36,21 +36,63 @@ class ArchitectBaseCommandModule extends command_module_1.CommandModule {
36
36
  (0, error_1.assertIsError)(e);
37
37
  return this.onMissingTarget(e.message);
38
38
  }
39
- await this.reportAnalytics({
40
- ...(await architectHost.getOptionsForTarget(target)),
41
- ...options,
42
- }, undefined /** paths */, undefined /** dimensions */, builderName);
43
39
  const { logger } = this.context;
44
40
  const run = await this.getArchitect().scheduleTarget(target, options, {
45
41
  logger,
46
- analytics: (0, analytics_1.isPackageNameSafeForAnalytics)(builderName) ? await this.getAnalytics() : undefined,
47
42
  });
48
- const { error, success } = await run.output.toPromise();
49
- await run.stop();
50
- if (error) {
51
- logger.error(error);
43
+ const analytics = (0, analytics_1.isPackageNameSafeForAnalytics)(builderName)
44
+ ? await this.getAnalytics()
45
+ : undefined;
46
+ let outputSubscription;
47
+ if (analytics) {
48
+ analytics.reportArchitectRunEvent({
49
+ [analytics_parameters_1.EventCustomDimension.BuilderTarget]: builderName,
50
+ });
51
+ let firstRun = true;
52
+ outputSubscription = run.output.subscribe(({ stats }) => {
53
+ const parameters = this.builderStatsToAnalyticsParameters(stats, builderName);
54
+ if (!parameters) {
55
+ return;
56
+ }
57
+ if (firstRun) {
58
+ firstRun = false;
59
+ analytics.reportBuildRunEvent(parameters);
60
+ }
61
+ else {
62
+ analytics.reportRebuildRunEvent(parameters);
63
+ }
64
+ });
65
+ }
66
+ try {
67
+ const { error, success } = await run.output.toPromise();
68
+ if (error) {
69
+ logger.error(error);
70
+ }
71
+ return success ? 0 : 1;
52
72
  }
53
- return success ? 0 : 1;
73
+ finally {
74
+ await run.stop();
75
+ outputSubscription === null || outputSubscription === void 0 ? void 0 : outputSubscription.unsubscribe();
76
+ }
77
+ }
78
+ builderStatsToAnalyticsParameters(stats, builderName) {
79
+ if (!stats || typeof stats !== 'object' || !('durationInMs' in stats)) {
80
+ return undefined;
81
+ }
82
+ const { optimization, allChunksCount, aot, lazyChunksCount, initialChunksCount, durationInMs, changedChunksCount, cssSizeInBytes, jsSizeInBytes, ngComponentCount, } = stats;
83
+ return {
84
+ [analytics_parameters_1.EventCustomDimension.BuilderTarget]: builderName,
85
+ [analytics_parameters_1.EventCustomDimension.Aot]: aot,
86
+ [analytics_parameters_1.EventCustomDimension.Optimization]: optimization,
87
+ [analytics_parameters_1.EventCustomMetric.AllChunksCount]: allChunksCount,
88
+ [analytics_parameters_1.EventCustomMetric.LazyChunksCount]: lazyChunksCount,
89
+ [analytics_parameters_1.EventCustomMetric.InitialChunksCount]: initialChunksCount,
90
+ [analytics_parameters_1.EventCustomMetric.ChangedChunksCount]: changedChunksCount,
91
+ [analytics_parameters_1.EventCustomMetric.DurationInMs]: durationInMs,
92
+ [analytics_parameters_1.EventCustomMetric.JsSizeInBytes]: jsSizeInBytes,
93
+ [analytics_parameters_1.EventCustomMetric.CssSizeInBytes]: cssSizeInBytes,
94
+ [analytics_parameters_1.EventCustomMetric.NgComponentCount]: ngComponentCount,
95
+ };
54
96
  }
55
97
  getArchitectHost() {
56
98
  if (this._architectHost) {