shipthis 0.1.30 → 0.1.32

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 (86) hide show
  1. package/README.md +122 -41
  2. package/assets/markdown/create-google-play-game.md +2 -4
  3. package/assets/markdown/ship-success.md +1 -1
  4. package/dist/{AppleBundleIdDetails-Fp5COwTa.js → AppleBundleIdDetails-6H3cNWxw.js} +17 -19
  5. package/dist/{Command-1p5alCz3.js → Command-WPpmLPkL.js} +13 -12
  6. package/dist/CommandGame-cxzWG4nT.js +7 -0
  7. package/dist/{Create-1xAdntNl.js → Create-3Ob8sjik.js} +20 -20
  8. package/dist/GameStatus-BQEtVKvv.js +137 -0
  9. package/dist/{Import-CzC-M4ln.js → Import-CFuPDI0K.js} +33 -35
  10. package/dist/{JobLogTail-CZxoMSd5.js → JobLogTail-0CBLoG8N.js} +53 -52
  11. package/dist/{JobProgress-BjNgtIjm.js → JobProgress-lKqVT88m.js} +46 -37
  12. package/dist/{JobStatusTable-BB-PWlwj.js → JobStatusTable-C_ZsZJCm.js} +14 -13
  13. package/dist/{NextSteps-CK9zHOCt.js → NextSteps-DbJHmscQ.js} +1 -3
  14. package/dist/{ProgressSpinner-6pw1T8Iw.js → ProgressSpinner-DGcakQSK.js} +1 -1
  15. package/dist/{ProjectCredentialsTable-DyZep993.js → ProjectCredentialsTable-B5pHOnGu.js} +11 -10
  16. package/dist/{StatusTable-Dm5St4g-.js → StatusTable-DzRWcMr4.js} +7 -9
  17. package/dist/{Table-CvM6pccN.js → Table-FaNgpyeq.js} +15 -15
  18. package/dist/{UserCredentialsTable-BraKyDWT.js → UserCredentialsTable-3W3qesh7.js} +18 -19
  19. package/dist/{baseAppleCommand-BHRIBtTj.js → baseAppleCommand-BGV088--.js} +1 -1
  20. package/dist/{baseGameAndroidCommand-SrDRbhAG.js → baseGameAndroidCommand-CsemgVjp.js} +23 -23
  21. package/dist/commands/apple/apiKey/create.js +35 -35
  22. package/dist/commands/apple/apiKey/export.js +26 -26
  23. package/dist/commands/apple/apiKey/import.js +27 -27
  24. package/dist/commands/apple/apiKey/status.js +31 -31
  25. package/dist/commands/apple/certificate/create.js +39 -39
  26. package/dist/commands/apple/certificate/export.js +26 -26
  27. package/dist/commands/apple/certificate/import.js +27 -27
  28. package/dist/commands/apple/certificate/status.js +31 -31
  29. package/dist/commands/apple/login.js +15 -15
  30. package/dist/commands/apple/status.js +28 -28
  31. package/dist/commands/dashboard.js +10 -10
  32. package/dist/commands/game/android/apiKey/connect.js +28 -28
  33. package/dist/commands/game/android/apiKey/create.js +28 -28
  34. package/dist/commands/game/android/apiKey/export.js +29 -29
  35. package/dist/commands/game/android/apiKey/import.js +31 -31
  36. package/dist/commands/game/android/apiKey/invite.js +14 -14
  37. package/dist/commands/game/android/apiKey/status.js +29 -29
  38. package/dist/commands/game/android/keyStore/create.js +24 -24
  39. package/dist/commands/game/android/keyStore/export.js +28 -28
  40. package/dist/commands/game/android/keyStore/import.js +35 -35
  41. package/dist/commands/game/android/keyStore/status.js +26 -26
  42. package/dist/commands/game/android/status.js +14 -58
  43. package/dist/commands/game/build/download.js +24 -24
  44. package/dist/commands/game/build/list.js +37 -37
  45. package/dist/commands/game/create.js +15 -15
  46. package/dist/commands/game/details.js +35 -36
  47. package/dist/commands/game/export.js +12 -12
  48. package/dist/commands/game/ios/app/addTester.js +24 -24
  49. package/dist/commands/game/ios/app/create.js +24 -24
  50. package/dist/commands/game/ios/app/status.js +29 -29
  51. package/dist/commands/game/ios/app/sync.js +31 -31
  52. package/dist/commands/game/ios/profile/create.js +30 -30
  53. package/dist/commands/game/ios/profile/export.js +28 -28
  54. package/dist/commands/game/ios/profile/import.js +32 -32
  55. package/dist/commands/game/ios/profile/status.js +36 -36
  56. package/dist/commands/game/ios/status.js +46 -58
  57. package/dist/commands/game/ios/wizard.js +31 -31
  58. package/dist/commands/game/job/list.js +34 -34
  59. package/dist/commands/game/job/status.js +31 -31
  60. package/dist/commands/game/list.js +45 -41
  61. package/dist/commands/game/ship.js +73 -70
  62. package/dist/commands/game/status.js +38 -82
  63. package/dist/commands/game/wizard.js +271 -307
  64. package/dist/commands/internal/fastlane.js +15 -17
  65. package/dist/commands/internal/readme.js +38 -36
  66. package/dist/commands/login.js +14 -14
  67. package/dist/commands/status.js +35 -33
  68. package/dist/{export-BKn02-NH.js → export-CXsVPXA1.js} +5 -5
  69. package/dist/{git-DREGq-jc.js → git-BpsfNFZ_.js} +8 -8
  70. package/dist/{import-CRMaNBVF.js → import-DGvG5REx.js} +14 -14
  71. package/dist/{index-DxzXU9Hd.js → index-BhhiXbey.js} +244 -221
  72. package/dist/{index-OZi8bvu8.js → index-C03TV1_J.js} +54 -38
  73. package/dist/{index-BTAL7EB_.js → index-C66Dd8Xc.js} +80 -79
  74. package/dist/{index-35Eswf6F.js → index-CGBdOm1q.js} +43 -27
  75. package/dist/{index--EbYyBAZ.js → index-CS9Gwcb0.js} +41 -43
  76. package/dist/{index-u1aj1OQW.js → index-CtTI85m-.js} +6 -6
  77. package/dist/{upload-Bw0zrS4M.js → upload-8y5MQEm9.js} +22 -22
  78. package/dist/{useAndroidServiceAccountTestResult-CJLIEYmA.js → useAndroidServiceAccountTestResult-DZk5SMxI.js} +11 -13
  79. package/dist/{useAppleApp-cnb8gX0x.js → useAppleApp-DWYGURwU.js} +4 -4
  80. package/dist/{useAppleBundleId-B0Etav8g.js → useAppleBundleId-PsTJ2g1B.js} +6 -6
  81. package/dist/{useProjectCredentials-DX3e_PPc.js → useProjectCredentials-BEphqa18.js} +10 -12
  82. package/dist/{useWebSocket-BOCa8v6o.js → useWebSocket-5PYa2QER.js} +1 -1
  83. package/dist/utils/help.js +4 -4
  84. package/package.json +4 -2
  85. package/dist/CommandGame-Z4eUQBjn.js +0 -9
  86. package/dist/{RunWithSpinner-BVXNWGD3.js → RunWithSpinner-gMVA07bZ.js} +2 -2
@@ -1,35 +1,35 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useContext, useState, useEffect } from 'react';
3
2
  import { Box, Text } from 'ink';
4
3
  import Spinner from 'ink-spinner';
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
- import 'axios';
8
- import 'crypto-js';
9
- import { v4 } from 'uuid';
10
- import fs__default from 'fs';
11
- import 'luxon';
12
- import '@inkjs/ui';
13
- import { useMutation } from '@tanstack/react-query';
14
- import yazl from 'yazl';
15
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
16
- import { i as importCredential } from './import-CRMaNBVF.js';
17
- import 'crypto';
18
- import 'readline-sync';
19
- import 'node:readline';
4
+ import { useContext, useState, useEffect } from 'react';
5
+ import 'node:crypto';
6
+ import fs__default from 'node:fs';
20
7
  import 'node:path';
8
+ import 'node:readline';
21
9
  import 'node:url';
10
+ import 'readline-sync';
11
+ import 'luxon';
12
+ import 'axios';
22
13
  import 'isomorphic-git';
14
+ import { K as queryClient, P as Platform, C as CredentialsType } from './index-BhhiXbey.js';
23
15
  import '@oclif/core';
16
+ import { useMutation } from '@tanstack/react-query';
17
+ import 'crypto-js';
18
+ import { v4 } from 'uuid';
24
19
  import 'fast-glob';
20
+ import yazl from 'yazl';
25
21
  import 'socket.io-client';
22
+ import 'fullscreen-ink';
23
+ import 'string-length';
24
+ import 'strip-ansi';
26
25
  import 'open';
26
+ import '@inkjs/ui';
27
27
  import 'marked';
28
28
  import 'marked-terminal';
29
- import 'path';
30
29
  import 'qrcode';
31
- import 'string-length';
32
- import 'strip-ansi';
30
+ import { G as GameContext } from './index-C66Dd8Xc.js';
31
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
32
+ import { i as importCredential } from './import-DGvG5REx.js';
33
33
 
34
34
  async function importKeystore({ log = () => {
35
35
  }, ...opt }) {
@@ -64,31 +64,29 @@ async function importKeystore({ log = () => {
64
64
  }
65
65
  log("Uploading and importing zip file...");
66
66
  const keyStore = await importCredential({
67
+ platform: Platform.ANDROID,
67
68
  projectId: opt.gameId,
68
- zipPath: `${opt.zipFilePath}`,
69
69
  type: CredentialsType.CERTIFICATE,
70
- platform: Platform.ANDROID
70
+ zipPath: `${opt.zipFilePath}`
71
71
  });
72
72
  log("Imported successfully");
73
- toDelete.forEach((file) => {
73
+ for (const file of toDelete) {
74
74
  log(`Deleting temporary file: ${file}`);
75
75
  fs__default.unlinkSync(file);
76
- });
76
+ }
77
77
  return keyStore;
78
78
  }
79
- const useImportKeystore = () => {
80
- return useMutation({
81
- mutationFn: importKeystore,
82
- onSuccess: async (data) => {
83
- const projectId = data.projectId;
84
- queryClient.invalidateQueries({
85
- queryKey: cacheKeys.projectCredentials({ projectId, pageNumber: 0 })
86
- });
87
- }
88
- });
89
- };
79
+ const useImportKeystore = () => useMutation({
80
+ mutationFn: importKeystore,
81
+ async onSuccess(data) {
82
+ const { projectId } = data;
83
+ queryClient.invalidateQueries({
84
+ queryKey: cacheKeys.projectCredentials({ pageNumber: 0, projectId })
85
+ });
86
+ }
87
+ });
90
88
 
91
- const ImportKeystore = ({ onComplete, onError, importKeystoreProps }) => {
89
+ const ImportKeystore = ({ importKeystoreProps, onComplete, onError }) => {
92
90
  const { gameId } = useContext(GameContext);
93
91
  const importMutation = useImportKeystore();
94
92
  const [log, setLog] = useState(null);
@@ -1,28 +1,29 @@
1
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 { d as getStageColor, j as getMessageColor } from './index-35Eswf6F.js';
5
- import { useState, useRef, useEffect } from 'react';
6
- import axios from 'axios';
7
4
  import { useInfiniteQuery } from '@tanstack/react-query';
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';
5
+ import axios from 'axios';
6
+ import { useState, useRef, useEffect } from 'react';
7
+ import 'node:fs';
9
8
  import 'crypto-js';
10
9
  import 'uuid';
11
- import 'fs';
10
+ import { p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates, J as JobStatus, a4 as castJobDates, a1 as castObjectDates, a5 as getShortTime } from './index-BhhiXbey.js';
11
+ import { d as getStageColor, j as getMessageColor } from './index-CGBdOm1q.js';
12
12
  import 'luxon';
13
13
  import 'fast-glob';
14
14
  import 'yazl';
15
15
  import 'socket.io-client';
16
- import 'crypto';
17
- import 'readline-sync';
18
- import 'node:readline';
16
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
17
+ import 'node:crypto';
19
18
  import 'node:path';
19
+ import 'node:readline';
20
20
  import 'node:url';
21
+ import 'readline-sync';
21
22
  import 'isomorphic-git';
22
23
  import '@oclif/core';
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';
24
+ import 'fullscreen-ink';
25
+ import { e as useJob } from './index-C66Dd8Xc.js';
26
+ import { u as useWebSocket } from './useWebSocket-5PYa2QER.js';
26
27
  import { T as Title } from './Title-BCQtayg6.js';
27
28
  import stringLength from 'string-length';
28
29
  import stripAnsi from 'strip-ansi';
@@ -38,10 +39,10 @@ function dictionaryToArray(dictionary) {
38
39
  }
39
40
 
40
41
  async function queryJobLogs({
41
- projectId,
42
- jobId,
43
42
  cursor,
44
- pageSize = 10
43
+ jobId,
44
+ pageSize = 10,
45
+ projectId
45
46
  }) {
46
47
  try {
47
48
  const headers = getAuthedHeaders();
@@ -59,35 +60,35 @@ async function queryJobLogs({
59
60
  }
60
61
  const useJobLogs = (props) => {
61
62
  const queryResult = useInfiniteQuery({
62
- queryKey: cacheKeys.jobLogs(props),
63
- queryFn: async ({ pageParam }) => {
63
+ getNextPageParam: (lastPage) => lastPage.nextCursor,
64
+ initialPageParam: props.cursor,
65
+ async queryFn({ pageParam }) {
64
66
  return queryJobLogs({
65
67
  ...props,
66
68
  cursor: pageParam
67
69
  });
68
70
  },
69
- getNextPageParam: (lastPage) => lastPage.nextCursor,
70
- initialPageParam: props.cursor
71
+ queryKey: cacheKeys.jobLogs(props)
71
72
  });
72
73
  return queryResult;
73
74
  };
74
75
 
75
76
  function useJobWatching({
76
- projectId,
77
- jobId,
78
77
  isWatching,
79
- onJobUpdate,
80
- onFailure,
78
+ jobId,
81
79
  onComplete,
82
- onNewLogEntry
80
+ onFailure,
81
+ onJobUpdate,
82
+ onNewLogEntry,
83
+ projectId
83
84
  }) {
84
85
  const [websocketJob, setWebsocketJob] = useState(null);
85
86
  const [mostRecentLog, setMostRecentLog] = useState(null);
86
87
  const prevJobStatus = useRef(JobStatus.PENDING);
87
88
  const handleJobUpdate = (job2) => {
88
- const completed = [JobStatus.COMPLETED, JobStatus.FAILED];
89
- const wasRunning = !completed.includes(prevJobStatus.current);
90
- if (completed.includes(job2.status) && wasRunning) {
89
+ const completed = /* @__PURE__ */ new Set([JobStatus.COMPLETED, JobStatus.FAILED]);
90
+ const wasRunning = !completed.has(prevJobStatus.current);
91
+ if (completed.has(job2.status) && wasRunning) {
91
92
  if (job2.status === JobStatus.FAILED) {
92
93
  onFailure && onFailure(job2);
93
94
  } else {
@@ -97,27 +98,27 @@ function useJobWatching({
97
98
  prevJobStatus.current = job2.status;
98
99
  };
99
100
  const jobStatusListener = {
100
- getPattern: () => [`project.${projectId}:job:created`, `project.${projectId}:job:updated`],
101
- eventHandler: async (pattern, rawJob) => {
101
+ async eventHandler(pattern, rawJob) {
102
102
  if (rawJob.id !== jobId) return;
103
103
  const job2 = castJobDates(rawJob);
104
104
  setWebsocketJob(job2);
105
105
  handleJobUpdate(job2);
106
106
  if (onJobUpdate) onJobUpdate(job2);
107
- }
107
+ },
108
+ getPattern: () => [`project.${projectId}:job:created`, `project.${projectId}:job:updated`]
108
109
  };
109
110
  const jobProgressListener = {
110
- getPattern: () => `project.${projectId}:job.${jobId}:log`,
111
- eventHandler: async (pattern, rawLogEntry) => {
111
+ async eventHandler(pattern, rawLogEntry) {
112
112
  const logEntry = castObjectDates(rawLogEntry, ["sentAt", "createdAt"]);
113
113
  if (onNewLogEntry) onNewLogEntry(logEntry);
114
114
  setMostRecentLog(logEntry);
115
- }
115
+ },
116
+ getPattern: () => `project.${projectId}:job.${jobId}:log`
116
117
  };
117
118
  useWebSocket(isWatching ? [jobStatusListener, jobProgressListener] : []);
118
- const { isLoading, data: job } = useJob({
119
- projectId,
120
- jobId
119
+ const { data: job, isLoading } = useJob({
120
+ jobId,
121
+ projectId
121
122
  });
122
123
  useEffect(() => {
123
124
  setWebsocketJob(null);
@@ -127,8 +128,8 @@ function useJobWatching({
127
128
  const progress = mostRecentLog?.progress || null;
128
129
  const stage = mostRecentLog?.stage || null;
129
130
  return {
130
- isLoading,
131
131
  data,
132
+ isLoading,
132
133
  progress,
133
134
  stage
134
135
  };
@@ -137,20 +138,20 @@ function useJobWatching({
137
138
  function getSortedJobLogs(logs) {
138
139
  return logs.sort((a, b) => a.sentAt.toMillis() - b.sentAt.toMillis());
139
140
  }
140
- function useJobLogTail({ projectId, jobId, isWatching, length }) {
141
+ function useJobLogTail({ isWatching, jobId, length, projectId }) {
141
142
  const [websocketLogs, setWebsocketLogs] = useState([]);
142
143
  useJobWatching({
143
- projectId,
144
- jobId,
145
144
  isWatching,
146
- onNewLogEntry: (logEntry) => {
145
+ jobId,
146
+ onNewLogEntry(logEntry) {
147
147
  setWebsocketLogs((prevLogs) => [...prevLogs, logEntry]);
148
- }
148
+ },
149
+ projectId
149
150
  });
150
- const { isLoading, data: fetchedJobLogs } = useJobLogs({
151
- projectId,
151
+ const { data: fetchedJobLogs, isLoading } = useJobLogs({
152
152
  jobId,
153
- pageSize: length
153
+ pageSize: length,
154
+ projectId
154
155
  });
155
156
  useEffect(() => {
156
157
  setWebsocketLogs([]);
@@ -161,8 +162,8 @@ function useJobLogTail({ projectId, jobId, isWatching, length }) {
161
162
  const uniqueLogs = dictionaryToArray(allLogsById);
162
163
  const data = getSortedJobLogs(uniqueLogs).slice(-length);
163
164
  return {
164
- isLoading,
165
- data
165
+ data,
166
+ isLoading
166
167
  };
167
168
  }
168
169
 
@@ -175,27 +176,27 @@ const TruncatedText = ({ children, wrap, ...textPropsWithoutWrap }) => {
175
176
  setWidth(measuredWidth);
176
177
  }, []);
177
178
  const getTruncated = (input) => {
178
- const withoutCrlf = input.replaceAll(/[\r\n]/g, "");
179
+ const withoutCrlf = input.replaceAll(/[\n\r]/g, "");
179
180
  if (width === null) return withoutCrlf;
180
181
  const withoutAnsi = stripAnsi(withoutCrlf);
181
182
  const textLength = stringLength(withoutAnsi);
182
- return textLength > width ? withoutCrlf.substring(0, width) : withoutCrlf;
183
+ return textLength > width ? withoutCrlf.slice(0, Math.max(0, width)) : withoutCrlf;
183
184
  };
184
185
  return /* @__PURE__ */ jsx(Box, { ref, children: /* @__PURE__ */ jsx(Text, { ...textPropsWithoutWrap, children: getTruncated(children) + "\x1B[0m" }) });
185
186
  };
186
187
 
187
188
  const JobLogTail = (props) => {
188
- const { isLoading, data } = useJobLogTail(props);
189
+ const { data, isLoading } = useJobLogTail(props);
189
190
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
190
191
  /* @__PURE__ */ jsx(Title, { children: "Job Logs" }),
191
192
  isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
192
193
  /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: data.map((log) => {
193
194
  const stageColor = getStageColor(log.stage);
194
195
  const messageColor = getMessageColor(log.level);
195
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", overflow: "hidden", height: 1, children: [
196
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", height: 1, overflow: "hidden", children: [
196
197
  /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: getShortTime(log.sentAt) }) }),
197
- /* @__PURE__ */ jsx(Box, { marginLeft: 1, width: 9, justifyContent: "flex-start", children: /* @__PURE__ */ jsx(Text, { color: stageColor, children: log.stage }) }),
198
- /* @__PURE__ */ jsx(Box, { marginLeft: 1, overflow: "hidden", height: 1, marginRight: 2, children: /* @__PURE__ */ jsx(TruncatedText, { color: messageColor, children: log.message }) })
198
+ /* @__PURE__ */ jsx(Box, { justifyContent: "flex-start", marginLeft: 1, width: 9, children: /* @__PURE__ */ jsx(Text, { color: stageColor, children: log.stage }) }),
199
+ /* @__PURE__ */ jsx(Box, { height: 1, marginLeft: 1, marginRight: 2, overflow: "hidden", children: /* @__PURE__ */ jsx(TruncatedText, { color: messageColor, children: log.message }) })
199
200
  ] }, log.id);
200
201
  }) })
201
202
  ] });
@@ -1,37 +1,45 @@
1
- import { v4 } from 'uuid';
1
+ import fs__default from 'node:fs';
2
+ import { useMutation } from '@tanstack/react-query';
2
3
  import axios from 'axios';
3
4
  import fg from 'fast-glob';
4
- import fs__default from 'fs';
5
+ import { v4 } from 'uuid';
5
6
  import yazl from 'yazl';
6
- import { useMutation } from '@tanstack/react-query';
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
- import { g as getCWDGitInfo } from './git-DREGq-jc.js';
7
+ import { K as queryClient, v as DEFAULT_SHIPPED_FILES_GLOBS, w as DEFAULT_IGNORED_FILES_GLOBS, $ as getNewUploadTicket, a0 as startJobsFromUpload } from './index-BhhiXbey.js';
8
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
9
+ import { f as getFileHash, h as getPlatformName } from './index-CGBdOm1q.js';
10
+ import { g as getCWDGitInfo } from './git-BpsfNFZ_.js';
11
11
  import { jsx, Fragment } from 'react/jsx-runtime';
12
- import 'react';
13
12
  import 'ink';
14
- import './index-BTAL7EB_.js';
15
13
  import 'ink-spinner';
14
+ import 'react';
16
15
  import 'crypto-js';
17
16
  import 'luxon';
18
- import '@inkjs/ui';
17
+ import 'socket.io-client';
18
+ import { u as useJobWatching } from './JobLogTail-0CBLoG8N.js';
19
+ import 'fullscreen-ink';
20
+ import 'string-length';
21
+ import 'strip-ansi';
19
22
  import 'open';
23
+ import '@inkjs/ui';
24
+ import 'node:path';
20
25
  import 'marked';
21
26
  import 'marked-terminal';
22
- import 'path';
23
- import { P as ProgressSpinner } from './ProgressSpinner-6pw1T8Iw.js';
27
+ import { P as ProgressSpinner } from './ProgressSpinner-DGcakQSK.js';
24
28
  import 'qrcode';
25
- import 'string-length';
26
- import 'strip-ansi';
27
- import 'socket.io-client';
28
- import { u as useJobWatching } from './JobLogTail-CZxoMSd5.js';
29
+ import './index-C66Dd8Xc.js';
29
30
 
30
31
  async function ship({ command, log = () => {
31
- } }) {
32
- log("Fetching project config...");
32
+ }, shipFlags }) {
33
+ log("Fetching game config...");
33
34
  const projectConfig = await command.getProjectConfig();
34
35
  if (!projectConfig.project) throw new Error("No project found in project config");
36
+ const hasConfiguredIos = Boolean(projectConfig.project.details?.iosBundleId);
37
+ const hasConfiguredAndroid = Boolean(projectConfig.project.details?.androidPackageName);
38
+ if (!hasConfiguredAndroid && !hasConfiguredIos) {
39
+ throw new Error(
40
+ "No Android or iOS configuration found. Please run `shipthis game wizard android` or `shipthis game wizard ios` to configure your game."
41
+ );
42
+ }
35
43
  log("Retrieving file globs...");
36
44
  const shippedFilesGlobs = projectConfig.shippedFilesGlobs || DEFAULT_SHIPPED_FILES_GLOBS;
37
45
  const ignoredFilesGlobs = projectConfig.ignoredFilesGlobs || DEFAULT_IGNORED_FILES_GLOBS;
@@ -58,8 +66,8 @@ async function ship({ command, log = () => {
58
66
  log("Uploading zip file...");
59
67
  await axios.put(uploadTicket.url, zipBuffer, {
60
68
  headers: {
61
- "Content-length": size,
62
- "Content-Type": "application/zip"
69
+ "Content-Type": "application/zip",
70
+ "Content-length": size
63
71
  }
64
72
  });
65
73
  log("Fetching Git info...");
@@ -71,39 +79,40 @@ async function ship({ command, log = () => {
71
79
  zipFileMd5
72
80
  };
73
81
  log("Starting jobs from upload...");
74
- const commandFlags = command.getFlags();
82
+ const finalFlags = shipFlags || command.getFlags();
75
83
  const startJobsOptions = {
76
84
  ...uploadDetails,
77
- skipPublish: commandFlags.skipPublish,
78
- platform: commandFlags.platform?.toUpperCase()
85
+ platform: finalFlags.platform?.toUpperCase(),
86
+ skipPublish: finalFlags.skipPublish
79
87
  };
80
88
  const jobs = await startJobsFromUpload(uploadTicket.id, startJobsOptions);
81
89
  log("Cleaning up temporary zip file...");
82
90
  fs__default.unlinkSync(tmpZipFile);
83
91
  log("Job submission complete.");
92
+ if (jobs.length === 0) {
93
+ throw new Error("No jobs were created. Please check your game configuration and try again.");
94
+ }
84
95
  return jobs;
85
96
  }
86
- const useShip = () => {
87
- return useMutation({
88
- mutationFn: ship,
89
- onSuccess: async (data) => {
90
- queryClient.invalidateQueries({
91
- queryKey: cacheKeys.jobs({ projectId: data[0].project.id, pageNumber: 0 })
92
- });
93
- }
94
- });
95
- };
97
+ const useShip = () => useMutation({
98
+ mutationFn: ship,
99
+ async onSuccess(data) {
100
+ queryClient.invalidateQueries({
101
+ queryKey: cacheKeys.jobs({ pageNumber: 0, projectId: data[0].project.id })
102
+ });
103
+ }
104
+ });
96
105
 
97
106
  const JobProgress = (props) => {
98
107
  const { progress } = useJobWatching({
99
- projectId: props.job.project.id,
100
- jobId: props.job.id,
101
108
  isWatching: true,
109
+ jobId: props.job.id,
102
110
  onComplete: props.onComplete,
103
- onFailure: props.onFailure
111
+ onFailure: props.onFailure,
112
+ projectId: props.job.project.id
104
113
  });
105
114
  const label = `${getPlatformName(props.job.type)} build progress...`;
106
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ProgressSpinner, { progress, label, spinnerType: "dots" }) });
115
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ProgressSpinner, { label, progress, spinnerType: "dots" }) });
107
116
  };
108
117
 
109
118
  export { JobProgress as J, useShip as u };
@@ -1,32 +1,33 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useState, useEffect } from 'react';
3
2
  import { Box, Text } from 'ink';
4
- import { DateTime } from 'luxon';
5
3
  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';
4
+ import { DateTime } from 'luxon';
5
+ import { useState, useEffect } from 'react';
6
+ import { J as JobStatus } from './index-BhhiXbey.js';
9
7
  import '@tanstack/react-query';
8
+ import 'axios';
9
+ import 'node:fs';
10
10
  import 'crypto-js';
11
11
  import 'uuid';
12
- import 'fs';
13
- import { a as getJobSummary } from './index-BTAL7EB_.js';
12
+ import { d as getStageColor, c as getJobStatusColor } from './index-CGBdOm1q.js';
13
+ import { a as getJobSummary } from './index-C66Dd8Xc.js';
14
14
  import 'fast-glob';
15
15
  import 'yazl';
16
16
  import 'socket.io-client';
17
- import { u as useJobWatching } from './JobLogTail-CZxoMSd5.js';
17
+ import { u as useJobWatching } from './JobLogTail-0CBLoG8N.js';
18
+ import 'fullscreen-ink';
19
+ import { a as StatusRow, b as StatusRowLabel } from './StatusTable-DzRWcMr4.js';
18
20
  import { T as Title } from './Title-BCQtayg6.js';
19
- import { a as StatusRow, b as StatusRowLabel } from './StatusTable-Dm5St4g-.js';
20
21
 
21
- const JobStatusSpinner = ({ status, showSpinner }) => /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ const JobStatusSpinner = ({ showSpinner, status }) => /* @__PURE__ */ jsxs(Fragment, { children: [
22
23
  /* @__PURE__ */ jsx(Box, { width: JobStatus.PROCESSING.length, children: /* @__PURE__ */ jsx(Text, { color: getJobStatusColor(status), children: `${status}` }) }),
23
24
  showSpinner && /* @__PURE__ */ jsxs(Fragment, { children: [
24
25
  /* @__PURE__ */ jsx(Text, { children: " " }),
25
26
  /* @__PURE__ */ jsx(Spinner, { type: "dots" })
26
27
  ] })
27
28
  ] });
28
- const JobStatusTable = ({ jobId, projectId, isWatching, onJobUpdate }) => {
29
- const { data: job, stage, isLoading } = useJobWatching({ projectId, jobId, isWatching, onJobUpdate });
29
+ const JobStatusTable = ({ isWatching, jobId, onJobUpdate, projectId }) => {
30
+ const { data: job, isLoading, stage } = useJobWatching({ isWatching, jobId, onJobUpdate, projectId });
30
31
  const [time, setTime] = useState(DateTime.now());
31
32
  useEffect(() => {
32
33
  if (!isWatching) return;
@@ -46,7 +47,7 @@ const JobStatusTable = ({ jobId, projectId, isWatching, onJobUpdate }) => {
46
47
  /* @__PURE__ */ jsx(StatusRow, { label: "Platform", value: summary.platform }),
47
48
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
48
49
  /* @__PURE__ */ jsx(StatusRowLabel, { label: "Status" }),
49
- /* @__PURE__ */ jsx(JobStatusSpinner, { status: job.status, showSpinner: isWatching && !!isJobInProgress })
50
+ /* @__PURE__ */ jsx(JobStatusSpinner, { showSpinner: isWatching && Boolean(isJobInProgress), status: job.status })
50
51
  ] }),
51
52
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
52
53
  /* @__PURE__ */ jsx(StatusRowLabel, { label: "Stage" }),
@@ -11,8 +11,6 @@ const ListWithTitle = ({ listItems, title }) => {
11
11
  ] });
12
12
  };
13
13
 
14
- const NextSteps = ({ steps }) => {
15
- return /* @__PURE__ */ jsx(ListWithTitle, { listItems: steps, title: "Next Steps" });
16
- };
14
+ const NextSteps = ({ steps }) => /* @__PURE__ */ jsx(ListWithTitle, { listItems: steps, title: "Next Steps" });
17
15
 
18
16
  export { NextSteps as N };
@@ -3,7 +3,7 @@ import { ProgressBar } from '@inkjs/ui';
3
3
  import { Box, Text } from 'ink';
4
4
  import Spinner from 'ink-spinner';
5
5
 
6
- const ProgressSpinner = ({ progress, label, spinnerType, labelProps, boxProps }) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, ...boxProps, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
6
+ const ProgressSpinner = ({ boxProps, label, labelProps, progress, spinnerType }) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, ...boxProps, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
7
7
  label && label != "" && /* @__PURE__ */ jsx(Text, { ...labelProps, children: label }),
8
8
  /* @__PURE__ */ jsx(ProgressBar, { value: progress || 0 }),
9
9
  /* @__PURE__ */ jsx(Box, { width: 4, children: /* @__PURE__ */ jsxs(Text, { children: [
@@ -1,34 +1,35 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
- import 'crypto';
5
- import 'fs';
6
- import 'readline-sync';
7
- import 'node:readline';
4
+ import 'node:crypto';
5
+ import 'node:fs';
8
6
  import 'node:path';
7
+ import 'node:readline';
9
8
  import 'node:url';
9
+ import 'readline-sync';
10
10
  import 'luxon';
11
11
  import 'axios';
12
12
  import 'isomorphic-git';
13
- import './index-DxzXU9Hd.js';
13
+ import './index-BhhiXbey.js';
14
14
  import '@oclif/core';
15
- import 'react';
16
15
  import '@tanstack/react-query';
16
+ import 'react';
17
17
  import 'crypto-js';
18
18
  import 'uuid';
19
- import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-DX3e_PPc.js';
19
+ import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-BEphqa18.js';
20
20
  import 'fast-glob';
21
21
  import 'yazl';
22
22
  import 'socket.io-client';
23
- import { T as Table } from './Table-CvM6pccN.js';
23
+ import 'fullscreen-ink';
24
+ import { T as Table } from './Table-FaNgpyeq.js';
24
25
  import { T as Title } from './Title-BCQtayg6.js';
25
26
 
26
27
  const ProjectCredentialsTable = ({ credentialTypeName, queryProps, ...boxProps }) => {
27
- const { isLoading, data } = useProjectCredentials(queryProps);
28
+ const { data, isLoading } = useProjectCredentials(queryProps);
28
29
  const hasActive = data?.data.some((credential) => credential.isActive);
29
30
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, ...boxProps, children: [
30
31
  /* @__PURE__ */ jsx(Title, { children: `${credentialTypeName}s in your ShipThis account` }),
31
- /* @__PURE__ */ jsx(Box, { marginLeft: 2, marginBottom: 1, flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { children: hasActive ? `You have an active ${credentialTypeName} in your ShipThis account.` : `You DO NOT have an active ${credentialTypeName} which ShipThis can use.` }) }),
32
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { children: hasActive ? `You have an active ${credentialTypeName} in your ShipThis account.` : `You DO NOT have an active ${credentialTypeName} which ShipThis can use.` }) }),
32
33
  isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
33
34
  data && data.data.length > 0 && /* @__PURE__ */ jsx(Table, { data: data.data.map(getProjectCredentialSummary) })
34
35
  ] });
@@ -2,14 +2,12 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { Box, Text } from 'ink';
3
3
  import { T as Title } from './Title-BCQtayg6.js';
4
4
 
5
- const StatusRowLabel = ({ label, width }) => /* @__PURE__ */ jsx(Box, { width: width || 10, marginRight: 2, children: /* @__PURE__ */ jsx(Text, { children: `${label}` }) });
6
- const StatusRow = ({ label, labelWidth, value, ...textProps }) => {
7
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", alignItems: "flex-end", children: [
8
- /* @__PURE__ */ jsx(StatusRowLabel, { width: labelWidth, label }),
9
- /* @__PURE__ */ jsx(Text, { bold: true, ...textProps, children: value })
10
- ] });
11
- };
12
- const StatusTable = ({ title, statuses, colors, ...rest }) => {
5
+ const StatusRowLabel = ({ label, width }) => /* @__PURE__ */ jsx(Box, { marginRight: 2, width: width || 10, children: /* @__PURE__ */ jsx(Text, { children: `${label}` }) });
6
+ const StatusRow = ({ label, labelWidth, value, ...textProps }) => /* @__PURE__ */ jsxs(Box, { alignItems: "flex-end", flexDirection: "row", children: [
7
+ /* @__PURE__ */ jsx(StatusRowLabel, { label, width: labelWidth }),
8
+ /* @__PURE__ */ jsx(Text, { bold: true, ...textProps, children: value })
9
+ ] });
10
+ const StatusTable = ({ colors, statuses, title, ...rest }) => {
13
11
  const getColor = (key) => {
14
12
  const value = statuses[key];
15
13
  if (typeof value === "boolean") return value ? "green" : "red";
@@ -26,7 +24,7 @@ const StatusTable = ({ title, statuses, colors, ...rest }) => {
26
24
  const labelWidth = Math.max(maxLabelLength, 10);
27
25
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", ...rest, children: [
28
26
  /* @__PURE__ */ jsx(Title, { children: title }),
29
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: Object.entries(statuses).map(([key, value]) => /* @__PURE__ */ jsx(StatusRow, { labelWidth, label: key, value: getText(key), color: getColor(key) }, key)) })
27
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: Object.entries(statuses).map(([key, value]) => /* @__PURE__ */ jsx(StatusRow, { color: getColor(key), label: key, labelWidth, value: getText(key) }, key)) })
30
28
  ] });
31
29
  };
32
30