eas-cli 2.4.1 → 2.5.0

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 (82) hide show
  1. package/README.md +47 -47
  2. package/build/analytics/{events.d.ts → AnalyticsManager.d.ts} +32 -3
  3. package/build/analytics/AnalyticsManager.js +188 -0
  4. package/build/analytics/common.d.ts +6 -7
  5. package/build/analytics/common.js +5 -5
  6. package/build/build/build.js +21 -21
  7. package/build/build/context.d.ts +3 -2
  8. package/build/build/createContext.d.ts +3 -1
  9. package/build/build/createContext.js +7 -5
  10. package/build/build/local.js +1 -1
  11. package/build/build/metadata.js +1 -1
  12. package/build/build/runBuildAndSubmit.d.ts +2 -1
  13. package/build/build/runBuildAndSubmit.js +5 -2
  14. package/build/commandUtils/EasCommand.d.ts +19 -2
  15. package/build/commandUtils/EasCommand.js +31 -17
  16. package/build/commandUtils/context/AnalyticsContextField.d.ts +5 -0
  17. package/build/commandUtils/context/AnalyticsContextField.js +10 -0
  18. package/build/commandUtils/context/ContextField.d.ts +2 -0
  19. package/build/commands/analytics.js +3 -3
  20. package/build/commands/build/index.d.ts +1 -0
  21. package/build/commands/build/index.js +3 -2
  22. package/build/commands/build/inspect.d.ts +1 -0
  23. package/build/commands/build/inspect.js +3 -2
  24. package/build/commands/credentials.d.ts +1 -0
  25. package/build/commands/credentials.js +3 -2
  26. package/build/commands/metadata/pull.d.ts +1 -0
  27. package/build/commands/metadata/pull.js +4 -1
  28. package/build/commands/metadata/push.d.ts +1 -0
  29. package/build/commands/metadata/push.js +4 -1
  30. package/build/commands/project/init.d.ts +3 -0
  31. package/build/commands/project/init.js +88 -4
  32. package/build/commands/secret/create.js +5 -5
  33. package/build/commands/secret/push.d.ts +16 -0
  34. package/build/commands/secret/push.js +149 -0
  35. package/build/commands/submit.d.ts +2 -1
  36. package/build/commands/submit.js +3 -1
  37. package/build/commands/update/index.js +2 -2
  38. package/build/commands/update/view.js +1 -14
  39. package/build/credentials/android/actions/CreateKeystore.js +3 -3
  40. package/build/credentials/android/utils/keystore.d.ts +2 -1
  41. package/build/credentials/android/utils/keystore.js +7 -7
  42. package/build/credentials/context.d.ts +3 -0
  43. package/build/credentials/context.js +1 -0
  44. package/build/credentials/ios/actions/AscApiKeyUtils.js +1 -1
  45. package/build/credentials/ios/appstore/AppStoreApi.d.ts +2 -1
  46. package/build/credentials/ios/appstore/AppStoreApi.js +2 -2
  47. package/build/credentials/ios/appstore/ascApiKey.d.ts +3 -2
  48. package/build/credentials/ios/appstore/ascApiKey.js +7 -7
  49. package/build/credentials/manager/HelperActions.d.ts +2 -0
  50. package/build/credentials/manager/ManageAndroid.js +1 -0
  51. package/build/credentials/manager/ManageIos.js +1 -0
  52. package/build/credentials/manager/SelectPlatform.d.ts +3 -1
  53. package/build/credentials/manager/SelectPlatform.js +2 -1
  54. package/build/metadata/context.d.ts +4 -0
  55. package/build/metadata/context.js +1 -0
  56. package/build/metadata/download.js +2 -2
  57. package/build/metadata/upload.js +2 -2
  58. package/build/metadata/utils/telemetry.d.ts +2 -2
  59. package/build/metadata/utils/telemetry.js +3 -4
  60. package/build/project/projectUtils.js +1 -3
  61. package/build/project/publish.js +14 -8
  62. package/build/submit/BaseSubmitter.d.ts +4 -4
  63. package/build/submit/BaseSubmitter.js +8 -8
  64. package/build/submit/android/AndroidSubmitter.js +7 -7
  65. package/build/submit/context.d.ts +4 -2
  66. package/build/submit/context.js +6 -5
  67. package/build/submit/ios/IosSubmitter.js +7 -7
  68. package/build/submit/submit.js +6 -6
  69. package/build/update/utils.d.ts +1 -0
  70. package/build/update/utils.js +11 -1
  71. package/build/user/SessionManager.d.ts +4 -1
  72. package/build/user/SessionManager.js +10 -13
  73. package/build/utils/expoCli.d.ts +1 -0
  74. package/build/utils/expoCli.js +8 -1
  75. package/build/utils/expodash/intersection.d.ts +1 -0
  76. package/build/utils/expodash/intersection.js +8 -0
  77. package/build/vcs/clients/git.js +13 -2
  78. package/oclif.manifest.json +1 -1
  79. package/package.json +3 -2
  80. package/build/analytics/events.js +0 -59
  81. package/build/analytics/rudderstackClient.d.ts +0 -7
  82. package/build/analytics/rudderstackClient.js +0 -112
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withAnalyticsAsync = void 0;
4
- const events_1 = require("./events");
5
- async function withAnalyticsAsync(fn, analytics) {
4
+ async function withAnalyticsAsync(analytics, fn, { attemptEvent, successEvent, failureEvent, properties, }) {
6
5
  try {
6
+ analytics.logEvent(attemptEvent, properties);
7
7
  const result = await fn();
8
- events_1.Analytics.logEvent(analytics.successEvent, analytics.trackingCtx);
8
+ analytics.logEvent(successEvent, properties);
9
9
  return result;
10
10
  }
11
11
  catch (error) {
12
- events_1.Analytics.logEvent(analytics.failureEvent, {
13
- ...analytics.trackingCtx,
12
+ analytics.logEvent(failureEvent, {
13
+ ...properties,
14
14
  reason: error.message,
15
15
  });
16
16
  throw error;
@@ -7,8 +7,8 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  const cli_progress_1 = tslib_1.__importDefault(require("cli-progress"));
8
8
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
9
9
  const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
10
+ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
10
11
  const common_1 = require("../analytics/common");
11
- const events_1 = require("../analytics/events");
12
12
  const api_1 = require("../api");
13
13
  const generated_1 = require("../graphql/generated");
14
14
  const BuildQuery_1 = require("../graphql/queries/BuildQuery");
@@ -31,17 +31,17 @@ function resolveBuildParamsInput(ctx) {
31
31
  }
32
32
  async function prepareBuildRequestForPlatformAsync(builder) {
33
33
  const { ctx } = builder;
34
- const credentialsResult = await (0, common_1.withAnalyticsAsync)(async () => await builder.ensureCredentialsAsync(ctx), {
35
- attemptEvent: events_1.BuildEvent.GATHER_CREDENTIALS_ATTEMPT,
36
- successEvent: events_1.BuildEvent.GATHER_CREDENTIALS_SUCCESS,
37
- failureEvent: events_1.BuildEvent.GATHER_CREDENTIALS_FAIL,
38
- trackingCtx: ctx.trackingCtx,
34
+ const credentialsResult = await (0, common_1.withAnalyticsAsync)(ctx.analytics, async () => await builder.ensureCredentialsAsync(ctx), {
35
+ attemptEvent: AnalyticsManager_1.BuildEvent.GATHER_CREDENTIALS_ATTEMPT,
36
+ successEvent: AnalyticsManager_1.BuildEvent.GATHER_CREDENTIALS_SUCCESS,
37
+ failureEvent: AnalyticsManager_1.BuildEvent.GATHER_CREDENTIALS_FAIL,
38
+ properties: ctx.analyticsEventProperties,
39
39
  });
40
- await (0, common_1.withAnalyticsAsync)(async () => await builder.syncProjectConfigurationAsync(ctx), {
41
- attemptEvent: events_1.BuildEvent.CONFIGURE_PROJECT_ATTEMPT,
42
- successEvent: events_1.BuildEvent.CONFIGURE_PROJECT_SUCCESS,
43
- failureEvent: events_1.BuildEvent.CONFIGURE_PROJECT_FAIL,
44
- trackingCtx: ctx.trackingCtx,
40
+ await (0, common_1.withAnalyticsAsync)(ctx.analytics, async () => await builder.syncProjectConfigurationAsync(ctx), {
41
+ attemptEvent: AnalyticsManager_1.BuildEvent.CONFIGURE_PROJECT_ATTEMPT,
42
+ successEvent: AnalyticsManager_1.BuildEvent.CONFIGURE_PROJECT_SUCCESS,
43
+ failureEvent: AnalyticsManager_1.BuildEvent.CONFIGURE_PROJECT_FAIL,
44
+ properties: ctx.analyticsEventProperties,
45
45
  });
46
46
  if (await (0, vcs_1.getVcsClient)().isCommitRequiredAsync()) {
47
47
  log_1.default.addNewLineIfNone();
@@ -112,7 +112,7 @@ function handleBuildRequestError(error, platform) {
112
112
  async function uploadProjectAsync(ctx) {
113
113
  let projectTarballPath;
114
114
  try {
115
- return await (0, common_1.withAnalyticsAsync)(async () => {
115
+ return await (0, common_1.withAnalyticsAsync)(ctx.analytics, async () => {
116
116
  log_1.default.newLine();
117
117
  log_1.default.log(`Compressing project files and uploading to EAS Build. ${(0, log_1.learnMore)('https://expo.fyi/eas-build-archive')}`);
118
118
  const projectTarball = await (0, repository_1.makeProjectTarballAsync)();
@@ -127,10 +127,10 @@ async function uploadProjectAsync(ctx) {
127
127
  }));
128
128
  return bucketKey;
129
129
  }, {
130
- attemptEvent: events_1.BuildEvent.PROJECT_UPLOAD_ATTEMPT,
131
- successEvent: events_1.BuildEvent.PROJECT_UPLOAD_SUCCESS,
132
- failureEvent: events_1.BuildEvent.PROJECT_UPLOAD_FAIL,
133
- trackingCtx: ctx.trackingCtx,
130
+ attemptEvent: AnalyticsManager_1.BuildEvent.PROJECT_UPLOAD_ATTEMPT,
131
+ successEvent: AnalyticsManager_1.BuildEvent.PROJECT_UPLOAD_SUCCESS,
132
+ failureEvent: AnalyticsManager_1.BuildEvent.PROJECT_UPLOAD_FAIL,
133
+ properties: ctx.analyticsEventProperties,
134
134
  });
135
135
  }
136
136
  finally {
@@ -141,7 +141,7 @@ async function uploadProjectAsync(ctx) {
141
141
  }
142
142
  async function sendBuildRequestAsync(builder, job, metadata, buildParams) {
143
143
  const { ctx } = builder;
144
- return await (0, common_1.withAnalyticsAsync)(async () => {
144
+ return await (0, common_1.withAnalyticsAsync)(ctx.analytics, async () => {
145
145
  if (log_1.default.isDebug) {
146
146
  log_1.default.log(`Starting ${platform_1.requestedPlatformDisplayNames[job.platform]} build`);
147
147
  }
@@ -149,10 +149,10 @@ async function sendBuildRequestAsync(builder, job, metadata, buildParams) {
149
149
  (0, printBuildInfo_1.printDeprecationWarnings)(deprecationInfo);
150
150
  return build;
151
151
  }, {
152
- attemptEvent: events_1.BuildEvent.BUILD_REQUEST_ATTEMPT,
153
- successEvent: events_1.BuildEvent.BUILD_REQUEST_SUCCESS,
154
- failureEvent: events_1.BuildEvent.BUILD_REQUEST_FAIL,
155
- trackingCtx: ctx.trackingCtx,
152
+ attemptEvent: AnalyticsManager_1.BuildEvent.BUILD_REQUEST_ATTEMPT,
153
+ successEvent: AnalyticsManager_1.BuildEvent.BUILD_REQUEST_SUCCESS,
154
+ failureEvent: AnalyticsManager_1.BuildEvent.BUILD_REQUEST_FAIL,
155
+ properties: ctx.analyticsEventProperties,
156
156
  });
157
157
  }
158
158
  async function waitForBuildEndAsync(graphqlClient, { buildIds, accountName }, { intervalSec = 10 } = {}) {
@@ -1,7 +1,7 @@
1
1
  import { ExpoConfig } from '@expo/config';
2
2
  import { Platform, Workflow } from '@expo/eas-build-job';
3
3
  import { BuildProfile, EasJson } from '@expo/eas-json';
4
- import { TrackingContext } from '../analytics/common';
4
+ import { Analytics, AnalyticsEventProperties } from '../analytics/AnalyticsManager';
5
5
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
6
6
  import { CredentialsContext } from '../credentials/context';
7
7
  import { Target } from '../credentials/ios/types';
@@ -41,9 +41,10 @@ export interface BuildContext<T extends Platform> {
41
41
  projectId: string;
42
42
  projectName: string;
43
43
  message?: string;
44
- trackingCtx: TrackingContext;
44
+ analyticsEventProperties: AnalyticsEventProperties;
45
45
  user: Actor;
46
46
  graphqlClient: ExpoGraphqlClient;
47
+ analytics: Analytics;
47
48
  workflow: Workflow;
48
49
  android: T extends Platform.ANDROID ? AndroidBuildContext : undefined;
49
50
  ios: T extends Platform.IOS ? IosBuildContext : undefined;
@@ -1,12 +1,13 @@
1
1
  import { Platform } from '@expo/eas-build-job';
2
2
  import { BuildProfile, EasJson } from '@expo/eas-json';
3
+ import { Analytics } from '../analytics/AnalyticsManager';
3
4
  import { DynamicConfigContextFn } from '../commandUtils/context/DynamicProjectConfigContextField';
4
5
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
5
6
  import { BuildResourceClass } from '../graphql/generated';
6
7
  import { Actor } from '../user/User';
7
8
  import { BuildContext } from './context';
8
9
  import { LocalBuildOptions } from './local';
9
- export declare function createBuildContextAsync<T extends Platform>({ buildProfileName, buildProfile, easJsonCliConfig, clearCache, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClass, message, actor, graphqlClient, getDynamicProjectConfigAsync, }: {
10
+ export declare function createBuildContextAsync<T extends Platform>({ buildProfileName, buildProfile, easJsonCliConfig, clearCache, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClass, message, actor, graphqlClient, analytics, getDynamicProjectConfigAsync, }: {
10
11
  buildProfileName: string;
11
12
  buildProfile: BuildProfile<T>;
12
13
  easJsonCliConfig: EasJson['cli'];
@@ -20,5 +21,6 @@ export declare function createBuildContextAsync<T extends Platform>({ buildProfi
20
21
  message?: string;
21
22
  actor: Actor;
22
23
  graphqlClient: ExpoGraphqlClient;
24
+ analytics: Analytics;
23
25
  getDynamicProjectConfigAsync: DynamicConfigContextFn;
24
26
  }): Promise<BuildContext<T>>;
@@ -7,13 +7,13 @@ const json_file_1 = tslib_1.__importDefault(require("@expo/json-file"));
7
7
  const getenv_1 = tslib_1.__importDefault(require("getenv"));
8
8
  const resolve_from_1 = tslib_1.__importDefault(require("resolve-from"));
9
9
  const uuid_1 = require("uuid");
10
- const events_1 = require("../analytics/events");
10
+ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
11
11
  const context_1 = require("../credentials/context");
12
12
  const projectUtils_1 = require("../project/projectUtils");
13
13
  const workflow_1 = require("../project/workflow");
14
14
  const build_1 = require("./android/build");
15
15
  const build_2 = require("./ios/build");
16
- async function createBuildContextAsync({ buildProfileName, buildProfile, easJsonCliConfig, clearCache = false, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClass, message, actor, graphqlClient, getDynamicProjectConfigAsync, }) {
16
+ async function createBuildContextAsync({ buildProfileName, buildProfile, easJsonCliConfig, clearCache = false, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClass, message, actor, graphqlClient, analytics, getDynamicProjectConfigAsync, }) {
17
17
  const { exp, projectId } = await getDynamicProjectConfigAsync({ env: buildProfile.env });
18
18
  const projectName = exp.slug;
19
19
  const account = await (0, projectUtils_1.getOwnerAccountForProjectIdAsync)(graphqlClient, projectId);
@@ -26,6 +26,7 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
26
26
  projectDir,
27
27
  user: actor,
28
28
  graphqlClient,
29
+ analytics,
29
30
  env: buildProfile.env,
30
31
  easJsonCliConfig,
31
32
  });
@@ -34,7 +35,7 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
34
35
  projectDir,
35
36
  buildProfile,
36
37
  });
37
- const trackingCtx = {
38
+ const analyticsEventProperties = {
38
39
  tracking_id: (0, uuid_1.v4)(),
39
40
  platform,
40
41
  ...(accountId && { account_id: accountId }),
@@ -44,7 +45,7 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
44
45
  no_wait: noWait,
45
46
  run_from_ci: runFromCI,
46
47
  };
47
- events_1.Analytics.logEvent(events_1.BuildEvent.BUILD_COMMAND, trackingCtx);
48
+ analytics.logEvent(AnalyticsManager_1.BuildEvent.BUILD_COMMAND, analyticsEventProperties);
48
49
  const commonContext = {
49
50
  accountName: account.name,
50
51
  buildProfile,
@@ -61,9 +62,10 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
61
62
  projectDir,
62
63
  projectId,
63
64
  projectName,
64
- trackingCtx,
65
+ analyticsEventProperties,
65
66
  user: actor,
66
67
  graphqlClient,
68
+ analytics,
67
69
  workflow,
68
70
  message,
69
71
  runFromCI,
@@ -6,7 +6,7 @@ const spawn_async_1 = tslib_1.__importDefault(require("@expo/spawn-async"));
6
6
  const semver_1 = tslib_1.__importDefault(require("semver"));
7
7
  const ora_1 = require("../ora");
8
8
  const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
9
- const PLUGIN_PACKAGE_VERSION = '0.0.114';
9
+ const PLUGIN_PACKAGE_VERSION = '0.0.115';
10
10
  async function runLocalBuildAsync(job, metadata, options) {
11
11
  var _a;
12
12
  const { command, args } = await getCommandAndArgsAsync(job, metadata);
@@ -22,7 +22,7 @@ async function collectMetadataAsync(ctx) {
22
22
  ? 'simulator'
23
23
  : ctx.buildProfile.distribution)) !== null && _a !== void 0 ? _a : 'store';
24
24
  const metadata = {
25
- trackingContext: ctx.trackingCtx,
25
+ trackingContext: ctx.analyticsEventProperties,
26
26
  ...(await maybeResolveVersionsAsync(ctx)),
27
27
  cliVersion: easCli_1.easCliVersion,
28
28
  workflow: ctx.workflow,
@@ -1,3 +1,4 @@
1
+ import { Analytics } from '../analytics/AnalyticsManager';
1
2
  import { DynamicConfigContextFn } from '../commandUtils/context/DynamicProjectConfigContextField';
2
3
  import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
3
4
  import { RequestedPlatform } from '../platform';
@@ -17,4 +18,4 @@ export interface BuildFlags {
17
18
  userInputResourceClass?: UserInputResourceClass;
18
19
  message?: string;
19
20
  }
20
- export declare function runBuildAndSubmitAsync(graphqlClient: ExpoGraphqlClient, projectDir: string, flags: BuildFlags, actor: Actor, getDynamicProjectConfigAsync: DynamicConfigContextFn): Promise<void>;
21
+ export declare function runBuildAndSubmitAsync(graphqlClient: ExpoGraphqlClient, analytics: Analytics, projectDir: string, flags: BuildFlags, actor: Actor, getDynamicProjectConfigAsync: DynamicConfigContextFn): Promise<void>;
@@ -50,7 +50,7 @@ function resolveResourceClass(platform, resourceClassInput) {
50
50
  ? androidUserInputResourceClassToBuildResourceClassMapping[resourceClassInput]
51
51
  : iosUserInputResourceClassToBuildResourceClassMapping[resourceClassInput];
52
52
  }
53
- async function runBuildAndSubmitAsync(graphqlClient, projectDir, flags, actor, getDynamicProjectConfigAsync) {
53
+ async function runBuildAndSubmitAsync(graphqlClient, analytics, projectDir, flags, actor, getDynamicProjectConfigAsync) {
54
54
  var _a, _b, _c;
55
55
  await (0, vcs_1.getVcsClient)().ensureRepoExistsAsync();
56
56
  await (0, repository_1.ensureRepoIsCleanAsync)(flags.nonInteractive);
@@ -87,6 +87,7 @@ async function runBuildAndSubmitAsync(graphqlClient, projectDir, flags, actor, g
87
87
  easJsonCliConfig,
88
88
  actor,
89
89
  graphqlClient,
90
+ analytics,
90
91
  getDynamicProjectConfigAsync,
91
92
  });
92
93
  if (maybeBuild) {
@@ -158,7 +159,7 @@ async function runBuildAndSubmitAsync(graphqlClient, projectDir, flags, actor, g
158
159
  }
159
160
  }
160
161
  exports.runBuildAndSubmitAsync = runBuildAndSubmitAsync;
161
- async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildProfile, resourceClass, easJsonCliConfig, actor, graphqlClient, getDynamicProjectConfigAsync, }) {
162
+ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildProfile, resourceClass, easJsonCliConfig, actor, graphqlClient, analytics, getDynamicProjectConfigAsync, }) {
162
163
  const buildCtx = await (0, createContext_1.createBuildContextAsync)({
163
164
  buildProfileName: buildProfile.profileName,
164
165
  resourceClass,
@@ -173,6 +174,7 @@ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildP
173
174
  message: flags.message,
174
175
  actor,
175
176
  graphqlClient,
177
+ analytics,
176
178
  getDynamicProjectConfigAsync,
177
179
  });
178
180
  if (moreBuilds) {
@@ -225,6 +227,7 @@ async function prepareAndStartSubmissionAsync({ build, buildCtx, moreBuilds, pro
225
227
  applicationIdentifier: (_b = (_a = buildCtx.android) === null || _a === void 0 ? void 0 : _a.applicationId) !== null && _b !== void 0 ? _b : (_c = buildCtx.ios) === null || _c === void 0 ? void 0 : _c.bundleIdentifier,
226
228
  actor: buildCtx.user,
227
229
  graphqlClient: buildCtx.graphqlClient,
230
+ analytics: buildCtx.analytics,
228
231
  projectId: buildCtx.projectId,
229
232
  exp: buildCtx.exp,
230
233
  });
@@ -1,4 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
+ import AnalyticsContextField from './context/AnalyticsContextField';
2
3
  import ContextField from './context/ContextField';
3
4
  import { DynamicProjectConfigContextField } from './context/DynamicProjectConfigContextField';
4
5
  import LoggedInContextField from './context/LoggedInContextField';
@@ -60,10 +61,19 @@ export default abstract class EasCommand extends Command {
60
61
  };
61
62
  /**
62
63
  * Require the project to be identified and registered on server. Returns the project config in the context.
64
+ * This also requires the user to be logged in (getProjectIdAsync requires logged in), so also expose that context.
65
+ * Exposing the loggedIn context here helps us guarantee user identification for logging purposes.
63
66
  */
64
67
  ProjectConfig: {
68
+ loggedIn: LoggedInContextField;
65
69
  projectConfig: ProjectConfigContextField;
66
70
  };
71
+ /**
72
+ * Analytics manager. Returns the analytics manager in the context for use by the command.
73
+ */
74
+ Analytics: {
75
+ analytics: AnalyticsContextField;
76
+ };
67
77
  };
68
78
  /**
69
79
  * Context allows for subclasses (commands) to declare their prerequisites in a type-safe manner.
@@ -87,9 +97,16 @@ export default abstract class EasCommand extends Command {
87
97
  }): Promise<ContextOutput<C>>;
88
98
  /**
89
99
  * The user session manager. Responsible for coordinating all user session related state.
90
- * If needed in a subclass, SessionManager ContextOption.
100
+ * If needed in a subclass, use the SessionManager ContextOption.
101
+ */
102
+ private sessionManagerInternal?;
103
+ private get sessionManager();
104
+ /**
105
+ * The analytics manager. Used for logging analytics.
106
+ * It is set up here to ensure a consistent set up.
91
107
  */
92
- private readonly sessionManager;
108
+ private analyticsInternal?;
109
+ private get analytics();
93
110
  protected abstract runAsync(): Promise<any>;
94
111
  run(): Promise<any>;
95
112
  finally(err: Error): Promise<any>;
@@ -2,8 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
- const rudderstackClient_1 = require("../analytics/rudderstackClient");
5
+ const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
6
+ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
6
7
  const SessionManager_1 = tslib_1.__importDefault(require("../user/SessionManager"));
8
+ const AnalyticsContextField_1 = tslib_1.__importDefault(require("./context/AnalyticsContextField"));
7
9
  const DynamicProjectConfigContextField_1 = require("./context/DynamicProjectConfigContextField");
8
10
  const LoggedInContextField_1 = tslib_1.__importDefault(require("./context/LoggedInContextField"));
9
11
  const MaybeLoggedInContextField_1 = tslib_1.__importDefault(require("./context/MaybeLoggedInContextField"));
@@ -12,36 +14,39 @@ const ProjectConfigContextField_1 = tslib_1.__importDefault(require("./context/P
12
14
  const ProjectDirContextField_1 = tslib_1.__importDefault(require("./context/ProjectDirContextField"));
13
15
  const SessionManagementContextField_1 = tslib_1.__importDefault(require("./context/SessionManagementContextField"));
14
16
  class EasCommand extends core_1.Command {
15
- constructor() {
16
- super(...arguments);
17
- /**
18
- * The user session manager. Responsible for coordinating all user session related state.
19
- * If needed in a subclass, SessionManager ContextOption.
20
- */
21
- this.sessionManager = new SessionManager_1.default();
22
- }
23
17
  /**
24
18
  * Execute the context in the contextDefinition to satisfy command prerequisites.
25
19
  */
26
20
  async getContextAsync(commandClass, { nonInteractive }) {
27
21
  const contextDefinition = commandClass.contextDefinition;
28
- const contextValuePairs = await Promise.all(Object.keys(contextDefinition).map(async (contextKey) => {
29
- return [
22
+ // do these serially so that they don't do things like ask for login twice in parallel
23
+ const contextValuePairs = [];
24
+ for (const [contextKey, contextField] of Object.entries(contextDefinition)) {
25
+ contextValuePairs.push([
30
26
  contextKey,
31
- await contextDefinition[contextKey].getValueAsync({
27
+ await contextField.getValueAsync({
32
28
  nonInteractive,
33
29
  sessionManager: this.sessionManager,
30
+ analytics: this.analytics,
34
31
  }),
35
- ];
36
- }));
32
+ ]);
33
+ }
37
34
  return Object.fromEntries(contextValuePairs);
38
35
  }
36
+ get sessionManager() {
37
+ return (0, nullthrows_1.default)(this.sessionManagerInternal);
38
+ }
39
+ get analytics() {
40
+ return (0, nullthrows_1.default)(this.analyticsInternal);
41
+ }
39
42
  // eslint-disable-next-line async-protect/async-suffix
40
43
  async run() {
41
- await (0, rudderstackClient_1.initAsync)();
44
+ this.analyticsInternal = await (0, AnalyticsManager_1.createAnalyticsAsync)();
45
+ this.sessionManagerInternal = new SessionManager_1.default(this.analytics);
42
46
  // this is needed for logEvent call below as it identifies the user in the analytics system
47
+ // if possible
43
48
  await this.sessionManager.getUserAsync();
44
- (0, rudderstackClient_1.logEvent)(rudderstackClient_1.AnalyticsEvent.ACTION, {
49
+ this.analytics.logEvent(AnalyticsManager_1.CommandEvent.ACTION, {
45
50
  // id is assigned by oclif in constructor based on the filepath:
46
51
  // commands/submit === submit, commands/build/list === build:list
47
52
  action: `eas ${this.id}`,
@@ -50,7 +55,7 @@ class EasCommand extends core_1.Command {
50
55
  }
51
56
  // eslint-disable-next-line async-protect/async-suffix
52
57
  async finally(err) {
53
- await (0, rudderstackClient_1.flushAsync)();
58
+ await this.analytics.flushAsync();
54
59
  return super.finally(err);
55
60
  }
56
61
  }
@@ -98,10 +103,19 @@ EasCommand.ContextOptions = {
98
103
  },
99
104
  /**
100
105
  * Require the project to be identified and registered on server. Returns the project config in the context.
106
+ * This also requires the user to be logged in (getProjectIdAsync requires logged in), so also expose that context.
107
+ * Exposing the loggedIn context here helps us guarantee user identification for logging purposes.
101
108
  */
102
109
  ProjectConfig: {
110
+ loggedIn: new LoggedInContextField_1.default(),
103
111
  projectConfig: new ProjectConfigContextField_1.default(),
104
112
  },
113
+ /**
114
+ * Analytics manager. Returns the analytics manager in the context for use by the command.
115
+ */
116
+ Analytics: {
117
+ analytics: new AnalyticsContextField_1.default(),
118
+ },
105
119
  };
106
120
  /**
107
121
  * Context allows for subclasses (commands) to declare their prerequisites in a type-safe manner.
@@ -0,0 +1,5 @@
1
+ import { Analytics } from '../../analytics/AnalyticsManager';
2
+ import ContextField, { ContextOptions } from './ContextField';
3
+ export default class AnalyticsContextField extends ContextField<Analytics> {
4
+ getValueAsync({ analytics }: ContextOptions): Promise<Analytics>;
5
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const ContextField_1 = tslib_1.__importDefault(require("./ContextField"));
5
+ class AnalyticsContextField extends ContextField_1.default {
6
+ async getValueAsync({ analytics }) {
7
+ return analytics;
8
+ }
9
+ }
10
+ exports.default = AnalyticsContextField;
@@ -1,6 +1,8 @@
1
+ import { Analytics } from '../../analytics/AnalyticsManager';
1
2
  import SessionManager from '../../user/SessionManager';
2
3
  export interface ContextOptions {
3
4
  sessionManager: SessionManager;
5
+ analytics: Analytics;
4
6
  nonInteractive: boolean;
5
7
  }
6
8
  export default abstract class ContextField<T> {
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
4
5
  const EasCommand_1 = tslib_1.__importDefault(require("../commandUtils/EasCommand"));
5
6
  const log_1 = tslib_1.__importDefault(require("../log"));
6
- const UserSettings_1 = tslib_1.__importDefault(require("../user/UserSettings"));
7
7
  class AnalyticsView extends EasCommand_1.default {
8
8
  async runAsync() {
9
9
  const { STATUS: status } = (await this.parse(AnalyticsView)).args;
10
10
  if (status) {
11
- await UserSettings_1.default.setAsync('analyticsEnabled', status === 'on');
11
+ (0, AnalyticsManager_1.setAnalyticsEnabledAsync)(status === 'on');
12
12
  log_1.default.withTick(`${status === 'on' ? 'Enabling' : 'Disabling'} analytics.`);
13
13
  }
14
14
  else {
15
- const analyticsEnabled = await UserSettings_1.default.getAsync('analyticsEnabled', null);
15
+ const analyticsEnabled = await (0, AnalyticsManager_1.getAnalyticsEnabledAsync)();
16
16
  log_1.default.log(`Analytics are ${analyticsEnabled === false ? 'disabled' : 'enabled'} on this eas-cli installation.`);
17
17
  }
18
18
  }
@@ -19,6 +19,7 @@ export default class Build extends EasCommand {
19
19
  message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
20
20
  };
21
21
  static contextDefinition: {
22
+ analytics: import("../../commandUtils/context/AnalyticsContextField").default;
22
23
  projectDir: import("../../commandUtils/context/ProjectDirContextField").default;
23
24
  getDynamicProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicProjectConfigContextField;
24
25
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
@@ -27,7 +27,7 @@ class Build extends EasCommand_1.default {
27
27
  (0, json_1.enableJsonOutput)();
28
28
  }
29
29
  const flags = this.sanitizeFlags(rawFlags);
30
- const { loggedIn: { actor, graphqlClient }, getDynamicProjectConfigAsync, projectDir, } = await this.getContextAsync(Build, {
30
+ const { loggedIn: { actor, graphqlClient }, getDynamicProjectConfigAsync, projectDir, analytics, } = await this.getContextAsync(Build, {
31
31
  nonInteractive: flags.nonInteractive,
32
32
  });
33
33
  await handleDeprecatedEasJsonAsync(projectDir, flags.nonInteractive);
@@ -37,7 +37,7 @@ class Build extends EasCommand_1.default {
37
37
  : [generated_1.StatuspageServiceName.EasBuild]);
38
38
  }
39
39
  const flagsWithPlatform = await this.ensurePlatformSelectedAsync(flags);
40
- await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(graphqlClient, projectDir, flagsWithPlatform, actor, getDynamicProjectConfigAsync);
40
+ await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(graphqlClient, analytics, projectDir, flagsWithPlatform, actor, getDynamicProjectConfigAsync);
41
41
  }
42
42
  sanitizeFlags(flags) {
43
43
  var _b, _c;
@@ -180,6 +180,7 @@ Build.contextDefinition = {
180
180
  ..._a.ContextOptions.LoggedIn,
181
181
  ..._a.ContextOptions.DynamicProjectConfig,
182
182
  ..._a.ContextOptions.ProjectDir,
183
+ ..._a.ContextOptions.Analytics,
183
184
  };
184
185
  async function handleDeprecatedEasJsonAsync(projectDir, nonInteractive) {
185
186
  if (!(await fs_extra_1.default.pathExists(eas_json_1.EasJsonAccessor.formatEasJsonPath(projectDir)))) {
@@ -16,6 +16,7 @@ export default class BuildInspect extends EasCommand {
16
16
  verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
17
  };
18
18
  static contextDefinition: {
19
+ analytics: import("../../commandUtils/context/AnalyticsContextField").default;
19
20
  projectDir: import("../../commandUtils/context/ProjectDirContextField").default;
20
21
  getDynamicProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicProjectConfigContextField;
21
22
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
@@ -27,7 +27,7 @@ const STAGE_DESCRIPTION = `Stage of the build you want to inspect.
27
27
  class BuildInspect extends EasCommand_1.default {
28
28
  async runAsync() {
29
29
  const { flags } = await this.parse(BuildInspect);
30
- const { loggedIn: { actor, graphqlClient }, getDynamicProjectConfigAsync, projectDir, } = await this.getContextAsync(BuildInspect, {
30
+ const { loggedIn: { actor, graphqlClient }, getDynamicProjectConfigAsync, projectDir, analytics, } = await this.getContextAsync(BuildInspect, {
31
31
  nonInteractive: false,
32
32
  });
33
33
  const outputDirectory = path_1.default.resolve(process.cwd(), flags.output);
@@ -44,7 +44,7 @@ class BuildInspect extends EasCommand_1.default {
44
44
  }
45
45
  else {
46
46
  try {
47
- await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(graphqlClient, projectDir, {
47
+ await (0, runBuildAndSubmit_1.runBuildAndSubmitAsync)(graphqlClient, analytics, projectDir, {
48
48
  nonInteractive: false,
49
49
  wait: true,
50
50
  clearCache: false,
@@ -141,4 +141,5 @@ BuildInspect.contextDefinition = {
141
141
  ..._a.ContextOptions.LoggedIn,
142
142
  ..._a.ContextOptions.DynamicProjectConfig,
143
143
  ..._a.ContextOptions.ProjectDir,
144
+ ..._a.ContextOptions.Analytics,
144
145
  };
@@ -5,6 +5,7 @@ export default class Credentials extends EasCommand {
5
5
  platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
6
6
  };
7
7
  static contextDefinition: {
8
+ analytics: import("../commandUtils/context/AnalyticsContextField").default;
8
9
  projectConfig: import("../commandUtils/context/OptionalProjectConfigContextField").OptionalProjectConfigContextField;
9
10
  loggedIn: import("../commandUtils/context/LoggedInContextField").default;
10
11
  };
@@ -8,10 +8,10 @@ const SelectPlatform_1 = require("../credentials/manager/SelectPlatform");
8
8
  class Credentials extends EasCommand_1.default {
9
9
  async runAsync() {
10
10
  const { flags } = await this.parse(Credentials);
11
- const { loggedIn: { actor, graphqlClient }, projectConfig, } = await this.getContextAsync(Credentials, {
11
+ const { loggedIn: { actor, graphqlClient }, projectConfig, analytics, } = await this.getContextAsync(Credentials, {
12
12
  nonInteractive: false,
13
13
  });
14
- await new SelectPlatform_1.SelectPlatform(actor, graphqlClient, projectConfig !== null && projectConfig !== void 0 ? projectConfig : null, flags.platform).runAsync();
14
+ await new SelectPlatform_1.SelectPlatform(actor, graphqlClient, analytics, projectConfig !== null && projectConfig !== void 0 ? projectConfig : null, flags.platform).runAsync();
15
15
  }
16
16
  }
17
17
  exports.default = Credentials;
@@ -23,4 +23,5 @@ Credentials.flags = {
23
23
  Credentials.contextDefinition = {
24
24
  ..._a.ContextOptions.LoggedIn,
25
25
  ..._a.ContextOptions.OptionalProjectConfig,
26
+ ..._a.ContextOptions.Analytics,
26
27
  };
@@ -5,6 +5,7 @@ export default class MetadataPull extends EasCommand {
5
5
  profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
6
6
  };
7
7
  static contextDefinition: {
8
+ analytics: import("../../commandUtils/context/AnalyticsContextField").default;
8
9
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
9
10
  projectConfig: import("../../commandUtils/context/ProjectConfigContextField").default;
10
11
  };
@@ -16,7 +16,7 @@ class MetadataPull extends EasCommand_1.default {
16
16
  async runAsync() {
17
17
  log_1.default.warn('EAS Metadata is in beta and subject to breaking changes.');
18
18
  const { flags } = await this.parse(MetadataPull);
19
- const { loggedIn: { actor, graphqlClient }, projectConfig: { exp, projectId, projectDir }, } = await this.getContextAsync(MetadataPull, {
19
+ const { loggedIn: { actor, graphqlClient }, projectConfig: { exp, projectId, projectDir }, analytics, } = await this.getContextAsync(MetadataPull, {
20
20
  nonInteractive: false,
21
21
  });
22
22
  // this command is interactive (all nonInteractive flags passed to utility functions are false)
@@ -26,10 +26,12 @@ class MetadataPull extends EasCommand_1.default {
26
26
  projectDir,
27
27
  user: actor,
28
28
  graphqlClient,
29
+ analytics,
29
30
  nonInteractive: false,
30
31
  });
31
32
  const metadataCtx = await (0, context_2.createMetadataContextAsync)({
32
33
  credentialsCtx,
34
+ analytics,
33
35
  projectDir,
34
36
  exp,
35
37
  profileName: flags.profile,
@@ -62,4 +64,5 @@ MetadataPull.flags = {
62
64
  MetadataPull.contextDefinition = {
63
65
  ..._a.ContextOptions.ProjectConfig,
64
66
  ..._a.ContextOptions.LoggedIn,
67
+ ..._a.ContextOptions.Analytics,
65
68
  };
@@ -5,6 +5,7 @@ export default class MetadataPush extends EasCommand {
5
5
  profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
6
6
  };
7
7
  static contextDefinition: {
8
+ analytics: import("../../commandUtils/context/AnalyticsContextField").default;
8
9
  loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
9
10
  projectConfig: import("../../commandUtils/context/ProjectConfigContextField").default;
10
11
  };