eas-cli 19.0.6 → 19.0.7

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.
@@ -0,0 +1,19 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ export default class SimulatorList extends EasCommand {
3
+ static hidden: boolean;
4
+ static description: string;
5
+ static flags: {
6
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ status: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ type: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined>;
12
+ after: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ };
14
+ static contextDefinition: {
15
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
16
+ projectId: import("../../commandUtils/context/ProjectIdContextField").ProjectIdContextField;
17
+ };
18
+ runAsync(): Promise<void>;
19
+ }
@@ -0,0 +1,146 @@
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 chalk_1 = tslib_1.__importDefault(require("chalk"));
6
+ const url_1 = require("../../build/utils/url");
7
+ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
8
+ const flags_1 = require("../../commandUtils/flags");
9
+ const pagination_1 = require("../../commandUtils/pagination");
10
+ const generated_1 = require("../../graphql/generated");
11
+ const DeviceRunSessionQuery_1 = require("../../graphql/queries/DeviceRunSessionQuery");
12
+ const log_1 = tslib_1.__importStar(require("../../log"));
13
+ const ora_1 = require("../../ora");
14
+ const utils_1 = require("../../simulator/utils");
15
+ const date_1 = require("../../utils/date");
16
+ const json_1 = require("../../utils/json");
17
+ const DEFAULT_LIMIT = 10;
18
+ const MAX_LIMIT = 100;
19
+ const STATUS_FLAG_VALUES = {
20
+ [generated_1.DeviceRunSessionStatus.New]: 'new',
21
+ [generated_1.DeviceRunSessionStatus.InProgress]: 'in-progress',
22
+ [generated_1.DeviceRunSessionStatus.Stopped]: 'stopped',
23
+ [generated_1.DeviceRunSessionStatus.Errored]: 'errored',
24
+ };
25
+ const STATUS_BY_FLAG_VALUE = Object.fromEntries(Object.entries(STATUS_FLAG_VALUES).map(([status, value]) => [
26
+ value,
27
+ status,
28
+ ]));
29
+ const PLATFORM_FLAG_VALUES = {
30
+ [generated_1.AppPlatform.Android]: 'android',
31
+ [generated_1.AppPlatform.Ios]: 'ios',
32
+ };
33
+ const PLATFORM_BY_FLAG_VALUE = Object.fromEntries(Object.entries(PLATFORM_FLAG_VALUES).map(([platform, value]) => [value, platform]));
34
+ class SimulatorList extends EasCommand_1.default {
35
+ static hidden = true;
36
+ static description = '[EXPERIMENTAL] list remote simulator sessions for the current project';
37
+ static flags = {
38
+ status: core_1.Flags.option({
39
+ description: 'Filter by session status (repeatable)',
40
+ options: Object.values(STATUS_FLAG_VALUES),
41
+ multiple: true,
42
+ })(),
43
+ type: core_1.Flags.option({
44
+ description: 'Filter by session type (repeatable)',
45
+ options: Object.values(utils_1.DEVICE_RUN_SESSION_TYPE_FLAG_VALUES),
46
+ multiple: true,
47
+ })(),
48
+ platform: core_1.Flags.option({
49
+ description: 'Filter by device platform (repeatable)',
50
+ options: Object.values(PLATFORM_FLAG_VALUES),
51
+ multiple: true,
52
+ })(),
53
+ limit: (0, pagination_1.getLimitFlagWithCustomValues)({ defaultTo: DEFAULT_LIMIT, limit: MAX_LIMIT }),
54
+ after: core_1.Flags.string({
55
+ description: 'Cursor for pagination. Use the endCursor from a previous query to fetch the next page.',
56
+ }),
57
+ ...flags_1.EasNonInteractiveAndJsonFlags,
58
+ };
59
+ static contextDefinition = {
60
+ ...this.ContextOptions.ProjectId,
61
+ ...this.ContextOptions.LoggedIn,
62
+ };
63
+ async runAsync() {
64
+ const { flags } = await this.parse(SimulatorList);
65
+ const { json: jsonFlag, nonInteractive } = (0, flags_1.resolveNonInteractiveAndJsonFlags)(flags);
66
+ if (jsonFlag) {
67
+ (0, json_1.enableJsonOutput)();
68
+ }
69
+ const { projectId, loggedIn: { graphqlClient }, } = await this.getContextAsync(SimulatorList, {
70
+ nonInteractive,
71
+ });
72
+ const filter = {};
73
+ if (flags.status && flags.status.length > 0) {
74
+ filter.statuses = flags.status.map(value => STATUS_BY_FLAG_VALUE[value]);
75
+ }
76
+ if (flags.type && flags.type.length > 0) {
77
+ filter.types = flags.type.map(value => utils_1.DEVICE_RUN_SESSION_TYPE_BY_FLAG_VALUE[value]);
78
+ }
79
+ if (flags.platform && flags.platform.length > 0) {
80
+ filter.platforms = flags.platform.map(value => PLATFORM_BY_FLAG_VALUE[value]);
81
+ }
82
+ const limit = flags.limit ?? DEFAULT_LIMIT;
83
+ const fetchSpinner = jsonFlag ? null : (0, ora_1.ora)('Fetching device run sessions').start();
84
+ let connection;
85
+ try {
86
+ connection = await DeviceRunSessionQuery_1.DeviceRunSessionQuery.listByAppIdAsync(graphqlClient, {
87
+ appId: projectId,
88
+ first: limit,
89
+ after: flags.after,
90
+ filter: Object.keys(filter).length > 0 ? filter : undefined,
91
+ });
92
+ fetchSpinner?.succeed(`Fetched ${connection.edges.length} device run session(s)`);
93
+ }
94
+ catch (err) {
95
+ fetchSpinner?.fail('Failed to fetch device run sessions');
96
+ throw err;
97
+ }
98
+ const sessions = connection.edges.map(edge => edge.node);
99
+ if (jsonFlag) {
100
+ (0, json_1.printJsonOnlyOutput)({
101
+ sessions: sessions.map(session => ({
102
+ id: session.id,
103
+ type: (0, utils_1.deviceRunSessionTypeToFlagValue)(session.type),
104
+ status: session.status,
105
+ platform: session.platform,
106
+ createdAt: session.createdAt,
107
+ startedAt: session.startedAt ?? undefined,
108
+ finishedAt: session.finishedAt ?? undefined,
109
+ jobRunUrl: session.turtleJobRun
110
+ ? (0, url_1.getBareJobRunUrl)(session.app.ownerAccount.name, session.app.slug, session.turtleJobRun.id)
111
+ : undefined,
112
+ })),
113
+ pageInfo: connection.pageInfo,
114
+ });
115
+ return;
116
+ }
117
+ if (sessions.length === 0) {
118
+ log_1.default.newLine();
119
+ log_1.default.log('No device run sessions found.');
120
+ return;
121
+ }
122
+ log_1.default.newLine();
123
+ const formattedEntries = sessions.map(session => {
124
+ const jobRunUrl = session.turtleJobRun
125
+ ? (0, url_1.getBareJobRunUrl)(session.app.ownerAccount.name, session.app.slug, session.turtleJobRun.id)
126
+ : null;
127
+ const lines = [
128
+ `ID: ${session.id}`,
129
+ `Type: ${session.type}`,
130
+ `Status: ${session.status}`,
131
+ `Platform: ${session.platform}`,
132
+ `Created: ${(0, date_1.fromNow)(new Date(session.createdAt))} ago`,
133
+ ];
134
+ if (jobRunUrl) {
135
+ lines.push(`URL: ${(0, log_1.link)(jobRunUrl)}`);
136
+ }
137
+ return lines.join('\n');
138
+ });
139
+ log_1.default.log(formattedEntries.join(`\n\n${chalk_1.default.dim('———')}\n\n`));
140
+ if (connection.pageInfo.hasNextPage && connection.pageInfo.endCursor) {
141
+ log_1.default.newLine();
142
+ log_1.default.log(`More results available. Re-run with --after ${connection.pageInfo.endCursor} to fetch the next page.`);
143
+ }
144
+ }
145
+ }
146
+ exports.default = SimulatorList;
@@ -1291,6 +1291,7 @@ export type App = Project & {
1291
1291
  /** @deprecated Classic updates have been deprecated. */
1292
1292
  description: Scalars['String']['output'];
1293
1293
  devDomainName?: Maybe<AppDevDomainName>;
1294
+ deviceRunSessionsPaginated: AppDeviceRunSessionsConnection;
1294
1295
  /** Environment secrets for an app */
1295
1296
  environmentSecrets: Array<EnvironmentSecret>;
1296
1297
  environmentVariableEnvironments: Array<Scalars['EnvironmentVariableEnvironment']['output']>;
@@ -1502,6 +1503,14 @@ export type AppDeploymentsArgs = {
1502
1503
  last?: InputMaybe<Scalars['Int']['input']>;
1503
1504
  };
1504
1505
  /** Represents an Exponent App (or Experience in legacy terms) */
1506
+ export type AppDeviceRunSessionsPaginatedArgs = {
1507
+ after?: InputMaybe<Scalars['String']['input']>;
1508
+ before?: InputMaybe<Scalars['String']['input']>;
1509
+ filter?: InputMaybe<DeviceRunSessionFilterInput>;
1510
+ first?: InputMaybe<Scalars['Int']['input']>;
1511
+ last?: InputMaybe<Scalars['Int']['input']>;
1512
+ };
1513
+ /** Represents an Exponent App (or Experience in legacy terms) */
1505
1514
  export type AppEnvironmentSecretsArgs = {
1506
1515
  filterNames?: InputMaybe<Array<Scalars['String']['input']>>;
1507
1516
  };
@@ -1741,6 +1750,16 @@ export type AppDevDomainNameMutationChangeDevDomainNameArgs = {
1741
1750
  appId: Scalars['ID']['input'];
1742
1751
  name: Scalars['DevDomainName']['input'];
1743
1752
  };
1753
+ export type AppDeviceRunSessionEdge = {
1754
+ __typename?: 'AppDeviceRunSessionEdge';
1755
+ cursor: Scalars['String']['output'];
1756
+ node: DeviceRunSession;
1757
+ };
1758
+ export type AppDeviceRunSessionsConnection = {
1759
+ __typename?: 'AppDeviceRunSessionsConnection';
1760
+ edges: Array<AppDeviceRunSessionEdge>;
1761
+ pageInfo: PageInfo;
1762
+ };
1744
1763
  export type AppFingerprintEdge = {
1745
1764
  __typename?: 'AppFingerprintEdge';
1746
1765
  cursor: Scalars['String']['output'];
@@ -1924,6 +1943,11 @@ export type AppObserveAppBuildEmbeddedSummary = {
1924
1943
  __typename?: 'AppObserveAppBuildEmbeddedSummary';
1925
1944
  eventCount: Scalars['Int']['output'];
1926
1945
  firstSeenAt: Scalars['DateTime']['output'];
1946
+ /**
1947
+ * Unique users whose most recent supported-metric event in the queried
1948
+ * range ran this build's embedded bundle.
1949
+ */
1950
+ lastSeenUserCount: Scalars['Int']['output'];
1927
1951
  uniqueUserCount: Scalars['Int']['output'];
1928
1952
  };
1929
1953
  export type AppObserveAppBuildNumber = {
@@ -1938,7 +1962,18 @@ export type AppObserveAppBuildNumber = {
1938
1962
  embedded?: Maybe<AppObserveAppBuildEmbeddedSummary>;
1939
1963
  eventCount: Scalars['Int']['output'];
1940
1964
  firstSeenAt: Scalars['DateTime']['output'];
1965
+ /**
1966
+ * Unique users whose most recent supported-metric event in the queried
1967
+ * range was on this (appVersion, appBuildNumber) tuple.
1968
+ */
1969
+ lastSeenUserCount: Scalars['Int']['output'];
1941
1970
  uniqueUserCount: Scalars['Int']['output'];
1971
+ /**
1972
+ * Updates seen on this build number in the queried time range. Each
1973
+ * entry's counts and EAS builds are scoped to this (appVersion,
1974
+ * appBuildNumber, appUpdateId) tuple.
1975
+ */
1976
+ updates: Array<AppObserveAppUpdate>;
1942
1977
  };
1943
1978
  export type AppObserveAppEasBuild = {
1944
1979
  __typename?: 'AppObserveAppEasBuild';
@@ -1954,6 +1989,11 @@ export type AppObserveAppUpdate = {
1954
1989
  easBuilds: Array<AppObserveAppEasBuild>;
1955
1990
  eventCount: Scalars['Int']['output'];
1956
1991
  firstSeenAt: Scalars['DateTime']['output'];
1992
+ /**
1993
+ * Unique users whose most recent supported-metric event in the queried
1994
+ * range matched this update at its current nesting level.
1995
+ */
1996
+ lastSeenUserCount: Scalars['Int']['output'];
1957
1997
  uniqueUserCount: Scalars['Int']['output'];
1958
1998
  };
1959
1999
  export type AppObserveAppVersion = {
@@ -4474,6 +4514,11 @@ export type DeviceRunSession = {
4474
4514
  type: DeviceRunSessionType;
4475
4515
  updatedAt: Scalars['DateTime']['output'];
4476
4516
  };
4517
+ export type DeviceRunSessionFilterInput = {
4518
+ platforms?: InputMaybe<Array<AppPlatform>>;
4519
+ statuses?: InputMaybe<Array<DeviceRunSessionStatus>>;
4520
+ types?: InputMaybe<Array<DeviceRunSessionType>>;
4521
+ };
4477
4522
  export type DeviceRunSessionMutation = {
4478
4523
  __typename?: 'DeviceRunSessionMutation';
4479
4524
  /** Create a device run session */
@@ -16959,6 +17004,61 @@ export type DeviceRunSessionByIdQuery = {
16959
17004
  };
16960
17005
  };
16961
17006
  };
17007
+ export type DeviceRunSessionsByAppIdQueryVariables = Exact<{
17008
+ appId: Scalars['String']['input'];
17009
+ first?: InputMaybe<Scalars['Int']['input']>;
17010
+ after?: InputMaybe<Scalars['String']['input']>;
17011
+ filter?: InputMaybe<DeviceRunSessionFilterInput>;
17012
+ }>;
17013
+ export type DeviceRunSessionsByAppIdQuery = {
17014
+ __typename?: 'RootQuery';
17015
+ app: {
17016
+ __typename?: 'AppQuery';
17017
+ byId: {
17018
+ __typename?: 'App';
17019
+ id: string;
17020
+ deviceRunSessionsPaginated: {
17021
+ __typename?: 'AppDeviceRunSessionsConnection';
17022
+ edges: Array<{
17023
+ __typename?: 'AppDeviceRunSessionEdge';
17024
+ cursor: string;
17025
+ node: {
17026
+ __typename?: 'DeviceRunSession';
17027
+ id: string;
17028
+ status: DeviceRunSessionStatus;
17029
+ type: DeviceRunSessionType;
17030
+ platform: AppPlatform;
17031
+ createdAt: any;
17032
+ startedAt?: any | null;
17033
+ finishedAt?: any | null;
17034
+ app: {
17035
+ __typename?: 'App';
17036
+ id: string;
17037
+ slug: string;
17038
+ ownerAccount: {
17039
+ __typename?: 'Account';
17040
+ id: string;
17041
+ name: string;
17042
+ };
17043
+ };
17044
+ turtleJobRun?: {
17045
+ __typename?: 'JobRun';
17046
+ id: string;
17047
+ status: JobRunStatus;
17048
+ } | null;
17049
+ };
17050
+ }>;
17051
+ pageInfo: {
17052
+ __typename?: 'PageInfo';
17053
+ hasNextPage: boolean;
17054
+ hasPreviousPage: boolean;
17055
+ startCursor?: string | null;
17056
+ endCursor?: string | null;
17057
+ };
17058
+ };
17059
+ };
17060
+ };
17061
+ };
16962
17062
  export type EnvironmentSecretsByAppIdQueryVariables = Exact<{
16963
17063
  appId: Scalars['String']['input'];
16964
17064
  }>;
@@ -1,5 +1,11 @@
1
1
  import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
2
- import { DeviceRunSessionByIdQuery } from '../generated';
2
+ import { DeviceRunSessionByIdQuery, DeviceRunSessionFilterInput, DeviceRunSessionsByAppIdQuery } from '../generated';
3
3
  export declare const DeviceRunSessionQuery: {
4
4
  byIdAsync(graphqlClient: ExpoGraphqlClient, deviceRunSessionId: string): Promise<DeviceRunSessionByIdQuery["deviceRunSessions"]["byId"]>;
5
+ listByAppIdAsync(graphqlClient: ExpoGraphqlClient, { appId, first, after, filter, }: {
6
+ appId: string;
7
+ first?: number;
8
+ after?: string;
9
+ filter?: DeviceRunSessionFilterInput;
10
+ }): Promise<DeviceRunSessionsByAppIdQuery["app"]["byId"]["deviceRunSessionsPaginated"]>;
5
11
  };
@@ -49,4 +49,55 @@ exports.DeviceRunSessionQuery = {
49
49
  .toPromise());
50
50
  return data.deviceRunSessions.byId;
51
51
  },
52
+ async listByAppIdAsync(graphqlClient, { appId, first, after, filter, }) {
53
+ const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
54
+ .query((0, graphql_tag_1.default) `
55
+ query DeviceRunSessionsByAppId(
56
+ $appId: String!
57
+ $first: Int
58
+ $after: String
59
+ $filter: DeviceRunSessionFilterInput
60
+ ) {
61
+ app {
62
+ byId(appId: $appId) {
63
+ id
64
+ deviceRunSessionsPaginated(first: $first, after: $after, filter: $filter) {
65
+ edges {
66
+ cursor
67
+ node {
68
+ id
69
+ status
70
+ type
71
+ platform
72
+ createdAt
73
+ startedAt
74
+ finishedAt
75
+ app {
76
+ id
77
+ slug
78
+ ownerAccount {
79
+ id
80
+ name
81
+ }
82
+ }
83
+ turtleJobRun {
84
+ id
85
+ status
86
+ }
87
+ }
88
+ }
89
+ pageInfo {
90
+ hasNextPage
91
+ hasPreviousPage
92
+ startCursor
93
+ endCursor
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ `, { appId, first, after, filter }, { requestPolicy: 'network-only' })
100
+ .toPromise());
101
+ return data.app.byId.deviceRunSessionsPaginated;
102
+ },
52
103
  };