eas-cli 19.0.8 → 20.0.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.
- package/README.md +305 -101
- package/build/build/createContext.d.ts +2 -1
- package/build/build/createContext.js +3 -1
- package/build/build/ios/credentials.js +5 -1
- package/build/build/ios/prepareJob.js +3 -0
- package/build/build/runBuildAndSubmit.d.ts +1 -0
- package/build/build/runBuildAndSubmit.js +1 -0
- package/build/build/types.d.ts +1 -0
- package/build/commands/build/index.d.ts +1 -0
- package/build/commands/build/index.js +13 -0
- package/build/commands/build/internal.d.ts +1 -0
- package/build/commands/build/internal.js +5 -0
- package/build/commands/go.d.ts +1 -0
- package/build/commands/go.js +29 -1
- package/build/commands/observe/events.d.ts +3 -3
- package/build/commands/observe/events.js +69 -51
- package/build/commands/observe/{logs.d.ts → metrics-summary.d.ts} +3 -11
- package/build/commands/observe/metrics-summary.js +95 -0
- package/build/commands/observe/metrics.d.ts +8 -3
- package/build/commands/observe/metrics.js +63 -47
- package/build/commands/observe/routes.d.ts +0 -1
- package/build/commands/observe/routes.js +0 -4
- package/build/commands/observe/versions.d.ts +0 -1
- package/build/commands/observe/versions.js +0 -4
- package/build/commands/update/embedded/upload.d.ts +20 -0
- package/build/commands/update/embedded/upload.js +129 -0
- package/build/credentials/context.d.ts +2 -0
- package/build/credentials/context.js +2 -0
- package/build/credentials/ios/actions/DeviceUtils.d.ts +2 -0
- package/build/credentials/ios/actions/DeviceUtils.js +21 -0
- package/build/credentials/ios/actions/SetUpAdhocProvisioningProfile.d.ts +1 -0
- package/build/credentials/ios/actions/SetUpAdhocProvisioningProfile.js +76 -14
- package/build/credentials/ios/actions/SetUpTargetBuildCredentials.js +8 -0
- package/build/graphql/client.js +1 -0
- package/build/graphql/generated.d.ts +70 -1
- package/build/graphql/mutations/EmbeddedUpdateAssetMutation.d.ts +13 -0
- package/build/graphql/mutations/EmbeddedUpdateAssetMutation.js +32 -0
- package/build/graphql/mutations/EmbeddedUpdateMutation.d.ts +14 -0
- package/build/graphql/mutations/EmbeddedUpdateMutation.js +37 -0
- package/build/graphql/queries/WorkflowRunQuery.d.ts +2 -1
- package/build/graphql/queries/WorkflowRunQuery.js +19 -6
- package/build/observe/formatCustomEvents.js +5 -5
- package/build/observe/metricNames.js +2 -0
- package/build/update/embeddedManifest.d.ts +3 -0
- package/build/update/embeddedManifest.js +28 -0
- package/oclif.manifest.json +1852 -1714
- package/package.json +6 -6
- package/build/commands/observe/logs.js +0 -141
|
@@ -9,7 +9,7 @@ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGr
|
|
|
9
9
|
import { CustomBuildConfigMetadata } from '../project/customBuildConfig';
|
|
10
10
|
import { Actor } from '../user/User';
|
|
11
11
|
import { Client } from '../vcs/vcs';
|
|
12
|
-
export declare function createBuildContextAsync<T extends Platform>({ buildProfileName, buildProfile, easJsonCliConfig, clearCache, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClassFlag, message, actor, graphqlClient, analytics, vcsClient, getDynamicPrivateProjectConfigAsync, customBuildConfigMetadata, buildLoggerLevel, freezeCredentials, isVerboseLoggingEnabled, whatToTest, env, }: {
|
|
12
|
+
export declare function createBuildContextAsync<T extends Platform>({ buildProfileName, buildProfile, easJsonCliConfig, clearCache, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClassFlag, message, actor, graphqlClient, analytics, vcsClient, getDynamicPrivateProjectConfigAsync, customBuildConfigMetadata, buildLoggerLevel, freezeCredentials, refreshAdHocProvisioningProfile: refreshAdHocProvisioningProfileFlag, isVerboseLoggingEnabled, whatToTest, env, }: {
|
|
13
13
|
buildProfileName: string;
|
|
14
14
|
buildProfile: BuildProfile<T>;
|
|
15
15
|
easJsonCliConfig: EasJson['cli'];
|
|
@@ -29,6 +29,7 @@ export declare function createBuildContextAsync<T extends Platform>({ buildProfi
|
|
|
29
29
|
customBuildConfigMetadata?: CustomBuildConfigMetadata;
|
|
30
30
|
buildLoggerLevel?: LoggerLevel;
|
|
31
31
|
freezeCredentials: boolean;
|
|
32
|
+
refreshAdHocProvisioningProfile?: boolean;
|
|
32
33
|
isVerboseLoggingEnabled: boolean;
|
|
33
34
|
whatToTest?: string;
|
|
34
35
|
env: Record<string, string>;
|
|
@@ -16,7 +16,7 @@ const AnalyticsManager_1 = require("../analytics/AnalyticsManager");
|
|
|
16
16
|
const context_1 = require("../credentials/context");
|
|
17
17
|
const projectUtils_1 = require("../project/projectUtils");
|
|
18
18
|
const workflow_1 = require("../project/workflow");
|
|
19
|
-
async function createBuildContextAsync({ buildProfileName, buildProfile, easJsonCliConfig, clearCache = false, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClassFlag, message, actor, graphqlClient, analytics, vcsClient, getDynamicPrivateProjectConfigAsync, customBuildConfigMetadata, buildLoggerLevel, freezeCredentials, isVerboseLoggingEnabled, whatToTest, env, }) {
|
|
19
|
+
async function createBuildContextAsync({ buildProfileName, buildProfile, easJsonCliConfig, clearCache = false, localBuildOptions, nonInteractive, noWait, platform, projectDir, resourceClassFlag, message, actor, graphqlClient, analytics, vcsClient, getDynamicPrivateProjectConfigAsync, customBuildConfigMetadata, buildLoggerLevel, freezeCredentials, refreshAdHocProvisioningProfile: refreshAdHocProvisioningProfileFlag, isVerboseLoggingEnabled, whatToTest, env, }) {
|
|
20
20
|
const { exp, projectId } = await getDynamicPrivateProjectConfigAsync({
|
|
21
21
|
env,
|
|
22
22
|
});
|
|
@@ -33,6 +33,7 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
|
|
|
33
33
|
: buildProfile?.buildConfiguration === 'Debug') ??
|
|
34
34
|
false;
|
|
35
35
|
const requiredPackageManager = (0, package_manager_1.resolvePackageManager)(projectDir);
|
|
36
|
+
const refreshAdHocProvisioningProfile = refreshAdHocProvisioningProfileFlag ?? false;
|
|
36
37
|
const credentialsCtx = new context_1.CredentialsContext({
|
|
37
38
|
projectInfo: { exp, projectId },
|
|
38
39
|
nonInteractive,
|
|
@@ -44,6 +45,7 @@ async function createBuildContextAsync({ buildProfileName, buildProfile, easJson
|
|
|
44
45
|
easJsonCliConfig,
|
|
45
46
|
vcsClient,
|
|
46
47
|
freezeCredentials,
|
|
48
|
+
refreshAdHocProvisioningProfile,
|
|
47
49
|
});
|
|
48
50
|
const devClientProperties = getDevClientEventProperties({
|
|
49
51
|
platform,
|
|
@@ -11,13 +11,17 @@ async function ensureIosCredentialsAsync(buildCtx, targets) {
|
|
|
11
11
|
if (!shouldProvideCredentials(buildCtx)) {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
+
const { credentialsSource } = buildCtx.buildProfile;
|
|
15
|
+
if (buildCtx.credentialsCtx.refreshAdHocProvisioningProfile &&
|
|
16
|
+
credentialsSource === 'local') {
|
|
17
|
+
throw new Error('--refresh-ad-hoc-provisioning-profile cannot be used with credentialsSource "local". Use remote credentials or omit the flag.');
|
|
18
|
+
}
|
|
14
19
|
const provider = new IosCredentialsProvider_1.default(buildCtx.credentialsCtx, {
|
|
15
20
|
app: await (0, BuildCredentialsUtils_1.getAppFromContextAsync)(buildCtx.credentialsCtx),
|
|
16
21
|
targets,
|
|
17
22
|
distribution: buildCtx.buildProfile.distribution ?? 'store',
|
|
18
23
|
enterpriseProvisioning: buildCtx.buildProfile.enterpriseProvisioning,
|
|
19
24
|
});
|
|
20
|
-
const { credentialsSource } = buildCtx.buildProfile;
|
|
21
25
|
(0, credentials_1.logCredentialsSource)(credentialsSource, eas_build_job_1.Platform.IOS);
|
|
22
26
|
return {
|
|
23
27
|
credentials: await provider.getCredentialsAsync(credentialsSource),
|
|
@@ -91,6 +91,9 @@ async function prepareJobAsync(ctx, jobData) {
|
|
|
91
91
|
// See: https://github.com/expo/eas-build/pull/454
|
|
92
92
|
appId: ctx.projectId,
|
|
93
93
|
initiatingUserId: ctx.user.id,
|
|
94
|
+
...(ctx.credentialsCtx.refreshAdHocProvisioningProfile && {
|
|
95
|
+
refreshAdHocProvisioningProfile: true,
|
|
96
|
+
}),
|
|
94
97
|
};
|
|
95
98
|
return (0, eas_build_job_1.sanitizeBuildJob)(job);
|
|
96
99
|
}
|
|
@@ -243,6 +243,7 @@ async function prepareAndStartBuildAsync({ projectDir, flags, moreBuilds, buildP
|
|
|
243
243
|
customBuildConfigMetadata,
|
|
244
244
|
buildLoggerLevel: flags.buildLoggerLevel ?? (log_1.default.isDebug ? logger_1.LoggerLevel.DEBUG : undefined),
|
|
245
245
|
freezeCredentials: flags.freezeCredentials,
|
|
246
|
+
refreshAdHocProvisioningProfile: flags.refreshAdHocProvisioningProfile,
|
|
246
247
|
isVerboseLoggingEnabled: flags.isVerboseLoggingEnabled ?? false,
|
|
247
248
|
whatToTest: flags.whatToTest,
|
|
248
249
|
env,
|
package/build/build/types.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export default class Build extends EasCommand {
|
|
|
21
21
|
message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
22
|
'build-logger-level': import("@oclif/core/lib/interfaces").OptionFlag<LoggerLevel | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
23
|
'freeze-credentials': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
'refresh-ad-hoc-provisioning-profile': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
25
|
'verbose-logs': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
26
|
};
|
|
26
27
|
static contextDefinition: {
|
|
@@ -92,6 +92,10 @@ class Build extends EasCommand_1.default {
|
|
|
92
92
|
default: false,
|
|
93
93
|
description: 'Prevent the build from updating credentials in non-interactive mode',
|
|
94
94
|
}),
|
|
95
|
+
'refresh-ad-hoc-provisioning-profile': core_1.Flags.boolean({
|
|
96
|
+
default: false,
|
|
97
|
+
description: 'Refresh managed ad-hoc provisioning profiles from App Store Connect before gathering build credentials',
|
|
98
|
+
}),
|
|
95
99
|
'verbose-logs': core_1.Flags.boolean({
|
|
96
100
|
default: false,
|
|
97
101
|
description: 'Use verbose logs for the build process',
|
|
@@ -138,6 +142,14 @@ class Build extends EasCommand_1.default {
|
|
|
138
142
|
}
|
|
139
143
|
sanitizeFlags(flags) {
|
|
140
144
|
const { json, nonInteractive } = (0, flags_1.resolveNonInteractiveAndJsonFlags)(flags);
|
|
145
|
+
if (flags['refresh-ad-hoc-provisioning-profile']) {
|
|
146
|
+
if (!nonInteractive) {
|
|
147
|
+
core_1.Errors.error('--refresh-ad-hoc-provisioning-profile can only be used in non-interactive mode.', { exit: 1 });
|
|
148
|
+
}
|
|
149
|
+
if (flags['freeze-credentials']) {
|
|
150
|
+
core_1.Errors.error('Cannot use --refresh-ad-hoc-provisioning-profile with --freeze-credentials.', { exit: 1 });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
141
153
|
if (!flags.local && flags.output) {
|
|
142
154
|
core_1.Errors.error('--output is allowed only for local builds', { exit: 1 });
|
|
143
155
|
}
|
|
@@ -185,6 +197,7 @@ class Build extends EasCommand_1.default {
|
|
|
185
197
|
message,
|
|
186
198
|
buildLoggerLevel: flags['build-logger-level'],
|
|
187
199
|
freezeCredentials: flags['freeze-credentials'],
|
|
200
|
+
refreshAdHocProvisioningProfile: flags['refresh-ad-hoc-provisioning-profile'],
|
|
188
201
|
isVerboseLoggingEnabled: flags['verbose-logs'],
|
|
189
202
|
whatToTest: flags['what-to-test'],
|
|
190
203
|
};
|
|
@@ -12,6 +12,7 @@ export default class BuildInternal extends EasCommand {
|
|
|
12
12
|
profile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
13
|
'auto-submit': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
'auto-submit-with-profile': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
'refresh-ad-hoc-provisioning-profile': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
16
|
};
|
|
16
17
|
static contextDefinition: {
|
|
17
18
|
vcsClient: import("../../commandUtils/context/VcsClientContextField").default;
|
|
@@ -37,6 +37,10 @@ class BuildInternal extends EasCommand_1.default {
|
|
|
37
37
|
helpValue: 'PROFILE_NAME',
|
|
38
38
|
exclusive: ['auto-submit'],
|
|
39
39
|
}),
|
|
40
|
+
'refresh-ad-hoc-provisioning-profile': core_1.Flags.boolean({
|
|
41
|
+
default: false,
|
|
42
|
+
description: 'Refresh managed ad-hoc provisioning profiles from App Store Connect before gathering build credentials',
|
|
43
|
+
}),
|
|
40
44
|
};
|
|
41
45
|
static contextDefinition = {
|
|
42
46
|
...this.ContextOptions.LoggedIn,
|
|
@@ -70,6 +74,7 @@ class BuildInternal extends EasCommand_1.default {
|
|
|
70
74
|
profile: flags.profile,
|
|
71
75
|
nonInteractive: true,
|
|
72
76
|
freezeCredentials: false,
|
|
77
|
+
refreshAdHocProvisioningProfile: flags['refresh-ad-hoc-provisioning-profile'],
|
|
73
78
|
wait: false,
|
|
74
79
|
clearCache: false,
|
|
75
80
|
json: true,
|
package/build/commands/go.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export default class Go extends EasCommand {
|
|
|
14
14
|
loggedIn: import("../commandUtils/context/LoggedInContextField").default;
|
|
15
15
|
};
|
|
16
16
|
runAsync(): Promise<void>;
|
|
17
|
+
private selectSdkVersionAsync;
|
|
17
18
|
private generateBundleId;
|
|
18
19
|
private ensureEasProjectAsync;
|
|
19
20
|
private setupCredentialsAsync;
|
package/build/commands/go.js
CHANGED
|
@@ -169,7 +169,10 @@ class Go extends EasCommand_1.default {
|
|
|
169
169
|
if (detectedSdkVersion && !flags['sdk-version']) {
|
|
170
170
|
log_1.default.log(`Current project using SDK ${detectedSdkVersion.split('.')[0]}. Auto-selected same version. To use a different version, pass --sdk-version.`);
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
let sdkVersion = flags['sdk-version'] ?? detectedSdkVersion;
|
|
173
|
+
if (!sdkVersion) {
|
|
174
|
+
({ sdkVersion } = await this.selectSdkVersionAsync(graphqlClient));
|
|
175
|
+
}
|
|
173
176
|
const bundleId = flags['bundle-id'] ?? this.generateBundleId(actor);
|
|
174
177
|
if (!(0, bundleIdentifier_1.isBundleIdentifierValid)(bundleId)) {
|
|
175
178
|
throw new Error(`"${bundleId}" is not a valid iOS bundle identifier. ${bundleIdentifier_1.INVALID_BUNDLE_IDENTIFIER_MESSAGE} Pass a valid identifier with --bundle-id.`);
|
|
@@ -217,6 +220,31 @@ class Go extends EasCommand_1.default {
|
|
|
217
220
|
await fs.remove(tmpDir);
|
|
218
221
|
}
|
|
219
222
|
}
|
|
223
|
+
async selectSdkVersionAsync(graphqlClient) {
|
|
224
|
+
let versions;
|
|
225
|
+
try {
|
|
226
|
+
versions = await WorkflowRunQuery_1.WorkflowRunQuery.expoGoSupportedSdkVersionsAsync(graphqlClient);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return { sdkVersion: undefined };
|
|
230
|
+
}
|
|
231
|
+
const selectable = versions.filter(v => !v.isDeprecated);
|
|
232
|
+
if (selectable.length === 0) {
|
|
233
|
+
return { sdkVersion: undefined };
|
|
234
|
+
}
|
|
235
|
+
const defaultVersion = selectable.find(v => v.isLatest) ?? selectable.at(-1);
|
|
236
|
+
return {
|
|
237
|
+
sdkVersion: await (0, prompts_1.selectAsync)('Select an Expo SDK version', selectable.map(v => {
|
|
238
|
+
const major = v.sdkVersion.split('.')[0];
|
|
239
|
+
const title = v.isLatest
|
|
240
|
+
? `SDK ${major} (latest)`
|
|
241
|
+
: v.isBeta
|
|
242
|
+
? `SDK ${major} (beta)`
|
|
243
|
+
: `SDK ${major}`;
|
|
244
|
+
return { title, value: v.sdkVersion };
|
|
245
|
+
}), { initial: defaultVersion?.sdkVersion }),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
220
248
|
generateBundleId(actor) {
|
|
221
249
|
const username = (0, actions_1.ensureActorHasPrimaryAccount)(actor).name;
|
|
222
250
|
const sanitizedUsername = username
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
2
|
export default class ObserveEvents extends EasCommand {
|
|
3
|
-
static hidden: boolean;
|
|
4
3
|
static description: string;
|
|
5
4
|
static args: {
|
|
6
|
-
|
|
5
|
+
eventName: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
6
|
};
|
|
8
7
|
static flags: {
|
|
9
8
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
9
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
10
|
'project-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
'session-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
'all-events': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
13
|
'update-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
14
|
'app-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
15
|
start: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -17,7 +18,6 @@ export default class ObserveEvents extends EasCommand {
|
|
|
17
18
|
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined>;
|
|
18
19
|
after: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
20
|
platform: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
-
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
21
|
};
|
|
22
22
|
static contextDefinition: {
|
|
23
23
|
loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
|
|
@@ -3,37 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const core_1 = require("@oclif/core");
|
|
5
5
|
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
6
|
-
const errors_1 = require("../../commandUtils/errors");
|
|
7
6
|
const flags_1 = require("../../commandUtils/flags");
|
|
8
7
|
const pagination_1 = require("../../commandUtils/pagination");
|
|
9
8
|
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
|
-
const
|
|
9
|
+
const ObserveQuery_1 = require("../../graphql/queries/ObserveQuery");
|
|
10
|
+
const fetchCustomEvents_1 = require("../../observe/fetchCustomEvents");
|
|
11
11
|
const flags_2 = require("../../observe/flags");
|
|
12
|
-
const
|
|
13
|
-
const formatEvents_1 = require("../../observe/formatEvents");
|
|
12
|
+
const formatCustomEvents_1 = require("../../observe/formatCustomEvents");
|
|
14
13
|
const platforms_1 = require("../../observe/platforms");
|
|
15
14
|
const resolveProjectContext_1 = require("../../observe/resolveProjectContext");
|
|
16
15
|
const startAndEndTime_1 = require("../../observe/startAndEndTime");
|
|
17
|
-
const prompts_1 = require("../../prompts");
|
|
18
16
|
const json_1 = require("../../utils/json");
|
|
19
17
|
const DEFAULT_EVENTS_LIMIT = 10;
|
|
20
18
|
class ObserveEvents extends EasCommand_1.default {
|
|
21
|
-
static
|
|
22
|
-
static description = 'display individual app performance events ordered by metric value';
|
|
19
|
+
static description = 'display individual events emitted by the app via `logEvent`, filtered by the event name in the argument. With no arguments, a list of the available event names and associated event counts is returned.';
|
|
23
20
|
static args = {
|
|
24
|
-
|
|
25
|
-
description: '
|
|
21
|
+
eventName: core_1.Args.string({
|
|
22
|
+
description: 'Event name to filter by',
|
|
26
23
|
required: false,
|
|
27
|
-
options: Object.keys(metricNames_1.METRIC_ALIASES),
|
|
28
24
|
}),
|
|
29
25
|
};
|
|
30
26
|
static flags = {
|
|
31
|
-
sort: core_1.Flags.option({
|
|
32
|
-
description: 'Sort order for events',
|
|
33
|
-
options: Object.values(fetchEvents_1.EventsOrderPreset).map(s => s.toLowerCase()),
|
|
34
|
-
required: false,
|
|
35
|
-
default: fetchEvents_1.EventsOrderPreset.Oldest.valueOf().toLowerCase(),
|
|
36
|
-
})(),
|
|
37
27
|
...flags_2.ObservePlatformFlag,
|
|
38
28
|
...flags_2.ObserveAfterFlag,
|
|
39
29
|
limit: (0, pagination_1.getLimitFlagWithCustomValues)({
|
|
@@ -43,6 +33,13 @@ class ObserveEvents extends EasCommand_1.default {
|
|
|
43
33
|
...flags_2.ObserveTimeRangeFlags,
|
|
44
34
|
...flags_2.ObserveAppVersionFlag,
|
|
45
35
|
...flags_2.ObserveUpdateIdFlag,
|
|
36
|
+
'session-id': core_1.Flags.string({
|
|
37
|
+
description: 'Filter by session ID',
|
|
38
|
+
}),
|
|
39
|
+
'all-events': core_1.Flags.boolean({
|
|
40
|
+
description: 'When no event name argument is provided, list all events across all event names instead of a summary of event names + counts.',
|
|
41
|
+
default: false,
|
|
42
|
+
}),
|
|
46
43
|
...flags_2.ObserveProjectIdFlag,
|
|
47
44
|
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
48
45
|
};
|
|
@@ -55,6 +52,9 @@ class ObserveEvents extends EasCommand_1.default {
|
|
|
55
52
|
};
|
|
56
53
|
async runAsync() {
|
|
57
54
|
const { flags, args } = await this.parse(ObserveEvents);
|
|
55
|
+
if (args.eventName && flags['all-events']) {
|
|
56
|
+
throw new Error('--all-events cannot be combined with an event name argument. Pass an event name to filter by it, or pass --all-events to list all events across all event names.');
|
|
57
|
+
}
|
|
58
58
|
const { projectId, graphqlClient } = await (0, resolveProjectContext_1.resolveObserveCommandContextAsync)({
|
|
59
59
|
command: this,
|
|
60
60
|
commandClass: ObserveEvents,
|
|
@@ -65,53 +65,71 @@ class ObserveEvents extends EasCommand_1.default {
|
|
|
65
65
|
if (flags.json) {
|
|
66
66
|
(0, json_1.enableJsonOutput)();
|
|
67
67
|
}
|
|
68
|
-
else {
|
|
69
|
-
log_1.default.warn('EAS Observe is in preview and subject to breaking changes.');
|
|
70
|
-
}
|
|
71
|
-
let metricName;
|
|
72
|
-
if (args.metric) {
|
|
73
|
-
metricName = (0, metricNames_1.resolveMetricName)(args.metric);
|
|
74
|
-
}
|
|
75
|
-
else if (flags['non-interactive']) {
|
|
76
|
-
throw new errors_1.EasCommandError('A metric argument is required in non-interactive mode. Available metrics: ' +
|
|
77
|
-
Object.keys(metricNames_1.METRIC_ALIASES).join(', '));
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
const choices = Object.entries(metricNames_1.METRIC_SHORT_NAMES).map(([fullName, displayName]) => ({
|
|
81
|
-
title: `${displayName} (${fullName})`,
|
|
82
|
-
value: fullName,
|
|
83
|
-
}));
|
|
84
|
-
metricName = await (0, prompts_1.selectAsync)('Select a metric', choices);
|
|
85
|
-
}
|
|
86
|
-
const orderBy = (0, fetchEvents_1.resolveOrderBy)(flags.sort);
|
|
87
68
|
const { daysBack, startTime, endTime } = (0, startAndEndTime_1.resolveTimeRange)(flags);
|
|
88
69
|
const platform = (0, platforms_1.appObservePlatformFromFlag)(flags.platform);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
70
|
+
if (!args.eventName && !flags['all-events']) {
|
|
71
|
+
const { names, isTruncated } = await ObserveQuery_1.ObserveQuery.customEventNamesAsync(graphqlClient, {
|
|
72
|
+
appId: projectId,
|
|
73
|
+
startTime,
|
|
74
|
+
endTime,
|
|
75
|
+
platform,
|
|
76
|
+
});
|
|
77
|
+
if (flags.json) {
|
|
78
|
+
(0, json_1.printJsonOnlyOutput)((0, formatCustomEvents_1.buildObserveCustomEventNamesJson)(names, isTruncated));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
log_1.default.addNewLineIfNone();
|
|
82
|
+
log_1.default.log((0, formatCustomEvents_1.buildObserveCustomEventNamesTable)(names, {
|
|
83
|
+
daysBack,
|
|
84
|
+
startTime,
|
|
85
|
+
endTime,
|
|
86
|
+
isTruncated,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const { events, pageInfo } = await (0, fetchCustomEvents_1.fetchObserveCustomEventsAsync)(graphqlClient, projectId, {
|
|
92
|
+
eventName: args.eventName,
|
|
93
|
+
limit: flags.limit ?? DEFAULT_EVENTS_LIMIT,
|
|
94
|
+
...(flags.after && { after: flags.after }),
|
|
95
|
+
startTime,
|
|
96
|
+
endTime,
|
|
97
|
+
platform,
|
|
98
|
+
appVersion: flags['app-version'],
|
|
99
|
+
updateId: flags['update-id'],
|
|
100
|
+
sessionId: flags['session-id'],
|
|
101
|
+
});
|
|
102
|
+
if (args.eventName && events.length === 0) {
|
|
103
|
+
const { names, isTruncated } = await ObserveQuery_1.ObserveQuery.customEventNamesAsync(graphqlClient, {
|
|
104
|
+
appId: projectId,
|
|
96
105
|
startTime,
|
|
97
106
|
endTime,
|
|
98
107
|
platform,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
});
|
|
109
|
+
if (flags.json) {
|
|
110
|
+
(0, json_1.printJsonOnlyOutput)((0, formatCustomEvents_1.buildObserveCustomEventsEmptyWithSuggestionsJson)(args.eventName, names, isTruncated));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
log_1.default.addNewLineIfNone();
|
|
114
|
+
log_1.default.log((0, formatCustomEvents_1.buildObserveCustomEventsEmptyWithSuggestionsTable)(args.eventName, names, {
|
|
115
|
+
daysBack,
|
|
116
|
+
startTime,
|
|
117
|
+
endTime,
|
|
118
|
+
isTruncated,
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
104
123
|
if (flags.json) {
|
|
105
|
-
(0, json_1.printJsonOnlyOutput)((0,
|
|
124
|
+
(0, json_1.printJsonOnlyOutput)((0, formatCustomEvents_1.buildObserveCustomEventsJson)(events, pageInfo));
|
|
106
125
|
}
|
|
107
126
|
else {
|
|
108
127
|
log_1.default.addNewLineIfNone();
|
|
109
|
-
log_1.default.log((0,
|
|
110
|
-
|
|
128
|
+
log_1.default.log((0, formatCustomEvents_1.buildObserveCustomEventsTable)(events, pageInfo, {
|
|
129
|
+
eventName: args.eventName,
|
|
111
130
|
daysBack,
|
|
112
131
|
startTime,
|
|
113
132
|
endTime,
|
|
114
|
-
totalEventCount,
|
|
115
133
|
}));
|
|
116
134
|
}
|
|
117
135
|
}
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
|
-
export default class
|
|
3
|
-
static hidden: boolean;
|
|
2
|
+
export default class ObserveMetricsSummary extends EasCommand {
|
|
4
3
|
static description: string;
|
|
5
|
-
static args: {
|
|
6
|
-
eventName: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
4
|
static flags: {
|
|
9
5
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
6
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
7
|
'project-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
-
'session-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
-
'all-events': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
-
'update-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
-
'app-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
8
|
start: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
9
|
end: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
10
|
days: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
metric: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
stat: import("@oclif/core/lib/interfaces").OptionFlag<("min" | "max" | "median" | "average" | "p80" | "p90" | "p99" | "eventCount")[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
13
|
platform: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
14
|
};
|
|
23
15
|
static contextDefinition: {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
|
|
6
|
+
const flags_1 = require("../../commandUtils/flags");
|
|
7
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
8
|
+
const fetchMetrics_1 = require("../../observe/fetchMetrics");
|
|
9
|
+
const flags_2 = require("../../observe/flags");
|
|
10
|
+
const formatMetrics_1 = require("../../observe/formatMetrics");
|
|
11
|
+
const metricNames_1 = require("../../observe/metricNames");
|
|
12
|
+
const platforms_1 = require("../../observe/platforms");
|
|
13
|
+
const resolveProjectContext_1 = require("../../observe/resolveProjectContext");
|
|
14
|
+
const startAndEndTime_1 = require("../../observe/startAndEndTime");
|
|
15
|
+
const json_1 = require("../../utils/json");
|
|
16
|
+
const DEFAULT_METRICS = [
|
|
17
|
+
'expo.app_startup.cold_launch_time',
|
|
18
|
+
'expo.app_startup.warm_launch_time',
|
|
19
|
+
'expo.app_startup.tti',
|
|
20
|
+
'expo.app_startup.ttr',
|
|
21
|
+
'expo.app_startup.bundle_load_time',
|
|
22
|
+
];
|
|
23
|
+
const DEFAULT_STATS_TABLE = ['median', 'eventCount'];
|
|
24
|
+
const DEFAULT_STATS_JSON = [
|
|
25
|
+
'min',
|
|
26
|
+
'median',
|
|
27
|
+
'max',
|
|
28
|
+
'average',
|
|
29
|
+
'p80',
|
|
30
|
+
'p90',
|
|
31
|
+
'p99',
|
|
32
|
+
'eventCount',
|
|
33
|
+
];
|
|
34
|
+
class ObserveMetricsSummary extends EasCommand_1.default {
|
|
35
|
+
static description = 'display aggregated performance metric statistics grouped by app version';
|
|
36
|
+
static flags = {
|
|
37
|
+
...flags_2.ObservePlatformFlag,
|
|
38
|
+
metric: core_1.Flags.option({
|
|
39
|
+
description: 'Metric name to display (can be specified multiple times).',
|
|
40
|
+
multiple: true,
|
|
41
|
+
options: Object.keys(metricNames_1.METRIC_ALIASES),
|
|
42
|
+
})(),
|
|
43
|
+
stat: core_1.Flags.option({
|
|
44
|
+
description: 'Statistic to display per metric (can be specified multiple times)',
|
|
45
|
+
multiple: true,
|
|
46
|
+
options: DEFAULT_STATS_JSON,
|
|
47
|
+
})(),
|
|
48
|
+
...flags_2.ObserveTimeRangeFlags,
|
|
49
|
+
...flags_2.ObserveProjectIdFlag,
|
|
50
|
+
...flags_1.EasNonInteractiveAndJsonFlags,
|
|
51
|
+
};
|
|
52
|
+
static contextDefinition = {
|
|
53
|
+
...this.ContextOptions.ProjectId,
|
|
54
|
+
...this.ContextOptions.LoggedIn,
|
|
55
|
+
};
|
|
56
|
+
static loggedInOnlyContextDefinition = {
|
|
57
|
+
...this.ContextOptions.LoggedIn,
|
|
58
|
+
};
|
|
59
|
+
async runAsync() {
|
|
60
|
+
const { flags } = await this.parse(ObserveMetricsSummary);
|
|
61
|
+
const { projectId, graphqlClient } = await (0, resolveProjectContext_1.resolveObserveCommandContextAsync)({
|
|
62
|
+
command: this,
|
|
63
|
+
commandClass: ObserveMetricsSummary,
|
|
64
|
+
loggedInOnlyContextDefinition: ObserveMetricsSummary.loggedInOnlyContextDefinition,
|
|
65
|
+
projectIdOverride: flags['project-id'],
|
|
66
|
+
nonInteractive: flags['non-interactive'],
|
|
67
|
+
});
|
|
68
|
+
if (flags.json) {
|
|
69
|
+
(0, json_1.enableJsonOutput)();
|
|
70
|
+
}
|
|
71
|
+
const metricNames = flags.metric?.length
|
|
72
|
+
? flags.metric.map(metricNames_1.resolveMetricName)
|
|
73
|
+
: DEFAULT_METRICS;
|
|
74
|
+
const { daysBack, startTime, endTime } = (0, startAndEndTime_1.resolveTimeRange)(flags);
|
|
75
|
+
const platforms = (0, platforms_1.appPlatformsFromFlag)(flags.platform);
|
|
76
|
+
const { metricsMap, buildNumbersMap, updateIdsMap, totalEventCounts } = await (0, fetchMetrics_1.fetchObserveMetricsAsync)(graphqlClient, projectId, metricNames, platforms, startTime, endTime);
|
|
77
|
+
const argumentsStat = flags.stat?.length
|
|
78
|
+
? Array.from(new Set(flags.stat.map(formatMetrics_1.resolveStatKey)))
|
|
79
|
+
: undefined;
|
|
80
|
+
if (flags.json) {
|
|
81
|
+
const stats = argumentsStat ?? DEFAULT_STATS_JSON;
|
|
82
|
+
(0, json_1.printJsonOnlyOutput)((0, formatMetrics_1.buildObserveMetricsJson)(metricsMap, metricNames, stats, totalEventCounts, buildNumbersMap, updateIdsMap));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const stats = argumentsStat ?? DEFAULT_STATS_TABLE;
|
|
86
|
+
log_1.default.addNewLineIfNone();
|
|
87
|
+
log_1.default.log((0, formatMetrics_1.buildObserveMetricsTable)(metricsMap, metricNames, stats, {
|
|
88
|
+
daysBack,
|
|
89
|
+
buildNumbersMap,
|
|
90
|
+
totalEventCounts,
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.default = ObserveMetricsSummary;
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
2
|
export default class ObserveMetrics extends EasCommand {
|
|
3
|
-
static hidden: boolean;
|
|
4
3
|
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
metric: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
6
|
+
};
|
|
5
7
|
static flags: {
|
|
6
8
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
9
|
'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
10
|
'project-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
'update-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
'app-version': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
13
|
start: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
14
|
end: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
15
|
days: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined>;
|
|
17
|
+
after: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
18
|
platform: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
20
|
};
|
|
16
21
|
static contextDefinition: {
|
|
17
22
|
loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
|