shipthis 0.1.30 → 0.1.32
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/README.md +122 -41
- package/assets/markdown/create-google-play-game.md +2 -4
- package/assets/markdown/ship-success.md +1 -1
- package/dist/{AppleBundleIdDetails-Fp5COwTa.js → AppleBundleIdDetails-6H3cNWxw.js} +17 -19
- package/dist/{Command-1p5alCz3.js → Command-WPpmLPkL.js} +13 -12
- package/dist/CommandGame-cxzWG4nT.js +7 -0
- package/dist/{Create-1xAdntNl.js → Create-3Ob8sjik.js} +20 -20
- package/dist/GameStatus-BQEtVKvv.js +137 -0
- package/dist/{Import-CzC-M4ln.js → Import-CFuPDI0K.js} +33 -35
- package/dist/{JobLogTail-CZxoMSd5.js → JobLogTail-0CBLoG8N.js} +53 -52
- package/dist/{JobProgress-BjNgtIjm.js → JobProgress-lKqVT88m.js} +46 -37
- package/dist/{JobStatusTable-BB-PWlwj.js → JobStatusTable-C_ZsZJCm.js} +14 -13
- package/dist/{NextSteps-CK9zHOCt.js → NextSteps-DbJHmscQ.js} +1 -3
- package/dist/{ProgressSpinner-6pw1T8Iw.js → ProgressSpinner-DGcakQSK.js} +1 -1
- package/dist/{ProjectCredentialsTable-DyZep993.js → ProjectCredentialsTable-B5pHOnGu.js} +11 -10
- package/dist/{StatusTable-Dm5St4g-.js → StatusTable-DzRWcMr4.js} +7 -9
- package/dist/{Table-CvM6pccN.js → Table-FaNgpyeq.js} +15 -15
- package/dist/{UserCredentialsTable-BraKyDWT.js → UserCredentialsTable-3W3qesh7.js} +18 -19
- package/dist/{baseAppleCommand-BHRIBtTj.js → baseAppleCommand-BGV088--.js} +1 -1
- package/dist/{baseGameAndroidCommand-SrDRbhAG.js → baseGameAndroidCommand-CsemgVjp.js} +23 -23
- package/dist/commands/apple/apiKey/create.js +35 -35
- package/dist/commands/apple/apiKey/export.js +26 -26
- package/dist/commands/apple/apiKey/import.js +27 -27
- package/dist/commands/apple/apiKey/status.js +31 -31
- package/dist/commands/apple/certificate/create.js +39 -39
- package/dist/commands/apple/certificate/export.js +26 -26
- package/dist/commands/apple/certificate/import.js +27 -27
- package/dist/commands/apple/certificate/status.js +31 -31
- package/dist/commands/apple/login.js +15 -15
- package/dist/commands/apple/status.js +28 -28
- package/dist/commands/dashboard.js +10 -10
- package/dist/commands/game/android/apiKey/connect.js +28 -28
- package/dist/commands/game/android/apiKey/create.js +28 -28
- package/dist/commands/game/android/apiKey/export.js +29 -29
- package/dist/commands/game/android/apiKey/import.js +31 -31
- package/dist/commands/game/android/apiKey/invite.js +14 -14
- package/dist/commands/game/android/apiKey/status.js +29 -29
- package/dist/commands/game/android/keyStore/create.js +24 -24
- package/dist/commands/game/android/keyStore/export.js +28 -28
- package/dist/commands/game/android/keyStore/import.js +35 -35
- package/dist/commands/game/android/keyStore/status.js +26 -26
- package/dist/commands/game/android/status.js +14 -58
- package/dist/commands/game/build/download.js +24 -24
- package/dist/commands/game/build/list.js +37 -37
- package/dist/commands/game/create.js +15 -15
- package/dist/commands/game/details.js +35 -36
- package/dist/commands/game/export.js +12 -12
- package/dist/commands/game/ios/app/addTester.js +24 -24
- package/dist/commands/game/ios/app/create.js +24 -24
- package/dist/commands/game/ios/app/status.js +29 -29
- package/dist/commands/game/ios/app/sync.js +31 -31
- package/dist/commands/game/ios/profile/create.js +30 -30
- package/dist/commands/game/ios/profile/export.js +28 -28
- package/dist/commands/game/ios/profile/import.js +32 -32
- package/dist/commands/game/ios/profile/status.js +36 -36
- package/dist/commands/game/ios/status.js +46 -58
- package/dist/commands/game/ios/wizard.js +31 -31
- package/dist/commands/game/job/list.js +34 -34
- package/dist/commands/game/job/status.js +31 -31
- package/dist/commands/game/list.js +45 -41
- package/dist/commands/game/ship.js +73 -70
- package/dist/commands/game/status.js +38 -82
- package/dist/commands/game/wizard.js +271 -307
- package/dist/commands/internal/fastlane.js +15 -17
- package/dist/commands/internal/readme.js +38 -36
- package/dist/commands/login.js +14 -14
- package/dist/commands/status.js +35 -33
- package/dist/{export-BKn02-NH.js → export-CXsVPXA1.js} +5 -5
- package/dist/{git-DREGq-jc.js → git-BpsfNFZ_.js} +8 -8
- package/dist/{import-CRMaNBVF.js → import-DGvG5REx.js} +14 -14
- package/dist/{index-DxzXU9Hd.js → index-BhhiXbey.js} +244 -221
- package/dist/{index-OZi8bvu8.js → index-C03TV1_J.js} +54 -38
- package/dist/{index-BTAL7EB_.js → index-C66Dd8Xc.js} +80 -79
- package/dist/{index-35Eswf6F.js → index-CGBdOm1q.js} +43 -27
- package/dist/{index--EbYyBAZ.js → index-CS9Gwcb0.js} +41 -43
- package/dist/{index-u1aj1OQW.js → index-CtTI85m-.js} +6 -6
- package/dist/{upload-Bw0zrS4M.js → upload-8y5MQEm9.js} +22 -22
- package/dist/{useAndroidServiceAccountTestResult-CJLIEYmA.js → useAndroidServiceAccountTestResult-DZk5SMxI.js} +11 -13
- package/dist/{useAppleApp-cnb8gX0x.js → useAppleApp-DWYGURwU.js} +4 -4
- package/dist/{useAppleBundleId-B0Etav8g.js → useAppleBundleId-PsTJ2g1B.js} +6 -6
- package/dist/{useProjectCredentials-DX3e_PPc.js → useProjectCredentials-BEphqa18.js} +10 -12
- package/dist/{useWebSocket-BOCa8v6o.js → useWebSocket-5PYa2QER.js} +1 -1
- package/dist/utils/help.js +4 -4
- package/package.json +4 -2
- package/dist/CommandGame-Z4eUQBjn.js +0 -9
- package/dist/{RunWithSpinner-BVXNWGD3.js → RunWithSpinner-gMVA07bZ.js} +2 -2
|
@@ -1,44 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import fs__default from 'fs';
|
|
4
|
-
import { Command, Flags } from '@oclif/core';
|
|
5
|
-
import * as expo from '@expo/apple-utils/build/index.js';
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import fs__default from 'node:fs';
|
|
6
3
|
import axios from 'axios';
|
|
7
4
|
import CryptoJS from 'crypto-js';
|
|
8
5
|
import { v4 } from 'uuid';
|
|
9
6
|
import { DateTime } from 'luxon';
|
|
10
|
-
import '
|
|
11
|
-
import '
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { Command, Flags } from '@oclif/core';
|
|
9
|
+
import * as expo from '@expo/apple-utils/build/index.js';
|
|
10
|
+
import 'node:crypto';
|
|
12
11
|
import 'node:readline';
|
|
13
|
-
import 'node:path';
|
|
14
12
|
import 'node:url';
|
|
13
|
+
import 'readline-sync';
|
|
15
14
|
import 'isomorphic-git';
|
|
16
|
-
import { parse } from 'ini';
|
|
17
15
|
import merge from 'deepmerge';
|
|
18
|
-
import '
|
|
16
|
+
import { parse } from 'ini';
|
|
19
17
|
import { QueryClient } from '@tanstack/react-query';
|
|
18
|
+
import 'react';
|
|
20
19
|
import 'fast-glob';
|
|
21
20
|
import 'yazl';
|
|
22
21
|
import 'socket.io-client';
|
|
22
|
+
import 'fullscreen-ink';
|
|
23
23
|
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
ApiKey,
|
|
27
|
-
ApiKeyType,
|
|
28
|
-
App,
|
|
29
|
-
Auth,
|
|
30
|
-
BundleId,
|
|
31
|
-
CapabilityType,
|
|
32
|
-
CapabilityTypeOption,
|
|
33
|
-
Certificate,
|
|
34
|
-
CertificateType,
|
|
35
|
-
Profile,
|
|
36
|
-
ProfileType,
|
|
37
|
-
Session,
|
|
38
|
-
UserRole,
|
|
39
|
-
BetaGroup
|
|
40
|
-
} = defaultExport;
|
|
41
|
-
|
|
24
|
+
const AUTH_ENV_VAR_NAME = "SHIPTHIS_TOKEN";
|
|
25
|
+
const DOMAIN_ENV_VAR_NAME = "SHIPTHIS_DOMAIN";
|
|
42
26
|
const DEFAULT_SHIPPED_FILES_GLOBS = ["**/*"];
|
|
43
27
|
const DEFAULT_IGNORED_FILES_GLOBS = [
|
|
44
28
|
".git",
|
|
@@ -62,11 +46,10 @@ function getUrlsForDomain(domain) {
|
|
|
62
46
|
const wsDomain = (isPublic ? `ws.` : "") + domain;
|
|
63
47
|
return {
|
|
64
48
|
api: `https://${apiDomain}/api/1.0.0`,
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
web: `https://${domain}/`,
|
|
50
|
+
ws: `wss://${wsDomain}`
|
|
67
51
|
};
|
|
68
52
|
}
|
|
69
|
-
const DOMAIN_ENV_VAR_NAME = "SHIPTHIS_DOMAIN";
|
|
70
53
|
const DOMAIN = process.env[DOMAIN_ENV_VAR_NAME] || PRIMARY_DOMAIN;
|
|
71
54
|
const BACKEND_URLS = getUrlsForDomain(DOMAIN);
|
|
72
55
|
const API_URL = BACKEND_URLS.api;
|
|
@@ -93,15 +76,15 @@ function castJobDates(jobObject) {
|
|
|
93
76
|
return castObjectDates(jobObject);
|
|
94
77
|
}
|
|
95
78
|
function getDateLocale() {
|
|
96
|
-
const fallback = Intl.DateTimeFormat().resolvedOptions().locale.
|
|
79
|
+
const fallback = Intl.DateTimeFormat().resolvedOptions().locale.replaceAll("_", "-") || DEFAULT_LOCALE;
|
|
97
80
|
try {
|
|
98
|
-
const env = process
|
|
81
|
+
const { env } = process;
|
|
99
82
|
const fullLocale = env.LC_TIME || env.LANG || env.LANGUAGE || env.LC_ALL || env.LC_MESSAGES;
|
|
100
|
-
const shortLocale = fullLocale?.split(".")[0].
|
|
83
|
+
const shortLocale = fullLocale?.split(".")[0].replaceAll("_", "-");
|
|
101
84
|
const finalLocal = shortLocale || fallback;
|
|
102
85
|
const _ = DateTime.now().toLocaleString(DateTime.DATE_SHORT, { locale: finalLocal });
|
|
103
86
|
return finalLocal;
|
|
104
|
-
} catch
|
|
87
|
+
} catch {
|
|
105
88
|
return fallback;
|
|
106
89
|
}
|
|
107
90
|
}
|
|
@@ -126,16 +109,16 @@ function getShortTimeDelta(start, end) {
|
|
|
126
109
|
});
|
|
127
110
|
}
|
|
128
111
|
|
|
129
|
-
|
|
112
|
+
var currentAuthToken;
|
|
130
113
|
function setAuthToken(token) {
|
|
131
|
-
|
|
114
|
+
currentAuthToken = token;
|
|
132
115
|
}
|
|
133
116
|
function getAuthToken() {
|
|
134
|
-
return
|
|
117
|
+
return currentAuthToken;
|
|
135
118
|
}
|
|
136
119
|
function getAuthedHeaders() {
|
|
137
120
|
return {
|
|
138
|
-
Authorization: `Bearer ${
|
|
121
|
+
Authorization: `Bearer ${currentAuthToken}`
|
|
139
122
|
};
|
|
140
123
|
}
|
|
141
124
|
async function createProject(props) {
|
|
@@ -214,9 +197,9 @@ async function getShortAuthRequiredUrl(destination) {
|
|
|
214
197
|
const fullKey = `${key}${salt}`;
|
|
215
198
|
const token = CryptoJS.AES.encrypt(email, fullKey).toString();
|
|
216
199
|
const params = {
|
|
200
|
+
destination,
|
|
217
201
|
key,
|
|
218
|
-
token
|
|
219
|
-
destination
|
|
202
|
+
token
|
|
220
203
|
};
|
|
221
204
|
const queryString = Object.entries(params).map(([key2, value]) => `${key2}=${encodeURIComponent(`${value}`)}`).join("&");
|
|
222
205
|
const url = `${WEB_URL}login/?${queryString}`;
|
|
@@ -286,12 +269,12 @@ async function inviteServiceAccount(projectId, developerId) {
|
|
|
286
269
|
}
|
|
287
270
|
async function downloadBuildById(projectId, buildId, fileName) {
|
|
288
271
|
const build = await getBuild(projectId, buildId);
|
|
289
|
-
const url = build
|
|
272
|
+
const { url } = build;
|
|
290
273
|
const writer = fs.createWriteStream(fileName);
|
|
291
274
|
const response = await axios({
|
|
292
|
-
url,
|
|
293
275
|
method: "GET",
|
|
294
|
-
responseType: "stream"
|
|
276
|
+
responseType: "stream",
|
|
277
|
+
url
|
|
295
278
|
});
|
|
296
279
|
response.data.pipe(writer);
|
|
297
280
|
return new Promise((resolve, reject) => {
|
|
@@ -300,9 +283,27 @@ async function downloadBuildById(projectId, buildId, fileName) {
|
|
|
300
283
|
});
|
|
301
284
|
}
|
|
302
285
|
|
|
286
|
+
const defaultExport = expo.default;
|
|
287
|
+
const {
|
|
288
|
+
ApiKey,
|
|
289
|
+
ApiKeyType,
|
|
290
|
+
App,
|
|
291
|
+
Auth,
|
|
292
|
+
BetaGroup,
|
|
293
|
+
BundleId,
|
|
294
|
+
CapabilityType,
|
|
295
|
+
CapabilityTypeOption,
|
|
296
|
+
Certificate,
|
|
297
|
+
CertificateType,
|
|
298
|
+
Profile,
|
|
299
|
+
ProfileType,
|
|
300
|
+
Session,
|
|
301
|
+
UserRole
|
|
302
|
+
} = defaultExport;
|
|
303
|
+
|
|
303
304
|
var Platform = /* @__PURE__ */ ((Platform2) => {
|
|
304
|
-
Platform2["IOS"] = "IOS";
|
|
305
305
|
Platform2["ANDROID"] = "ANDROID";
|
|
306
|
+
Platform2["IOS"] = "IOS";
|
|
306
307
|
return Platform2;
|
|
307
308
|
})(Platform || {});
|
|
308
309
|
var GameEngine = /* @__PURE__ */ ((GameEngine2) => {
|
|
@@ -310,24 +311,24 @@ var GameEngine = /* @__PURE__ */ ((GameEngine2) => {
|
|
|
310
311
|
return GameEngine2;
|
|
311
312
|
})(GameEngine || {});
|
|
312
313
|
var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
|
|
313
|
-
JobStatus2["PENDING"] = "PENDING";
|
|
314
|
-
JobStatus2["PROCESSING"] = "PROCESSING";
|
|
315
314
|
JobStatus2["COMPLETED"] = "COMPLETED";
|
|
316
315
|
JobStatus2["FAILED"] = "FAILED";
|
|
316
|
+
JobStatus2["PENDING"] = "PENDING";
|
|
317
|
+
JobStatus2["PROCESSING"] = "PROCESSING";
|
|
317
318
|
return JobStatus2;
|
|
318
319
|
})(JobStatus || {});
|
|
319
320
|
var JobStage = /* @__PURE__ */ ((JobStage2) => {
|
|
320
|
-
JobStage2["SETUP"] = "SETUP";
|
|
321
|
-
JobStage2["EXPORT"] = "EXPORT";
|
|
322
|
-
JobStage2["CONFIGURE"] = "CONFIGURE";
|
|
323
321
|
JobStage2["BUILD"] = "BUILD";
|
|
322
|
+
JobStage2["CONFIGURE"] = "CONFIGURE";
|
|
323
|
+
JobStage2["EXPORT"] = "EXPORT";
|
|
324
324
|
JobStage2["PUBLISH"] = "PUBLISH";
|
|
325
|
+
JobStage2["SETUP"] = "SETUP";
|
|
325
326
|
return JobStage2;
|
|
326
327
|
})(JobStage || {});
|
|
327
328
|
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
329
|
+
LogLevel2["ERROR"] = "ERROR";
|
|
328
330
|
LogLevel2["INFO"] = "INFO";
|
|
329
331
|
LogLevel2["WARN"] = "WARN";
|
|
330
|
-
LogLevel2["ERROR"] = "ERROR";
|
|
331
332
|
return LogLevel2;
|
|
332
333
|
})(LogLevel || {});
|
|
333
334
|
var CredentialsType = /* @__PURE__ */ ((CredentialsType2) => {
|
|
@@ -335,6 +336,12 @@ var CredentialsType = /* @__PURE__ */ ((CredentialsType2) => {
|
|
|
335
336
|
CredentialsType2["KEY"] = "KEY";
|
|
336
337
|
return CredentialsType2;
|
|
337
338
|
})(CredentialsType || {});
|
|
339
|
+
var BuildType = /* @__PURE__ */ ((BuildType2) => {
|
|
340
|
+
BuildType2["AAB"] = "AAB";
|
|
341
|
+
BuildType2["APK"] = "APK";
|
|
342
|
+
BuildType2["IPA"] = "IPA";
|
|
343
|
+
return BuildType2;
|
|
344
|
+
})(BuildType || {});
|
|
338
345
|
|
|
339
346
|
function isCWDGodotGame() {
|
|
340
347
|
const cwd = process.cwd();
|
|
@@ -343,12 +350,12 @@ function isCWDGodotGame() {
|
|
|
343
350
|
}
|
|
344
351
|
const GODOT_CAPABILITIES = [
|
|
345
352
|
// TODO: how about capabilities from godot extensions
|
|
346
|
-
{
|
|
347
|
-
{
|
|
353
|
+
{ key: "capabilities/access_wifi", name: "Access WiFi", type: CapabilityType.ACCESS_WIFI },
|
|
354
|
+
{ key: "capabilities/push_notifications", name: "Push Notifications", type: CapabilityType.PUSH_NOTIFICATIONS }
|
|
348
355
|
];
|
|
349
356
|
function getGodotProjectCapabilities(platform) {
|
|
350
357
|
const exportPresets = getGodotExportPresets(platform);
|
|
351
|
-
const options = exportPresets
|
|
358
|
+
const { options } = exportPresets;
|
|
352
359
|
const capabilities = [];
|
|
353
360
|
for (const capability of GODOT_CAPABILITIES) {
|
|
354
361
|
if (!(capability.key in options)) continue;
|
|
@@ -365,8 +372,8 @@ function getGodotProjectConfig() {
|
|
|
365
372
|
function getGodotProjectName() {
|
|
366
373
|
try {
|
|
367
374
|
const projectGodotConfig = getGodotProjectConfig();
|
|
368
|
-
return projectGodotConfig
|
|
369
|
-
} catch
|
|
375
|
+
return projectGodotConfig.application["config/name"];
|
|
376
|
+
} catch {
|
|
370
377
|
return null;
|
|
371
378
|
}
|
|
372
379
|
}
|
|
@@ -374,8 +381,8 @@ function getGodotAppleBundleIdentifier() {
|
|
|
374
381
|
try {
|
|
375
382
|
const preset = getGodotExportPresets(Platform.IOS);
|
|
376
383
|
return preset.options["application/bundle_identifier"];
|
|
377
|
-
} catch (
|
|
378
|
-
console.log(
|
|
384
|
+
} catch (error) {
|
|
385
|
+
console.log(error);
|
|
379
386
|
return null;
|
|
380
387
|
}
|
|
381
388
|
}
|
|
@@ -383,15 +390,15 @@ function getGodotAndroidPackageName() {
|
|
|
383
390
|
try {
|
|
384
391
|
const preset = getGodotExportPresets(Platform.ANDROID);
|
|
385
392
|
return preset.options["package/unique_name"];
|
|
386
|
-
} catch (
|
|
387
|
-
console.log(
|
|
393
|
+
} catch (error) {
|
|
394
|
+
console.log(error);
|
|
388
395
|
return null;
|
|
389
396
|
}
|
|
390
397
|
}
|
|
391
398
|
function getGodotVersion() {
|
|
392
399
|
const projectGodotConfig = getGodotProjectConfig();
|
|
393
|
-
if ("config/features" in projectGodotConfig
|
|
394
|
-
const features = projectGodotConfig
|
|
400
|
+
if ("config/features" in projectGodotConfig.application) {
|
|
401
|
+
const features = projectGodotConfig.application["config/features"];
|
|
395
402
|
const match = features.match(/"(\d+\.\d+)"/);
|
|
396
403
|
if (!match) throw new Error("Couldn't find Godot version in project.godot");
|
|
397
404
|
return match[1];
|
|
@@ -405,9 +412,7 @@ function getGodotExportPresets(platform) {
|
|
|
405
412
|
const filename = "export_presets.cfg";
|
|
406
413
|
const exportPresetsPath = path.join(cwd, filename);
|
|
407
414
|
const isFound = fs__default.existsSync(exportPresetsPath);
|
|
408
|
-
if (
|
|
409
|
-
warn(`${filename} not found at ${exportPresetsPath}`);
|
|
410
|
-
} else {
|
|
415
|
+
if (isFound) {
|
|
411
416
|
const exportPresetsContent = fs__default.readFileSync(exportPresetsPath, "utf8");
|
|
412
417
|
const exportPresetsIni = parse(exportPresetsContent);
|
|
413
418
|
const presetIndexes = Object.keys(exportPresetsIni.preset);
|
|
@@ -415,89 +420,91 @@ function getGodotExportPresets(platform) {
|
|
|
415
420
|
const current = exportPresetsIni.preset[index];
|
|
416
421
|
return `${current.name}`.toUpperCase() === platform;
|
|
417
422
|
});
|
|
418
|
-
if (
|
|
419
|
-
warn(`Preset ${platform} not found in ${filename} - will use defaults`);
|
|
420
|
-
} else {
|
|
423
|
+
if (presetIndex) {
|
|
421
424
|
presetConfig = merge(presetConfig, exportPresetsIni.preset[presetIndex]);
|
|
425
|
+
} else {
|
|
426
|
+
warn(`Preset ${platform} not found in ${filename} - will use defaults`);
|
|
422
427
|
}
|
|
428
|
+
} else {
|
|
429
|
+
warn(`${filename} not found at ${exportPresetsPath}`);
|
|
423
430
|
}
|
|
424
431
|
return presetConfig;
|
|
425
432
|
}
|
|
426
433
|
function getBaseExportPresets_iOS() {
|
|
427
434
|
return {
|
|
428
|
-
name: "iOS",
|
|
429
|
-
platform: "iOS",
|
|
430
|
-
runnable: true,
|
|
431
|
-
dedicated_server: false,
|
|
432
435
|
custom_features: "",
|
|
433
|
-
|
|
434
|
-
|
|
436
|
+
dedicated_server: false,
|
|
437
|
+
encrypt_directory: false,
|
|
438
|
+
encrypt_pck: false,
|
|
439
|
+
encryption_exclude_filters: "",
|
|
440
|
+
encryption_include_filters: "",
|
|
435
441
|
exclude_filter: "",
|
|
442
|
+
export_filter: "all_resources",
|
|
436
443
|
export_path: "output",
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
encrypt_pck: false,
|
|
440
|
-
encrypt_directory: false,
|
|
444
|
+
include_filter: "",
|
|
445
|
+
name: "iOS",
|
|
441
446
|
options: {
|
|
442
|
-
"
|
|
443
|
-
"custom_template/release": "",
|
|
444
|
-
"architectures/arm64": true,
|
|
445
|
-
"application/signature": "",
|
|
447
|
+
"application/export_project_only": true,
|
|
446
448
|
"application/icon_interpolation": "4",
|
|
447
449
|
"application/launch_screens_interpolation": "4",
|
|
448
|
-
"application/
|
|
450
|
+
"application/short_version": "1.0.0",
|
|
451
|
+
// default version number
|
|
452
|
+
"application/signature": "",
|
|
453
|
+
"architectures/arm64": true,
|
|
449
454
|
"capabilities/access_wifi": false,
|
|
450
455
|
"capabilities/push_notifications": false,
|
|
451
|
-
"
|
|
452
|
-
"
|
|
453
|
-
"
|
|
454
|
-
"privacy/camera_usage_description_localized": "{}",
|
|
455
|
-
"privacy/microphone_usage_description": "",
|
|
456
|
-
"privacy/microphone_usage_description_localized": "{}",
|
|
457
|
-
"privacy/photolibrary_usage_description": "",
|
|
458
|
-
"privacy/photolibrary_usage_description_localized": "{}",
|
|
459
|
-
"icons/iphone_120x120": "",
|
|
460
|
-
"icons/iphone_180x180": "",
|
|
456
|
+
"custom_template/debug": "",
|
|
457
|
+
"custom_template/release": "",
|
|
458
|
+
"icons/app_store_1024x1024": "",
|
|
461
459
|
"icons/ipad_76x76": "",
|
|
462
460
|
"icons/ipad_152x152": "",
|
|
463
461
|
"icons/ipad_167x167": "",
|
|
464
|
-
"icons/
|
|
465
|
-
"icons/
|
|
466
|
-
"icons/spotlight_80x80": "",
|
|
467
|
-
"icons/settings_58x58": "",
|
|
468
|
-
"icons/settings_87x87": "",
|
|
462
|
+
"icons/iphone_120x120": "",
|
|
463
|
+
"icons/iphone_180x180": "",
|
|
469
464
|
"icons/notification_40x40": "",
|
|
470
465
|
"icons/notification_60x60": "",
|
|
471
|
-
"
|
|
472
|
-
"
|
|
473
|
-
"
|
|
474
|
-
"
|
|
475
|
-
"storyboard/use_custom_bg_color": false,
|
|
476
|
-
"storyboard/custom_bg_color": "Color(0, 0, 0, 1)",
|
|
477
|
-
"landscape_launch_screens/iphone_2436x1125": "",
|
|
478
|
-
"landscape_launch_screens/iphone_2208x1242": "",
|
|
466
|
+
"icons/settings_58x58": "",
|
|
467
|
+
"icons/settings_87x87": "",
|
|
468
|
+
"icons/spotlight_40x40": "",
|
|
469
|
+
"icons/spotlight_80x80": "",
|
|
479
470
|
"landscape_launch_screens/ipad_1024x768": "",
|
|
480
471
|
"landscape_launch_screens/ipad_2048x1536": "",
|
|
472
|
+
"landscape_launch_screens/iphone_2208x1242": "",
|
|
473
|
+
"landscape_launch_screens/iphone_2436x1125": "",
|
|
474
|
+
"portrait_launch_screens/ipad_768x1024": "",
|
|
475
|
+
"portrait_launch_screens/ipad_1536x2048": "",
|
|
481
476
|
"portrait_launch_screens/iphone_640x960": "",
|
|
482
477
|
"portrait_launch_screens/iphone_640x1136": "",
|
|
483
478
|
"portrait_launch_screens/iphone_750x1334": "",
|
|
484
479
|
"portrait_launch_screens/iphone_1125x2436": "",
|
|
485
|
-
"portrait_launch_screens/ipad_768x1024": "",
|
|
486
|
-
"portrait_launch_screens/ipad_1536x2048": "",
|
|
487
480
|
"portrait_launch_screens/iphone_1242x2208": "",
|
|
488
|
-
"
|
|
489
|
-
|
|
490
|
-
|
|
481
|
+
"privacy/camera_usage_description": "",
|
|
482
|
+
"privacy/camera_usage_description_localized": "{}",
|
|
483
|
+
"privacy/microphone_usage_description": "",
|
|
484
|
+
"privacy/microphone_usage_description_localized": "{}",
|
|
485
|
+
"privacy/photolibrary_usage_description": "",
|
|
486
|
+
"privacy/photolibrary_usage_description_localized": "{}",
|
|
487
|
+
"storyboard/custom_bg_color": "Color(0, 0, 0, 1)",
|
|
488
|
+
"storyboard/custom_image@2x": "",
|
|
489
|
+
"storyboard/custom_image@3x": "",
|
|
490
|
+
"storyboard/image_scale_mode": "0",
|
|
491
|
+
"storyboard/use_custom_bg_color": false,
|
|
492
|
+
"storyboard/use_launch_screen_storyboard": true,
|
|
493
|
+
"user_data/accessible_from_files_app": false,
|
|
494
|
+
"user_data/accessible_from_itunes_sharing": false
|
|
495
|
+
},
|
|
496
|
+
platform: "iOS",
|
|
497
|
+
runnable: true
|
|
491
498
|
};
|
|
492
499
|
}
|
|
493
500
|
function getBaseExportPresets_Android() {
|
|
494
501
|
return {
|
|
495
502
|
name: "Android",
|
|
496
|
-
platform: "Android",
|
|
497
503
|
// TODO
|
|
498
504
|
options: {
|
|
499
505
|
// TODO
|
|
500
|
-
}
|
|
506
|
+
},
|
|
507
|
+
platform: "Android"
|
|
501
508
|
};
|
|
502
509
|
}
|
|
503
510
|
|
|
@@ -510,103 +517,138 @@ const queryClient = new QueryClient({
|
|
|
510
517
|
});
|
|
511
518
|
|
|
512
519
|
class BaseCommand extends Command {
|
|
513
|
-
// add the --json flag
|
|
514
|
-
static enableJsonFlag = false;
|
|
515
520
|
// define flags that can be inherited by any command that extends BaseCommand
|
|
516
521
|
static baseFlags = {};
|
|
517
|
-
|
|
522
|
+
// add the --json flag
|
|
523
|
+
static enableJsonFlag = false;
|
|
518
524
|
args;
|
|
519
|
-
|
|
520
|
-
process.on("SIGINT", () => process.exit(0));
|
|
521
|
-
process.on("SIGTERM", () => process.exit(0));
|
|
522
|
-
await super.init();
|
|
523
|
-
const { args, flags } = await this.parse({
|
|
524
|
-
flags: this.ctor.flags,
|
|
525
|
-
baseFlags: super.ctor.baseFlags,
|
|
526
|
-
enableJsonFlag: this.ctor.enableJsonFlag,
|
|
527
|
-
args: this.ctor.args,
|
|
528
|
-
strict: this.ctor.strict
|
|
529
|
-
});
|
|
530
|
-
this.flags = flags;
|
|
531
|
-
this.args = args;
|
|
532
|
-
if (this.hasAuthConfig()) await this.loadAuthConfig();
|
|
533
|
-
}
|
|
525
|
+
flags;
|
|
534
526
|
async catch(err) {
|
|
535
527
|
return super.catch(err);
|
|
536
528
|
}
|
|
537
|
-
|
|
538
|
-
|
|
529
|
+
// Used in baseGameCommand and the other commands that need to ensure that the CWD is a Godot project
|
|
530
|
+
ensureWeAreInAProjectDir() {
|
|
531
|
+
if (!isCWDGodotGame()) {
|
|
532
|
+
this.error("No Godot project detected. Please run this from a godot project directory.", { exit: 1 });
|
|
533
|
+
}
|
|
534
|
+
if (!this.hasProjectConfig()) {
|
|
535
|
+
this.error(
|
|
536
|
+
'No ShipThis config found. Please run `shipthis game create --name "Space Invaders"` to create a game.',
|
|
537
|
+
{ exit: 1 }
|
|
538
|
+
);
|
|
539
|
+
}
|
|
539
540
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
541
|
+
ensureWeHaveAppleCookies() {
|
|
542
|
+
if (!this.hasAuthConfigFile()) {
|
|
543
|
+
this.error("You must be authenticated with Apple in to use this command. Please run shipthis apple login", {
|
|
544
|
+
exit: 1
|
|
545
|
+
});
|
|
546
|
+
}
|
|
543
547
|
}
|
|
544
|
-
|
|
545
|
-
return
|
|
548
|
+
async finally(_) {
|
|
549
|
+
return super.finally(_);
|
|
546
550
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
551
|
+
// Used in the apple commands to get the cookies from the auth file
|
|
552
|
+
async getAppleCookies() {
|
|
553
|
+
const authConfig = await this.getAuthConfig();
|
|
554
|
+
if (!authConfig.appleCookies) return null;
|
|
555
|
+
return authConfig.appleCookies;
|
|
550
556
|
}
|
|
557
|
+
// Returns the current auth config - prefers to use the env var
|
|
551
558
|
async getAuthConfig() {
|
|
559
|
+
const envVarValue = process.env[AUTH_ENV_VAR_NAME];
|
|
560
|
+
if (!envVarValue) return await this.getAuthConfigFromFile();
|
|
561
|
+
setAuthToken(envVarValue);
|
|
562
|
+
const self = await getSelf();
|
|
563
|
+
const selfWithJwt = {
|
|
564
|
+
...self,
|
|
565
|
+
jwt: envVarValue
|
|
566
|
+
};
|
|
567
|
+
return {
|
|
568
|
+
shipThisUser: selfWithJwt
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
// Loads the auth config from the file system
|
|
572
|
+
async getAuthConfigFromFile() {
|
|
552
573
|
const baseConfig = {};
|
|
553
574
|
const configPath = this.getAuthConfigPath();
|
|
554
575
|
if (!fs__default.existsSync(configPath)) return baseConfig;
|
|
555
576
|
const raw = await fs__default.promises.readFile(configPath, "utf8");
|
|
556
|
-
const
|
|
577
|
+
const parsed = JSON.parse(raw);
|
|
578
|
+
if (parsed.shipThisUser) {
|
|
579
|
+
setAuthToken(parsed.shipThisUser.jwt);
|
|
580
|
+
}
|
|
557
581
|
return {
|
|
558
582
|
...baseConfig,
|
|
559
|
-
...
|
|
583
|
+
...parsed
|
|
560
584
|
};
|
|
561
585
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (!authConfig.shipThisUser) {
|
|
569
|
-
throw new Error("You must be logged in to use this command");
|
|
586
|
+
// This is used to expose the flags to the Android Wizard
|
|
587
|
+
getDetailsFlagsValues() {
|
|
588
|
+
const keys = Object.keys(DetailsFlags);
|
|
589
|
+
const values = {};
|
|
590
|
+
for (const key of keys) {
|
|
591
|
+
if (this.flags[key]) values[key] = this.flags[key];
|
|
570
592
|
}
|
|
571
|
-
|
|
593
|
+
return values;
|
|
572
594
|
}
|
|
573
|
-
|
|
574
|
-
|
|
595
|
+
// Exposing it to the react components using the CommandContext
|
|
596
|
+
getFlags() {
|
|
597
|
+
return this.flags;
|
|
575
598
|
}
|
|
576
|
-
|
|
577
|
-
const
|
|
578
|
-
return
|
|
599
|
+
getGameId() {
|
|
600
|
+
const { flags } = this;
|
|
601
|
+
if (flags.gameId) return flags.gameId;
|
|
602
|
+
const { project } = this.getProjectConfigSafe();
|
|
603
|
+
if (!project) return null;
|
|
604
|
+
return project.id;
|
|
579
605
|
}
|
|
580
606
|
async getProjectConfig() {
|
|
581
607
|
if (!this.hasProjectConfig()) throw new Error("No project config found");
|
|
582
608
|
return this.getProjectConfigSafe();
|
|
583
609
|
}
|
|
584
|
-
|
|
610
|
+
getProjectConfigSafe() {
|
|
585
611
|
if (!this.hasProjectConfig()) return {};
|
|
586
612
|
const configPath = this.getProjectConfigPath();
|
|
587
|
-
const raw =
|
|
613
|
+
const raw = fs__default.readFileSync(configPath, "utf8");
|
|
588
614
|
return JSON.parse(raw);
|
|
589
615
|
}
|
|
590
|
-
|
|
591
|
-
const configPath = this.
|
|
592
|
-
|
|
616
|
+
hasAuthConfigFile() {
|
|
617
|
+
const configPath = this.getAuthConfigPath();
|
|
618
|
+
return fs__default.existsSync(configPath);
|
|
593
619
|
}
|
|
594
|
-
|
|
595
|
-
const
|
|
596
|
-
|
|
620
|
+
hasProjectConfig() {
|
|
621
|
+
const configPath = this.getProjectConfigPath();
|
|
622
|
+
return fs__default.existsSync(configPath);
|
|
597
623
|
}
|
|
598
|
-
//
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
this.
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
'No ShipThis config found. Please run `shipthis game create --name "Space Invaders"` to create a game.',
|
|
606
|
-
{ exit: 1 }
|
|
607
|
-
);
|
|
624
|
+
// Tests the apple cookies
|
|
625
|
+
async hasValidAppleAuthState() {
|
|
626
|
+
try {
|
|
627
|
+
await this.refreshAppleAuthState();
|
|
628
|
+
return true;
|
|
629
|
+
} catch {
|
|
630
|
+
return false;
|
|
608
631
|
}
|
|
609
632
|
}
|
|
633
|
+
async init() {
|
|
634
|
+
process.on("SIGINT", () => process.exit(0));
|
|
635
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
636
|
+
await super.init();
|
|
637
|
+
const { args, flags } = await this.parse({
|
|
638
|
+
args: this.ctor.args,
|
|
639
|
+
baseFlags: super.ctor.baseFlags,
|
|
640
|
+
enableJsonFlag: this.ctor.enableJsonFlag,
|
|
641
|
+
flags: this.ctor.flags,
|
|
642
|
+
strict: this.ctor.strict
|
|
643
|
+
});
|
|
644
|
+
this.flags = flags;
|
|
645
|
+
this.args = args;
|
|
646
|
+
await this.getAuthConfig();
|
|
647
|
+
}
|
|
648
|
+
async isAuthenticated() {
|
|
649
|
+
const authConfig = await this.getAuthConfig();
|
|
650
|
+
return Boolean(authConfig.shipThisUser?.jwt);
|
|
651
|
+
}
|
|
610
652
|
async refreshAppleAuthState() {
|
|
611
653
|
const cookies = await this.getAppleCookies();
|
|
612
654
|
const rerunMessage = "Please run shipthis apple login to authenticate with Apple.";
|
|
@@ -620,48 +662,29 @@ class BaseCommand extends Command {
|
|
|
620
662
|
if (!authState) throw new Error(`Failed to refresh Apple auth state. ${rerunMessage}`);
|
|
621
663
|
return authState;
|
|
622
664
|
}
|
|
623
|
-
// Tests the apple cookies
|
|
624
|
-
async hasValidAppleAuthState() {
|
|
625
|
-
try {
|
|
626
|
-
await this.refreshAppleAuthState();
|
|
627
|
-
return true;
|
|
628
|
-
} catch (e) {
|
|
629
|
-
return false;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
// Used in the apple commands to get the cookies from the auth file
|
|
633
|
-
async getAppleCookies() {
|
|
634
|
-
const authConfig = await this.getAuthConfig();
|
|
635
|
-
if (!authConfig.appleCookies) return null;
|
|
636
|
-
return authConfig.appleCookies;
|
|
637
|
-
}
|
|
638
665
|
async setAppleCookies(cookies) {
|
|
639
666
|
const authConfig = await this.getAuthConfig();
|
|
640
667
|
await this.setAuthConfig({ ...authConfig, appleCookies: cookies });
|
|
641
668
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
669
|
+
// This is called after login to persist the JWT and user details
|
|
670
|
+
async setAuthConfig(config) {
|
|
671
|
+
const configPath = this.getAuthConfigPath();
|
|
672
|
+
await fs__default.promises.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
673
|
+
}
|
|
674
|
+
async setProjectConfig(config) {
|
|
675
|
+
const configPath = this.getProjectConfigPath();
|
|
676
|
+
await fs__default.promises.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
677
|
+
}
|
|
678
|
+
async updateProjectConfig(update) {
|
|
679
|
+
const config = await this.getProjectConfig();
|
|
680
|
+
await this.setProjectConfig({ ...config, ...update });
|
|
648
681
|
}
|
|
649
682
|
// Returns the values of the flags in DetailsFlags
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const keys = Object.keys(DetailsFlags);
|
|
653
|
-
const values = {};
|
|
654
|
-
for (const key of keys) {
|
|
655
|
-
if (this.flags[key]) values[key] = this.flags[key];
|
|
656
|
-
}
|
|
657
|
-
return values;
|
|
683
|
+
getAuthConfigPath() {
|
|
684
|
+
return path.join(this.config.home, ".shipthis.auth.json");
|
|
658
685
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
if (flags.gameId) return flags.gameId;
|
|
662
|
-
const { project } = await this.getProjectConfigSafe();
|
|
663
|
-
if (!project) return null;
|
|
664
|
-
return project.id;
|
|
686
|
+
getProjectConfigPath() {
|
|
687
|
+
return path.join(process.cwd(), "shipthis.json");
|
|
665
688
|
}
|
|
666
689
|
}
|
|
667
690
|
|
|
@@ -669,11 +692,11 @@ class BaseAuthenticatedCommand extends BaseCommand {
|
|
|
669
692
|
static flags = {};
|
|
670
693
|
async init() {
|
|
671
694
|
await super.init();
|
|
672
|
-
if (!this.
|
|
695
|
+
if (!this.isAuthenticated()) {
|
|
673
696
|
this.error("No auth config found. Please run `shipthis login` to authenticate.", { exit: 1 });
|
|
674
697
|
}
|
|
675
698
|
const self = await getSelf();
|
|
676
|
-
const accepted =
|
|
699
|
+
const accepted = Boolean(self.details?.hasAcceptedTerms);
|
|
677
700
|
if (!accepted) {
|
|
678
701
|
this.error("You must accept the terms and conditions. Please run `shipthis login --force` to re-authenticate", {
|
|
679
702
|
exit: 1
|
|
@@ -692,10 +715,10 @@ class BaseGameCommand extends BaseAuthenticatedCommand {
|
|
|
692
715
|
const gameId = await this.getGameId();
|
|
693
716
|
if (!gameId) this.error("No game ID found.");
|
|
694
717
|
return await getProject(gameId);
|
|
695
|
-
} catch (
|
|
696
|
-
if (
|
|
718
|
+
} catch (error) {
|
|
719
|
+
if (error?.response?.status === 404) {
|
|
697
720
|
this.error("Game not found - please check you have access");
|
|
698
|
-
} else throw
|
|
721
|
+
} else throw error;
|
|
699
722
|
}
|
|
700
723
|
}
|
|
701
724
|
async updateGame(update) {
|
|
@@ -711,15 +734,15 @@ class BaseGameCommand extends BaseAuthenticatedCommand {
|
|
|
711
734
|
}
|
|
712
735
|
|
|
713
736
|
const DetailsFlags = {
|
|
714
|
-
|
|
737
|
+
androidPackageName: Flags.string({ char: "a", description: "Set the Android package name" }),
|
|
715
738
|
buildNumber: Flags.integer({ char: "b", description: "Set the build number" }),
|
|
716
|
-
semanticVersion: Flags.string({ char: "s", description: "Set the semantic version" }),
|
|
717
739
|
gameEngine: Flags.string({ char: "e", description: "Set the game engine" }),
|
|
718
740
|
gameEngineVersion: Flags.string({ char: "v", description: "Set the game engine version" }),
|
|
719
|
-
iosBundleId: Flags.string({ char: "i", description: "Set the iOS bundle ID" }),
|
|
720
|
-
androidPackageName: Flags.string({ char: "a", description: "Set the Android package name" }),
|
|
721
741
|
gcpProjectId: Flags.string({ char: "g", description: "Set the GCP project ID" }),
|
|
722
|
-
gcpServiceAccountId: Flags.string({ char: "c", description: "Set the GCP service account ID" })
|
|
742
|
+
gcpServiceAccountId: Flags.string({ char: "c", description: "Set the GCP service account ID" }),
|
|
743
|
+
iosBundleId: Flags.string({ char: "i", description: "Set the iOS bundle ID" }),
|
|
744
|
+
name: Flags.string({ char: "n", description: "The name of the game" }),
|
|
745
|
+
semanticVersion: Flags.string({ char: "s", description: "Set the semantic version" })
|
|
723
746
|
};
|
|
724
747
|
|
|
725
|
-
export { getNewUploadTicket as $, ApiKey as A, BaseAuthenticatedCommand as B, CredentialsType as C, DetailsFlags as D,
|
|
748
|
+
export { getNewUploadTicket as $, ApiKey as A, BaseAuthenticatedCommand as B, CredentialsType as C, DetailsFlags as D, getProject as E, getProjectPlatformProgress as F, GODOT_CAPABILITIES as G, downloadBuildById as H, castArrayObjectDates as I, JobStatus as J, queryClient as K, JobStage as L, LogLevel as M, WS_URL as N, getAuthToken as O, Platform as P, getGoogleStatus as Q, getGodotAndroidPackageName as R, inviteServiceAccount as S, disconnectGoogle as T, UserRole as U, BaseCommand as V, WEB_URL as W, getSingleUseUrl as X, setAuthToken as Y, acceptTerms as Z, Auth as _, ApiKeyType as a, startJobsFromUpload as a0, castObjectDates as a1, getShortAuthRequiredUrl as a2, getGoogleAuthUrl as a3, castJobDates as a4, getShortTime as a5, getShortDateTime as a6, getShortTimeDelta as a7, BuildType as a8, updateProject as a9, getShortDate as b, BaseGameCommand as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, BetaGroup as i, isCWDGodotGame as j, Certificate as k, CertificateType as l, Profile as m, ProfileType as n, API_URL as o, getAuthedHeaders as p, getGodotProjectCapabilities as q, CapabilityType as r, GameEngine as s, getGodotVersion as t, createProject as u, DEFAULT_SHIPPED_FILES_GLOBS as v, DEFAULT_IGNORED_FILES_GLOBS as w, getGodotProjectName as x, getProjectJobs as y, getJob as z };
|