shipthis 0.1.31 → 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 (84) hide show
  1. package/dist/{AppleBundleIdDetails-eoK5F8Qn.js → AppleBundleIdDetails-6H3cNWxw.js} +17 -19
  2. package/dist/Command-WPpmLPkL.js +29 -0
  3. package/dist/CommandGame-cxzWG4nT.js +7 -0
  4. package/dist/{Create-ISdroJ3G.js → Create-3Ob8sjik.js} +20 -20
  5. package/dist/GameStatus-BQEtVKvv.js +137 -0
  6. package/dist/{Import-CfThJF6k.js → Import-CFuPDI0K.js} +33 -35
  7. package/dist/{JobLogTail-BWzbQBZz.js → JobLogTail-0CBLoG8N.js} +53 -52
  8. package/dist/{JobProgress-DjIkuk5U.js → JobProgress-lKqVT88m.js} +35 -36
  9. package/dist/{JobStatusTable-CEqWU73q.js → JobStatusTable-C_ZsZJCm.js} +14 -13
  10. package/dist/{NextSteps-CK9zHOCt.js → NextSteps-DbJHmscQ.js} +1 -3
  11. package/dist/{ProgressSpinner-6pw1T8Iw.js → ProgressSpinner-DGcakQSK.js} +1 -1
  12. package/dist/{ProjectCredentialsTable-u9ruZ9mN.js → ProjectCredentialsTable-B5pHOnGu.js} +11 -10
  13. package/dist/{StatusTable-Dm5St4g-.js → StatusTable-DzRWcMr4.js} +7 -9
  14. package/dist/{Table-CvM6pccN.js → Table-FaNgpyeq.js} +15 -15
  15. package/dist/{UserCredentialsTable-Q7u9M-ap.js → UserCredentialsTable-3W3qesh7.js} +18 -19
  16. package/dist/{baseAppleCommand-zhkGlKq0.js → baseAppleCommand-BGV088--.js} +1 -1
  17. package/dist/{baseGameAndroidCommand-DJ-cMLa_.js → baseGameAndroidCommand-CsemgVjp.js} +23 -23
  18. package/dist/commands/apple/apiKey/create.js +35 -35
  19. package/dist/commands/apple/apiKey/export.js +26 -26
  20. package/dist/commands/apple/apiKey/import.js +27 -27
  21. package/dist/commands/apple/apiKey/status.js +31 -31
  22. package/dist/commands/apple/certificate/create.js +39 -39
  23. package/dist/commands/apple/certificate/export.js +26 -26
  24. package/dist/commands/apple/certificate/import.js +27 -27
  25. package/dist/commands/apple/certificate/status.js +31 -31
  26. package/dist/commands/apple/login.js +15 -16
  27. package/dist/commands/apple/status.js +27 -27
  28. package/dist/commands/dashboard.js +10 -11
  29. package/dist/commands/game/android/apiKey/connect.js +28 -28
  30. package/dist/commands/game/android/apiKey/create.js +28 -28
  31. package/dist/commands/game/android/apiKey/export.js +29 -29
  32. package/dist/commands/game/android/apiKey/import.js +31 -31
  33. package/dist/commands/game/android/apiKey/invite.js +14 -15
  34. package/dist/commands/game/android/apiKey/status.js +29 -29
  35. package/dist/commands/game/android/keyStore/create.js +24 -24
  36. package/dist/commands/game/android/keyStore/export.js +28 -28
  37. package/dist/commands/game/android/keyStore/import.js +35 -35
  38. package/dist/commands/game/android/keyStore/status.js +26 -26
  39. package/dist/commands/game/android/status.js +14 -58
  40. package/dist/commands/game/build/download.js +24 -24
  41. package/dist/commands/game/build/list.js +37 -37
  42. package/dist/commands/game/create.js +15 -16
  43. package/dist/commands/game/details.js +35 -36
  44. package/dist/commands/game/export.js +12 -13
  45. package/dist/commands/game/ios/app/addTester.js +24 -24
  46. package/dist/commands/game/ios/app/create.js +24 -24
  47. package/dist/commands/game/ios/app/status.js +29 -29
  48. package/dist/commands/game/ios/app/sync.js +31 -31
  49. package/dist/commands/game/ios/profile/create.js +30 -30
  50. package/dist/commands/game/ios/profile/export.js +28 -28
  51. package/dist/commands/game/ios/profile/import.js +32 -32
  52. package/dist/commands/game/ios/profile/status.js +36 -36
  53. package/dist/commands/game/ios/status.js +46 -58
  54. package/dist/commands/game/ios/wizard.js +31 -31
  55. package/dist/commands/game/job/list.js +34 -34
  56. package/dist/commands/game/job/status.js +31 -31
  57. package/dist/commands/game/list.js +37 -39
  58. package/dist/commands/game/ship.js +73 -71
  59. package/dist/commands/game/status.js +38 -85
  60. package/dist/commands/game/wizard.js +250 -239
  61. package/dist/commands/internal/fastlane.js +15 -18
  62. package/dist/commands/internal/readme.js +38 -37
  63. package/dist/commands/login.js +14 -15
  64. package/dist/commands/status.js +32 -30
  65. package/dist/{export-DZxo2_e_.js → export-CXsVPXA1.js} +5 -5
  66. package/dist/{git-DREGq-jc.js → git-BpsfNFZ_.js} +8 -8
  67. package/dist/{import-8pL1AF47.js → import-DGvG5REx.js} +14 -14
  68. package/dist/{index-w3lHxk5O.js → index-BhhiXbey.js} +240 -224
  69. package/dist/{index-BHh0BZvD.js → index-C03TV1_J.js} +37 -55
  70. package/dist/{index-CyvGh-kt.js → index-C66Dd8Xc.js} +77 -87
  71. package/dist/{index-DJ078v-U.js → index-CGBdOm1q.js} +43 -28
  72. package/dist/{index-DKQjnJrC.js → index-CS9Gwcb0.js} +41 -43
  73. package/dist/{index-C6aAyrXW.js → index-CtTI85m-.js} +6 -6
  74. package/dist/{upload-BTpxj3QP.js → upload-8y5MQEm9.js} +22 -22
  75. package/dist/{useAndroidServiceAccountTestResult-Dy3Ag7_r.js → useAndroidServiceAccountTestResult-DZk5SMxI.js} +11 -13
  76. package/dist/{useAppleApp-h1Ogi_qc.js → useAppleApp-DWYGURwU.js} +4 -4
  77. package/dist/{useAppleBundleId-B3TTNap0.js → useAppleBundleId-PsTJ2g1B.js} +6 -6
  78. package/dist/{useProjectCredentials-DpeXZcHP.js → useProjectCredentials-BEphqa18.js} +10 -12
  79. package/dist/{useWebSocket-gyuCsore.js → useWebSocket-5PYa2QER.js} +1 -1
  80. package/dist/utils/help.js +4 -4
  81. package/package.json +4 -3
  82. package/dist/Command-DFdHXDiU.js +0 -44
  83. package/dist/CommandGame-Dif-oSky.js +0 -9
  84. package/dist/{RunWithSpinner-BVXNWGD3.js → RunWithSpinner-gMVA07bZ.js} +2 -2
@@ -1,54 +1,79 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { Args } from '@oclif/core';
3
- import { p as getAuthedHeaders, q as API_URL, I as castArrayObjectDates, _ as queryClient, a9 as updateProject, u as getGodotVersion, t as GameEngine, v as createProject, w as DEFAULT_IGNORED_FILES_GLOBS, x as DEFAULT_SHIPPED_FILES_GLOBS, P as Platform, J as JobStatus, W as WEB_URL, F as getProject, C as CredentialsType, Q as getGoogleStatus, B as BaseAuthenticatedCommand, j as isCWDGodotGame } from '../../index-w3lHxk5O.js';
4
- import React, { useState, useContext, useEffect, useRef } from 'react';
5
- import { Text, Box, useInput } from 'ink';
6
- import { d as CommandContext, b as GameContext, M as Markdown, u as useBuilds, q as queryBuilds, G as GameProvider, f as CreateGooglePlayGame } from '../../index-CyvGh-kt.js';
3
+ import { useScreenSize, withFullScreen } from 'fullscreen-ink';
4
+ import { K as queryClient, p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates, a9 as updateProject, t as getGodotVersion, s as GameEngine, u as createProject, v as DEFAULT_SHIPPED_FILES_GLOBS, w as DEFAULT_IGNORED_FILES_GLOBS, P as Platform, J as JobStatus, W as WEB_URL, E as getProject, C as CredentialsType, Q as getGoogleStatus, B as BaseAuthenticatedCommand, j as isCWDGodotGame } from '../../index-BhhiXbey.js';
5
+ import { Box, Text, useInput } from 'ink';
7
6
  import Spinner from 'ink-spinner';
8
- import { Alert, TextInput } from '@inkjs/ui';
9
- import axios from 'axios';
10
- import 'crypto-js';
11
- import 'uuid';
12
- import fs__default from 'fs';
13
- import 'luxon';
14
- import { useQuery, useMutation } from '@tanstack/react-query';
15
- import 'yazl';
16
- import 'crypto';
17
- import 'readline-sync';
18
- import 'node:readline';
7
+ import 'node:crypto';
8
+ import fs__default from 'node:fs';
19
9
  import 'node:path';
10
+ import 'node:readline';
20
11
  import 'node:url';
12
+ import 'readline-sync';
13
+ import 'luxon';
14
+ import axios from 'axios';
21
15
  import 'isomorphic-git';
16
+ import { useMutation, useQuery } from '@tanstack/react-query';
17
+ import React, { useState, useContext, useEffect, useRef } from 'react';
18
+ import 'crypto-js';
19
+ import 'uuid';
22
20
  import 'fast-glob';
21
+ import 'yazl';
23
22
  import 'socket.io-client';
23
+ import 'string-length';
24
+ import 'strip-ansi';
24
25
  import 'open';
26
+ import { C as ConnectGoogle } from '../../index-C03TV1_J.js';
27
+ import { C as CommandContext, G as GameContext, u as useBuilds, M as Markdown, q as queryBuilds, c as GameProvider, f as CreateGooglePlayGame } from '../../index-C66Dd8Xc.js';
28
+ import { TextInput, Alert } from '@inkjs/ui';
25
29
  import 'marked';
26
30
  import 'marked-terminal';
27
- import 'path';
28
31
  import 'qrcode';
29
- import 'string-length';
30
- import 'strip-ansi';
31
- import { C as CreateKeystore } from '../../Create-ISdroJ3G.js';
32
- import { I as ImportKeystore } from '../../Import-CfThJF6k.js';
33
- import { u as useResponsive, C as ConnectGoogle } from '../../index-BHh0BZvD.js';
34
- import { C as CreateServiceAccountKey } from '../../index-DKQjnJrC.js';
35
- import { g as getShortUUID } from '../../index-DJ078v-U.js';
36
- import { u as useShip, J as JobProgress } from '../../JobProgress-DjIkuk5U.js';
37
- import { c as cacheKeys, f as fetchKeyTestResult, K as KeyTestStatus, a as KeyTestError } from '../../useAndroidServiceAccountTestResult-Dy3Ag7_r.js';
38
- import { J as JobLogTail } from '../../JobLogTail-BWzbQBZz.js';
39
- import { a as getProjectCredentials } from '../../index-C6aAyrXW.js';
32
+ import { g as getShortUUID } from '../../index-CGBdOm1q.js';
33
+ import { J as JobLogTail } from '../../JobLogTail-0CBLoG8N.js';
34
+ import { c as cacheKeys, f as fetchKeyTestResult, K as KeyTestStatus, a as KeyTestError } from '../../useAndroidServiceAccountTestResult-DZk5SMxI.js';
35
+ import { u as useShip, J as JobProgress } from '../../JobProgress-lKqVT88m.js';
36
+ import { C as CreateServiceAccountKey } from '../../index-CS9Gwcb0.js';
37
+ import { C as CreateKeystore } from '../../Create-3Ob8sjik.js';
38
+ import { I as ImportKeystore } from '../../Import-CFuPDI0K.js';
39
+ import { a as getProjectCredentials } from '../../index-CtTI85m-.js';
40
40
  import { T as Title } from '../../Title-BCQtayg6.js';
41
- import { C as Command } from '../../Command-DFdHXDiU.js';
42
- import { withFullScreen } from 'fullscreen-ink';
41
+ import { C as Command } from '../../Command-WPpmLPkL.js';
43
42
  import '@expo/apple-utils/build/index.js';
44
- import 'ini';
45
43
  import 'deepmerge';
46
- import '../../RunWithSpinner-BVXNWGD3.js';
47
- import '../../import-8pL1AF47.js';
48
- import '../../useWebSocket-gyuCsore.js';
49
- import '../../useProjectCredentials-DpeXZcHP.js';
50
- import '../../ProgressSpinner-6pw1T8Iw.js';
51
- import '../../git-DREGq-jc.js';
44
+ import 'ini';
45
+ import '../../useWebSocket-5PYa2QER.js';
46
+ import '../../git-BpsfNFZ_.js';
47
+ import '../../ProgressSpinner-DGcakQSK.js';
48
+ import '../../useProjectCredentials-BEphqa18.js';
49
+ import '../../RunWithSpinner-gMVA07bZ.js';
50
+ import '../../import-DGvG5REx.js';
51
+
52
+ const useInviteServiceAccount = () => useMutation({
53
+ async mutationFn({ developerId, projectId }) {
54
+ try {
55
+ const headers = getAuthedHeaders();
56
+ const { data } = await axios.post(
57
+ `${API_URL}/projects/${projectId}/credentials/android/key/invite/`,
58
+ { developerId },
59
+ {
60
+ headers
61
+ }
62
+ );
63
+ return data;
64
+ } catch (error) {
65
+ console.error("useInviteMutation Error", error);
66
+ throw error;
67
+ }
68
+ },
69
+ async onSuccess(data) {
70
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
71
+ await sleep(1e3);
72
+ queryClient.invalidateQueries({
73
+ queryKey: cacheKeys.androidKeyTestResult({ projectId: data.projectId })
74
+ });
75
+ }
76
+ });
52
77
 
53
78
  async function queryJobs({ projectId, ...pageAndSortParams }) {
54
79
  try {
@@ -66,39 +91,30 @@ async function queryJobs({ projectId, ...pageAndSortParams }) {
66
91
  }
67
92
  const useJobs = (props) => {
68
93
  const queryResult = useQuery({
69
- queryKey: cacheKeys.jobs(props),
70
- queryFn: async () => queryJobs(props)
94
+ queryFn: async () => queryJobs(props),
95
+ queryKey: cacheKeys.jobs(props)
71
96
  });
72
97
  return queryResult;
73
98
  };
74
99
 
75
- const useInviteServiceAccount = () => {
76
- return useMutation({
77
- mutationFn: async ({ projectId, developerId }) => {
78
- try {
79
- const headers = getAuthedHeaders();
80
- const { data } = await axios.post(
81
- `${API_URL}/projects/${projectId}/credentials/android/key/invite/`,
82
- { developerId },
83
- {
84
- headers
85
- }
86
- );
87
- return data;
88
- } catch (error) {
89
- console.error("useInviteMutation Error", error);
90
- throw error;
91
- }
92
- },
93
- onSuccess: async (data) => {
94
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
95
- await sleep(1e3);
96
- queryClient.invalidateQueries({
97
- queryKey: cacheKeys.androidKeyTestResult({ projectId: data.projectId })
98
- });
99
- }
100
- });
101
- };
100
+ const WIDE_BREAKPOINT = 100;
101
+ const TALL_BREAKPOINT = 35;
102
+ function useResponsive() {
103
+ const { height, width } = useScreenSize();
104
+ const isWide = width >= WIDE_BREAKPOINT;
105
+ const isTall = height >= TALL_BREAKPOINT;
106
+ return {
107
+ height,
108
+ isTall,
109
+ isWide,
110
+ width
111
+ };
112
+ }
113
+
114
+ const FormTextInput = ({ label, labelProps, ...rest }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
115
+ /* @__PURE__ */ jsx(Text, { ...labelProps, children: label }),
116
+ /* @__PURE__ */ jsx(TextInput, { ...rest })
117
+ ] });
102
118
 
103
119
  const GameInfoForm = ({ gameInfo, onSubmit }) => {
104
120
  const [activeInput, setActiveInput] = useState("name");
@@ -115,18 +131,18 @@ const GameInfoForm = ({ gameInfo, onSubmit }) => {
115
131
  };
116
132
  const handleSubmitPackageName = () => {
117
133
  setError(null);
118
- const packageRegex = /^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)+$/;
134
+ const packageRegex = /^[A-Za-z]\w*(\.[A-Za-z]\w*)+$/;
119
135
  if (!packageRegex.test(`${androidPackageName}`)) {
120
136
  setError("Please enter a valid package name e.g. com.flappy.souls");
121
137
  return;
122
138
  }
123
139
  onSubmit({
124
140
  ...gameInfo,
125
- name,
126
141
  details: {
127
142
  ...gameInfo.details,
128
143
  androidPackageName
129
- }
144
+ },
145
+ name
130
146
  });
131
147
  };
132
148
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -136,23 +152,23 @@ const GameInfoForm = ({ gameInfo, onSubmit }) => {
136
152
  /* @__PURE__ */ jsx(
137
153
  FormTextInput,
138
154
  {
139
- label: "Game name:",
140
- isDisabled: activeInput !== "name",
141
155
  defaultValue: name,
142
- placeholder: "Enter the name of your game...",
156
+ isDisabled: activeInput !== "name",
157
+ label: "Game name:",
143
158
  onChange: setName,
144
- onSubmit: handleSubmitName
159
+ onSubmit: handleSubmitName,
160
+ placeholder: "Enter the name of your game..."
145
161
  }
146
162
  ),
147
163
  /* @__PURE__ */ jsx(
148
164
  FormTextInput,
149
165
  {
150
- label: "Android package name :",
151
- isDisabled: activeInput !== "androidPackageName",
152
166
  defaultValue: androidPackageName,
153
- placeholder: "e.g. com.flappy.souls",
167
+ isDisabled: activeInput !== "androidPackageName",
168
+ label: "Android package name :",
154
169
  onChange: setAndroidPackageName,
155
- onSubmit: handleSubmitPackageName
170
+ onSubmit: handleSubmitPackageName,
171
+ placeholder: "e.g. com.flappy.souls"
156
172
  }
157
173
  )
158
174
  ] })
@@ -162,11 +178,11 @@ const GameInfoForm = ({ gameInfo, onSubmit }) => {
162
178
  const getGameInfo = (flagValues, project) => {
163
179
  const androidPackageName = flagValues.androidPackageName || project?.details?.androidPackageName || "";
164
180
  const gameInfo = {
165
- name: project?.name || flagValues.name || "",
166
181
  details: {
167
182
  ...project?.details,
168
183
  androidPackageName
169
- }
184
+ },
185
+ name: project?.name || flagValues.name || ""
170
186
  };
171
187
  return gameInfo;
172
188
  };
@@ -175,11 +191,11 @@ const CreateGame = (props) => {
175
191
  const [gameInfo, setGameInfo] = useState(null);
176
192
  const [showForm, setShowForm] = useState(false);
177
193
  const { command } = useContext(CommandContext);
178
- const { setGameId, game } = useContext(GameContext);
194
+ const { game, setGameId } = useContext(GameContext);
179
195
  const handleLoad = async () => {
180
196
  if (!command) throw new Error("No command");
181
197
  const flags = command.getDetailsFlagsValues();
182
- const config = await command.getProjectConfigSafe();
198
+ const config = command.getProjectConfigSafe();
183
199
  setShowForm(true);
184
200
  setIsLoading(false);
185
201
  const info = getGameInfo(flags, config.project);
@@ -193,7 +209,7 @@ const CreateGame = (props) => {
193
209
  setShowForm(false);
194
210
  setIsLoading(true);
195
211
  if (!command) throw new Error("No command");
196
- const projectConfig = await command.getProjectConfigSafe();
212
+ const projectConfig = command.getProjectConfigSafe();
197
213
  const existingGame = projectConfig.project;
198
214
  const isNew = !existingGame;
199
215
  if (!isNew) {
@@ -205,142 +221,40 @@ const CreateGame = (props) => {
205
221
  await command.setProjectConfig(updatedConfig);
206
222
  return props.onComplete();
207
223
  }
208
- const { name, details } = gameInfo2;
224
+ const { details, name } = gameInfo2;
209
225
  const projectDetails = {
210
226
  ...details,
211
227
  gameEngine: GameEngine.GODOT,
212
228
  gameEngineVersion: getGodotVersion()
213
229
  };
214
- const project = await createProject({ name, details: projectDetails });
230
+ const project = await createProject({ details: projectDetails, name });
215
231
  await command.setProjectConfig({
232
+ ignoredFilesGlobs: DEFAULT_IGNORED_FILES_GLOBS,
216
233
  project,
217
- shippedFilesGlobs: DEFAULT_SHIPPED_FILES_GLOBS,
218
- ignoredFilesGlobs: DEFAULT_IGNORED_FILES_GLOBS
234
+ shippedFilesGlobs: DEFAULT_SHIPPED_FILES_GLOBS
219
235
  });
220
236
  setGameId(project.id);
221
237
  props.onComplete();
222
- } catch (e) {
223
- props.onError(e);
238
+ } catch (error) {
239
+ props.onError(error);
224
240
  }
225
241
  };
226
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, borderStyle: "single", margin: 1, children: [
242
+ return /* @__PURE__ */ jsxs(Box, { borderStyle: "single", flexDirection: "column", gap: 1, margin: 1, children: [
227
243
  isLoading && /* @__PURE__ */ jsx(Spinner, {}),
228
244
  showForm && gameInfo && /* @__PURE__ */ jsx(GameInfoForm, { gameInfo, onSubmit: handleSubmitForm })
229
245
  ] });
230
246
  };
231
247
 
232
- const FormTextInput = ({ label, labelProps, ...rest }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
233
- /* @__PURE__ */ jsx(Text, { ...labelProps, children: label }),
234
- /* @__PURE__ */ jsx(TextInput, { ...rest })
235
- ] });
236
-
237
- const ImportForm = ({ importKeystoreProps, onSubmit }) => {
238
- const [activeInput, setActiveInput] = useState("jksFilePath" /* jksFilePath */);
239
- const [error, setError] = useState(null);
240
- const [jksFilePath, setJksFilePath] = useState(importKeystoreProps.jksFilePath);
241
- const [password, setPassword] = useState(importKeystoreProps.keyPassword);
242
- const handleSubmitJksFilePath = () => {
243
- setError(null);
244
- if (!jksFilePath || jksFilePath.length === 0) {
245
- setError("Please enter a path to your jks file");
246
- return;
247
- }
248
- if (!fs__default.existsSync(jksFilePath)) {
249
- setError("The file does not exist");
250
- return;
251
- }
252
- setActiveInput("password" /* password */);
253
- };
254
- const handleSubmitPassword = () => {
255
- setError(null);
256
- if (!password || password.length === 0) {
257
- setError("Please enter a password");
258
- return;
259
- }
260
- onSubmit({
261
- ...importKeystoreProps,
262
- jksFilePath,
263
- keyPassword: password,
264
- keystorePassword: password
265
- });
266
- };
267
- return /* @__PURE__ */ jsxs(Fragment, { children: [
268
- error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }),
269
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [
270
- /* @__PURE__ */ jsx(
271
- FormTextInput,
272
- {
273
- label: "Path to your jks file:",
274
- isDisabled: activeInput !== "jksFilePath" /* jksFilePath */,
275
- defaultValue: jksFilePath,
276
- placeholder: "Enter the path to your jks file...",
277
- onChange: setJksFilePath,
278
- onSubmit: handleSubmitJksFilePath
279
- }
280
- ),
281
- /* @__PURE__ */ jsx(
282
- FormTextInput,
283
- {
284
- label: "Password:",
285
- isDisabled: activeInput !== "password" /* password */,
286
- defaultValue: password,
287
- placeholder: "Enter the password for your jks file...",
288
- onChange: setPassword,
289
- onSubmit: handleSubmitPassword
290
- }
291
- )
292
- ] })
293
- ] });
294
- };
295
-
296
- const CreateOrImport = ({ onComplete, onError, ...boxProps }) => {
297
- const [stage, setStage] = useState(0 /* Choose */);
298
- const [importKeystoreProps, setImportKeystoreProps] = useState({
299
- jksFilePath: "",
300
- keyPassword: "",
301
- keystorePassword: ""
302
- });
303
- useInput(async (input) => {
304
- if (stage !== 0 /* Choose */) return;
305
- if (input === "c") return setStage(1 /* Create */);
306
- if (input === "i") return setStage(2 /* ImportForm */);
307
- });
308
- const handleImportFormSubmit = (newImportProps) => {
309
- setImportKeystoreProps(newImportProps);
310
- setStage(3 /* ImportKeystore */);
311
- };
312
- const renderStage = () => {
313
- switch (stage) {
314
- case 0 /* Choose */:
315
- return /* @__PURE__ */ jsxs(Fragment, { children: [
316
- /* @__PURE__ */ jsx(Text, { children: "Would you like to create a new keystore or import an existing one?" }),
317
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Press C to create a new keystore" }),
318
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Press I to import an existing keystore" })
319
- ] });
320
- case 1 /* Create */:
321
- return /* @__PURE__ */ jsx(CreateKeystore, { onComplete, onError });
322
- case 2 /* ImportForm */:
323
- return /* @__PURE__ */ jsx(ImportForm, { onSubmit: handleImportFormSubmit, importKeystoreProps });
324
- case 3 /* ImportKeystore */:
325
- return /* @__PURE__ */ jsx(ImportKeystore, { onComplete, onError, importKeystoreProps });
326
- }
327
- };
328
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, ...boxProps, children: [
329
- /* @__PURE__ */ jsx(Markdown, { filename: "create-or-import-keystore.md", templateVars: {} }),
330
- renderStage()
331
- ] });
332
- };
333
-
334
248
  const CreateInitialBuild = (props) => {
335
249
  const { gameId } = useContext(GameContext);
336
250
  return /* @__PURE__ */ jsx(Fragment, { children: gameId && /* @__PURE__ */ jsx(CreateForGame, { gameId, ...props }) });
337
251
  };
338
- const CreateForGame = ({ onComplete, onError, gameId, ...boxProps }) => {
252
+ const CreateForGame = ({ gameId, onComplete, onError, ...boxProps }) => {
339
253
  const { command } = useContext(CommandContext);
340
- const { data: buildData, isLoading: isLoadingBuilds } = useBuilds({ projectId: gameId, pageNumber: 0 });
254
+ const { data: buildData, isLoading: isLoadingBuilds } = useBuilds({ pageNumber: 0, projectId: gameId });
341
255
  const { data: jobData, isLoading: isLoadingJobs } = useJobs({
342
- projectId: gameId,
343
- pageNumber: 0
256
+ pageNumber: 0,
257
+ projectId: gameId
344
258
  });
345
259
  const prevHasBuild = useRef(false);
346
260
  const shipMutation = useShip();
@@ -393,7 +307,7 @@ const CreateForGame = ({ onComplete, onError, gameId, ...boxProps }) => {
393
307
  }
394
308
  }
395
309
  ),
396
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(JobLogTail, { jobId: failedJob.id, projectId: gameId, isWatching: false, length: 10 }) })
310
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(JobLogTail, { isWatching: false, jobId: failedJob.id, length: 10, projectId: gameId }) })
397
311
  ] })
398
312
  ] }) });
399
313
  };
@@ -414,12 +328,12 @@ const InviteForm = ({ onSubmit }) => {
414
328
  /* @__PURE__ */ jsx(
415
329
  FormTextInput,
416
330
  {
331
+ defaultValue: accountId,
417
332
  label: "Please enter your Google Play Account ID:",
418
333
  labelProps: { bold: true },
419
- defaultValue: accountId,
420
- placeholder: "e.g. 8110853839480950872",
421
334
  onChange: setAccountId,
422
- onSubmit: handleSubmitAccountId
335
+ onSubmit: handleSubmitAccountId,
336
+ placeholder: "e.g. 8110853839480950872"
423
337
  }
424
338
  ),
425
339
  error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error })
@@ -432,7 +346,7 @@ const InviteServiceAccount = ({ onComplete, onError, ...boxProps }) => {
432
346
  const handleSubmit = async (developerId) => {
433
347
  try {
434
348
  if (!gameId) return;
435
- await inviteMutation.mutateAsync({ projectId: gameId, developerId });
349
+ await inviteMutation.mutateAsync({ developerId, projectId: gameId });
436
350
  onComplete();
437
351
  } catch (error) {
438
352
  onError(error);
@@ -450,11 +364,112 @@ const InviteServiceAccount = ({ onComplete, onError, ...boxProps }) => {
450
364
  ] }) });
451
365
  };
452
366
 
367
+ const ImportForm = ({ importKeystoreProps, onSubmit }) => {
368
+ const [activeInput, setActiveInput] = useState("jksFilePath" /* jksFilePath */);
369
+ const [error, setError] = useState(null);
370
+ const [jksFilePath, setJksFilePath] = useState(importKeystoreProps.jksFilePath);
371
+ const [password, setPassword] = useState(importKeystoreProps.keyPassword);
372
+ const handleSubmitJksFilePath = () => {
373
+ setError(null);
374
+ if (!jksFilePath || jksFilePath.length === 0) {
375
+ setError("Please enter a path to your jks file");
376
+ return;
377
+ }
378
+ if (!fs__default.existsSync(jksFilePath)) {
379
+ setError("The file does not exist");
380
+ return;
381
+ }
382
+ setActiveInput("password" /* password */);
383
+ };
384
+ const handleSubmitPassword = () => {
385
+ setError(null);
386
+ if (!password || password.length === 0) {
387
+ setError("Please enter a password");
388
+ return;
389
+ }
390
+ onSubmit({
391
+ ...importKeystoreProps,
392
+ jksFilePath,
393
+ keyPassword: password,
394
+ keystorePassword: password
395
+ });
396
+ };
397
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
398
+ error && /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }),
399
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [
400
+ /* @__PURE__ */ jsx(
401
+ FormTextInput,
402
+ {
403
+ defaultValue: jksFilePath,
404
+ isDisabled: activeInput !== "jksFilePath" /* jksFilePath */,
405
+ label: "Path to your jks file:",
406
+ onChange: setJksFilePath,
407
+ onSubmit: handleSubmitJksFilePath,
408
+ placeholder: "Enter the path to your jks file..."
409
+ }
410
+ ),
411
+ /* @__PURE__ */ jsx(
412
+ FormTextInput,
413
+ {
414
+ defaultValue: password,
415
+ isDisabled: activeInput !== "password" /* password */,
416
+ label: "Password:",
417
+ onChange: setPassword,
418
+ onSubmit: handleSubmitPassword,
419
+ placeholder: "Enter the password for your jks file..."
420
+ }
421
+ )
422
+ ] })
423
+ ] });
424
+ };
425
+
426
+ const CreateOrImport = ({ onComplete, onError, ...boxProps }) => {
427
+ const [stage, setStage] = useState(0 /* Choose */);
428
+ const [importKeystoreProps, setImportKeystoreProps] = useState({
429
+ jksFilePath: "",
430
+ keyPassword: "",
431
+ keystorePassword: ""
432
+ });
433
+ useInput(async (input) => {
434
+ if (stage !== 0 /* Choose */) return;
435
+ if (input === "c") return setStage(1 /* Create */);
436
+ if (input === "i") return setStage(2 /* ImportForm */);
437
+ });
438
+ const handleImportFormSubmit = (newImportProps) => {
439
+ setImportKeystoreProps(newImportProps);
440
+ setStage(3 /* ImportKeystore */);
441
+ };
442
+ const renderStage = () => {
443
+ switch (stage) {
444
+ case 0 /* Choose */: {
445
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
446
+ /* @__PURE__ */ jsx(Text, { children: "Would you like to create a new keystore or import an existing one?" }),
447
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Press C to create a new keystore" }),
448
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Press I to import an existing keystore" })
449
+ ] });
450
+ }
451
+ case 1 /* Create */: {
452
+ return /* @__PURE__ */ jsx(CreateKeystore, { onComplete, onError });
453
+ }
454
+ case 2 /* ImportForm */: {
455
+ return /* @__PURE__ */ jsx(ImportForm, { importKeystoreProps, onSubmit: handleImportFormSubmit });
456
+ }
457
+ case 3 /* ImportKeystore */: {
458
+ return /* @__PURE__ */ jsx(ImportKeystore, { importKeystoreProps, onComplete, onError });
459
+ }
460
+ }
461
+ };
462
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, ...boxProps, children: [
463
+ /* @__PURE__ */ jsx(Markdown, { filename: "create-or-import-keystore.md", templateVars: {} }),
464
+ renderStage()
465
+ ] });
466
+ };
467
+
453
468
  var StepStatus = /* @__PURE__ */ ((StepStatus2) => {
469
+ StepStatus2["FAILURE"] = "FAILURE";
454
470
  StepStatus2["PENDING"] = "PENDING";
455
471
  StepStatus2["RUNNING"] = "RUNNING";
456
472
  StepStatus2["SUCCESS"] = "SUCCESS";
457
- StepStatus2["FAILURE"] = "FAILURE";
458
473
  StepStatus2["WARN"] = "WARN";
459
474
  return StepStatus2;
460
475
  })(StepStatus || {});
@@ -479,20 +494,20 @@ const getStepInitialStatus = (step, statusFlags) => {
479
494
  }
480
495
  const base = {
481
496
  createGame: statusFlags.hasGameName && statusFlags.hasAndroidPackageName,
497
+ createGooglePlayGame: statusFlags.hasGooglePlayGame,
482
498
  createKeystore: statusFlags.hasAndroidKeystore,
483
499
  createServiceAccount: statusFlags.hasServiceAccountKey,
484
- createGooglePlayGame: statusFlags.hasGooglePlayGame,
485
500
  inviteServiceAccount: statusFlags.hasInvitedServiceAccount
486
501
  };
487
502
  return base[step] ? "SUCCESS" /* SUCCESS */ : "PENDING" /* PENDING */;
488
503
  };
489
504
  const getStatusFlags = async (cmd) => {
490
- const projectConfig = await cmd.getProjectConfigSafe();
505
+ const projectConfig = cmd.getProjectConfigSafe();
491
506
  const projectId = projectConfig.project?.id;
492
- const project = !!projectId && await getProject(projectId);
493
- const hasShipThisProject = !!project;
494
- const hasGameName = project && !!project?.name;
495
- const hasAndroidPackageName = project && !!project?.details?.androidPackageName;
507
+ const project = Boolean(projectId) && await getProject(projectId);
508
+ const hasShipThisProject = Boolean(project);
509
+ const hasGameName = project && Boolean(project?.name);
510
+ const hasAndroidPackageName = project && Boolean(project?.details?.androidPackageName);
496
511
  const projectCredentials = hasShipThisProject ? await getProjectCredentials(project.id) : [];
497
512
  const hasAndroidKeystore = projectCredentials.some(
498
513
  (cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type == CredentialsType.CERTIFICATE
@@ -502,35 +517,37 @@ const getStatusFlags = async (cmd) => {
502
517
  const hasServiceAccountKey = projectCredentials.some(
503
518
  (cred) => cred.isActive && cred.platform == Platform.ANDROID && cred.type == CredentialsType.KEY
504
519
  );
505
- const buildsResponse = !!projectId && hasShipThisProject && await queryBuilds({ projectId, pageNumber: 0 });
506
- const hasInitialBuild = !!buildsResponse && buildsResponse.data.some((build) => build.platform === Platform.ANDROID);
520
+ const buildsResponse = Boolean(projectId) && hasShipThisProject && await queryBuilds({ pageNumber: 0, projectId });
521
+ const hasInitialBuild = Boolean(buildsResponse) && buildsResponse.data.some((build) => build.platform === Platform.ANDROID);
507
522
  const testResult = projectId ? await fetchKeyTestResult({ projectId }) : null;
508
523
  const hasGooglePlayGame = testResult && testResult?.status === KeyTestStatus.SUCCESS || testResult?.status === KeyTestStatus.ERROR && testResult?.error === KeyTestError.NOT_INVITED;
509
524
  const hasInvitedServiceAccount = testResult ? testResult?.status === KeyTestStatus.SUCCESS : false;
510
525
  return {
511
- hasShipThisProject,
512
- hasGameName,
513
- hasAndroidPackageName,
514
526
  hasAndroidKeystore,
527
+ hasAndroidPackageName,
528
+ hasGameName,
515
529
  hasGoogleConnection,
516
- hasServiceAccountKey,
517
- hasInitialBuild,
518
530
  hasGooglePlayGame,
519
- hasInvitedServiceAccount
531
+ hasInitialBuild,
532
+ hasInvitedServiceAccount,
533
+ hasServiceAccountKey,
534
+ hasShipThisProject
520
535
  };
521
536
  };
522
537
 
523
538
  const StepLabels = {
539
+ connectGoogle: "Connect ShipThis with Google",
524
540
  createGame: "Create game in ShipThis",
541
+ createGooglePlayGame: "Create the game in Google Play",
542
+ createInitialBuild: "Create an initial build",
525
543
  createKeystore: "Create or import an Android Keystore",
526
- connectGoogle: "Connect ShipThis with Google",
527
544
  createServiceAccount: "Create a Service Account & API Key",
528
- createInitialBuild: "Create an initial build",
529
- createGooglePlayGame: "Create the game in Google Play",
530
545
  inviteServiceAccount: "Invite the Service Account"
531
546
  };
532
- const StepWithStatus = ({ position, title, status }) => {
547
+ const StepWithStatus = ({ position, status, title }) => {
533
548
  const indicator = {
549
+ [StepStatus.FAILURE]: "\u274C",
550
+ // this is 2 wide?
534
551
  [StepStatus.PENDING]: " ",
535
552
  // double space
536
553
  [StepStatus.RUNNING]: /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -539,8 +556,6 @@ const StepWithStatus = ({ position, title, status }) => {
539
556
  ] }),
540
557
  [StepStatus.SUCCESS]: "\u2705",
541
558
  // this is 2 wide?
542
- [StepStatus.FAILURE]: "\u274C",
543
- // this is 2 wide?
544
559
  [StepStatus.WARN]: "\u26A0\uFE0F "
545
560
  // double
546
561
  }[status];
@@ -553,16 +568,12 @@ const StepWithStatus = ({ position, title, status }) => {
553
568
  title
554
569
  ] });
555
570
  };
556
- const StepStatusTable = ({ stepStatuses }) => {
557
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 1, children: Steps.map((step, index) => {
558
- return /* @__PURE__ */ jsx(StepWithStatus, { position: index + 1, title: StepLabels[step], status: stepStatuses[index] }, step);
559
- }) });
560
- };
571
+ const StepStatusTable = ({ stepStatuses }) => /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 1, children: Steps.map((step, index) => /* @__PURE__ */ jsx(StepWithStatus, { position: index + 1, status: stepStatuses[index], title: StepLabels[step] }, step)) });
561
572
 
562
573
  const WizardHeader = ({ currentStepIndex, stepStatuses }) => {
563
574
  const { isTall } = useResponsive();
564
575
  const stepCount = stepStatuses ? stepStatuses.length : 0;
565
- const currentStep = currentStepIndex !== null ? currentStepIndex + 1 : null;
576
+ const currentStep = currentStepIndex === null ? null : currentStepIndex + 1;
566
577
  const title = isTall ? "ShipThis Android Wizard" : `ShipThis Android Wizard (step ${currentStep} of ${stepCount})`;
567
578
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
568
579
  /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Title, { children: title }) }),
@@ -571,18 +582,18 @@ const WizardHeader = ({ currentStepIndex, stepStatuses }) => {
571
582
  };
572
583
 
573
584
  const stepComponentMap = {
585
+ connectGoogle: ConnectGoogle,
574
586
  createGame: CreateGame,
587
+ createGooglePlayGame: CreateGooglePlayGame,
588
+ createInitialBuild: CreateInitialBuild,
575
589
  createKeystore: CreateOrImport,
576
- connectGoogle: ConnectGoogle,
577
590
  createServiceAccount: CreateServiceAccountKey,
578
- createInitialBuild: CreateInitialBuild,
579
- createGooglePlayGame: CreateGooglePlayGame,
580
591
  inviteServiceAccount: InviteServiceAccount
581
592
  };
582
593
  const ON_COMPLETE_DELAY_MS = 500;
583
594
  const AndroidWizard = (props) => {
584
595
  const { command } = React.useContext(CommandContext);
585
- const { isWide, isTall } = useResponsive();
596
+ const { isTall, isWide } = useResponsive();
586
597
  const [currentStep, setCurrentStep] = useState(null);
587
598
  const [currentStepIndex, setCurrentStepIndex] = useState(null);
588
599
  const [stepStatuses, setStepStatuses] = useState(null);
@@ -591,7 +602,7 @@ const AndroidWizard = (props) => {
591
602
  if (!command) return;
592
603
  const statusFlags = await getStatusFlags(command);
593
604
  const initStatuses = Steps.map((step) => getStepInitialStatus(step, statusFlags));
594
- const firstPending = initStatuses.findIndex((status) => status === StepStatus.PENDING);
605
+ const firstPending = initStatuses.indexOf(StepStatus.PENDING);
595
606
  const pendingStep = firstPending === -1 ? null : Steps[firstPending];
596
607
  const withPending = initStatuses.map((status, index) => {
597
608
  if (index === firstPending) return StepStatus.RUNNING;
@@ -610,18 +621,18 @@ const AndroidWizard = (props) => {
610
621
  const handleStepComplete = () => determineStep().catch(props.onError);
611
622
  const StepInterface = currentStep ? stepComponentMap[currentStep] : null;
612
623
  const templateVars = {
613
- iosSetupURL: new URL("/docs/ios", WEB_URL).toString(),
614
- docsURL: new URL("/docs", WEB_URL).toString()
624
+ docsURL: new URL("/docs", WEB_URL).toString(),
625
+ iosSetupURL: new URL("/docs/ios", WEB_URL).toString()
615
626
  };
616
627
  return /* @__PURE__ */ jsxs(GameProvider, { children: [
617
- /* @__PURE__ */ jsx(WizardHeader, { stepStatuses, currentStepIndex }),
628
+ /* @__PURE__ */ jsx(WizardHeader, { currentStepIndex, stepStatuses }),
618
629
  StepInterface && /* @__PURE__ */ jsx(
619
630
  StepInterface,
620
631
  {
632
+ borderStyle: isTall && isWide ? "single" : void 0,
633
+ margin: isTall && isWide ? 1 : 0,
621
634
  onComplete: handleStepComplete,
622
635
  onError: props.onError,
623
- margin: isTall && isWide ? 1 : 0,
624
- borderStyle: isTall && isWide ? "single" : void 0,
625
636
  padding: isTall && isWide ? 1 : 0
626
637
  }
627
638
  ),
@@ -633,8 +644,8 @@ class GameWizard extends BaseAuthenticatedCommand {
633
644
  static args = {
634
645
  platform: Args.string({
635
646
  description: 'The platform to run the wizard for. This can be "android" or "ios"',
636
- required: true,
637
- options: ["android", "ios"]
647
+ options: ["android", "ios"],
648
+ required: true
638
649
  })
639
650
  };
640
651
  static description = "Runs all the steps for the specific platform";