shipthis 0.1.32 → 0.1.34

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 +8 -7
  2. package/assets/markdown/apikey-create.md +11 -0
  3. package/dist/{AppleBundleIdDetails-6H3cNWxw.js → AppleBundleIdDetails-By-sSGNl.js} +4 -4
  4. package/dist/{Command-WPpmLPkL.js → Command-VWMnGslo.js} +2 -2
  5. package/dist/{CommandGame-cxzWG4nT.js → CommandGame-BSVPZzNl.js} +2 -2
  6. package/dist/{Create-3Ob8sjik.js → Create-SR1Mq7BY.js} +4 -4
  7. package/dist/{GameStatus-BQEtVKvv.js → GameStatus-1ntFyxEx.js} +3 -3
  8. package/dist/{Import-CFuPDI0K.js → Import-cedOWPDz.js} +6 -6
  9. package/dist/{JobLogTail-0CBLoG8N.js → JobLogTail-C_W8UAMg.js} +5 -5
  10. package/dist/{JobProgress-lKqVT88m.js → JobProgress-CI385G53.js} +11 -8
  11. package/dist/{JobStatusTable-C_ZsZJCm.js → JobStatusTable-CdbKtwJE.js} +4 -4
  12. package/dist/{ProgressSpinner-DGcakQSK.js → ProgressSpinner-Um6ARKlk.js} +1 -1
  13. package/dist/{ProjectCredentialsTable-B5pHOnGu.js → ProjectCredentialsTable-ZnuIfcDB.js} +2 -2
  14. package/dist/{RunWithSpinner-gMVA07bZ.js → RunWithSpinner-DucRnFp6.js} +2 -1
  15. package/dist/{UserCredentialsTable-3W3qesh7.js → UserCredentialsTable-DRkAYgEA.js} +3 -3
  16. package/dist/{baseAppleCommand-BGV088--.js → baseAppleCommand-CsO-_Yzn.js} +1 -1
  17. package/dist/{baseGameAndroidCommand-CsemgVjp.js → baseGameAndroidCommand-CdjaAbNX.js} +2 -2
  18. package/dist/commands/apiKey/create.js +97 -0
  19. package/dist/commands/apiKey/list.js +91 -0
  20. package/dist/commands/apiKey/revoke.js +82 -0
  21. package/dist/commands/apple/apiKey/create.js +10 -10
  22. package/dist/commands/apple/apiKey/export.js +9 -9
  23. package/dist/commands/apple/apiKey/import.js +9 -9
  24. package/dist/commands/apple/apiKey/status.js +7 -7
  25. package/dist/commands/apple/certificate/create.js +10 -10
  26. package/dist/commands/apple/certificate/export.js +9 -9
  27. package/dist/commands/apple/certificate/import.js +9 -9
  28. package/dist/commands/apple/certificate/status.js +8 -8
  29. package/dist/commands/apple/login.js +3 -2
  30. package/dist/commands/apple/status.js +5 -5
  31. package/dist/commands/dashboard.js +2 -1
  32. package/dist/commands/game/android/apiKey/connect.js +9 -9
  33. package/dist/commands/game/android/apiKey/create.js +13 -13
  34. package/dist/commands/game/android/apiKey/export.js +10 -10
  35. package/dist/commands/game/android/apiKey/import.js +10 -10
  36. package/dist/commands/game/android/apiKey/invite.js +5 -4
  37. package/dist/commands/game/android/apiKey/status.js +9 -9
  38. package/dist/commands/game/android/keyStore/create.js +11 -11
  39. package/dist/commands/game/android/keyStore/export.js +9 -9
  40. package/dist/commands/game/android/keyStore/import.js +11 -11
  41. package/dist/commands/game/android/keyStore/status.js +7 -7
  42. package/dist/commands/game/android/status.js +2 -1
  43. package/dist/commands/game/build/download.js +6 -6
  44. package/dist/commands/game/build/list.js +6 -6
  45. package/dist/commands/game/create.js +3 -2
  46. package/dist/commands/game/details.js +5 -5
  47. package/dist/commands/game/export.js +2 -1
  48. package/dist/commands/game/ios/app/addTester.js +20 -15
  49. package/dist/commands/game/ios/app/create.js +6 -6
  50. package/dist/commands/game/ios/app/status.js +8 -8
  51. package/dist/commands/game/ios/app/sync.js +7 -7
  52. package/dist/commands/game/ios/profile/create.js +11 -11
  53. package/dist/commands/game/ios/profile/export.js +9 -9
  54. package/dist/commands/game/ios/profile/import.js +9 -9
  55. package/dist/commands/game/ios/profile/status.js +7 -7
  56. package/dist/commands/game/ios/status.js +10 -10
  57. package/dist/commands/game/ios/wizard.js +13 -8
  58. package/dist/commands/game/job/list.js +5 -5
  59. package/dist/commands/game/job/status.js +9 -9
  60. package/dist/commands/game/list.js +6 -6
  61. package/dist/commands/game/ship.js +19 -17
  62. package/dist/commands/game/status.js +7 -7
  63. package/dist/commands/game/wizard.js +22 -22
  64. package/dist/commands/internal/fastlane.js +2 -1
  65. package/dist/commands/internal/readme.js +2 -1
  66. package/dist/commands/login.js +3 -2
  67. package/dist/commands/status.js +5 -5
  68. package/dist/{export-CXsVPXA1.js → export-B5Yfd9vw.js} +1 -1
  69. package/dist/{import-DGvG5REx.js → import-A2WcStHl.js} +1 -1
  70. package/dist/{index-CS9Gwcb0.js → index-BBLtvl1Y.js} +7 -7
  71. package/dist/{index-C03TV1_J.js → index-Bz1qt_8T.js} +17 -9
  72. package/dist/{index-C66Dd8Xc.js → index-CA6-uLMn.js} +23 -12
  73. package/dist/{index-BhhiXbey.js → index-CO_ssVFA.js} +28 -4
  74. package/dist/{index-CGBdOm1q.js → index-CYjZ26If.js} +2 -1
  75. package/dist/{index-CtTI85m-.js → index-CgzANgJt.js} +1 -1
  76. package/dist/{upload-8y5MQEm9.js → upload-BIsFZzBO.js} +1 -1
  77. package/dist/{useAndroidServiceAccountTestResult-DZk5SMxI.js → useAndroidServiceAccountTestResult-DueKynFy.js} +1 -1
  78. package/dist/{useAppleApp-DWYGURwU.js → useAppleApp-BZR94exU.js} +1 -1
  79. package/dist/{useAppleBundleId-PsTJ2g1B.js → useAppleBundleId-Dg5DsItN.js} +1 -1
  80. package/dist/{useProjectCredentials-BEphqa18.js → useProjectCredentials-jQYGcDhT.js} +3 -3
  81. package/dist/{useWebSocket-5PYa2QER.js → useWebSocket-CIxkPaYi.js} +1 -1
  82. package/docs/apiKey/create.md +27 -0
  83. package/docs/apiKey/list.md +30 -0
  84. package/docs/apiKey/revoke.md +26 -0
  85. package/docs/apiKey.md +93 -0
  86. package/package.json +10 -4
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { Args } from '@oclif/core';
3
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';
4
+ import { K as queryClient, p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates, ac 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-CO_ssVFA.js';
5
+ import { Box, Text } from 'ink';
6
6
  import Spinner from 'ink-spinner';
7
7
  import 'node:crypto';
8
8
  import fs__default from 'node:fs';
@@ -23,31 +23,31 @@ import 'socket.io-client';
23
23
  import 'string-length';
24
24
  import 'strip-ansi';
25
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';
26
+ import { C as ConnectGoogle } from '../../index-Bz1qt_8T.js';
27
+ import { C as CommandContext, G as GameContext, u as useBuilds, M as Markdown, e as useSafeInput, q as queryBuilds, c as GameProvider, h as CreateGooglePlayGame } from '../../index-CA6-uLMn.js';
28
28
  import { TextInput, Alert } from '@inkjs/ui';
29
29
  import 'marked';
30
30
  import 'marked-terminal';
31
31
  import 'qrcode';
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';
32
+ import { g as getShortUUID } from '../../index-CYjZ26If.js';
33
+ import { J as JobLogTail } from '../../JobLogTail-C_W8UAMg.js';
34
+ import { c as cacheKeys, f as fetchKeyTestResult, K as KeyTestStatus, a as KeyTestError } from '../../useAndroidServiceAccountTestResult-DueKynFy.js';
35
+ import { u as useShip, J as JobProgress } from '../../JobProgress-CI385G53.js';
36
+ import { C as CreateServiceAccountKey } from '../../index-BBLtvl1Y.js';
37
+ import { C as CreateKeystore } from '../../Create-SR1Mq7BY.js';
38
+ import { I as ImportKeystore } from '../../Import-cedOWPDz.js';
39
+ import { a as getProjectCredentials } from '../../index-CgzANgJt.js';
40
40
  import { T as Title } from '../../Title-BCQtayg6.js';
41
- import { C as Command } from '../../Command-WPpmLPkL.js';
41
+ import { C as Command } from '../../Command-VWMnGslo.js';
42
42
  import '@expo/apple-utils/build/index.js';
43
43
  import 'deepmerge';
44
44
  import 'ini';
45
- import '../../useWebSocket-5PYa2QER.js';
45
+ import '../../useWebSocket-CIxkPaYi.js';
46
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';
47
+ import '../../ProgressSpinner-Um6ARKlk.js';
48
+ import '../../useProjectCredentials-jQYGcDhT.js';
49
+ import '../../RunWithSpinner-DucRnFp6.js';
50
+ import '../../import-A2WcStHl.js';
51
51
 
52
52
  const useInviteServiceAccount = () => useMutation({
53
53
  async mutationFn({ developerId, projectId }) {
@@ -290,7 +290,7 @@ const CreateForGame = ({ gameId, onComplete, onError, ...boxProps }) => {
290
290
  /* @__PURE__ */ jsx(Text, { children: "Create an initial build..." }),
291
291
  (isLoadingBuilds || isLoadingJobs || shipMutation.isPending) && /* @__PURE__ */ jsx(Spinner, { type: "dots" })
292
292
  ] }),
293
- androidJob == null && /* @__PURE__ */ jsx(Text, { children: shipLog }),
293
+ androidJob === null && /* @__PURE__ */ jsx(Text, { children: shipLog }),
294
294
  androidJob && /* @__PURE__ */ jsx(JobProgress, { job: androidJob, onComplete, onFailure: (j) => {
295
295
  setFailedJob(j);
296
296
  setTimeout(() => {
@@ -430,7 +430,7 @@ const CreateOrImport = ({ onComplete, onError, ...boxProps }) => {
430
430
  keyPassword: "",
431
431
  keystorePassword: ""
432
432
  });
433
- useInput(async (input) => {
433
+ useSafeInput(async (input) => {
434
434
  if (stage !== 0 /* Choose */) return;
435
435
  if (input === "c") return setStage(1 /* Create */);
436
436
  if (input === "i") return setStage(2 /* ImportForm */);
@@ -510,12 +510,12 @@ const getStatusFlags = async (cmd) => {
510
510
  const hasAndroidPackageName = project && Boolean(project?.details?.androidPackageName);
511
511
  const projectCredentials = hasShipThisProject ? await getProjectCredentials(project.id) : [];
512
512
  const hasAndroidKeystore = projectCredentials.some(
513
- (cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type == CredentialsType.CERTIFICATE
513
+ (cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type === CredentialsType.CERTIFICATE
514
514
  );
515
515
  const googleStatus = await getGoogleStatus();
516
516
  const hasGoogleConnection = googleStatus.isAuthenticated;
517
517
  const hasServiceAccountKey = projectCredentials.some(
518
- (cred) => cred.isActive && cred.platform == Platform.ANDROID && cred.type == CredentialsType.KEY
518
+ (cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type === CredentialsType.KEY
519
519
  );
520
520
  const buildsResponse = Boolean(projectId) && hasShipThisProject && await queryBuilds({ pageNumber: 0, projectId });
521
521
  const hasInitialBuild = Boolean(buildsResponse) && buildsResponse.data.some((build) => build.platform === Platform.ANDROID);
@@ -1,7 +1,7 @@
1
1
  import fs__default, { promises } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { Args, Flags } from '@oclif/core';
4
- import { V as BaseCommand } from '../../index-BhhiXbey.js';
4
+ import { V as BaseCommand } from '../../index-CO_ssVFA.js';
5
5
  import 'axios';
6
6
  import 'crypto-js';
7
7
  import 'uuid';
@@ -20,6 +20,7 @@ import 'fast-glob';
20
20
  import 'yazl';
21
21
  import 'socket.io-client';
22
22
  import 'fullscreen-ink';
23
+ import 'ink';
23
24
 
24
25
  function generateFastlaneSession(cookieData) {
25
26
  return cookieData.cookies.map((cookie) => `- !ruby/object:HTTP::Cookie
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { Args, Flags } from '@oclif/core';
4
4
  import require$$0 from 'fs';
5
5
  import require$$1 from 'path';
6
- import { V as BaseCommand } from '../../index-BhhiXbey.js';
6
+ import { V as BaseCommand } from '../../index-CO_ssVFA.js';
7
7
  import CustomHelp from '../../utils/help.js';
8
8
  import 'axios';
9
9
  import 'crypto-js';
@@ -23,6 +23,7 @@ import 'fast-glob';
23
23
  import 'yazl';
24
24
  import 'socket.io-client';
25
25
  import 'fullscreen-ink';
26
+ import 'ink';
26
27
 
27
28
  function getDefaultExportFromCjs (x) {
28
29
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -1,7 +1,7 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import axios from 'axios';
3
- import { W as WEB_URL, V as BaseCommand, o as API_URL, Y as setAuthToken, Z as acceptTerms } from '../index-BhhiXbey.js';
4
- import { a as getInput } from '../index-CGBdOm1q.js';
3
+ import { W as WEB_URL, V as BaseCommand, o as API_URL, $ as setAuthToken, a0 as acceptTerms } from '../index-CO_ssVFA.js';
4
+ import { a as getInput } from '../index-CYjZ26If.js';
5
5
  import 'node:fs';
6
6
  import 'crypto-js';
7
7
  import 'uuid';
@@ -21,6 +21,7 @@ import 'fast-glob';
21
21
  import 'yazl';
22
22
  import 'socket.io-client';
23
23
  import 'fullscreen-ink';
24
+ import 'ink';
24
25
 
25
26
  const TERMS_URL = new URL("/terms", WEB_URL).href;
26
27
  const PRIVACY_URL = new URL("/privacy", WEB_URL).href;
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { render } from 'ink';
3
- import { V as BaseCommand, j as isCWDGodotGame } from '../index-BhhiXbey.js';
3
+ import { V as BaseCommand, j as isCWDGodotGame } from '../index-CO_ssVFA.js';
4
4
  import 'ink-spinner';
5
5
  import 'node:crypto';
6
6
  import 'node:fs';
@@ -29,15 +29,15 @@ import 'marked';
29
29
  import 'marked-terminal';
30
30
  import { N as NextSteps } from '../NextSteps-DbJHmscQ.js';
31
31
  import 'qrcode';
32
- import '../index-C66Dd8Xc.js';
33
- import { C as Command } from '../Command-WPpmLPkL.js';
32
+ import '../index-CA6-uLMn.js';
33
+ import { C as Command } from '../Command-VWMnGslo.js';
34
34
  import '@expo/apple-utils/build/index.js';
35
35
  import 'isomorphic-git';
36
36
  import 'deepmerge';
37
37
  import 'ini';
38
38
  import '../Title-BCQtayg6.js';
39
- import '../index-CGBdOm1q.js';
40
- import '../useAndroidServiceAccountTestResult-DZk5SMxI.js';
39
+ import '../index-CYjZ26If.js';
40
+ import '../useAndroidServiceAccountTestResult-DueKynFy.js';
41
41
 
42
42
  class Status extends BaseCommand {
43
43
  static args = {};
@@ -1,6 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import axios from 'axios';
3
- import { o as API_URL, p as getAuthedHeaders } from './index-BhhiXbey.js';
3
+ import { o as API_URL, p as getAuthedHeaders } from './index-CO_ssVFA.js';
4
4
 
5
5
  async function exportCredential({ credentialId, projectId, zipPath }) {
6
6
  const headers = getAuthedHeaders();
@@ -1,6 +1,6 @@
1
1
  import { promises } from 'node:fs';
2
2
  import axios from 'axios';
3
- import { o as API_URL, p as getAuthedHeaders } from './index-BhhiXbey.js';
3
+ import { o as API_URL, p as getAuthedHeaders } from './index-CO_ssVFA.js';
4
4
 
5
5
  async function getNewImportTicket(projectId) {
6
6
  const url = projectId ? `${API_URL}/projects/${projectId}/credentials/import/url` : `${API_URL}/credentials/import/url`;
@@ -11,17 +11,17 @@ import 'readline-sync';
11
11
  import 'luxon';
12
12
  import axios from 'axios';
13
13
  import 'isomorphic-git';
14
- import { p as getAuthedHeaders, o as API_URL, a1 as castObjectDates, P as Platform, C as CredentialsType, Q as getGoogleStatus } from './index-BhhiXbey.js';
14
+ import { p as getAuthedHeaders, o as API_URL, a4 as castObjectDates, P as Platform, C as CredentialsType, Q as getGoogleStatus } from './index-CO_ssVFA.js';
15
15
  import '@oclif/core';
16
16
  import { useQuery, useQueryClient } from '@tanstack/react-query';
17
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
17
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DueKynFy.js';
18
18
  import 'fast-glob';
19
19
  import 'uuid';
20
20
  import 'yazl';
21
21
  import 'socket.io-client';
22
22
  import 'fullscreen-ink';
23
- import { u as useWebSocket } from './useWebSocket-5PYa2QER.js';
24
- import { u as useProjectCredentials } from './useProjectCredentials-BEphqa18.js';
23
+ import { u as useWebSocket } from './useWebSocket-CIxkPaYi.js';
24
+ import { u as useProjectCredentials } from './useProjectCredentials-jQYGcDhT.js';
25
25
  import 'crypto-js';
26
26
  import 'string-length';
27
27
  import 'strip-ansi';
@@ -29,9 +29,9 @@ import 'open';
29
29
  import '@inkjs/ui';
30
30
  import 'marked';
31
31
  import 'marked-terminal';
32
- import { P as ProgressSpinner } from './ProgressSpinner-DGcakQSK.js';
32
+ import { P as ProgressSpinner } from './ProgressSpinner-Um6ARKlk.js';
33
33
  import 'qrcode';
34
- import { G as GameContext } from './index-C66Dd8Xc.js';
34
+ import { G as GameContext } from './index-CA6-uLMn.js';
35
35
 
36
36
  async function fetchStatus({ projectId }) {
37
37
  try {
@@ -56,7 +56,7 @@ const useAndroidServiceAccountSetupStatus = (props) => useQuery({
56
56
  const ERR_NOT_AUTHENTICATED = "You must be connected to Google to create a Service Account Key";
57
57
  const useHasServiceAccountKey = (projectId) => {
58
58
  const { data, isSuccess } = useProjectCredentials({ platform: Platform.ANDROID, projectId });
59
- return isSuccess && data.data.some((cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type == CredentialsType.KEY);
59
+ return isSuccess && data.data.some((cred) => cred.isActive && cred.platform === Platform.ANDROID && cred.type === CredentialsType.KEY);
60
60
  };
61
61
  const useAndroidServiceAccount = ({ onComplete, onError, projectId }) => {
62
62
  const queryClient = useQueryClient();
@@ -1,5 +1,5 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
- import { Text, useInput, Box } from 'ink';
2
+ import { Text, Box } from 'ink';
3
3
  import open from 'open';
4
4
  import { useState, useEffect, useContext } from 'react';
5
5
  import 'ink-spinner';
@@ -12,7 +12,7 @@ import 'readline-sync';
12
12
  import 'luxon';
13
13
  import 'axios';
14
14
  import 'isomorphic-git';
15
- import { Q as getGoogleStatus, a2 as getShortAuthRequiredUrl, a3 as getGoogleAuthUrl, W as WEB_URL } from './index-BhhiXbey.js';
15
+ import { Q as getGoogleStatus, a5 as getShortAuthRequiredUrl, a6 as getGoogleAuthUrl, W as WEB_URL } from './index-CO_ssVFA.js';
16
16
  import '@oclif/core';
17
17
  import { useQuery } from '@tanstack/react-query';
18
18
  import 'crypto-js';
@@ -20,13 +20,13 @@ import 'uuid';
20
20
  import 'fast-glob';
21
21
  import 'yazl';
22
22
  import 'socket.io-client';
23
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
24
- import { u as useWebSocket } from './useWebSocket-5PYa2QER.js';
23
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DueKynFy.js';
24
+ import { u as useWebSocket } from './useWebSocket-CIxkPaYi.js';
25
25
  import 'fullscreen-ink';
26
+ import { G as GameContext, e as useSafeInput, M as Markdown } from './index-CA6-uLMn.js';
26
27
  import 'string-length';
27
28
  import 'strip-ansi';
28
29
  import '@inkjs/ui';
29
- import { G as GameContext, M as Markdown } from './index-C66Dd8Xc.js';
30
30
  import 'marked';
31
31
  import 'marked-terminal';
32
32
  import qrcode from 'qrcode';
@@ -97,6 +97,14 @@ const ConnectGoogle = (props) => {
97
97
  };
98
98
  const ConnectForGame = ({ gameId, helpPage, onComplete, onError, ...boxProps }) => {
99
99
  const [showQRCode, setShowQRCode] = useState(false);
100
+ const [connectUrl, setConnectUrl] = useState(null);
101
+ useEffect(() => {
102
+ const fetchConnectUrl = async () => {
103
+ const url = await getConnectUrl(gameId, Boolean(helpPage));
104
+ setConnectUrl(url);
105
+ };
106
+ if (!connectUrl) fetchConnectUrl();
107
+ }, []);
100
108
  useGoogleStatusWatching({
101
109
  isWatching: true,
102
110
  onGoogleStatusUpdate(status) {
@@ -104,7 +112,7 @@ const ConnectForGame = ({ gameId, helpPage, onComplete, onError, ...boxProps })
104
112
  },
105
113
  projectId: gameId
106
114
  });
107
- useInput(async (input) => {
115
+ useSafeInput(async (input) => {
108
116
  switch (input) {
109
117
  case "q": {
110
118
  setShowQRCode(true);
@@ -116,8 +124,8 @@ const ConnectForGame = ({ gameId, helpPage, onComplete, onError, ...boxProps })
116
124
  }
117
125
  case "b": {
118
126
  if (!gameId) return;
119
- const url = await getConnectUrl(gameId, true);
120
- await open(url);
127
+ if (!connectUrl) return;
128
+ await open(connectUrl);
121
129
  }
122
130
  }
123
131
  });
@@ -127,7 +135,7 @@ const ConnectForGame = ({ gameId, helpPage, onComplete, onError, ...boxProps })
127
135
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, ...boxProps, children: [
128
136
  !showQRCode && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
129
137
  /* @__PURE__ */ jsx(Markdown, { filename: "privacy-notification.md", templateVars }),
130
- /* @__PURE__ */ jsx(Text, { bold: true, color: "#4CE64C", children: "Press B to open your browser and connect your Google account to ShipThis" }),
138
+ connectUrl && /* @__PURE__ */ jsx(Text, { bold: true, color: "#4CE64C", children: `Press B to open ${connectUrl} in your browser and connect your Google account to ShipThis` }),
131
139
  /* @__PURE__ */ jsx(Text, { bold: true, color: "#4CE64C", children: "Press Q to show a QR-code to connect using your mobile phone" })
132
140
  ] }),
133
141
  showQRCode && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
@@ -1,13 +1,13 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
- import { Text, useInput, Box } from 'ink';
2
+ import { useStdin, useInput, Text, Box } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
4
  import open from 'open';
5
5
  import React, { useState, useEffect, useContext, useRef } from 'react';
6
- import { p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates, P as Platform, a6 as getShortDateTime, J as JobStatus, a7 as getShortTimeDelta, z as getJob, E as getProject, a2 as getShortAuthRequiredUrl, K as queryClient, a8 as BuildType, W as WEB_URL } from './index-BhhiXbey.js';
7
- import { h as getPlatformName, g as getShortUUID, s as scriptDir } from './index-CGBdOm1q.js';
6
+ import { P as Platform, a9 as getShortDateTime, p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates, J as JobStatus, aa as getShortTimeDelta, z as getJob, E as getProject, a5 as getShortAuthRequiredUrl, K as queryClient, ab as BuildType, W as WEB_URL } from './index-CO_ssVFA.js';
7
+ import { h as getPlatformName, g as getShortUUID, s as scriptDir } from './index-CYjZ26If.js';
8
8
  import { useQuery } from '@tanstack/react-query';
9
9
  import axios from 'axios';
10
- import { c as cacheKeys, u as useAndroidServiceAccountTestResult, K as KeyTestStatus, a as KeyTestError } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
10
+ import { c as cacheKeys, u as useAndroidServiceAccountTestResult, K as KeyTestStatus, a as KeyTestError } from './useAndroidServiceAccountTestResult-DueKynFy.js';
11
11
  import 'luxon';
12
12
  import fs__default from 'node:fs';
13
13
  import 'fast-glob';
@@ -38,7 +38,7 @@ async function queryBuilds({ projectId, ...pageAndSortParams }) {
38
38
  }
39
39
  }
40
40
  function getBuildSummary(build) {
41
- const ext = build.buildType || (build.platform == Platform.IOS ? "IPA" : "AAB");
41
+ const ext = build.buildType || (build.platform === Platform.IOS ? "IPA" : "AAB");
42
42
  const filename = `game.${ext.toLowerCase()}`;
43
43
  return {
44
44
  id: getShortUUID(build.id),
@@ -83,6 +83,18 @@ const useJob = (props) => useQuery({
83
83
  queryKey: cacheKeys.job(props)
84
84
  });
85
85
 
86
+ const useSafeInput = (handler, options = { isActive: true }) => {
87
+ const { isRawModeSupported } = useStdin();
88
+ const isActive = isRawModeSupported === true && options.isActive !== false;
89
+ useInput(
90
+ (input, key) => {
91
+ const lowerInput = input.toLowerCase();
92
+ return handler(lowerInput, key);
93
+ },
94
+ { isActive }
95
+ );
96
+ };
97
+
86
98
  const cleanHyperlinks = (input) => (
87
99
  // When we run in a <ScrollArea> the links break
88
100
  // Remove OSC 8 hyperlink wrappers but preserve the styled content inside
@@ -173,7 +185,7 @@ const Create = ({ gameId, onComplete, onError, ...boxProps }) => {
173
185
  }
174
186
  previousIsFound.current = isFound;
175
187
  }, [result]);
176
- useInput(async (input) => {
188
+ useSafeInput(async (input) => {
177
189
  if (!gameId) return;
178
190
  switch (input) {
179
191
  case "r": {
@@ -185,14 +197,13 @@ const Create = ({ gameId, onComplete, onError, ...boxProps }) => {
185
197
  case "d": {
186
198
  const dashUrl = await getShortAuthRequiredUrl(`/games/${getShortUUID(gameId)}/builds`);
187
199
  await open(dashUrl);
200
+ break;
188
201
  }
189
202
  }
190
- if (input !== "r") return;
191
- queryClient.invalidateQueries({
192
- queryKey: cacheKeys.androidKeyTestResult({ projectId: gameId })
193
- });
194
203
  });
195
- const initialBuild = builds?.data.find((build) => build.platform === Platform.ANDROID && build.buildType === BuildType.AAB);
204
+ const initialBuild = builds?.data.find(
205
+ (build) => build.platform === Platform.ANDROID && build.buildType === BuildType.AAB
206
+ );
196
207
  const downloadCmd = initialBuild ? `${getBuildSummary(initialBuild).cmd}` : "Initial AAB build not found!";
197
208
  const templateVars = {
198
209
  dashboardURL: new URL(`/games/${getShortUUID(gameId)}/builds`, WEB_URL).toString(),
@@ -207,4 +218,4 @@ const Create = ({ gameId, onComplete, onError, ...boxProps }) => {
207
218
  ] }) });
208
219
  };
209
220
 
210
- export { CommandContext as C, GameContext as G, Markdown as M, getJobSummary as a, CommandProvider as b, GameProvider as c, getBuildSummary as d, useJob as e, CreateGooglePlayGame as f, getRenderedMarkdown as g, queryBuilds as q, useBuilds as u };
221
+ export { CommandContext as C, GameContext as G, Markdown as M, getJobSummary as a, CommandProvider as b, GameProvider as c, getBuildSummary as d, useSafeInput as e, useJob as f, getRenderedMarkdown as g, CreateGooglePlayGame as h, queryBuilds as q, useBuilds as u };
@@ -20,6 +20,7 @@ import 'fast-glob';
20
20
  import 'yazl';
21
21
  import 'socket.io-client';
22
22
  import 'fullscreen-ink';
23
+ import 'ink';
23
24
 
24
25
  const AUTH_ENV_VAR_NAME = "SHIPTHIS_TOKEN";
25
26
  const DOMAIN_ENV_VAR_NAME = "SHIPTHIS_DOMAIN";
@@ -60,6 +61,7 @@ const DEFAULT_LOCALE = "en-US";
60
61
  function castObjectDates(apiObject, keys = ["createdAt", "updatedAt"]) {
61
62
  if (!apiObject) return apiObject;
62
63
  const datesOnly = Object.keys(apiObject).filter((k) => keys.includes(k)).reduce((a, c) => {
64
+ if (!apiObject[c]) return a;
63
65
  a[c] = DateTime.fromISO(apiObject[c]);
64
66
  return a;
65
67
  }, {});
@@ -109,7 +111,7 @@ function getShortTimeDelta(start, end) {
109
111
  });
110
112
  }
111
113
 
112
- var currentAuthToken;
114
+ let currentAuthToken;
113
115
  function setAuthToken(token) {
114
116
  currentAuthToken = token;
115
117
  }
@@ -282,6 +284,28 @@ async function downloadBuildById(projectId, buildId, fileName) {
282
284
  writer.on("error", reject);
283
285
  });
284
286
  }
287
+ const APIKEYS_DATE_FIELDS = ["createdAt", "updatedAt", "expiresAt", "lastUsedAt", "revokedAt"];
288
+ async function getAPIKeys(params) {
289
+ const headers = getAuthedHeaders();
290
+ const opt = { headers, params };
291
+ const { data: rawData } = await axios.get(`${API_URL}/me/keys`, opt);
292
+ const data = castArrayObjectDates(rawData.data, APIKEYS_DATE_FIELDS);
293
+ return {
294
+ data,
295
+ pageCount: rawData.pageCount
296
+ };
297
+ }
298
+ async function createAPIKey(createProps) {
299
+ const headers = getAuthedHeaders();
300
+ const opt = { headers };
301
+ const { data } = await axios.post(`${API_URL}/me/keys`, createProps, opt);
302
+ return castObjectDates(data, APIKEYS_DATE_FIELDS);
303
+ }
304
+ async function revokeAPIKey(apiKeyId) {
305
+ const headers = getAuthedHeaders();
306
+ const opt = { headers };
307
+ await axios.delete(`${API_URL}/me/keys/${apiKeyId}`, opt);
308
+ }
285
309
 
286
310
  const defaultExport = expo.default;
287
311
  const {
@@ -359,7 +383,7 @@ function getGodotProjectCapabilities(platform) {
359
383
  const capabilities = [];
360
384
  for (const capability of GODOT_CAPABILITIES) {
361
385
  if (!(capability.key in options)) continue;
362
- if (`${options[capability.key]}`.toLocaleLowerCase() == "true") capabilities.push(capability.type);
386
+ if (`${options[capability.key]}`.toLocaleLowerCase() === "true") capabilities.push(capability.type);
363
387
  }
364
388
  return capabilities;
365
389
  }
@@ -415,7 +439,7 @@ function getGodotExportPresets(platform) {
415
439
  if (isFound) {
416
440
  const exportPresetsContent = fs__default.readFileSync(exportPresetsPath, "utf8");
417
441
  const exportPresetsIni = parse(exportPresetsContent);
418
- const presetIndexes = Object.keys(exportPresetsIni.preset);
442
+ const presetIndexes = Object.keys(exportPresetsIni.preset || {});
419
443
  const presetIndex = presetIndexes.find((index) => {
420
444
  const current = exportPresetsIni.preset[index];
421
445
  return `${current.name}`.toUpperCase() === platform;
@@ -745,4 +769,4 @@ const DetailsFlags = {
745
769
  semanticVersion: Flags.string({ char: "s", description: "Set the semantic version" })
746
770
  };
747
771
 
748
- export { getNewUploadTicket as $, ApiKey as A, BaseAuthenticatedCommand as B, CredentialsType as C, DetailsFlags as D, getProject as E, getProjectPlatformProgress as F, GODOT_CAPABILITIES as G, downloadBuildById as H, castArrayObjectDates as I, JobStatus as J, queryClient as K, JobStage as L, LogLevel as M, WS_URL as N, getAuthToken as O, Platform as P, getGoogleStatus as Q, getGodotAndroidPackageName as R, inviteServiceAccount as S, disconnectGoogle as T, UserRole as U, BaseCommand as V, WEB_URL as W, getSingleUseUrl as X, setAuthToken as Y, acceptTerms as Z, Auth as _, ApiKeyType as a, startJobsFromUpload as a0, castObjectDates as a1, getShortAuthRequiredUrl as a2, getGoogleAuthUrl as a3, castJobDates as a4, getShortTime as a5, getShortDateTime as a6, getShortTimeDelta as a7, BuildType as a8, updateProject as a9, getShortDate as b, BaseGameCommand as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, BetaGroup as i, isCWDGodotGame as j, Certificate as k, CertificateType as l, Profile as m, ProfileType as n, API_URL as o, getAuthedHeaders as p, getGodotProjectCapabilities as q, CapabilityType as r, GameEngine as s, getGodotVersion as t, createProject as u, DEFAULT_SHIPPED_FILES_GLOBS as v, DEFAULT_IGNORED_FILES_GLOBS as w, getGodotProjectName as x, getProjectJobs as y, getJob as z };
772
+ export { setAuthToken as $, ApiKey as A, BaseAuthenticatedCommand as B, CredentialsType as C, DetailsFlags as D, getProject as E, getProjectPlatformProgress as F, GODOT_CAPABILITIES as G, downloadBuildById as H, castArrayObjectDates as I, JobStatus as J, queryClient as K, JobStage as L, LogLevel as M, WS_URL as N, getAuthToken as O, Platform as P, getGoogleStatus as Q, getGodotAndroidPackageName as R, inviteServiceAccount as S, disconnectGoogle as T, UserRole as U, BaseCommand as V, WEB_URL as W, getAPIKeys as X, createAPIKey as Y, revokeAPIKey as Z, getSingleUseUrl as _, ApiKeyType as a, acceptTerms as a0, Auth as a1, getNewUploadTicket as a2, startJobsFromUpload as a3, castObjectDates as a4, getShortAuthRequiredUrl as a5, getGoogleAuthUrl as a6, castJobDates as a7, getShortTime as a8, getShortDateTime as a9, getShortTimeDelta as aa, BuildType as ab, updateProject as ac, getShortDate as b, BaseGameCommand as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, BetaGroup as i, isCWDGodotGame as j, Certificate as k, CertificateType as l, Profile as m, ProfileType as n, API_URL as o, getAuthedHeaders as p, getGodotProjectCapabilities as q, CapabilityType as r, GameEngine as s, getGodotVersion as t, createProject as u, DEFAULT_SHIPPED_FILES_GLOBS as v, DEFAULT_IGNORED_FILES_GLOBS as w, getGodotProjectName as x, getProjectJobs as y, getJob as z };
@@ -4,7 +4,7 @@ import path from 'node:path';
4
4
  import { promises } from 'node:readline';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import readlineSync from 'readline-sync';
7
- import { L as JobStage, P as Platform, M as LogLevel, J as JobStatus } from './index-BhhiXbey.js';
7
+ import { L as JobStage, P as Platform, M as LogLevel, J as JobStatus } from './index-CO_ssVFA.js';
8
8
  import 'luxon';
9
9
  import 'axios';
10
10
  import 'isomorphic-git';
@@ -17,6 +17,7 @@ import 'fast-glob';
17
17
  import 'yazl';
18
18
  import 'socket.io-client';
19
19
  import 'fullscreen-ink';
20
+ import 'ink';
20
21
 
21
22
  function getShortUUID(originalUuid) {
22
23
  return originalUuid.slice(0, 8);
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import { o as API_URL, p as getAuthedHeaders, I as castArrayObjectDates } from './index-BhhiXbey.js';
2
+ import { o as API_URL, p as getAuthedHeaders, I as castArrayObjectDates } from './index-CO_ssVFA.js';
3
3
  import 'node:fs';
4
4
 
5
5
  async function getUserCredentials(pageSize = 100) {
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import { o as API_URL, p as getAuthedHeaders } from './index-BhhiXbey.js';
2
+ import { o as API_URL, p as getAuthedHeaders } from './index-CO_ssVFA.js';
3
3
 
4
4
  async function getNewUploadTicket(projectId = null) {
5
5
  const url = projectId ? `${API_URL}/projects/${projectId}/credentials/url` : `${API_URL}/credentials/url`;
@@ -1,6 +1,6 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import axios from 'axios';
3
- import { o as API_URL, p as getAuthedHeaders } from './index-BhhiXbey.js';
3
+ import { o as API_URL, p as getAuthedHeaders } from './index-CO_ssVFA.js';
4
4
 
5
5
  const cacheKeys = {
6
6
  androidKeyTestResult: (props) => ["androidKeyTestResult", ...Object.values(props)],
@@ -1,5 +1,5 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
- import { f as App } from './index-BhhiXbey.js';
2
+ import { f as App } from './index-CO_ssVFA.js';
3
3
 
4
4
  const queryAppleApp = async ({ ctx, iosBundleId }) => {
5
5
  if (!iosBundleId) {
@@ -1,5 +1,5 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
- import { e as BundleId, q as getGodotProjectCapabilities, P as Platform, G as GODOT_CAPABILITIES, r as CapabilityType } from './index-BhhiXbey.js';
2
+ import { e as BundleId, q as getGodotProjectCapabilities, P as Platform, G as GODOT_CAPABILITIES, r as CapabilityType } from './index-CO_ssVFA.js';
3
3
 
4
4
  async function getBundleIdCapabilities(bundleId) {
5
5
  const current = await bundleId.getBundleIdCapabilitiesAsync();
@@ -1,8 +1,8 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  import axios from 'axios';
3
- import { b as getShortDate, p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates } from './index-BhhiXbey.js';
4
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
5
- import { g as getShortUUID } from './index-CGBdOm1q.js';
3
+ import { b as getShortDate, p as getAuthedHeaders, o as API_URL, I as castArrayObjectDates } from './index-CO_ssVFA.js';
4
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DueKynFy.js';
5
+ import { g as getShortUUID } from './index-CYjZ26If.js';
6
6
 
7
7
  async function queryProjectCredentials({
8
8
  projectId,
@@ -1,6 +1,6 @@
1
1
  import { useEffect } from 'react';
2
2
  import { io } from 'socket.io-client';
3
- import { N as WS_URL, O as getAuthToken } from './index-BhhiXbey.js';
3
+ import { N as WS_URL, O as getAuthToken } from './index-CO_ssVFA.js';
4
4
 
5
5
  function useWebSocket(listeners = []) {
6
6
  const log = () => {
@@ -0,0 +1,27 @@
1
+ # Command: `apiKey create`
2
+
3
+ ## Description
4
+
5
+ Create a new API key for your ShipThis account.
6
+
7
+ ## Help Output
8
+
9
+ ```help
10
+ USAGE
11
+ $ shipthis apiKey create [-n <value>] [-d <value>] [-q]
12
+
13
+ FLAGS
14
+ -d, --durationDays=<value> [default: 365] duration of the API key in days
15
+ -n, --name=<value> name to apply to the API key (if not provided, a random name will be generated)
16
+ -q, --quiet Outputs just the secret value
17
+
18
+ DESCRIPTION
19
+ Create a new API key for your ShipThis account.
20
+
21
+ EXAMPLES
22
+ $ shipthis apiKey create --durationDays 30
23
+
24
+ $ shipthis apiKey create --name ci-key --durationDays 90
25
+
26
+ $ shipthis apiKey create --name ci-key-headless --durationDays 365 --quiet
27
+ ```
@@ -0,0 +1,30 @@
1
+ # Command: `apiKey list`
2
+
3
+ ## Description
4
+
5
+ Displays a list of your ShipThis API keys.
6
+
7
+ ## Help Output
8
+
9
+ ```help
10
+ USAGE
11
+ $ shipthis apiKey list [-r asc|desc] [-o createdAt|updatedAt|name] [-p <value>] [-s <value>]
12
+
13
+ FLAGS
14
+ -o, --orderBy=<option> [default: createdAt] The field to order by
15
+ <options: createdAt|updatedAt|name>
16
+ -p, --pageNumber=<value> The page number to show (starts at 0)
17
+ -r, --order=<option> [default: desc] The order to sort by
18
+ <options: asc|desc>
19
+ -s, --pageSize=<value> [default: 10] The number of items to show per page
20
+
21
+ DESCRIPTION
22
+ Displays a list of your ShipThis API keys.
23
+
24
+ EXAMPLES
25
+ $ shipthis apiKey list
26
+
27
+ $ shipthis apiKey list --pageNumber 1
28
+
29
+ $ shipthis apiKey list --orderBy createdAt --order asc
30
+ ```
@@ -0,0 +1,26 @@
1
+ # Command: `apiKey revoke`
2
+
3
+ ## Description
4
+
5
+ Revokes a specific ShipThis API key.
6
+
7
+ ## Help Output
8
+
9
+ ```help
10
+ USAGE
11
+ $ shipthis apiKey revoke APIKEYID [-q]
12
+
13
+ ARGUMENTS
14
+ APIKEYID The ID of the API key to revoke
15
+
16
+ FLAGS
17
+ -q, --quiet Suppress output except for errors
18
+
19
+ DESCRIPTION
20
+ Revokes a specific ShipThis API key.
21
+
22
+ EXAMPLES
23
+ $ shipthis apiKey revoke abcd1234
24
+
25
+ $ shipthis apiKey revoke abcd1234 --quiet
26
+ ```