shipthis 0.1.41 → 0.1.42

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 (92) hide show
  1. package/README.md +1 -0
  2. package/assets/markdown/confirm-change-android-build-method.md.ejs +13 -0
  3. package/dist/{AppleBundleIdDetails-BJC7GCx_.js → AppleBundleIdDetails-jDq3gYbk.js} +7 -6
  4. package/dist/{Command-Cj6F5B5a.js → Command-cVo97lkQ.js} +2 -2
  5. package/dist/{CommandGame-CuvuH-z6.js → CommandGame-BwudtYCO.js} +2 -2
  6. package/dist/{Create-pfGYcKu4.js → Create-By4NsPEI.js} +3 -2
  7. package/dist/{GameStatus-ZSe-qG3y.js → GameStatus-C59zQE1H.js} +3 -2
  8. package/dist/{Import-D046HBaF.js → Import-DTcVM-T-.js} +4 -3
  9. package/dist/{JobLogTail-Da8GuReK.js → JobLogTail-BzisGkY8.js} +30 -17
  10. package/dist/{JobProgress-DltCQpzA.js → JobProgress-DAnhaTho.js} +21 -10
  11. package/dist/{JobStatusTable-DVJjHw97.js → JobStatusTable-BYEi8dtD.js} +3 -3
  12. package/dist/{ProjectCredentialsTable-BJJz7W1P.js → ProjectCredentialsTable-NZf3V39z.js} +2 -2
  13. package/dist/{UserCredentialsTable-CSynIVHU.js → UserCredentialsTable-Dp884nYO.js} +2 -2
  14. package/dist/{baseAppleCommand-Aq-Eaw_K.js → baseAppleCommand-DewNWX3L.js} +1 -1
  15. package/dist/{baseCommand-CTn3KGH3.js → baseCommand-CscxrTMI.js} +80 -110
  16. package/dist/{baseGameAndroidCommand-DRzVMKuG.js → baseGameAndroidCommand-CEcDz5P2.js} +4 -3
  17. package/dist/{baseGameCommand-8VL7xe-O.js → baseGameCommand-BKvHM3h_.js} +3 -2
  18. package/dist/commands/apiKey/create.js +4 -5
  19. package/dist/commands/apiKey/list.js +4 -5
  20. package/dist/commands/apiKey/revoke.js +4 -5
  21. package/dist/commands/apple/apiKey/create.js +7 -8
  22. package/dist/commands/apple/apiKey/delete.js +5 -6
  23. package/dist/commands/apple/apiKey/export.js +6 -7
  24. package/dist/commands/apple/apiKey/import.js +6 -7
  25. package/dist/commands/apple/apiKey/status.js +5 -6
  26. package/dist/commands/apple/certificate/create.js +7 -8
  27. package/dist/commands/apple/certificate/delete.js +5 -6
  28. package/dist/commands/apple/certificate/export.js +6 -7
  29. package/dist/commands/apple/certificate/import.js +6 -7
  30. package/dist/commands/apple/certificate/status.js +5 -6
  31. package/dist/commands/apple/login.js +3 -4
  32. package/dist/commands/apple/status.js +4 -5
  33. package/dist/commands/dashboard.js +3 -4
  34. package/dist/commands/game/android/apiKey/connect.js +9 -10
  35. package/dist/commands/game/android/apiKey/create.js +11 -12
  36. package/dist/commands/game/android/apiKey/delete.js +5 -6
  37. package/dist/commands/game/android/apiKey/export.js +7 -8
  38. package/dist/commands/game/android/apiKey/import.js +7 -8
  39. package/dist/commands/game/android/apiKey/invite.js +4 -5
  40. package/dist/commands/game/android/apiKey/policy.js +4 -5
  41. package/dist/commands/game/android/apiKey/status.js +7 -8
  42. package/dist/commands/game/android/keyStore/create.js +8 -9
  43. package/dist/commands/game/android/keyStore/delete.js +5 -6
  44. package/dist/commands/game/android/keyStore/export.js +6 -7
  45. package/dist/commands/game/android/keyStore/import.js +9 -10
  46. package/dist/commands/game/android/keyStore/status.js +6 -7
  47. package/dist/commands/game/android/status.js +3 -4
  48. package/dist/commands/game/build/download.js +4 -5
  49. package/dist/commands/game/build/list.js +5 -6
  50. package/dist/commands/game/create.js +3 -4
  51. package/dist/commands/game/details.js +4 -5
  52. package/dist/commands/game/export.js +3 -4
  53. package/dist/commands/game/ios/app/addTester.js +5 -6
  54. package/dist/commands/game/ios/app/create.js +6 -6
  55. package/dist/commands/game/ios/app/status.js +7 -8
  56. package/dist/commands/game/ios/app/sync.js +5 -6
  57. package/dist/commands/game/ios/profile/create.js +7 -8
  58. package/dist/commands/game/ios/profile/delete.js +5 -6
  59. package/dist/commands/game/ios/profile/export.js +6 -7
  60. package/dist/commands/game/ios/profile/import.js +6 -7
  61. package/dist/commands/game/ios/profile/status.js +7 -8
  62. package/dist/commands/game/ios/status.js +9 -10
  63. package/dist/commands/game/ios/wizard.js +4 -5
  64. package/dist/commands/game/job/list.js +4 -5
  65. package/dist/commands/game/job/status.js +9 -10
  66. package/dist/commands/game/list.js +4 -5
  67. package/dist/commands/game/ship.js +30 -14
  68. package/dist/commands/game/status.js +6 -7
  69. package/dist/commands/game/wizard.js +78 -29
  70. package/dist/commands/internal/fastlane.js +3 -4
  71. package/dist/commands/internal/readme.js +3 -4
  72. package/dist/commands/login.js +3 -4
  73. package/dist/commands/status.js +4 -5
  74. package/dist/commands/util/android-build-method.js +66 -0
  75. package/dist/commands/util/glass.js +2 -3
  76. package/dist/{export-DtATljiz.js → export-DBQHSKU-.js} +1 -1
  77. package/dist/{import-Dk2ywOVU.js → import-Bk4w8kks.js} +1 -1
  78. package/dist/{index-cRnjcGxV.js → index-WrVwh6le.js} +6 -5
  79. package/dist/{index-BW7z-5sB.js → index-qOGviaGc.js} +1 -1
  80. package/dist/{index-CuyVBHWc.js → index-zdIBXHs2.js} +5 -4
  81. package/dist/{upload-CHaDSvvi.js → upload-CeRPHRCP.js} +1 -1
  82. package/dist/{useAppleApp-CR847GWc.js → useAppleApp-DgZH0CBS.js} +1 -1
  83. package/dist/{useAppleBundleId-BnwPmVEu.js → useAppleBundleId-CA7Pg4Hi.js} +2 -2
  84. package/dist/{useAppleProfiles-DY-H0420.js → useAppleProfiles-CUBTPbcC.js} +1 -1
  85. package/dist/{useGoogleStatus-WqPgHteE.js → useGoogleStatus-DpPwKmw_.js} +2 -2
  86. package/dist/{useProjectCredentials-TvlolkId.js → useProjectCredentials-rQLm2O1J.js} +2 -2
  87. package/dist/{useWebSocket-MXDbQHcu.js → useWebSocket-PU55rRGt.js} +1 -1
  88. package/docs/util/android-build-method.md +26 -0
  89. package/docs/util.md +2 -1
  90. package/npm-shrinkwrap.json +14181 -0
  91. package/oclif.manifest.json +2966 -0
  92. package/package.json +9 -6
package/README.md CHANGED
@@ -415,6 +415,7 @@ The build machines do not keep user files after a job completes.
415
415
  - [apiKey](https://shipth.is/docs/reference/apiKey?ref=github_readme) - Commands related to ShipThis API Keys
416
416
  - [apple](https://shipth.is/docs/reference/apple?ref=github_readme) - Commands that relate to linking your ShipThis account with your Apple Developer account
417
417
  - [game](https://shipth.is/docs/reference/game?ref=github_readme) - Commands that relate to configuring the specific game in the current working directory.
418
+ - [util](https://shipth.is/docs/reference/util?ref=github_readme) - Utility commands that do not require authentication
418
419
 
419
420
  ### 🔧 Commands
420
421
 
@@ -0,0 +1,13 @@
1
+ # Confirm change to export_presets.cfg
2
+
3
+ **In order to publish your game on Google Play, an edit must be made to your `export_presets.cfg` file to enable the Gradle build method.**
4
+
5
+ This change is necessary because Google Play requires Android App Bundles (AAB files) for new apps, and the Gradle build method is needed to create AAB files.
6
+
7
+ You can read more about this in the **ShipThis Documentation** [<%= docsURL %>](<%= docsURL %>)
8
+
9
+ You are using Godot version **<%= godotVersion %>**, ShipThis will update the **<%= optionKey %>** option in your `export_presets.cfg` file to enable the Gradle build method.
10
+
11
+ ## Do you want to proceed with this change?
12
+
13
+ Please press **Y** to confirm and proceed with the change or **N** to cancel the operation and exit the Android wizard.
@@ -11,27 +11,28 @@ import 'readline-sync';
11
11
  import 'luxon';
12
12
  import 'axios';
13
13
  import 'isomorphic-git';
14
- import './baseCommand-CTn3KGH3.js';
14
+ import './baseCommand-CscxrTMI.js';
15
15
  import '@oclif/core';
16
16
  import '@tanstack/react-query';
17
17
  import 'react';
18
18
  import 'crypto-js';
19
19
  import 'uuid';
20
- import { u as useAppleApp } from './useAppleApp-CR847GWc.js';
20
+ import { u as useAppleApp } from './useAppleApp-DgZH0CBS.js';
21
21
  import 'fast-glob';
22
22
  import 'yazl';
23
23
  import 'socket.io-client';
24
24
  import 'fullscreen-ink';
25
- import { T as Table } from './Table-FaNgpyeq.js';
26
- import { T as Title } from './Title-BCQtayg6.js';
27
25
  import 'string-length';
28
26
  import 'strip-ansi';
27
+ import { T as Table } from './Table-FaNgpyeq.js';
28
+ import { T as Title } from './Title-BCQtayg6.js';
29
29
  import 'open';
30
- import './baseGameCommand-8VL7xe-O.js';
30
+ import './baseGameCommand-BKvHM3h_.js';
31
+ import 'godot-export-presets';
31
32
  import 'marked';
32
33
  import 'marked-terminal';
33
34
  import 'qrcode';
34
- import { u as useAppleBundleId } from './useAppleBundleId-BnwPmVEu.js';
35
+ import { u as useAppleBundleId } from './useAppleBundleId-CA7Pg4Hi.js';
35
36
 
36
37
  const AppleAppDetails = (props) => {
37
38
  const { data, isLoading } = useAppleApp(props);
@@ -2,7 +2,7 @@ import { jsx } from 'react/jsx-runtime';
2
2
  import { QueryClientProvider } from '@tanstack/react-query';
3
3
  import { useScreenSize } from 'fullscreen-ink';
4
4
  import { Box } from 'ink';
5
- import { H as queryClient } from './baseCommand-CTn3KGH3.js';
5
+ import { I as queryClient } from './baseCommand-CscxrTMI.js';
6
6
  import 'axios';
7
7
  import 'node:fs';
8
8
  import 'crypto-js';
@@ -19,7 +19,7 @@ import 'react';
19
19
  import 'socket.io-client';
20
20
  import 'fast-glob';
21
21
  import 'yazl';
22
- import { i as CommandProvider } from './baseGameCommand-8VL7xe-O.js';
22
+ import { C as CommandProvider } from './baseGameCommand-BKvHM3h_.js';
23
23
 
24
24
  const Command = ({ children, command }) => {
25
25
  const { width } = useScreenSize();
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { j as GameProvider } from './baseGameCommand-8VL7xe-O.js';
3
- import { C as Command } from './Command-Cj6F5B5a.js';
2
+ import { G as GameProvider } from './baseGameCommand-BKvHM3h_.js';
3
+ import { C as Command } from './Command-cVo97lkQ.js';
4
4
 
5
5
  const CommandGame = ({ children, command }) => /* @__PURE__ */ jsx(Command, { command, children: /* @__PURE__ */ jsx(GameProvider, { children }) });
6
6
 
@@ -3,7 +3,7 @@ import { useQueryClient } from '@tanstack/react-query';
3
3
  import axios from 'axios';
4
4
  import { Box } from 'ink';
5
5
  import { useContext } from 'react';
6
- import { p as getAuthedHeaders, o as API_URL } from './baseCommand-CTn3KGH3.js';
6
+ import { q as getAuthedHeaders, p as API_URL } from './baseCommand-CscxrTMI.js';
7
7
  import 'ink-spinner';
8
8
  import 'node:crypto';
9
9
  import 'node:fs';
@@ -14,7 +14,7 @@ import 'readline-sync';
14
14
  import 'luxon';
15
15
  import 'isomorphic-git';
16
16
  import '@oclif/core';
17
- import { G as GameContext, k as cacheKeys } from './baseGameCommand-8VL7xe-O.js';
17
+ import { i as GameContext, k as cacheKeys } from './baseGameCommand-BKvHM3h_.js';
18
18
  import 'fast-glob';
19
19
  import 'uuid';
20
20
  import 'yazl';
@@ -28,6 +28,7 @@ import 'marked';
28
28
  import 'marked-terminal';
29
29
  import 'qrcode';
30
30
  import { R as RunWithSpinner } from './RunWithSpinner-DucRnFp6.js';
31
+ import 'godot-export-presets';
31
32
 
32
33
  const CreateKeystore = ({ onComplete, onError, ...boxProps }) => {
33
34
  const { gameId } = useContext(GameContext);
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { Text, Box } from 'ink';
3
3
  import { useState, useEffect, useContext } from 'react';
4
- import { c as getShortDate, P as Platform, k as getProject, E as getProjectPlatformProgress } from './baseCommand-CTn3KGH3.js';
4
+ import { c as getShortDate, P as Platform, l as getProject, M as getProjectPlatformProgress } from './baseCommand-CscxrTMI.js';
5
5
  import 'ink-spinner';
6
- import { g as getShortUUID, m as makeHumanReadable, G as GameContext, C as CommandContext } from './baseGameCommand-8VL7xe-O.js';
6
+ import { g as getShortUUID, m as makeHumanReadable, i as GameContext, j as CommandContext } from './baseGameCommand-BKvHM3h_.js';
7
7
  import '@tanstack/react-query';
8
8
  import 'axios';
9
9
  import 'luxon';
@@ -23,6 +23,7 @@ import 'marked';
23
23
  import 'marked-terminal';
24
24
  import { N as NextSteps } from './NextSteps-DbJHmscQ.js';
25
25
  import 'qrcode';
26
+ import 'godot-export-presets';
26
27
 
27
28
  function isPlatformConfigured(platform, progress) {
28
29
  if (!progress) return false;
@@ -11,7 +11,7 @@ import 'readline-sync';
11
11
  import 'luxon';
12
12
  import 'axios';
13
13
  import 'isomorphic-git';
14
- import { H as queryClient, P as Platform, C as CredentialsType } from './baseCommand-CTn3KGH3.js';
14
+ import { I as queryClient, P as Platform, C as CredentialsType } from './baseCommand-CscxrTMI.js';
15
15
  import '@oclif/core';
16
16
  import { useMutation } from '@tanstack/react-query';
17
17
  import 'crypto-js';
@@ -24,11 +24,12 @@ import 'string-length';
24
24
  import 'strip-ansi';
25
25
  import 'open';
26
26
  import '@inkjs/ui';
27
- import { k as cacheKeys, G as GameContext } from './baseGameCommand-8VL7xe-O.js';
27
+ import { k as cacheKeys, i as GameContext } from './baseGameCommand-BKvHM3h_.js';
28
28
  import 'marked';
29
29
  import 'marked-terminal';
30
30
  import 'qrcode';
31
- import { i as importCredential } from './import-Dk2ywOVU.js';
31
+ import 'godot-export-presets';
32
+ import { i as importCredential } from './import-Bk4w8kks.js';
32
33
 
33
34
  async function importKeystore({ log = () => {
34
35
  }, ...opt }) {
@@ -7,12 +7,8 @@ import { useState, useRef, useEffect } from 'react';
7
7
  import 'node:fs';
8
8
  import 'crypto-js';
9
9
  import 'uuid';
10
- import { p as getAuthedHeaders, o as API_URL, F as castArrayObjectDates, J as JobStatus, a6 as castJobDates, a4 as castObjectDates, a7 as getShortTime } from './baseCommand-CTn3KGH3.js';
11
- import { k as cacheKeys, x as useJob, h as getStageColor, y as getMessageColor } from './baseGameCommand-8VL7xe-O.js';
10
+ import { q as getAuthedHeaders, p as API_URL, H as castArrayObjectDates, J as JobStatus, a8 as castJobDates, a6 as castObjectDates, a9 as getShortTime } from './baseCommand-CscxrTMI.js';
12
11
  import 'luxon';
13
- import 'fast-glob';
14
- import 'yazl';
15
- import 'socket.io-client';
16
12
  import 'node:crypto';
17
13
  import 'node:path';
18
14
  import 'node:readline';
@@ -20,8 +16,12 @@ import 'node:url';
20
16
  import 'readline-sync';
21
17
  import 'isomorphic-git';
22
18
  import '@oclif/core';
19
+ import 'fast-glob';
20
+ import 'yazl';
21
+ import 'socket.io-client';
22
+ import { k as cacheKeys, y as useJob, h as getStageColor, u as getMessageColor } from './baseGameCommand-BKvHM3h_.js';
23
23
  import 'fullscreen-ink';
24
- import { u as useWebSocket } from './useWebSocket-MXDbQHcu.js';
24
+ import { u as useWebSocket } from './useWebSocket-PU55rRGt.js';
25
25
  import { T as Title } from './Title-BCQtayg6.js';
26
26
  import stringLength from 'string-length';
27
27
  import stripAnsi from 'strip-ansi';
@@ -134,7 +134,18 @@ function useJobWatching({
134
134
  }
135
135
 
136
136
  function getSortedJobLogs(logs) {
137
- return logs.sort((a, b) => a.sentAt.toMillis() - b.sentAt.toMillis());
137
+ return [...logs].sort((a, b) => {
138
+ if (a.sequence != null && b.sequence != null) {
139
+ return a.sequence - b.sequence;
140
+ }
141
+ if (a.sequence != null && b.sequence == null) {
142
+ return -1;
143
+ }
144
+ if (a.sequence == null && b.sequence != null) {
145
+ return 1;
146
+ }
147
+ return a.sentAt.toMillis() - b.sentAt.toMillis();
148
+ });
138
149
  }
139
150
  function useJobLogTail({ isWatching, jobId, length, projectId }) {
140
151
  const [websocketLogs, setWebsocketLogs] = useState([]);
@@ -183,21 +194,23 @@ const TruncatedText = ({ children, wrap, ...textPropsWithoutWrap }) => {
183
194
  return /* @__PURE__ */ jsx(Box, { ref, children: /* @__PURE__ */ jsx(Text, { ...textPropsWithoutWrap, children: getTruncated(children) + "\x1B[0m" }) });
184
195
  };
185
196
 
197
+ const JobLogLine = ({ log, showTimestamp = true, showStage = true }) => {
198
+ const stageColor = getStageColor(log.stage);
199
+ const messageColor = getMessageColor(log.level);
200
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", height: 1, overflow: "hidden", gap: 1, children: [
201
+ showTimestamp && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: getShortTime(log.sentAt) }) }),
202
+ showStage && /* @__PURE__ */ jsx(Box, { justifyContent: "flex-start", width: 9, children: /* @__PURE__ */ jsx(Text, { color: stageColor, children: log.stage }) }),
203
+ /* @__PURE__ */ jsx(Box, { height: 1, marginRight: 2, overflow: "hidden", children: /* @__PURE__ */ jsx(TruncatedText, { color: messageColor, children: log.message }) })
204
+ ] }, log.id);
205
+ };
206
+
186
207
  const JobLogTail = (props) => {
187
208
  const { data, isLoading } = useJobLogTail(props);
188
209
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
189
210
  /* @__PURE__ */ jsx(Title, { children: "Job Logs" }),
190
211
  isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
191
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: data.map((log) => {
192
- const stageColor = getStageColor(log.stage);
193
- const messageColor = getMessageColor(log.level);
194
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", height: 1, overflow: "hidden", children: [
195
- /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: getShortTime(log.sentAt) }) }),
196
- /* @__PURE__ */ jsx(Box, { justifyContent: "flex-start", marginLeft: 1, width: 9, children: /* @__PURE__ */ jsx(Text, { color: stageColor, children: log.stage }) }),
197
- /* @__PURE__ */ jsx(Box, { height: 1, marginLeft: 1, marginRight: 2, overflow: "hidden", children: /* @__PURE__ */ jsx(TruncatedText, { color: messageColor, children: log.message }) })
198
- ] }, log.id);
199
- }) })
212
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: data.map((log) => /* @__PURE__ */ jsx(JobLogLine, { log }, log.id)) })
200
213
  ] });
201
214
  };
202
215
 
203
- export { JobLogTail as J, useJobWatching as u };
216
+ export { JobLogTail as J, JobLogLine as a, useJobWatching as u };
@@ -4,20 +4,18 @@ import axios from 'axios';
4
4
  import fg from 'fast-glob';
5
5
  import { v4 } from 'uuid';
6
6
  import { ZipFile } from 'yazl';
7
- import { H as queryClient, k as getProject, v as DEFAULT_SHIPPED_FILES_GLOBS, w as DEFAULT_IGNORED_FILES_GLOBS, a0 as getNewUploadTicket, a1 as startJobsFromUpload } from './baseCommand-CTn3KGH3.js';
8
- import { k as cacheKeys, s as getFileHash, t as getPlatformName } from './baseGameCommand-8VL7xe-O.js';
7
+ import { I as queryClient, l as getProject, x as DEFAULT_SHIPPED_FILES_GLOBS, y as DEFAULT_IGNORED_FILES_GLOBS, a2 as getNewUploadTicket, a3 as startJobsFromUpload, a4 as LogLevel } from './baseCommand-CscxrTMI.js';
8
+ import { k as cacheKeys, s as getFileHash, t as getPlatformName, u as getMessageColor } from './baseGameCommand-BKvHM3h_.js';
9
9
  import { g as getCWDGitInfo } from './git-BpsfNFZ_.js';
10
- import { jsx, Fragment } from 'react/jsx-runtime';
11
- import 'ink';
10
+ import { jsxs, jsx } from 'react/jsx-runtime';
11
+ import { Box, Text } from 'ink';
12
12
  import 'ink-spinner';
13
- import 'react';
13
+ import { useState } from 'react';
14
14
  import 'crypto-js';
15
15
  import 'luxon';
16
16
  import 'socket.io-client';
17
- import { u as useJobWatching } from './JobLogTail-Da8GuReK.js';
17
+ import { u as useJobWatching, a as JobLogLine } from './JobLogTail-BzisGkY8.js';
18
18
  import 'fullscreen-ink';
19
- import 'string-length';
20
- import 'strip-ansi';
21
19
  import 'open';
22
20
  import '@inkjs/ui';
23
21
  import 'node:path';
@@ -25,6 +23,9 @@ import 'marked';
25
23
  import 'marked-terminal';
26
24
  import { P as ProgressSpinner } from './ProgressSpinner-Um6ARKlk.js';
27
25
  import 'qrcode';
26
+ import 'string-length';
27
+ import 'strip-ansi';
28
+ import 'godot-export-presets';
28
29
 
29
30
  async function ship({ command, log = () => {
30
31
  }, shipFlags }) {
@@ -113,15 +114,25 @@ const useShip = () => useMutation({
113
114
  });
114
115
 
115
116
  const JobProgress = (props) => {
117
+ const [lastWarningLog, setLastWarningLog] = useState(null);
116
118
  const { progress } = useJobWatching({
117
119
  isWatching: true,
118
120
  jobId: props.job.id,
119
121
  onComplete: props.onComplete,
120
122
  onFailure: props.onFailure,
121
- projectId: props.job.project.id
123
+ projectId: props.job.project.id,
124
+ onNewLogEntry: (logEntry) => {
125
+ if (logEntry.level == LogLevel.WARN) setLastWarningLog(logEntry);
126
+ }
122
127
  });
123
128
  const label = `${getPlatformName(props.job.type)} build progress...`;
124
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(ProgressSpinner, { label, progress, spinnerType: "dots" }) });
129
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
130
+ /* @__PURE__ */ jsx(ProgressSpinner, { label, progress, spinnerType: "dots" }),
131
+ lastWarningLog && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginLeft: 2, children: [
132
+ /* @__PURE__ */ jsx(Text, { color: getMessageColor(lastWarningLog.level), children: "WARNING" }),
133
+ /* @__PURE__ */ jsx(JobLogLine, { log: lastWarningLog, showTimestamp: false, showStage: false })
134
+ ] })
135
+ ] });
125
136
  };
126
137
 
127
138
  export { JobProgress as J, useShip as u };
@@ -3,17 +3,17 @@ import { Box, Text } from 'ink';
3
3
  import Spinner from 'ink-spinner';
4
4
  import { DateTime } from 'luxon';
5
5
  import { useState, useEffect } from 'react';
6
- import { J as JobStatus } from './baseCommand-CTn3KGH3.js';
6
+ import { J as JobStatus } from './baseCommand-CscxrTMI.js';
7
7
  import '@tanstack/react-query';
8
8
  import 'axios';
9
9
  import 'node:fs';
10
10
  import 'crypto-js';
11
11
  import 'uuid';
12
- import { e as getJobSummary, h as getStageColor, f as getJobStatusColor } from './baseGameCommand-8VL7xe-O.js';
12
+ import { e as getJobSummary, h as getStageColor, f as getJobStatusColor } from './baseGameCommand-BKvHM3h_.js';
13
13
  import 'fast-glob';
14
14
  import 'yazl';
15
15
  import 'socket.io-client';
16
- import { u as useJobWatching } from './JobLogTail-Da8GuReK.js';
16
+ import { u as useJobWatching } from './JobLogTail-BzisGkY8.js';
17
17
  import 'fullscreen-ink';
18
18
  import { a as StatusRow, b as StatusRowLabel } from './StatusTable-DzRWcMr4.js';
19
19
  import { T as Title } from './Title-BCQtayg6.js';
@@ -10,13 +10,13 @@ import 'readline-sync';
10
10
  import 'luxon';
11
11
  import 'axios';
12
12
  import 'isomorphic-git';
13
- import './baseCommand-CTn3KGH3.js';
13
+ import './baseCommand-CscxrTMI.js';
14
14
  import '@oclif/core';
15
15
  import '@tanstack/react-query';
16
16
  import 'react';
17
17
  import 'crypto-js';
18
18
  import 'uuid';
19
- import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-TvlolkId.js';
19
+ import { u as useProjectCredentials, g as getProjectCredentialSummary } from './useProjectCredentials-rQLm2O1J.js';
20
20
  import 'fast-glob';
21
21
  import 'yazl';
22
22
  import 'socket.io-client';
@@ -10,7 +10,7 @@ import 'readline-sync';
10
10
  import 'luxon';
11
11
  import axios from 'axios';
12
12
  import 'isomorphic-git';
13
- import { c as getShortDate, p as getAuthedHeaders, o as API_URL, F as castArrayObjectDates } from './baseCommand-CTn3KGH3.js';
13
+ import { c as getShortDate, q as getAuthedHeaders, p as API_URL, H as castArrayObjectDates } from './baseCommand-CscxrTMI.js';
14
14
  import '@oclif/core';
15
15
  import { useQuery } from '@tanstack/react-query';
16
16
  import 'react';
@@ -18,7 +18,7 @@ import 'crypto-js';
18
18
  import 'uuid';
19
19
  import 'fast-glob';
20
20
  import 'yazl';
21
- import { k as cacheKeys, g as getShortUUID } from './baseGameCommand-8VL7xe-O.js';
21
+ import { k as cacheKeys, g as getShortUUID } from './baseGameCommand-BKvHM3h_.js';
22
22
  import 'socket.io-client';
23
23
  import 'fullscreen-ink';
24
24
  import { T as Table } from './Table-FaNgpyeq.js';
@@ -1,4 +1,4 @@
1
- import { B as BaseAuthenticatedCommand } from './baseGameCommand-8VL7xe-O.js';
1
+ import { B as BaseAuthenticatedCommand } from './baseGameCommand-BKvHM3h_.js';
2
2
 
3
3
  class BaseAppleCommand extends BaseAuthenticatedCommand {
4
4
  async init() {
@@ -13,8 +13,7 @@ import 'node:readline';
13
13
  import 'node:url';
14
14
  import 'readline-sync';
15
15
  import 'isomorphic-git';
16
- import merge from 'deepmerge';
17
- import { parse } from 'ini';
16
+ import { getMajorVersion, loadExportPresets, findPreset, getBasePreset, saveExportPresets, mergePresets, ConfigFile } from 'godot-export-presets';
18
17
  import { QueryClient } from '@tanstack/react-query';
19
18
  import 'react';
20
19
  import 'fast-glob';
@@ -444,8 +443,8 @@ const GODOT_CAPABILITIES = [
444
443
  { key: "capabilities/access_wifi", name: "Access WiFi", type: CapabilityType.ACCESS_WIFI },
445
444
  { key: "capabilities/push_notifications", name: "Push Notifications", type: CapabilityType.PUSH_NOTIFICATIONS }
446
445
  ];
447
- function getGodotProjectCapabilities(platform) {
448
- const exportPresets = getGodotExportPresets(platform);
446
+ async function getGodotProjectCapabilities(platform) {
447
+ const exportPresets = await getGodotExportPresets(platform);
449
448
  const options = exportPresets.options || {};
450
449
  const capabilities = [];
451
450
  for (const capability of GODOT_CAPABILITIES) {
@@ -458,29 +457,34 @@ function getGodotProjectConfig() {
458
457
  const cwd = process.cwd();
459
458
  const projectGodotPath = path__default.join(cwd, "project.godot");
460
459
  const projectGodotContent = fs__default.readFileSync(projectGodotPath, "utf8");
461
- return parse(projectGodotContent);
460
+ const configFile = new ConfigFile();
461
+ const error = configFile.parse(projectGodotContent);
462
+ if (error) {
463
+ throw error;
464
+ }
465
+ return configFile;
462
466
  }
463
467
  function getGodotProjectName() {
464
468
  try {
465
469
  const projectGodotConfig = getGodotProjectConfig();
466
- return projectGodotConfig.application["config/name"];
470
+ return projectGodotConfig.get_value("application", "config/name") || null;
467
471
  } catch {
468
472
  return null;
469
473
  }
470
474
  }
471
- function getGodotAppleBundleIdentifier() {
475
+ async function getGodotAppleBundleIdentifier() {
472
476
  try {
473
- const preset = getGodotExportPresets(Platform.IOS);
474
- return preset.options["application/bundle_identifier"];
477
+ const preset = await getGodotExportPresets(Platform.IOS);
478
+ return preset.options?.["application/bundle_identifier"] || null;
475
479
  } catch (error) {
476
480
  console.log(error);
477
481
  return null;
478
482
  }
479
483
  }
480
- function getGodotAndroidPackageName() {
484
+ async function getGodotAndroidPackageName() {
481
485
  try {
482
- const preset = getGodotExportPresets(Platform.ANDROID);
483
- return preset.options["package/unique_name"];
486
+ const preset = await getGodotExportPresets(Platform.ANDROID);
487
+ return preset.options?.["package/unique_name"] || null;
484
488
  } catch (error) {
485
489
  console.log(error);
486
490
  return null;
@@ -488,115 +492,81 @@ function getGodotAndroidPackageName() {
488
492
  }
489
493
  function getGodotVersion() {
490
494
  const projectGodotConfig = getGodotProjectConfig();
491
- if ("config/features" in projectGodotConfig.application) {
492
- const features = projectGodotConfig.application["config/features"];
493
- const match = features.match(/"(\d+\.\d+)"/);
494
- if (!match) throw new Error("Couldn't find Godot version in project.godot");
495
- return match[1];
495
+ const features = projectGodotConfig.get_value("application", "config/features");
496
+ if (!features || features.length === 0) {
497
+ return "3.6";
496
498
  }
497
- return "3.6";
499
+ const [version] = features;
500
+ return version;
498
501
  }
499
- function getGodotExportPresets(platform) {
500
- const { warn } = console;
501
- let presetConfig = platform === Platform.IOS ? getBaseExportPresets_iOS() : getBaseExportPresets_Android();
502
+ function getExportPresetsPath() {
502
503
  const cwd = process.cwd();
503
504
  const filename = "export_presets.cfg";
504
505
  const exportPresetsPath = path__default.join(cwd, filename);
506
+ return exportPresetsPath;
507
+ }
508
+ async function getGodotExportPresets(platform) {
509
+ const { warn } = console;
510
+ const godotVersion = getGodotVersion();
511
+ const majorVersion = getMajorVersion(godotVersion);
512
+ const godotPlatform = platform === Platform.IOS ? "iOS" : "Android";
513
+ let presetConfig = getBasePreset(godotPlatform, majorVersion);
514
+ const exportPresetsPath = getExportPresetsPath();
505
515
  const isFound = fs__default.existsSync(exportPresetsPath);
506
516
  if (isFound) {
507
- const exportPresetsContent = fs__default.readFileSync(exportPresetsPath, "utf8");
508
- const exportPresetsIni = parse(exportPresetsContent);
509
- const presetIndexes = Object.keys(exportPresetsIni.preset || {});
510
- const presetIndex = presetIndexes.find((index) => {
511
- const current = exportPresetsIni.preset[index];
512
- return `${current.name}`.toUpperCase() === platform;
513
- });
514
- if (presetIndex) {
515
- presetConfig = merge(presetConfig, exportPresetsIni.preset[presetIndex]);
516
- } else {
517
- warn(`Preset ${platform} not found in ${filename} - will use defaults`);
517
+ try {
518
+ const exportPresets = await loadExportPresets(exportPresetsPath);
519
+ const foundPreset = findPreset(exportPresets, { platform: godotPlatform });
520
+ if (foundPreset) {
521
+ presetConfig = mergePresets(presetConfig, foundPreset);
522
+ } else {
523
+ warn(`Preset ${platform} not found in ${exportPresetsPath} - will use defaults`);
524
+ }
525
+ } catch (error) {
526
+ warn(`Error loading ${exportPresetsPath}: ${error} - will use defaults`);
518
527
  }
519
528
  } else {
520
- warn(`${filename} not found at ${exportPresetsPath}`);
529
+ warn(`Export presets not found at ${exportPresetsPath} - will use defaults`);
521
530
  }
522
531
  return presetConfig;
523
532
  }
524
- function getBaseExportPresets_iOS() {
525
- return {
526
- custom_features: "",
527
- dedicated_server: false,
528
- encrypt_directory: false,
529
- encrypt_pck: false,
530
- encryption_exclude_filters: "",
531
- encryption_include_filters: "",
532
- exclude_filter: "",
533
- export_filter: "all_resources",
534
- export_path: "output",
535
- include_filter: "",
536
- name: "iOS",
537
- options: {
538
- "application/export_project_only": true,
539
- "application/icon_interpolation": "4",
540
- "application/launch_screens_interpolation": "4",
541
- "application/short_version": "1.0.0",
542
- // default version number
543
- "application/signature": "",
544
- "architectures/arm64": true,
545
- "capabilities/access_wifi": false,
546
- "capabilities/push_notifications": false,
547
- "custom_template/debug": "",
548
- "custom_template/release": "",
549
- "icons/app_store_1024x1024": "",
550
- "icons/ipad_76x76": "",
551
- "icons/ipad_152x152": "",
552
- "icons/ipad_167x167": "",
553
- "icons/iphone_120x120": "",
554
- "icons/iphone_180x180": "",
555
- "icons/notification_40x40": "",
556
- "icons/notification_60x60": "",
557
- "icons/settings_58x58": "",
558
- "icons/settings_87x87": "",
559
- "icons/spotlight_40x40": "",
560
- "icons/spotlight_80x80": "",
561
- "landscape_launch_screens/ipad_1024x768": "",
562
- "landscape_launch_screens/ipad_2048x1536": "",
563
- "landscape_launch_screens/iphone_2208x1242": "",
564
- "landscape_launch_screens/iphone_2436x1125": "",
565
- "portrait_launch_screens/ipad_768x1024": "",
566
- "portrait_launch_screens/ipad_1536x2048": "",
567
- "portrait_launch_screens/iphone_640x960": "",
568
- "portrait_launch_screens/iphone_640x1136": "",
569
- "portrait_launch_screens/iphone_750x1334": "",
570
- "portrait_launch_screens/iphone_1125x2436": "",
571
- "portrait_launch_screens/iphone_1242x2208": "",
572
- "privacy/camera_usage_description": "",
573
- "privacy/camera_usage_description_localized": "{}",
574
- "privacy/microphone_usage_description": "",
575
- "privacy/microphone_usage_description_localized": "{}",
576
- "privacy/photolibrary_usage_description": "",
577
- "privacy/photolibrary_usage_description_localized": "{}",
578
- "storyboard/custom_bg_color": "Color(0, 0, 0, 1)",
579
- "storyboard/custom_image@2x": "",
580
- "storyboard/custom_image@3x": "",
581
- "storyboard/image_scale_mode": "0",
582
- "storyboard/use_custom_bg_color": false,
583
- "storyboard/use_launch_screen_storyboard": true,
584
- "user_data/accessible_from_files_app": false,
585
- "user_data/accessible_from_itunes_sharing": false
586
- },
587
- platform: "iOS",
588
- runnable: true
589
- };
590
- }
591
- function getBaseExportPresets_Android() {
592
- return {
593
- name: "Android",
594
- // TODO
595
- options: {
596
- // TODO
597
- },
598
- platform: "Android"
599
- };
533
+ function getGradleBuildOptionKey(majorVersion) {
534
+ return majorVersion === 4 ? "gradle_build/use_gradle_build" : "custom_build/use_custom_build";
535
+ }
536
+ function getExportFormatOptionKey(majorVersion) {
537
+ return majorVersion === 4 ? "gradle_build/export_format" : "custom_build/export_format";
538
+ }
539
+ async function isGradleBuildEnabled() {
540
+ const godotVersion = getGodotVersion();
541
+ const majorVersion = getMajorVersion(godotVersion);
542
+ const preset = await getGodotExportPresets(Platform.ANDROID);
543
+ const buildOptionKey = getGradleBuildOptionKey(majorVersion);
544
+ const isEnabled = preset.options?.[buildOptionKey];
545
+ return isEnabled === true || isEnabled === "true";
546
+ }
547
+ async function setGradleBuildEnabled(value) {
548
+ const exportPresetsPath = getExportPresetsPath();
549
+ let exportPresets = { presets: [] };
550
+ if (fs__default.existsSync(exportPresetsPath)) {
551
+ exportPresets = await loadExportPresets(exportPresetsPath);
552
+ } else {
553
+ console.warn(`Export presets not found at ${exportPresetsPath} - creating new file`);
554
+ }
555
+ const godotVersion = getGodotVersion();
556
+ const majorVersion = getMajorVersion(godotVersion);
557
+ let androidPreset = findPreset(exportPresets, { platform: "Android" });
558
+ if (!androidPreset) {
559
+ androidPreset = getBasePreset("Android", majorVersion);
560
+ exportPresets.presets.push(androidPreset);
561
+ }
562
+ const buildOptionKey = getGradleBuildOptionKey(majorVersion);
563
+ androidPreset.options = androidPreset.options || {};
564
+ androidPreset.options[buildOptionKey] = value;
565
+ const exportFormatOptionKey = getExportFormatOptionKey(majorVersion);
566
+ if (value === false) {
567
+ androidPreset.options[exportFormatOptionKey] = 0;
568
+ }
569
+ await saveExportPresets(exportPresetsPath, exportPresets);
600
570
  }
601
571
 
602
572
  const queryClient = new QueryClient({
@@ -784,4 +754,4 @@ class BaseCommand extends Command {
784
754
  }
785
755
  }
786
756
 
787
- export { Auth as $, ApiKey as A, BaseCommand as B, CredentialsType as C, DetailsFlags as D, getProjectPlatformProgress as E, castArrayObjectDates as F, GODOT_CAPABILITIES as G, queryClient as H, WS_URL as I, JobStatus as J, getAuthToken as K, downloadBuildById as L, getGoogleStatus as M, getGodotAndroidPackageName as N, enforcePolicy as O, Platform as P, revokePolicy as Q, inviteServiceAccount as R, disconnectGoogle as S, getAPIKeys as T, UserRole as U, createAPIKey as V, WEB_URL as W, revokeAPIKey as X, getSingleUseUrl as Y, acceptTerms as Z, setAuthToken as _, ApiKeyType as a, getNewUploadTicket as a0, startJobsFromUpload as a1, LogLevel as a2, getShortAuthRequiredUrl as a3, castObjectDates as a4, getGoogleAuthUrl as a5, castJobDates as a6, getShortTime as a7, updateProject as a8, getShortDateTime as a9, getShortTimeDelta as aa, JobStage as ab, BuildType as ac, getSelf as ad, getTerms as ae, Certificate as b, getShortDate as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, BetaGroup as i, isCWDGodotGame as j, getProject 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 };
757
+ export { acceptTerms as $, ApiKey as A, BaseCommand as B, CredentialsType as C, DetailsFlags as D, getProjectJobs as E, getJob as F, GODOT_CAPABILITIES as G, castArrayObjectDates as H, queryClient as I, JobStatus as J, WS_URL as K, getAuthToken as L, getProjectPlatformProgress as M, downloadBuildById as N, getGoogleStatus as O, Platform as P, getGodotAndroidPackageName as Q, enforcePolicy as R, revokePolicy as S, inviteServiceAccount as T, UserRole as U, disconnectGoogle as V, WEB_URL as W, getAPIKeys as X, createAPIKey as Y, revokeAPIKey as Z, getSingleUseUrl as _, ApiKeyType as a, setAuthToken as a0, Auth as a1, getNewUploadTicket as a2, startJobsFromUpload as a3, LogLevel as a4, getShortAuthRequiredUrl as a5, castObjectDates as a6, getGoogleAuthUrl as a7, castJobDates as a8, getShortTime as a9, updateProject as aa, BuildType as ab, getGradleBuildOptionKey as ac, getShortDateTime as ad, getShortTimeDelta as ae, JobStage as af, getSelf as ag, getTerms as ah, 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_SHIPPED_FILES_GLOBS as x, DEFAULT_IGNORED_FILES_GLOBS as y, getGodotProjectName as z };