shipthis 0.1.30 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +122 -41
  2. package/assets/markdown/create-google-play-game.md +2 -4
  3. package/assets/markdown/ship-success.md +1 -1
  4. package/dist/{AppleBundleIdDetails-Fp5COwTa.js → AppleBundleIdDetails-6H3cNWxw.js} +17 -19
  5. package/dist/{Command-1p5alCz3.js → Command-WPpmLPkL.js} +13 -12
  6. package/dist/CommandGame-cxzWG4nT.js +7 -0
  7. package/dist/{Create-1xAdntNl.js → Create-3Ob8sjik.js} +20 -20
  8. package/dist/GameStatus-BQEtVKvv.js +137 -0
  9. package/dist/{Import-CzC-M4ln.js → Import-CFuPDI0K.js} +33 -35
  10. package/dist/{JobLogTail-CZxoMSd5.js → JobLogTail-0CBLoG8N.js} +53 -52
  11. package/dist/{JobProgress-BjNgtIjm.js → JobProgress-lKqVT88m.js} +46 -37
  12. package/dist/{JobStatusTable-BB-PWlwj.js → JobStatusTable-C_ZsZJCm.js} +14 -13
  13. package/dist/{NextSteps-CK9zHOCt.js → NextSteps-DbJHmscQ.js} +1 -3
  14. package/dist/{ProgressSpinner-6pw1T8Iw.js → ProgressSpinner-DGcakQSK.js} +1 -1
  15. package/dist/{ProjectCredentialsTable-DyZep993.js → ProjectCredentialsTable-B5pHOnGu.js} +11 -10
  16. package/dist/{StatusTable-Dm5St4g-.js → StatusTable-DzRWcMr4.js} +7 -9
  17. package/dist/{Table-CvM6pccN.js → Table-FaNgpyeq.js} +15 -15
  18. package/dist/{UserCredentialsTable-BraKyDWT.js → UserCredentialsTable-3W3qesh7.js} +18 -19
  19. package/dist/{baseAppleCommand-BHRIBtTj.js → baseAppleCommand-BGV088--.js} +1 -1
  20. package/dist/{baseGameAndroidCommand-SrDRbhAG.js → baseGameAndroidCommand-CsemgVjp.js} +23 -23
  21. package/dist/commands/apple/apiKey/create.js +35 -35
  22. package/dist/commands/apple/apiKey/export.js +26 -26
  23. package/dist/commands/apple/apiKey/import.js +27 -27
  24. package/dist/commands/apple/apiKey/status.js +31 -31
  25. package/dist/commands/apple/certificate/create.js +39 -39
  26. package/dist/commands/apple/certificate/export.js +26 -26
  27. package/dist/commands/apple/certificate/import.js +27 -27
  28. package/dist/commands/apple/certificate/status.js +31 -31
  29. package/dist/commands/apple/login.js +15 -15
  30. package/dist/commands/apple/status.js +28 -28
  31. package/dist/commands/dashboard.js +10 -10
  32. package/dist/commands/game/android/apiKey/connect.js +28 -28
  33. package/dist/commands/game/android/apiKey/create.js +28 -28
  34. package/dist/commands/game/android/apiKey/export.js +29 -29
  35. package/dist/commands/game/android/apiKey/import.js +31 -31
  36. package/dist/commands/game/android/apiKey/invite.js +14 -14
  37. package/dist/commands/game/android/apiKey/status.js +29 -29
  38. package/dist/commands/game/android/keyStore/create.js +24 -24
  39. package/dist/commands/game/android/keyStore/export.js +28 -28
  40. package/dist/commands/game/android/keyStore/import.js +35 -35
  41. package/dist/commands/game/android/keyStore/status.js +26 -26
  42. package/dist/commands/game/android/status.js +14 -58
  43. package/dist/commands/game/build/download.js +24 -24
  44. package/dist/commands/game/build/list.js +37 -37
  45. package/dist/commands/game/create.js +15 -15
  46. package/dist/commands/game/details.js +35 -36
  47. package/dist/commands/game/export.js +12 -12
  48. package/dist/commands/game/ios/app/addTester.js +24 -24
  49. package/dist/commands/game/ios/app/create.js +24 -24
  50. package/dist/commands/game/ios/app/status.js +29 -29
  51. package/dist/commands/game/ios/app/sync.js +31 -31
  52. package/dist/commands/game/ios/profile/create.js +30 -30
  53. package/dist/commands/game/ios/profile/export.js +28 -28
  54. package/dist/commands/game/ios/profile/import.js +32 -32
  55. package/dist/commands/game/ios/profile/status.js +36 -36
  56. package/dist/commands/game/ios/status.js +46 -58
  57. package/dist/commands/game/ios/wizard.js +31 -31
  58. package/dist/commands/game/job/list.js +34 -34
  59. package/dist/commands/game/job/status.js +31 -31
  60. package/dist/commands/game/list.js +45 -41
  61. package/dist/commands/game/ship.js +73 -70
  62. package/dist/commands/game/status.js +38 -82
  63. package/dist/commands/game/wizard.js +271 -307
  64. package/dist/commands/internal/fastlane.js +15 -17
  65. package/dist/commands/internal/readme.js +38 -36
  66. package/dist/commands/login.js +14 -14
  67. package/dist/commands/status.js +35 -33
  68. package/dist/{export-BKn02-NH.js → export-CXsVPXA1.js} +5 -5
  69. package/dist/{git-DREGq-jc.js → git-BpsfNFZ_.js} +8 -8
  70. package/dist/{import-CRMaNBVF.js → import-DGvG5REx.js} +14 -14
  71. package/dist/{index-DxzXU9Hd.js → index-BhhiXbey.js} +244 -221
  72. package/dist/{index-OZi8bvu8.js → index-C03TV1_J.js} +54 -38
  73. package/dist/{index-BTAL7EB_.js → index-C66Dd8Xc.js} +80 -79
  74. package/dist/{index-35Eswf6F.js → index-CGBdOm1q.js} +43 -27
  75. package/dist/{index--EbYyBAZ.js → index-CS9Gwcb0.js} +41 -43
  76. package/dist/{index-u1aj1OQW.js → index-CtTI85m-.js} +6 -6
  77. package/dist/{upload-Bw0zrS4M.js → upload-8y5MQEm9.js} +22 -22
  78. package/dist/{useAndroidServiceAccountTestResult-CJLIEYmA.js → useAndroidServiceAccountTestResult-DZk5SMxI.js} +11 -13
  79. package/dist/{useAppleApp-cnb8gX0x.js → useAppleApp-DWYGURwU.js} +4 -4
  80. package/dist/{useAppleBundleId-B0Etav8g.js → useAppleBundleId-PsTJ2g1B.js} +6 -6
  81. package/dist/{useProjectCredentials-DX3e_PPc.js → useProjectCredentials-BEphqa18.js} +10 -12
  82. package/dist/{useWebSocket-BOCa8v6o.js → useWebSocket-5PYa2QER.js} +1 -1
  83. package/dist/utils/help.js +4 -4
  84. package/package.json +4 -2
  85. package/dist/CommandGame-Z4eUQBjn.js +0 -9
  86. package/dist/{RunWithSpinner-BVXNWGD3.js → RunWithSpinner-gMVA07bZ.js} +2 -2
@@ -2,16 +2,17 @@ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { Text, useInput, Box } from 'ink';
3
3
  import open from 'open';
4
4
  import { useState, useEffect, useContext } from 'react';
5
- import { R as getGoogleStatus, a2 as getShortAuthRequiredUrl, a3 as getGoogleAuthUrl, W as WEB_URL } from './index-DxzXU9Hd.js';
6
- import 'crypto';
7
- import 'fs';
8
- import 'readline-sync';
9
- import 'node:readline';
5
+ import 'ink-spinner';
6
+ import 'node:crypto';
7
+ import 'node:fs';
10
8
  import 'node:path';
9
+ import 'node:readline';
11
10
  import 'node:url';
11
+ 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
16
  import '@oclif/core';
16
17
  import { useQuery } from '@tanstack/react-query';
17
18
  import 'crypto-js';
@@ -19,55 +20,52 @@ import 'uuid';
19
20
  import 'fast-glob';
20
21
  import 'yazl';
21
22
  import 'socket.io-client';
22
- import { u as useWebSocket } from './useWebSocket-BOCa8v6o.js';
23
- import { c as cacheKeys } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
24
- import { b as GameContext, M as Markdown } from './index-BTAL7EB_.js';
25
- import 'ink-spinner';
26
- import '@inkjs/ui';
23
+ import { c as cacheKeys } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
24
+ import { u as useWebSocket } from './useWebSocket-5PYa2QER.js';
25
+ import 'fullscreen-ink';
27
26
  import 'string-length';
28
27
  import 'strip-ansi';
28
+ import '@inkjs/ui';
29
+ import { G as GameContext, M as Markdown } from './index-C66Dd8Xc.js';
29
30
  import 'marked';
30
31
  import 'marked-terminal';
31
- import 'path';
32
32
  import qrcode from 'qrcode';
33
33
 
34
- const useGoogleStatus = () => {
35
- return useQuery({
36
- queryKey: cacheKeys.googleStatus(),
37
- queryFn: getGoogleStatus
38
- });
39
- };
34
+ const useGoogleStatus = () => useQuery({
35
+ queryFn: getGoogleStatus,
36
+ queryKey: cacheKeys.googleStatus()
37
+ });
40
38
 
41
39
  function useGoogleStatusWatching({
42
- projectId,
43
40
  isWatching,
44
- onGoogleStatusUpdate
41
+ onGoogleStatusUpdate,
42
+ projectId
45
43
  }) {
46
44
  const [wsGoogleStatus, setWsGoogleStatus] = useState(null);
47
45
  const listener = {
48
- getPattern: () => `project.${projectId}:google-status`,
49
- eventHandler: async (pattern, data2) => {
46
+ async eventHandler(pattern, data2) {
50
47
  setWsGoogleStatus(data2);
51
48
  if (onGoogleStatusUpdate) onGoogleStatusUpdate(data2);
52
- }
49
+ },
50
+ getPattern: () => `project.${projectId}:google-status`
53
51
  };
54
52
  useWebSocket([listener] );
55
- const { isLoading, data: googleStatus } = useGoogleStatus();
53
+ const { data: googleStatus, isLoading } = useGoogleStatus();
56
54
  useEffect(() => {
57
55
  setWsGoogleStatus(null);
58
56
  }, [projectId, isWatching, googleStatus]);
59
57
  const fetchedGoogleStatus = googleStatus ? googleStatus : null;
60
58
  const data = wsGoogleStatus ? wsGoogleStatus : fetchedGoogleStatus;
61
59
  return {
62
- isLoading,
63
- data
60
+ data,
61
+ isLoading
64
62
  };
65
63
  }
66
64
 
67
65
  const QRCodeTerminal = ({ url }) => {
68
66
  const [code, setCode] = useState(null);
69
67
  const handleLoad = async () => {
70
- const codeString = await qrcode.toString(url, { type: "terminal", errorCorrectionLevel: "L", small: true });
68
+ const codeString = await qrcode.toString(url, { errorCorrectionLevel: "L", small: true, type: "terminal" });
71
69
  setCode(codeString);
72
70
  };
73
71
  useEffect(() => {
@@ -97,28 +95,46 @@ const ConnectGoogle = (props) => {
97
95
  const { gameId } = useContext(GameContext);
98
96
  return /* @__PURE__ */ jsx(Fragment, { children: gameId && /* @__PURE__ */ jsx(ConnectForGame, { gameId, ...props }) });
99
97
  };
100
- const ConnectForGame = ({ onComplete, onError, helpPage, gameId, ...boxProps }) => {
98
+ const ConnectForGame = ({ gameId, helpPage, onComplete, onError, ...boxProps }) => {
99
+ const [showQRCode, setShowQRCode] = useState(false);
101
100
  useGoogleStatusWatching({
102
- projectId: gameId,
103
101
  isWatching: true,
104
- onGoogleStatusUpdate: (status) => {
102
+ onGoogleStatusUpdate(status) {
105
103
  if (status.isAuthenticated) return onComplete();
106
- }
104
+ },
105
+ projectId: gameId
107
106
  });
108
107
  useInput(async (input) => {
109
- if (!gameId) return;
110
- if (input !== "d") return;
111
- const url = await getConnectUrl(gameId, true);
112
- await open(url);
108
+ switch (input) {
109
+ case "q": {
110
+ setShowQRCode(true);
111
+ return;
112
+ }
113
+ case "x": {
114
+ setShowQRCode(false);
115
+ return;
116
+ }
117
+ case "b": {
118
+ if (!gameId) return;
119
+ const url = await getConnectUrl(gameId, true);
120
+ await open(url);
121
+ }
122
+ }
113
123
  });
114
124
  const templateVars = {
115
125
  privacyURL: new URL("/privacy", WEB_URL).toString()
116
126
  };
117
127
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, ...boxProps, children: [
118
- /* @__PURE__ */ jsx(Markdown, { filename: "privacy-notification.md", templateVars }),
119
- /* @__PURE__ */ jsx(Text, { children: "Scan the QR code below to connect your Google account to ShipThis:" }),
120
- gameId && /* @__PURE__ */ jsx(GoogleAuthQRCode, { gameId, helpPage: !!helpPage }),
121
- /* @__PURE__ */ jsx(Text, { children: "Or press D to sign-in using your browser" })
128
+ !showQRCode && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
129
+ /* @__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" }),
131
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "#4CE64C", children: "Press Q to show a QR-code to connect using your mobile phone" })
132
+ ] }),
133
+ showQRCode && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
134
+ /* @__PURE__ */ jsx(Text, { children: "Scan the QR code below to connect your Google account to ShipThis:" }),
135
+ gameId && /* @__PURE__ */ jsx(GoogleAuthQRCode, { gameId, helpPage: Boolean(helpPage) }),
136
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "#4CE64C", children: "Press X to hide the QR code" })
137
+ ] })
122
138
  ] });
123
139
  };
124
140
 
@@ -1,26 +1,27 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { Text, useInput, Box } from 'ink';
3
- import React, { useState, useEffect, useContext, useRef } from 'react';
4
3
  import Spinner from 'ink-spinner';
5
4
  import open from 'open';
6
- import { g as getShortUUID, h as getPlatformName, s as scriptDir } from './index-35Eswf6F.js';
7
- import { c as cacheKeys, u as useAndroidServiceAccountTestResult, K as KeyTestStatus, a as KeyTestError } from './useAndroidServiceAccountTestResult-CJLIEYmA.js';
8
- import { p as getAuthedHeaders, q as API_URL, I as castArrayObjectDates, P as Platform, a6 as getShortDateTime, J as JobStatus, a7 as getShortTimeDelta, E as getJob, F as getProject, a2 as getShortAuthRequiredUrl, K as queryClient, W as WEB_URL } from './index-DxzXU9Hd.js';
9
- import '@inkjs/ui';
10
- import axios from 'axios';
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';
11
8
  import { useQuery } from '@tanstack/react-query';
12
- import fs__default from 'fs';
9
+ import axios from 'axios';
10
+ import { c as cacheKeys, u as useAndroidServiceAccountTestResult, K as KeyTestStatus, a as KeyTestError } from './useAndroidServiceAccountTestResult-DZk5SMxI.js';
11
+ import 'luxon';
12
+ import fs__default from 'node:fs';
13
+ import 'fast-glob';
13
14
  import 'uuid';
14
15
  import 'yazl';
16
+ import 'socket.io-client';
17
+ import 'fullscreen-ink';
18
+ import 'string-length';
19
+ import 'strip-ansi';
20
+ import '@inkjs/ui';
21
+ import path from 'node:path';
15
22
  import { setOptions, parse } from 'marked';
16
23
  import TerminalRenderer from 'marked-terminal';
17
- import path from 'path';
18
24
  import 'qrcode';
19
- import 'string-length';
20
- import 'strip-ansi';
21
- import 'luxon';
22
- import 'fast-glob';
23
- import 'socket.io-client';
24
25
 
25
26
  async function queryBuilds({ projectId, ...pageAndSortParams }) {
26
27
  try {
@@ -37,21 +38,21 @@ async function queryBuilds({ projectId, ...pageAndSortParams }) {
37
38
  }
38
39
  }
39
40
  function getBuildSummary(build) {
40
- const buildType = build.buildType || (build.platform == Platform.IOS ? "IPA" : "AAB");
41
- const filename = `game.${buildType.toLowerCase()}`;
41
+ const ext = build.buildType || (build.platform == Platform.IOS ? "IPA" : "AAB");
42
+ const filename = `game.${ext.toLowerCase()}`;
42
43
  return {
43
44
  id: getShortUUID(build.id),
44
45
  jobId: getShortUUID(build.jobId),
45
46
  ...getJobDetailsSummary(build.jobDetails),
46
- type: `${getPlatformName(build.platform)} ${buildType}`,
47
+ cmd: `shipthis game build download ${getShortUUID(build.id)} ${filename}`,
47
48
  createdAt: getShortDateTime(build.createdAt),
48
- cmd: `shipthis game build download ${getShortUUID(build.id)} ${filename}`
49
+ type: `${getPlatformName(build.platform)} ${build.buildType || ""}`.trim()
49
50
  };
50
51
  }
51
52
  const useBuilds = (props) => {
52
53
  const queryResult = useQuery({
53
- queryKey: cacheKeys.builds(props),
54
- queryFn: async () => queryBuilds(props)
54
+ queryFn: async () => queryBuilds(props),
55
+ queryKey: cacheKeys.builds(props)
55
56
  });
56
57
  return queryResult;
57
58
  };
@@ -62,8 +63,8 @@ function getJobDetailsSummary(jobDetails) {
62
63
  const gitCommit = jobDetails?.gitCommitHash ? getShortUUID(jobDetails?.gitCommitHash) : "";
63
64
  const gitBranch = jobDetails?.gitBranch || "";
64
65
  return {
65
- version: `${semanticVersion} (${buildNumber})`,
66
- gitInfo: gitCommit ? `${gitCommit} (${gitBranch})` : ""
66
+ gitInfo: gitCommit ? `${gitCommit} (${gitBranch})` : "",
67
+ version: `${semanticVersion} (${buildNumber})`
67
68
  };
68
69
  }
69
70
  function getJobSummary(job, timeNow) {
@@ -71,22 +72,56 @@ function getJobSummary(job, timeNow) {
71
72
  return {
72
73
  id: getShortUUID(job.id),
73
74
  ...getJobDetailsSummary(job.details),
74
- platform: getPlatformName(job.type),
75
- status: job.status,
76
75
  createdAt: getShortDateTime(job.createdAt),
77
- runtime: getShortTimeDelta(job.createdAt, inProgress ? timeNow : job.updatedAt)
76
+ platform: getPlatformName(job.type),
77
+ runtime: getShortTimeDelta(job.createdAt, inProgress ? timeNow : job.updatedAt),
78
+ status: job.status
78
79
  };
79
80
  }
80
- const useJob = (props) => {
81
- return useQuery({
82
- queryKey: cacheKeys.job(props),
83
- queryFn: () => getJob(props.jobId, props.projectId)
81
+ const useJob = (props) => useQuery({
82
+ queryFn: () => getJob(props.jobId, props.projectId),
83
+ queryKey: cacheKeys.job(props)
84
+ });
85
+
86
+ const cleanHyperlinks = (input) => (
87
+ // When we run in a <ScrollArea> the links break
88
+ // Remove OSC 8 hyperlink wrappers but preserve the styled content inside
89
+ input.replaceAll(/\u001B]8;;[^\u0007]*\u0007/g, "").replaceAll("\x1B]8;;\x07", "")
90
+ );
91
+ const getRenderedMarkdown = ({ filename, templateVars, ...options }) => {
92
+ setOptions({
93
+ renderer: new TerminalRenderer({
94
+ ...options
95
+ })
84
96
  });
97
+ const entrypointPath = fs__default.realpathSync(process.argv[1]);
98
+ const root = path.dirname(entrypointPath);
99
+ const mdPath = path.join(root, "..", "assets", "markdown", filename);
100
+ const mdTemplate = fs__default.readFileSync(mdPath, "utf8").trim();
101
+ let markdown = mdTemplate;
102
+ if (templateVars) {
103
+ markdown = markdown.replaceAll(/\${if (.*?)}([\S\s]*?)\${endif}/g, (_, key, content) => templateVars[key.trim()] ? content : "");
104
+ markdown = markdown.replaceAll(/\${(.*?)}/g, (_, key) => {
105
+ const trimmed = key.trim();
106
+ return templateVars[trimmed] ? String(templateVars[trimmed]) : "";
107
+ });
108
+ }
109
+ const rendered = parse(markdown).trim();
110
+ const cleaned = cleanHyperlinks(rendered);
111
+ return cleaned;
112
+ };
113
+ const Markdown = ({ filename, templateVars, ...options }) => {
114
+ const [text, setText] = useState("");
115
+ useEffect(() => {
116
+ const cleaned = getRenderedMarkdown({ filename, templateVars, ...options });
117
+ setText(cleaned);
118
+ }, [filename, templateVars, options]);
119
+ return /* @__PURE__ */ jsx(Text, { children: text });
85
120
  };
86
121
 
87
122
  const CommandContext = React.createContext({
88
123
  command: null,
89
- setCommand: (command) => {
124
+ setCommand(command) {
90
125
  }
91
126
  });
92
127
  const CommandProvider = (props) => {
@@ -95,21 +130,15 @@ const CommandProvider = (props) => {
95
130
  };
96
131
 
97
132
  const GameContext = React.createContext({
98
- gameId: null,
99
133
  game: null,
100
- setGameId: (gameId) => {
134
+ gameId: null,
135
+ setGameId(gameId) {
101
136
  }
102
137
  });
103
138
  const GameProvider = ({ children }) => {
104
- const [gameId, setGameId] = useState(null);
105
- const [game, setGame] = useState(null);
106
139
  const { command } = React.useContext(CommandContext);
107
- const handleLoad = async () => {
108
- if (command) {
109
- const commandGameId = await command.getGameId();
110
- if (commandGameId) setGameId(commandGameId);
111
- }
112
- };
140
+ const [gameId, setGameId] = useState(command?.getGameId() || null);
141
+ const [game, setGame] = useState(null);
113
142
  const handleGameIdChange = async () => {
114
143
  if (!gameId) {
115
144
  setGame(null);
@@ -121,37 +150,7 @@ const GameProvider = ({ children }) => {
121
150
  useEffect(() => {
122
151
  handleGameIdChange();
123
152
  }, [gameId]);
124
- useEffect(() => {
125
- handleLoad();
126
- }, [command]);
127
- return /* @__PURE__ */ jsx(GameContext.Provider, { value: { gameId, game, setGameId }, children });
128
- };
129
-
130
- const cleanHyperlinks = (input) => {
131
- return input.replace(/\x1b]8;;[^\x07]*\x07/g, "").replace(/\x1b]8;;\x07/g, "");
132
- };
133
- const getRenderedMarkdown = ({ filename, templateVars, ...options }) => {
134
- setOptions({
135
- renderer: new TerminalRenderer({
136
- ...options
137
- })
138
- });
139
- const entrypointPath = fs__default.realpathSync(process.argv[1]);
140
- const root = path.dirname(entrypointPath);
141
- const mdPath = path.join(root, "..", "assets", "markdown", filename);
142
- const mdTemplate = fs__default.readFileSync(mdPath, "utf8").trim();
143
- const markdown = !templateVars ? mdTemplate : mdTemplate.replace(/\${(.*?)}/g, (_, key) => templateVars[key.trim()] || "");
144
- const rendered = parse(markdown).trim();
145
- const cleaned = cleanHyperlinks(rendered);
146
- return cleaned;
147
- };
148
- const Markdown = ({ filename, templateVars, ...options }) => {
149
- const [text, setText] = useState("");
150
- useEffect(() => {
151
- const cleaned = getRenderedMarkdown({ filename, templateVars, ...options });
152
- setText(cleaned);
153
- }, [filename, templateVars, options]);
154
- return /* @__PURE__ */ jsx(Text, { children: text });
153
+ return /* @__PURE__ */ jsx(GameContext.Provider, { value: { game, gameId, setGameId }, children });
155
154
  };
156
155
 
157
156
  scriptDir(import.meta);
@@ -163,9 +162,9 @@ const CreateGooglePlayGame = (props) => {
163
162
  const { gameId } = useContext(GameContext);
164
163
  return /* @__PURE__ */ jsx(Fragment, { children: gameId && /* @__PURE__ */ jsx(Create, { gameId, ...props }) });
165
164
  };
166
- const Create = ({ onComplete, onError, gameId, ...boxProps }) => {
165
+ const Create = ({ gameId, onComplete, onError, ...boxProps }) => {
167
166
  const { data: result, isFetching } = useAndroidServiceAccountTestResult({ projectId: gameId });
168
- const { data: builds } = useBuilds({ projectId: gameId, pageNumber: 0 });
167
+ const { data: builds } = useBuilds({ pageNumber: 0, projectId: gameId });
169
168
  const previousIsFound = useRef(false);
170
169
  useEffect(() => {
171
170
  const isFound = getIsAppFound(result);
@@ -177,25 +176,27 @@ const Create = ({ onComplete, onError, gameId, ...boxProps }) => {
177
176
  useInput(async (input) => {
178
177
  if (!gameId) return;
179
178
  switch (input) {
180
- case "r":
179
+ case "r": {
181
180
  queryClient.invalidateQueries({
182
181
  queryKey: cacheKeys.androidKeyTestResult({ projectId: gameId })
183
182
  });
184
183
  break;
185
- case "d":
184
+ }
185
+ case "d": {
186
186
  const dashUrl = await getShortAuthRequiredUrl(`/games/${getShortUUID(gameId)}/builds`);
187
187
  await open(dashUrl);
188
+ }
188
189
  }
189
190
  if (input !== "r") return;
190
191
  queryClient.invalidateQueries({
191
192
  queryKey: cacheKeys.androidKeyTestResult({ projectId: gameId })
192
193
  });
193
194
  });
194
- const initialBuild = builds?.data.find((build) => build.platform === Platform.ANDROID);
195
- const downloadCmd = initialBuild ? `${getBuildSummary(initialBuild).cmd}` : "";
195
+ const initialBuild = builds?.data.find((build) => build.platform === Platform.ANDROID && build.buildType === BuildType.AAB);
196
+ const downloadCmd = initialBuild ? `${getBuildSummary(initialBuild).cmd}` : "Initial AAB build not found!";
196
197
  const templateVars = {
197
- downloadCmd,
198
- dashboardURL: new URL(`/games/${getShortUUID(gameId)}/builds`, WEB_URL).toString()
198
+ dashboardURL: new URL(`/games/${getShortUUID(gameId)}/builds`, WEB_URL).toString(),
199
+ downloadCmd
199
200
  };
200
201
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, ...boxProps, children: [
201
202
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
@@ -206,4 +207,4 @@ const Create = ({ onComplete, onError, gameId, ...boxProps }) => {
206
207
  ] }) });
207
208
  };
208
209
 
209
- export { CommandProvider as C, GameProvider as G, Markdown as M, getJobSummary as a, GameContext as b, getBuildSummary as c, CommandContext as d, useJob as e, CreateGooglePlayGame as f, getRenderedMarkdown as g, queryBuilds as q, useBuilds as u };
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 };
@@ -1,63 +1,76 @@
1
- import crypto from 'crypto';
2
- import fs__default from 'fs';
3
- import readlineSync from 'readline-sync';
4
- import { promises } from 'node:readline';
1
+ import crypto from 'node:crypto';
2
+ import fs__default from 'node:fs';
5
3
  import path from 'node:path';
4
+ import { promises } from 'node:readline';
6
5
  import { fileURLToPath } from 'node:url';
7
- import { L as JobStage, P as Platform, M as LogLevel, J as JobStatus } from './index-DxzXU9Hd.js';
6
+ import readlineSync from 'readline-sync';
7
+ import { L as JobStage, P as Platform, M as LogLevel, J as JobStatus } from './index-BhhiXbey.js';
8
8
  import 'luxon';
9
9
  import 'axios';
10
10
  import 'isomorphic-git';
11
11
  import '@oclif/core';
12
- import 'react';
13
12
  import '@tanstack/react-query';
13
+ import 'react';
14
14
  import 'crypto-js';
15
15
  import 'uuid';
16
16
  import 'fast-glob';
17
17
  import 'yazl';
18
18
  import 'socket.io-client';
19
+ import 'fullscreen-ink';
19
20
 
20
21
  function getShortUUID(originalUuid) {
21
22
  return originalUuid.slice(0, 8);
22
23
  }
23
24
  function getStageColor(stage) {
24
25
  switch (stage) {
25
- case JobStage.SETUP:
26
+ case JobStage.SETUP: {
26
27
  return "#FFB3B3";
28
+ }
27
29
  // pastel red
28
- case JobStage.CONFIGURE:
30
+ case JobStage.CONFIGURE: {
29
31
  return "#FFD9B3";
32
+ }
30
33
  // pastel orange
31
- case JobStage.EXPORT:
34
+ case JobStage.EXPORT: {
32
35
  return "#FFFACD";
36
+ }
33
37
  // pastel yellow
34
- case JobStage.BUILD:
38
+ case JobStage.BUILD: {
35
39
  return "#B3FFB3";
40
+ }
36
41
  // pastel green
37
- case JobStage.PUBLISH:
42
+ case JobStage.PUBLISH: {
38
43
  return "#B3D9FF";
44
+ }
39
45
  }
40
46
  }
41
47
  function getMessageColor(level) {
42
48
  switch (level) {
43
- case LogLevel.INFO:
49
+ case LogLevel.INFO: {
44
50
  return "white";
45
- case LogLevel.WARN:
51
+ }
52
+ case LogLevel.WARN: {
46
53
  return "yellow";
47
- case LogLevel.ERROR:
54
+ }
55
+ case LogLevel.ERROR: {
48
56
  return "red";
57
+ }
49
58
  }
50
59
  }
51
60
  function getJobStatusColor(status) {
52
61
  switch (status) {
53
- case JobStatus.PENDING:
62
+ case JobStatus.PENDING: {
54
63
  return "yellow";
55
- case JobStatus.PROCESSING:
64
+ }
65
+ case JobStatus.PROCESSING: {
56
66
  return "blue";
57
- case JobStatus.COMPLETED:
67
+ }
68
+ case JobStatus.COMPLETED: {
58
69
  return "green";
59
- case JobStatus.FAILED:
70
+ }
71
+ case JobStatus.FAILED: {
60
72
  return "red";
73
+ }
61
74
  }
62
75
  }
63
76
  async function getFileHash(filename) {
@@ -71,9 +84,9 @@ async function getFileHash(filename) {
71
84
  }
72
85
  function isValidSemVer(versionString) {
73
86
  const [semVer, major, minor, patch, prerelease, buildmetadata] = versionString.match(
74
- /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
87
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][\dA-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][\dA-Za-z-]*))*))?(?:\+([\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*))?$/
75
88
  ) ?? [];
76
- return !!semVer;
89
+ return Boolean(semVer);
77
90
  }
78
91
  function makeHumanReadable(rawObject) {
79
92
  const getLabel = (key) => {
@@ -88,12 +101,15 @@ function makeHumanReadable(rawObject) {
88
101
  }
89
102
  function getPlatformName(platform) {
90
103
  switch (platform) {
91
- case Platform.IOS:
104
+ case Platform.IOS: {
92
105
  return "iOS";
93
- case Platform.ANDROID:
106
+ }
107
+ case Platform.ANDROID: {
94
108
  return "Android";
95
- default:
109
+ }
110
+ default: {
96
111
  throw new Error(`Unknown platform: ${platform}`);
112
+ }
97
113
  }
98
114
  }
99
115
  async function getMaskedInput(message) {
@@ -114,11 +130,11 @@ async function getInput(message) {
114
130
  }
115
131
  function generatePackageName(gameName) {
116
132
  let normalizedGameName = gameName.trim().toLowerCase();
117
- normalizedGameName = normalizedGameName.replace(/[\s\-_]+/g, ".");
118
- normalizedGameName = normalizedGameName.replace(/[^a-z0-9\.]/g, "");
119
- normalizedGameName = normalizedGameName.replace(/\.+/g, ".");
133
+ normalizedGameName = normalizedGameName.replaceAll(/[\s_\-]+/g, ".");
134
+ normalizedGameName = normalizedGameName.replaceAll(/[^\d.a-z]/g, "");
135
+ normalizedGameName = normalizedGameName.replaceAll(/\.+/g, ".");
120
136
  normalizedGameName = normalizedGameName.replace(/^\./, "").replace(/\.$/, "");
121
- if (/^[0-9]/.test(normalizedGameName)) {
137
+ if (/^\d/.test(normalizedGameName)) {
122
138
  normalizedGameName = "app." + normalizedGameName;
123
139
  }
124
140
  const prefix = "com.";