@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
package/bin/ng.js CHANGED
@@ -24,7 +24,7 @@ try {
24
24
  // These may not support ES2015 features such as const/let/async/await/etc.
25
25
  // These would then crash with a hard to diagnose error message.
26
26
  var version = process.versions.node.split('.').map((part) => Number(part));
27
- if (version[0] % 2 === 1 && version[0] > 16) {
27
+ if (version[0] % 2 === 1) {
28
28
  // Allow new odd numbered releases with a warning (currently v17+)
29
29
  console.warn(
30
30
  'Node.js version ' +
@@ -37,16 +37,16 @@ if (version[0] % 2 === 1 && version[0] > 16) {
37
37
  require('./bootstrap');
38
38
  } else if (
39
39
  version[0] < 14 ||
40
- version[0] === 15 ||
41
- (version[0] === 14 && version[1] < 15) ||
42
- (version[0] === 16 && version[1] < 10)
40
+ (version[0] === 14 && version[1] < 20) ||
41
+ (version[0] === 16 && version[1] < 13) ||
42
+ (version[0] === 18 && version[1] < 10)
43
43
  ) {
44
- // Error and exit if less than 14.15 or 15.x or less than 16.10
44
+ // Error and exit if less than 14.20, 16.13 or 18.10
45
45
  console.error(
46
46
  'Node.js version ' +
47
47
  process.version +
48
48
  ' detected.\n' +
49
- 'The Angular CLI requires a minimum Node.js version of either v14.15, or v16.10.\n\n' +
49
+ 'The Angular CLI requires a minimum Node.js version of either v14.20, v16.13 or v18.10.\n\n' +
50
50
  'Please update your Node.js version or visit https://nodejs.org/ for additional instructions.\n',
51
51
  );
52
52
 
@@ -84,22 +84,6 @@
84
84
  ],
85
85
  "description": "Share pseudonymous usage data with the Angular Team at Google."
86
86
  },
87
- "analyticsSharing": {
88
- "type": "object",
89
- "properties": {
90
- "tracking": {
91
- "description": "Analytics sharing info tracking ID.",
92
- "type": "string",
93
- "pattern": "^(GA|UA)?-\\d+-\\d+$"
94
- },
95
- "uuid": {
96
- "description": "Analytics sharing info universally unique identifier.",
97
- "type": "string",
98
- "format": "uuid"
99
- }
100
- },
101
- "additionalProperties": false
102
- },
103
87
  "cache": {
104
88
  "description": "Control disk cache.",
105
89
  "type": "object",
@@ -171,22 +155,6 @@
171
155
  ],
172
156
  "description": "Share pseudonymous usage data with the Angular Team at Google."
173
157
  },
174
- "analyticsSharing": {
175
- "type": "object",
176
- "properties": {
177
- "tracking": {
178
- "description": "Analytics sharing info tracking ID.",
179
- "type": "string",
180
- "pattern": "^(GA|UA)?-\\d+-\\d+$"
181
- },
182
- "uuid": {
183
- "description": "Analytics sharing info universally unique identifier.",
184
- "type": "string",
185
- "format": "uuid"
186
- }
187
- },
188
- "additionalProperties": false
189
- },
190
158
  "completion": {
191
159
  "type": "object",
192
160
  "description": "Angular CLI completion settings.",
@@ -708,12 +676,11 @@
708
676
  "additionalProperties": false,
709
677
  "properties": {
710
678
  "projectRoot": {
711
- "description": "The root directory of the new app.",
712
- "type": "string",
713
- "visible": false
679
+ "description": "The root directory of the new application.",
680
+ "type": "string"
714
681
  },
715
682
  "name": {
716
- "description": "The name of the new app.",
683
+ "description": "The name of the new application.",
717
684
  "type": "string",
718
685
  "pattern": "^(?:@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*/)?[a-zA-Z0-9-~][a-zA-Z0-9-._~]*$",
719
686
  "$default": {
@@ -1278,6 +1245,10 @@
1278
1245
  "type": "boolean",
1279
1246
  "default": false,
1280
1247
  "description": "Do not update \"tsconfig.json\" to add a path mapping for the new library. The path mapping is needed to use the library in an app, but can be disabled here to simplify development."
1248
+ },
1249
+ "projectRoot": {
1250
+ "type": "string",
1251
+ "description": "The root directory of the new library."
1281
1252
  }
1282
1253
  }
1283
1254
  },
@@ -19,7 +19,6 @@ export interface CliOptions {
19
19
  * Share pseudonymous usage data with the Angular Team at Google.
20
20
  */
21
21
  analytics?: Analytics;
22
- analyticsSharing?: AnalyticsSharing;
23
22
  /**
24
23
  * Control disk cache.
25
24
  */
@@ -45,16 +44,6 @@ export interface CliOptions {
45
44
  * Share pseudonymous usage data with the Angular Team at Google.
46
45
  */
47
46
  export declare type Analytics = boolean | string;
48
- export interface AnalyticsSharing {
49
- /**
50
- * Analytics sharing info tracking ID.
51
- */
52
- tracking?: string;
53
- /**
54
- * Analytics sharing info universally unique identifier.
55
- */
56
- uuid?: string;
57
- }
58
47
  /**
59
48
  * Control disk cache.
60
49
  */
@@ -139,7 +128,7 @@ export interface AngularApplicationOptionsSchema {
139
128
  */
140
129
  minimal?: boolean;
141
130
  /**
142
- * The name of the new app.
131
+ * The name of the new application.
143
132
  */
144
133
  name: string;
145
134
  /**
@@ -147,7 +136,7 @@ export interface AngularApplicationOptionsSchema {
147
136
  */
148
137
  prefix?: string;
149
138
  /**
150
- * The root directory of the new app.
139
+ * The root directory of the new application.
151
140
  */
152
141
  projectRoot?: string;
153
142
  /**
@@ -502,6 +491,10 @@ export interface LibraryOptionsSchema {
502
491
  * A prefix to apply to generated selectors.
503
492
  */
504
493
  prefix?: string;
494
+ /**
495
+ * The root directory of the new library.
496
+ */
497
+ projectRoot?: string;
505
498
  /**
506
499
  * Do not install dependency packages.
507
500
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/cli",
3
- "version": "15.0.0-next.3",
3
+ "version": "15.0.0-next.5",
4
4
  "description": "CLI tool for Angular",
5
5
  "main": "lib/cli/index.js",
6
6
  "bin": {
@@ -25,40 +25,38 @@
25
25
  },
26
26
  "homepage": "https://github.com/angular/angular-cli",
27
27
  "dependencies": {
28
- "@angular-devkit/architect": "0.1500.0-next.3",
29
- "@angular-devkit/core": "15.0.0-next.3",
30
- "@angular-devkit/schematics": "15.0.0-next.3",
31
- "@schematics/angular": "15.0.0-next.3",
28
+ "@angular-devkit/architect": "0.1500.0-next.5",
29
+ "@angular-devkit/core": "15.0.0-next.5",
30
+ "@angular-devkit/schematics": "15.0.0-next.5",
31
+ "@schematics/angular": "15.0.0-next.5",
32
32
  "@yarnpkg/lockfile": "1.1.0",
33
33
  "ansi-colors": "4.1.3",
34
- "debug": "4.3.4",
35
34
  "ini": "3.0.1",
36
35
  "inquirer": "8.2.4",
37
36
  "jsonc-parser": "3.2.0",
38
- "npm-package-arg": "9.1.0",
37
+ "npm-package-arg": "9.1.2",
39
38
  "npm-pick-manifest": "7.0.2",
40
39
  "open": "8.4.0",
41
40
  "ora": "5.4.1",
42
- "pacote": "13.6.2",
41
+ "pacote": "14.0.0",
43
42
  "resolve": "1.22.1",
44
- "semver": "7.3.7",
43
+ "semver": "7.3.8",
45
44
  "symbol-observable": "4.0.0",
46
- "uuid": "9.0.0",
47
- "yargs": "17.5.1"
45
+ "yargs": "17.6.0"
48
46
  },
49
47
  "ng-update": {
50
48
  "migrations": "@schematics/angular/migrations/migration-collection.json",
51
49
  "packageGroup": {
52
- "@angular/cli": "15.0.0-next.3",
53
- "@angular-devkit/architect": "0.1500.0-next.3",
54
- "@angular-devkit/build-angular": "15.0.0-next.3",
55
- "@angular-devkit/build-webpack": "0.1500.0-next.3",
56
- "@angular-devkit/core": "15.0.0-next.3",
57
- "@angular-devkit/schematics": "15.0.0-next.3"
50
+ "@angular/cli": "15.0.0-next.5",
51
+ "@angular-devkit/architect": "0.1500.0-next.5",
52
+ "@angular-devkit/build-angular": "15.0.0-next.5",
53
+ "@angular-devkit/build-webpack": "0.1500.0-next.5",
54
+ "@angular-devkit/core": "15.0.0-next.5",
55
+ "@angular-devkit/schematics": "15.0.0-next.5"
58
56
  }
59
57
  },
60
58
  "engines": {
61
- "node": "^14.15.0 || >=16.10.0",
59
+ "node": "^14.20.0 || ^16.13.0 || >=18.10.0",
62
60
  "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
63
61
  "yarn": ">= 1.13.0"
64
62
  }
@@ -5,25 +5,27 @@
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
- /**
10
- * See: https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
11
- */
12
- export declare class AnalyticsCollector implements analytics.Analytics {
8
+ import type { CommandContext } from '../command-builder/command-module';
9
+ import { EventCustomDimension, EventCustomMetric, PrimitiveTypes } from './analytics-parameters';
10
+ export declare class AnalyticsCollector {
11
+ private context;
13
12
  private trackingEventsQueue;
14
- private readonly parameters;
15
- private readonly analyticsLogDebug;
16
- constructor(trackingId: string, userId: string);
17
- event(ec: string, ea: string, options?: analytics.EventOptions): void;
18
- pageview(dp: string, options?: analytics.PageviewOptions): void;
19
- timing(utc: string, utv: string, utt: string | number, options?: analytics.TimingOptions): void;
20
- screenview(cd: string, an: string, options?: analytics.ScreenviewOptions): void;
21
- flush(): Promise<void>;
22
- private addToQueue;
23
- private send;
13
+ private readonly requestParameterStringified;
14
+ private readonly userParameters;
15
+ constructor(context: CommandContext, userId: string);
16
+ reportRebuildRunEvent(parameters: Partial<Record<EventCustomMetric & EventCustomDimension, string | boolean | number | undefined>>): void;
17
+ reportBuildRunEvent(parameters: Partial<Record<EventCustomMetric & EventCustomDimension, string | boolean | number | undefined>>): void;
18
+ reportArchitectRunEvent(parameters: Partial<Record<EventCustomDimension, PrimitiveTypes>>): void;
19
+ reportSchematicRunEvent(parameters: Partial<Record<EventCustomDimension, PrimitiveTypes>>): void;
20
+ reportCommandRunEvent(command: string): void;
21
+ private event;
24
22
  /**
25
- * Creates the dimension and metrics variables to add to the queue.
26
- * @private
23
+ * Flush on an interval (if the event loop is waiting).
24
+ *
25
+ * @returns a method that when called will terminate the periodic
26
+ * flush and call flush one last time.
27
27
  */
28
- private customVariables;
28
+ periodFlush(): () => Promise<void>;
29
+ flush(): Promise<void>;
30
+ private send;
29
31
  }
@@ -29,213 +29,136 @@ 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
33
  exports.AnalyticsCollector = void 0;
37
- const core_1 = require("@angular-devkit/core");
38
- const child_process_1 = require("child_process");
39
- const debug_1 = __importDefault(require("debug"));
34
+ const crypto_1 = require("crypto");
40
35
  const https = __importStar(require("https"));
41
36
  const os = __importStar(require("os"));
42
37
  const querystring = __importStar(require("querystring"));
38
+ const environment_options_1 = require("../utilities/environment-options");
39
+ const error_1 = require("../utilities/error");
43
40
  const version_1 = require("../utilities/version");
44
- /**
45
- * See: https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
46
- */
41
+ const analytics_parameters_1 = require("./analytics-parameters");
42
+ const TRACKING_ID_PROD = 'G-VETNJBW8L4';
43
+ const TRACKING_ID_STAGING = 'G-TBMPRL1BTM';
47
44
  class AnalyticsCollector {
48
- constructor(trackingId, userId) {
49
- this.trackingEventsQueue = [];
50
- this.parameters = {};
51
- this.analyticsLogDebug = (0, debug_1.default)('ng:analytics:log');
52
- // API Version
53
- this.parameters['v'] = '1';
54
- // User ID
55
- this.parameters['cid'] = userId;
56
- // Tracking
57
- this.parameters['tid'] = trackingId;
58
- this.parameters['ds'] = 'cli';
59
- this.parameters['ua'] = _buildUserAgentString();
60
- this.parameters['ul'] = _getLanguage();
61
- // @angular/cli with version.
62
- this.parameters['an'] = '@angular/cli';
63
- this.parameters['av'] = version_1.VERSION.full;
64
- // We use the application ID for the Node version. This should be "node v12.10.0".
65
- const nodeVersion = `node ${process.version}`;
66
- this.parameters['aid'] = nodeVersion;
67
- // Custom dimentions
68
- // We set custom metrics for values we care about.
69
- this.parameters['cd' + core_1.analytics.NgCliAnalyticsDimensions.CpuCount] = os.cpus().length;
70
- // Get the first CPU's speed. It's very rare to have multiple CPUs of different speed (in most
71
- // non-ARM configurations anyway), so that's all we care about.
72
- this.parameters['cd' + core_1.analytics.NgCliAnalyticsDimensions.CpuSpeed] = Math.floor(os.cpus()[0].speed);
73
- this.parameters['cd' + core_1.analytics.NgCliAnalyticsDimensions.RamInGigabytes] = Math.round(os.totalmem() / (1024 * 1024 * 1024));
74
- this.parameters['cd' + core_1.analytics.NgCliAnalyticsDimensions.NodeVersion] = nodeVersion;
75
- this.parameters['cd' + core_1.analytics.NgCliAnalyticsDimensions.AngularCLIMajorVersion] =
76
- version_1.VERSION.major;
45
+ constructor(context, userId) {
46
+ this.context = context;
47
+ const requestParameters = {
48
+ [analytics_parameters_1.RequestParameter.ProtocolVersion]: 2,
49
+ [analytics_parameters_1.RequestParameter.ClientId]: userId,
50
+ [analytics_parameters_1.RequestParameter.UserId]: userId,
51
+ [analytics_parameters_1.RequestParameter.TrackingId]: /^\d+\.\d+\.\d+$/.test(version_1.VERSION.full) && version_1.VERSION.full !== '0.0.0'
52
+ ? TRACKING_ID_PROD
53
+ : TRACKING_ID_STAGING,
54
+ // Built-in user properties
55
+ [analytics_parameters_1.RequestParameter.SessionId]: (0, crypto_1.randomUUID)(),
56
+ [analytics_parameters_1.RequestParameter.UserAgentArchitecture]: os.arch(),
57
+ [analytics_parameters_1.RequestParameter.UserAgentPlatform]: os.platform(),
58
+ [analytics_parameters_1.RequestParameter.UserAgentPlatformVersion]: os.version(),
59
+ // Set undefined to disable debug view.
60
+ [analytics_parameters_1.RequestParameter.DebugView]: environment_options_1.ngDebug ? 1 : undefined,
61
+ };
62
+ this.requestParameterStringified = querystring.stringify(requestParameters);
63
+ // Remove the `v` at the beginning.
64
+ const nodeVersion = process.version.substring(1);
65
+ const packageManagerVersion = context.packageManager.version;
66
+ this.userParameters = {
67
+ // While architecture is being collect by GA as UserAgentArchitecture.
68
+ // It doesn't look like there is a way to query this. Therefore we collect this as a custom user dimension too.
69
+ [analytics_parameters_1.UserCustomDimension.OsArchitecture]: os.arch(),
70
+ [analytics_parameters_1.UserCustomDimension.NodeVersion]: nodeVersion,
71
+ [analytics_parameters_1.UserCustomDimension.NodeMajorVersion]: +nodeVersion.split('.', 1)[0],
72
+ [analytics_parameters_1.UserCustomDimension.PackageManager]: context.packageManager.name,
73
+ [analytics_parameters_1.UserCustomDimension.PackageManagerVersion]: packageManagerVersion,
74
+ [analytics_parameters_1.UserCustomDimension.PackageManagerMajorVersion]: packageManagerVersion
75
+ ? +packageManagerVersion.split('.', 1)[0]
76
+ : undefined,
77
+ [analytics_parameters_1.UserCustomDimension.AngularCLIVersion]: version_1.VERSION.full,
78
+ [analytics_parameters_1.UserCustomDimension.AngularCLIMajorVersion]: version_1.VERSION.major,
79
+ };
77
80
  }
78
- event(ec, ea, options = {}) {
79
- const { label: el, value: ev, metrics, dimensions } = options;
80
- this.addToQueue('event', { ec, ea, el, ev, metrics, dimensions });
81
+ reportRebuildRunEvent(parameters) {
82
+ this.event('run_rebuild', parameters);
81
83
  }
82
- pageview(dp, options = {}) {
83
- const { hostname: dh, title: dt, metrics, dimensions } = options;
84
- this.addToQueue('pageview', { dp, dh, dt, metrics, dimensions });
84
+ reportBuildRunEvent(parameters) {
85
+ this.event('run_build', parameters);
85
86
  }
86
- timing(utc, utv, utt, options = {}) {
87
- const { label: utl, metrics, dimensions } = options;
88
- this.addToQueue('timing', { utc, utv, utt, utl, metrics, dimensions });
87
+ reportArchitectRunEvent(parameters) {
88
+ this.event('run_architect', parameters);
89
89
  }
90
- screenview(cd, an, options = {}) {
91
- const { appVersion: av, appId: aid, appInstallerId: aiid, metrics, dimensions } = options;
92
- this.addToQueue('screenview', { cd, an, av, aid, aiid, metrics, dimensions });
90
+ reportSchematicRunEvent(parameters) {
91
+ this.event('run_schematic', parameters);
92
+ }
93
+ reportCommandRunEvent(command) {
94
+ this.event('run_command', { [analytics_parameters_1.EventCustomDimension.Command]: command });
95
+ }
96
+ event(eventName, parameters) {
97
+ var _a;
98
+ (_a = this.trackingEventsQueue) !== null && _a !== void 0 ? _a : (this.trackingEventsQueue = []);
99
+ this.trackingEventsQueue.push({
100
+ ...this.userParameters,
101
+ ...parameters,
102
+ 'en': eventName,
103
+ });
104
+ }
105
+ /**
106
+ * Flush on an interval (if the event loop is waiting).
107
+ *
108
+ * @returns a method that when called will terminate the periodic
109
+ * flush and call flush one last time.
110
+ */
111
+ periodFlush() {
112
+ let analyticsFlushPromise = Promise.resolve();
113
+ const analyticsFlushInterval = setInterval(() => {
114
+ var _a;
115
+ if ((_a = this.trackingEventsQueue) === null || _a === void 0 ? void 0 : _a.length) {
116
+ analyticsFlushPromise = analyticsFlushPromise.then(() => this.flush());
117
+ }
118
+ }, 4000);
119
+ return () => {
120
+ clearInterval(analyticsFlushInterval);
121
+ // Flush one last time.
122
+ return analyticsFlushPromise.then(() => this.flush());
123
+ };
93
124
  }
94
125
  async flush() {
95
- const pending = this.trackingEventsQueue.length;
96
- this.analyticsLogDebug(`flush queue size: ${pending}`);
97
- if (!pending) {
126
+ const pendingTrackingEvents = this.trackingEventsQueue;
127
+ this.context.logger.debug(`Analytics flush size. ${pendingTrackingEvents === null || pendingTrackingEvents === void 0 ? void 0 : pendingTrackingEvents.length}.`);
128
+ if (!(pendingTrackingEvents === null || pendingTrackingEvents === void 0 ? void 0 : pendingTrackingEvents.length)) {
98
129
  return;
99
130
  }
100
131
  // The below is needed so that if flush is called multiple times,
101
132
  // we don't report the same event multiple times.
102
- const pendingTrackingEvents = this.trackingEventsQueue;
103
- this.trackingEventsQueue = [];
133
+ this.trackingEventsQueue = undefined;
104
134
  try {
105
135
  await this.send(pendingTrackingEvents);
106
136
  }
107
137
  catch (error) {
108
138
  // Failure to report analytics shouldn't crash the CLI.
109
- this.analyticsLogDebug('send error: %j', error);
139
+ (0, error_1.assertIsError)(error);
140
+ this.context.logger.debug(`Send analytics error. ${error.message}.`);
110
141
  }
111
142
  }
112
- addToQueue(eventType, parameters) {
113
- const { metrics, dimensions, ...restParameters } = parameters;
114
- const data = {
115
- ...this.parameters,
116
- ...restParameters,
117
- ...this.customVariables({ metrics, dimensions }),
118
- t: eventType,
119
- };
120
- this.analyticsLogDebug('add event to queue: %j', data);
121
- this.trackingEventsQueue.push(data);
122
- }
123
143
  async send(data) {
124
- this.analyticsLogDebug('send event: %j', data);
125
144
  return new Promise((resolve, reject) => {
126
145
  const request = https.request({
127
146
  host: 'www.google-analytics.com',
128
147
  method: 'POST',
129
- path: data.length > 1 ? '/batch' : '/collect',
148
+ path: '/g/collect?' + this.requestParameterStringified,
130
149
  }, (response) => {
131
- if (response.statusCode !== 200) {
150
+ if (response.statusCode !== 200 && response.statusCode !== 204) {
132
151
  reject(new Error(`Analytics reporting failed with status code: ${response.statusCode}.`));
133
- return;
152
+ }
153
+ else {
154
+ resolve();
134
155
  }
135
156
  });
136
157
  request.on('error', reject);
137
158
  const queryParameters = data.map((p) => querystring.stringify(p)).join('\n');
138
159
  request.write(queryParameters);
139
- request.end(resolve);
160
+ request.end();
140
161
  });
141
162
  }
142
- /**
143
- * Creates the dimension and metrics variables to add to the queue.
144
- * @private
145
- */
146
- customVariables(options) {
147
- const additionals = {};
148
- const { dimensions, metrics } = options;
149
- dimensions === null || dimensions === void 0 ? void 0 : dimensions.forEach((v, i) => (additionals[`cd${i}`] = v));
150
- metrics === null || metrics === void 0 ? void 0 : metrics.forEach((v, i) => (additionals[`cm${i}`] = v));
151
- return additionals;
152
- }
153
163
  }
154
164
  exports.AnalyticsCollector = AnalyticsCollector;
155
- // These are just approximations of UA strings. We just try to fool Google Analytics to give us the
156
- // data we want.
157
- // See https://developers.whatismybrowser.com/useragents/
158
- const osVersionMap = {
159
- darwin: {
160
- '1.3.1': '10_0_4',
161
- '1.4.1': '10_1_0',
162
- '5.1': '10_1_1',
163
- '5.2': '10_1_5',
164
- '6.0.1': '10_2',
165
- '6.8': '10_2_8',
166
- '7.0': '10_3_0',
167
- '7.9': '10_3_9',
168
- '8.0': '10_4_0',
169
- '8.11': '10_4_11',
170
- '9.0': '10_5_0',
171
- '9.8': '10_5_8',
172
- '10.0': '10_6_0',
173
- '10.8': '10_6_8',
174
- // We stop here because we try to math out the version for anything greater than 10, and it
175
- // works. Those versions are standardized using a calculation now.
176
- },
177
- win32: {
178
- '6.3.9600': 'Windows 8.1',
179
- '6.2.9200': 'Windows 8',
180
- '6.1.7601': 'Windows 7 SP1',
181
- '6.1.7600': 'Windows 7',
182
- '6.0.6002': 'Windows Vista SP2',
183
- '6.0.6000': 'Windows Vista',
184
- '5.1.2600': 'Windows XP',
185
- },
186
- };
187
- /**
188
- * Build a fake User Agent string. This gets sent to Analytics so it shows the proper OS version.
189
- * @private
190
- */
191
- function _buildUserAgentString() {
192
- switch (os.platform()) {
193
- case 'darwin': {
194
- let v = osVersionMap.darwin[os.release()];
195
- if (!v) {
196
- // Remove 4 to tie Darwin version to OSX version, add other info.
197
- const x = parseFloat(os.release());
198
- if (x > 10) {
199
- v = `10_` + (x - 4).toString().replace('.', '_');
200
- }
201
- }
202
- const cpuModel = os.cpus()[0].model.match(/^[a-z]+/i);
203
- const cpu = cpuModel ? cpuModel[0] : os.cpus()[0].model;
204
- return `(Macintosh; ${cpu} Mac OS X ${v || os.release()})`;
205
- }
206
- case 'win32':
207
- return `(Windows NT ${os.release()})`;
208
- case 'linux':
209
- return `(X11; Linux i686; ${os.release()}; ${os.cpus()[0].model})`;
210
- default:
211
- return os.platform() + ' ' + os.release();
212
- }
213
- }
214
- /**
215
- * Get a language code.
216
- * @private
217
- */
218
- function _getLanguage() {
219
- // Note: Windows does not expose the configured language by default.
220
- return (process.env.LANG || // Default Unix env variable.
221
- process.env.LC_CTYPE || // For C libraries. Sometimes the above isn't set.
222
- process.env.LANGSPEC || // For Windows, sometimes this will be set (not always).
223
- _getWindowsLanguageCode() ||
224
- '??'); // ¯\_(ツ)_/¯
225
- }
226
- /**
227
- * Attempt to get the Windows Language Code string.
228
- * @private
229
- */
230
- function _getWindowsLanguageCode() {
231
- if (!os.platform().startsWith('win')) {
232
- return undefined;
233
- }
234
- try {
235
- // This is true on Windows XP, 7, 8 and 10 AFAIK. Would return empty string or fail if it
236
- // doesn't work.
237
- return (0, child_process_1.execSync)('wmic.exe os get locale').toString().trim();
238
- }
239
- catch { }
240
- return undefined;
241
- }