shipthis 0.1.25 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/AppleBundleIdDetails-mPUG2R4N.js +76 -0
  2. package/dist/Command-B3AmRt2w.js +28 -0
  3. package/dist/CommandGame-BCMzP9pc.js +9 -0
  4. package/dist/Create-CsJxpzUs.js +59 -0
  5. package/dist/Import-v0M_ygyF.js +110 -0
  6. package/dist/JobProgress-9uvq8IBn.js +121 -0
  7. package/dist/JobStatusTable-Bf7J9WXe.js +191 -0
  8. package/dist/NextSteps-CK9zHOCt.js +18 -0
  9. package/dist/ProgressSpinner-6pw1T8Iw.js +16 -0
  10. package/dist/ProjectCredentialsTable-CTkP1mvy.js +37 -0
  11. package/dist/RunWithSpinner-BVXNWGD3.js +27 -0
  12. package/dist/StatusTable-Dm5St4g-.js +33 -0
  13. package/dist/Table-CvM6pccN.js +101 -0
  14. package/dist/Title-BCQtayg6.js +6 -0
  15. package/dist/UserCredentialsTable-DhtM_iTG.js +82 -0
  16. package/dist/baseAppleCommand-IGl6KTvv.js +10 -0
  17. package/dist/baseGameAndroidCommand-DFn4zMvq.js +43 -0
  18. package/dist/commands/apple/apiKey/create.js +103 -0
  19. package/dist/commands/apple/apiKey/export.js +81 -0
  20. package/dist/commands/apple/apiKey/import.js +85 -0
  21. package/dist/commands/apple/apiKey/status.js +122 -0
  22. package/dist/commands/apple/certificate/create.js +133 -0
  23. package/dist/commands/apple/certificate/export.js +81 -0
  24. package/dist/commands/apple/certificate/import.js +85 -0
  25. package/dist/commands/apple/certificate/status.js +130 -0
  26. package/dist/commands/apple/login.js +76 -0
  27. package/dist/commands/apple/status.js +79 -0
  28. package/dist/commands/dashboard.js +38 -0
  29. package/dist/commands/game/android/apiKey/connect.js +74 -0
  30. package/dist/commands/game/android/apiKey/create.js +74 -0
  31. package/dist/commands/game/android/apiKey/export.js +84 -0
  32. package/dist/commands/game/android/apiKey/import.js +93 -0
  33. package/dist/commands/game/android/apiKey/invite.js +81 -0
  34. package/dist/commands/game/android/apiKey/status.js +87 -0
  35. package/dist/commands/game/android/keyStore/create.js +69 -0
  36. package/dist/commands/game/android/keyStore/export.js +83 -0
  37. package/dist/commands/game/android/keyStore/import.js +112 -0
  38. package/dist/commands/game/android/keyStore/status.js +70 -0
  39. package/dist/commands/game/android/status.js +84 -0
  40. package/dist/commands/game/build/download.js +80 -0
  41. package/dist/commands/game/build/list.js +96 -0
  42. package/dist/commands/game/create.js +67 -0
  43. package/dist/commands/game/details.js +113 -0
  44. package/dist/commands/game/export.js +58 -0
  45. package/dist/commands/game/ios/app/addTester.js +124 -0
  46. package/dist/commands/game/ios/app/create.js +117 -0
  47. package/dist/commands/game/ios/app/status.js +66 -0
  48. package/dist/commands/game/ios/app/sync.js +95 -0
  49. package/dist/commands/game/ios/profile/create.js +129 -0
  50. package/dist/commands/game/ios/profile/export.js +83 -0
  51. package/dist/commands/game/ios/profile/import.js +92 -0
  52. package/dist/commands/game/ios/profile/status.js +139 -0
  53. package/dist/commands/game/ios/status.js +92 -0
  54. package/dist/commands/game/ios/wizard.js +153 -0
  55. package/dist/commands/game/job/list.js +95 -0
  56. package/dist/commands/game/job/status.js +91 -0
  57. package/dist/commands/game/list.js +83 -0
  58. package/dist/commands/game/ship.js +216 -0
  59. package/dist/commands/game/status.js +114 -0
  60. package/dist/commands/game/wizard.js +686 -0
  61. package/dist/commands/internal/fastlane.js +74 -0
  62. package/dist/commands/internal/readme.js +937 -0
  63. package/dist/commands/login.js +92 -0
  64. package/dist/commands/status.js +76 -0
  65. package/dist/export-CVs_xoDN.js +36 -0
  66. package/dist/git-DREGq-jc.js +32 -0
  67. package/dist/import-Ch5O7xfN.js +47 -0
  68. package/dist/index-BB00V5oF.js +136 -0
  69. package/dist/index-BD1WLuFJ.js +125 -0
  70. package/dist/index-CIa2EDQ6.js +24 -0
  71. package/dist/index-CboPN9aq.js +138 -0
  72. package/dist/index-DkNQs11R.js +711 -0
  73. package/dist/index-nnzhQ3nY.js +209 -0
  74. package/dist/index.d.ts +1 -0
  75. package/dist/index.js +1 -0
  76. package/dist/upload-CRE2nVdd.js +60 -0
  77. package/dist/useAndroidServiceAccountTestResult-DcYDam-p.js +52 -0
  78. package/dist/useAppleApp-B16WbUxJ.js +32 -0
  79. package/dist/useAppleBundleId-DobPATan.js +64 -0
  80. package/dist/useJobWatching--BvVn7xS.js +45 -0
  81. package/dist/useProjectCredentials-Btnr7WK3.js +54 -0
  82. package/dist/useWebSocket-ByuNoqRw.js +36 -0
  83. package/dist/utils/help.js +14 -0
  84. package/package.json +1 -1
@@ -0,0 +1,95 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { render, Box, Text } from 'ink';
3
+ import { Flags } from '@oclif/core';
4
+ import { c as BaseGameCommand, z as getProjectJobs } from '../../../index-DkNQs11R.js';
5
+ import 'react';
6
+ import { a as getJobSummary } from '../../../index-nnzhQ3nY.js';
7
+ import 'ink-spinner';
8
+ import '@inkjs/ui';
9
+ import 'axios';
10
+ import '@tanstack/react-query';
11
+ import 'fs';
12
+ import 'uuid';
13
+ import 'yazl';
14
+ import { c as getJobStatusColor } from '../../../index-BB00V5oF.js';
15
+ import 'open';
16
+ import { T as Title } from '../../../Title-BCQtayg6.js';
17
+ import 'marked';
18
+ import 'marked-terminal';
19
+ import 'path';
20
+ import 'qrcode';
21
+ import { T as Table } from '../../../Table-CvM6pccN.js';
22
+ import 'string-length';
23
+ import 'strip-ansi';
24
+ import { DateTime } from 'luxon';
25
+ import 'fast-glob';
26
+ import { C as Command } from '../../../Command-B3AmRt2w.js';
27
+ import 'socket.io-client';
28
+ import '@expo/apple-utils/build/index.js';
29
+ import 'crypto-js';
30
+ import 'crypto';
31
+ import 'readline-sync';
32
+ import 'node:readline';
33
+ import 'node:path';
34
+ import 'node:url';
35
+ import 'isomorphic-git';
36
+ import 'ini';
37
+ import 'deepmerge';
38
+ import '../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
39
+
40
+ class GameJobList extends BaseGameCommand {
41
+ static args = {};
42
+ static description = "Lists the jobs for a game.";
43
+ static examples = [
44
+ "<%= config.bin %> <%= command.id %>",
45
+ "<%= config.bin %> <%= command.id %> --gameId 0c179fc4"
46
+ ];
47
+ static flags = {
48
+ ...super.flags,
49
+ pageNumber: Flags.integer({ char: "p", description: "The page number to show (starts at 0)", default: 0 }),
50
+ pageSize: Flags.integer({ char: "s", description: "The number of items to show per page", default: 10 }),
51
+ orderBy: Flags.string({
52
+ char: "o",
53
+ description: "The field to order by",
54
+ default: "createdAt",
55
+ options: ["createdAt", "updatedAt"]
56
+ }),
57
+ order: Flags.string({
58
+ char: "r",
59
+ description: "The order to sort by",
60
+ default: "desc",
61
+ options: ["asc", "desc"]
62
+ })
63
+ };
64
+ async run() {
65
+ const game = await this.getGame();
66
+ const { flags } = this;
67
+ const { gameId, ...otherFlags } = flags;
68
+ const params = otherFlags;
69
+ const jobListResponse = await getProjectJobs(game.id, params);
70
+ const data = jobListResponse.data.map((j) => getJobSummary(j, DateTime.now()));
71
+ const hasJobs = data.length > 0;
72
+ render(
73
+ /* @__PURE__ */ jsxs(Command, { command: this, children: [
74
+ /* @__PURE__ */ jsx(Title, { children: "Jobs for this game" }),
75
+ !hasJobs && /* @__PURE__ */ jsx(Box, { marginLeft: 2, marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { children: "You DO NOT have any jobs for this game." }) }),
76
+ hasJobs && /* @__PURE__ */ jsx(
77
+ Table,
78
+ {
79
+ data,
80
+ getTextProps: (col, val) => {
81
+ if (col.key !== "status") return {};
82
+ return { color: getJobStatusColor(val) };
83
+ }
84
+ }
85
+ ),
86
+ jobListResponse.pageCount > 1 && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
87
+ /* @__PURE__ */ jsx(Text, { children: `Showing page ${flags.pageNumber + 1} of ${jobListResponse.pageCount}.` }),
88
+ /* @__PURE__ */ jsx(Text, { children: "Use the --pageNumber parameter to see other pages." })
89
+ ] })
90
+ ] })
91
+ );
92
+ }
93
+ }
94
+
95
+ export { GameJobList as default };
@@ -0,0 +1,91 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Args, Flags } from '@oclif/core';
3
+ import { render } from 'ink';
4
+ import { c as BaseGameCommand, E as getJob, J as JobStatus } from '../../../index-DkNQs11R.js';
5
+ import 'react';
6
+ import '../../../index-nnzhQ3nY.js';
7
+ import 'ink-spinner';
8
+ import '@inkjs/ui';
9
+ import 'axios';
10
+ import '@tanstack/react-query';
11
+ import 'fs';
12
+ import 'uuid';
13
+ import 'yazl';
14
+ import 'crypto';
15
+ import 'readline-sync';
16
+ import 'node:readline';
17
+ import 'node:path';
18
+ import 'node:url';
19
+ import 'luxon';
20
+ import 'isomorphic-git';
21
+ import 'fast-glob';
22
+ import 'socket.io-client';
23
+ import 'open';
24
+ import 'marked';
25
+ import 'marked-terminal';
26
+ import 'path';
27
+ import { N as NextSteps } from '../../../NextSteps-CK9zHOCt.js';
28
+ import 'qrcode';
29
+ import 'string-length';
30
+ import 'strip-ansi';
31
+ import { C as Command } from '../../../Command-B3AmRt2w.js';
32
+ import { J as JobStatusTable, a as JobLogTail } from '../../../JobStatusTable-Bf7J9WXe.js';
33
+ import '@expo/apple-utils/build/index.js';
34
+ import 'crypto-js';
35
+ import 'ini';
36
+ import 'deepmerge';
37
+ import '../../../index-BB00V5oF.js';
38
+ import '../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
39
+ import '../../../Title-BCQtayg6.js';
40
+ import '../../../useWebSocket-ByuNoqRw.js';
41
+ import '../../../useJobWatching--BvVn7xS.js';
42
+ import '../../../StatusTable-Dm5St4g-.js';
43
+
44
+ class GameJobStatus extends BaseGameCommand {
45
+ static args = {
46
+ job_id: Args.string({ description: "The id of the job to get the status of", required: true })
47
+ };
48
+ static description = "Shows the real-time status of a job.";
49
+ static examples = [
50
+ "<%= config.bin %> <%= command.id %> 4d32239e",
51
+ "<%= config.bin %> <%= command.id %> --gameId 0c179fc4 4d32239e",
52
+ "<%= config.bin %> <%= command.id %> --gameId 0c179fc4 --lines 20 --follow 4d32239e"
53
+ ];
54
+ static flags = {
55
+ ...super.flags,
56
+ lines: Flags.integer({ char: "n", description: "The number of lines to show", default: 10 }),
57
+ follow: Flags.boolean({ char: "f", description: "Follow the log in real-time", default: false })
58
+ };
59
+ async getJob() {
60
+ try {
61
+ const game = await this.getGame();
62
+ const job = await getJob(this.args.job_id, game.id);
63
+ return job;
64
+ } catch (e) {
65
+ if (e?.response?.status === 404) {
66
+ this.error("Job not found - please check you have access", { exit: 1 });
67
+ }
68
+ throw e;
69
+ }
70
+ }
71
+ async run() {
72
+ const job = await this.getJob();
73
+ const { lines, follow } = this.flags;
74
+ const handleJobUpdate = (job2) => {
75
+ if (!follow) return;
76
+ if ([JobStatus.COMPLETED, JobStatus.FAILED].includes(job2.status)) {
77
+ const exitCode = job2.status == JobStatus.FAILED ? 1 : 0;
78
+ setTimeout(() => process.exit(exitCode), 5e3);
79
+ }
80
+ };
81
+ render(
82
+ /* @__PURE__ */ jsxs(Command, { command: this, children: [
83
+ /* @__PURE__ */ jsx(JobStatusTable, { jobId: job.id, projectId: job.project.id, isWatching: follow, onJobUpdate: handleJobUpdate }),
84
+ /* @__PURE__ */ jsx(JobLogTail, { jobId: job.id, projectId: job.project.id, isWatching: follow, length: lines }),
85
+ /* @__PURE__ */ jsx(NextSteps, { steps: [] })
86
+ ] })
87
+ );
88
+ }
89
+ }
90
+
91
+ export { GameJobStatus as default };
@@ -0,0 +1,83 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { render, Text, Box } from 'ink';
3
+ import { Flags } from '@oclif/core';
4
+ import { B as BaseAuthenticatedCommand, g as getProjects, b as getShortDate } from '../../index-DkNQs11R.js';
5
+ import 'react';
6
+ import '../../index-nnzhQ3nY.js';
7
+ import 'ink-spinner';
8
+ import '@inkjs/ui';
9
+ import 'axios';
10
+ import '@tanstack/react-query';
11
+ import 'fs';
12
+ import 'uuid';
13
+ import 'yazl';
14
+ import { g as getShortUUID } from '../../index-BB00V5oF.js';
15
+ import 'open';
16
+ import 'marked';
17
+ import 'marked-terminal';
18
+ import 'path';
19
+ import 'qrcode';
20
+ import { T as Table } from '../../Table-CvM6pccN.js';
21
+ import 'string-length';
22
+ import 'strip-ansi';
23
+ import 'luxon';
24
+ import 'fast-glob';
25
+ import { C as Command } from '../../Command-B3AmRt2w.js';
26
+ import 'socket.io-client';
27
+ import '@expo/apple-utils/build/index.js';
28
+ import 'crypto-js';
29
+ import 'crypto';
30
+ import 'readline-sync';
31
+ import 'node:readline';
32
+ import 'node:path';
33
+ import 'node:url';
34
+ import 'isomorphic-git';
35
+ import 'ini';
36
+ import 'deepmerge';
37
+ import '../../useAndroidServiceAccountTestResult-DcYDam-p.js';
38
+
39
+ class GameList extends BaseAuthenticatedCommand {
40
+ static args = {};
41
+ static description = "Shows a list of all your games.";
42
+ static examples = ["<%= config.bin %> <%= command.id %>"];
43
+ static flags = {
44
+ pageNumber: Flags.integer({ char: "p", description: "The page number to show (starts at 0)", default: 0 }),
45
+ pageSize: Flags.integer({ char: "s", description: "The number of items to show per page", default: 10 }),
46
+ orderBy: Flags.string({
47
+ char: "o",
48
+ description: "The field to order by",
49
+ default: "createdAt",
50
+ options: ["createdAt", "updatedAt", "name"]
51
+ }),
52
+ order: Flags.string({
53
+ char: "r",
54
+ description: "The order to sort by",
55
+ default: "desc",
56
+ options: ["asc", "desc"]
57
+ })
58
+ };
59
+ async run() {
60
+ const { flags } = this;
61
+ const params = flags;
62
+ const gameListResponse = await getProjects(params);
63
+ const data = gameListResponse.data.map((game) => {
64
+ return {
65
+ id: getShortUUID(game.id),
66
+ name: game.name,
67
+ createdAt: getShortDate(game.createdAt)
68
+ };
69
+ });
70
+ render(
71
+ /* @__PURE__ */ jsxs(Command, { command: this, children: [
72
+ gameListResponse.data.length === 0 && params.pageNumber == 0 && /* @__PURE__ */ jsx(Text, { children: "No games found. Create one now with $ shipthis game wizard" }),
73
+ gameListResponse.data.length > 0 && /* @__PURE__ */ jsx(Table, { data }),
74
+ gameListResponse.pageCount > 1 && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
75
+ /* @__PURE__ */ jsx(Text, { children: `Showing page ${flags.pageNumber + 1} of ${gameListResponse.pageCount}.` }),
76
+ /* @__PURE__ */ jsx(Text, { children: "Use the --pageNumber parameter to see other pages." })
77
+ ] })
78
+ ] })
79
+ );
80
+ }
81
+ }
82
+
83
+ export { GameList as default };
@@ -0,0 +1,216 @@
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
+ import { Flags } from '@oclif/core';
3
+ import { useInput, Box, Text, render } from 'ink';
4
+ import { a3 as getShortAuthRequiredUrl, W as WEB_URL, c as BaseGameCommand, K as downloadBuildById } from '../../index-DkNQs11R.js';
5
+ import { useContext, useState, useEffect } from 'react';
6
+ import { e as CommandContext, b as GameContext, M as Markdown } from '../../index-nnzhQ3nY.js';
7
+ import 'ink-spinner';
8
+ import '@inkjs/ui';
9
+ import axios from 'axios';
10
+ import '@tanstack/react-query';
11
+ import 'fs';
12
+ import 'uuid';
13
+ import 'yazl';
14
+ import 'crypto';
15
+ import 'readline-sync';
16
+ import 'node:readline';
17
+ import 'node:path';
18
+ import 'node:url';
19
+ import 'luxon';
20
+ import 'isomorphic-git';
21
+ import 'fast-glob';
22
+ import 'socket.io-client';
23
+ import open from 'open';
24
+ import 'marked';
25
+ import 'marked-terminal';
26
+ import 'path';
27
+ import 'qrcode';
28
+ import 'string-length';
29
+ import 'strip-ansi';
30
+ import { C as CommandGame } from '../../CommandGame-BCMzP9pc.js';
31
+ import { g as getShortUUID } from '../../index-BB00V5oF.js';
32
+ import { u as useShip, J as JobProgress } from '../../JobProgress-9uvq8IBn.js';
33
+ import { J as JobStatusTable, a as JobLogTail } from '../../JobStatusTable-Bf7J9WXe.js';
34
+ import '@expo/apple-utils/build/index.js';
35
+ import 'crypto-js';
36
+ import 'ini';
37
+ import 'deepmerge';
38
+ import '../../useAndroidServiceAccountTestResult-DcYDam-p.js';
39
+ import '../../Command-B3AmRt2w.js';
40
+ import '../../git-DREGq-jc.js';
41
+ import '../../ProgressSpinner-6pw1T8Iw.js';
42
+ import '../../useJobWatching--BvVn7xS.js';
43
+ import '../../useWebSocket-ByuNoqRw.js';
44
+ import '../../Title-BCQtayg6.js';
45
+ import '../../StatusTable-Dm5St4g-.js';
46
+
47
+ function isNetworkError(exception) {
48
+ if (!axios.isAxiosError(exception)) return false;
49
+ return ["ECONNABORTED", "ERR_NETWORK"].includes(`${exception.code}`);
50
+ }
51
+ function getErrorMessage(error) {
52
+ try {
53
+ if (isNetworkError(error)) {
54
+ return "Please check your internet connection.";
55
+ }
56
+ const data = error?.response?.data;
57
+ const apiValidation = Array.isArray(data) ? data.map((r) => "message" in r ? `Error - ${r.message}` : r.toString()).join(" ") : "";
58
+ const apiErr = error?.response?.data?.error || "";
59
+ const apiMsg = `${apiErr}${apiValidation ? " " + apiValidation : ""}`;
60
+ if (apiMsg.length === 0) {
61
+ return "message" in error ? error.message : error.toString();
62
+ }
63
+ return apiMsg;
64
+ } catch {
65
+ return error ? error.toString() : "Error";
66
+ }
67
+ }
68
+
69
+ const Ship = ({ onComplete, onError }) => {
70
+ const { command } = useContext(CommandContext);
71
+ const { gameId } = useContext(GameContext);
72
+ const shipMutation = useShip();
73
+ const [jobs, setJobs] = useState(null);
74
+ const [failedJobs, setFailedJobs] = useState([]);
75
+ const [successJobs, setSuccessJobs] = useState([]);
76
+ const [shipLog, setShipLog] = useState("");
77
+ const [showLog, setShowLog] = useState(false);
78
+ const [isComplete, setIsComplete] = useState(false);
79
+ const handleStartOnMount = async () => {
80
+ if (!command) throw new Error("No command in context");
81
+ const startedJobs = await shipMutation.mutateAsync({ command, log: setShipLog });
82
+ setJobs(startedJobs);
83
+ };
84
+ useEffect(() => {
85
+ handleStartOnMount().catch(onError);
86
+ }, []);
87
+ useInput(async (input) => {
88
+ if (!gameId) return;
89
+ switch (input) {
90
+ case "l":
91
+ setShowLog((prev) => !prev);
92
+ break;
93
+ case "b":
94
+ const dashUrl = jobs?.length !== 1 ? `/games/${gameId}` : `/games/${gameId}/job/${jobs[0].id}`;
95
+ const url = await getShortAuthRequiredUrl(dashUrl);
96
+ await open(url);
97
+ break;
98
+ }
99
+ });
100
+ const handleJobComplete = (job) => {
101
+ setSuccessJobs([...successJobs, job]);
102
+ const newJobs = (jobs || []).filter((prevJob) => prevJob.id !== job.id);
103
+ setJobs(newJobs);
104
+ if (newJobs.length === 0) {
105
+ setIsComplete(true);
106
+ }
107
+ };
108
+ const handleJobFailure = (job) => {
109
+ setFailedJobs([...failedJobs, job]);
110
+ handleJobComplete(job);
111
+ };
112
+ useEffect(() => {
113
+ if (!isComplete) return;
114
+ setTimeout(() => {
115
+ failedJobs.length === 0 ? onComplete(successJobs) : onError("One or more jobs failed");
116
+ }, 500);
117
+ }, [isComplete]);
118
+ if (!gameId) return /* @__PURE__ */ jsx(Fragment, {});
119
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
120
+ jobs == null && /* @__PURE__ */ jsx(Text, { children: shipLog }),
121
+ jobs && jobs.map((job) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
122
+ /* @__PURE__ */ jsx(JobStatusTable, { jobId: job.id, projectId: job.project.id, isWatching: true }),
123
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(JobProgress, { job, onComplete: handleJobComplete, onFailure: handleJobFailure }) }),
124
+ showLog && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(JobLogTail, { jobId: job.id, projectId: job.project.id, isWatching: true, length: 10 }) })
125
+ ] }, job.id)),
126
+ jobs && !isComplete && /* @__PURE__ */ jsxs(Fragment, { children: [
127
+ /* @__PURE__ */ jsx(Text, { children: "Press L to show and hide the job logs." }),
128
+ /* @__PURE__ */ jsx(Text, { children: "Press B to open the ShipThis dashboard in your browser." }),
129
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Please wait while ShipThis builds your game..." })
130
+ ] }),
131
+ isComplete && /* @__PURE__ */ jsxs(Fragment, { children: [
132
+ failedJobs.length == 0 && /* @__PURE__ */ jsx(
133
+ Markdown,
134
+ {
135
+ filename: "ship-success.md",
136
+ templateVars: {
137
+ gameBuildsUrl: `${WEB_URL}games/${getShortUUID(gameId)}/builds`
138
+ }
139
+ }
140
+ ),
141
+ failedJobs.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
142
+ /* @__PURE__ */ jsx(
143
+ Markdown,
144
+ {
145
+ filename: "ship-failure.md",
146
+ templateVars: {
147
+ jobDashboardUrl: `${WEB_URL}games/${getShortUUID(gameId)}/job/${getShortUUID(failedJobs[0].id)}`
148
+ }
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: failedJobs.map((fj) => /* @__PURE__ */ jsx(JobLogTail, { jobId: fj.id, projectId: fj.project.id, isWatching: false, length: 10 }, fj.id)) })
152
+ ] })
153
+ ] })
154
+ ] });
155
+ };
156
+
157
+ class GameShip extends BaseGameCommand {
158
+ static args = {};
159
+ static flags = {
160
+ ...BaseGameCommand.flags,
161
+ platform: Flags.string({
162
+ description: 'The platform to ship the game to. This can be "android" or "ios"',
163
+ required: false,
164
+ options: ["android", "ios"]
165
+ }),
166
+ skipPublish: Flags.boolean({
167
+ description: "Skip the publish step",
168
+ required: false,
169
+ default: false
170
+ }),
171
+ download: Flags.string({
172
+ description: "Download the build artifact to the specified file",
173
+ required: false,
174
+ dependsOn: ["platform"]
175
+ }),
176
+ downloadAPK: Flags.string({
177
+ description: "Download the APK artifact (if available) to the specified file",
178
+ required: false,
179
+ dependsOn: ["platform"]
180
+ })
181
+ };
182
+ static description = "Builds the app (for all platforms with valid credentials) and ships it to the stores.";
183
+ static examples = [
184
+ "<%= config.bin %> <%= command.id %>",
185
+ "<%= config.bin %> <%= command.id %> --platform ios",
186
+ "<%= config.bin %> <%= command.id %> --platform android --skipPublish",
187
+ "<%= config.bin %> <%= command.id %> --platform android --download output.aab"
188
+ ];
189
+ async run() {
190
+ await this.ensureWeAreInAProjectDir();
191
+ const gameId = await this.getGameId();
192
+ if (!gameId) {
193
+ this.error("No game ID found");
194
+ }
195
+ const handleComplete = async ([job]) => {
196
+ if (!this.flags.download && !this.flags.downloadAPK) return process.exit(0);
197
+ const builds = job.builds ?? [];
198
+ if (builds.length === 0) this.error("No builds found for this job");
199
+ const platform = this.flags.platform;
200
+ const type = platform === "android" ? this.flags.downloadAPK ? "APK" : "AAB" : "IPA";
201
+ const build = builds.find((b) => b.buildType === type);
202
+ if (!build) this.error(`No build found for type ${type}`);
203
+ const filename = this.flags.download || this.flags.downloadAPK;
204
+ await downloadBuildById(gameId, build.id, `${filename}`);
205
+ process.exit(0);
206
+ };
207
+ const handleError = (e) => {
208
+ this.error(getErrorMessage(e));
209
+ };
210
+ render(
211
+ /* @__PURE__ */ jsx(CommandGame, { command: this, children: /* @__PURE__ */ jsx(Ship, { onComplete: handleComplete, onError: handleError }) })
212
+ );
213
+ }
214
+ }
215
+
216
+ export { GameShip as default };
@@ -0,0 +1,114 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { render } from 'ink';
3
+ import { Flags } from '@oclif/core';
4
+ import 'react';
5
+ import '../../index-nnzhQ3nY.js';
6
+ import { B as BaseAuthenticatedCommand, I as getProject, P as Platform, k as getProjectPlatformProgress, b as getShortDate } from '../../index-DkNQs11R.js';
7
+ import 'ink-spinner';
8
+ import '@inkjs/ui';
9
+ import 'axios';
10
+ import '@tanstack/react-query';
11
+ import 'fs';
12
+ import 'uuid';
13
+ import 'yazl';
14
+ import { g as getShortUUID, m as makeHumanReadable } from '../../index-BB00V5oF.js';
15
+ import 'open';
16
+ import 'marked';
17
+ import 'marked-terminal';
18
+ import 'path';
19
+ import { N as NextSteps } from '../../NextSteps-CK9zHOCt.js';
20
+ import 'qrcode';
21
+ import { S as StatusTable } from '../../StatusTable-Dm5St4g-.js';
22
+ import 'string-length';
23
+ import 'strip-ansi';
24
+ import 'luxon';
25
+ import 'fast-glob';
26
+ import { C as Command } from '../../Command-B3AmRt2w.js';
27
+ import 'socket.io-client';
28
+ import '../../useAndroidServiceAccountTestResult-DcYDam-p.js';
29
+ import '@expo/apple-utils/build/index.js';
30
+ import 'crypto-js';
31
+ import 'crypto';
32
+ import 'readline-sync';
33
+ import 'node:readline';
34
+ import 'node:path';
35
+ import 'node:url';
36
+ import 'isomorphic-git';
37
+ import 'ini';
38
+ import 'deepmerge';
39
+ import '../../Title-BCQtayg6.js';
40
+
41
+ function getSteps(platform, progress) {
42
+ if (!progress) return [];
43
+ switch (platform) {
44
+ case Platform.ANDROID:
45
+ return [
46
+ !progress.hasCredentialsForPlatform && "$ shipthis game android keyStore create",
47
+ !progress.hasApiKeyForPlatform && "$ shipthis game android apiKey create",
48
+ progress.hasCredentialsForPlatform && progress.hasApiKeyForPlatform && "$ shipthis game ship"
49
+ ].filter(Boolean);
50
+ case Platform.IOS:
51
+ return [
52
+ !progress.hasApiKeyForPlatform && "$ shipthis apple apiKey create",
53
+ !progress.hasCredentialsForPlatform && "$ shipthis game ios profile create",
54
+ progress.hasApiKeyForPlatform && progress.hasCredentialsForPlatform && "$ shipthis game ship"
55
+ ].filter(Boolean);
56
+ default:
57
+ throw new Error("Invalid platform");
58
+ }
59
+ }
60
+ class GameStatus extends BaseAuthenticatedCommand {
61
+ static args = {};
62
+ static description = "Shows the status of the current game.";
63
+ static examples = [
64
+ "<%= config.bin %> <%= command.id %>",
65
+ "<%= config.bin %> <%= command.id %> --gameId 0c179fc4"
66
+ ];
67
+ static flags = {
68
+ gameId: Flags.string({ char: "g", description: "The ID of the game" })
69
+ };
70
+ async run() {
71
+ const gameId = await this.getGameId();
72
+ if (!gameId) {
73
+ this.error("No game found - please run `shipthis game wizard` or specify a game ID with --gameId", { exit: 1 });
74
+ }
75
+ const game = await getProject(gameId);
76
+ const hasConfiguredIos = !!game.details?.iosBundleId;
77
+ const hasConfiguredAndroid = !!game.details?.androidPackageName;
78
+ let statuses = {
79
+ [Platform.IOS]: hasConfiguredIos ? await getProjectPlatformProgress(game.id, Platform.IOS) : null,
80
+ [Platform.ANDROID]: hasConfiguredAndroid ? await getProjectPlatformProgress(game.id, Platform.ANDROID) : null
81
+ };
82
+ let steps = [];
83
+ if (hasConfiguredIos) steps = steps.concat(getSteps(Platform.IOS, statuses[Platform.IOS]));
84
+ if (hasConfiguredAndroid) steps = steps.concat(getSteps(Platform.ANDROID, statuses[Platform.ANDROID]));
85
+ const progressToStatuses = (progress) => {
86
+ const { platform, ...rest } = progress;
87
+ return makeHumanReadable(rest);
88
+ };
89
+ render(
90
+ /* @__PURE__ */ jsxs(Command, { command: this, children: [
91
+ /* @__PURE__ */ jsx(
92
+ StatusTable,
93
+ {
94
+ marginBottom: 1,
95
+ title: "Game Details",
96
+ statuses: {
97
+ "Game ID": getShortUUID(game.id),
98
+ Name: game.name,
99
+ Version: `${game.details?.semanticVersion || "0.0.1"}`,
100
+ "Build Number": `${game.details?.buildNumber || 1}`,
101
+ "Created At": getShortDate(game.createdAt),
102
+ "Game Engine": `${game.details?.gameEngine || "godot"} ${game.details?.gameEngineVersion || "4.3"}`
103
+ }
104
+ }
105
+ ),
106
+ statuses[Platform.IOS] && /* @__PURE__ */ jsx(StatusTable, { title: "iOS Status", statuses: progressToStatuses(statuses[Platform.IOS]) }),
107
+ statuses[Platform.ANDROID] && /* @__PURE__ */ jsx(StatusTable, { title: "Android Status", statuses: progressToStatuses(statuses[Platform.ANDROID]) }),
108
+ /* @__PURE__ */ jsx(NextSteps, { steps })
109
+ ] })
110
+ );
111
+ }
112
+ }
113
+
114
+ export { GameStatus as default };