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.
Files changed (86) hide show
  1. package/README.md +122 -41
  2. package/assets/markdown/create-google-play-game.md +2 -4
  3. package/assets/markdown/ship-success.md +1 -1
  4. package/dist/{AppleBundleIdDetails-Fp5COwTa.js → AppleBundleIdDetails-6H3cNWxw.js} +17 -19
  5. package/dist/{Command-1p5alCz3.js → Command-WPpmLPkL.js} +13 -12
  6. package/dist/CommandGame-cxzWG4nT.js +7 -0
  7. package/dist/{Create-1xAdntNl.js → Create-3Ob8sjik.js} +20 -20
  8. package/dist/GameStatus-BQEtVKvv.js +137 -0
  9. package/dist/{Import-CzC-M4ln.js → Import-CFuPDI0K.js} +33 -35
  10. package/dist/{JobLogTail-CZxoMSd5.js → JobLogTail-0CBLoG8N.js} +53 -52
  11. package/dist/{JobProgress-BjNgtIjm.js → JobProgress-lKqVT88m.js} +46 -37
  12. package/dist/{JobStatusTable-BB-PWlwj.js → JobStatusTable-C_ZsZJCm.js} +14 -13
  13. package/dist/{NextSteps-CK9zHOCt.js → NextSteps-DbJHmscQ.js} +1 -3
  14. package/dist/{ProgressSpinner-6pw1T8Iw.js → ProgressSpinner-DGcakQSK.js} +1 -1
  15. package/dist/{ProjectCredentialsTable-DyZep993.js → ProjectCredentialsTable-B5pHOnGu.js} +11 -10
  16. package/dist/{StatusTable-Dm5St4g-.js → StatusTable-DzRWcMr4.js} +7 -9
  17. package/dist/{Table-CvM6pccN.js → Table-FaNgpyeq.js} +15 -15
  18. package/dist/{UserCredentialsTable-BraKyDWT.js → UserCredentialsTable-3W3qesh7.js} +18 -19
  19. package/dist/{baseAppleCommand-BHRIBtTj.js → baseAppleCommand-BGV088--.js} +1 -1
  20. package/dist/{baseGameAndroidCommand-SrDRbhAG.js → baseGameAndroidCommand-CsemgVjp.js} +23 -23
  21. package/dist/commands/apple/apiKey/create.js +35 -35
  22. package/dist/commands/apple/apiKey/export.js +26 -26
  23. package/dist/commands/apple/apiKey/import.js +27 -27
  24. package/dist/commands/apple/apiKey/status.js +31 -31
  25. package/dist/commands/apple/certificate/create.js +39 -39
  26. package/dist/commands/apple/certificate/export.js +26 -26
  27. package/dist/commands/apple/certificate/import.js +27 -27
  28. package/dist/commands/apple/certificate/status.js +31 -31
  29. package/dist/commands/apple/login.js +15 -15
  30. package/dist/commands/apple/status.js +28 -28
  31. package/dist/commands/dashboard.js +10 -10
  32. package/dist/commands/game/android/apiKey/connect.js +28 -28
  33. package/dist/commands/game/android/apiKey/create.js +28 -28
  34. package/dist/commands/game/android/apiKey/export.js +29 -29
  35. package/dist/commands/game/android/apiKey/import.js +31 -31
  36. package/dist/commands/game/android/apiKey/invite.js +14 -14
  37. package/dist/commands/game/android/apiKey/status.js +29 -29
  38. package/dist/commands/game/android/keyStore/create.js +24 -24
  39. package/dist/commands/game/android/keyStore/export.js +28 -28
  40. package/dist/commands/game/android/keyStore/import.js +35 -35
  41. package/dist/commands/game/android/keyStore/status.js +26 -26
  42. package/dist/commands/game/android/status.js +14 -58
  43. package/dist/commands/game/build/download.js +24 -24
  44. package/dist/commands/game/build/list.js +37 -37
  45. package/dist/commands/game/create.js +15 -15
  46. package/dist/commands/game/details.js +35 -36
  47. package/dist/commands/game/export.js +12 -12
  48. package/dist/commands/game/ios/app/addTester.js +24 -24
  49. package/dist/commands/game/ios/app/create.js +24 -24
  50. package/dist/commands/game/ios/app/status.js +29 -29
  51. package/dist/commands/game/ios/app/sync.js +31 -31
  52. package/dist/commands/game/ios/profile/create.js +30 -30
  53. package/dist/commands/game/ios/profile/export.js +28 -28
  54. package/dist/commands/game/ios/profile/import.js +32 -32
  55. package/dist/commands/game/ios/profile/status.js +36 -36
  56. package/dist/commands/game/ios/status.js +46 -58
  57. package/dist/commands/game/ios/wizard.js +31 -31
  58. package/dist/commands/game/job/list.js +34 -34
  59. package/dist/commands/game/job/status.js +31 -31
  60. package/dist/commands/game/list.js +45 -41
  61. package/dist/commands/game/ship.js +73 -70
  62. package/dist/commands/game/status.js +38 -82
  63. package/dist/commands/game/wizard.js +271 -307
  64. package/dist/commands/internal/fastlane.js +15 -17
  65. package/dist/commands/internal/readme.js +38 -36
  66. package/dist/commands/login.js +14 -14
  67. package/dist/commands/status.js +35 -33
  68. package/dist/{export-BKn02-NH.js → export-CXsVPXA1.js} +5 -5
  69. package/dist/{git-DREGq-jc.js → git-BpsfNFZ_.js} +8 -8
  70. package/dist/{import-CRMaNBVF.js → import-DGvG5REx.js} +14 -14
  71. package/dist/{index-DxzXU9Hd.js → index-BhhiXbey.js} +244 -221
  72. package/dist/{index-OZi8bvu8.js → index-C03TV1_J.js} +54 -38
  73. package/dist/{index-BTAL7EB_.js → index-C66Dd8Xc.js} +80 -79
  74. package/dist/{index-35Eswf6F.js → index-CGBdOm1q.js} +43 -27
  75. package/dist/{index--EbYyBAZ.js → index-CS9Gwcb0.js} +41 -43
  76. package/dist/{index-u1aj1OQW.js → index-CtTI85m-.js} +6 -6
  77. package/dist/{upload-Bw0zrS4M.js → upload-8y5MQEm9.js} +22 -22
  78. package/dist/{useAndroidServiceAccountTestResult-CJLIEYmA.js → useAndroidServiceAccountTestResult-DZk5SMxI.js} +11 -13
  79. package/dist/{useAppleApp-cnb8gX0x.js → useAppleApp-DWYGURwU.js} +4 -4
  80. package/dist/{useAppleBundleId-B0Etav8g.js → useAppleBundleId-PsTJ2g1B.js} +6 -6
  81. package/dist/{useProjectCredentials-DX3e_PPc.js → useProjectCredentials-BEphqa18.js} +10 -12
  82. package/dist/{useWebSocket-BOCa8v6o.js → useWebSocket-5PYa2QER.js} +1 -1
  83. package/dist/utils/help.js +4 -4
  84. package/package.json +4 -2
  85. package/dist/CommandGame-Z4eUQBjn.js +0 -9
  86. package/dist/{RunWithSpinner-BVXNWGD3.js → RunWithSpinner-gMVA07bZ.js} +2 -2
@@ -1,44 +1,28 @@
1
- import path from 'path';
2
- import * as fs from 'fs';
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 'crypto';
11
- import 'readline-sync';
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 'react';
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 defaultExport = expo.default;
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
- ws: `wss://${wsDomain}`,
66
- web: `https://${domain}/`
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.replace(/_/g, "-") || DEFAULT_LOCALE;
79
+ const fallback = Intl.DateTimeFormat().resolvedOptions().locale.replaceAll("_", "-") || DEFAULT_LOCALE;
97
80
  try {
98
- const env = process.env;
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].replace(/_/g, "-");
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 (e) {
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
- const AUTH_ENV_VAR_NAME = "SHIPTHIS_TOKEN";
112
+ var currentAuthToken;
130
113
  function setAuthToken(token) {
131
- process.env[AUTH_ENV_VAR_NAME] = token;
114
+ currentAuthToken = token;
132
115
  }
133
116
  function getAuthToken() {
134
- return process.env[AUTH_ENV_VAR_NAME];
117
+ return currentAuthToken;
135
118
  }
136
119
  function getAuthedHeaders() {
137
120
  return {
138
- Authorization: `Bearer ${process.env[AUTH_ENV_VAR_NAME]}`
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.url;
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
- { name: "Access WiFi", key: "capabilities/access_wifi", type: CapabilityType.ACCESS_WIFI },
347
- { name: "Push Notifications", key: "capabilities/push_notifications", type: CapabilityType.PUSH_NOTIFICATIONS }
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.options;
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["application"]["config/name"];
369
- } catch (e) {
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 (e) {
378
- console.log(e);
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 (e) {
387
- console.log(e);
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["application"]) {
394
- const features = projectGodotConfig["application"]["config/features"];
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 (!isFound) {
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 (!presetIndex) {
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
- export_filter: "all_resources",
434
- include_filter: "",
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
- encryption_include_filters: "",
438
- encryption_exclude_filters: "",
439
- encrypt_pck: false,
440
- encrypt_directory: false,
444
+ include_filter: "",
445
+ name: "iOS",
441
446
  options: {
442
- "custom_template/debug": "",
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/export_project_only": true,
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
- "user_data/accessible_from_files_app": false,
452
- "user_data/accessible_from_itunes_sharing": false,
453
- "privacy/camera_usage_description": "",
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/app_store_1024x1024": "",
465
- "icons/spotlight_40x40": "",
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
- "storyboard/use_launch_screen_storyboard": true,
472
- "storyboard/image_scale_mode": "0",
473
- "storyboard/custom_image@2x": "",
474
- "storyboard/custom_image@3x": "",
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
- "application/short_version": "1.0.0"
489
- // default version number
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
- flags;
522
+ // add the --json flag
523
+ static enableJsonFlag = false;
518
524
  args;
519
- async init() {
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
- async finally(_) {
538
- return super.finally(_);
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
- // Exposing it to the react components using the CommandContext
541
- getFlags() {
542
- return this.flags;
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
- getAuthConfigPath() {
545
- return path.join(this.config.home, ".shipthis.auth.json");
548
+ async finally(_) {
549
+ return super.finally(_);
546
550
  }
547
- hasAuthConfig() {
548
- const configPath = this.getAuthConfigPath();
549
- return fs__default.existsSync(configPath);
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 typesConfig = JSON.parse(raw);
577
+ const parsed = JSON.parse(raw);
578
+ if (parsed.shipThisUser) {
579
+ setAuthToken(parsed.shipThisUser.jwt);
580
+ }
557
581
  return {
558
582
  ...baseConfig,
559
- ...typesConfig
583
+ ...parsed
560
584
  };
561
585
  }
562
- async setAuthConfig(config) {
563
- const configPath = this.getAuthConfigPath();
564
- await fs__default.promises.writeFile(configPath, JSON.stringify(config, null, 2));
565
- }
566
- async loadAuthConfig() {
567
- const authConfig = await this.getAuthConfig();
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
- setAuthToken(authConfig.shipThisUser.jwt);
593
+ return values;
572
594
  }
573
- getProjectConfigPath() {
574
- return path.join(process.cwd(), "shipthis.json");
595
+ // Exposing it to the react components using the CommandContext
596
+ getFlags() {
597
+ return this.flags;
575
598
  }
576
- hasProjectConfig() {
577
- const configPath = this.getProjectConfigPath();
578
- return fs__default.existsSync(configPath);
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
- async getProjectConfigSafe() {
610
+ getProjectConfigSafe() {
585
611
  if (!this.hasProjectConfig()) return {};
586
612
  const configPath = this.getProjectConfigPath();
587
- const raw = await fs__default.promises.readFile(configPath, "utf8");
613
+ const raw = fs__default.readFileSync(configPath, "utf8");
588
614
  return JSON.parse(raw);
589
615
  }
590
- async setProjectConfig(config) {
591
- const configPath = this.getProjectConfigPath();
592
- await fs__default.promises.writeFile(configPath, JSON.stringify(config, null, 2));
616
+ hasAuthConfigFile() {
617
+ const configPath = this.getAuthConfigPath();
618
+ return fs__default.existsSync(configPath);
593
619
  }
594
- async updateProjectConfig(update) {
595
- const config = await this.getProjectConfig();
596
- await this.setProjectConfig({ ...config, ...update });
620
+ hasProjectConfig() {
621
+ const configPath = this.getProjectConfigPath();
622
+ return fs__default.existsSync(configPath);
597
623
  }
598
- // Used in baseGameCommand and the other commands that need to ensure that the CWD is a Godot project
599
- ensureWeAreInAProjectDir() {
600
- if (!isCWDGodotGame()) {
601
- this.error("No Godot project detected. Please run this from a godot project directory.", { exit: 1 });
602
- }
603
- if (!this.hasProjectConfig()) {
604
- this.error(
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
- ensureWeHaveAppleCookies() {
643
- if (!this.hasAuthConfig()) {
644
- this.error("You must be authenticated with Apple in to use this command. Please run shipthis apple login", {
645
- exit: 1
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
- // This is used to expose the flags to the Android Wizard
651
- getDetailsFlagsValues() {
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
- async getGameId() {
660
- const { flags } = this;
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.hasAuthConfig()) {
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 = !!self.details?.hasAcceptedTerms;
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 (e) {
696
- if (e?.response?.status === 404) {
718
+ } catch (error) {
719
+ if (error?.response?.status === 404) {
697
720
  this.error("Game not found - please check you have access");
698
- } else throw e;
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
- name: Flags.string({ char: "n", description: "The name of the game" }),
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, getJob as E, getProject as F, GODOT_CAPABILITIES as G, downloadBuildById as H, castArrayObjectDates as I, JobStatus as J, queryClient as K, JobStage as L, LogLevel as M, getAuthToken as N, WS_URL as O, Platform as P, getGodotAndroidPackageName as Q, getGoogleStatus 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, updateProject as a8, 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, getProjectPlatformProgress as k, Certificate as l, CertificateType as m, Profile as n, ProfileType as o, getAuthedHeaders as p, API_URL as q, getGodotProjectCapabilities as r, CapabilityType as s, GameEngine as t, getGodotVersion as u, createProject as v, DEFAULT_IGNORED_FILES_GLOBS as w, DEFAULT_SHIPPED_FILES_GLOBS as x, getGodotProjectName as y, getProjectJobs as z };
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 };