shipthis 0.0.1

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 (67) hide show
  1. package/README.md +894 -0
  2. package/bin/alias.sh +10 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/dev.tsc.js +15 -0
  6. package/bin/loader.js +20 -0
  7. package/bin/run.cmd +3 -0
  8. package/bin/run.js +5 -0
  9. package/bin/run.tsc.js +15 -0
  10. package/dist/App-DFPMSEZF.js +21 -0
  11. package/dist/AppleBundleIdDetails-CuhAbVEp.js +61 -0
  12. package/dist/NextSteps-CK9zHOCt.js +18 -0
  13. package/dist/RunWithSpinner-BVXNWGD3.js +27 -0
  14. package/dist/StatusTable-CxuX_R1D.js +38 -0
  15. package/dist/Table-CvM6pccN.js +101 -0
  16. package/dist/Title-BCQtayg6.js +6 -0
  17. package/dist/UserCredentialsTable-DHeRI4h6.js +76 -0
  18. package/dist/baseAppleCommand-BXUu-026.js +10 -0
  19. package/dist/baseGameCommand-xrD2WDDN.js +599 -0
  20. package/dist/cacheKeys-CShA-ZjE.js +9 -0
  21. package/dist/commands/apple/apiKey/create.js +88 -0
  22. package/dist/commands/apple/apiKey/export.js +66 -0
  23. package/dist/commands/apple/apiKey/import.js +70 -0
  24. package/dist/commands/apple/apiKey/status.js +108 -0
  25. package/dist/commands/apple/certificate/create.js +118 -0
  26. package/dist/commands/apple/certificate/export.js +66 -0
  27. package/dist/commands/apple/certificate/import.js +70 -0
  28. package/dist/commands/apple/certificate/status.js +116 -0
  29. package/dist/commands/apple/login.js +74 -0
  30. package/dist/commands/apple/status.js +50 -0
  31. package/dist/commands/dashboard.js +32 -0
  32. package/dist/commands/game/build/download.js +78 -0
  33. package/dist/commands/game/build/list.js +83 -0
  34. package/dist/commands/game/create.js +59 -0
  35. package/dist/commands/game/details.js +89 -0
  36. package/dist/commands/game/export.js +52 -0
  37. package/dist/commands/game/ios/app/addTester.js +111 -0
  38. package/dist/commands/game/ios/app/create.js +104 -0
  39. package/dist/commands/game/ios/app/status.js +52 -0
  40. package/dist/commands/game/ios/app/sync.js +81 -0
  41. package/dist/commands/game/ios/profile/create.js +110 -0
  42. package/dist/commands/game/ios/profile/export.js +68 -0
  43. package/dist/commands/game/ios/profile/import.js +77 -0
  44. package/dist/commands/game/ios/profile/status.js +183 -0
  45. package/dist/commands/game/ios/status.js +79 -0
  46. package/dist/commands/game/job/list.js +80 -0
  47. package/dist/commands/game/job/status.js +297 -0
  48. package/dist/commands/game/list.js +69 -0
  49. package/dist/commands/game/ship.js +67 -0
  50. package/dist/commands/game/status.js +76 -0
  51. package/dist/commands/game/wizard.js +124 -0
  52. package/dist/commands/login.js +63 -0
  53. package/dist/commands/status.js +80 -0
  54. package/dist/export-CujqsTR_.js +36 -0
  55. package/dist/git-DREGq-jc.js +32 -0
  56. package/dist/import-Q-KO61ll.js +38 -0
  57. package/dist/index-DKsVctbw.js +125 -0
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.js +1 -0
  60. package/dist/run.js +3 -0
  61. package/dist/upload-CUlWmNbS.js +60 -0
  62. package/dist/useAppleApp-BmwYu7qG.js +32 -0
  63. package/dist/useAppleBundleId-DCJnfNWr.js +64 -0
  64. package/dist/useBuilds-Dh_PWwCf.js +41 -0
  65. package/dist/useJob-CCkqCMvF.js +34 -0
  66. package/oclif.manifest.json +1510 -0
  67. package/package.json +167 -0
@@ -0,0 +1,124 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { B as BaseAuthenticatedCommand, i as isCWDGodotGame, g as getUserCredentials, P as Platform, C as CredentialsType, n as getProjectCredentials } from '../../baseGameCommand-xrD2WDDN.js';
3
+ import 'path';
4
+ import 'fs';
5
+ import '@expo/apple-utils/build/index.js';
6
+ import 'axios';
7
+ import 'luxon';
8
+ import 'crypto';
9
+ import 'readline-sync';
10
+ import 'node:readline';
11
+ import 'react';
12
+ import '@tanstack/react-query';
13
+ import 'socket.io-client';
14
+ import 'isomorphic-git';
15
+ import 'ini';
16
+ import 'deepmerge';
17
+
18
+ class GameWizard extends BaseAuthenticatedCommand {
19
+ static args = {};
20
+ static description = "Runs all the steps for the specific platform";
21
+ static examples = ["<%= config.bin %> <%= command.id %>"];
22
+ static flags = {
23
+ forceStep: Flags.string({
24
+ char: "f",
25
+ description: "Force a specific step to run. You can repeat this flag to force multiple steps."
26
+ }),
27
+ platform: Flags.string({
28
+ char: "p",
29
+ description: "The platform to run the wizard for",
30
+ options: [
31
+ "ios"
32
+ /* TODO - android */
33
+ ],
34
+ required: true
35
+ })
36
+ };
37
+ async run() {
38
+ const { flags } = this;
39
+ if (!isCWDGodotGame()) {
40
+ this.error("No Godot project detected. Please run this from a godot project directory.", { exit: 1 });
41
+ }
42
+ const projectConfig = await this.getProjectConfigSafe();
43
+ const game = projectConfig.project;
44
+ const isStepForced = (commandName) => flags.forceStep?.includes(commandName);
45
+ const steps = [
46
+ {
47
+ command: "game:create",
48
+ args: ["--quiet"],
49
+ shouldRun: async () => !game
50
+ },
51
+ {
52
+ command: "apple:login",
53
+ args: ["--quiet"],
54
+ shouldRun: async () => {
55
+ const isLoggedIn = await this.hasValidAppleAuthState();
56
+ return !isLoggedIn;
57
+ }
58
+ },
59
+ {
60
+ command: "apple:apiKey:create",
61
+ args: ["--quiet"],
62
+ shouldRun: async () => {
63
+ const userCredentials = await getUserCredentials();
64
+ const userAppleApiKeyCredentials = userCredentials.filter(
65
+ (cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.KEY
66
+ );
67
+ return userAppleApiKeyCredentials.length === 0;
68
+ }
69
+ },
70
+ {
71
+ command: "apple:certificate:create",
72
+ args: ["--quiet"],
73
+ shouldRun: async () => {
74
+ const userCredentials = await getUserCredentials();
75
+ const userAppleDistCredentials = userCredentials.filter(
76
+ (cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
77
+ );
78
+ return userAppleDistCredentials.length === 0;
79
+ }
80
+ },
81
+ {
82
+ command: "game:ios:app:create",
83
+ args: ["--quiet"],
84
+ shouldRun: async () => {
85
+ if (!game) return true;
86
+ const hasBundleIdSet = !!game.details?.iosBundleId;
87
+ return !hasBundleIdSet;
88
+ }
89
+ },
90
+ {
91
+ command: "game:ios:app:sync",
92
+ args: ["--quiet"],
93
+ // Can always run this
94
+ shouldRun: async () => true
95
+ },
96
+ {
97
+ command: "game:ios:profile:create",
98
+ args: ["--quiet"],
99
+ shouldRun: async () => {
100
+ if (!game) return true;
101
+ const projectCredentials = await getProjectCredentials(game.id);
102
+ const projectAppleProfileCredentials = projectCredentials.filter(
103
+ (cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
104
+ );
105
+ return projectAppleProfileCredentials.length === 0;
106
+ }
107
+ }
108
+ ];
109
+ for (const step of steps) {
110
+ const command = step.command;
111
+ const willRun = isStepForced(command) || await step.shouldRun();
112
+ if (!willRun) {
113
+ this.debug(`Skipping step: ${command}`);
114
+ continue;
115
+ }
116
+ const args = [...step.args, ...isStepForced(command) ? ["--force"] : []];
117
+ this.debug(`Running step: ${command} with args: ${args.join(" ")}`);
118
+ await this.config.runCommand(command, args);
119
+ }
120
+ await this.config.runCommand("game:status");
121
+ }
122
+ }
123
+
124
+ export { GameWizard as default };
@@ -0,0 +1,63 @@
1
+ import axios from 'axios';
2
+ import { Flags } from '@oclif/core';
3
+ import { V as BaseCommand, p as API_URL } from '../baseGameCommand-xrD2WDDN.js';
4
+ import { a as getInput } from '../index-DKsVctbw.js';
5
+ import 'path';
6
+ import 'fs';
7
+ import '@expo/apple-utils/build/index.js';
8
+ import 'luxon';
9
+ import 'crypto';
10
+ import 'readline-sync';
11
+ import 'node:readline';
12
+ import 'react';
13
+ import '@tanstack/react-query';
14
+ import 'socket.io-client';
15
+ import 'ini';
16
+ import 'deepmerge';
17
+ import 'isomorphic-git';
18
+
19
+ class Login extends BaseCommand {
20
+ static args = {};
21
+ static description = "Authenticate - will create a new account if one does not exist.";
22
+ static examples = [
23
+ "<%= config.bin %> <%= command.id %>",
24
+ "<%= config.bin %> <%= command.id %> --force --email me@email.nowhere"
25
+ ];
26
+ static flags = {
27
+ force: Flags.boolean({ char: "f" }),
28
+ email: Flags.string({
29
+ char: "e",
30
+ description: "Your email address"
31
+ })
32
+ };
33
+ async run() {
34
+ const { flags } = this;
35
+ const authConfig = await this.getAuthConfig();
36
+ if (authConfig.shipThisUser && !flags.force) {
37
+ throw new Error(
38
+ `You are already logged in as ${authConfig.shipThisUser.email} use --force to login as a different user or remove the auth file`
39
+ );
40
+ }
41
+ const getEmail = async () => {
42
+ if (flags.email) return flags.email;
43
+ const email2 = await getInput("Please enter your email address: ");
44
+ if (!email2) throw new Error("Email address is required");
45
+ return email2;
46
+ };
47
+ const email = await getEmail();
48
+ await axios.post(`${API_URL}/auth/email/send`, { email });
49
+ this.log("Please check your email for an email with an OTP.");
50
+ const getOTP = async () => {
51
+ const otp2 = await getInput("Please enter the OTP: ");
52
+ if (!otp2) throw new Error("OTP is required");
53
+ return otp2;
54
+ };
55
+ const otp = await getOTP();
56
+ const { data: shipThisUser } = await axios.post(`${API_URL}/auth/email/verify`, { email, otp });
57
+ await this.setAuthConfig({ shipThisUser });
58
+ this.log("You are now logged in as", shipThisUser.email);
59
+ await this.config.runCommand("status");
60
+ }
61
+ }
62
+
63
+ export { Login as default };
@@ -0,0 +1,80 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { render } from 'ink';
3
+ import { X as BACKEND_NAME, p as API_URL, Y as WS_URL, Z as WEB_URL, V as BaseCommand, i as isCWDGodotGame } from '../baseGameCommand-xrD2WDDN.js';
4
+ import { A as App } from '../App-DFPMSEZF.js';
5
+ import 'ink-spinner';
6
+ import 'crypto';
7
+ import 'fs';
8
+ import 'readline-sync';
9
+ import 'node:readline';
10
+ import 'react';
11
+ import 'axios';
12
+ import '@tanstack/react-query';
13
+ import 'luxon';
14
+ import 'socket.io-client';
15
+ import '@expo/apple-utils/build/index.js';
16
+ import { i as isCWDGitRepo } from '../git-DREGq-jc.js';
17
+ import { S as StatusTable } from '../StatusTable-CxuX_R1D.js';
18
+ import 'string-length';
19
+ import 'strip-ansi';
20
+ import { N as NextSteps } from '../NextSteps-CK9zHOCt.js';
21
+ import '@oclif/core';
22
+ import 'path';
23
+ import 'ini';
24
+ import 'deepmerge';
25
+ import 'isomorphic-git';
26
+ import '../Title-BCQtayg6.js';
27
+
28
+ const Environment = () => {
29
+ if (process.env.NODE_ENV === "production") return null;
30
+ return /* @__PURE__ */ jsx(
31
+ StatusTable,
32
+ {
33
+ marginTop: 1,
34
+ title: "Environment",
35
+ statuses: {
36
+ Backend: BACKEND_NAME,
37
+ API_URL,
38
+ WS_URL,
39
+ WEB_URL
40
+ }
41
+ }
42
+ );
43
+ };
44
+
45
+ class Status extends BaseCommand {
46
+ static args = {};
47
+ static description = "Displays the current overall status.";
48
+ static examples = ["<%= config.bin %> <%= command.id %>"];
49
+ static flags = {};
50
+ async run() {
51
+ const authConfig = await this.getAuthConfig();
52
+ const isLoggedIn = !!authConfig.shipThisUser;
53
+ const isGodotGame = isCWDGodotGame();
54
+ const isShipThisConfigured = await this.hasProjectConfig();
55
+ const isGitRepo = await isCWDGitRepo();
56
+ let steps = [];
57
+ if (!isLoggedIn) steps.push("$ shipthis login --email my.email@address.nowhere");
58
+ if (!isGodotGame) steps.push("Run this command in a Godot project directory");
59
+ if (!isShipThisConfigured) steps.push('$ shipthis game create --name "My Awesome Game"');
60
+ if (steps.length === 0) steps = ["$ shipthis game status"];
61
+ const statusProps = {
62
+ title: "Status",
63
+ statuses: {
64
+ "Logged in": isLoggedIn,
65
+ "Godot project detected": isGodotGame,
66
+ "ShipThis project configured": isShipThisConfigured,
67
+ "Git repository detected (not required)": isGitRepo
68
+ }
69
+ };
70
+ render(
71
+ /* @__PURE__ */ jsxs(App, { children: [
72
+ /* @__PURE__ */ jsx(StatusTable, { ...statusProps }),
73
+ /* @__PURE__ */ jsx(Environment, {}),
74
+ /* @__PURE__ */ jsx(NextSteps, { steps })
75
+ ] })
76
+ );
77
+ }
78
+ }
79
+
80
+ export { Status as default };
@@ -0,0 +1,36 @@
1
+ import axios from 'axios';
2
+ import * as fs from 'fs';
3
+ import { o as getAuthedHeaders, p as API_URL } from './baseGameCommand-xrD2WDDN.js';
4
+
5
+ async function exportCredential({ zipPath, credentialId, projectId }) {
6
+ const headers = getAuthedHeaders();
7
+ const url = projectId ? `${API_URL}/projects/${projectId}/credentials/${credentialId}/export` : `${API_URL}/credentials/${credentialId}/export`;
8
+ const { data } = await axios.post(
9
+ url,
10
+ {},
11
+ // no-body
12
+ { headers }
13
+ );
14
+ const downloadUrl = data.url;
15
+ return await downloadFile(downloadUrl, zipPath);
16
+ }
17
+ async function downloadFile(url, destination) {
18
+ const response = await axios({
19
+ url,
20
+ method: "GET",
21
+ responseType: "stream"
22
+ });
23
+ return new Promise((resolve, reject) => {
24
+ const file = fs.createWriteStream(destination);
25
+ response.data.pipe(file);
26
+ file.on("finish", () => {
27
+ file.close();
28
+ resolve();
29
+ });
30
+ file.on("error", (err) => {
31
+ fs.unlink(destination, () => reject(err));
32
+ });
33
+ });
34
+ }
35
+
36
+ export { exportCredential as e };
@@ -0,0 +1,32 @@
1
+ import git from 'isomorphic-git';
2
+ import { promises } from 'fs';
3
+
4
+ async function isCWDGitRepo() {
5
+ const dir = process.cwd();
6
+ try {
7
+ await git.log({ fs: promises, dir, depth: 1 });
8
+ return true;
9
+ } catch (e) {
10
+ return false;
11
+ }
12
+ }
13
+ async function getCWDGitInfo() {
14
+ const dir = process.cwd();
15
+ const empty = {};
16
+ try {
17
+ const commits = await git.log({ fs: promises, dir, depth: 1 });
18
+ const branch = await git.currentBranch({
19
+ fs: promises,
20
+ dir,
21
+ fullname: false
22
+ });
23
+ return {
24
+ gitCommitHash: commits[0].oid,
25
+ gitBranch: branch
26
+ };
27
+ } catch (e) {
28
+ return empty;
29
+ }
30
+ }
31
+
32
+ export { getCWDGitInfo as g, isCWDGitRepo as i };
@@ -0,0 +1,38 @@
1
+ import axios from 'axios';
2
+ import { promises } from 'fs';
3
+ import { o as getAuthedHeaders, p as API_URL } from './baseGameCommand-xrD2WDDN.js';
4
+
5
+ async function getNewImportTicket(projectId) {
6
+ const url = projectId ? `${API_URL}/projects/${projectId}/credentials/import/url` : `${API_URL}/credentials/import/url`;
7
+ const headers = getAuthedHeaders();
8
+ const { data: importInfo } = await axios({
9
+ method: "post",
10
+ url,
11
+ headers
12
+ });
13
+ return importInfo;
14
+ }
15
+ async function importCredential({ projectId, zipPath, type, platform }) {
16
+ const importTicket = await getNewImportTicket(projectId);
17
+ const zipBuffer = await promises.readFile(zipPath);
18
+ await axios.put(importTicket.url, zipBuffer, {
19
+ headers: {
20
+ "Content-length": zipBuffer.length,
21
+ "Content-Type": "application/zip"
22
+ }
23
+ });
24
+ const headers = getAuthedHeaders();
25
+ const url = projectId ? `${API_URL}/projects/${projectId}/credentials/import` : `${API_URL}/credentials/import`;
26
+ return await axios({
27
+ method: "post",
28
+ url,
29
+ headers,
30
+ data: {
31
+ uuid: importTicket.uuid,
32
+ type,
33
+ platform
34
+ }
35
+ });
36
+ }
37
+
38
+ export { importCredential as i };
@@ -0,0 +1,125 @@
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 { K as JobStatus, P as Platform, R as JobStage, S as LogLevel } from './baseGameCommand-xrD2WDDN.js';
6
+ import 'react';
7
+ import 'axios';
8
+ import '@tanstack/react-query';
9
+ import 'luxon';
10
+ import '@expo/apple-utils/build/index.js';
11
+ import 'isomorphic-git';
12
+ import 'socket.io-client';
13
+
14
+ function getShortUUID(originalUuid) {
15
+ return originalUuid.slice(0, 8);
16
+ }
17
+ function getStageColor(stage) {
18
+ switch (stage) {
19
+ case JobStage.SETUP:
20
+ return "#FFB3B3";
21
+ // pastel red
22
+ case JobStage.CONFIGURE:
23
+ return "#FFD9B3";
24
+ // pastel orange
25
+ case JobStage.EXPORT:
26
+ return "#FFFACD";
27
+ // pastel yellow
28
+ case JobStage.BUILD:
29
+ return "#B3FFB3";
30
+ // pastel green
31
+ case JobStage.PUBLISH:
32
+ return "#B3D9FF";
33
+ }
34
+ }
35
+ function getMessageColor(level) {
36
+ switch (level) {
37
+ case LogLevel.INFO:
38
+ return "white";
39
+ case LogLevel.WARN:
40
+ return "yellow";
41
+ case LogLevel.ERROR:
42
+ return "red";
43
+ }
44
+ }
45
+ function getJobStatusColor(status) {
46
+ switch (status) {
47
+ case JobStatus.PENDING:
48
+ return "yellow";
49
+ case JobStatus.PROCESSING:
50
+ return "blue";
51
+ case JobStatus.COMPLETED:
52
+ return "green";
53
+ case JobStatus.FAILED:
54
+ return "red";
55
+ }
56
+ }
57
+ async function getFileHash(filename) {
58
+ return new Promise((resolve, reject) => {
59
+ const hash = crypto.createHash("sha256");
60
+ const rs = fs__default.createReadStream(filename);
61
+ rs.on("error", reject);
62
+ rs.on("data", (chunk) => hash.update(chunk));
63
+ rs.on("end", () => resolve(hash.digest("hex")));
64
+ });
65
+ }
66
+ function isValidSemVer(versionString) {
67
+ const [semVer, major, minor, patch, prerelease, buildmetadata] = versionString.match(
68
+ /^(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-]+)*))?$/
69
+ ) ?? [];
70
+ return !!semVer;
71
+ }
72
+ function makeHumanReadable(rawObject) {
73
+ const getLabel = (key) => {
74
+ const words = key.split(/(?=[A-Z])/);
75
+ return words.map((word) => word[0].toUpperCase() + word.slice(1)).join(" ").replaceAll(" ", " ");
76
+ };
77
+ const withLabels = Object.entries(rawObject).reduce((acc, [key, value]) => {
78
+ acc[getLabel(key)] = value;
79
+ return acc;
80
+ }, {});
81
+ return withLabels;
82
+ }
83
+ function getPlatformName(platform) {
84
+ switch (platform) {
85
+ case Platform.IOS:
86
+ return "iOS";
87
+ case Platform.ANDROID:
88
+ return "Android";
89
+ default:
90
+ throw new Error(`Unknown platform: ${platform}`);
91
+ }
92
+ }
93
+ async function getMaskedInput(message) {
94
+ const password = readlineSync.question(message, {
95
+ hideEchoBack: true
96
+ // This will hide the input as the user types
97
+ });
98
+ return password;
99
+ }
100
+ async function getInput(message) {
101
+ const rl = promises.createInterface({
102
+ input: process.stdin,
103
+ output: process.stdout
104
+ });
105
+ const answer = await rl.question(message);
106
+ rl.close();
107
+ return answer;
108
+ }
109
+ function generatePackageName(gameName) {
110
+ let normalizedGameName = gameName.trim().toLowerCase();
111
+ normalizedGameName = normalizedGameName.replace(/[\s\-_]+/g, ".");
112
+ normalizedGameName = normalizedGameName.replace(/[^a-z0-9\.]/g, "");
113
+ normalizedGameName = normalizedGameName.replace(/\.+/g, ".");
114
+ normalizedGameName = normalizedGameName.replace(/^\./, "").replace(/\.$/, "");
115
+ if (/^[0-9]/.test(normalizedGameName)) {
116
+ normalizedGameName = "app." + normalizedGameName;
117
+ }
118
+ const prefix = "com.";
119
+ if (normalizedGameName === "") {
120
+ return null;
121
+ }
122
+ return prefix + normalizedGameName;
123
+ }
124
+
125
+ export { getInput as a, generatePackageName as b, getPlatformName as c, getJobStatusColor as d, getFileHash as e, getMaskedInput as f, getShortUUID as g, getStageColor as h, isValidSemVer as i, getMessageColor as j, makeHumanReadable as m };
@@ -0,0 +1 @@
1
+ export { run } from '@oclif/core';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { run } from '@oclif/core';
package/dist/run.js ADDED
@@ -0,0 +1,3 @@
1
+ import { execute } from '@oclif/core';
2
+
3
+ await execute({dir: import.meta.url});
@@ -0,0 +1,60 @@
1
+ import axios from 'axios';
2
+ import { o as getAuthedHeaders, p as API_URL } from './baseGameCommand-xrD2WDDN.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,32 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { k as App } from './baseGameCommand-xrD2WDDN.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 { m as BundleId, u as getGodotProjectCapabilities, P as Platform, G as GODOT_CAPABILITIES, v as CapabilityType } from './baseGameCommand-xrD2WDDN.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 };