shipthis 0.1.4 → 0.1.6
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.
- package/dist/AppleBundleIdDetails-Df30MPFC.js +73 -0
- package/dist/Command-DxmQn3XT.js +204 -0
- package/dist/CommandGame-DspVLTPZ.js +8 -0
- package/dist/CreateKeystore-D8uTRamD.js +56 -0
- package/dist/JobProgress-Dk0UoNah.js +108 -0
- package/dist/JobStatusTable-q4atKzhu.js +75 -0
- package/dist/ProgressSpinner-6pw1T8Iw.js +16 -0
- package/dist/ProjectCredentialsTable-BIWBAXCh.js +37 -0
- package/dist/UserCredentialsTable-CeJS3_hd.js +82 -0
- package/dist/baseAppleCommand-D-G4h8zQ.js +10 -0
- package/dist/baseGameAndroidCommand-DD0H8iy-.js +43 -0
- package/dist/commands/apple/apiKey/create.js +7 -7
- package/dist/commands/apple/apiKey/export.js +6 -6
- package/dist/commands/apple/apiKey/import.js +6 -6
- package/dist/commands/apple/apiKey/status.js +6 -6
- package/dist/commands/apple/certificate/create.js +7 -7
- package/dist/commands/apple/certificate/export.js +6 -6
- package/dist/commands/apple/certificate/import.js +6 -6
- package/dist/commands/apple/certificate/status.js +6 -6
- package/dist/commands/apple/login.js +2 -2
- package/dist/commands/apple/status.js +4 -4
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/game/android/apiKey/connect.js +8 -8
- package/dist/commands/game/android/apiKey/create.js +11 -10
- package/dist/commands/game/android/apiKey/export.js +7 -7
- package/dist/commands/game/android/apiKey/import.js +7 -7
- package/dist/commands/game/android/apiKey/invite.js +4 -4
- package/dist/commands/game/android/apiKey/status.js +7 -7
- package/dist/commands/game/android/keyStore/create.js +8 -8
- package/dist/commands/game/android/keyStore/export.js +6 -6
- package/dist/commands/game/android/keyStore/import.js +6 -6
- package/dist/commands/game/android/keyStore/status.js +6 -6
- package/dist/commands/game/android/status.js +4 -4
- package/dist/commands/game/android/wizard.js +18 -81
- package/dist/commands/game/build/download.js +4 -4
- package/dist/commands/game/build/list.js +5 -5
- package/dist/commands/game/create.js +2 -2
- package/dist/commands/game/details.js +4 -4
- package/dist/commands/game/export.js +1 -1
- package/dist/commands/game/ios/app/addTester.js +5 -5
- package/dist/commands/game/ios/app/create.js +4 -4
- package/dist/commands/game/ios/app/status.js +7 -7
- package/dist/commands/game/ios/app/sync.js +5 -5
- package/dist/commands/game/ios/profile/create.js +7 -7
- package/dist/commands/game/ios/profile/export.js +6 -6
- package/dist/commands/game/ios/profile/import.js +6 -6
- package/dist/commands/game/ios/profile/status.js +7 -7
- package/dist/commands/game/ios/status.js +7 -7
- package/dist/commands/game/ios/wizard.js +2 -2
- package/dist/commands/game/job/list.js +4 -4
- package/dist/commands/game/job/status.js +10 -59
- package/dist/commands/game/list.js +4 -4
- package/dist/commands/game/ship.js +73 -50
- package/dist/commands/game/status.js +4 -4
- package/dist/commands/game/wizard.js +1 -1
- package/dist/commands/internal/fastlane.js +1 -1
- package/dist/commands/internal/readme.js +3 -3
- package/dist/commands/login.js +2 -2
- package/dist/commands/status.js +4 -4
- package/dist/export-BDxGDZdh.js +36 -0
- package/dist/import-BrlJuE2Z.js +38 -0
- package/dist/index-BDFKyTPb.js +24 -0
- package/dist/index-BL-1G60K.js +135 -0
- package/dist/index-DBrQda8r.js +122 -0
- package/dist/index-DdABTtYO.js +693 -0
- package/dist/index-wyPoxiTc.js +136 -0
- package/dist/upload-LXRr4pMa.js +60 -0
- package/dist/useAndroidServiceAccountTestResult-InDf5WSl.js +52 -0
- package/dist/useAppleApp-DgE0wEaq.js +32 -0
- package/dist/useAppleBundleId-DtLODy3p.js +64 -0
- package/dist/useJobWatching-P5oC7mNB.js +45 -0
- package/dist/useProjectCredentials-BRffcsO3.js +54 -0
- package/dist/useWebSocket-D8PojLtx.js +36 -0
- package/docs/apple/apiKey/create.md +1 -1
- package/docs/apple/apiKey/export.md +1 -1
- package/docs/apple/apiKey/import.md +1 -1
- package/docs/apple/apiKey/status.md +1 -1
- package/docs/apple/apiKey.md +4 -4
- package/docs/apple/certificate/create.md +1 -1
- package/docs/apple/certificate/export.md +1 -1
- package/docs/apple/certificate/import.md +1 -1
- package/docs/apple/certificate/status.md +1 -1
- package/docs/apple/certificate.md +4 -4
- package/docs/apple/login.md +1 -1
- package/docs/apple/status.md +2 -1
- package/docs/dashboard.md +1 -1
- package/docs/game/android/apiKey/connect.md +1 -1
- package/docs/game/android/apiKey/create.md +1 -1
- package/docs/game/android/apiKey/export.md +1 -1
- package/docs/game/android/apiKey/import.md +1 -1
- package/docs/game/android/apiKey/invite.md +1 -1
- package/docs/game/android/apiKey/status.md +1 -1
- package/docs/game/android/apiKey.md +6 -6
- package/docs/game/android/keyStore/create.md +1 -1
- package/docs/game/android/keyStore/export.md +1 -1
- package/docs/game/android/keyStore/import.md +1 -1
- package/docs/game/android/keyStore/status.md +1 -1
- package/docs/game/android/keyStore.md +4 -4
- package/docs/game/android/status.md +1 -1
- package/docs/game/android/wizard.md +1 -1
- package/docs/game/android.md +12 -12
- package/docs/game/build/download.md +1 -1
- package/docs/game/build/list.md +1 -1
- package/docs/game/build.md +2 -2
- package/docs/game/create.md +1 -1
- package/docs/game/details.md +1 -1
- package/docs/game/export.md +1 -1
- package/docs/game/ios/app/addTester.md +1 -1
- package/docs/game/ios/app/create.md +1 -1
- package/docs/game/ios/app/status.md +1 -1
- package/docs/game/ios/app/sync.md +1 -1
- package/docs/game/ios/app.md +3 -3
- package/docs/game/ios/profile/create.md +1 -1
- package/docs/game/ios/profile/export.md +1 -1
- package/docs/game/ios/profile/import.md +1 -1
- package/docs/game/ios/profile/status.md +1 -1
- package/docs/game/ios/profile.md +4 -4
- package/docs/game/ios/status.md +1 -1
- package/docs/game/ios/wizard.md +1 -1
- package/docs/game/job/list.md +1 -1
- package/docs/game/job/status.md +1 -1
- package/docs/game/job.md +2 -2
- package/docs/game/list.md +1 -1
- package/docs/game/ship.md +1 -1
- package/docs/game/status.md +1 -1
- package/docs/game/wizard.md +1 -1
- package/docs/help.md +1 -1
- package/docs/login.md +1 -1
- package/docs/status.md +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/oclif.manifest.json +122 -122
- package/package.json +1 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import fs__default from 'fs';
|
|
3
|
+
import readlineSync from 'readline-sync';
|
|
4
|
+
import { promises } from 'node:readline';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { J as JobStatus, P as Platform, I as JobStage, L as LogLevel } from './index-DdABTtYO.js';
|
|
8
|
+
import 'react';
|
|
9
|
+
import 'axios';
|
|
10
|
+
import '@tanstack/react-query';
|
|
11
|
+
import 'luxon';
|
|
12
|
+
import 'isomorphic-git';
|
|
13
|
+
import '@oclif/core';
|
|
14
|
+
import 'crypto-js';
|
|
15
|
+
import 'uuid';
|
|
16
|
+
import 'fast-glob';
|
|
17
|
+
import 'yazl';
|
|
18
|
+
import 'socket.io-client';
|
|
19
|
+
|
|
20
|
+
function getShortUUID(originalUuid) {
|
|
21
|
+
return originalUuid.slice(0, 8);
|
|
22
|
+
}
|
|
23
|
+
function getStageColor(stage) {
|
|
24
|
+
switch (stage) {
|
|
25
|
+
case JobStage.SETUP:
|
|
26
|
+
return "#FFB3B3";
|
|
27
|
+
// pastel red
|
|
28
|
+
case JobStage.CONFIGURE:
|
|
29
|
+
return "#FFD9B3";
|
|
30
|
+
// pastel orange
|
|
31
|
+
case JobStage.EXPORT:
|
|
32
|
+
return "#FFFACD";
|
|
33
|
+
// pastel yellow
|
|
34
|
+
case JobStage.BUILD:
|
|
35
|
+
return "#B3FFB3";
|
|
36
|
+
// pastel green
|
|
37
|
+
case JobStage.PUBLISH:
|
|
38
|
+
return "#B3D9FF";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function getMessageColor(level) {
|
|
42
|
+
switch (level) {
|
|
43
|
+
case LogLevel.INFO:
|
|
44
|
+
return "white";
|
|
45
|
+
case LogLevel.WARN:
|
|
46
|
+
return "yellow";
|
|
47
|
+
case LogLevel.ERROR:
|
|
48
|
+
return "red";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function getJobStatusColor(status) {
|
|
52
|
+
switch (status) {
|
|
53
|
+
case JobStatus.PENDING:
|
|
54
|
+
return "yellow";
|
|
55
|
+
case JobStatus.PROCESSING:
|
|
56
|
+
return "blue";
|
|
57
|
+
case JobStatus.COMPLETED:
|
|
58
|
+
return "green";
|
|
59
|
+
case JobStatus.FAILED:
|
|
60
|
+
return "red";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function getFileHash(filename) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const hash = crypto.createHash("sha256");
|
|
66
|
+
const rs = fs__default.createReadStream(filename);
|
|
67
|
+
rs.on("error", reject);
|
|
68
|
+
rs.on("data", (chunk) => hash.update(chunk));
|
|
69
|
+
rs.on("end", () => resolve(hash.digest("hex")));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function isValidSemVer(versionString) {
|
|
73
|
+
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-]+)*))?$/
|
|
75
|
+
) ?? [];
|
|
76
|
+
return !!semVer;
|
|
77
|
+
}
|
|
78
|
+
function makeHumanReadable(rawObject) {
|
|
79
|
+
const getLabel = (key) => {
|
|
80
|
+
const words = key.split(/(?=[A-Z])/);
|
|
81
|
+
return words.map((word) => word[0].toUpperCase() + word.slice(1)).join(" ").replaceAll(" ", " ");
|
|
82
|
+
};
|
|
83
|
+
const withLabels = Object.entries(rawObject).reduce((acc, [key, value]) => {
|
|
84
|
+
acc[getLabel(key)] = value;
|
|
85
|
+
return acc;
|
|
86
|
+
}, {});
|
|
87
|
+
return withLabels;
|
|
88
|
+
}
|
|
89
|
+
function getPlatformName(platform) {
|
|
90
|
+
switch (platform) {
|
|
91
|
+
case Platform.IOS:
|
|
92
|
+
return "iOS";
|
|
93
|
+
case Platform.ANDROID:
|
|
94
|
+
return "Android";
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(`Unknown platform: ${platform}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async function getMaskedInput(message) {
|
|
100
|
+
const password = readlineSync.question(message, {
|
|
101
|
+
hideEchoBack: true
|
|
102
|
+
// This will hide the input as the user types
|
|
103
|
+
});
|
|
104
|
+
return password;
|
|
105
|
+
}
|
|
106
|
+
async function getInput(message) {
|
|
107
|
+
const rl = promises.createInterface({
|
|
108
|
+
input: process.stdin,
|
|
109
|
+
output: process.stdout
|
|
110
|
+
});
|
|
111
|
+
const answer = await rl.question(message);
|
|
112
|
+
rl.close();
|
|
113
|
+
return answer;
|
|
114
|
+
}
|
|
115
|
+
function generatePackageName(gameName) {
|
|
116
|
+
let normalizedGameName = gameName.trim().toLowerCase();
|
|
117
|
+
normalizedGameName = normalizedGameName.replace(/[\s\-_]+/g, ".");
|
|
118
|
+
normalizedGameName = normalizedGameName.replace(/[^a-z0-9\.]/g, "");
|
|
119
|
+
normalizedGameName = normalizedGameName.replace(/\.+/g, ".");
|
|
120
|
+
normalizedGameName = normalizedGameName.replace(/^\./, "").replace(/\.$/, "");
|
|
121
|
+
if (/^[0-9]/.test(normalizedGameName)) {
|
|
122
|
+
normalizedGameName = "app." + normalizedGameName;
|
|
123
|
+
}
|
|
124
|
+
const prefix = "com.";
|
|
125
|
+
if (normalizedGameName === "") {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return prefix + normalizedGameName;
|
|
129
|
+
}
|
|
130
|
+
function scriptDir(importMeta) {
|
|
131
|
+
const filename = fileURLToPath(importMeta.url);
|
|
132
|
+
const dirname = path.dirname(filename);
|
|
133
|
+
return dirname;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { getInput as a, generatePackageName as b, getJobStatusColor as c, getStageColor as d, getMaskedInput as e, getFileHash as f, getShortUUID as g, getPlatformName as h, isValidSemVer as i, getMessageColor as j, makeHumanReadable as m, scriptDir as s };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { p as getAuthedHeaders, q as API_URL } from './index-DdABTtYO.js';
|
|
3
|
+
|
|
4
|
+
async function getNewUploadTicket(projectId = null) {
|
|
5
|
+
const url = projectId ? `${API_URL}/projects/${projectId}/credentials/url` : `${API_URL}/credentials/url`;
|
|
6
|
+
const headers = getAuthedHeaders();
|
|
7
|
+
const { data: uploadInfo } = await axios({
|
|
8
|
+
method: "post",
|
|
9
|
+
url,
|
|
10
|
+
headers
|
|
11
|
+
});
|
|
12
|
+
return uploadInfo;
|
|
13
|
+
}
|
|
14
|
+
async function uploadUserCredentials({ contents, platform, type, serialNumber }) {
|
|
15
|
+
const uploadInfo = await getNewUploadTicket();
|
|
16
|
+
const jsonBuffer = Buffer.from(JSON.stringify(contents));
|
|
17
|
+
await axios.put(uploadInfo.url, jsonBuffer, {
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-length": jsonBuffer.length,
|
|
20
|
+
"Content-Type": "application/json"
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const headers = getAuthedHeaders();
|
|
24
|
+
return await axios({
|
|
25
|
+
method: "post",
|
|
26
|
+
url: `${API_URL}/credentials`,
|
|
27
|
+
headers,
|
|
28
|
+
data: {
|
|
29
|
+
platform,
|
|
30
|
+
type,
|
|
31
|
+
uuid: uploadInfo.uuid,
|
|
32
|
+
serialNumber
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function uploadProjectCredentials(projectId, { contents, platform, type, serialNumber, identifier }) {
|
|
37
|
+
const uploadInfo = await getNewUploadTicket(projectId);
|
|
38
|
+
const jsonBuffer = Buffer.from(JSON.stringify(contents));
|
|
39
|
+
await axios.put(uploadInfo.url, jsonBuffer, {
|
|
40
|
+
headers: {
|
|
41
|
+
"Content-length": jsonBuffer.length,
|
|
42
|
+
"Content-Type": "application/json"
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const headers = getAuthedHeaders();
|
|
46
|
+
return await axios({
|
|
47
|
+
method: "post",
|
|
48
|
+
url: `${API_URL}/projects/${projectId}/credentials`,
|
|
49
|
+
headers,
|
|
50
|
+
data: {
|
|
51
|
+
platform,
|
|
52
|
+
type,
|
|
53
|
+
uuid: uploadInfo.uuid,
|
|
54
|
+
identifier,
|
|
55
|
+
serialNumber
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { uploadProjectCredentials as a, uploadUserCredentials as u };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { p as getAuthedHeaders, q as API_URL } from './index-DdABTtYO.js';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import { useQuery } from '@tanstack/react-query';
|
|
4
|
+
|
|
5
|
+
const cacheKeys = {
|
|
6
|
+
androidKeyTestResult: (props) => ["androidKeyTestResult", ...Object.values(props)],
|
|
7
|
+
androidSetupStatus: (props) => ["androidSetupStatus", ...Object.values(props)],
|
|
8
|
+
builds: (props) => ["builds", ...Object.values(props)],
|
|
9
|
+
googleStatus: () => ["googleStatus"],
|
|
10
|
+
job: (props) => ["job", ...Object.values(props)],
|
|
11
|
+
jobLogs: (props) => ["jobLogs", ...Object.values(props)],
|
|
12
|
+
jobs: (props) => ["jobs", ...Object.values(props)],
|
|
13
|
+
projectCredentials: (props) => ["projectCredentials", ...Object.values(props)],
|
|
14
|
+
userCredentials: (props) => ["userCredentials", ...Object.values(props)]
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
var KeyTestStatus = /* @__PURE__ */ ((KeyTestStatus2) => {
|
|
18
|
+
KeyTestStatus2["SUCCESS"] = "success";
|
|
19
|
+
KeyTestStatus2["ERROR"] = "error";
|
|
20
|
+
return KeyTestStatus2;
|
|
21
|
+
})(KeyTestStatus || {});
|
|
22
|
+
var KeyTestError = /* @__PURE__ */ ((KeyTestError2) => {
|
|
23
|
+
KeyTestError2["NO_SERVICE_ACCOUNT_KEY"] = "no_service_account_key";
|
|
24
|
+
KeyTestError2["NO_PACKAGE_NAME"] = "no_package_name";
|
|
25
|
+
KeyTestError2["APP_NOT_FOUND"] = "app_not_found";
|
|
26
|
+
KeyTestError2["NOT_INVITED"] = "not_invited";
|
|
27
|
+
return KeyTestError2;
|
|
28
|
+
})(KeyTestError || {});
|
|
29
|
+
const KeyTestErrorMessage = {
|
|
30
|
+
["no_service_account_key" /* NO_SERVICE_ACCOUNT_KEY */]: "Service Account API Key not found in your account",
|
|
31
|
+
["no_package_name" /* NO_PACKAGE_NAME */]: "Android Package Name has not been set",
|
|
32
|
+
["app_not_found" /* APP_NOT_FOUND */]: "Application not found in Google Play Console",
|
|
33
|
+
["not_invited" /* NOT_INVITED */]: "Service Account has not been invited to Google Play"
|
|
34
|
+
};
|
|
35
|
+
function niceError(keyError) {
|
|
36
|
+
return keyError ? KeyTestErrorMessage[keyError] : undefined;
|
|
37
|
+
}
|
|
38
|
+
const fetchKeyTestResult = async ({ projectId }, config) => {
|
|
39
|
+
if (!projectId) throw new Error("projectId is required");
|
|
40
|
+
const url = `${API_URL}/projects/${projectId}/credentials/android/key/test`;
|
|
41
|
+
const headers = getAuthedHeaders();
|
|
42
|
+
const { data } = await axios.post(url, {}, { headers, ...config });
|
|
43
|
+
return data;
|
|
44
|
+
};
|
|
45
|
+
const useAndroidServiceAccountTestResult = (props) => {
|
|
46
|
+
return useQuery({
|
|
47
|
+
queryKey: cacheKeys.androidKeyTestResult(props),
|
|
48
|
+
queryFn: () => fetchKeyTestResult(props)
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { KeyTestStatus as K, KeyTestError as a, cacheKeys as c, fetchKeyTestResult as f, niceError as n, useAndroidServiceAccountTestResult as u };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { f as App } from './index-DdABTtYO.js';
|
|
3
|
+
|
|
4
|
+
const queryAppleApp = async ({ ctx, iosBundleId }) => {
|
|
5
|
+
if (!iosBundleId) {
|
|
6
|
+
return { app: null, summary: null };
|
|
7
|
+
}
|
|
8
|
+
const app = await App.findAsync(ctx, {
|
|
9
|
+
bundleId: iosBundleId
|
|
10
|
+
});
|
|
11
|
+
if (!app) {
|
|
12
|
+
return { app: null, summary: null };
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
app,
|
|
16
|
+
summary: {
|
|
17
|
+
id: app.id,
|
|
18
|
+
name: app.attributes.name,
|
|
19
|
+
bundleId: app.attributes.bundleId,
|
|
20
|
+
primaryLocale: app.attributes.primaryLocale
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
const useAppleApp = (props) => {
|
|
25
|
+
const queryResult = useQuery({
|
|
26
|
+
queryKey: ["appleApp", props.iosBundleId],
|
|
27
|
+
queryFn: () => queryAppleApp(props)
|
|
28
|
+
});
|
|
29
|
+
return queryResult;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { queryAppleApp as q, useAppleApp as u };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { e as BundleId, r as getGodotProjectCapabilities, P as Platform, G as GODOT_CAPABILITIES, s as CapabilityType } from './index-DdABTtYO.js';
|
|
3
|
+
|
|
4
|
+
async function getBundleIdCapabilities(bundleId) {
|
|
5
|
+
const current = await bundleId.getBundleIdCapabilitiesAsync();
|
|
6
|
+
let existing = [];
|
|
7
|
+
for (const capability of current) {
|
|
8
|
+
const capabilityType = Object.values(CapabilityType).find((c) => capability.isType(c));
|
|
9
|
+
if (capabilityType) {
|
|
10
|
+
existing.push(capabilityType);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return existing;
|
|
14
|
+
}
|
|
15
|
+
const fetchBundleId = async ({ ctx, iosBundleId }) => {
|
|
16
|
+
const empty = {
|
|
17
|
+
bundleId: null,
|
|
18
|
+
bundleIdSummary: null,
|
|
19
|
+
capabilities: null,
|
|
20
|
+
capabilitiesTable: null,
|
|
21
|
+
projectCapabilities: null,
|
|
22
|
+
shouldSyncCapabilities: null
|
|
23
|
+
};
|
|
24
|
+
if (!iosBundleId) return empty;
|
|
25
|
+
const bundleId = await BundleId.findAsync(ctx, {
|
|
26
|
+
identifier: iosBundleId
|
|
27
|
+
});
|
|
28
|
+
if (!bundleId) return empty;
|
|
29
|
+
const bundleIdCapabilities = await getBundleIdCapabilities(bundleId);
|
|
30
|
+
const projectCapabilities = getGodotProjectCapabilities(Platform.IOS);
|
|
31
|
+
const capabilitiesTable = GODOT_CAPABILITIES.map((gc) => {
|
|
32
|
+
const isEnabledInBundle = bundleIdCapabilities.includes(gc.type);
|
|
33
|
+
const isEnabledInProject = projectCapabilities.includes(gc.type);
|
|
34
|
+
const isCorrectlyConfigured = isEnabledInBundle === isEnabledInProject;
|
|
35
|
+
return {
|
|
36
|
+
name: gc.name,
|
|
37
|
+
isEnabledInBundle,
|
|
38
|
+
isEnabledInProject,
|
|
39
|
+
isCorrectlyConfigured
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
bundleId,
|
|
44
|
+
bundleIdSummary: {
|
|
45
|
+
id: bundleId.id,
|
|
46
|
+
identifier: bundleId.attributes.identifier,
|
|
47
|
+
name: bundleId.attributes.name,
|
|
48
|
+
platform: bundleId.attributes.platform
|
|
49
|
+
},
|
|
50
|
+
capabilities: bundleIdCapabilities,
|
|
51
|
+
capabilitiesTable,
|
|
52
|
+
projectCapabilities,
|
|
53
|
+
shouldSyncCapabilities: !capabilitiesTable.every((c) => c.isCorrectlyConfigured)
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
const useAppleBundleId = (props) => {
|
|
57
|
+
const queryResult = useQuery({
|
|
58
|
+
queryKey: ["appleBundleId", props.iosBundleId],
|
|
59
|
+
queryFn: () => fetchBundleId(props)
|
|
60
|
+
});
|
|
61
|
+
return queryResult;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export { fetchBundleId as f, useAppleBundleId as u };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { u as useJob } from './Command-DxmQn3XT.js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { u as useWebSocket } from './useWebSocket-D8PojLtx.js';
|
|
4
|
+
import { K as castJobDates, M as castObjectDates } from './index-DdABTtYO.js';
|
|
5
|
+
|
|
6
|
+
function useJobWatching({ projectId, jobId, isWatching, onJobUpdate }) {
|
|
7
|
+
const [websocketJob, setWebsocketJob] = useState(null);
|
|
8
|
+
const [mostRecentLog, setMostRecentLog] = useState(null);
|
|
9
|
+
const jobStatusListener = {
|
|
10
|
+
getPattern: () => [`project.${projectId}:job:created`, `project.${projectId}:job:updated`],
|
|
11
|
+
eventHandler: async (pattern, rawJob) => {
|
|
12
|
+
if (rawJob.id !== jobId) return;
|
|
13
|
+
const job2 = castJobDates(rawJob);
|
|
14
|
+
setWebsocketJob(job2);
|
|
15
|
+
if (onJobUpdate) onJobUpdate(job2);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const jobProgressListener = {
|
|
19
|
+
getPattern: () => `project.${projectId}:job.${jobId}:log`,
|
|
20
|
+
eventHandler: async (pattern, rawLogEntry) => {
|
|
21
|
+
const logEntry = castObjectDates(rawLogEntry, ["sentAt", "createdAt"]);
|
|
22
|
+
setMostRecentLog(logEntry);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
useWebSocket(isWatching ? [jobStatusListener, jobProgressListener] : []);
|
|
26
|
+
const { isLoading, data: job } = useJob({
|
|
27
|
+
projectId,
|
|
28
|
+
jobId
|
|
29
|
+
});
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setWebsocketJob(null);
|
|
32
|
+
}, [jobId, projectId, isWatching, job]);
|
|
33
|
+
const fetchedJob = job ? job : null;
|
|
34
|
+
const data = websocketJob ? websocketJob : fetchedJob;
|
|
35
|
+
const progress = mostRecentLog?.progress || null;
|
|
36
|
+
const stage = mostRecentLog?.stage || null;
|
|
37
|
+
return {
|
|
38
|
+
isLoading,
|
|
39
|
+
data,
|
|
40
|
+
progress,
|
|
41
|
+
stage
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { useJobWatching as u };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
import { c as cacheKeys } from './useAndroidServiceAccountTestResult-InDf5WSl.js';
|
|
4
|
+
import { b as getShortDate, p as getAuthedHeaders, q as API_URL, H as castArrayObjectDates } from './index-DdABTtYO.js';
|
|
5
|
+
import { g as getShortUUID } from './index-wyPoxiTc.js';
|
|
6
|
+
|
|
7
|
+
async function queryProjectCredentials({
|
|
8
|
+
projectId,
|
|
9
|
+
...pageAndSortParams
|
|
10
|
+
}) {
|
|
11
|
+
try {
|
|
12
|
+
const headers = getAuthedHeaders();
|
|
13
|
+
const url = `${API_URL}/projects/${projectId}/credentials`;
|
|
14
|
+
const response = await axios.get(url, { headers, params: pageAndSortParams });
|
|
15
|
+
return {
|
|
16
|
+
...response.data,
|
|
17
|
+
data: castArrayObjectDates(response.data.data)
|
|
18
|
+
};
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.warn("queryProjectCredentials Error", error);
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function getProjectCredentialSummary(credential) {
|
|
25
|
+
return {
|
|
26
|
+
id: getShortUUID(credential.id),
|
|
27
|
+
type: credential.type,
|
|
28
|
+
serial: credential.serialNumber.substring(0, 30) + (credential.serialNumber.length > 30 ? "\u2026" : ""),
|
|
29
|
+
isActive: credential.isActive,
|
|
30
|
+
createdAt: getShortDate(credential.createdAt)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const useProjectCredentials = ({
|
|
34
|
+
platform,
|
|
35
|
+
type,
|
|
36
|
+
...fetchProps
|
|
37
|
+
}) => {
|
|
38
|
+
const queryResult = useQuery({
|
|
39
|
+
queryKey: cacheKeys.projectCredentials(fetchProps),
|
|
40
|
+
queryFn: async () => queryProjectCredentials(fetchProps),
|
|
41
|
+
select: (data) => {
|
|
42
|
+
if (!(platform || type)) return data;
|
|
43
|
+
return {
|
|
44
|
+
...data,
|
|
45
|
+
data: data.data.filter((credential) => {
|
|
46
|
+
return (!platform || credential.platform === platform) && (!type || credential.type === type);
|
|
47
|
+
})
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return queryResult;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export { getProjectCredentialSummary as g, useProjectCredentials as u };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { io } from 'socket.io-client';
|
|
3
|
+
import { N as getAuthToken, W as WS_URL } from './index-DdABTtYO.js';
|
|
4
|
+
|
|
5
|
+
function useWebSocket(listeners = []) {
|
|
6
|
+
const log = () => {
|
|
7
|
+
};
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (listeners.length === 0) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const token = getAuthToken();
|
|
13
|
+
const socket = io(WS_URL, {
|
|
14
|
+
auth: { token },
|
|
15
|
+
forceNew: true
|
|
16
|
+
});
|
|
17
|
+
socket.on("connect", () => log());
|
|
18
|
+
for (const listener of listeners) {
|
|
19
|
+
const pattern = listener.getPattern();
|
|
20
|
+
const bindSocket = (pattern2) => {
|
|
21
|
+
const boundListener = listener.eventHandler.bind(listener, pattern2);
|
|
22
|
+
socket.on(pattern2, boundListener);
|
|
23
|
+
};
|
|
24
|
+
if (Array.isArray(pattern)) {
|
|
25
|
+
pattern.forEach(bindSocket);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
bindSocket(pattern);
|
|
29
|
+
}
|
|
30
|
+
return () => {
|
|
31
|
+
socket.disconnect();
|
|
32
|
+
};
|
|
33
|
+
}, []);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { useWebSocket as u };
|
package/docs/apple/apiKey.md
CHANGED
|
@@ -37,7 +37,7 @@ Saves the private key in your ShipThis account.
|
|
|
37
37
|
|
|
38
38
|
#### Help Output
|
|
39
39
|
|
|
40
|
-
```
|
|
40
|
+
```help
|
|
41
41
|
USAGE
|
|
42
42
|
$ shipthis apple apiKey create [-f] [-q]
|
|
43
43
|
|
|
@@ -63,7 +63,7 @@ Saves the current App Store Connect API Key to a ZIP file
|
|
|
63
63
|
|
|
64
64
|
#### Help Output
|
|
65
65
|
|
|
66
|
-
```
|
|
66
|
+
```help
|
|
67
67
|
USAGE
|
|
68
68
|
$ shipthis apple apiKey export FILE [-f]
|
|
69
69
|
|
|
@@ -88,7 +88,7 @@ Imports an App Store Connect API Key ZIP file into your ShipThis account
|
|
|
88
88
|
|
|
89
89
|
#### Help Output
|
|
90
90
|
|
|
91
|
-
```
|
|
91
|
+
```help
|
|
92
92
|
USAGE
|
|
93
93
|
$ shipthis apple apiKey import FILE [-f]
|
|
94
94
|
|
|
@@ -114,7 +114,7 @@ This API key is used to automatically publish your games to the App Store.
|
|
|
114
114
|
|
|
115
115
|
#### Help Output
|
|
116
116
|
|
|
117
|
-
```
|
|
117
|
+
```help
|
|
118
118
|
USAGE
|
|
119
119
|
$ shipthis apple apiKey status [-f]
|
|
120
120
|
|
|
@@ -39,7 +39,7 @@ Saves the certificate with the private key to your ShipThis account
|
|
|
39
39
|
|
|
40
40
|
#### Help Output
|
|
41
41
|
|
|
42
|
-
```
|
|
42
|
+
```help
|
|
43
43
|
USAGE
|
|
44
44
|
$ shipthis apple certificate create [-f] [-q]
|
|
45
45
|
|
|
@@ -65,7 +65,7 @@ Saves the current Apple Distribution Certificate to a ZIP file.
|
|
|
65
65
|
|
|
66
66
|
#### Help Output
|
|
67
67
|
|
|
68
|
-
```
|
|
68
|
+
```help
|
|
69
69
|
USAGE
|
|
70
70
|
$ shipthis apple certificate export FILE [-f]
|
|
71
71
|
|
|
@@ -90,7 +90,7 @@ Imports an iOS Distribution Certificate to your ShipThis account
|
|
|
90
90
|
|
|
91
91
|
#### Help Output
|
|
92
92
|
|
|
93
|
-
```
|
|
93
|
+
```help
|
|
94
94
|
USAGE
|
|
95
95
|
$ shipthis apple certificate import FILE [-f]
|
|
96
96
|
|
|
@@ -116,7 +116,7 @@ These are used to sign all of your iOS apps.
|
|
|
116
116
|
|
|
117
117
|
#### Help Output
|
|
118
118
|
|
|
119
|
-
```
|
|
119
|
+
```help
|
|
120
120
|
USAGE
|
|
121
121
|
$ shipthis apple certificate status [-f]
|
|
122
122
|
|
package/docs/apple/login.md
CHANGED
package/docs/apple/status.md
CHANGED
|
@@ -13,7 +13,8 @@ To authenticate, please run [`shipthis apple login`](/docs/reference/apple/login
|
|
|
13
13
|
[](https://asciinema.org/a/PPSZ5EUxbdnd3IqCk6vtb2Bmw)
|
|
14
14
|
|
|
15
15
|
## Help Output
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
```help
|
|
17
18
|
USAGE
|
|
18
19
|
$ shipthis apple status
|
|
19
20
|
|
package/docs/dashboard.md
CHANGED