eas-cli 18.10.0 → 18.12.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 +107 -102
- package/build/build/runBuildAndSubmit.d.ts +3 -1
- package/build/build/runBuildAndSubmit.js +12 -4
- package/build/build/utils/repository.js +8 -0
- package/build/build/validateLockfile.d.ts +1 -0
- package/build/build/validateLockfile.js +37 -0
- package/build/commandUtils/buildFlags.d.ts +1 -0
- package/build/commandUtils/buildFlags.js +18 -0
- package/build/commandUtils/convex.d.ts +1 -0
- package/build/commandUtils/convex.js +8 -2
- package/build/commands/build/dev.d.ts +1 -0
- package/build/commands/build/dev.js +12 -2
- package/build/commands/build/run.d.ts +1 -0
- package/build/commands/build/run.js +12 -3
- package/build/commands/integrations/convex/connect.d.ts +1 -0
- package/build/commands/integrations/convex/connect.js +65 -7
- package/build/commands/integrations/convex/team/invite.js +6 -1
- package/build/commands/observe/events.js +12 -24
- package/build/commands/observe/logs.d.ts +29 -0
- package/build/commands/observe/logs.js +163 -0
- package/build/commands/observe/metrics.js +11 -19
- package/build/commands/observe/versions.js +11 -19
- package/build/commands/simulator/start.js +85 -92
- package/build/commands/simulator/stop.js +1 -1
- package/build/graphql/generated.d.ts +290 -10
- package/build/graphql/generated.js +32 -3
- package/build/graphql/mutations/DeviceRunSessionMutation.d.ts +2 -2
- package/build/graphql/mutations/DeviceRunSessionMutation.js +4 -4
- package/build/graphql/queries/DeviceRunSessionQuery.js +8 -1
- package/build/graphql/queries/ObserveQuery.d.ts +21 -1
- package/build/graphql/queries/ObserveQuery.js +80 -0
- package/build/graphql/types/ConvexTeamConnection.d.ts +1 -1
- package/build/graphql/types/ConvexTeamConnection.js +1 -0
- package/build/graphql/types/Observe.d.ts +1 -0
- package/build/graphql/types/Observe.js +26 -1
- package/build/observe/fetchCustomEvents.d.ts +19 -0
- package/build/observe/fetchCustomEvents.js +21 -0
- package/build/observe/formatCustomEvents.d.ts +70 -0
- package/build/observe/formatCustomEvents.js +140 -0
- package/build/observe/formatEvents.js +5 -34
- package/build/observe/formatMetrics.js +2 -7
- package/build/observe/formatUtils.d.ts +27 -0
- package/build/observe/formatUtils.js +64 -0
- package/build/observe/formatVersions.js +2 -9
- package/build/observe/platforms.d.ts +21 -0
- package/build/observe/platforms.js +48 -0
- package/build/observe/resolveProjectContext.d.ts +22 -0
- package/build/observe/resolveProjectContext.js +21 -0
- package/build/run/ios/run.d.ts +2 -1
- package/build/run/ios/run.js +6 -2
- package/build/run/ios/simulator.d.ts +4 -1
- package/build/run/ios/simulator.js +14 -2
- package/build/run/run.d.ts +2 -1
- package/build/run/run.js +2 -2
- package/oclif.manifest.json +568 -375
- package/package.json +5 -5
|
@@ -13,10 +13,17 @@ exports.DeviceRunSessionQuery = {
|
|
|
13
13
|
byId(deviceRunSessionId: $deviceRunSessionId) {
|
|
14
14
|
id
|
|
15
15
|
status
|
|
16
|
+
type
|
|
17
|
+
remoteConfig {
|
|
18
|
+
__typename
|
|
19
|
+
... on AgentDeviceRunSessionRemoteConfig {
|
|
20
|
+
url
|
|
21
|
+
token
|
|
22
|
+
}
|
|
23
|
+
}
|
|
16
24
|
turtleJobRun {
|
|
17
25
|
id
|
|
18
26
|
status
|
|
19
|
-
logFileUrls
|
|
20
27
|
}
|
|
21
28
|
}
|
|
22
29
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
|
2
|
-
import { AppObserveAppVersion, AppObserveEvent, AppObserveEventsFilter, AppObserveEventsOrderBy, AppObservePlatform, AppObserveTimeSeriesStatistics, PageInfo } from '../generated';
|
|
2
|
+
import { AppObserveAppVersion, AppObserveCustomEvent, AppObserveCustomEventListFilter, AppObserveCustomEventName, AppObserveEvent, AppObserveEventsFilter, AppObserveEventsOrderBy, AppObservePlatform, AppObserveTimeSeriesStatistics, PageInfo } from '../generated';
|
|
3
3
|
export type AppObserveTimeSeriesResult = {
|
|
4
4
|
appVersionMarkers: AppObserveAppVersion[];
|
|
5
5
|
eventCount: number;
|
|
@@ -12,6 +12,12 @@ type AppObserveEventsQueryVariables = {
|
|
|
12
12
|
after?: string;
|
|
13
13
|
orderBy?: AppObserveEventsOrderBy;
|
|
14
14
|
};
|
|
15
|
+
type AppObserveCustomEventListQueryVariables = {
|
|
16
|
+
appId: string;
|
|
17
|
+
filter?: AppObserveCustomEventListFilter;
|
|
18
|
+
first?: number;
|
|
19
|
+
after?: string;
|
|
20
|
+
};
|
|
15
21
|
export declare const ObserveQuery: {
|
|
16
22
|
timeSeriesAsync(graphqlClient: ExpoGraphqlClient, { appId, metricName, platform, startTime, endTime, }: {
|
|
17
23
|
appId: string;
|
|
@@ -31,5 +37,19 @@ export declare const ObserveQuery: {
|
|
|
31
37
|
events: AppObserveEvent[];
|
|
32
38
|
pageInfo: PageInfo;
|
|
33
39
|
}>;
|
|
40
|
+
customEventListAsync(graphqlClient: ExpoGraphqlClient, variables: AppObserveCustomEventListQueryVariables): Promise<{
|
|
41
|
+
events: AppObserveCustomEvent[];
|
|
42
|
+
pageInfo: PageInfo;
|
|
43
|
+
}>;
|
|
44
|
+
customEventNamesAsync(graphqlClient: ExpoGraphqlClient, { appId, startTime, endTime, platform, environment, }: {
|
|
45
|
+
appId: string;
|
|
46
|
+
startTime: string;
|
|
47
|
+
endTime: string;
|
|
48
|
+
platform?: AppObservePlatform;
|
|
49
|
+
environment?: string;
|
|
50
|
+
}): Promise<{
|
|
51
|
+
names: AppObserveCustomEventName[];
|
|
52
|
+
isTruncated: boolean;
|
|
53
|
+
}>;
|
|
34
54
|
};
|
|
35
55
|
export {};
|
|
@@ -106,4 +106,84 @@ exports.ObserveQuery = {
|
|
|
106
106
|
pageInfo,
|
|
107
107
|
};
|
|
108
108
|
},
|
|
109
|
+
async customEventListAsync(graphqlClient, variables) {
|
|
110
|
+
const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
111
|
+
.query((0, graphql_tag_1.default) `
|
|
112
|
+
query AppObserveCustomEventList(
|
|
113
|
+
$appId: String!
|
|
114
|
+
$filter: AppObserveCustomEventListFilter
|
|
115
|
+
$first: Int
|
|
116
|
+
$after: String
|
|
117
|
+
) {
|
|
118
|
+
app {
|
|
119
|
+
byId(appId: $appId) {
|
|
120
|
+
id
|
|
121
|
+
observe {
|
|
122
|
+
customEventList(filter: $filter, first: $first, after: $after) {
|
|
123
|
+
pageInfo {
|
|
124
|
+
hasNextPage
|
|
125
|
+
hasPreviousPage
|
|
126
|
+
endCursor
|
|
127
|
+
}
|
|
128
|
+
edges {
|
|
129
|
+
cursor
|
|
130
|
+
node {
|
|
131
|
+
id
|
|
132
|
+
...AppObserveCustomEventFragment
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
${(0, graphql_1.print)(Observe_1.AppObserveCustomEventFragmentNode)}
|
|
141
|
+
`, variables)
|
|
142
|
+
.toPromise());
|
|
143
|
+
const { edges, pageInfo } = data.app.byId.observe.customEventList;
|
|
144
|
+
return {
|
|
145
|
+
events: edges.map(edge => edge.node),
|
|
146
|
+
pageInfo,
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
async customEventNamesAsync(graphqlClient, { appId, startTime, endTime, platform, environment, }) {
|
|
150
|
+
const data = await (0, client_1.withErrorHandlingAsync)(graphqlClient
|
|
151
|
+
.query((0, graphql_tag_1.default) `
|
|
152
|
+
query AppObserveCustomEventNames(
|
|
153
|
+
$appId: String!
|
|
154
|
+
$startTime: DateTime!
|
|
155
|
+
$endTime: DateTime!
|
|
156
|
+
$platform: AppObservePlatform
|
|
157
|
+
$environment: String
|
|
158
|
+
) {
|
|
159
|
+
app {
|
|
160
|
+
byId(appId: $appId) {
|
|
161
|
+
id
|
|
162
|
+
observe {
|
|
163
|
+
customEventNames(
|
|
164
|
+
startTime: $startTime
|
|
165
|
+
endTime: $endTime
|
|
166
|
+
platform: $platform
|
|
167
|
+
environment: $environment
|
|
168
|
+
) {
|
|
169
|
+
isTruncated
|
|
170
|
+
names {
|
|
171
|
+
eventName
|
|
172
|
+
count
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
`, {
|
|
180
|
+
appId,
|
|
181
|
+
startTime,
|
|
182
|
+
endTime,
|
|
183
|
+
...(platform && { platform }),
|
|
184
|
+
...(environment && { environment }),
|
|
185
|
+
})
|
|
186
|
+
.toPromise());
|
|
187
|
+
return data.app.byId.observe.customEventNames;
|
|
188
|
+
},
|
|
109
189
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConvexProject, ConvexTeamConnection, SetupConvexProjectResult } from '../generated';
|
|
2
|
-
export type ConvexTeamConnectionData = Pick<ConvexTeamConnection, 'id' | 'convexTeamIdentifier' | 'convexTeamName' | 'convexTeamSlug' | 'createdAt' | 'updatedAt' | 'invitedAt' | 'invitedEmail'>;
|
|
2
|
+
export type ConvexTeamConnectionData = Pick<ConvexTeamConnection, 'id' | 'convexTeamIdentifier' | 'convexTeamName' | 'convexTeamSlug' | 'hasBeenClaimed' | 'createdAt' | 'updatedAt' | 'invitedAt' | 'invitedEmail'>;
|
|
3
3
|
export type ConvexProjectData = Pick<ConvexProject, 'id' | 'convexProjectIdentifier' | 'convexProjectName' | 'convexProjectSlug' | 'createdAt' | 'updatedAt'> & {
|
|
4
4
|
convexTeamConnection: ConvexTeamConnectionData;
|
|
5
5
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare const AppObserveTimeSeriesFragmentNode: import("graphql").DocumentNode;
|
|
2
|
+
export declare const AppObserveCustomEventFragmentNode: import("graphql").DocumentNode;
|
|
2
3
|
export declare const AppObserveEventFragmentNode: import("graphql").DocumentNode;
|
|
3
4
|
export declare const AppObserveAppVersionFragmentNode: import("graphql").DocumentNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AppObserveAppVersionFragmentNode = exports.AppObserveEventFragmentNode = exports.AppObserveTimeSeriesFragmentNode = void 0;
|
|
3
|
+
exports.AppObserveAppVersionFragmentNode = exports.AppObserveEventFragmentNode = exports.AppObserveCustomEventFragmentNode = exports.AppObserveTimeSeriesFragmentNode = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const graphql_tag_1 = tslib_1.__importDefault(require("graphql-tag"));
|
|
6
6
|
exports.AppObserveTimeSeriesFragmentNode = (0, graphql_tag_1.default) `
|
|
@@ -20,6 +20,31 @@ exports.AppObserveTimeSeriesFragmentNode = (0, graphql_tag_1.default) `
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
`;
|
|
23
|
+
exports.AppObserveCustomEventFragmentNode = (0, graphql_tag_1.default) `
|
|
24
|
+
fragment AppObserveCustomEventFragment on AppObserveCustomEvent {
|
|
25
|
+
id
|
|
26
|
+
eventName
|
|
27
|
+
timestamp
|
|
28
|
+
sessionId
|
|
29
|
+
severityNumber
|
|
30
|
+
severityText
|
|
31
|
+
properties {
|
|
32
|
+
key
|
|
33
|
+
value
|
|
34
|
+
type
|
|
35
|
+
}
|
|
36
|
+
appVersion
|
|
37
|
+
appBuildNumber
|
|
38
|
+
appUpdateId
|
|
39
|
+
appEasBuildId
|
|
40
|
+
deviceOs
|
|
41
|
+
deviceOsVersion
|
|
42
|
+
deviceModel
|
|
43
|
+
environment
|
|
44
|
+
easClientId
|
|
45
|
+
countryCode
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
23
48
|
exports.AppObserveEventFragmentNode = (0, graphql_tag_1.default) `
|
|
24
49
|
fragment AppObserveEventFragment on AppObserveEvent {
|
|
25
50
|
id
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
|
2
|
+
import { AppObserveCustomEvent, AppObservePlatform, PageInfo } from '../graphql/generated';
|
|
3
|
+
interface FetchCustomEventsOptions {
|
|
4
|
+
eventName?: string;
|
|
5
|
+
limit: number;
|
|
6
|
+
after?: string;
|
|
7
|
+
startTime: string;
|
|
8
|
+
endTime: string;
|
|
9
|
+
platform?: AppObservePlatform;
|
|
10
|
+
appVersion?: string;
|
|
11
|
+
updateId?: string;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
}
|
|
14
|
+
interface FetchCustomEventsResult {
|
|
15
|
+
events: AppObserveCustomEvent[];
|
|
16
|
+
pageInfo: PageInfo;
|
|
17
|
+
}
|
|
18
|
+
export declare function fetchObserveCustomEventsAsync(graphqlClient: ExpoGraphqlClient, appId: string, options: FetchCustomEventsOptions): Promise<FetchCustomEventsResult>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchObserveCustomEventsAsync = fetchObserveCustomEventsAsync;
|
|
4
|
+
const ObserveQuery_1 = require("../graphql/queries/ObserveQuery");
|
|
5
|
+
async function fetchObserveCustomEventsAsync(graphqlClient, appId, options) {
|
|
6
|
+
const filter = {
|
|
7
|
+
startTime: options.startTime,
|
|
8
|
+
endTime: options.endTime,
|
|
9
|
+
...(options.eventName && { eventName: options.eventName }),
|
|
10
|
+
...(options.platform && { platform: options.platform }),
|
|
11
|
+
...(options.appVersion && { appVersion: options.appVersion }),
|
|
12
|
+
...(options.updateId && { appUpdateId: options.updateId }),
|
|
13
|
+
...(options.sessionId && { sessionId: options.sessionId }),
|
|
14
|
+
};
|
|
15
|
+
return await ObserveQuery_1.ObserveQuery.customEventListAsync(graphqlClient, {
|
|
16
|
+
appId,
|
|
17
|
+
filter,
|
|
18
|
+
first: options.limit,
|
|
19
|
+
...(options.after && { after: options.after }),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { AppObserveCustomEvent, AppObserveCustomEventName, PageInfo } from '../graphql/generated';
|
|
2
|
+
export interface ObserveCustomEventPropertyJson {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
type: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ObserveCustomEventJson {
|
|
8
|
+
id: string;
|
|
9
|
+
eventName: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
severityNumber: number | null;
|
|
13
|
+
severityText: string | null;
|
|
14
|
+
properties: ObserveCustomEventPropertyJson[];
|
|
15
|
+
appVersion: string;
|
|
16
|
+
appBuildNumber: string;
|
|
17
|
+
appUpdateId: string | null;
|
|
18
|
+
appEasBuildId: string | null;
|
|
19
|
+
deviceModel: string;
|
|
20
|
+
deviceOs: string;
|
|
21
|
+
deviceOsVersion: string;
|
|
22
|
+
countryCode: string | null;
|
|
23
|
+
environment: string | null;
|
|
24
|
+
easClientId: string;
|
|
25
|
+
}
|
|
26
|
+
export interface BuildCustomEventsTableOptions {
|
|
27
|
+
eventName?: string;
|
|
28
|
+
daysBack?: number;
|
|
29
|
+
startTime?: string;
|
|
30
|
+
endTime?: string;
|
|
31
|
+
totalEventCount?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function buildObserveCustomEventsTable(events: AppObserveCustomEvent[], pageInfo: PageInfo, options?: BuildCustomEventsTableOptions): string;
|
|
34
|
+
export declare function buildObserveCustomEventsJson(events: AppObserveCustomEvent[], pageInfo: PageInfo): {
|
|
35
|
+
events: ObserveCustomEventJson[];
|
|
36
|
+
pageInfo: {
|
|
37
|
+
hasNextPage: boolean;
|
|
38
|
+
endCursor: string | null;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export interface BuildEmptyCustomEventsWithSuggestionsOptions {
|
|
42
|
+
daysBack?: number;
|
|
43
|
+
startTime?: string;
|
|
44
|
+
endTime?: string;
|
|
45
|
+
isTruncated?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function buildObserveCustomEventsEmptyWithSuggestionsTable(eventName: string, names: AppObserveCustomEventName[], options?: BuildEmptyCustomEventsWithSuggestionsOptions): string;
|
|
48
|
+
export declare function buildObserveCustomEventsEmptyWithSuggestionsJson(eventName: string, names: AppObserveCustomEventName[], isTruncated: boolean): {
|
|
49
|
+
filteredEventName: string;
|
|
50
|
+
events: [];
|
|
51
|
+
availableEventNames: Array<{
|
|
52
|
+
eventName: string;
|
|
53
|
+
count: number;
|
|
54
|
+
}>;
|
|
55
|
+
availableEventNamesIsTruncated: boolean;
|
|
56
|
+
};
|
|
57
|
+
export interface BuildCustomEventNamesTableOptions {
|
|
58
|
+
daysBack?: number;
|
|
59
|
+
startTime?: string;
|
|
60
|
+
endTime?: string;
|
|
61
|
+
isTruncated?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export declare function buildObserveCustomEventNamesTable(names: AppObserveCustomEventName[], options?: BuildCustomEventNamesTableOptions): string;
|
|
64
|
+
export declare function buildObserveCustomEventNamesJson(names: AppObserveCustomEventName[], isTruncated: boolean): {
|
|
65
|
+
names: Array<{
|
|
66
|
+
eventName: string;
|
|
67
|
+
count: number;
|
|
68
|
+
}>;
|
|
69
|
+
isTruncated: boolean;
|
|
70
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildObserveCustomEventsTable = buildObserveCustomEventsTable;
|
|
4
|
+
exports.buildObserveCustomEventsJson = buildObserveCustomEventsJson;
|
|
5
|
+
exports.buildObserveCustomEventsEmptyWithSuggestionsTable = buildObserveCustomEventsEmptyWithSuggestionsTable;
|
|
6
|
+
exports.buildObserveCustomEventsEmptyWithSuggestionsJson = buildObserveCustomEventsEmptyWithSuggestionsJson;
|
|
7
|
+
exports.buildObserveCustomEventNamesTable = buildObserveCustomEventNamesTable;
|
|
8
|
+
exports.buildObserveCustomEventNamesJson = buildObserveCustomEventNamesJson;
|
|
9
|
+
const tslib_1 = require("tslib");
|
|
10
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
11
|
+
const renderTextTable_1 = tslib_1.__importDefault(require("../utils/renderTextTable"));
|
|
12
|
+
const formatUtils_1 = require("./formatUtils");
|
|
13
|
+
function formatSeverity(event) {
|
|
14
|
+
if (event.severityText) {
|
|
15
|
+
return event.severityText;
|
|
16
|
+
}
|
|
17
|
+
if (event.severityNumber != null) {
|
|
18
|
+
return String(event.severityNumber);
|
|
19
|
+
}
|
|
20
|
+
return '-';
|
|
21
|
+
}
|
|
22
|
+
function buildObserveCustomEventsTable(events, pageInfo, options) {
|
|
23
|
+
if (events.length === 0) {
|
|
24
|
+
return chalk_1.default.yellow('No custom events found.');
|
|
25
|
+
}
|
|
26
|
+
const showEventName = !options?.eventName;
|
|
27
|
+
const hasSeverity = events.some(e => e.severityText != null || e.severityNumber != null);
|
|
28
|
+
const headers = [
|
|
29
|
+
'Timestamp',
|
|
30
|
+
...(showEventName ? ['Event'] : []),
|
|
31
|
+
...(hasSeverity ? ['Severity'] : []),
|
|
32
|
+
'App Version',
|
|
33
|
+
'Platform',
|
|
34
|
+
'Device',
|
|
35
|
+
'Country',
|
|
36
|
+
];
|
|
37
|
+
const rows = events.map(event => [
|
|
38
|
+
(0, formatUtils_1.formatLogTimestamp)(event.timestamp),
|
|
39
|
+
...(showEventName ? [event.eventName] : []),
|
|
40
|
+
...(hasSeverity ? [formatSeverity(event)] : []),
|
|
41
|
+
`${event.appVersion} (${event.appBuildNumber})`,
|
|
42
|
+
`${event.deviceOs} ${event.deviceOsVersion}`,
|
|
43
|
+
event.deviceModel,
|
|
44
|
+
event.countryCode ?? '-',
|
|
45
|
+
]);
|
|
46
|
+
const lines = [];
|
|
47
|
+
if (options) {
|
|
48
|
+
const timeDesc = (0, formatUtils_1.buildTimeRangeDescription)(options);
|
|
49
|
+
const totalDesc = options.totalEventCount != null
|
|
50
|
+
? ` — ${options.totalEventCount.toLocaleString()} total events`
|
|
51
|
+
: '';
|
|
52
|
+
const subject = options.eventName ? `${options.eventName} events` : 'Custom events';
|
|
53
|
+
lines.push(chalk_1.default.bold(`${subject} ${timeDesc}${totalDesc}`.trim()), '');
|
|
54
|
+
}
|
|
55
|
+
lines.push((0, renderTextTable_1.default)(headers, rows));
|
|
56
|
+
if (pageInfo.hasNextPage && pageInfo.endCursor) {
|
|
57
|
+
lines.push('', `Next page: --after ${pageInfo.endCursor}`);
|
|
58
|
+
}
|
|
59
|
+
return lines.join('\n');
|
|
60
|
+
}
|
|
61
|
+
function buildObserveCustomEventsJson(events, pageInfo) {
|
|
62
|
+
return {
|
|
63
|
+
events: events.map(event => ({
|
|
64
|
+
id: event.id,
|
|
65
|
+
eventName: event.eventName,
|
|
66
|
+
timestamp: event.timestamp,
|
|
67
|
+
sessionId: event.sessionId ?? null,
|
|
68
|
+
severityNumber: event.severityNumber ?? null,
|
|
69
|
+
severityText: event.severityText ?? null,
|
|
70
|
+
properties: event.properties.map(p => ({
|
|
71
|
+
key: p.key,
|
|
72
|
+
value: p.value,
|
|
73
|
+
type: p.type,
|
|
74
|
+
})),
|
|
75
|
+
appVersion: event.appVersion,
|
|
76
|
+
appBuildNumber: event.appBuildNumber,
|
|
77
|
+
appUpdateId: event.appUpdateId ?? null,
|
|
78
|
+
appEasBuildId: event.appEasBuildId ?? null,
|
|
79
|
+
deviceModel: event.deviceModel,
|
|
80
|
+
deviceOs: event.deviceOs,
|
|
81
|
+
deviceOsVersion: event.deviceOsVersion,
|
|
82
|
+
countryCode: event.countryCode ?? null,
|
|
83
|
+
environment: event.environment ?? null,
|
|
84
|
+
easClientId: event.easClientId,
|
|
85
|
+
})),
|
|
86
|
+
pageInfo: {
|
|
87
|
+
hasNextPage: pageInfo.hasNextPage,
|
|
88
|
+
endCursor: pageInfo.endCursor ?? null,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function buildObserveCustomEventsEmptyWithSuggestionsTable(eventName, names, options) {
|
|
93
|
+
const lines = [];
|
|
94
|
+
const timeDesc = options ? (0, formatUtils_1.buildTimeRangeDescription)(options) : '';
|
|
95
|
+
lines.push(chalk_1.default.yellow(`No events found matching "${eventName}" ${timeDesc}.`.trim()));
|
|
96
|
+
if (names.length === 0) {
|
|
97
|
+
lines.push('', chalk_1.default.yellow('No custom event names found in this time range.'));
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
}
|
|
100
|
+
lines.push('', 'Available event names in this time range:', '');
|
|
101
|
+
const headers = ['Event Name', 'Count'];
|
|
102
|
+
const rows = names.map(n => [n.eventName, n.count.toLocaleString()]);
|
|
103
|
+
lines.push((0, renderTextTable_1.default)(headers, rows));
|
|
104
|
+
if (options?.isTruncated) {
|
|
105
|
+
lines.push('', chalk_1.default.yellow('Result is truncated; not all event names are shown.'));
|
|
106
|
+
}
|
|
107
|
+
return lines.join('\n');
|
|
108
|
+
}
|
|
109
|
+
function buildObserveCustomEventsEmptyWithSuggestionsJson(eventName, names, isTruncated) {
|
|
110
|
+
return {
|
|
111
|
+
filteredEventName: eventName,
|
|
112
|
+
events: [],
|
|
113
|
+
availableEventNames: names.map(n => ({ eventName: n.eventName, count: n.count })),
|
|
114
|
+
availableEventNamesIsTruncated: isTruncated,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function buildObserveCustomEventNamesTable(names, options) {
|
|
118
|
+
if (names.length === 0) {
|
|
119
|
+
return chalk_1.default.yellow('No custom event names found.');
|
|
120
|
+
}
|
|
121
|
+
const headers = ['Event Name', 'Count'];
|
|
122
|
+
const rows = names.map(n => [n.eventName, n.count.toLocaleString()]);
|
|
123
|
+
const lines = [];
|
|
124
|
+
if (options) {
|
|
125
|
+
const timeDesc = (0, formatUtils_1.buildTimeRangeDescription)(options);
|
|
126
|
+
const subject = 'Custom event names';
|
|
127
|
+
lines.push(chalk_1.default.bold(`${subject} ${timeDesc}`.trim()), '');
|
|
128
|
+
}
|
|
129
|
+
lines.push((0, renderTextTable_1.default)(headers, rows));
|
|
130
|
+
if (options?.isTruncated) {
|
|
131
|
+
lines.push('', chalk_1.default.yellow('Result is truncated; not all event names are shown.'));
|
|
132
|
+
}
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
function buildObserveCustomEventNamesJson(names, isTruncated) {
|
|
136
|
+
return {
|
|
137
|
+
names: names.map(n => ({ eventName: n.eventName, count: n.count })),
|
|
138
|
+
isTruncated,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -4,25 +4,9 @@ exports.buildObserveEventsTable = buildObserveEventsTable;
|
|
|
4
4
|
exports.buildObserveEventsJson = buildObserveEventsJson;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const renderTextTable_1 = tslib_1.__importDefault(require("../utils/renderTextTable"));
|
|
8
|
+
const formatUtils_1 = require("./formatUtils");
|
|
7
9
|
const metricNames_1 = require("./metricNames");
|
|
8
|
-
function formatTimestamp(isoString) {
|
|
9
|
-
const date = new Date(isoString);
|
|
10
|
-
return date.toLocaleDateString('en-US', {
|
|
11
|
-
year: 'numeric',
|
|
12
|
-
month: 'short',
|
|
13
|
-
day: 'numeric',
|
|
14
|
-
hour: '2-digit',
|
|
15
|
-
minute: '2-digit',
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
function formatDate(isoString) {
|
|
19
|
-
const date = new Date(isoString);
|
|
20
|
-
return date.toLocaleDateString('en-US', {
|
|
21
|
-
year: 'numeric',
|
|
22
|
-
month: 'short',
|
|
23
|
-
day: 'numeric',
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
10
|
function resolveCustomParams(event) {
|
|
27
11
|
return event.customParams ?? null;
|
|
28
12
|
}
|
|
@@ -47,31 +31,18 @@ function buildObserveEventsTable(events, pageInfo, options) {
|
|
|
47
31
|
`${event.deviceOs} ${event.deviceOsVersion}`,
|
|
48
32
|
event.deviceModel,
|
|
49
33
|
event.countryCode ?? '-',
|
|
50
|
-
formatTimestamp(event.timestamp),
|
|
34
|
+
(0, formatUtils_1.formatTimestamp)(event.timestamp),
|
|
51
35
|
]);
|
|
52
|
-
const colWidths = headers.map((h, i) => Math.max(h.length, ...rows.map(r => r[i].length)));
|
|
53
|
-
const headerLine = headers.map((h, i) => h.padEnd(colWidths[i])).join(' ');
|
|
54
|
-
const separatorLine = colWidths.map(w => '-'.repeat(w)).join(' ');
|
|
55
|
-
const dataLines = rows.map(row => row.map((cell, i) => cell.padEnd(colWidths[i])).join(' '));
|
|
56
36
|
const lines = [];
|
|
57
37
|
if (options) {
|
|
58
38
|
const metricDisplay = (0, metricNames_1.getMetricDisplayName)(options.metricName);
|
|
59
|
-
|
|
60
|
-
if (options.daysBack) {
|
|
61
|
-
timeDesc = `for the last ${options.daysBack} days`;
|
|
62
|
-
}
|
|
63
|
-
else if (options.startTime && options.endTime) {
|
|
64
|
-
timeDesc = `from ${formatDate(options.startTime)} to ${formatDate(options.endTime)}`;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
timeDesc = '';
|
|
68
|
-
}
|
|
39
|
+
const timeDesc = (0, formatUtils_1.buildTimeRangeDescription)(options);
|
|
69
40
|
const totalDesc = options.totalEventCount != null
|
|
70
41
|
? ` — ${options.totalEventCount.toLocaleString()} total events`
|
|
71
42
|
: '';
|
|
72
43
|
lines.push(chalk_1.default.bold(`${metricDisplay} events ${timeDesc}${totalDesc}`.trim()), '');
|
|
73
44
|
}
|
|
74
|
-
lines.push(
|
|
45
|
+
lines.push((0, renderTextTable_1.default)(headers, rows));
|
|
75
46
|
if (pageInfo.hasNextPage && pageInfo.endCursor) {
|
|
76
47
|
lines.push('', `Next page: --after ${pageInfo.endCursor}`);
|
|
77
48
|
}
|
|
@@ -10,6 +10,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
|
10
10
|
const errors_1 = require("../commandUtils/errors");
|
|
11
11
|
const platform_1 = require("../platform");
|
|
12
12
|
const renderTextTable_1 = tslib_1.__importDefault(require("../utils/renderTextTable"));
|
|
13
|
+
const formatUtils_1 = require("./formatUtils");
|
|
13
14
|
const metricNames_1 = require("./metricNames");
|
|
14
15
|
exports.STAT_ALIASES = {
|
|
15
16
|
min: 'min',
|
|
@@ -105,12 +106,6 @@ function buildObserveMetricsJson(metricsMap, metricNames, stats, totalEventCount
|
|
|
105
106
|
function buildStatsDescription(displayStats) {
|
|
106
107
|
return displayStats.map(s => exports.STAT_DISPLAY_NAMES[s]).join(', ');
|
|
107
108
|
}
|
|
108
|
-
function buildTimeRangeDescription(daysBack) {
|
|
109
|
-
if (daysBack) {
|
|
110
|
-
return `for the last ${daysBack} days`;
|
|
111
|
-
}
|
|
112
|
-
return '';
|
|
113
|
-
}
|
|
114
109
|
function buildObserveMetricsTable(metricsMap, metricNames, stats, options) {
|
|
115
110
|
const { versions: results } = buildObserveMetricsJson(metricsMap, metricNames, stats);
|
|
116
111
|
if (results.length === 0) {
|
|
@@ -120,7 +115,7 @@ function buildObserveMetricsTable(metricsMap, metricNames, stats, options) {
|
|
|
120
115
|
const hasEventCount = stats.includes('eventCount');
|
|
121
116
|
// Build summary header
|
|
122
117
|
const statsDesc = displayStats.length > 0 ? buildStatsDescription(displayStats) : 'Event count';
|
|
123
|
-
const timeDesc = buildTimeRangeDescription(options?.daysBack);
|
|
118
|
+
const timeDesc = (0, formatUtils_1.buildTimeRangeDescription)({ daysBack: options?.daysBack });
|
|
124
119
|
const countSuffix = hasEventCount && displayStats.length > 0 ? ' (event count)' : '';
|
|
125
120
|
const summaryLine = `${statsDesc} values${countSuffix}${timeDesc ? ` ${timeDesc}` : ''}`;
|
|
126
121
|
// Group results by platform
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format an ISO timestamp for display in event tables (minute precision).
|
|
3
|
+
* Uses the runtime's default locale.
|
|
4
|
+
*/
|
|
5
|
+
export declare function formatTimestamp(isoString: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Format an ISO timestamp for display in log tables (millisecond precision).
|
|
8
|
+
* Use this instead of formatTimestamp when the table represents individual
|
|
9
|
+
* log entries where sub-minute resolution matters. Uses the runtime's
|
|
10
|
+
* default locale.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatLogTimestamp(isoString: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format an ISO timestamp for display as a date only (no time). Uses the
|
|
15
|
+
* runtime's default locale.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatDate(isoString: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Build the time-range fragment used in summary headers, e.g.
|
|
20
|
+
* "for the last 7 days" or "from Jan 1, 2025 to Feb 1, 2025".
|
|
21
|
+
* Returns an empty string when no range information is provided.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildTimeRangeDescription(options: {
|
|
24
|
+
daysBack?: number;
|
|
25
|
+
startTime?: string;
|
|
26
|
+
endTime?: string;
|
|
27
|
+
}): string;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatTimestamp = formatTimestamp;
|
|
4
|
+
exports.formatLogTimestamp = formatLogTimestamp;
|
|
5
|
+
exports.formatDate = formatDate;
|
|
6
|
+
exports.buildTimeRangeDescription = buildTimeRangeDescription;
|
|
7
|
+
/**
|
|
8
|
+
* Format an ISO timestamp for display in event tables (minute precision).
|
|
9
|
+
* Uses the runtime's default locale.
|
|
10
|
+
*/
|
|
11
|
+
function formatTimestamp(isoString) {
|
|
12
|
+
const date = new Date(isoString);
|
|
13
|
+
return date.toLocaleDateString(undefined, {
|
|
14
|
+
year: 'numeric',
|
|
15
|
+
month: 'short',
|
|
16
|
+
day: 'numeric',
|
|
17
|
+
hour: '2-digit',
|
|
18
|
+
minute: '2-digit',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Format an ISO timestamp for display in log tables (millisecond precision).
|
|
23
|
+
* Use this instead of formatTimestamp when the table represents individual
|
|
24
|
+
* log entries where sub-minute resolution matters. Uses the runtime's
|
|
25
|
+
* default locale.
|
|
26
|
+
*/
|
|
27
|
+
function formatLogTimestamp(isoString) {
|
|
28
|
+
const date = new Date(isoString);
|
|
29
|
+
return date.toLocaleDateString(undefined, {
|
|
30
|
+
year: 'numeric',
|
|
31
|
+
month: 'short',
|
|
32
|
+
day: 'numeric',
|
|
33
|
+
hour: '2-digit',
|
|
34
|
+
minute: '2-digit',
|
|
35
|
+
second: '2-digit',
|
|
36
|
+
fractionalSecondDigits: 3,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format an ISO timestamp for display as a date only (no time). Uses the
|
|
41
|
+
* runtime's default locale.
|
|
42
|
+
*/
|
|
43
|
+
function formatDate(isoString) {
|
|
44
|
+
const date = new Date(isoString);
|
|
45
|
+
return date.toLocaleDateString(undefined, {
|
|
46
|
+
year: 'numeric',
|
|
47
|
+
month: 'short',
|
|
48
|
+
day: 'numeric',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build the time-range fragment used in summary headers, e.g.
|
|
53
|
+
* "for the last 7 days" or "from Jan 1, 2025 to Feb 1, 2025".
|
|
54
|
+
* Returns an empty string when no range information is provided.
|
|
55
|
+
*/
|
|
56
|
+
function buildTimeRangeDescription(options) {
|
|
57
|
+
if (options.daysBack) {
|
|
58
|
+
return `for the last ${options.daysBack} days`;
|
|
59
|
+
}
|
|
60
|
+
if (options.startTime && options.endTime) {
|
|
61
|
+
return `from ${formatDate(options.startTime)} to ${formatDate(options.endTime)}`;
|
|
62
|
+
}
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
@@ -6,14 +6,7 @@ const tslib_1 = require("tslib");
|
|
|
6
6
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
7
|
const platform_1 = require("../platform");
|
|
8
8
|
const renderTextTable_1 = tslib_1.__importDefault(require("../utils/renderTextTable"));
|
|
9
|
-
|
|
10
|
-
const date = new Date(isoString);
|
|
11
|
-
return date.toLocaleDateString('en-US', {
|
|
12
|
-
year: 'numeric',
|
|
13
|
-
month: 'short',
|
|
14
|
-
day: 'numeric',
|
|
15
|
-
});
|
|
16
|
-
}
|
|
9
|
+
const formatUtils_1 = require("./formatUtils");
|
|
17
10
|
function mapEasBuilds(easBuilds) {
|
|
18
11
|
return easBuilds.map(b => ({
|
|
19
12
|
easBuildId: b.easBuildId,
|
|
@@ -74,7 +67,7 @@ function buildObserveVersionsTable(results) {
|
|
|
74
67
|
sections.push(chalk_1.default.bold(platform_1.appPlatformDisplayNames[platform]));
|
|
75
68
|
const rows = appVersions.map(version => [
|
|
76
69
|
version.appVersion,
|
|
77
|
-
formatDate(version.firstSeenAt),
|
|
70
|
+
(0, formatUtils_1.formatDate)(version.firstSeenAt),
|
|
78
71
|
String(version.eventCount),
|
|
79
72
|
String(version.uniqueUserCount),
|
|
80
73
|
String(version.buildNumbers.length),
|