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.
- package/dist/AppleBundleIdDetails-mPUG2R4N.js +76 -0
- package/dist/Command-B3AmRt2w.js +28 -0
- package/dist/CommandGame-BCMzP9pc.js +9 -0
- package/dist/Create-CsJxpzUs.js +59 -0
- package/dist/Import-v0M_ygyF.js +110 -0
- package/dist/JobProgress-9uvq8IBn.js +121 -0
- package/dist/JobStatusTable-Bf7J9WXe.js +191 -0
- package/dist/NextSteps-CK9zHOCt.js +18 -0
- package/dist/ProgressSpinner-6pw1T8Iw.js +16 -0
- package/dist/ProjectCredentialsTable-CTkP1mvy.js +37 -0
- package/dist/RunWithSpinner-BVXNWGD3.js +27 -0
- package/dist/StatusTable-Dm5St4g-.js +33 -0
- package/dist/Table-CvM6pccN.js +101 -0
- package/dist/Title-BCQtayg6.js +6 -0
- package/dist/UserCredentialsTable-DhtM_iTG.js +82 -0
- package/dist/baseAppleCommand-IGl6KTvv.js +10 -0
- package/dist/baseGameAndroidCommand-DFn4zMvq.js +43 -0
- package/dist/commands/apple/apiKey/create.js +103 -0
- package/dist/commands/apple/apiKey/export.js +81 -0
- package/dist/commands/apple/apiKey/import.js +85 -0
- package/dist/commands/apple/apiKey/status.js +122 -0
- package/dist/commands/apple/certificate/create.js +133 -0
- package/dist/commands/apple/certificate/export.js +81 -0
- package/dist/commands/apple/certificate/import.js +85 -0
- package/dist/commands/apple/certificate/status.js +130 -0
- package/dist/commands/apple/login.js +76 -0
- package/dist/commands/apple/status.js +79 -0
- package/dist/commands/dashboard.js +38 -0
- package/dist/commands/game/android/apiKey/connect.js +74 -0
- package/dist/commands/game/android/apiKey/create.js +74 -0
- package/dist/commands/game/android/apiKey/export.js +84 -0
- package/dist/commands/game/android/apiKey/import.js +93 -0
- package/dist/commands/game/android/apiKey/invite.js +81 -0
- package/dist/commands/game/android/apiKey/status.js +87 -0
- package/dist/commands/game/android/keyStore/create.js +69 -0
- package/dist/commands/game/android/keyStore/export.js +83 -0
- package/dist/commands/game/android/keyStore/import.js +112 -0
- package/dist/commands/game/android/keyStore/status.js +70 -0
- package/dist/commands/game/android/status.js +84 -0
- package/dist/commands/game/build/download.js +80 -0
- package/dist/commands/game/build/list.js +96 -0
- package/dist/commands/game/create.js +67 -0
- package/dist/commands/game/details.js +113 -0
- package/dist/commands/game/export.js +58 -0
- package/dist/commands/game/ios/app/addTester.js +124 -0
- package/dist/commands/game/ios/app/create.js +117 -0
- package/dist/commands/game/ios/app/status.js +66 -0
- package/dist/commands/game/ios/app/sync.js +95 -0
- package/dist/commands/game/ios/profile/create.js +129 -0
- package/dist/commands/game/ios/profile/export.js +83 -0
- package/dist/commands/game/ios/profile/import.js +92 -0
- package/dist/commands/game/ios/profile/status.js +139 -0
- package/dist/commands/game/ios/status.js +92 -0
- package/dist/commands/game/ios/wizard.js +153 -0
- package/dist/commands/game/job/list.js +95 -0
- package/dist/commands/game/job/status.js +91 -0
- package/dist/commands/game/list.js +83 -0
- package/dist/commands/game/ship.js +216 -0
- package/dist/commands/game/status.js +114 -0
- package/dist/commands/game/wizard.js +686 -0
- package/dist/commands/internal/fastlane.js +74 -0
- package/dist/commands/internal/readme.js +937 -0
- package/dist/commands/login.js +92 -0
- package/dist/commands/status.js +76 -0
- package/dist/export-CVs_xoDN.js +36 -0
- package/dist/git-DREGq-jc.js +32 -0
- package/dist/import-Ch5O7xfN.js +47 -0
- package/dist/index-BB00V5oF.js +136 -0
- package/dist/index-BD1WLuFJ.js +125 -0
- package/dist/index-CIa2EDQ6.js +24 -0
- package/dist/index-CboPN9aq.js +138 -0
- package/dist/index-DkNQs11R.js +711 -0
- package/dist/index-nnzhQ3nY.js +209 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/upload-CRE2nVdd.js +60 -0
- package/dist/useAndroidServiceAccountTestResult-DcYDam-p.js +52 -0
- package/dist/useAppleApp-B16WbUxJ.js +32 -0
- package/dist/useAppleBundleId-DobPATan.js +64 -0
- package/dist/useJobWatching--BvVn7xS.js +45 -0
- package/dist/useProjectCredentials-Btnr7WK3.js +54 -0
- package/dist/useWebSocket-ByuNoqRw.js +36 -0
- package/dist/utils/help.js +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { render } from 'ink';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import 'react';
|
|
6
|
+
import '../../../../index-nnzhQ3nY.js';
|
|
7
|
+
import { c as BaseGameCommand, P as Platform, C as CredentialsType, l as Certificate, m as CertificateType, n as Profile, o as ProfileType } from '../../../../index-DkNQs11R.js';
|
|
8
|
+
import 'ink-spinner';
|
|
9
|
+
import 'crypto-js';
|
|
10
|
+
import 'uuid';
|
|
11
|
+
import 'fs';
|
|
12
|
+
import 'luxon';
|
|
13
|
+
import { a as getProjectCredentials, g as getUserCredentials } from '../../../../index-CIa2EDQ6.js';
|
|
14
|
+
import '@inkjs/ui';
|
|
15
|
+
import '@tanstack/react-query';
|
|
16
|
+
import 'yazl';
|
|
17
|
+
import 'crypto';
|
|
18
|
+
import 'readline-sync';
|
|
19
|
+
import 'node:readline';
|
|
20
|
+
import 'node:path';
|
|
21
|
+
import 'node:url';
|
|
22
|
+
import 'isomorphic-git';
|
|
23
|
+
import { f as fetchBundleId } from '../../../../useAppleBundleId-DobPATan.js';
|
|
24
|
+
import 'fast-glob';
|
|
25
|
+
import 'socket.io-client';
|
|
26
|
+
import 'open';
|
|
27
|
+
import 'marked';
|
|
28
|
+
import 'marked-terminal';
|
|
29
|
+
import 'path';
|
|
30
|
+
import 'qrcode';
|
|
31
|
+
import { R as RunWithSpinner } from '../../../../RunWithSpinner-BVXNWGD3.js';
|
|
32
|
+
import 'string-length';
|
|
33
|
+
import 'strip-ansi';
|
|
34
|
+
import { C as Command } from '../../../../Command-B3AmRt2w.js';
|
|
35
|
+
import { a as uploadProjectCredentials } from '../../../../upload-CRE2nVdd.js';
|
|
36
|
+
import '../../../../index-BB00V5oF.js';
|
|
37
|
+
import '../../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
38
|
+
import '@expo/apple-utils/build/index.js';
|
|
39
|
+
import 'ini';
|
|
40
|
+
import 'deepmerge';
|
|
41
|
+
|
|
42
|
+
class GameIosProfileCreate extends BaseGameCommand {
|
|
43
|
+
static args = {};
|
|
44
|
+
static description = "Creates a Mobile Provisioning Profile in the Apple Developer Portal.";
|
|
45
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
46
|
+
static flags = {
|
|
47
|
+
quiet: Flags.boolean({ char: "q", description: "Avoid output except for interactions and errors" }),
|
|
48
|
+
gameId: Flags.string({ char: "g", description: "The ID of the game" }),
|
|
49
|
+
force: Flags.boolean({ char: "f" })
|
|
50
|
+
};
|
|
51
|
+
async run() {
|
|
52
|
+
const game = await this.getGame();
|
|
53
|
+
const authState = await this.refreshAppleAuthState();
|
|
54
|
+
const ctx = authState.context;
|
|
55
|
+
const { flags } = this;
|
|
56
|
+
const { force } = flags;
|
|
57
|
+
const projectCredentials = await getProjectCredentials(game.id);
|
|
58
|
+
const projectAppleProfileCredentials = projectCredentials.filter(
|
|
59
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
|
|
60
|
+
);
|
|
61
|
+
if (projectAppleProfileCredentials.length !== 0 && !force) {
|
|
62
|
+
this.error("A Mobile Provisioning Profile already exists. Use --force to overwrite it.");
|
|
63
|
+
}
|
|
64
|
+
const createProfile = async () => {
|
|
65
|
+
if (!game.details?.iosBundleId) throw new Error("iosBundleId not found in game details");
|
|
66
|
+
const { iosBundleId } = game.details;
|
|
67
|
+
const { bundleId } = await fetchBundleId({ ctx, iosBundleId });
|
|
68
|
+
if (!bundleId) throw new Error("BundleId not found");
|
|
69
|
+
const appleCerts = await Certificate.getAsync(ctx, {
|
|
70
|
+
query: {
|
|
71
|
+
filter: {
|
|
72
|
+
certificateType: [CertificateType.DISTRIBUTION, CertificateType.IOS_DISTRIBUTION]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const userCerts = await getUserCredentials();
|
|
77
|
+
const validCert = userCerts.find(
|
|
78
|
+
(cred) => cred.platform === Platform.IOS && cred.type === CredentialsType.CERTIFICATE && cred.isActive == true
|
|
79
|
+
);
|
|
80
|
+
const validAppleCert = appleCerts.find(
|
|
81
|
+
(cert) => validCert && cert.attributes.serialNumber === validCert.serialNumber
|
|
82
|
+
);
|
|
83
|
+
if (!validCert || !validAppleCert)
|
|
84
|
+
throw new Error(
|
|
85
|
+
'No usable iOS Distribution Certificate found. Please run "shipthis apple certificate create" first.'
|
|
86
|
+
);
|
|
87
|
+
const profile = await Profile.createAsync(ctx, {
|
|
88
|
+
bundleId: bundleId.id,
|
|
89
|
+
certificates: [validAppleCert.id],
|
|
90
|
+
devices: [],
|
|
91
|
+
name: `ShipThis Profile for ${iosBundleId}`,
|
|
92
|
+
profileType: ProfileType.IOS_APP_STORE
|
|
93
|
+
});
|
|
94
|
+
const { data: contents } = await axios({
|
|
95
|
+
method: "get",
|
|
96
|
+
url: validCert.url
|
|
97
|
+
});
|
|
98
|
+
const userCertContent = contents;
|
|
99
|
+
const projectCertContent = {
|
|
100
|
+
...userCertContent,
|
|
101
|
+
mobileProvisionBase64: `${profile.attributes.profileContent}`
|
|
102
|
+
};
|
|
103
|
+
await uploadProjectCredentials(game.id, {
|
|
104
|
+
contents: projectCertContent,
|
|
105
|
+
platform: Platform.IOS,
|
|
106
|
+
type: CredentialsType.CERTIFICATE,
|
|
107
|
+
serialNumber: validCert.serialNumber,
|
|
108
|
+
identifier: iosBundleId
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const handleComplete = async () => {
|
|
112
|
+
await this.config.runCommand("game:ios:profile:status", ["--gameId", game.id]);
|
|
113
|
+
};
|
|
114
|
+
if (this.flags.quiet) return await createProfile();
|
|
115
|
+
render(
|
|
116
|
+
/* @__PURE__ */ jsx(Command, { command: this, children: /* @__PURE__ */ jsx(
|
|
117
|
+
RunWithSpinner,
|
|
118
|
+
{
|
|
119
|
+
msgInProgress: "Creating Mobile Provisioning Profile in the Apple Developer Portal",
|
|
120
|
+
msgComplete: "Mobile Provisioning Profile created",
|
|
121
|
+
executeMethod: createProfile,
|
|
122
|
+
onComplete: handleComplete
|
|
123
|
+
}
|
|
124
|
+
) })
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { GameIosProfileCreate as default };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import { c as BaseGameCommand, P as Platform, C as CredentialsType } from '../../../../index-DkNQs11R.js';
|
|
6
|
+
import { a as getProjectCredentials } from '../../../../index-CIa2EDQ6.js';
|
|
7
|
+
import 'react';
|
|
8
|
+
import '../../../../index-nnzhQ3nY.js';
|
|
9
|
+
import 'ink-spinner';
|
|
10
|
+
import 'axios';
|
|
11
|
+
import 'crypto-js';
|
|
12
|
+
import 'uuid';
|
|
13
|
+
import 'luxon';
|
|
14
|
+
import '@inkjs/ui';
|
|
15
|
+
import '@tanstack/react-query';
|
|
16
|
+
import 'yazl';
|
|
17
|
+
import 'crypto';
|
|
18
|
+
import 'readline-sync';
|
|
19
|
+
import 'node:readline';
|
|
20
|
+
import 'node:path';
|
|
21
|
+
import 'node:url';
|
|
22
|
+
import 'isomorphic-git';
|
|
23
|
+
import 'fast-glob';
|
|
24
|
+
import 'socket.io-client';
|
|
25
|
+
import 'open';
|
|
26
|
+
import 'marked';
|
|
27
|
+
import 'marked-terminal';
|
|
28
|
+
import 'path';
|
|
29
|
+
import 'qrcode';
|
|
30
|
+
import { R as RunWithSpinner } from '../../../../RunWithSpinner-BVXNWGD3.js';
|
|
31
|
+
import 'string-length';
|
|
32
|
+
import 'strip-ansi';
|
|
33
|
+
import { C as Command } from '../../../../Command-B3AmRt2w.js';
|
|
34
|
+
import { e as exportCredential } from '../../../../export-CVs_xoDN.js';
|
|
35
|
+
import '@expo/apple-utils/build/index.js';
|
|
36
|
+
import 'ini';
|
|
37
|
+
import 'deepmerge';
|
|
38
|
+
import '../../../../index-BB00V5oF.js';
|
|
39
|
+
import '../../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
40
|
+
|
|
41
|
+
class GameIosProfileExport extends BaseGameCommand {
|
|
42
|
+
static args = {
|
|
43
|
+
file: Args.string({ description: "Name of the ZIP file to create", required: true })
|
|
44
|
+
};
|
|
45
|
+
static description = "Saves the current Mobile Provisioning Profile to a ZIP file";
|
|
46
|
+
static examples = ["<%= config.bin %> <%= command.id %> userProfile.zip"];
|
|
47
|
+
static flags = {
|
|
48
|
+
gameId: Flags.string({ char: "g", description: "The ID of the game" }),
|
|
49
|
+
force: Flags.boolean({ char: "f", description: "Overwrite the file if it already exists" })
|
|
50
|
+
};
|
|
51
|
+
async run() {
|
|
52
|
+
const { args, flags } = this;
|
|
53
|
+
const { file } = args;
|
|
54
|
+
const { force } = flags;
|
|
55
|
+
const game = await this.getGame();
|
|
56
|
+
const zipAlreadyExists = fs.existsSync(file);
|
|
57
|
+
if (zipAlreadyExists && !force) {
|
|
58
|
+
this.error(`The file ${file} already exists. Use --force to overwrite it.`);
|
|
59
|
+
}
|
|
60
|
+
const projectCredentials = await getProjectCredentials(game.id);
|
|
61
|
+
const userAppleProfileCredentials = projectCredentials.filter(
|
|
62
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
|
|
63
|
+
);
|
|
64
|
+
if (userAppleProfileCredentials.length === 0) {
|
|
65
|
+
this.error("No Mobile Provisioning Profile found which can be exported.");
|
|
66
|
+
}
|
|
67
|
+
const [profile] = userAppleProfileCredentials;
|
|
68
|
+
const handleComplete = async () => process.exit(0);
|
|
69
|
+
render(
|
|
70
|
+
/* @__PURE__ */ jsx(Command, { command: this, children: /* @__PURE__ */ jsx(
|
|
71
|
+
RunWithSpinner,
|
|
72
|
+
{
|
|
73
|
+
msgInProgress: `Exporting Mobile Provisioning Profile to ${file}...`,
|
|
74
|
+
msgComplete: `Mobile Provisioning Profile exported to ${file}`,
|
|
75
|
+
executeMethod: () => exportCredential({ zipPath: file, credentialId: profile.id, projectId: game.id }),
|
|
76
|
+
onComplete: handleComplete
|
|
77
|
+
}
|
|
78
|
+
) })
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { GameIosProfileExport as default };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import { c as BaseGameCommand, P as Platform, C as CredentialsType } from '../../../../index-DkNQs11R.js';
|
|
6
|
+
import { a as getProjectCredentials } from '../../../../index-CIa2EDQ6.js';
|
|
7
|
+
import 'react';
|
|
8
|
+
import '../../../../index-nnzhQ3nY.js';
|
|
9
|
+
import 'ink-spinner';
|
|
10
|
+
import 'axios';
|
|
11
|
+
import 'crypto-js';
|
|
12
|
+
import 'uuid';
|
|
13
|
+
import 'luxon';
|
|
14
|
+
import '@inkjs/ui';
|
|
15
|
+
import '@tanstack/react-query';
|
|
16
|
+
import 'yazl';
|
|
17
|
+
import 'crypto';
|
|
18
|
+
import 'readline-sync';
|
|
19
|
+
import 'node:readline';
|
|
20
|
+
import 'node:path';
|
|
21
|
+
import 'node:url';
|
|
22
|
+
import 'isomorphic-git';
|
|
23
|
+
import 'fast-glob';
|
|
24
|
+
import 'socket.io-client';
|
|
25
|
+
import 'open';
|
|
26
|
+
import 'marked';
|
|
27
|
+
import 'marked-terminal';
|
|
28
|
+
import 'path';
|
|
29
|
+
import 'qrcode';
|
|
30
|
+
import { R as RunWithSpinner } from '../../../../RunWithSpinner-BVXNWGD3.js';
|
|
31
|
+
import 'string-length';
|
|
32
|
+
import 'strip-ansi';
|
|
33
|
+
import { C as Command } from '../../../../Command-B3AmRt2w.js';
|
|
34
|
+
import { i as importCredential } from '../../../../import-Ch5O7xfN.js';
|
|
35
|
+
import '@expo/apple-utils/build/index.js';
|
|
36
|
+
import 'ini';
|
|
37
|
+
import 'deepmerge';
|
|
38
|
+
import '../../../../index-BB00V5oF.js';
|
|
39
|
+
import '../../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
40
|
+
|
|
41
|
+
class GameIosProfileImport extends BaseGameCommand {
|
|
42
|
+
static args = {
|
|
43
|
+
file: Args.string({
|
|
44
|
+
description: "Name of the ZIP file to import (must be in the same format as the export)",
|
|
45
|
+
required: true
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
static description = "Imports an Mobile Provisioning Profile to your ShipThis account";
|
|
49
|
+
static examples = ["<%= config.bin %> <%= command.id %> profile.zip"];
|
|
50
|
+
static flags = {
|
|
51
|
+
gameId: Flags.string({ char: "g", description: "The ID of the game" }),
|
|
52
|
+
force: Flags.boolean({ char: "f" })
|
|
53
|
+
};
|
|
54
|
+
async run() {
|
|
55
|
+
const { args, flags } = this;
|
|
56
|
+
const { file } = args;
|
|
57
|
+
const { force } = flags;
|
|
58
|
+
const game = await this.getGame();
|
|
59
|
+
const zipFound = fs.existsSync(file);
|
|
60
|
+
if (!zipFound) {
|
|
61
|
+
this.error(`The file ${file} does not exist.`);
|
|
62
|
+
}
|
|
63
|
+
const projectCredentials = await getProjectCredentials(game.id);
|
|
64
|
+
const projectAppleProfileCredentials = projectCredentials.filter(
|
|
65
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
|
|
66
|
+
);
|
|
67
|
+
if (projectAppleProfileCredentials.length !== 0 && !force) {
|
|
68
|
+
this.error("A Mobile Provisioning Profile already exists. Use --force to overwrite it.");
|
|
69
|
+
}
|
|
70
|
+
const handleComplete = async () => {
|
|
71
|
+
await this.config.runCommand(`game:ios:profile:status`, ["--noAppleAuth", "--gameId", game.id]);
|
|
72
|
+
};
|
|
73
|
+
render(
|
|
74
|
+
/* @__PURE__ */ jsx(Command, { command: this, children: /* @__PURE__ */ jsx(
|
|
75
|
+
RunWithSpinner,
|
|
76
|
+
{
|
|
77
|
+
msgInProgress: `Importing Mobile Provisioning Profile from ${file}...`,
|
|
78
|
+
msgComplete: `Mobile Provisioning Profile imported from ${file}`,
|
|
79
|
+
executeMethod: () => importCredential({
|
|
80
|
+
zipPath: file,
|
|
81
|
+
type: CredentialsType.CERTIFICATE,
|
|
82
|
+
platform: Platform.IOS,
|
|
83
|
+
projectId: game.id
|
|
84
|
+
}),
|
|
85
|
+
onComplete: handleComplete
|
|
86
|
+
}
|
|
87
|
+
) })
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { GameIosProfileImport as default };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, Text, render } from 'ink';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
import 'react';
|
|
5
|
+
import '../../../../index-nnzhQ3nY.js';
|
|
6
|
+
import { b as getShortDate, n as Profile, o as ProfileType, C as CredentialsType, P as Platform, c as BaseGameCommand } from '../../../../index-DkNQs11R.js';
|
|
7
|
+
import Spinner from 'ink-spinner';
|
|
8
|
+
import 'axios';
|
|
9
|
+
import 'crypto-js';
|
|
10
|
+
import 'uuid';
|
|
11
|
+
import 'fs';
|
|
12
|
+
import { DateTime } from 'luxon';
|
|
13
|
+
import '@inkjs/ui';
|
|
14
|
+
import { useQuery } from '@tanstack/react-query';
|
|
15
|
+
import 'yazl';
|
|
16
|
+
import 'crypto';
|
|
17
|
+
import 'readline-sync';
|
|
18
|
+
import 'node:readline';
|
|
19
|
+
import 'node:path';
|
|
20
|
+
import 'node:url';
|
|
21
|
+
import 'isomorphic-git';
|
|
22
|
+
import 'fast-glob';
|
|
23
|
+
import 'socket.io-client';
|
|
24
|
+
import 'open';
|
|
25
|
+
import 'marked';
|
|
26
|
+
import 'marked-terminal';
|
|
27
|
+
import 'path';
|
|
28
|
+
import 'qrcode';
|
|
29
|
+
import 'string-length';
|
|
30
|
+
import 'strip-ansi';
|
|
31
|
+
import { u as useProjectCredentials } from '../../../../useProjectCredentials-Btnr7WK3.js';
|
|
32
|
+
import { T as Table } from '../../../../Table-CvM6pccN.js';
|
|
33
|
+
import { T as Title } from '../../../../Title-BCQtayg6.js';
|
|
34
|
+
import { N as NextSteps } from '../../../../NextSteps-CK9zHOCt.js';
|
|
35
|
+
import { C as Command } from '../../../../Command-B3AmRt2w.js';
|
|
36
|
+
import { P as ProjectCredentialsTable } from '../../../../ProjectCredentialsTable-CTkP1mvy.js';
|
|
37
|
+
import '../../../../index-BB00V5oF.js';
|
|
38
|
+
import '../../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
39
|
+
import '@expo/apple-utils/build/index.js';
|
|
40
|
+
import 'ini';
|
|
41
|
+
import 'deepmerge';
|
|
42
|
+
|
|
43
|
+
async function queryAppleProfiles({ ctx }) {
|
|
44
|
+
const appleProfiles = await Profile.getAsync(ctx, {
|
|
45
|
+
query: {
|
|
46
|
+
filter: {
|
|
47
|
+
profileType: [ProfileType.IOS_APP_STORE]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return appleProfiles;
|
|
52
|
+
}
|
|
53
|
+
const canAppleProfileBeUsed = (appleProfile, project, projectCredentials) => {
|
|
54
|
+
try {
|
|
55
|
+
if (!appleProfile.isValid) return false;
|
|
56
|
+
const profileBundleId = appleProfile.attributes.bundleId?.attributes.identifier;
|
|
57
|
+
const profileCertificateSerialNumber = appleProfile.attributes.certificates?.[0]?.attributes.serialNumber;
|
|
58
|
+
if (profileBundleId !== project.details?.iosBundleId) return false;
|
|
59
|
+
return projectCredentials.some(
|
|
60
|
+
(credential) => credential.isActive && credential.serialNumber === profileCertificateSerialNumber
|
|
61
|
+
);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.log(e);
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function getAppleProfileSummary(appleProfile, project, projectCredentials) {
|
|
68
|
+
return {
|
|
69
|
+
id: appleProfile.id,
|
|
70
|
+
name: appleProfile.attributes.name,
|
|
71
|
+
platform: appleProfile.attributes.platform,
|
|
72
|
+
expires: getShortDate(DateTime.fromISO(appleProfile.attributes.expirationDate)),
|
|
73
|
+
canBeUsed: canAppleProfileBeUsed(appleProfile, project, projectCredentials)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const useAppleProfiles = (props) => {
|
|
77
|
+
const queryResult = useQuery({
|
|
78
|
+
queryKey: ["appleProfiles"],
|
|
79
|
+
queryFn: () => queryAppleProfiles(props)
|
|
80
|
+
});
|
|
81
|
+
return queryResult;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const AppleProfilesTable = ({ ctx, project, ...boxProps }) => {
|
|
85
|
+
const { data: credentialsResponse } = useProjectCredentials({
|
|
86
|
+
projectId: project.id,
|
|
87
|
+
platform: Platform.IOS,
|
|
88
|
+
type: CredentialsType.CERTIFICATE
|
|
89
|
+
});
|
|
90
|
+
const { data: profiles, isLoading } = useAppleProfiles({ ctx });
|
|
91
|
+
const hasUsable = profiles && credentialsResponse && profiles.some((cert) => canAppleProfileBeUsed(cert, project, credentialsResponse.data));
|
|
92
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, ...boxProps, children: [
|
|
93
|
+
/* @__PURE__ */ jsx(Title, { children: "Mobile Provisioning Profiles in your Apple account" }),
|
|
94
|
+
isLoading && /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
|
|
95
|
+
profiles && credentialsResponse && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
96
|
+
/* @__PURE__ */ jsxs(Box, { marginLeft: 2, marginBottom: 1, flexDirection: "column", children: [
|
|
97
|
+
/* @__PURE__ */ jsx(Text, { children: `You have ${profiles.length} Mobile Provisioning Profiles in your Apple account` }),
|
|
98
|
+
/* @__PURE__ */ jsx(Text, { children: `${hasUsable ? "One" : "None"} of these can be used by ShipThis` })
|
|
99
|
+
] }),
|
|
100
|
+
profiles.length > 0 && /* @__PURE__ */ jsx(Table, { data: profiles.map((cert) => getAppleProfileSummary(cert, project, credentialsResponse.data)) }),
|
|
101
|
+
!hasUsable && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "You do not have a usable Mobile Provisioning Profile. To ship an iOS game, you will need a usable Mobile Provisioning Profile." }) })
|
|
102
|
+
] }),
|
|
103
|
+
profiles && !hasUsable && /* @__PURE__ */ jsx(NextSteps, { steps: ["shipthis game ios profile create"] })
|
|
104
|
+
] });
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
class GameIosProfileStatus extends BaseGameCommand {
|
|
108
|
+
static args = {};
|
|
109
|
+
static description = "Shows the Game iOS Mobile Provisioning Profile Status.";
|
|
110
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
111
|
+
static flags = {
|
|
112
|
+
gameId: Flags.string({ char: "g", description: "The ID of the game" }),
|
|
113
|
+
noAppleAuth: Flags.boolean({ char: "f" })
|
|
114
|
+
};
|
|
115
|
+
async run() {
|
|
116
|
+
const { flags } = this;
|
|
117
|
+
const showApple = !flags.noAppleAuth;
|
|
118
|
+
const game = await this.getGame();
|
|
119
|
+
let ctx = null;
|
|
120
|
+
if (showApple) {
|
|
121
|
+
const authState = await this.refreshAppleAuthState();
|
|
122
|
+
ctx = authState.context;
|
|
123
|
+
}
|
|
124
|
+
render(
|
|
125
|
+
/* @__PURE__ */ jsxs(Command, { command: this, children: [
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
ProjectCredentialsTable,
|
|
128
|
+
{
|
|
129
|
+
credentialTypeName: "Mobile Provisioning Profile",
|
|
130
|
+
queryProps: { platform: Platform.IOS, type: CredentialsType.CERTIFICATE, projectId: game.id }
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
showApple && /* @__PURE__ */ jsx(AppleProfilesTable, { ctx, project: game })
|
|
134
|
+
] })
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export { GameIosProfileStatus as default };
|
|
@@ -0,0 +1,92 @@
|
|
|
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 { c as BaseGameCommand, k as getProjectPlatformProgress, P as Platform, 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 { A as AppleAppDetails, a as AppleBundleIdDetails } from '../../../AppleBundleIdDetails-mPUG2R4N.js';
|
|
25
|
+
import { C as Command } from '../../../Command-B3AmRt2w.js';
|
|
26
|
+
import 'luxon';
|
|
27
|
+
import 'fast-glob';
|
|
28
|
+
import 'socket.io-client';
|
|
29
|
+
import '../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
30
|
+
import '@expo/apple-utils/build/index.js';
|
|
31
|
+
import 'crypto-js';
|
|
32
|
+
import 'crypto';
|
|
33
|
+
import 'readline-sync';
|
|
34
|
+
import 'node:readline';
|
|
35
|
+
import 'node:path';
|
|
36
|
+
import 'node:url';
|
|
37
|
+
import 'isomorphic-git';
|
|
38
|
+
import 'ini';
|
|
39
|
+
import 'deepmerge';
|
|
40
|
+
import '../../../Title-BCQtayg6.js';
|
|
41
|
+
import '../../../useAppleApp-B16WbUxJ.js';
|
|
42
|
+
import '../../../Table-CvM6pccN.js';
|
|
43
|
+
import '../../../useAppleBundleId-DobPATan.js';
|
|
44
|
+
|
|
45
|
+
class GameIosStatus extends BaseGameCommand {
|
|
46
|
+
static args = {};
|
|
47
|
+
static description = "Shows the Game iOS Platform status. If --gameId is not provided it will look in the current directory.";
|
|
48
|
+
static examples = [
|
|
49
|
+
"<%= config.bin %> <%= command.id %>",
|
|
50
|
+
"<%= config.bin %> <%= command.id %> --gameId 0c179fc4"
|
|
51
|
+
];
|
|
52
|
+
static flags = {
|
|
53
|
+
gameId: Flags.string({ char: "g", description: "The ID of the game" })
|
|
54
|
+
};
|
|
55
|
+
async run() {
|
|
56
|
+
const game = await this.getGame();
|
|
57
|
+
const iosPlatformStatus = await getProjectPlatformProgress(game.id, Platform.IOS);
|
|
58
|
+
const gameStatuses = {
|
|
59
|
+
name: game.name,
|
|
60
|
+
id: getShortUUID(game.id),
|
|
61
|
+
createdAt: getShortDate(game.createdAt),
|
|
62
|
+
engine: "Godot"
|
|
63
|
+
};
|
|
64
|
+
const steps = [iosPlatformStatus.hasBundleSet == false && "$ shipthis game ios app create"].filter(
|
|
65
|
+
Boolean
|
|
66
|
+
);
|
|
67
|
+
const progressToStatuses = (progress) => {
|
|
68
|
+
const { platform, ...rest } = progress;
|
|
69
|
+
return makeHumanReadable(rest);
|
|
70
|
+
};
|
|
71
|
+
const authState = await this.refreshAppleAuthState();
|
|
72
|
+
const ctx = authState.context;
|
|
73
|
+
render(
|
|
74
|
+
/* @__PURE__ */ jsxs(Command, { command: this, children: [
|
|
75
|
+
/* @__PURE__ */ jsx(StatusTable, { marginBottom: 1, title: "ShipThis game status", statuses: gameStatuses }),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
StatusTable,
|
|
78
|
+
{
|
|
79
|
+
marginBottom: 1,
|
|
80
|
+
title: "Overall iOS status for game",
|
|
81
|
+
statuses: progressToStatuses(iosPlatformStatus)
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsx(AppleAppDetails, { iosBundleId: game.details?.iosBundleId, ctx }),
|
|
85
|
+
/* @__PURE__ */ jsx(AppleBundleIdDetails, { iosBundleId: game.details?.iosBundleId, ctx }),
|
|
86
|
+
/* @__PURE__ */ jsx(NextSteps, { steps })
|
|
87
|
+
] })
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { GameIosStatus as default };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { B as BaseAuthenticatedCommand, j as isCWDGodotGame, W as WEB_URL, P as Platform, C as CredentialsType } from '../../../index-DkNQs11R.js';
|
|
4
|
+
import 'axios';
|
|
5
|
+
import 'crypto-js';
|
|
6
|
+
import 'uuid';
|
|
7
|
+
import 'fs';
|
|
8
|
+
import 'luxon';
|
|
9
|
+
import { g as getUserCredentials, a as getProjectCredentials } from '../../../index-CIa2EDQ6.js';
|
|
10
|
+
import 'react/jsx-runtime';
|
|
11
|
+
import 'react';
|
|
12
|
+
import 'ink';
|
|
13
|
+
import { g as getRenderedMarkdown } from '../../../index-nnzhQ3nY.js';
|
|
14
|
+
import 'ink-spinner';
|
|
15
|
+
import '@inkjs/ui';
|
|
16
|
+
import '@tanstack/react-query';
|
|
17
|
+
import 'yazl';
|
|
18
|
+
import 'crypto';
|
|
19
|
+
import 'readline-sync';
|
|
20
|
+
import 'node:readline';
|
|
21
|
+
import 'node:path';
|
|
22
|
+
import 'node:url';
|
|
23
|
+
import 'isomorphic-git';
|
|
24
|
+
import 'fast-glob';
|
|
25
|
+
import 'socket.io-client';
|
|
26
|
+
import 'open';
|
|
27
|
+
import 'qrcode';
|
|
28
|
+
import 'string-length';
|
|
29
|
+
import 'strip-ansi';
|
|
30
|
+
import 'path';
|
|
31
|
+
import '@expo/apple-utils/build/index.js';
|
|
32
|
+
import 'ini';
|
|
33
|
+
import 'deepmerge';
|
|
34
|
+
import '../../../index-BB00V5oF.js';
|
|
35
|
+
import '../../../useAndroidServiceAccountTestResult-DcYDam-p.js';
|
|
36
|
+
import 'marked';
|
|
37
|
+
import 'marked-terminal';
|
|
38
|
+
|
|
39
|
+
class GameIosWizard extends BaseAuthenticatedCommand {
|
|
40
|
+
static args = {};
|
|
41
|
+
static description = "Runs all the steps for iOS";
|
|
42
|
+
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
43
|
+
static flags = {
|
|
44
|
+
forceStep: Flags.string({
|
|
45
|
+
char: "f",
|
|
46
|
+
description: "Force a specific step to run."
|
|
47
|
+
})
|
|
48
|
+
};
|
|
49
|
+
async run() {
|
|
50
|
+
const { flags } = this;
|
|
51
|
+
if (!isCWDGodotGame()) {
|
|
52
|
+
this.error(
|
|
53
|
+
"No Godot project detected. Please run this from a Godot project directory with a project.godot file.",
|
|
54
|
+
{ exit: 1 }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const projectConfig = await this.getProjectConfigSafe();
|
|
58
|
+
const game = projectConfig.project;
|
|
59
|
+
const isStepForced = (cmdName) => flags.forceStep?.includes(cmdName);
|
|
60
|
+
const logSkip = (cmdName) => this.log(chalk.blue(`[skip] shipthis ${cmdName.replaceAll(":", " ")}`));
|
|
61
|
+
const logRun = (cmdName, args) => this.log(chalk.green(`[run] shipthis ${cmdName.replaceAll(":", " ")} ${args.join(" ")}`));
|
|
62
|
+
const iosSteps = [
|
|
63
|
+
{
|
|
64
|
+
command: "game:create",
|
|
65
|
+
args: ["--quiet"],
|
|
66
|
+
shouldRun: async () => !game
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
command: "apple:login",
|
|
70
|
+
args: ["--quiet"],
|
|
71
|
+
shouldRun: async () => {
|
|
72
|
+
const isLoggedIn = await this.hasValidAppleAuthState();
|
|
73
|
+
return !isLoggedIn;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
command: "apple:apiKey:create",
|
|
78
|
+
args: ["--quiet"],
|
|
79
|
+
shouldRun: async () => {
|
|
80
|
+
const userCredentials = await getUserCredentials();
|
|
81
|
+
const userAppleApiKeyCredentials = userCredentials.filter(
|
|
82
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.KEY
|
|
83
|
+
);
|
|
84
|
+
const hasKey = userAppleApiKeyCredentials.length > 0;
|
|
85
|
+
return !hasKey;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
command: "apple:certificate:create",
|
|
90
|
+
args: ["--quiet"],
|
|
91
|
+
shouldRun: async () => {
|
|
92
|
+
const userCredentials = await getUserCredentials();
|
|
93
|
+
const userAppleDistCredentials = userCredentials.filter(
|
|
94
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
|
|
95
|
+
);
|
|
96
|
+
const hasDistCert = userAppleDistCredentials.length > 0;
|
|
97
|
+
return !hasDistCert;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
command: "game:ios:app:create",
|
|
102
|
+
args: ["--quiet"],
|
|
103
|
+
shouldRun: async () => {
|
|
104
|
+
if (!game) return true;
|
|
105
|
+
const hasBundleIdSet = !!game.details?.iosBundleId;
|
|
106
|
+
return !hasBundleIdSet;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
command: "game:ios:app:sync",
|
|
111
|
+
args: ["--quiet"],
|
|
112
|
+
// Can always run this
|
|
113
|
+
shouldRun: async () => true
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
command: "game:ios:profile:create",
|
|
117
|
+
args: ["--quiet"],
|
|
118
|
+
shouldRun: async () => {
|
|
119
|
+
if (!game) return true;
|
|
120
|
+
const projectCredentials = await getProjectCredentials(game.id);
|
|
121
|
+
const projectAppleProfileCredentials = projectCredentials.filter(
|
|
122
|
+
(cred) => cred.platform == Platform.IOS && cred.type == CredentialsType.CERTIFICATE
|
|
123
|
+
);
|
|
124
|
+
const hasProfile = projectAppleProfileCredentials.length > 0;
|
|
125
|
+
return !hasProfile;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
];
|
|
129
|
+
for (const step of iosSteps) {
|
|
130
|
+
const command = step.command;
|
|
131
|
+
const willRun = isStepForced(command) || await step.shouldRun();
|
|
132
|
+
if (!willRun) {
|
|
133
|
+
logSkip(command);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const args = [...step.args, ...isStepForced(command) ? ["--force"] : []];
|
|
137
|
+
logRun(command, args);
|
|
138
|
+
await this.config.runCommand(command, args);
|
|
139
|
+
}
|
|
140
|
+
const successMessage = getRenderedMarkdown({
|
|
141
|
+
filename: "ios-success.md",
|
|
142
|
+
templateVars: {
|
|
143
|
+
androidSetupURL: new URL("/docs/android", WEB_URL).toString(),
|
|
144
|
+
docsURL: new URL("/docs", WEB_URL).toString()
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
this.log(`
|
|
148
|
+
${successMessage}
|
|
149
|
+
`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export { GameIosWizard as default };
|