shipthis 0.1.39 → 0.1.42
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 +58 -0
- package/assets/markdown/confirm-change-android-build-method.md.ejs +13 -0
- package/dist/{AppleBundleIdDetails-Ck7iAjMb.js → AppleBundleIdDetails-jDq3gYbk.js} +7 -5
- package/dist/{Command-C84QiOWP.js → Command-cVo97lkQ.js} +2 -1
- package/dist/{CommandGame-CsM9GE5Q.js → CommandGame-BwudtYCO.js} +2 -2
- package/dist/{Create-Dx1nEKmS.js → Create-By4NsPEI.js} +3 -1
- package/dist/{GameStatus-B4WBgoLs.js → GameStatus-C59zQE1H.js} +3 -1
- package/dist/{Import-BC5XgwRT.js → Import-DTcVM-T-.js} +4 -2
- package/dist/{JobLogTail-mBXpeWMu.js → JobLogTail-BzisGkY8.js} +30 -16
- package/dist/{JobProgress-KZ6EkMFi.js → JobProgress-DAnhaTho.js} +21 -9
- package/dist/{JobStatusTable-BYIxTt0d.js → JobStatusTable-BYEi8dtD.js} +3 -2
- package/dist/{ProjectCredentialsTable-DSy1YIWX.js → ProjectCredentialsTable-NZf3V39z.js} +2 -2
- package/dist/{UserCredentialsTable-qNByRE84.js → UserCredentialsTable-Dp884nYO.js} +2 -1
- package/dist/{baseAppleCommand-CdROzhyU.js → baseAppleCommand-DewNWX3L.js} +1 -1
- package/dist/baseCommand-CscxrTMI.js +757 -0
- package/dist/{baseGameAndroidCommand-B21zS0MN.js → baseGameAndroidCommand-CEcDz5P2.js} +4 -2
- package/dist/{index-Cv-92xRd.js → baseGameCommand-BKvHM3h_.js} +19 -755
- package/dist/commands/apiKey/create.js +7 -7
- package/dist/commands/apiKey/list.js +7 -7
- package/dist/commands/apiKey/revoke.js +7 -7
- package/dist/commands/apple/apiKey/create.js +14 -14
- package/dist/commands/apple/apiKey/delete.js +8 -8
- package/dist/commands/apple/apiKey/export.js +14 -14
- package/dist/commands/apple/apiKey/import.js +14 -14
- package/dist/commands/apple/apiKey/status.js +13 -13
- package/dist/commands/apple/certificate/create.js +14 -14
- package/dist/commands/apple/certificate/delete.js +8 -8
- package/dist/commands/apple/certificate/export.js +14 -14
- package/dist/commands/apple/certificate/import.js +14 -14
- package/dist/commands/apple/certificate/status.js +13 -13
- package/dist/commands/apple/login.js +5 -5
- package/dist/commands/apple/status.js +13 -13
- package/dist/commands/dashboard.js +8 -8
- package/dist/commands/game/android/apiKey/connect.js +12 -12
- package/dist/commands/game/android/apiKey/create.js +14 -14
- package/dist/commands/game/android/apiKey/delete.js +7 -7
- package/dist/commands/game/android/apiKey/export.js +14 -14
- package/dist/commands/game/android/apiKey/import.js +14 -14
- package/dist/commands/game/android/apiKey/invite.js +20 -20
- package/dist/commands/game/android/apiKey/policy.js +9 -9
- package/dist/commands/game/android/apiKey/status.js +14 -14
- package/dist/commands/game/android/keyStore/create.js +11 -11
- package/dist/commands/game/android/keyStore/delete.js +7 -7
- package/dist/commands/game/android/keyStore/export.js +13 -13
- package/dist/commands/game/android/keyStore/import.js +16 -16
- package/dist/commands/game/android/keyStore/status.js +16 -16
- package/dist/commands/game/android/status.js +6 -6
- package/dist/commands/game/build/download.js +7 -7
- package/dist/commands/game/build/list.js +12 -12
- package/dist/commands/game/create.js +5 -5
- package/dist/commands/game/details.js +16 -13
- package/dist/commands/game/export.js +5 -5
- package/dist/commands/game/ios/app/addTester.js +9 -9
- package/dist/commands/game/ios/app/create.js +10 -9
- package/dist/commands/game/ios/app/status.js +14 -14
- package/dist/commands/game/ios/app/sync.js +12 -12
- package/dist/commands/game/ios/profile/create.js +10 -10
- package/dist/commands/game/ios/profile/delete.js +8 -8
- package/dist/commands/game/ios/profile/export.js +13 -13
- package/dist/commands/game/ios/profile/import.js +13 -13
- package/dist/commands/game/ios/profile/status.js +14 -14
- package/dist/commands/game/ios/status.js +18 -18
- package/dist/commands/game/ios/wizard.js +8 -8
- package/dist/commands/game/job/list.js +7 -7
- package/dist/commands/game/job/status.js +14 -14
- package/dist/commands/game/list.js +7 -7
- package/dist/commands/game/ship.js +30 -13
- package/dist/commands/game/status.js +14 -14
- package/dist/commands/game/wizard.js +87 -37
- package/dist/commands/internal/fastlane.js +13 -13
- package/dist/commands/internal/readme.js +17 -17
- package/dist/commands/login.js +21 -21
- package/dist/commands/status.js +10 -10
- package/dist/commands/util/android-build-method.js +66 -0
- package/dist/commands/util/glass.js +118 -0
- package/dist/{export-BtUjg3Tl.js → export-DBQHSKU-.js} +1 -1
- package/dist/{import-BYSkF-tX.js → import-Bk4w8kks.js} +1 -1
- package/dist/{index-CcGRePRU.js → index-WrVwh6le.js} +6 -4
- package/dist/{index-Du6l7ZyV.js → index-qOGviaGc.js} +1 -1
- package/dist/{index-CgGLBt2v.js → index-zdIBXHs2.js} +5 -3
- package/dist/{upload-LoVBuJbT.js → upload-CeRPHRCP.js} +1 -1
- package/dist/{useAppleApp-Bg0x6s97.js → useAppleApp-DgZH0CBS.js} +1 -1
- package/dist/{useAppleBundleId-CEOssLqN.js → useAppleBundleId-CA7Pg4Hi.js} +2 -2
- package/dist/{useAppleProfiles-CHf_gHdZ.js → useAppleProfiles-CUBTPbcC.js} +1 -1
- package/dist/{useGoogleStatus-Ch36GbVo.js → useGoogleStatus-DpPwKmw_.js} +2 -1
- package/dist/{useProjectCredentials-CsQWPdyo.js → useProjectCredentials-rQLm2O1J.js} +2 -1
- package/dist/{useWebSocket-CWeaaLqi.js → useWebSocket-PU55rRGt.js} +1 -1
- package/docs/README.md +1 -0
- package/docs/util/android-build-method.md +26 -0
- package/docs/util/glass.md +47 -0
- package/docs/util.md +12 -0
- package/npm-shrinkwrap.json +14181 -0
- package/oclif.manifest.json +2966 -0
- package/package.json +11 -6
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import fs__default from 'node:fs';
|
|
3
|
+
import path__default from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { Flags, Command } from '@oclif/core';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import CryptoJS from 'crypto-js';
|
|
8
|
+
import { v4 } from 'uuid';
|
|
9
|
+
import { DateTime } from 'luxon';
|
|
10
|
+
import * as expo from '@expo/apple-utils/build/index.js';
|
|
11
|
+
import 'node:crypto';
|
|
12
|
+
import 'node:readline';
|
|
13
|
+
import 'node:url';
|
|
14
|
+
import 'readline-sync';
|
|
15
|
+
import 'isomorphic-git';
|
|
16
|
+
import { getMajorVersion, loadExportPresets, findPreset, getBasePreset, saveExportPresets, mergePresets, ConfigFile } from 'godot-export-presets';
|
|
17
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
18
|
+
import 'react';
|
|
19
|
+
import 'fast-glob';
|
|
20
|
+
import 'yazl';
|
|
21
|
+
import 'socket.io-client';
|
|
22
|
+
import 'fullscreen-ink';
|
|
23
|
+
import 'ink';
|
|
24
|
+
|
|
25
|
+
const AUTH_ENV_VAR_NAME = "SHIPTHIS_TOKEN";
|
|
26
|
+
const DOMAIN_ENV_VAR_NAME = "SHIPTHIS_DOMAIN";
|
|
27
|
+
const DEFAULT_SHIPPED_FILES_GLOBS = ["**/*"];
|
|
28
|
+
const DEFAULT_IGNORED_FILES_GLOBS = [
|
|
29
|
+
".git",
|
|
30
|
+
".gitignore",
|
|
31
|
+
"shipthis.json",
|
|
32
|
+
"shipthis-*.zip",
|
|
33
|
+
".godot/**",
|
|
34
|
+
".nomedia",
|
|
35
|
+
".import/**",
|
|
36
|
+
"export.cfg",
|
|
37
|
+
"export_credentials.cfg",
|
|
38
|
+
"*.translation",
|
|
39
|
+
".mono/**",
|
|
40
|
+
"data_*/**",
|
|
41
|
+
"mono_crash.*.json",
|
|
42
|
+
"*.apk",
|
|
43
|
+
"*.aab",
|
|
44
|
+
// OS cruft
|
|
45
|
+
".DS_Store",
|
|
46
|
+
"Thumbs.db",
|
|
47
|
+
// IDE project files
|
|
48
|
+
"*.iml",
|
|
49
|
+
".idea/",
|
|
50
|
+
".vscode/",
|
|
51
|
+
// Gradle + build outputs
|
|
52
|
+
".gradle/",
|
|
53
|
+
"**/build/",
|
|
54
|
+
// Android local config
|
|
55
|
+
"local.properties",
|
|
56
|
+
// Signing (keep secrets out of git)
|
|
57
|
+
"*.jks",
|
|
58
|
+
"*.keystore",
|
|
59
|
+
"keystore.properties",
|
|
60
|
+
// NDK
|
|
61
|
+
".cxx/",
|
|
62
|
+
".externalNativeBuild/",
|
|
63
|
+
// Misc temp
|
|
64
|
+
"*.log",
|
|
65
|
+
"*.tmp",
|
|
66
|
+
"*.temp",
|
|
67
|
+
"*.swp",
|
|
68
|
+
"*.swo",
|
|
69
|
+
"*~",
|
|
70
|
+
".env"
|
|
71
|
+
];
|
|
72
|
+
const PRIMARY_DOMAIN = "shipth.is";
|
|
73
|
+
function getUrlsForDomain(domain) {
|
|
74
|
+
const isPublic = domain.includes(PRIMARY_DOMAIN);
|
|
75
|
+
const apiDomain = (isPublic ? `api.` : "") + domain;
|
|
76
|
+
const wsDomain = (isPublic ? `ws.` : "") + domain;
|
|
77
|
+
return {
|
|
78
|
+
api: `https://${apiDomain}/api/1.0.0`,
|
|
79
|
+
web: `https://${domain}/`,
|
|
80
|
+
ws: `wss://${wsDomain}`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const DOMAIN = process.env[DOMAIN_ENV_VAR_NAME] || PRIMARY_DOMAIN;
|
|
84
|
+
const BACKEND_URLS = getUrlsForDomain(DOMAIN);
|
|
85
|
+
const API_URL = BACKEND_URLS.api;
|
|
86
|
+
const WS_URL = BACKEND_URLS.ws;
|
|
87
|
+
const WEB_URL = BACKEND_URLS.web;
|
|
88
|
+
|
|
89
|
+
const DetailsFlags = {
|
|
90
|
+
androidPackageName: Flags.string({ char: "a", description: "Set the Android package name" }),
|
|
91
|
+
buildNumber: Flags.integer({ char: "b", description: "Set the build number" }),
|
|
92
|
+
gameEngine: Flags.string({ char: "e", description: "Set the game engine" }),
|
|
93
|
+
gameEngineVersion: Flags.string({ char: "v", description: "Set the game engine version" }),
|
|
94
|
+
gcpProjectId: Flags.string({ char: "g", description: "Set the GCP project ID" }),
|
|
95
|
+
gcpServiceAccountId: Flags.string({ char: "c", description: "Set the GCP service account ID" }),
|
|
96
|
+
iosBundleId: Flags.string({ char: "i", description: "Set the iOS bundle ID" }),
|
|
97
|
+
liquidGlassIconPath: Flags.string({ char: "l", description: "Set the Liquid Glass icon path" }),
|
|
98
|
+
name: Flags.string({ char: "n", description: "The name of the game" }),
|
|
99
|
+
semanticVersion: Flags.string({ char: "s", description: "Set the semantic version" }),
|
|
100
|
+
useDemoCredentials: Flags.string({ char: "d", description: "Use demo credentials for this project" })
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const DEFAULT_LOCALE = "en-US";
|
|
104
|
+
function castObjectDates(apiObject, keys = ["createdAt", "updatedAt"]) {
|
|
105
|
+
if (!apiObject) return apiObject;
|
|
106
|
+
const datesOnly = Object.keys(apiObject).filter((k) => keys.includes(k)).reduce((a, c) => {
|
|
107
|
+
if (!apiObject[c]) return a;
|
|
108
|
+
a[c] = DateTime.fromISO(apiObject[c]);
|
|
109
|
+
return a;
|
|
110
|
+
}, {});
|
|
111
|
+
return {
|
|
112
|
+
...apiObject,
|
|
113
|
+
...datesOnly
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function castArrayObjectDates(apiArray, keys = ["createdAt", "updatedAt"]) {
|
|
117
|
+
return apiArray.map((apiObject) => castObjectDates(apiObject, keys));
|
|
118
|
+
}
|
|
119
|
+
function castJobDates(jobObject) {
|
|
120
|
+
if (jobObject.build) return castObjectDates({ ...jobObject, build: castObjectDates(jobObject.build) });
|
|
121
|
+
return castObjectDates(jobObject);
|
|
122
|
+
}
|
|
123
|
+
function getDateLocale() {
|
|
124
|
+
const fallback = Intl.DateTimeFormat().resolvedOptions().locale.replaceAll("_", "-") || DEFAULT_LOCALE;
|
|
125
|
+
try {
|
|
126
|
+
const { env } = process;
|
|
127
|
+
const fullLocale = env.LC_TIME || env.LANG || env.LANGUAGE || env.LC_ALL || env.LC_MESSAGES;
|
|
128
|
+
const shortLocale = fullLocale?.split(".")[0].replaceAll("_", "-");
|
|
129
|
+
const finalLocal = shortLocale || fallback;
|
|
130
|
+
const _ = DateTime.now().toLocaleString(DateTime.DATE_SHORT, { locale: finalLocal });
|
|
131
|
+
return finalLocal;
|
|
132
|
+
} catch {
|
|
133
|
+
return fallback;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function getShortDate(inputDate) {
|
|
137
|
+
const locale = getDateLocale();
|
|
138
|
+
return inputDate.toLocaleString(DateTime.DATE_SHORT, { locale });
|
|
139
|
+
}
|
|
140
|
+
function getShortDateTime(inputDate, extraFormatOpts = {}) {
|
|
141
|
+
const locale = getDateLocale();
|
|
142
|
+
const formatOpts = { ...DateTime.DATETIME_SHORT, ...extraFormatOpts };
|
|
143
|
+
return inputDate.toLocaleString(formatOpts, { locale });
|
|
144
|
+
}
|
|
145
|
+
function getShortTime(inputDate, extraFormatOpts = { fractionalSecondDigits: 3 }) {
|
|
146
|
+
const locale = getDateLocale();
|
|
147
|
+
const formatOpts = { ...DateTime.TIME_24_WITH_SECONDS, ...extraFormatOpts };
|
|
148
|
+
return inputDate.toLocaleString(formatOpts, { locale });
|
|
149
|
+
}
|
|
150
|
+
function getShortTimeDelta(start, end) {
|
|
151
|
+
return end.diff(start).rescale().set({ milliseconds: 0 }).shiftTo("minutes", "seconds").toHuman({
|
|
152
|
+
listStyle: "short",
|
|
153
|
+
unitDisplay: "short"
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let currentAuthToken;
|
|
158
|
+
function setAuthToken(token) {
|
|
159
|
+
currentAuthToken = token;
|
|
160
|
+
}
|
|
161
|
+
function getAuthToken() {
|
|
162
|
+
return currentAuthToken;
|
|
163
|
+
}
|
|
164
|
+
function getAuthedHeaders() {
|
|
165
|
+
return {
|
|
166
|
+
Authorization: `Bearer ${currentAuthToken}`
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function createProject(props) {
|
|
170
|
+
const headers = getAuthedHeaders();
|
|
171
|
+
const opt = { headers };
|
|
172
|
+
const { data } = await axios.post(`${API_URL}/projects`, props, opt);
|
|
173
|
+
return castObjectDates(data);
|
|
174
|
+
}
|
|
175
|
+
async function getProject(projectId) {
|
|
176
|
+
const headers = getAuthedHeaders();
|
|
177
|
+
const opt = { headers };
|
|
178
|
+
const { data } = await axios.get(`${API_URL}/projects/${projectId}`, opt);
|
|
179
|
+
return castObjectDates(data);
|
|
180
|
+
}
|
|
181
|
+
async function getProjects(params) {
|
|
182
|
+
const headers = getAuthedHeaders();
|
|
183
|
+
const opt = { headers, params };
|
|
184
|
+
const { data: rawData } = await axios.get(`${API_URL}/projects`, opt);
|
|
185
|
+
const data = castArrayObjectDates(rawData.data);
|
|
186
|
+
return {
|
|
187
|
+
data,
|
|
188
|
+
pageCount: rawData.pageCount
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
async function updateProject(projectId, edits) {
|
|
192
|
+
const headers = getAuthedHeaders();
|
|
193
|
+
const opt = { headers };
|
|
194
|
+
const { data } = await axios.put(`${API_URL}/projects/${projectId}`, edits, opt);
|
|
195
|
+
return castObjectDates(data);
|
|
196
|
+
}
|
|
197
|
+
async function getProjectPlatformProgress(projectId, platform) {
|
|
198
|
+
const headers = getAuthedHeaders();
|
|
199
|
+
const opt = { headers };
|
|
200
|
+
const { data } = await axios.get(`${API_URL}/projects/${projectId}/${platform}/progress`, opt);
|
|
201
|
+
return data;
|
|
202
|
+
}
|
|
203
|
+
async function getNewUploadTicket(projectId) {
|
|
204
|
+
const headers = getAuthedHeaders();
|
|
205
|
+
const opt = { headers };
|
|
206
|
+
const { data } = await axios.post(`${API_URL}/upload/${projectId}/url`, {}, opt);
|
|
207
|
+
return data;
|
|
208
|
+
}
|
|
209
|
+
async function startJobsFromUpload(uploadTicketId, startOptions) {
|
|
210
|
+
const headers = getAuthedHeaders();
|
|
211
|
+
const opt = { headers };
|
|
212
|
+
const { data } = await axios.post(`${API_URL}/upload/start/${uploadTicketId}`, startOptions, opt);
|
|
213
|
+
return castArrayObjectDates(data);
|
|
214
|
+
}
|
|
215
|
+
async function getProjectJobs(projectId, params) {
|
|
216
|
+
const headers = getAuthedHeaders();
|
|
217
|
+
const opt = { headers, params };
|
|
218
|
+
const { data: rawData } = await axios.get(`${API_URL}/projects/${projectId}/jobs`, opt);
|
|
219
|
+
const data = castArrayObjectDates(rawData.data);
|
|
220
|
+
return {
|
|
221
|
+
data,
|
|
222
|
+
pageCount: rawData.pageCount
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
async function getJob(jobId, projectId) {
|
|
226
|
+
const headers = getAuthedHeaders();
|
|
227
|
+
const opt = { headers };
|
|
228
|
+
const { data } = await axios.get(`${API_URL}/projects/${projectId}/jobs/${jobId}`, opt);
|
|
229
|
+
return castJobDates(data);
|
|
230
|
+
}
|
|
231
|
+
async function getSingleUseUrl(destination) {
|
|
232
|
+
const headers = await getAuthedHeaders();
|
|
233
|
+
const { data } = await axios.post(`${API_URL}/me/otp`, {}, { headers });
|
|
234
|
+
const queryString = Object.entries({ ...data, destination }).map(([key, value]) => `${key}=${encodeURIComponent(`${value}`)}`).join("&");
|
|
235
|
+
const url = `${WEB_URL}exchange/?${queryString}`;
|
|
236
|
+
return url;
|
|
237
|
+
}
|
|
238
|
+
async function getShortAuthRequiredUrl(destination) {
|
|
239
|
+
const { email } = await getSelf();
|
|
240
|
+
const key = v4();
|
|
241
|
+
const salt = "Na (s) + 1/2 Cl\u2082 (g) \u2192 NaCl (s)";
|
|
242
|
+
const fullKey = `${key}${salt}`;
|
|
243
|
+
const token = CryptoJS.AES.encrypt(email, fullKey).toString();
|
|
244
|
+
const params = {
|
|
245
|
+
destination,
|
|
246
|
+
key,
|
|
247
|
+
token
|
|
248
|
+
};
|
|
249
|
+
const queryString = Object.entries(params).map(([key2, value]) => `${key2}=${encodeURIComponent(`${value}`)}`).join("&");
|
|
250
|
+
const url = `${WEB_URL}login/?${queryString}`;
|
|
251
|
+
const headers = await getAuthedHeaders();
|
|
252
|
+
const { data } = await axios.post(
|
|
253
|
+
`${API_URL}/me/shorten`,
|
|
254
|
+
{
|
|
255
|
+
url
|
|
256
|
+
},
|
|
257
|
+
{ headers }
|
|
258
|
+
);
|
|
259
|
+
return data.url;
|
|
260
|
+
}
|
|
261
|
+
async function getBuild(projectId, buildId) {
|
|
262
|
+
const headers = getAuthedHeaders();
|
|
263
|
+
const opt = { headers };
|
|
264
|
+
const { data } = await axios.get(`${API_URL}/projects/${projectId}/builds/${buildId}`, opt);
|
|
265
|
+
return castObjectDates(data);
|
|
266
|
+
}
|
|
267
|
+
async function getSelf() {
|
|
268
|
+
const headers = getAuthedHeaders();
|
|
269
|
+
const opt = { headers };
|
|
270
|
+
const { data } = await axios.get(`${API_URL}/me`, opt);
|
|
271
|
+
return castObjectDates(data);
|
|
272
|
+
}
|
|
273
|
+
async function getTerms() {
|
|
274
|
+
const headers = getAuthedHeaders();
|
|
275
|
+
const opt = { headers };
|
|
276
|
+
const { data } = await axios.get(`${API_URL}/me/terms`, opt);
|
|
277
|
+
return {
|
|
278
|
+
// Any agreements which have changed since the user last accepted terms
|
|
279
|
+
changes: castArrayObjectDates(data.changes),
|
|
280
|
+
// Current versions of any agreements
|
|
281
|
+
current: castArrayObjectDates(data.current)
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
async function acceptTerms() {
|
|
285
|
+
const headers = getAuthedHeaders();
|
|
286
|
+
const opt = { headers };
|
|
287
|
+
const { data } = await axios.post(`${API_URL}/me/terms`, {}, opt);
|
|
288
|
+
return castObjectDates(data);
|
|
289
|
+
}
|
|
290
|
+
async function getGoogleAuthUrl(projectId) {
|
|
291
|
+
const headers = getAuthedHeaders();
|
|
292
|
+
const opt = { headers };
|
|
293
|
+
const web = encodeURIComponent(new URL("/google/redirect/", WEB_URL).href);
|
|
294
|
+
const url = `${API_URL}/projects/${projectId}/credentials/android/key/connect`;
|
|
295
|
+
const { data } = await axios.get(`${url}?redirectUri=${web}`, opt);
|
|
296
|
+
const response = data;
|
|
297
|
+
return await getShortAuthRequiredUrl(response.url);
|
|
298
|
+
}
|
|
299
|
+
async function disconnectGoogle() {
|
|
300
|
+
const headers = getAuthedHeaders();
|
|
301
|
+
const opt = { headers };
|
|
302
|
+
await axios.delete(`${API_URL}/me/google/connect`, opt);
|
|
303
|
+
}
|
|
304
|
+
async function getGoogleStatus() {
|
|
305
|
+
const headers = getAuthedHeaders();
|
|
306
|
+
const opt = { headers };
|
|
307
|
+
const { data } = await axios.get(`${API_URL}/me/google/status`, opt);
|
|
308
|
+
return castObjectDates(data, ["orgCreatedAt"]);
|
|
309
|
+
}
|
|
310
|
+
async function enforcePolicy() {
|
|
311
|
+
const headers = getAuthedHeaders();
|
|
312
|
+
const opt = { headers };
|
|
313
|
+
const { data } = await axios.post(`${API_URL}/me/google/policy`, null, opt);
|
|
314
|
+
return castObjectDates(data, ["orgCreatedAt"]);
|
|
315
|
+
}
|
|
316
|
+
async function revokePolicy() {
|
|
317
|
+
const headers = getAuthedHeaders();
|
|
318
|
+
const opt = { headers };
|
|
319
|
+
const { data } = await axios.delete(`${API_URL}/me/google/policy`, opt);
|
|
320
|
+
return castObjectDates(data, ["orgCreatedAt"]);
|
|
321
|
+
}
|
|
322
|
+
async function inviteServiceAccount(projectId, developerId) {
|
|
323
|
+
try {
|
|
324
|
+
const headers = getAuthedHeaders();
|
|
325
|
+
const { data } = await axios.post(
|
|
326
|
+
`${API_URL}/projects/${projectId}/credentials/android/key/invite/`,
|
|
327
|
+
{ developerId },
|
|
328
|
+
{
|
|
329
|
+
headers
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
return data;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.error("inviteServiceAccount Error", error);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async function downloadBuildById(projectId, buildId, fileName) {
|
|
339
|
+
const build = await getBuild(projectId, buildId);
|
|
340
|
+
const { url } = build;
|
|
341
|
+
const writer = fs.createWriteStream(fileName);
|
|
342
|
+
const response = await axios({
|
|
343
|
+
method: "GET",
|
|
344
|
+
responseType: "stream",
|
|
345
|
+
url
|
|
346
|
+
});
|
|
347
|
+
response.data.pipe(writer);
|
|
348
|
+
return new Promise((resolve, reject) => {
|
|
349
|
+
writer.on("finish", resolve);
|
|
350
|
+
writer.on("error", reject);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
const APIKEYS_DATE_FIELDS = ["createdAt", "updatedAt", "expiresAt", "lastUsedAt", "revokedAt"];
|
|
354
|
+
async function getAPIKeys(params) {
|
|
355
|
+
const headers = getAuthedHeaders();
|
|
356
|
+
const opt = { headers, params };
|
|
357
|
+
const { data: rawData } = await axios.get(`${API_URL}/me/keys`, opt);
|
|
358
|
+
const data = castArrayObjectDates(rawData.data, APIKEYS_DATE_FIELDS);
|
|
359
|
+
return {
|
|
360
|
+
data,
|
|
361
|
+
pageCount: rawData.pageCount
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
async function createAPIKey(createProps) {
|
|
365
|
+
const headers = getAuthedHeaders();
|
|
366
|
+
const opt = { headers };
|
|
367
|
+
const { data } = await axios.post(`${API_URL}/me/keys`, createProps, opt);
|
|
368
|
+
return castObjectDates(data, APIKEYS_DATE_FIELDS);
|
|
369
|
+
}
|
|
370
|
+
async function revokeAPIKey(apiKeyId) {
|
|
371
|
+
const headers = getAuthedHeaders();
|
|
372
|
+
const opt = { headers };
|
|
373
|
+
await axios.delete(`${API_URL}/me/keys/${apiKeyId}`, opt);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const defaultExport = expo.default;
|
|
377
|
+
const {
|
|
378
|
+
ApiKey,
|
|
379
|
+
ApiKeyType,
|
|
380
|
+
App,
|
|
381
|
+
Auth,
|
|
382
|
+
BetaGroup,
|
|
383
|
+
BundleId,
|
|
384
|
+
CapabilityType,
|
|
385
|
+
CapabilityTypeOption,
|
|
386
|
+
Certificate,
|
|
387
|
+
CertificateType,
|
|
388
|
+
Profile,
|
|
389
|
+
ProfileType,
|
|
390
|
+
Session,
|
|
391
|
+
UserRole
|
|
392
|
+
} = defaultExport;
|
|
393
|
+
|
|
394
|
+
var Platform = /* @__PURE__ */ ((Platform2) => {
|
|
395
|
+
Platform2["ANDROID"] = "ANDROID";
|
|
396
|
+
Platform2["IOS"] = "IOS";
|
|
397
|
+
return Platform2;
|
|
398
|
+
})(Platform || {});
|
|
399
|
+
var GameEngine = /* @__PURE__ */ ((GameEngine2) => {
|
|
400
|
+
GameEngine2["GODOT"] = "godot";
|
|
401
|
+
return GameEngine2;
|
|
402
|
+
})(GameEngine || {});
|
|
403
|
+
var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
|
|
404
|
+
JobStatus2["COMPLETED"] = "COMPLETED";
|
|
405
|
+
JobStatus2["FAILED"] = "FAILED";
|
|
406
|
+
JobStatus2["PENDING"] = "PENDING";
|
|
407
|
+
JobStatus2["PROCESSING"] = "PROCESSING";
|
|
408
|
+
return JobStatus2;
|
|
409
|
+
})(JobStatus || {});
|
|
410
|
+
var JobStage = /* @__PURE__ */ ((JobStage2) => {
|
|
411
|
+
JobStage2["BUILD"] = "BUILD";
|
|
412
|
+
JobStage2["CONFIGURE"] = "CONFIGURE";
|
|
413
|
+
JobStage2["EXPORT"] = "EXPORT";
|
|
414
|
+
JobStage2["PUBLISH"] = "PUBLISH";
|
|
415
|
+
JobStage2["SETUP"] = "SETUP";
|
|
416
|
+
return JobStage2;
|
|
417
|
+
})(JobStage || {});
|
|
418
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
419
|
+
LogLevel2["ERROR"] = "ERROR";
|
|
420
|
+
LogLevel2["INFO"] = "INFO";
|
|
421
|
+
LogLevel2["WARN"] = "WARN";
|
|
422
|
+
return LogLevel2;
|
|
423
|
+
})(LogLevel || {});
|
|
424
|
+
var CredentialsType = /* @__PURE__ */ ((CredentialsType2) => {
|
|
425
|
+
CredentialsType2["CERTIFICATE"] = "CERTIFICATE";
|
|
426
|
+
CredentialsType2["KEY"] = "KEY";
|
|
427
|
+
return CredentialsType2;
|
|
428
|
+
})(CredentialsType || {});
|
|
429
|
+
var BuildType = /* @__PURE__ */ ((BuildType2) => {
|
|
430
|
+
BuildType2["AAB"] = "AAB";
|
|
431
|
+
BuildType2["APK"] = "APK";
|
|
432
|
+
BuildType2["IPA"] = "IPA";
|
|
433
|
+
return BuildType2;
|
|
434
|
+
})(BuildType || {});
|
|
435
|
+
|
|
436
|
+
function isCWDGodotGame() {
|
|
437
|
+
const cwd = process.cwd();
|
|
438
|
+
const godotProject = path__default.join(cwd, "project.godot");
|
|
439
|
+
return fs__default.existsSync(godotProject);
|
|
440
|
+
}
|
|
441
|
+
const GODOT_CAPABILITIES = [
|
|
442
|
+
// TODO: how about capabilities from godot extensions
|
|
443
|
+
{ key: "capabilities/access_wifi", name: "Access WiFi", type: CapabilityType.ACCESS_WIFI },
|
|
444
|
+
{ key: "capabilities/push_notifications", name: "Push Notifications", type: CapabilityType.PUSH_NOTIFICATIONS }
|
|
445
|
+
];
|
|
446
|
+
async function getGodotProjectCapabilities(platform) {
|
|
447
|
+
const exportPresets = await getGodotExportPresets(platform);
|
|
448
|
+
const options = exportPresets.options || {};
|
|
449
|
+
const capabilities = [];
|
|
450
|
+
for (const capability of GODOT_CAPABILITIES) {
|
|
451
|
+
if (!(capability.key in options)) continue;
|
|
452
|
+
if (`${options[capability.key]}`.toLocaleLowerCase() === "true") capabilities.push(capability.type);
|
|
453
|
+
}
|
|
454
|
+
return capabilities;
|
|
455
|
+
}
|
|
456
|
+
function getGodotProjectConfig() {
|
|
457
|
+
const cwd = process.cwd();
|
|
458
|
+
const projectGodotPath = path__default.join(cwd, "project.godot");
|
|
459
|
+
const projectGodotContent = fs__default.readFileSync(projectGodotPath, "utf8");
|
|
460
|
+
const configFile = new ConfigFile();
|
|
461
|
+
const error = configFile.parse(projectGodotContent);
|
|
462
|
+
if (error) {
|
|
463
|
+
throw error;
|
|
464
|
+
}
|
|
465
|
+
return configFile;
|
|
466
|
+
}
|
|
467
|
+
function getGodotProjectName() {
|
|
468
|
+
try {
|
|
469
|
+
const projectGodotConfig = getGodotProjectConfig();
|
|
470
|
+
return projectGodotConfig.get_value("application", "config/name") || null;
|
|
471
|
+
} catch {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
async function getGodotAppleBundleIdentifier() {
|
|
476
|
+
try {
|
|
477
|
+
const preset = await getGodotExportPresets(Platform.IOS);
|
|
478
|
+
return preset.options?.["application/bundle_identifier"] || null;
|
|
479
|
+
} catch (error) {
|
|
480
|
+
console.log(error);
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
async function getGodotAndroidPackageName() {
|
|
485
|
+
try {
|
|
486
|
+
const preset = await getGodotExportPresets(Platform.ANDROID);
|
|
487
|
+
return preset.options?.["package/unique_name"] || null;
|
|
488
|
+
} catch (error) {
|
|
489
|
+
console.log(error);
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
function getGodotVersion() {
|
|
494
|
+
const projectGodotConfig = getGodotProjectConfig();
|
|
495
|
+
const features = projectGodotConfig.get_value("application", "config/features");
|
|
496
|
+
if (!features || features.length === 0) {
|
|
497
|
+
return "3.6";
|
|
498
|
+
}
|
|
499
|
+
const [version] = features;
|
|
500
|
+
return version;
|
|
501
|
+
}
|
|
502
|
+
function getExportPresetsPath() {
|
|
503
|
+
const cwd = process.cwd();
|
|
504
|
+
const filename = "export_presets.cfg";
|
|
505
|
+
const exportPresetsPath = path__default.join(cwd, filename);
|
|
506
|
+
return exportPresetsPath;
|
|
507
|
+
}
|
|
508
|
+
async function getGodotExportPresets(platform) {
|
|
509
|
+
const { warn } = console;
|
|
510
|
+
const godotVersion = getGodotVersion();
|
|
511
|
+
const majorVersion = getMajorVersion(godotVersion);
|
|
512
|
+
const godotPlatform = platform === Platform.IOS ? "iOS" : "Android";
|
|
513
|
+
let presetConfig = getBasePreset(godotPlatform, majorVersion);
|
|
514
|
+
const exportPresetsPath = getExportPresetsPath();
|
|
515
|
+
const isFound = fs__default.existsSync(exportPresetsPath);
|
|
516
|
+
if (isFound) {
|
|
517
|
+
try {
|
|
518
|
+
const exportPresets = await loadExportPresets(exportPresetsPath);
|
|
519
|
+
const foundPreset = findPreset(exportPresets, { platform: godotPlatform });
|
|
520
|
+
if (foundPreset) {
|
|
521
|
+
presetConfig = mergePresets(presetConfig, foundPreset);
|
|
522
|
+
} else {
|
|
523
|
+
warn(`Preset ${platform} not found in ${exportPresetsPath} - will use defaults`);
|
|
524
|
+
}
|
|
525
|
+
} catch (error) {
|
|
526
|
+
warn(`Error loading ${exportPresetsPath}: ${error} - will use defaults`);
|
|
527
|
+
}
|
|
528
|
+
} else {
|
|
529
|
+
warn(`Export presets not found at ${exportPresetsPath} - will use defaults`);
|
|
530
|
+
}
|
|
531
|
+
return presetConfig;
|
|
532
|
+
}
|
|
533
|
+
function getGradleBuildOptionKey(majorVersion) {
|
|
534
|
+
return majorVersion === 4 ? "gradle_build/use_gradle_build" : "custom_build/use_custom_build";
|
|
535
|
+
}
|
|
536
|
+
function getExportFormatOptionKey(majorVersion) {
|
|
537
|
+
return majorVersion === 4 ? "gradle_build/export_format" : "custom_build/export_format";
|
|
538
|
+
}
|
|
539
|
+
async function isGradleBuildEnabled() {
|
|
540
|
+
const godotVersion = getGodotVersion();
|
|
541
|
+
const majorVersion = getMajorVersion(godotVersion);
|
|
542
|
+
const preset = await getGodotExportPresets(Platform.ANDROID);
|
|
543
|
+
const buildOptionKey = getGradleBuildOptionKey(majorVersion);
|
|
544
|
+
const isEnabled = preset.options?.[buildOptionKey];
|
|
545
|
+
return isEnabled === true || isEnabled === "true";
|
|
546
|
+
}
|
|
547
|
+
async function setGradleBuildEnabled(value) {
|
|
548
|
+
const exportPresetsPath = getExportPresetsPath();
|
|
549
|
+
let exportPresets = { presets: [] };
|
|
550
|
+
if (fs__default.existsSync(exportPresetsPath)) {
|
|
551
|
+
exportPresets = await loadExportPresets(exportPresetsPath);
|
|
552
|
+
} else {
|
|
553
|
+
console.warn(`Export presets not found at ${exportPresetsPath} - creating new file`);
|
|
554
|
+
}
|
|
555
|
+
const godotVersion = getGodotVersion();
|
|
556
|
+
const majorVersion = getMajorVersion(godotVersion);
|
|
557
|
+
let androidPreset = findPreset(exportPresets, { platform: "Android" });
|
|
558
|
+
if (!androidPreset) {
|
|
559
|
+
androidPreset = getBasePreset("Android", majorVersion);
|
|
560
|
+
exportPresets.presets.push(androidPreset);
|
|
561
|
+
}
|
|
562
|
+
const buildOptionKey = getGradleBuildOptionKey(majorVersion);
|
|
563
|
+
androidPreset.options = androidPreset.options || {};
|
|
564
|
+
androidPreset.options[buildOptionKey] = value;
|
|
565
|
+
const exportFormatOptionKey = getExportFormatOptionKey(majorVersion);
|
|
566
|
+
if (value === false) {
|
|
567
|
+
androidPreset.options[exportFormatOptionKey] = 0;
|
|
568
|
+
}
|
|
569
|
+
await saveExportPresets(exportPresetsPath, exportPresets);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const queryClient = new QueryClient({
|
|
573
|
+
defaultOptions: {
|
|
574
|
+
queries: {
|
|
575
|
+
staleTime: 50
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
class BaseCommand extends Command {
|
|
581
|
+
// define flags that can be inherited by any command that extends BaseCommand
|
|
582
|
+
static baseFlags = {};
|
|
583
|
+
// add the --json flag
|
|
584
|
+
static enableJsonFlag = false;
|
|
585
|
+
args;
|
|
586
|
+
flags;
|
|
587
|
+
async catch(err) {
|
|
588
|
+
return super.catch(err);
|
|
589
|
+
}
|
|
590
|
+
// Used in baseGameCommand and the other commands that need to ensure that the CWD is a Godot project
|
|
591
|
+
ensureWeAreInAProjectDir() {
|
|
592
|
+
if (!isCWDGodotGame()) {
|
|
593
|
+
this.error("No Godot project detected. Please run this from a godot project directory.", { exit: 1 });
|
|
594
|
+
}
|
|
595
|
+
if (!this.hasProjectConfig()) {
|
|
596
|
+
this.error(
|
|
597
|
+
'No ShipThis config found. Please run `shipthis game create --name "Space Invaders"` to create a game.',
|
|
598
|
+
{ exit: 1 }
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
ensureWeHaveAppleCookies() {
|
|
603
|
+
if (!this.hasAuthConfigFile()) {
|
|
604
|
+
this.error("You must be authenticated with Apple in to use this command. Please run shipthis apple login", {
|
|
605
|
+
exit: 1
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async finally(_) {
|
|
610
|
+
return super.finally(_);
|
|
611
|
+
}
|
|
612
|
+
// Used in the apple commands to get the cookies from the auth file
|
|
613
|
+
async getAppleCookies() {
|
|
614
|
+
const authConfig = await this.getAuthConfig();
|
|
615
|
+
if (!authConfig.appleCookies) return null;
|
|
616
|
+
return authConfig.appleCookies;
|
|
617
|
+
}
|
|
618
|
+
// Returns the current auth config - prefers to use the env var
|
|
619
|
+
async getAuthConfig() {
|
|
620
|
+
const envVarValue = process.env[AUTH_ENV_VAR_NAME];
|
|
621
|
+
if (!envVarValue) return await this.getAuthConfigFromFile();
|
|
622
|
+
setAuthToken(envVarValue);
|
|
623
|
+
const self = await getSelf();
|
|
624
|
+
const selfWithJwt = {
|
|
625
|
+
...self,
|
|
626
|
+
jwt: envVarValue
|
|
627
|
+
};
|
|
628
|
+
return {
|
|
629
|
+
shipThisUser: selfWithJwt
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
// Loads the auth config from the file system
|
|
633
|
+
async getAuthConfigFromFile() {
|
|
634
|
+
const baseConfig = {};
|
|
635
|
+
const configPath = this.getAuthConfigPath();
|
|
636
|
+
if (!fs__default.existsSync(configPath)) return baseConfig;
|
|
637
|
+
const raw = await fs__default.promises.readFile(configPath, "utf8");
|
|
638
|
+
const parsed = JSON.parse(raw);
|
|
639
|
+
if (parsed.shipThisUser) {
|
|
640
|
+
setAuthToken(parsed.shipThisUser.jwt);
|
|
641
|
+
}
|
|
642
|
+
return {
|
|
643
|
+
...baseConfig,
|
|
644
|
+
...parsed
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
// This is used to expose the flags to the Android Wizard
|
|
648
|
+
getDetailsFlagsValues() {
|
|
649
|
+
const keys = Object.keys(DetailsFlags);
|
|
650
|
+
const values = {};
|
|
651
|
+
for (const key of keys) {
|
|
652
|
+
if (this.flags[key]) values[key] = this.flags[key];
|
|
653
|
+
}
|
|
654
|
+
return values;
|
|
655
|
+
}
|
|
656
|
+
// Exposing it to the react components using the CommandContext
|
|
657
|
+
getFlags() {
|
|
658
|
+
return this.flags;
|
|
659
|
+
}
|
|
660
|
+
getGameId() {
|
|
661
|
+
const { flags } = this;
|
|
662
|
+
if (flags.gameId) return flags.gameId;
|
|
663
|
+
const { project } = this.getProjectConfigSafe();
|
|
664
|
+
if (!project) return null;
|
|
665
|
+
return project.id;
|
|
666
|
+
}
|
|
667
|
+
async getProjectConfig() {
|
|
668
|
+
if (!this.hasProjectConfig()) throw new Error("No project config found");
|
|
669
|
+
return this.getProjectConfigSafe();
|
|
670
|
+
}
|
|
671
|
+
getProjectConfigSafe() {
|
|
672
|
+
if (!this.hasProjectConfig()) return {};
|
|
673
|
+
const configPath = this.getProjectConfigPath();
|
|
674
|
+
const raw = fs__default.readFileSync(configPath, "utf8");
|
|
675
|
+
return JSON.parse(raw);
|
|
676
|
+
}
|
|
677
|
+
hasAuthConfigFile() {
|
|
678
|
+
const configPath = this.getAuthConfigPath();
|
|
679
|
+
return fs__default.existsSync(configPath);
|
|
680
|
+
}
|
|
681
|
+
hasProjectConfig() {
|
|
682
|
+
const configPath = this.getProjectConfigPath();
|
|
683
|
+
return fs__default.existsSync(configPath);
|
|
684
|
+
}
|
|
685
|
+
// Tests the apple cookies
|
|
686
|
+
async hasValidAppleAuthState() {
|
|
687
|
+
try {
|
|
688
|
+
await this.refreshAppleAuthState();
|
|
689
|
+
return true;
|
|
690
|
+
} catch {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
async init() {
|
|
695
|
+
process.on("SIGINT", () => process.exit(0));
|
|
696
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
697
|
+
await super.init();
|
|
698
|
+
const { args, flags } = await this.parse({
|
|
699
|
+
args: this.ctor.args,
|
|
700
|
+
baseFlags: super.ctor.baseFlags,
|
|
701
|
+
enableJsonFlag: this.ctor.enableJsonFlag,
|
|
702
|
+
flags: this.ctor.flags,
|
|
703
|
+
strict: this.ctor.strict
|
|
704
|
+
});
|
|
705
|
+
this.flags = flags;
|
|
706
|
+
this.args = args;
|
|
707
|
+
await this.getAuthConfig();
|
|
708
|
+
}
|
|
709
|
+
async isAuthenticated() {
|
|
710
|
+
const authConfig = await this.getAuthConfig();
|
|
711
|
+
return Boolean(authConfig.shipThisUser?.jwt);
|
|
712
|
+
}
|
|
713
|
+
async refreshAppleAuthState() {
|
|
714
|
+
const cookies = await this.getAppleCookies();
|
|
715
|
+
const rerunMessage = `Please run ${chalk.bold("shipthis apple login")} to authenticate with Apple.`;
|
|
716
|
+
if (!cookies) throw new Error(`No Apple cookies found. ${rerunMessage}`);
|
|
717
|
+
const authState = await Auth.loginWithCookiesAsync(
|
|
718
|
+
{
|
|
719
|
+
cookies
|
|
720
|
+
},
|
|
721
|
+
{}
|
|
722
|
+
);
|
|
723
|
+
if (!authState) throw new Error(`Failed to refresh Apple auth state. ${rerunMessage}`);
|
|
724
|
+
return authState;
|
|
725
|
+
}
|
|
726
|
+
// Pass undefined to logout
|
|
727
|
+
async setAppleCookies(cookies) {
|
|
728
|
+
const authConfig = await this.getAuthConfig();
|
|
729
|
+
await this.setAuthConfig({ ...authConfig, appleCookies: cookies });
|
|
730
|
+
}
|
|
731
|
+
// This is called after login to persist the JWT and user details
|
|
732
|
+
async setAuthConfig(config) {
|
|
733
|
+
const configPath = this.getAuthConfigPath();
|
|
734
|
+
await fs__default.promises.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
735
|
+
}
|
|
736
|
+
async setProjectConfig(config) {
|
|
737
|
+
const configPath = this.getProjectConfigPath();
|
|
738
|
+
const clean = {
|
|
739
|
+
...config,
|
|
740
|
+
project: config.project ? { id: config.project.id } : void 0
|
|
741
|
+
};
|
|
742
|
+
await fs__default.promises.writeFile(configPath, JSON.stringify(clean, null, 2));
|
|
743
|
+
}
|
|
744
|
+
async updateProjectConfig(update) {
|
|
745
|
+
const config = await this.getProjectConfig();
|
|
746
|
+
await this.setProjectConfig({ ...config, ...update });
|
|
747
|
+
}
|
|
748
|
+
// Returns the values of the flags in DetailsFlags
|
|
749
|
+
getAuthConfigPath() {
|
|
750
|
+
return path__default.join(this.config.home, ".shipthis.auth.json");
|
|
751
|
+
}
|
|
752
|
+
getProjectConfigPath() {
|
|
753
|
+
return path__default.join(process.cwd(), "shipthis.json");
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
export { acceptTerms as $, ApiKey as A, BaseCommand as B, CredentialsType as C, DetailsFlags as D, getProjectJobs as E, getJob as F, GODOT_CAPABILITIES as G, castArrayObjectDates as H, queryClient as I, JobStatus as J, WS_URL as K, getAuthToken as L, getProjectPlatformProgress as M, downloadBuildById as N, getGoogleStatus as O, Platform as P, getGodotAndroidPackageName as Q, enforcePolicy as R, revokePolicy as S, inviteServiceAccount as T, UserRole as U, disconnectGoogle as V, WEB_URL as W, getAPIKeys as X, createAPIKey as Y, revokeAPIKey as Z, getSingleUseUrl as _, ApiKeyType as a, setAuthToken as a0, Auth as a1, getNewUploadTicket as a2, startJobsFromUpload as a3, LogLevel as a4, getShortAuthRequiredUrl as a5, castObjectDates as a6, getGoogleAuthUrl as a7, castJobDates as a8, getShortTime as a9, updateProject as aa, BuildType as ab, getGradleBuildOptionKey as ac, getShortDateTime as ad, getShortTimeDelta as ae, JobStage as af, getSelf as ag, getTerms as ah, Certificate as b, getShortDate as c, getGodotAppleBundleIdentifier as d, BundleId as e, App as f, getProjects as g, CapabilityTypeOption as h, isGradleBuildEnabled as i, BetaGroup as j, isCWDGodotGame as k, getProject as l, CertificateType as m, Profile as n, ProfileType as o, API_URL as p, getAuthedHeaders as q, getGodotProjectCapabilities as r, setGradleBuildEnabled as s, CapabilityType as t, GameEngine as u, getGodotVersion as v, createProject as w, DEFAULT_SHIPPED_FILES_GLOBS as x, DEFAULT_IGNORED_FILES_GLOBS as y, getGodotProjectName as z };
|