@angular/cli 15.0.0-next.4 → 15.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.
- package/bin/ng.js +6 -6
- package/lib/config/schema.json +7 -36
- package/lib/config/workspace-schema.d.ts +6 -13
- package/package.json +13 -14
- package/src/analytics/analytics-collector.d.ts +21 -18
- package/src/analytics/analytics-collector.js +98 -170
- package/src/analytics/analytics-parameters.d.ts +99 -0
- package/src/analytics/analytics-parameters.js +105 -0
- package/src/analytics/analytics.d.ts +4 -24
- package/src/analytics/analytics.js +49 -142
- package/src/command-builder/architect-base-command-module.d.ts +1 -1
- package/src/command-builder/architect-base-command-module.js +53 -11
- package/src/command-builder/command-module.d.ts +7 -4
- package/src/command-builder/command-module.js +67 -34
- package/src/command-builder/schematics-command-module.d.ts +0 -1
- package/src/command-builder/schematics-command-module.js +12 -19
- package/src/command-builder/utilities/json-schema.d.ts +1 -1
- package/src/command-builder/utilities/json-schema.js +1 -1
- package/src/commands/add/cli.d.ts +0 -1
- package/src/commands/add/cli.js +0 -10
- package/src/commands/analytics/info/cli.js +1 -1
- package/src/commands/analytics/settings/cli.js +3 -3
- package/src/commands/update/cli.js +5 -4
- package/src/commands/version/cli.js +2 -2
- package/src/utilities/completion.d.ts +2 -2
- package/src/utilities/completion.js +18 -30
- package/src/utilities/environment-options.d.ts +0 -1
- package/src/utilities/environment-options.js +1 -2
- package/src/utilities/package-metadata.js +1 -6
|
@@ -0,0 +1,99 @@
|
|
|
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
|
+
UserId = "up.ng_user_id",
|
|
49
|
+
OsArchitecture = "up.ng_os_architecture",
|
|
50
|
+
NodeVersion = "up.ng_node_version",
|
|
51
|
+
NodeMajorVersion = "upn.ng_node_major_version",
|
|
52
|
+
AngularCLIVersion = "up.ng_cli_version",
|
|
53
|
+
AngularCLIMajorVersion = "upn.ng_cli_major_version",
|
|
54
|
+
PackageManager = "up.ng_package_manager",
|
|
55
|
+
PackageManagerVersion = "up.ng_pkg_manager_version",
|
|
56
|
+
PackageManagerMajorVersion = "upn.ng_pkg_manager_major_v"
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Event scoped custom dimensions.
|
|
60
|
+
* @notes
|
|
61
|
+
* - Event custom dimensions limit is 50.
|
|
62
|
+
* - `ep.*` string type.
|
|
63
|
+
* - `epn.*` number type.
|
|
64
|
+
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
|
65
|
+
*/
|
|
66
|
+
export declare enum EventCustomDimension {
|
|
67
|
+
Command = "ep.ng_command",
|
|
68
|
+
SchematicCollectionName = "ep.ng_schematic_collection_name",
|
|
69
|
+
SchematicName = "ep.ng_schematic_name",
|
|
70
|
+
Standalone = "ep.ng_standalone",
|
|
71
|
+
Style = "ep.ng_style",
|
|
72
|
+
Routing = "ep.ng_routing",
|
|
73
|
+
InlineTemplate = "ep.ng_inline_template",
|
|
74
|
+
InlineStyle = "ep.ng_inline_style",
|
|
75
|
+
BuilderTarget = "ep.ng_builder_target",
|
|
76
|
+
Aot = "ep.ng_aot",
|
|
77
|
+
Optimization = "ep.ng_optimization"
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Event scoped custom mertics.
|
|
81
|
+
* @notes
|
|
82
|
+
* - Event scoped custom mertics limit is 50.
|
|
83
|
+
* - `ep.*` string type.
|
|
84
|
+
* - `epn.*` number type.
|
|
85
|
+
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
|
86
|
+
*/
|
|
87
|
+
export declare enum EventCustomMetric {
|
|
88
|
+
AllChunksCount = "epn.ng_all_chunks_count",
|
|
89
|
+
LazyChunksCount = "epn.ng_lazy_chunks_count",
|
|
90
|
+
InitialChunksCount = "epn.ng_initial_chunks_count",
|
|
91
|
+
ChangedChunksCount = "epn.ng_changed_chunks_count",
|
|
92
|
+
DurationInMs = "epn.ng_duration_ms",
|
|
93
|
+
CssSizeInBytes = "epn.ng_css_size_bytes",
|
|
94
|
+
JsSizeInBytes = "epn.ng_js_size_bytes",
|
|
95
|
+
NgComponentCount = "epn.ng_component_count",
|
|
96
|
+
AllProjectsCount = "epn.all_projects_count",
|
|
97
|
+
LibraryProjectsCount = "epn.libs_projects_count",
|
|
98
|
+
ApplicationProjectsCount = "epn.apps_projects_count"
|
|
99
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
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["UserId"] = "up.ng_user_id";
|
|
53
|
+
UserCustomDimension["OsArchitecture"] = "up.ng_os_architecture";
|
|
54
|
+
UserCustomDimension["NodeVersion"] = "up.ng_node_version";
|
|
55
|
+
UserCustomDimension["NodeMajorVersion"] = "upn.ng_node_major_version";
|
|
56
|
+
UserCustomDimension["AngularCLIVersion"] = "up.ng_cli_version";
|
|
57
|
+
UserCustomDimension["AngularCLIMajorVersion"] = "upn.ng_cli_major_version";
|
|
58
|
+
UserCustomDimension["PackageManager"] = "up.ng_package_manager";
|
|
59
|
+
UserCustomDimension["PackageManagerVersion"] = "up.ng_pkg_manager_version";
|
|
60
|
+
UserCustomDimension["PackageManagerMajorVersion"] = "upn.ng_pkg_manager_major_v";
|
|
61
|
+
})(UserCustomDimension = exports.UserCustomDimension || (exports.UserCustomDimension = {}));
|
|
62
|
+
/**
|
|
63
|
+
* Event scoped custom dimensions.
|
|
64
|
+
* @notes
|
|
65
|
+
* - Event custom dimensions limit is 50.
|
|
66
|
+
* - `ep.*` string type.
|
|
67
|
+
* - `epn.*` number type.
|
|
68
|
+
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
|
69
|
+
*/
|
|
70
|
+
var EventCustomDimension;
|
|
71
|
+
(function (EventCustomDimension) {
|
|
72
|
+
EventCustomDimension["Command"] = "ep.ng_command";
|
|
73
|
+
EventCustomDimension["SchematicCollectionName"] = "ep.ng_schematic_collection_name";
|
|
74
|
+
EventCustomDimension["SchematicName"] = "ep.ng_schematic_name";
|
|
75
|
+
EventCustomDimension["Standalone"] = "ep.ng_standalone";
|
|
76
|
+
EventCustomDimension["Style"] = "ep.ng_style";
|
|
77
|
+
EventCustomDimension["Routing"] = "ep.ng_routing";
|
|
78
|
+
EventCustomDimension["InlineTemplate"] = "ep.ng_inline_template";
|
|
79
|
+
EventCustomDimension["InlineStyle"] = "ep.ng_inline_style";
|
|
80
|
+
EventCustomDimension["BuilderTarget"] = "ep.ng_builder_target";
|
|
81
|
+
EventCustomDimension["Aot"] = "ep.ng_aot";
|
|
82
|
+
EventCustomDimension["Optimization"] = "ep.ng_optimization";
|
|
83
|
+
})(EventCustomDimension = exports.EventCustomDimension || (exports.EventCustomDimension = {}));
|
|
84
|
+
/**
|
|
85
|
+
* Event scoped custom mertics.
|
|
86
|
+
* @notes
|
|
87
|
+
* - Event scoped custom mertics limit is 50.
|
|
88
|
+
* - `ep.*` string type.
|
|
89
|
+
* - `epn.*` number type.
|
|
90
|
+
* @see https://support.google.com/analytics/answer/10075209?hl=en
|
|
91
|
+
*/
|
|
92
|
+
var EventCustomMetric;
|
|
93
|
+
(function (EventCustomMetric) {
|
|
94
|
+
EventCustomMetric["AllChunksCount"] = "epn.ng_all_chunks_count";
|
|
95
|
+
EventCustomMetric["LazyChunksCount"] = "epn.ng_lazy_chunks_count";
|
|
96
|
+
EventCustomMetric["InitialChunksCount"] = "epn.ng_initial_chunks_count";
|
|
97
|
+
EventCustomMetric["ChangedChunksCount"] = "epn.ng_changed_chunks_count";
|
|
98
|
+
EventCustomMetric["DurationInMs"] = "epn.ng_duration_ms";
|
|
99
|
+
EventCustomMetric["CssSizeInBytes"] = "epn.ng_css_size_bytes";
|
|
100
|
+
EventCustomMetric["JsSizeInBytes"] = "epn.ng_js_size_bytes";
|
|
101
|
+
EventCustomMetric["NgComponentCount"] = "epn.ng_component_count";
|
|
102
|
+
EventCustomMetric["AllProjectsCount"] = "epn.all_projects_count";
|
|
103
|
+
EventCustomMetric["LibraryProjectsCount"] = "epn.libs_projects_count";
|
|
104
|
+
EventCustomMetric["ApplicationProjectsCount"] = "epn.apps_projects_count";
|
|
105
|
+
})(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 {
|
|
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
|
-
|
|
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.
|
|
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
35
|
const crypto_1 = require("crypto");
|
|
39
|
-
const debug_1 = __importDefault(require("debug"));
|
|
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
|
-
/^@
|
|
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.`);
|
|
@@ -103,7 +77,6 @@ async function setAnalyticsConfig(global, value) {
|
|
|
103
77
|
}
|
|
104
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
141
|
-
|
|
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
|
-
|
|
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
|
|
126
|
+
* Get the analytics user id.
|
|
165
127
|
*
|
|
166
128
|
* @returns
|
|
167
|
-
* - `
|
|
168
|
-
* - `
|
|
129
|
+
* - `string` user id.
|
|
130
|
+
* - `false` when disabled.
|
|
169
131
|
* - `undefined` when not configured.
|
|
170
132
|
*/
|
|
171
|
-
async function
|
|
133
|
+
async function getAnalyticsUserIdForLevel(level) {
|
|
172
134
|
var _a;
|
|
173
|
-
analyticsDebug('getAnalytics');
|
|
174
135
|
if (environment_options_1.analyticsDisabled) {
|
|
175
|
-
|
|
176
|
-
return new core_1.analytics.NoopAnalytics();
|
|
136
|
+
return false;
|
|
177
137
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
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
|
-
|
|
240
|
-
|
|
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
|
|
248
|
-
if (globalConfig
|
|
249
|
-
return
|
|
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
|
|
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
|
|
177
|
+
await promptAnalytics(context, !workspace /** global */);
|
|
178
|
+
localOrGlobalConfig = await getAnalyticsUserIdForLevel(level);
|
|
264
179
|
}
|
|
265
180
|
}
|
|
266
|
-
if (localOrGlobalConfig
|
|
267
|
-
return
|
|
181
|
+
if (localOrGlobalConfig === false) {
|
|
182
|
+
return undefined;
|
|
268
183
|
}
|
|
269
|
-
else if (localOrGlobalConfig) {
|
|
270
|
-
|
|
271
|
-
config = localOrGlobalConfig;
|
|
184
|
+
else if (typeof localOrGlobalConfig === 'string') {
|
|
185
|
+
return localOrGlobalConfig;
|
|
272
186
|
}
|
|
273
187
|
}
|
|
274
|
-
|
|
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;
|
|
281
189
|
}
|
|
282
|
-
exports.
|
|
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
|
|
297
|
-
const localWorkspace =
|
|
298
|
-
const globalSetting = (_a =
|
|
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
|
-
|
|
303
|
-
|
|
209
|
+
Global setting: ${analyticsConfigValueToHumanFormat(globalSetting)}
|
|
210
|
+
Local setting: ${localWorkspace
|
|
304
211
|
? analyticsConfigValueToHumanFormat(localSetting)
|
|
305
212
|
: 'No local workspace configuration file.'}
|
|
306
|
-
|
|
307
|
-
|
|
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
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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) {
|