shipthis 0.1.28 → 0.1.30

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 (75) hide show
  1. package/dist/{AppleBundleIdDetails-CY13Z5I8.js → AppleBundleIdDetails-Fp5COwTa.js} +4 -4
  2. package/dist/{Command-CeGf4miL.js → Command-1p5alCz3.js} +2 -2
  3. package/dist/{CommandGame-IYChs1fH.js → CommandGame-Z4eUQBjn.js} +2 -2
  4. package/dist/{Create-C2rBb6bV.js → Create-1xAdntNl.js} +3 -3
  5. package/dist/{Import-BPZCr3jP.js → Import-CzC-M4ln.js} +4 -4
  6. package/dist/{JobStatusTable-lbvEKRYC.js → JobLogTail-CZxoMSd5.js} +84 -71
  7. package/dist/{JobProgress-DMrbHnBR.js → JobProgress-BjNgtIjm.js} +8 -20
  8. package/dist/JobStatusTable-BB-PWlwj.js +66 -0
  9. package/dist/{ProjectCredentialsTable-BfGWOTBf.js → ProjectCredentialsTable-DyZep993.js} +2 -2
  10. package/dist/{UserCredentialsTable-DtZ3eqnN.js → UserCredentialsTable-BraKyDWT.js} +3 -3
  11. package/dist/{baseAppleCommand-DOUAN8L8.js → baseAppleCommand-BHRIBtTj.js} +1 -1
  12. package/dist/{baseGameAndroidCommand-C_rLCJ2y.js → baseGameAndroidCommand-SrDRbhAG.js} +2 -2
  13. package/dist/commands/apple/apiKey/create.js +8 -8
  14. package/dist/commands/apple/apiKey/export.js +7 -7
  15. package/dist/commands/apple/apiKey/import.js +7 -7
  16. package/dist/commands/apple/apiKey/status.js +6 -6
  17. package/dist/commands/apple/certificate/create.js +8 -8
  18. package/dist/commands/apple/certificate/export.js +7 -7
  19. package/dist/commands/apple/certificate/import.js +7 -7
  20. package/dist/commands/apple/certificate/status.js +6 -6
  21. package/dist/commands/apple/login.js +2 -2
  22. package/dist/commands/apple/status.js +5 -5
  23. package/dist/commands/dashboard.js +1 -1
  24. package/dist/commands/game/android/apiKey/connect.js +9 -9
  25. package/dist/commands/game/android/apiKey/create.js +11 -11
  26. package/dist/commands/game/android/apiKey/export.js +8 -8
  27. package/dist/commands/game/android/apiKey/import.js +8 -8
  28. package/dist/commands/game/android/apiKey/invite.js +4 -4
  29. package/dist/commands/game/android/apiKey/status.js +8 -8
  30. package/dist/commands/game/android/keyStore/create.js +9 -9
  31. package/dist/commands/game/android/keyStore/export.js +7 -7
  32. package/dist/commands/game/android/keyStore/import.js +10 -10
  33. package/dist/commands/game/android/keyStore/status.js +7 -7
  34. package/dist/commands/game/android/status.js +5 -5
  35. package/dist/commands/game/build/download.js +5 -5
  36. package/dist/commands/game/build/list.js +6 -6
  37. package/dist/commands/game/create.js +2 -2
  38. package/dist/commands/game/details.js +5 -5
  39. package/dist/commands/game/export.js +1 -1
  40. package/dist/commands/game/ios/app/addTester.js +6 -6
  41. package/dist/commands/game/ios/app/create.js +5 -5
  42. package/dist/commands/game/ios/app/status.js +8 -8
  43. package/dist/commands/game/ios/app/sync.js +6 -6
  44. package/dist/commands/game/ios/profile/create.js +8 -8
  45. package/dist/commands/game/ios/profile/export.js +7 -7
  46. package/dist/commands/game/ios/profile/import.js +7 -7
  47. package/dist/commands/game/ios/profile/status.js +7 -7
  48. package/dist/commands/game/ios/status.js +8 -8
  49. package/dist/commands/game/ios/wizard.js +5 -5
  50. package/dist/commands/game/job/list.js +5 -5
  51. package/dist/commands/game/job/status.js +8 -8
  52. package/dist/commands/game/list.js +5 -5
  53. package/dist/commands/game/ship.js +51 -16
  54. package/dist/commands/game/status.js +5 -5
  55. package/dist/commands/game/wizard.js +34 -16
  56. package/dist/commands/internal/fastlane.js +1 -1
  57. package/dist/commands/internal/readme.js +1 -1
  58. package/dist/commands/login.js +2 -2
  59. package/dist/commands/status.js +5 -5
  60. package/dist/{export-5Q2q94Hl.js → export-BKn02-NH.js} +1 -1
  61. package/dist/{import-C7KDmp4k.js → import-CRMaNBVF.js} +1 -1
  62. package/dist/{index-B7aHFyRH.js → index--EbYyBAZ.js} +5 -5
  63. package/dist/{index-CXjz-cpD.js → index-35Eswf6F.js} +2 -2
  64. package/dist/{index-CSWTmILs.js → index-BTAL7EB_.js} +4 -4
  65. package/dist/{index-CvO4XDD6.js → index-DxzXU9Hd.js} +1 -1
  66. package/dist/{index-BvfjfOt0.js → index-OZi8bvu8.js} +4 -4
  67. package/dist/{index-DjoMdgss.js → index-u1aj1OQW.js} +1 -1
  68. package/dist/{upload-CKAdc33_.js → upload-Bw0zrS4M.js} +1 -1
  69. package/dist/{useAndroidServiceAccountTestResult-B6F8iB1C.js → useAndroidServiceAccountTestResult-CJLIEYmA.js} +1 -1
  70. package/dist/{useAppleApp-DcKBxjaR.js → useAppleApp-cnb8gX0x.js} +1 -1
  71. package/dist/{useAppleBundleId-DeRlEmrW.js → useAppleBundleId-B0Etav8g.js} +1 -1
  72. package/dist/{useProjectCredentials-CbhW7DPY.js → useProjectCredentials-DX3e_PPc.js} +3 -3
  73. package/dist/{useWebSocket-C0T22ckI.js → useWebSocket-BOCa8v6o.js} +1 -1
  74. package/package.json +1 -1
  75. package/dist/useJobWatching-CIPv7G9D.js +0 -45
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
- import './index-CvO4XDD6.js';
4
+ import './index-DxzXU9Hd.js';
5
5
  import 'axios';
6
6
  import '@tanstack/react-query';
7
7
  import 'crypto';
@@ -17,11 +17,11 @@ import 'react';
17
17
  import 'crypto-js';
18
18
  import 'uuid';
19
19
  import 'socket.io-client';
20
- import { u as useAppleApp } from './useAppleApp-DcKBxjaR.js';
20
+ import { u as useAppleApp } from './useAppleApp-cnb8gX0x.js';
21
21
  import 'fast-glob';
22
22
  import 'yazl';
23
23
  import '@inkjs/ui';
24
- import './index-CSWTmILs.js';
24
+ import './index-BTAL7EB_.js';
25
25
  import 'open';
26
26
  import { T as Table } from './Table-CvM6pccN.js';
27
27
  import { T as Title } from './Title-BCQtayg6.js';
@@ -31,7 +31,7 @@ import 'marked';
31
31
  import 'marked-terminal';
32
32
  import 'path';
33
33
  import 'qrcode';
34
- import { u as useAppleBundleId } from './useAppleBundleId-DeRlEmrW.js';
34
+ import { u as useAppleBundleId } from './useAppleBundleId-B0Etav8g.js';
35
35
 
36
36
  const AppleAppDetails = (props) => {
37
37
  const { data, isLoading } = useAppleApp(props);
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { Box } from 'ink';
3
3
  import { QueryClientProvider } from '@tanstack/react-query';
4
- import { M as queryClient } from './index-CvO4XDD6.js';
4
+ import { K as queryClient } from './index-DxzXU9Hd.js';
5
5
  import 'axios';
6
6
  import 'crypto';
7
7
  import 'fs';
@@ -18,7 +18,7 @@ import 'uuid';
18
18
  import 'socket.io-client';
19
19
  import 'fast-glob';
20
20
  import 'yazl';
21
- import { C as CommandProvider } from './index-CSWTmILs.js';
21
+ import { C as CommandProvider } from './index-BTAL7EB_.js';
22
22
 
23
23
  const Command = ({ children, command }) => {
24
24
  const width = process.stdout.columns || 80;
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { G as GameProvider } from './index-CSWTmILs.js';
3
- import { C as Command } from './Command-CeGf4miL.js';
2
+ import { G as GameProvider } from './index-BTAL7EB_.js';
3
+ import { C as Command } from './Command-1p5alCz3.js';
4
4
 
5
5
  const CommandGame = ({ children, command }) => {
6
6
  return /* @__PURE__ */ jsx(Command, { command, children: /* @__PURE__ */ jsx(GameProvider, { children }) });
@@ -3,9 +3,9 @@ import { Box } from 'ink';
3
3
  import axios from 'axios';
4
4
  import { useContext } from 'react';
5
5
  import { useQueryClient } from '@tanstack/react-query';
6
- import { p as getAuthedHeaders, q as API_URL } from './index-CvO4XDD6.js';
7
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-B6F8iB1C.js';
8
- import { b as GameContext } from './index-CSWTmILs.js';
6
+ import { p as getAuthedHeaders, q as API_URL } from './index-DxzXU9Hd.js';
7
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
8
+ import { b as GameContext } from './index-BTAL7EB_.js';
9
9
  import 'ink-spinner';
10
10
  import '@inkjs/ui';
11
11
  import 'fs';
@@ -2,8 +2,8 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useContext, useState, useEffect } from 'react';
3
3
  import { Box, Text } from 'ink';
4
4
  import Spinner from 'ink-spinner';
5
- import { b as GameContext } from './index-CSWTmILs.js';
6
- import { M as queryClient, P as Platform, C as CredentialsType } from './index-CvO4XDD6.js';
5
+ import { b as GameContext } from './index-BTAL7EB_.js';
6
+ import { K as queryClient, P as Platform, C as CredentialsType } from './index-DxzXU9Hd.js';
7
7
  import 'axios';
8
8
  import 'crypto-js';
9
9
  import { v4 } from 'uuid';
@@ -12,8 +12,8 @@ import 'luxon';
12
12
  import '@inkjs/ui';
13
13
  import { useMutation } from '@tanstack/react-query';
14
14
  import yazl from 'yazl';
15
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-B6F8iB1C.js';
16
- import { i as importCredential } from './import-C7KDmp4k.js';
15
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
16
+ import { i as importCredential } from './import-CRMaNBVF.js';
17
17
  import 'crypto';
18
18
  import 'readline-sync';
19
19
  import 'node:readline';
@@ -1,15 +1,15 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { measureElement, Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
- import { h as getStageColor, j as getMessageColor, c as getJobStatusColor } from './index-CXjz-cpD.js';
5
- import { useState, useEffect, useRef } from 'react';
4
+ import { d as getStageColor, j as getMessageColor } from './index-35Eswf6F.js';
5
+ import { useState, useRef, useEffect } from 'react';
6
6
  import axios from 'axios';
7
7
  import { useInfiniteQuery } from '@tanstack/react-query';
8
- import { p as getAuthedHeaders, q as API_URL, L as castArrayObjectDates, H as castObjectDates, a5 as getShortTime, J as JobStatus } from './index-CvO4XDD6.js';
8
+ import { p as getAuthedHeaders, q as API_URL, I as castArrayObjectDates, J as JobStatus, a4 as castJobDates, a1 as castObjectDates, a5 as getShortTime } from './index-DxzXU9Hd.js';
9
9
  import 'crypto-js';
10
10
  import 'uuid';
11
11
  import 'fs';
12
- import { DateTime } from 'luxon';
12
+ import 'luxon';
13
13
  import 'fast-glob';
14
14
  import 'yazl';
15
15
  import 'socket.io-client';
@@ -20,14 +20,12 @@ import 'node:path';
20
20
  import 'node:url';
21
21
  import 'isomorphic-git';
22
22
  import '@oclif/core';
23
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-B6F8iB1C.js';
24
- import { u as useWebSocket } from './useWebSocket-C0T22ckI.js';
23
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
24
+ import { e as useJob } from './index-BTAL7EB_.js';
25
+ import { u as useWebSocket } from './useWebSocket-BOCa8v6o.js';
25
26
  import { T as Title } from './Title-BCQtayg6.js';
26
27
  import stringLength from 'string-length';
27
28
  import stripAnsi from 'strip-ansi';
28
- import { a as getJobSummary } from './index-CSWTmILs.js';
29
- import { u as useJobWatching } from './useJobWatching-CIPv7G9D.js';
30
- import { a as StatusRow, b as StatusRowLabel } from './StatusTable-Dm5St4g-.js';
31
29
 
32
30
  function arrayToDictionary(array, key = "id") {
33
31
  return array.reduce((a, i) => {
@@ -74,34 +72,94 @@ const useJobLogs = (props) => {
74
72
  return queryResult;
75
73
  };
76
74
 
75
+ function useJobWatching({
76
+ projectId,
77
+ jobId,
78
+ isWatching,
79
+ onJobUpdate,
80
+ onFailure,
81
+ onComplete,
82
+ onNewLogEntry
83
+ }) {
84
+ const [websocketJob, setWebsocketJob] = useState(null);
85
+ const [mostRecentLog, setMostRecentLog] = useState(null);
86
+ const prevJobStatus = useRef(JobStatus.PENDING);
87
+ const handleJobUpdate = (job2) => {
88
+ const completed = [JobStatus.COMPLETED, JobStatus.FAILED];
89
+ const wasRunning = !completed.includes(prevJobStatus.current);
90
+ if (completed.includes(job2.status) && wasRunning) {
91
+ if (job2.status === JobStatus.FAILED) {
92
+ onFailure && onFailure(job2);
93
+ } else {
94
+ onComplete && onComplete(job2);
95
+ }
96
+ }
97
+ prevJobStatus.current = job2.status;
98
+ };
99
+ const jobStatusListener = {
100
+ getPattern: () => [`project.${projectId}:job:created`, `project.${projectId}:job:updated`],
101
+ eventHandler: async (pattern, rawJob) => {
102
+ if (rawJob.id !== jobId) return;
103
+ const job2 = castJobDates(rawJob);
104
+ setWebsocketJob(job2);
105
+ handleJobUpdate(job2);
106
+ if (onJobUpdate) onJobUpdate(job2);
107
+ }
108
+ };
109
+ const jobProgressListener = {
110
+ getPattern: () => `project.${projectId}:job.${jobId}:log`,
111
+ eventHandler: async (pattern, rawLogEntry) => {
112
+ const logEntry = castObjectDates(rawLogEntry, ["sentAt", "createdAt"]);
113
+ if (onNewLogEntry) onNewLogEntry(logEntry);
114
+ setMostRecentLog(logEntry);
115
+ }
116
+ };
117
+ useWebSocket(isWatching ? [jobStatusListener, jobProgressListener] : []);
118
+ const { isLoading, data: job } = useJob({
119
+ projectId,
120
+ jobId
121
+ });
122
+ useEffect(() => {
123
+ setWebsocketJob(null);
124
+ }, [jobId, projectId, isWatching, job]);
125
+ const fetchedJob = job ? job : null;
126
+ const data = websocketJob ? websocketJob : fetchedJob;
127
+ const progress = mostRecentLog?.progress || null;
128
+ const stage = mostRecentLog?.stage || null;
129
+ return {
130
+ isLoading,
131
+ data,
132
+ progress,
133
+ stage
134
+ };
135
+ }
136
+
77
137
  function getSortedJobLogs(logs) {
78
138
  return logs.sort((a, b) => a.sentAt.toMillis() - b.sentAt.toMillis());
79
139
  }
80
- function useJobLogTail(props) {
140
+ function useJobLogTail({ projectId, jobId, isWatching, length }) {
81
141
  const [websocketLogs, setWebsocketLogs] = useState([]);
82
- const listener = {
83
- getPattern: () => `project.${props.projectId}:job.${props.jobId}:log`,
84
- eventHandler: async (pattern, rawLogEntry) => {
85
- setWebsocketLogs((prevLogs) => {
86
- const logEntry = castObjectDates(rawLogEntry, ["sentAt", "createdAt"]);
87
- return [...prevLogs, logEntry];
88
- });
142
+ useJobWatching({
143
+ projectId,
144
+ jobId,
145
+ isWatching,
146
+ onNewLogEntry: (logEntry) => {
147
+ setWebsocketLogs((prevLogs) => [...prevLogs, logEntry]);
89
148
  }
90
- };
91
- useWebSocket(props.isWatching ? [listener] : []);
149
+ });
92
150
  const { isLoading, data: fetchedJobLogs } = useJobLogs({
93
- projectId: props.projectId,
94
- jobId: props.jobId,
95
- pageSize: props.length
151
+ projectId,
152
+ jobId,
153
+ pageSize: length
96
154
  });
97
155
  useEffect(() => {
98
156
  setWebsocketLogs([]);
99
- }, [props.jobId, props.projectId, props.length, props.isWatching, fetchedJobLogs]);
157
+ }, [jobId, projectId, length, isWatching, fetchedJobLogs]);
100
158
  const firstPage = fetchedJobLogs ? fetchedJobLogs?.pages[0].data : [];
101
159
  const allLogs = [...firstPage, ...websocketLogs];
102
160
  const allLogsById = arrayToDictionary(allLogs);
103
161
  const uniqueLogs = dictionaryToArray(allLogsById);
104
- const data = getSortedJobLogs(uniqueLogs).slice(-props.length);
162
+ const data = getSortedJobLogs(uniqueLogs).slice(-length);
105
163
  return {
106
164
  isLoading,
107
165
  data
@@ -143,49 +201,4 @@ const JobLogTail = (props) => {
143
201
  ] });
144
202
  };
145
203
 
146
- const JobStatusSpinner = ({ status, showSpinner }) => /* @__PURE__ */ jsxs(Fragment, { children: [
147
- /* @__PURE__ */ jsx(Box, { width: JobStatus.PROCESSING.length, children: /* @__PURE__ */ jsx(Text, { color: getJobStatusColor(status), children: `${status}` }) }),
148
- showSpinner && /* @__PURE__ */ jsxs(Fragment, { children: [
149
- /* @__PURE__ */ jsx(Text, { children: " " }),
150
- /* @__PURE__ */ jsx(Spinner, { type: "dots" })
151
- ] })
152
- ] });
153
- const JobStatusTable = ({ jobId, projectId, isWatching, onJobUpdate }) => {
154
- const { data: job, stage, isLoading } = useJobWatching({ projectId, jobId, isWatching, onJobUpdate });
155
- const [time, setTime] = useState(DateTime.now());
156
- useEffect(() => {
157
- if (!isWatching) return;
158
- const interval = setInterval(() => setTime(DateTime.now()), 1e3);
159
- return () => {
160
- clearInterval(interval);
161
- };
162
- }, []);
163
- const isJobInProgress = job && ![JobStatus.COMPLETED, JobStatus.FAILED].includes(job.status);
164
- const summary = job ? getJobSummary(job, time) : null;
165
- return /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
166
- /* @__PURE__ */ jsx(Title, { children: "Job Details" }),
167
- isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
168
- summary && job && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
169
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
170
- /* @__PURE__ */ jsx(StatusRow, { label: "ID", value: summary.id }),
171
- /* @__PURE__ */ jsx(StatusRow, { label: "Platform", value: summary.platform }),
172
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
173
- /* @__PURE__ */ jsx(StatusRowLabel, { label: "Status" }),
174
- /* @__PURE__ */ jsx(JobStatusSpinner, { status: job.status, showSpinner: isWatching && !!isJobInProgress })
175
- ] }),
176
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
177
- /* @__PURE__ */ jsx(StatusRowLabel, { label: "Stage" }),
178
- stage && /* @__PURE__ */ jsx(Text, { color: getStageColor(stage), children: `${stage}` })
179
- ] })
180
- ] }),
181
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
182
- /* @__PURE__ */ jsx(StatusRow, { label: "Version", value: summary.version }),
183
- /* @__PURE__ */ jsx(StatusRow, { label: "Git Info", value: summary.gitInfo }),
184
- /* @__PURE__ */ jsx(StatusRow, { label: "Started At", value: summary.createdAt }),
185
- /* @__PURE__ */ jsx(StatusRow, { label: "Runtime", value: summary.runtime })
186
- ] })
187
- ] })
188
- ] }) });
189
- };
190
-
191
- export { JobStatusTable as J, JobLogTail as a };
204
+ export { JobLogTail as J, useJobWatching as u };
@@ -4,14 +4,14 @@ import fg from 'fast-glob';
4
4
  import fs__default from 'fs';
5
5
  import yazl from 'yazl';
6
6
  import { useMutation } from '@tanstack/react-query';
7
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-B6F8iB1C.js';
8
- import { M as queryClient, x as DEFAULT_SHIPPED_FILES_GLOBS, w as DEFAULT_IGNORED_FILES_GLOBS, a1 as getNewUploadTicket, a2 as startJobsFromUpload, J as JobStatus } from './index-CvO4XDD6.js';
9
- import { e as getFileHash, f as getPlatformName } from './index-CXjz-cpD.js';
7
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
8
+ import { K as queryClient, x as DEFAULT_SHIPPED_FILES_GLOBS, w as DEFAULT_IGNORED_FILES_GLOBS, $ as getNewUploadTicket, a0 as startJobsFromUpload } from './index-DxzXU9Hd.js';
9
+ import { f as getFileHash, h as getPlatformName } from './index-35Eswf6F.js';
10
10
  import { g as getCWDGitInfo } from './git-DREGq-jc.js';
11
11
  import { jsx, Fragment } from 'react/jsx-runtime';
12
- import { useRef } from 'react';
12
+ import 'react';
13
13
  import 'ink';
14
- import './index-CSWTmILs.js';
14
+ import './index-BTAL7EB_.js';
15
15
  import 'ink-spinner';
16
16
  import 'crypto-js';
17
17
  import 'luxon';
@@ -25,7 +25,7 @@ import 'qrcode';
25
25
  import 'string-length';
26
26
  import 'strip-ansi';
27
27
  import 'socket.io-client';
28
- import { u as useJobWatching } from './useJobWatching-CIPv7G9D.js';
28
+ import { u as useJobWatching } from './JobLogTail-CZxoMSd5.js';
29
29
 
30
30
  async function ship({ command, log = () => {
31
31
  } }) {
@@ -95,24 +95,12 @@ const useShip = () => {
95
95
  };
96
96
 
97
97
  const JobProgress = (props) => {
98
- const prevJobStatus = useRef(props.job.status);
99
- const handleJobUpdate = (job) => {
100
- const completed = [JobStatus.COMPLETED, JobStatus.FAILED];
101
- const wasRunning = !completed.includes(prevJobStatus.current);
102
- if (completed.includes(job.status) && wasRunning) {
103
- if (job.status === JobStatus.FAILED) {
104
- props.onFailure(job);
105
- } else {
106
- props.onComplete(job);
107
- }
108
- }
109
- prevJobStatus.current = job.status;
110
- };
111
98
  const { progress } = useJobWatching({
112
99
  projectId: props.job.project.id,
113
100
  jobId: props.job.id,
114
101
  isWatching: true,
115
- onJobUpdate: handleJobUpdate
102
+ onComplete: props.onComplete,
103
+ onFailure: props.onFailure
116
104
  });
117
105
  const label = `${getPlatformName(props.job.type)} build progress...`;
118
106
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ProgressSpinner, { progress, label, spinnerType: "dots" }) });
@@ -0,0 +1,66 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { DateTime } from 'luxon';
5
+ import Spinner from 'ink-spinner';
6
+ import { d as getStageColor, c as getJobStatusColor } from './index-35Eswf6F.js';
7
+ import { J as JobStatus } from './index-DxzXU9Hd.js';
8
+ import 'axios';
9
+ import '@tanstack/react-query';
10
+ import 'crypto-js';
11
+ import 'uuid';
12
+ import 'fs';
13
+ import { a as getJobSummary } from './index-BTAL7EB_.js';
14
+ import 'fast-glob';
15
+ import 'yazl';
16
+ import 'socket.io-client';
17
+ import { u as useJobWatching } from './JobLogTail-CZxoMSd5.js';
18
+ import { T as Title } from './Title-BCQtayg6.js';
19
+ import { a as StatusRow, b as StatusRowLabel } from './StatusTable-Dm5St4g-.js';
20
+
21
+ const JobStatusSpinner = ({ status, showSpinner }) => /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ /* @__PURE__ */ jsx(Box, { width: JobStatus.PROCESSING.length, children: /* @__PURE__ */ jsx(Text, { color: getJobStatusColor(status), children: `${status}` }) }),
23
+ showSpinner && /* @__PURE__ */ jsxs(Fragment, { children: [
24
+ /* @__PURE__ */ jsx(Text, { children: " " }),
25
+ /* @__PURE__ */ jsx(Spinner, { type: "dots" })
26
+ ] })
27
+ ] });
28
+ const JobStatusTable = ({ jobId, projectId, isWatching, onJobUpdate }) => {
29
+ const { data: job, stage, isLoading } = useJobWatching({ projectId, jobId, isWatching, onJobUpdate });
30
+ const [time, setTime] = useState(DateTime.now());
31
+ useEffect(() => {
32
+ if (!isWatching) return;
33
+ const interval = setInterval(() => setTime(DateTime.now()), 1e3);
34
+ return () => {
35
+ clearInterval(interval);
36
+ };
37
+ }, []);
38
+ const isJobInProgress = job && ![JobStatus.COMPLETED, JobStatus.FAILED].includes(job.status);
39
+ const summary = job ? getJobSummary(job, time) : null;
40
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
41
+ /* @__PURE__ */ jsx(Title, { children: "Job Details" }),
42
+ isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
43
+ summary && job && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
44
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
45
+ /* @__PURE__ */ jsx(StatusRow, { label: "ID", value: summary.id }),
46
+ /* @__PURE__ */ jsx(StatusRow, { label: "Platform", value: summary.platform }),
47
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
48
+ /* @__PURE__ */ jsx(StatusRowLabel, { label: "Status" }),
49
+ /* @__PURE__ */ jsx(JobStatusSpinner, { status: job.status, showSpinner: isWatching && !!isJobInProgress })
50
+ ] }),
51
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
52
+ /* @__PURE__ */ jsx(StatusRowLabel, { label: "Stage" }),
53
+ stage && /* @__PURE__ */ jsx(Text, { color: getStageColor(stage), children: `${stage}` })
54
+ ] })
55
+ ] }),
56
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
57
+ /* @__PURE__ */ jsx(StatusRow, { label: "Version", value: summary.version }),
58
+ /* @__PURE__ */ jsx(StatusRow, { label: "Git Info", value: summary.gitInfo }),
59
+ /* @__PURE__ */ jsx(StatusRow, { label: "Started At", value: summary.createdAt }),
60
+ /* @__PURE__ */ jsx(StatusRow, { label: "Runtime", value: summary.runtime })
61
+ ] })
62
+ ] })
63
+ ] }) });
64
+ };
65
+
66
+ export { JobStatusTable as J };
@@ -10,13 +10,13 @@ import 'node:url';
10
10
  import 'luxon';
11
11
  import 'axios';
12
12
  import 'isomorphic-git';
13
- import './index-CvO4XDD6.js';
13
+ import './index-DxzXU9Hd.js';
14
14
  import '@oclif/core';
15
15
  import 'react';
16
16
  import '@tanstack/react-query';
17
17
  import 'crypto-js';
18
18
  import 'uuid';
19
- import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-CbhW7DPY.js';
19
+ import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-DX3e_PPc.js';
20
20
  import 'fast-glob';
21
21
  import 'yazl';
22
22
  import 'socket.io-client';
@@ -10,7 +10,7 @@ import 'node:url';
10
10
  import 'luxon';
11
11
  import axios from 'axios';
12
12
  import 'isomorphic-git';
13
- import { b as getShortDate, p as getAuthedHeaders, q as API_URL, L as castArrayObjectDates } from './index-CvO4XDD6.js';
13
+ import { b as getShortDate, p as getAuthedHeaders, q as API_URL, I as castArrayObjectDates } from './index-DxzXU9Hd.js';
14
14
  import '@oclif/core';
15
15
  import 'react';
16
16
  import { useQuery } from '@tanstack/react-query';
@@ -18,8 +18,8 @@ import 'crypto-js';
18
18
  import 'uuid';
19
19
  import 'fast-glob';
20
20
  import 'yazl';
21
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-B6F8iB1C.js';
22
- import { g as getShortUUID } from './index-CXjz-cpD.js';
21
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
22
+ import { g as getShortUUID } from './index-35Eswf6F.js';
23
23
  import 'socket.io-client';
24
24
  import { T as Table } from './Table-CvM6pccN.js';
25
25
  import { T as Title } from './Title-BCQtayg6.js';
@@ -1,4 +1,4 @@
1
- import { B as BaseAuthenticatedCommand } from './index-CvO4XDD6.js';
1
+ import { B as BaseAuthenticatedCommand } from './index-DxzXU9Hd.js';
2
2
 
3
3
  class BaseAppleCommand extends BaseAuthenticatedCommand {
4
4
  async init() {
@@ -1,5 +1,5 @@
1
- import { c as BaseGameCommand, S as getGodotAndroidPackageName, T as getGoogleStatus } from './index-CvO4XDD6.js';
2
- import { b as generatePackageName, a as getInput } from './index-CXjz-cpD.js';
1
+ import { c as BaseGameCommand, Q as getGodotAndroidPackageName, R as getGoogleStatus } from './index-DxzXU9Hd.js';
2
+ import { b as generatePackageName, a as getInput } from './index-35Eswf6F.js';
3
3
 
4
4
  class BaseGameAndroidCommand extends BaseGameCommand {
5
5
  async init() {
@@ -1,10 +1,10 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { Flags } from '@oclif/core';
3
3
  import { render } from 'ink';
4
- import { P as Platform, C as CredentialsType, A as ApiKey, a as ApiKeyType, U as UserRole } from '../../../index-CvO4XDD6.js';
5
- import { g as getUserCredentials } from '../../../index-DjoMdgss.js';
4
+ import { P as Platform, C as CredentialsType, A as ApiKey, a as ApiKeyType, U as UserRole } from '../../../index-DxzXU9Hd.js';
5
+ import { g as getUserCredentials } from '../../../index-u1aj1OQW.js';
6
6
  import 'react';
7
- import '../../../index-CSWTmILs.js';
7
+ import '../../../index-BTAL7EB_.js';
8
8
  import 'ink-spinner';
9
9
  import 'axios';
10
10
  import 'crypto-js';
@@ -30,14 +30,14 @@ import 'qrcode';
30
30
  import { R as RunWithSpinner } from '../../../RunWithSpinner-BVXNWGD3.js';
31
31
  import 'string-length';
32
32
  import 'strip-ansi';
33
- import { C as Command } from '../../../Command-CeGf4miL.js';
34
- import { B as BaseAppleCommand } from '../../../baseAppleCommand-DOUAN8L8.js';
35
- import { u as uploadUserCredentials } from '../../../upload-CKAdc33_.js';
33
+ import { C as Command } from '../../../Command-1p5alCz3.js';
34
+ import { B as BaseAppleCommand } from '../../../baseAppleCommand-BHRIBtTj.js';
35
+ import { u as uploadUserCredentials } from '../../../upload-Bw0zrS4M.js';
36
36
  import '@expo/apple-utils/build/index.js';
37
37
  import 'ini';
38
38
  import 'deepmerge';
39
- import '../../../index-CXjz-cpD.js';
40
- import '../../../useAndroidServiceAccountTestResult-B6F8iB1C.js';
39
+ import '../../../index-35Eswf6F.js';
40
+ import '../../../useAndroidServiceAccountTestResult-CJLIEYmA.js';
41
41
 
42
42
  class AppleApiKeyCreate extends BaseAppleCommand {
43
43
  static args = {};
@@ -2,10 +2,10 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { Args, Flags } from '@oclif/core';
3
3
  import { render } from 'ink';
4
4
  import * as fs from 'fs';
5
- import { B as BaseAuthenticatedCommand, P as Platform, C as CredentialsType } from '../../../index-CvO4XDD6.js';
6
- import { g as getUserCredentials } from '../../../index-DjoMdgss.js';
5
+ import { B as BaseAuthenticatedCommand, P as Platform, C as CredentialsType } from '../../../index-DxzXU9Hd.js';
6
+ import { g as getUserCredentials } from '../../../index-u1aj1OQW.js';
7
7
  import 'react';
8
- import '../../../index-CSWTmILs.js';
8
+ import '../../../index-BTAL7EB_.js';
9
9
  import 'ink-spinner';
10
10
  import 'axios';
11
11
  import 'crypto-js';
@@ -30,13 +30,13 @@ import 'qrcode';
30
30
  import { R as RunWithSpinner } from '../../../RunWithSpinner-BVXNWGD3.js';
31
31
  import 'string-length';
32
32
  import 'strip-ansi';
33
- import { C as Command } from '../../../Command-CeGf4miL.js';
34
- import { e as exportCredential } from '../../../export-5Q2q94Hl.js';
33
+ import { C as Command } from '../../../Command-1p5alCz3.js';
34
+ import { e as exportCredential } from '../../../export-BKn02-NH.js';
35
35
  import '@expo/apple-utils/build/index.js';
36
36
  import 'ini';
37
37
  import 'deepmerge';
38
- import '../../../index-CXjz-cpD.js';
39
- import '../../../useAndroidServiceAccountTestResult-B6F8iB1C.js';
38
+ import '../../../index-35Eswf6F.js';
39
+ import '../../../useAndroidServiceAccountTestResult-CJLIEYmA.js';
40
40
 
41
41
  class AppleApiKeyExport extends BaseAuthenticatedCommand {
42
42
  static args = {
@@ -2,10 +2,10 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { Args, Flags } from '@oclif/core';
3
3
  import { render } from 'ink';
4
4
  import * as fs from 'fs';
5
- import { B as BaseAuthenticatedCommand, P as Platform, C as CredentialsType } from '../../../index-CvO4XDD6.js';
6
- import { g as getUserCredentials } from '../../../index-DjoMdgss.js';
5
+ import { B as BaseAuthenticatedCommand, P as Platform, C as CredentialsType } from '../../../index-DxzXU9Hd.js';
6
+ import { g as getUserCredentials } from '../../../index-u1aj1OQW.js';
7
7
  import 'react';
8
- import '../../../index-CSWTmILs.js';
8
+ import '../../../index-BTAL7EB_.js';
9
9
  import 'ink-spinner';
10
10
  import 'axios';
11
11
  import 'crypto-js';
@@ -30,13 +30,13 @@ import 'qrcode';
30
30
  import { R as RunWithSpinner } from '../../../RunWithSpinner-BVXNWGD3.js';
31
31
  import 'string-length';
32
32
  import 'strip-ansi';
33
- import { C as Command } from '../../../Command-CeGf4miL.js';
34
- import { i as importCredential } from '../../../import-C7KDmp4k.js';
33
+ import { C as Command } from '../../../Command-1p5alCz3.js';
34
+ import { i as importCredential } from '../../../import-CRMaNBVF.js';
35
35
  import '@expo/apple-utils/build/index.js';
36
36
  import 'ini';
37
37
  import 'deepmerge';
38
- import '../../../index-CXjz-cpD.js';
39
- import '../../../useAndroidServiceAccountTestResult-B6F8iB1C.js';
38
+ import '../../../index-35Eswf6F.js';
39
+ import '../../../useAndroidServiceAccountTestResult-CJLIEYmA.js';
40
40
 
41
41
  class AppleApiKeyImport extends BaseAuthenticatedCommand {
42
42
  static args = {
@@ -1,9 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { Flags } from '@oclif/core';
3
3
  import { Box, Text, render } from 'ink';
4
- import { b as getShortDate, A as ApiKey, C as CredentialsType, P as Platform, B as BaseAuthenticatedCommand } from '../../../index-CvO4XDD6.js';
4
+ import { b as getShortDate, A as ApiKey, C as CredentialsType, P as Platform, B as BaseAuthenticatedCommand } from '../../../index-DxzXU9Hd.js';
5
5
  import 'react';
6
- import '../../../index-CSWTmILs.js';
6
+ import '../../../index-BTAL7EB_.js';
7
7
  import Spinner from 'ink-spinner';
8
8
  import 'axios';
9
9
  import 'crypto-js';
@@ -28,16 +28,16 @@ import 'path';
28
28
  import 'qrcode';
29
29
  import 'string-length';
30
30
  import 'strip-ansi';
31
- import { u as useUserCredentials, U as UserCredentialsTable } from '../../../UserCredentialsTable-DtZ3eqnN.js';
31
+ import { u as useUserCredentials, U as UserCredentialsTable } from '../../../UserCredentialsTable-BraKyDWT.js';
32
32
  import { T as Table } from '../../../Table-CvM6pccN.js';
33
33
  import { T as Title } from '../../../Title-BCQtayg6.js';
34
34
  import { N as NextSteps } from '../../../NextSteps-CK9zHOCt.js';
35
- import { C as Command } from '../../../Command-CeGf4miL.js';
35
+ import { C as Command } from '../../../Command-1p5alCz3.js';
36
36
  import '@expo/apple-utils/build/index.js';
37
37
  import 'ini';
38
38
  import 'deepmerge';
39
- import '../../../index-CXjz-cpD.js';
40
- import '../../../useAndroidServiceAccountTestResult-B6F8iB1C.js';
39
+ import '../../../index-35Eswf6F.js';
40
+ import '../../../useAndroidServiceAccountTestResult-CJLIEYmA.js';
41
41
 
42
42
  async function queryAppleApiKeys({ ctx }) {
43
43
  const keys = await ApiKey.getAsync(ctx);
@@ -1,10 +1,10 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { Flags } from '@oclif/core';
3
3
  import { render } from 'ink';
4
- import { m as CertificateType, l as Certificate, P as Platform, C as CredentialsType } from '../../../index-CvO4XDD6.js';
5
- import { g as getUserCredentials } from '../../../index-DjoMdgss.js';
4
+ import { m as CertificateType, l as Certificate, P as Platform, C as CredentialsType } from '../../../index-DxzXU9Hd.js';
5
+ import { g as getUserCredentials } from '../../../index-u1aj1OQW.js';
6
6
  import 'react';
7
- import '../../../index-CSWTmILs.js';
7
+ import '../../../index-BTAL7EB_.js';
8
8
  import 'ink-spinner';
9
9
  import 'axios';
10
10
  import 'crypto-js';
@@ -30,15 +30,15 @@ import 'qrcode';
30
30
  import { R as RunWithSpinner } from '../../../RunWithSpinner-BVXNWGD3.js';
31
31
  import 'string-length';
32
32
  import 'strip-ansi';
33
- import { C as Command } from '../../../Command-CeGf4miL.js';
33
+ import { C as Command } from '../../../Command-1p5alCz3.js';
34
34
  import forge from 'node-forge';
35
- import { B as BaseAppleCommand } from '../../../baseAppleCommand-DOUAN8L8.js';
36
- import { u as uploadUserCredentials } from '../../../upload-CKAdc33_.js';
35
+ import { B as BaseAppleCommand } from '../../../baseAppleCommand-BHRIBtTj.js';
36
+ import { u as uploadUserCredentials } from '../../../upload-Bw0zrS4M.js';
37
37
  import '@expo/apple-utils/build/index.js';
38
38
  import 'ini';
39
39
  import 'deepmerge';
40
- import '../../../index-CXjz-cpD.js';
41
- import '../../../useAndroidServiceAccountTestResult-B6F8iB1C.js';
40
+ import '../../../index-35Eswf6F.js';
41
+ import '../../../useAndroidServiceAccountTestResult-CJLIEYmA.js';
42
42
 
43
43
  function decodeCertificate(certificateContent) {
44
44
  const decodedContent = forge.util.decode64(certificateContent);