eoas 2.3.17 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/init.js +11 -0
- package/dist/commands/publish.js +4 -3
- package/dist/commands/republish.js +12 -5
- package/dist/commands/rollback.d.ts +1 -0
- package/dist/commands/rollback.js +18 -10
- package/dist/lib/expoConfig.d.ts +1 -0
- package/dist/lib/expoConfig.js +14 -2
- package/package.json +1 -1
- package/dist/lib/channel.d.ts +0 -2
- package/dist/lib/channel.js +0 -24
package/dist/commands/init.js
CHANGED
|
@@ -27,6 +27,16 @@ class Init extends core_1.Command {
|
|
|
27
27
|
log_1.default.error('Could not find Expo config in this project. Please make sure you have an Expo config.');
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
+
const detectedAppId = config.extra?.eas
|
|
31
|
+
?.projectId;
|
|
32
|
+
const { appId } = await (0, prompts_1.promptAsync)({
|
|
33
|
+
message: 'Enter the Expo project id for this project (sent as the expo-app-id header).\n' +
|
|
34
|
+
' See https://axelmarciano.github.io/expo-open-ota/docs/getting-started/prerequisites for details.',
|
|
35
|
+
name: 'appId',
|
|
36
|
+
type: 'text',
|
|
37
|
+
initial: detectedAppId,
|
|
38
|
+
validate: v => !!v,
|
|
39
|
+
});
|
|
30
40
|
const { updateUrl: promptedUrl } = await (0, prompts_1.promptAsync)({
|
|
31
41
|
message: 'Enter the URL of your update server (ex: https://customota.com)',
|
|
32
42
|
name: 'updateUrl',
|
|
@@ -95,6 +105,7 @@ class Init extends core_1.Command {
|
|
|
95
105
|
enabled: true,
|
|
96
106
|
requestHeaders: {
|
|
97
107
|
'expo-channel-name': 'process.env.RELEASE_CHANNEL',
|
|
108
|
+
'expo-app-id': appId,
|
|
98
109
|
},
|
|
99
110
|
};
|
|
100
111
|
const updateConfigSpinner = (0, ora_1.ora)('Updating Expo config').start();
|
package/dist/commands/publish.js
CHANGED
|
@@ -111,6 +111,7 @@ class Publish extends core_1.Command {
|
|
|
111
111
|
log_1.default.error(e.message);
|
|
112
112
|
process.exit(1);
|
|
113
113
|
});
|
|
114
|
+
const appId = (0, expoConfig_1.requireExpoAppId)(config);
|
|
114
115
|
if (!nonInteractive) {
|
|
115
116
|
const confirmed = await (0, prompts_1.confirmAsync)({
|
|
116
117
|
message: `Is this the correct URL of your self-hosted update server? ${serverUrl}`,
|
|
@@ -231,7 +232,7 @@ class Publish extends core_1.Command {
|
|
|
231
232
|
body: {
|
|
232
233
|
fileNames: files.map(file => file.path),
|
|
233
234
|
},
|
|
234
|
-
requestUploadUrl: `${serverUrl}/requestUploadUrl/${branch}`,
|
|
235
|
+
requestUploadUrl: `${serverUrl}/${appId}/requestUploadUrl/${branch}`,
|
|
235
236
|
auth: credentials,
|
|
236
237
|
runtimeVersion,
|
|
237
238
|
platform,
|
|
@@ -244,7 +245,7 @@ class Publish extends core_1.Command {
|
|
|
244
245
|
}));
|
|
245
246
|
const allItems = uploadUrls.flatMap(({ uploadRequests }) => uploadRequests);
|
|
246
247
|
await Promise.all(allItems.map(async (itm) => {
|
|
247
|
-
const isLocalBucketFileUpload = itm.requestUploadUrl.startsWith(`${serverUrl}/uploadLocalFile`);
|
|
248
|
+
const isLocalBucketFileUpload = itm.requestUploadUrl.startsWith(`${serverUrl}/${appId}/uploadLocalFile`);
|
|
248
249
|
const formData = new form_data_1.default();
|
|
249
250
|
let file;
|
|
250
251
|
try {
|
|
@@ -303,7 +304,7 @@ class Publish extends core_1.Command {
|
|
|
303
304
|
}
|
|
304
305
|
const markAsFinishedSpinner = (0, ora_1.ora)('🔗 Marking the updates as finished...').start();
|
|
305
306
|
const results = await Promise.all(uploadUrls.map(async ({ updateId, platform, runtimeVersion }) => {
|
|
306
|
-
const markAsUploadedUrl = new URL(`${serverUrl}/markUpdateAsUploaded/${branch}`);
|
|
307
|
+
const markAsUploadedUrl = new URL(`${serverUrl}/${appId}/markUpdateAsUploaded/${branch}`);
|
|
307
308
|
markAsUploadedUrl.searchParams.set('platform', platform);
|
|
308
309
|
markAsUploadedUrl.searchParams.set('updateId', updateId);
|
|
309
310
|
markAsUploadedUrl.searchParams.set('runtimeVersion', runtimeVersion);
|
|
@@ -65,6 +65,7 @@ class Publish extends core_1.Command {
|
|
|
65
65
|
log_1.default.error("Update url is not setup in your config. Please run 'eoas init' to setup the update url");
|
|
66
66
|
process.exit(1);
|
|
67
67
|
}
|
|
68
|
+
const appId = (0, expoConfig_1.requireExpoAppId)(privateConfig);
|
|
68
69
|
let baseUrl;
|
|
69
70
|
try {
|
|
70
71
|
const parsedUrl = new URL(updateUrl);
|
|
@@ -74,9 +75,12 @@ class Publish extends core_1.Command {
|
|
|
74
75
|
log_1.default.error('Invalid URL', e);
|
|
75
76
|
process.exit(1);
|
|
76
77
|
}
|
|
77
|
-
const runtimeVersionsEndpoint = `${baseUrl}/api/branch/${branch}/runtimeVersions`;
|
|
78
|
+
const runtimeVersionsEndpoint = `${baseUrl}/api/apps/${appId}/branch/${branch}/runtimeVersions`;
|
|
78
79
|
const response = await (0, fetch_1.fetchWithRetries)(runtimeVersionsEndpoint, {
|
|
79
|
-
headers: {
|
|
80
|
+
headers: {
|
|
81
|
+
...(0, auth_1.getAuthExpoHeaders)(credentials),
|
|
82
|
+
'use-expo-auth': 'true',
|
|
83
|
+
},
|
|
80
84
|
});
|
|
81
85
|
if (!response.ok) {
|
|
82
86
|
log_1.default.error(`Failed to fetch runtime versions: ${await response.text()}`);
|
|
@@ -99,9 +103,12 @@ class Publish extends core_1.Command {
|
|
|
99
103
|
})),
|
|
100
104
|
});
|
|
101
105
|
log_1.default.log(`Selected runtime version: ${selectedRuntimeVersion.runtimeVersion}`);
|
|
102
|
-
const updatesEndpoint = `${baseUrl}/api/branch/${branch}/runtimeVersion/${selectedRuntimeVersion.runtimeVersion}/updates`;
|
|
106
|
+
const updatesEndpoint = `${baseUrl}/api/apps/${appId}/branch/${branch}/runtimeVersion/${selectedRuntimeVersion.runtimeVersion}/updates`;
|
|
103
107
|
const updatesResponse = await (0, fetch_1.fetchWithRetries)(updatesEndpoint, {
|
|
104
|
-
headers: {
|
|
108
|
+
headers: {
|
|
109
|
+
...(0, auth_1.getAuthExpoHeaders)(credentials),
|
|
110
|
+
'use-expo-auth': 'true',
|
|
111
|
+
},
|
|
105
112
|
});
|
|
106
113
|
if (!updatesResponse.ok) {
|
|
107
114
|
log_1.default.error(`Failed to fetch updates: ${await updatesResponse.text()}`);
|
|
@@ -121,7 +128,7 @@ class Publish extends core_1.Command {
|
|
|
121
128
|
})),
|
|
122
129
|
});
|
|
123
130
|
log_1.default.log(`Re-publishing update: ${selectedUpdated.update.updateUUID}`);
|
|
124
|
-
const republishUrl = new URL(`${baseUrl}/republish/${branch}`);
|
|
131
|
+
const republishUrl = new URL(`${baseUrl}/${appId}/republish/${branch}`);
|
|
125
132
|
republishUrl.searchParams.set('platform', platform);
|
|
126
133
|
republishUrl.searchParams.set('runtimeVersion', selectedRuntimeVersion.runtimeVersion);
|
|
127
134
|
republishUrl.searchParams.set('updateId', selectedUpdated.update.updateId);
|
|
@@ -6,6 +6,7 @@ export default class Publish extends Command {
|
|
|
6
6
|
static flags: {
|
|
7
7
|
platform: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
branch: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
nonInteractive: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
};
|
|
10
11
|
private sanitizeFlags;
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -28,11 +28,16 @@ class Publish extends core_1.Command {
|
|
|
28
28
|
description: 'Name of the branch to point to',
|
|
29
29
|
required: true,
|
|
30
30
|
}),
|
|
31
|
+
nonInteractive: core_1.Flags.boolean({
|
|
32
|
+
description: 'Run command in non-interactive mode',
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
31
35
|
};
|
|
32
36
|
sanitizeFlags(flags) {
|
|
33
37
|
return {
|
|
34
38
|
platform: flags.platform,
|
|
35
39
|
branch: flags.branch,
|
|
40
|
+
nonInteractive: flags.nonInteractive,
|
|
36
41
|
};
|
|
37
42
|
}
|
|
38
43
|
async run() {
|
|
@@ -42,7 +47,7 @@ class Publish extends core_1.Command {
|
|
|
42
47
|
process.exit(1);
|
|
43
48
|
}
|
|
44
49
|
const { flags } = await this.parse(Publish);
|
|
45
|
-
const { platform, branch } = this.sanitizeFlags(flags);
|
|
50
|
+
const { platform, branch, nonInteractive } = this.sanitizeFlags(flags);
|
|
46
51
|
if (!branch) {
|
|
47
52
|
log_1.default.error('Branch name is required');
|
|
48
53
|
process.exit(1);
|
|
@@ -56,14 +61,16 @@ class Publish extends core_1.Command {
|
|
|
56
61
|
log_1.default.error('Expo is not installed in this project. Please install Expo first.');
|
|
57
62
|
process.exit(1);
|
|
58
63
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
if (!nonInteractive) {
|
|
65
|
+
const confirmed = await (0, prompts_1.confirmAsync)({
|
|
66
|
+
message: `Are you sure you want to publish a rollback to the branch ${branch} ?`,
|
|
67
|
+
name: 'export',
|
|
68
|
+
type: 'confirm',
|
|
69
|
+
});
|
|
70
|
+
if (!confirmed) {
|
|
71
|
+
log_1.default.error('Operation cancelled');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
67
74
|
}
|
|
68
75
|
const privateConfig = await (0, expoConfig_1.getPrivateExpoConfigAsync)(projectDir, {
|
|
69
76
|
env: process.env,
|
|
@@ -77,6 +84,7 @@ class Publish extends core_1.Command {
|
|
|
77
84
|
log_1.default.error("Update url is not setup in your config. Please run 'eoas init' to setup the update url");
|
|
78
85
|
process.exit(1);
|
|
79
86
|
}
|
|
87
|
+
const appId = (0, expoConfig_1.requireExpoAppId)(privateConfig);
|
|
80
88
|
let baseUrl;
|
|
81
89
|
try {
|
|
82
90
|
const parsedUrl = new URL(updateUrl);
|
|
@@ -126,7 +134,7 @@ class Publish extends core_1.Command {
|
|
|
126
134
|
const rollbackSpinner = (0, ora_1.ora)('📦 Uploading rollback...').start();
|
|
127
135
|
const erroredPlatforms = [];
|
|
128
136
|
await Promise.all(runtimeVersions.map(async ({ runtimeVersion, platform }) => {
|
|
129
|
-
const rollbackUrl = new URL(`${baseUrl}/rollback/${branch}`);
|
|
137
|
+
const rollbackUrl = new URL(`${baseUrl}/${appId}/rollback/${branch}`);
|
|
130
138
|
rollbackUrl.searchParams.set('commitHash', commitHash ?? '');
|
|
131
139
|
rollbackUrl.searchParams.set('platform', platform);
|
|
132
140
|
rollbackUrl.searchParams.set('runtimeVersion', runtimeVersion ?? '');
|
package/dist/lib/expoConfig.d.ts
CHANGED
|
@@ -21,5 +21,6 @@ export declare function ensureExpoConfigExists(projectDir: string): void;
|
|
|
21
21
|
export declare function isUsingStaticExpoConfig(projectDir: string): boolean;
|
|
22
22
|
export declare function getPublicExpoConfigAsync(projectDir: string, opts?: ExpoConfigOptions): Promise<PublicExpoConfig>;
|
|
23
23
|
export declare function getExpoConfigUpdateUrl(config: ExpoConfig): string | undefined;
|
|
24
|
+
export declare function requireExpoAppId(config: ExpoConfig): string;
|
|
24
25
|
export declare function createOrModifyExpoConfigAsync(projectDir: string, exp: Partial<ExpoConfig>): Promise<void>;
|
|
25
26
|
export declare function resolveServerUrl(config: ExpoConfig): Promise<string>;
|
package/dist/lib/expoConfig.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveServerUrl = exports.createOrModifyExpoConfigAsync = exports.getExpoConfigUpdateUrl = exports.getPublicExpoConfigAsync = exports.isUsingStaticExpoConfig = exports.ensureExpoConfigExists = exports.getPrivateExpoConfigAsync = exports.RequestedPlatform = void 0;
|
|
3
|
+
exports.resolveServerUrl = exports.createOrModifyExpoConfigAsync = exports.requireExpoAppId = exports.getExpoConfigUpdateUrl = exports.getPublicExpoConfigAsync = exports.isUsingStaticExpoConfig = exports.ensureExpoConfigExists = exports.getPrivateExpoConfigAsync = exports.RequestedPlatform = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
// This file is copied from eas-cli[https://github.com/expo/eas-cli] to ensure consistent user experience across the CLI.
|
|
6
6
|
const config_1 = require("@expo/config");
|
|
@@ -111,6 +111,18 @@ function getExpoConfigUpdateUrl(config) {
|
|
|
111
111
|
return config.updates?.url;
|
|
112
112
|
}
|
|
113
113
|
exports.getExpoConfigUpdateUrl = getExpoConfigUpdateUrl;
|
|
114
|
+
function requireExpoAppId(config) {
|
|
115
|
+
const appId = config.updates
|
|
116
|
+
?.requestHeaders?.['expo-app-id'];
|
|
117
|
+
if (!appId) {
|
|
118
|
+
log_1.default.error("Your Expo config is missing the 'expo-app-id' entry in updates.requestHeaders.");
|
|
119
|
+
log_1.default.error("This usually means you're running eoas v3+ against a v3-style single-app config or your config is missing the 'expo-app-id' entry.");
|
|
120
|
+
log_1.default.error("Fix: run 'npx eoas init' to migrate, or pin to the previous CLI via 'npx eoas@2 ...'.");
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
return appId;
|
|
124
|
+
}
|
|
125
|
+
exports.requireExpoAppId = requireExpoAppId;
|
|
114
126
|
async function createOrModifyExpoConfigAsync(projectDir, exp) {
|
|
115
127
|
try {
|
|
116
128
|
ensureExpoConfigExists(projectDir);
|
|
@@ -208,7 +220,7 @@ async function resolveServerUrl(config) {
|
|
|
208
220
|
const parsedUrl = new URL(updateUrl);
|
|
209
221
|
baseUrl = parsedUrl.origin;
|
|
210
222
|
}
|
|
211
|
-
catch
|
|
223
|
+
catch {
|
|
212
224
|
throw new Error('Invalid update URL.');
|
|
213
225
|
}
|
|
214
226
|
return baseUrl;
|
package/package.json
CHANGED
package/dist/lib/channel.d.ts
DELETED
package/dist/lib/channel.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveReleaseChannelDynamicallyFromBranch = void 0;
|
|
4
|
-
const auth_1 = require("./auth");
|
|
5
|
-
const fetch_1 = require("./fetch");
|
|
6
|
-
async function resolveReleaseChannelDynamicallyFromBranch(baseUrl, branch, credentials) {
|
|
7
|
-
const branchesEndpoint = `${baseUrl}/api/branches`;
|
|
8
|
-
const response = await (0, fetch_1.fetchWithRetries)(branchesEndpoint, {
|
|
9
|
-
headers: { ...(0, auth_1.getAuthExpoHeaders)(credentials), 'use-expo-auth': 'true' },
|
|
10
|
-
});
|
|
11
|
-
if (!response.ok) {
|
|
12
|
-
throw new Error(`Failed to retrieve branches from server: ${await response.text()}`);
|
|
13
|
-
}
|
|
14
|
-
const branches = (await response.json());
|
|
15
|
-
const branchInfo = branches.find(b => b.branchName === branch);
|
|
16
|
-
if (!branchInfo) {
|
|
17
|
-
throw new Error(`Branch ${branch} not found`);
|
|
18
|
-
}
|
|
19
|
-
if (!branchInfo.releaseChannel) {
|
|
20
|
-
throw new Error(`Branch ${branch} does not have a release channel linked`);
|
|
21
|
-
}
|
|
22
|
-
return branchInfo.releaseChannel;
|
|
23
|
-
}
|
|
24
|
-
exports.resolveReleaseChannelDynamicallyFromBranch = resolveReleaseChannelDynamicallyFromBranch;
|