shipthis 0.1.50 → 0.1.52

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 (102) hide show
  1. package/README.md +1 -1
  2. package/dist/{AppleBundleIdDetails-4WNaBSGY.js → AppleBundleIdDetails-BUJnAu52.js} +4 -4
  3. package/dist/{Command-DuEKI93-.js → Command-B-MWAVPL.js} +2 -2
  4. package/dist/CommandGame-DPJEVhuw.js +14 -0
  5. package/dist/{Create-DUl1dfhZ.js → Create-CmEndHAZ.js} +2 -2
  6. package/dist/CredentialDetailsView-B7Y9sj8K.js +131 -0
  7. package/dist/ErrorBox-DS5e6VmF.js +21 -0
  8. package/dist/{GameStatus-NSIKI7Zi.js → GameStatus-XFGHRbVP.js} +5 -5
  9. package/dist/{Import-B_2jztJs.js → Import-ea-wsQt-.js} +3 -3
  10. package/dist/{JobLogTail-CDGqKKin.js → JobLogTail-BwFUt8LB.js} +6 -25
  11. package/dist/{JobProgress-COP5mbrn.js → JobProgress-_cIUK7Ho.js} +6 -6
  12. package/dist/{JobStatusTable-DamWqM1t.js → JobStatusTable-CyDhk3lr.js} +3 -3
  13. package/dist/{ProjectCredentialsTable-BXWs0Ler.js → ProjectCredentialsTable-0DY-GdfY.js} +2 -2
  14. package/dist/TruncatedText-DhEXCrnE.js +25 -0
  15. package/dist/{UserCredentialsTable-Cr2NT9gg.js → UserCredentialsTable-CTJMS9Kc.js} +2 -2
  16. package/dist/{baseAppleCommand-CMBV0P9z.js → baseAppleCommand-9xmssZ7g.js} +1 -1
  17. package/dist/{baseCommand-C7OdounZ.js → baseCommand-CpAJaJoG.js} +289 -230
  18. package/dist/{baseGameAndroidCommand-BE6hsL-c.js → baseGameAndroidCommand-HO8as-RL.js} +2 -2
  19. package/dist/{baseGameCommand-Bap2bDqP.js → baseGameCommand-Cbx4ywHl.js} +32 -17
  20. package/dist/commands/apiKey/create.js +11 -11
  21. package/dist/commands/apiKey/list.js +12 -12
  22. package/dist/commands/apiKey/revoke.js +12 -12
  23. package/dist/commands/apple/apiKey/create.js +7 -7
  24. package/dist/commands/apple/apiKey/delete.js +7 -7
  25. package/dist/commands/apple/apiKey/export.js +5 -5
  26. package/dist/commands/apple/apiKey/import.js +5 -5
  27. package/dist/commands/apple/apiKey/status.js +4 -4
  28. package/dist/commands/apple/certificate/create.js +7 -7
  29. package/dist/commands/apple/certificate/delete.js +7 -7
  30. package/dist/commands/apple/certificate/export.js +5 -5
  31. package/dist/commands/apple/certificate/import.js +5 -5
  32. package/dist/commands/apple/certificate/show.js +78 -0
  33. package/dist/commands/apple/certificate/status.js +4 -4
  34. package/dist/commands/apple/login.js +3 -3
  35. package/dist/commands/apple/status.js +3 -3
  36. package/dist/commands/dashboard.js +3 -3
  37. package/dist/commands/game/android/apiKey/connect.js +9 -8
  38. package/dist/commands/game/android/apiKey/create.js +12 -11
  39. package/dist/commands/game/android/apiKey/delete.js +7 -7
  40. package/dist/commands/game/android/apiKey/export.js +7 -7
  41. package/dist/commands/game/android/apiKey/import.js +7 -7
  42. package/dist/commands/game/android/apiKey/invite.js +7 -7
  43. package/dist/commands/game/android/apiKey/policy.js +3 -3
  44. package/dist/commands/game/android/apiKey/show.js +79 -0
  45. package/dist/commands/game/android/apiKey/status.js +7 -7
  46. package/dist/commands/game/android/keyStore/create.js +9 -8
  47. package/dist/commands/game/android/keyStore/delete.js +7 -7
  48. package/dist/commands/game/android/keyStore/export.js +6 -6
  49. package/dist/commands/game/android/keyStore/import.js +10 -9
  50. package/dist/commands/game/android/keyStore/status.js +6 -6
  51. package/dist/commands/game/android/status.js +5 -5
  52. package/dist/commands/game/build/download.js +3 -3
  53. package/dist/commands/game/build/list.js +6 -5
  54. package/dist/commands/game/create.js +3 -3
  55. package/dist/commands/game/details.js +6 -6
  56. package/dist/commands/game/export.js +3 -3
  57. package/dist/commands/game/ios/app/addTester.js +7 -7
  58. package/dist/commands/game/ios/app/create.js +6 -6
  59. package/dist/commands/game/ios/app/status.js +7 -7
  60. package/dist/commands/game/ios/app/sync.js +5 -5
  61. package/dist/commands/game/ios/profile/create.js +7 -7
  62. package/dist/commands/game/ios/profile/delete.js +7 -7
  63. package/dist/commands/game/ios/profile/export.js +6 -6
  64. package/dist/commands/game/ios/profile/import.js +6 -6
  65. package/dist/commands/game/ios/profile/show.js +78 -0
  66. package/dist/commands/game/ios/profile/status.js +7 -7
  67. package/dist/commands/game/ios/status.js +10 -9
  68. package/dist/commands/game/ios/wizard.js +3 -3
  69. package/dist/commands/game/job/list.js +6 -6
  70. package/dist/commands/game/job/status.js +9 -8
  71. package/dist/commands/game/list.js +12 -12
  72. package/dist/commands/game/ship.js +14 -34
  73. package/dist/commands/game/status.js +6 -5
  74. package/dist/commands/game/wizard.js +26 -18
  75. package/dist/commands/internal/fastlane.js +5 -5
  76. package/dist/commands/internal/readme.js +5 -5
  77. package/dist/commands/login.js +6 -6
  78. package/dist/commands/status.js +5 -5
  79. package/dist/commands/util/android-build-method.js +5 -5
  80. package/dist/commands/util/glass.js +2 -2
  81. package/dist/{export-gdKqwR7u.js → export-Blt3BR-u.js} +1 -1
  82. package/dist/{import-CICoTBgo.js → import-IVcS8WFM.js} +1 -1
  83. package/dist/{index-BaxMfQnE.js → index-B5s20dhm.js} +5 -5
  84. package/dist/{index-YX-OJ2AA.js → index-By3xdL8c.js} +1 -1
  85. package/dist/{index-CjYag6UG.js → index-KJtngKaE.js} +4 -4
  86. package/dist/{upload-Drre-qsL.js → upload-B56rRpZW.js} +1 -1
  87. package/dist/{useAppleApp-ChI2baWJ.js → useAppleApp-BHUjGmw0.js} +1 -1
  88. package/dist/{useAppleBundleId-CUTbojvt.js → useAppleBundleId-Cv5maswG.js} +1 -1
  89. package/dist/{useAppleProfiles-omIx9KVc.js → useAppleProfiles-kDiUOXiX.js} +1 -1
  90. package/dist/{useGoogleStatus-v86ZyFiz.js → useGoogleStatus-BHd_Wp59.js} +2 -2
  91. package/dist/{useProjectCredentials-5Ycm5B4x.js → useProjectCredentials-ADtDLDmx.js} +19 -2
  92. package/dist/{useWebSocket-AjcqLcJX.js → useWebSocket-DlNe_zDR.js} +1 -1
  93. package/docs/apple/certificate/show.md +23 -0
  94. package/docs/apple/certificate.md +24 -0
  95. package/docs/game/android/apiKey/show.md +26 -0
  96. package/docs/game/android/apiKey.md +27 -0
  97. package/docs/game/ios/profile/show.md +26 -0
  98. package/docs/game/ios/profile.md +27 -0
  99. package/npm-shrinkwrap.json +52 -47
  100. package/oclif.manifest.json +351 -236
  101. package/package.json +8 -4
  102. package/dist/CommandGame-BeyPCeC7.js +0 -7
@@ -5,13 +5,13 @@ import { Flags, Command } from '@oclif/core';
5
5
  import chalk from 'chalk';
6
6
  import axios from 'axios';
7
7
  import { DateTime } from 'luxon';
8
- import * as expo from '@expo/apple-utils/build/index.js';
9
8
  import 'node:crypto';
10
9
  import 'node:readline';
11
10
  import 'node:url';
12
11
  import 'readline-sync';
13
12
  import 'isomorphic-git';
14
13
  import { getMajorVersion, loadExportPresets, findPreset, getBasePreset, saveExportPresets, mergePresets, ConfigFile } from 'godot-export-presets';
14
+ import * as expo from '@expo/apple-utils/build/index.js';
15
15
  import { QueryClient } from '@tanstack/react-query';
16
16
  import 'react';
17
17
  import 'uuid';
@@ -168,232 +168,6 @@ function getShortTimeDelta(start, end) {
168
168
  });
169
169
  }
170
170
 
171
- let currentAuthToken;
172
- function setAuthToken(token) {
173
- currentAuthToken = token;
174
- }
175
- function getAuthToken() {
176
- return currentAuthToken;
177
- }
178
- function getAuthedHeaders() {
179
- return {
180
- Authorization: `Bearer ${currentAuthToken}`
181
- };
182
- }
183
- async function createProject(props) {
184
- const headers = getAuthedHeaders();
185
- const opt = { headers };
186
- const { data } = await axios.post(`${API_URL}/projects`, props, opt);
187
- return castObjectDates(data);
188
- }
189
- async function getProject(projectId) {
190
- const headers = getAuthedHeaders();
191
- const opt = { headers };
192
- const { data } = await axios.get(`${API_URL}/projects/${projectId}`, opt);
193
- return castObjectDates(data);
194
- }
195
- async function getProjects(params) {
196
- const headers = getAuthedHeaders();
197
- const opt = { headers, params };
198
- const { data: rawData } = await axios.get(`${API_URL}/projects`, opt);
199
- const data = castArrayObjectDates(rawData.data);
200
- return {
201
- data,
202
- pageCount: rawData.pageCount
203
- };
204
- }
205
- async function updateProject(projectId, edits) {
206
- const headers = getAuthedHeaders();
207
- const opt = { headers };
208
- const { data } = await axios.put(`${API_URL}/projects/${projectId}`, edits, opt);
209
- return castObjectDates(data);
210
- }
211
- async function getProjectPlatformProgress(projectId, platform) {
212
- const headers = getAuthedHeaders();
213
- const opt = { headers };
214
- const { data } = await axios.get(`${API_URL}/projects/${projectId}/${platform}/progress`, opt);
215
- return data;
216
- }
217
- async function getNewUploadTicket(projectId) {
218
- const headers = getAuthedHeaders();
219
- const opt = { headers };
220
- const { data } = await axios.post(`${API_URL}/upload/${projectId}/url`, {}, opt);
221
- return data;
222
- }
223
- async function startJobsFromUpload(uploadTicketId, startOptions) {
224
- const headers = getAuthedHeaders();
225
- const opt = { headers };
226
- const { data } = await axios.post(`${API_URL}/upload/start/${uploadTicketId}`, startOptions, opt);
227
- return castArrayObjectDates(data);
228
- }
229
- async function getProjectJobs(projectId, params) {
230
- const headers = getAuthedHeaders();
231
- const opt = { headers, params };
232
- const { data: rawData } = await axios.get(`${API_URL}/projects/${projectId}/jobs`, opt);
233
- const data = castArrayObjectDates(rawData.data);
234
- return {
235
- data,
236
- pageCount: rawData.pageCount
237
- };
238
- }
239
- async function getJob(jobId, projectId) {
240
- const headers = getAuthedHeaders();
241
- const opt = { headers };
242
- const { data } = await axios.get(`${API_URL}/projects/${projectId}/jobs/${jobId}`, opt);
243
- return castJobDates(data);
244
- }
245
- async function getSingleUseUrl(destination) {
246
- const headers = await getAuthedHeaders();
247
- const { data } = await axios.post(`${API_URL}/me/otp`, {}, { headers });
248
- const queryString = Object.entries({ ...data, destination }).map(([key, value]) => `${key}=${encodeURIComponent(`${value}`)}`).join("&");
249
- const url = `${WEB_URL}exchange/?${queryString}`;
250
- return url;
251
- }
252
- async function getShortAuthRequiredUrl(destination) {
253
- const headers = await getAuthedHeaders();
254
- const { data } = await axios.post(
255
- `${API_URL}/me/login-link`,
256
- {
257
- destination,
258
- webUrl: WEB_URL
259
- },
260
- { headers }
261
- );
262
- return data.url;
263
- }
264
- async function getBuild(projectId, buildId) {
265
- const headers = getAuthedHeaders();
266
- const opt = { headers };
267
- const { data } = await axios.get(`${API_URL}/projects/${projectId}/builds/${buildId}`, opt);
268
- return castObjectDates(data);
269
- }
270
- async function getSelf() {
271
- const headers = getAuthedHeaders();
272
- const opt = { headers };
273
- const { data } = await axios.get(`${API_URL}/me`, opt);
274
- return castObjectDates(data);
275
- }
276
- async function getTerms() {
277
- const headers = getAuthedHeaders();
278
- const opt = { headers };
279
- const { data } = await axios.get(`${API_URL}/me/terms`, opt);
280
- return {
281
- // Any agreements which have changed since the user last accepted terms
282
- changes: castArrayObjectDates(data.changes),
283
- // Current versions of any agreements
284
- current: castArrayObjectDates(data.current)
285
- };
286
- }
287
- async function acceptTerms() {
288
- const headers = getAuthedHeaders();
289
- const opt = { headers };
290
- const { data } = await axios.post(`${API_URL}/me/terms`, {}, opt);
291
- return castObjectDates(data);
292
- }
293
- async function getGoogleAuthUrl(projectId) {
294
- const headers = getAuthedHeaders();
295
- const opt = { headers };
296
- const web = encodeURIComponent(new URL("/google/redirect/", WEB_URL).href);
297
- const url = `${API_URL}/projects/${projectId}/credentials/android/key/connect`;
298
- const { data } = await axios.get(`${url}?redirectUri=${web}`, opt);
299
- const response = data;
300
- return await getShortAuthRequiredUrl(response.url);
301
- }
302
- async function disconnectGoogle() {
303
- const headers = getAuthedHeaders();
304
- const opt = { headers };
305
- await axios.delete(`${API_URL}/me/google/connect`, opt);
306
- }
307
- async function getGoogleStatus() {
308
- const headers = getAuthedHeaders();
309
- const opt = { headers };
310
- const { data } = await axios.get(`${API_URL}/me/google/status`, opt);
311
- return castObjectDates(data, ["orgCreatedAt"]);
312
- }
313
- async function enforcePolicy() {
314
- const headers = getAuthedHeaders();
315
- const opt = { headers };
316
- const { data } = await axios.post(`${API_URL}/me/google/policy`, null, opt);
317
- return castObjectDates(data, ["orgCreatedAt"]);
318
- }
319
- async function revokePolicy() {
320
- const headers = getAuthedHeaders();
321
- const opt = { headers };
322
- const { data } = await axios.delete(`${API_URL}/me/google/policy`, opt);
323
- return castObjectDates(data, ["orgCreatedAt"]);
324
- }
325
- async function inviteServiceAccount(projectId, developerId) {
326
- try {
327
- const headers = getAuthedHeaders();
328
- const { data } = await axios.post(
329
- `${API_URL}/projects/${projectId}/credentials/android/key/invite/`,
330
- { developerId },
331
- {
332
- headers
333
- }
334
- );
335
- return data;
336
- } catch (error) {
337
- console.error("inviteServiceAccount Error", error);
338
- throw error;
339
- }
340
- }
341
- async function downloadBuildById(projectId, buildId, fileName) {
342
- const build = await getBuild(projectId, buildId);
343
- const { url } = build;
344
- const writer = fs.createWriteStream(fileName);
345
- const response = await axios({
346
- method: "GET",
347
- responseType: "stream",
348
- url
349
- });
350
- response.data.pipe(writer);
351
- return new Promise((resolve, reject) => {
352
- writer.on("finish", resolve);
353
- writer.on("error", reject);
354
- });
355
- }
356
- const APIKEYS_DATE_FIELDS = ["createdAt", "updatedAt", "expiresAt", "lastUsedAt", "revokedAt"];
357
- async function getAPIKeys(params) {
358
- const headers = getAuthedHeaders();
359
- const opt = { headers, params };
360
- const { data: rawData } = await axios.get(`${API_URL}/me/keys`, opt);
361
- const data = castArrayObjectDates(rawData.data, APIKEYS_DATE_FIELDS);
362
- return {
363
- data,
364
- pageCount: rawData.pageCount
365
- };
366
- }
367
- async function createAPIKey(createProps) {
368
- const headers = getAuthedHeaders();
369
- const opt = { headers };
370
- const { data } = await axios.post(`${API_URL}/me/keys`, createProps, opt);
371
- return castObjectDates(data, APIKEYS_DATE_FIELDS);
372
- }
373
- async function revokeAPIKey(apiKeyId) {
374
- const headers = getAuthedHeaders();
375
- const opt = { headers };
376
- await axios.delete(`${API_URL}/me/keys/${apiKeyId}`, opt);
377
- }
378
-
379
- const defaultExport = expo.default;
380
- const {
381
- ApiKey,
382
- ApiKeyType,
383
- App,
384
- Auth,
385
- BetaGroup,
386
- BundleId,
387
- CapabilityType,
388
- CapabilityTypeOption,
389
- Certificate,
390
- CertificateType,
391
- Profile,
392
- ProfileType,
393
- Session,
394
- UserRole
395
- } = defaultExport;
396
-
397
171
  var Platform = /* @__PURE__ */ ((Platform2) => {
398
172
  Platform2["ANDROID"] = "ANDROID";
399
173
  Platform2["IOS"] = "IOS";
@@ -436,6 +210,77 @@ var BuildType = /* @__PURE__ */ ((BuildType2) => {
436
210
  return BuildType2;
437
211
  })(BuildType || {});
438
212
 
213
+ class HandledError extends Error {
214
+ constructor(message) {
215
+ super(message);
216
+ this.name = "HandledError";
217
+ }
218
+ }
219
+
220
+ function getShortUUID(originalUuid) {
221
+ return originalUuid.slice(0, 8);
222
+ }
223
+
224
+ function isNetworkError(exception) {
225
+ if (!axios.isAxiosError(exception)) return false;
226
+ return ["ECONNABORTED", "ERR_NETWORK"].includes(`${exception.code}`);
227
+ }
228
+ function getErrorMessage(error) {
229
+ try {
230
+ if (isNetworkError(error)) {
231
+ return "Please check your internet connection.";
232
+ }
233
+ const data = error?.response?.data;
234
+ const apiValidation = Array.isArray(data) ? data.map((r) => "message" in r ? `Error - ${r.message}` : r.toString()).join(" ") : "";
235
+ const apiErr = error?.response?.data?.error || "";
236
+ const apiMsg = `${apiErr}${apiValidation ? " " + apiValidation : ""}`;
237
+ if (apiMsg.length === 0) {
238
+ return "message" in error ? error.message : error.toString();
239
+ }
240
+ return apiMsg;
241
+ } catch {
242
+ return error ? error.toString() : "Error";
243
+ }
244
+ }
245
+ function toHandledError(error, context = {}) {
246
+ if (isNetworkError(error)) {
247
+ return new HandledError("Please check your internet connection.");
248
+ }
249
+ const { projectId } = context || {};
250
+ const statusCode = error?.response?.status || error.status;
251
+ switch (statusCode) {
252
+ case 404: {
253
+ const msg = projectId ? `Game "${getShortUUID(projectId)}" not found. You may not have access to this game.
254
+ Run \`shipthis game list\` to see your games.` : "Requested resource not found.";
255
+ return new HandledError(msg);
256
+ }
257
+ case 401:
258
+ return new HandledError(`Unauthorized. Please run \`shipthis login\` to log in.`);
259
+ case 500:
260
+ return new HandledError(`Server error. Please try again later.`);
261
+ default:
262
+ return error;
263
+ }
264
+ }
265
+
266
+ const defaultExport = expo.default;
267
+ const {
268
+ ApiKey,
269
+ ApiKeyType,
270
+ App,
271
+ Auth,
272
+ BetaGroup,
273
+ BundleId,
274
+ CapabilityType,
275
+ CapabilityTypeOption,
276
+ Certificate,
277
+ CertificateType,
278
+ Profile,
279
+ ProfileType,
280
+ Session,
281
+ UserRole
282
+ } = defaultExport;
283
+
439
284
  const ENTITLEMENT_KEY_TO_CAPABILITY = {
440
285
  "com.apple.developer.applesignin": { name: "Sign in with Apple", type: CapabilityType.APPLE_ID_AUTH },
441
286
  "com.apple.developer.game-center": { name: "Game Center", type: CapabilityType.GAME_CENTER },
@@ -692,6 +537,222 @@ const queryClient = new QueryClient({
692
537
  }
693
538
  });
694
539
 
540
+ let currentAuthToken;
541
+ function setAuthToken(token) {
542
+ currentAuthToken = token;
543
+ }
544
+ function getAuthToken() {
545
+ return currentAuthToken;
546
+ }
547
+ function getAuthedHeaders() {
548
+ return {
549
+ Authorization: `Bearer ${currentAuthToken}`
550
+ };
551
+ }
552
+ async function createProject(props) {
553
+ const headers = getAuthedHeaders();
554
+ const opt = { headers };
555
+ const { data } = await axios.post(`${API_URL}/projects`, props, opt);
556
+ return castObjectDates(data);
557
+ }
558
+ async function getProject(projectId) {
559
+ const headers = getAuthedHeaders();
560
+ const opt = { headers };
561
+ try {
562
+ const { data } = await axios.get(`${API_URL}/projects/${projectId}`, opt);
563
+ return castObjectDates(data);
564
+ } catch (error) {
565
+ throw toHandledError(error, { projectId });
566
+ }
567
+ }
568
+ async function getProjects(params) {
569
+ const headers = getAuthedHeaders();
570
+ const opt = { headers, params };
571
+ const { data: rawData } = await axios.get(`${API_URL}/projects`, opt);
572
+ const data = castArrayObjectDates(rawData.data);
573
+ return {
574
+ data,
575
+ pageCount: rawData.pageCount
576
+ };
577
+ }
578
+ async function updateProject(projectId, edits) {
579
+ const headers = getAuthedHeaders();
580
+ const opt = { headers };
581
+ const { data } = await axios.put(`${API_URL}/projects/${projectId}`, edits, opt);
582
+ return castObjectDates(data);
583
+ }
584
+ async function getProjectPlatformProgress(projectId, platform) {
585
+ const headers = getAuthedHeaders();
586
+ const opt = { headers };
587
+ const { data } = await axios.get(`${API_URL}/projects/${projectId}/${platform}/progress`, opt);
588
+ return data;
589
+ }
590
+ async function getNewUploadTicket(projectId) {
591
+ const headers = getAuthedHeaders();
592
+ const opt = { headers };
593
+ const { data } = await axios.post(`${API_URL}/upload/${projectId}/url`, {}, opt);
594
+ return data;
595
+ }
596
+ async function startJobsFromUpload(uploadTicketId, startOptions) {
597
+ const headers = getAuthedHeaders();
598
+ const opt = { headers };
599
+ const { data } = await axios.post(`${API_URL}/upload/start/${uploadTicketId}`, startOptions, opt);
600
+ return castArrayObjectDates(data);
601
+ }
602
+ async function getProjectJobs(projectId, params) {
603
+ const headers = getAuthedHeaders();
604
+ const opt = { headers, params };
605
+ const { data: rawData } = await axios.get(`${API_URL}/projects/${projectId}/jobs`, opt);
606
+ const data = castArrayObjectDates(rawData.data);
607
+ return {
608
+ data,
609
+ pageCount: rawData.pageCount
610
+ };
611
+ }
612
+ async function getJob(jobId, projectId) {
613
+ const headers = getAuthedHeaders();
614
+ const opt = { headers };
615
+ const { data } = await axios.get(`${API_URL}/projects/${projectId}/jobs/${jobId}`, opt);
616
+ return castJobDates(data);
617
+ }
618
+ async function getSingleUseUrl(destination) {
619
+ const headers = await getAuthedHeaders();
620
+ const { data } = await axios.post(`${API_URL}/me/otp`, {}, { headers });
621
+ const queryString = Object.entries({ ...data, destination }).map(([key, value]) => `${key}=${encodeURIComponent(`${value}`)}`).join("&");
622
+ const url = `${WEB_URL}exchange/?${queryString}`;
623
+ return url;
624
+ }
625
+ async function getShortAuthRequiredUrl(destination) {
626
+ const headers = await getAuthedHeaders();
627
+ const { data } = await axios.post(
628
+ `${API_URL}/me/login-link`,
629
+ {
630
+ destination,
631
+ webUrl: WEB_URL
632
+ },
633
+ { headers }
634
+ );
635
+ return data.url;
636
+ }
637
+ async function getBuild(projectId, buildId) {
638
+ const headers = getAuthedHeaders();
639
+ const opt = { headers };
640
+ const { data } = await axios.get(`${API_URL}/projects/${projectId}/builds/${buildId}`, opt);
641
+ return castObjectDates(data);
642
+ }
643
+ async function getSelf() {
644
+ const headers = getAuthedHeaders();
645
+ const opt = { headers };
646
+ try {
647
+ const { data } = await axios.get(`${API_URL}/me`, opt);
648
+ return castObjectDates(data);
649
+ } catch (error) {
650
+ throw toHandledError(error);
651
+ }
652
+ }
653
+ async function getTerms() {
654
+ const headers = getAuthedHeaders();
655
+ const opt = { headers };
656
+ const { data } = await axios.get(`${API_URL}/me/terms`, opt);
657
+ return {
658
+ // Any agreements which have changed since the user last accepted terms
659
+ changes: castArrayObjectDates(data.changes),
660
+ // Current versions of any agreements
661
+ current: castArrayObjectDates(data.current)
662
+ };
663
+ }
664
+ async function acceptTerms() {
665
+ const headers = getAuthedHeaders();
666
+ const opt = { headers };
667
+ const { data } = await axios.post(`${API_URL}/me/terms`, {}, opt);
668
+ return castObjectDates(data);
669
+ }
670
+ async function getGoogleAuthUrl(projectId) {
671
+ const headers = getAuthedHeaders();
672
+ const opt = { headers };
673
+ const web = encodeURIComponent(new URL("/google/redirect/", WEB_URL).href);
674
+ const url = `${API_URL}/projects/${projectId}/credentials/android/key/connect`;
675
+ const { data } = await axios.get(`${url}?redirectUri=${web}`, opt);
676
+ const response = data;
677
+ return await getShortAuthRequiredUrl(response.url);
678
+ }
679
+ async function disconnectGoogle() {
680
+ const headers = getAuthedHeaders();
681
+ const opt = { headers };
682
+ await axios.delete(`${API_URL}/me/google/connect`, opt);
683
+ }
684
+ async function getGoogleStatus() {
685
+ const headers = getAuthedHeaders();
686
+ const opt = { headers };
687
+ const { data } = await axios.get(`${API_URL}/me/google/status`, opt);
688
+ return castObjectDates(data, ["orgCreatedAt"]);
689
+ }
690
+ async function enforcePolicy() {
691
+ const headers = getAuthedHeaders();
692
+ const opt = { headers };
693
+ const { data } = await axios.post(`${API_URL}/me/google/policy`, null, opt);
694
+ return castObjectDates(data, ["orgCreatedAt"]);
695
+ }
696
+ async function revokePolicy() {
697
+ const headers = getAuthedHeaders();
698
+ const opt = { headers };
699
+ const { data } = await axios.delete(`${API_URL}/me/google/policy`, opt);
700
+ return castObjectDates(data, ["orgCreatedAt"]);
701
+ }
702
+ async function inviteServiceAccount(projectId, developerId) {
703
+ try {
704
+ const headers = getAuthedHeaders();
705
+ const { data } = await axios.post(
706
+ `${API_URL}/projects/${projectId}/credentials/android/key/invite/`,
707
+ { developerId },
708
+ {
709
+ headers
710
+ }
711
+ );
712
+ return data;
713
+ } catch (error) {
714
+ console.error("inviteServiceAccount Error", error);
715
+ throw error;
716
+ }
717
+ }
718
+ async function downloadBuildById(projectId, buildId, fileName) {
719
+ const build = await getBuild(projectId, buildId);
720
+ const { url } = build;
721
+ const writer = fs.createWriteStream(fileName);
722
+ const response = await axios({
723
+ method: "GET",
724
+ responseType: "stream",
725
+ url
726
+ });
727
+ response.data.pipe(writer);
728
+ return new Promise((resolve, reject) => {
729
+ writer.on("finish", resolve);
730
+ writer.on("error", reject);
731
+ });
732
+ }
733
+ const APIKEYS_DATE_FIELDS = ["createdAt", "updatedAt", "expiresAt", "lastUsedAt", "revokedAt"];
734
+ async function getAPIKeys(params) {
735
+ const headers = getAuthedHeaders();
736
+ const opt = { headers, params };
737
+ const { data: rawData } = await axios.get(`${API_URL}/me/keys`, opt);
738
+ const data = castArrayObjectDates(rawData.data, APIKEYS_DATE_FIELDS);
739
+ return {
740
+ data,
741
+ pageCount: rawData.pageCount
742
+ };
743
+ }
744
+ async function createAPIKey(createProps) {
745
+ const headers = getAuthedHeaders();
746
+ const opt = { headers };
747
+ const { data } = await axios.post(`${API_URL}/me/keys`, createProps, opt);
748
+ return castObjectDates(data, APIKEYS_DATE_FIELDS);
749
+ }
750
+ async function revokeAPIKey(apiKeyId) {
751
+ const headers = getAuthedHeaders();
752
+ const opt = { headers };
753
+ await axios.delete(`${API_URL}/me/keys/${apiKeyId}`, opt);
754
+ }
755
+
695
756
  class BaseCommand extends Command {
696
757
  // define flags that can be inherited by any command that extends BaseCommand
697
758
  static baseFlags = {};
@@ -807,8 +868,6 @@ class BaseCommand extends Command {
807
868
  }
808
869
  }
809
870
  async init() {
810
- process.on("SIGINT", () => process.exit(0));
811
- process.on("SIGTERM", () => process.exit(0));
812
871
  await super.init();
813
872
  const { args, flags } = await this.parse({
814
873
  args: this.ctor.args,
@@ -869,4 +928,4 @@ class BaseCommand extends Command {
869
928
  }
870
929
  }
871
930
 
872
- export { setAuthToken as $, ApiKey as A, BaseCommand as B, CredentialsType as C, DetailsFlags as D, getJob as E, castArrayObjectDates as F, GODOT_CAPABILITIES as G, queryClient as H, WS_URL as I, JobStatus as J, getAuthToken as K, getProjectPlatformProgress as L, downloadBuildById as M, getGoogleStatus as N, getGodotAndroidPackageName as O, Platform as P, enforcePolicy as Q, revokePolicy as R, inviteServiceAccount as S, disconnectGoogle as T, UserRole as U, getAPIKeys as V, WEB_URL as W, createAPIKey as X, revokeAPIKey as Y, getSingleUseUrl as Z, acceptTerms as _, ApiKeyType as a, Auth as a0, LogLevel as a1, getShortAuthRequiredUrl as a2, castObjectDates as a3, getGoogleAuthUrl as a4, castJobDates as a5, getShortTime as a6, LEGACY_DEFAULT_IGNORED_FILES_GLOBS as a7, LEGACY_DEFAULT_SHIPPED_FILES_GLOBS as a8, getNewUploadTicket as a9, startJobsFromUpload as aa, updateProject as ab, getGradleBuildOptionKey as ac, BuildType as ad, getShortDateTime as ae, getShortTimeDelta as af, JobStage as ag, getSelf as ah, getTerms as ai, Certificate as b, getShortDate as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, isGradleBuildEnabled as i, BetaGroup as j, isCWDGodotGame as k, getProject as l, CertificateType as m, Profile as n, ProfileType as o, API_URL as p, getAuthedHeaders as q, getGodotProjectCapabilities as r, setGradleBuildEnabled as s, CapabilityType as t, GameEngine as u, getGodotVersion as v, createProject as w, DEFAULT_PLATFORM_GLOBS as x, getGodotProjectName as y, getProjectJobs as z };
931
+ export { getSingleUseUrl as $, ApiKey as A, BaseCommand as B, CredentialsType as C, DetailsFlags as D, castArrayObjectDates as E, queryClient as F, GODOT_CAPABILITIES as G, HandledError as H, WS_URL as I, JobStatus as J, getAuthToken as K, getProjectPlatformProgress as L, getProjectJobs as M, getJob as N, downloadBuildById as O, Platform as P, getGoogleStatus as Q, getGodotAndroidPackageName as R, enforcePolicy as S, revokePolicy as T, UserRole as U, inviteServiceAccount as V, WEB_URL as W, disconnectGoogle as X, getAPIKeys as Y, createAPIKey as Z, revokeAPIKey as _, ApiKeyType as a, acceptTerms as a0, setAuthToken as a1, Auth as a2, LogLevel as a3, getShortAuthRequiredUrl as a4, getErrorMessage as a5, castObjectDates as a6, getGoogleAuthUrl as a7, castJobDates as a8, getShortTime as a9, LEGACY_DEFAULT_IGNORED_FILES_GLOBS as aa, LEGACY_DEFAULT_SHIPPED_FILES_GLOBS as ab, getNewUploadTicket as ac, startJobsFromUpload as ad, updateProject as ae, getGradleBuildOptionKey as af, BuildType as ag, getShortDateTime as ah, getShortTimeDelta as ai, JobStage as aj, getSelf as ak, getTerms as al, Certificate as b, getProjects as c, getShortDate as d, getGodotAppleBundleIdentifier as e, BundleId as f, getShortUUID as g, App as h, isGradleBuildEnabled as i, CapabilityTypeOption as j, BetaGroup as k, isCWDGodotGame as l, getProject as m, CertificateType as n, Profile as o, ProfileType as p, API_URL as q, getAuthedHeaders as r, setGradleBuildEnabled as s, getGodotProjectCapabilities as t, CapabilityType as u, GameEngine as v, getGodotVersion as w, createProject as x, DEFAULT_PLATFORM_GLOBS as y, getGodotProjectName as z };
@@ -1,5 +1,5 @@
1
- import { N as getGoogleStatus, O as getGodotAndroidPackageName } from './baseCommand-C7OdounZ.js';
2
- import { c as BaseGameCommand, d as generatePackageName, b as getInput } from './baseGameCommand-Bap2bDqP.js';
1
+ import { Q as getGoogleStatus, R as getGodotAndroidPackageName } from './baseCommand-CpAJaJoG.js';
2
+ import { b as BaseGameCommand, c as generatePackageName, a as getInput } from './baseGameCommand-Cbx4ywHl.js';
3
3
 
4
4
  class BaseGameAndroidCommand extends BaseGameCommand {
5
5
  async checkGoogleAuth(waitForAuth = false) {
@@ -1,5 +1,5 @@
1
1
  import { Flags } from '@oclif/core';
2
- import { p as API_URL, q as getAuthedHeaders, P as Platform, ae as getShortDateTime, F as castArrayObjectDates, J as JobStatus, af as getShortTimeDelta, E as getJob, ag as JobStage, a1 as LogLevel, l as getProject, a2 as getShortAuthRequiredUrl, H as queryClient, ad as BuildType, W as WEB_URL, B as BaseCommand, ah as getSelf, ai as getTerms, ab as updateProject } from './baseCommand-C7OdounZ.js';
2
+ import { q as API_URL, r as getAuthedHeaders, P as Platform, g as getShortUUID, ah as getShortDateTime, E as castArrayObjectDates, J as JobStatus, ai as getShortTimeDelta, N as getJob, aj as JobStage, a3 as LogLevel, m as getProject, a4 as getShortAuthRequiredUrl, F as queryClient, ag as BuildType, W as WEB_URL, B as BaseCommand, ak as getSelf, H as HandledError, al as getTerms, ae as updateProject } from './baseCommand-CpAJaJoG.js';
3
3
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
4
  import { useStdin, useInput, Text, Box } from 'ink';
5
5
  import Spinner from 'ink-spinner';
@@ -152,9 +152,6 @@ const useSafeInput = (handler, options = { isActive: true }) => {
152
152
  );
153
153
  };
154
154
 
155
- function getShortUUID(originalUuid) {
156
- return originalUuid.slice(0, 8);
157
- }
158
155
  function getStageColor(stage) {
159
156
  switch (stage) {
160
157
  case JobStage.SETUP: {
@@ -1039,6 +1036,7 @@ const CommandProvider = (props) => {
1039
1036
  const GameContext = React.createContext({
1040
1037
  game: null,
1041
1038
  gameId: null,
1039
+ error: null,
1042
1040
  setGameId(gameId) {
1043
1041
  }
1044
1042
  });
@@ -1046,18 +1044,25 @@ const GameProvider = ({ children }) => {
1046
1044
  const { command } = React.useContext(CommandContext);
1047
1045
  const [gameId, setGameId] = useState(command?.getGameId() || null);
1048
1046
  const [game, setGame] = useState(null);
1047
+ const [error, setError] = useState(null);
1049
1048
  const handleGameIdChange = async () => {
1050
1049
  if (!gameId) {
1051
1050
  setGame(null);
1052
1051
  return;
1053
1052
  }
1054
- const game2 = await getProject(gameId);
1055
- setGame(game2);
1053
+ try {
1054
+ const game2 = await getProject(gameId);
1055
+ setGame(game2);
1056
+ setError(null);
1057
+ } catch (err) {
1058
+ setError(err);
1059
+ setGame(null);
1060
+ }
1056
1061
  };
1057
1062
  useEffect(() => {
1058
1063
  handleGameIdChange();
1059
1064
  }, [gameId]);
1060
- return /* @__PURE__ */ jsx(GameContext.Provider, { value: { game, gameId, setGameId }, children });
1065
+ return /* @__PURE__ */ jsx(GameContext.Provider, { value: { game, gameId, error, setGameId }, children });
1061
1066
  };
1062
1067
 
1063
1068
  scriptDir(import.meta);
@@ -1120,12 +1125,20 @@ class BaseAuthenticatedCommand extends BaseCommand {
1120
1125
  if (!this.isAuthenticated()) {
1121
1126
  this.error("No auth config found. Please run `shipthis login` to authenticate.", { exit: 1 });
1122
1127
  }
1123
- const self = await getSelf();
1124
- const accepted = Boolean(self.details?.hasAcceptedTerms);
1125
- if (!accepted) {
1126
- this.error("You must accept the agreements first. Please run `shipthis login --acceptAgreements` to do this.", {
1127
- exit: 1
1128
- });
1128
+ try {
1129
+ const self = await getSelf();
1130
+ const accepted = Boolean(self.details?.hasAcceptedTerms);
1131
+ if (!accepted) {
1132
+ this.error("You must accept the agreements first. Please run `shipthis login --acceptAgreements` to do this.", {
1133
+ exit: 1
1134
+ });
1135
+ }
1136
+ } catch (error) {
1137
+ if (error instanceof HandledError) {
1138
+ return this.error(error.message, { exit: 1 });
1139
+ } else {
1140
+ throw error;
1141
+ }
1129
1142
  }
1130
1143
  const terms = await getTerms();
1131
1144
  if (terms.changes.length > 0) {
@@ -1156,9 +1169,11 @@ class BaseGameCommand extends BaseAuthenticatedCommand {
1156
1169
  if (!gameId) this.error("No game ID found.");
1157
1170
  return await getProject(gameId);
1158
1171
  } catch (error) {
1159
- if (error?.response?.status === 404) {
1160
- this.error("Game not found - please check you have access");
1161
- } else throw error;
1172
+ if (error instanceof HandledError) {
1173
+ return this.error(error.message, { exit: 1 });
1174
+ } else {
1175
+ throw error;
1176
+ }
1162
1177
  }
1163
1178
  }
1164
1179
  async updateGame(update) {
@@ -1173,4 +1188,4 @@ class BaseGameCommand extends BaseAuthenticatedCommand {
1173
1188
  }
1174
1189
  }
1175
1190
 
1176
- export { CreateGooglePlayGame as A, BaseAuthenticatedCommand as B, CommandProvider as C, GameProvider as G, KeyTestStatus as K, Markdown as M, getRenderedMarkdown as a, getInput as b, BaseGameCommand as c, generatePackageName as d, getJobSummary as e, getJobStatusColor as f, getShortUUID as g, getStageColor as h, cacheKeys as i, GameContext as j, CommandContext as k, isValidSemVer as l, makeHumanReadable as m, fetchKeyTestResult as n, niceError as o, KeyTestError as p, ejs as q, getMaskedInput as r, getBuildSummary as s, useSafeInput as t, useBuilds as u, useJob as v, getMessageColor as w, getFileHash as x, getPlatformName as y, queryBuilds as z };
1191
+ export { BaseAuthenticatedCommand as B, CommandProvider as C, GameProvider as G, KeyTestStatus as K, Markdown as M, getInput as a, BaseGameCommand as b, generatePackageName as c, GameContext as d, getJobSummary as e, getStageColor as f, getRenderedMarkdown as g, getJobStatusColor as h, cacheKeys as i, CommandContext as j, isValidSemVer as k, fetchKeyTestResult as l, makeHumanReadable as m, niceError as n, KeyTestError as o, ejs as p, getMaskedInput as q, getBuildSummary as r, useSafeInput as s, useJob as t, useBuilds as u, getMessageColor as v, getFileHash as w, getPlatformName as x, queryBuilds as y, CreateGooglePlayGame as z };