@capgo/cli 7.18.10 → 7.18.12
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/index.js +180 -180
- package/dist/package.json +1 -1
- package/dist/src/build/request.d.ts +48 -0
- package/dist/src/build/request.d.ts.map +1 -0
- package/dist/src/build/request.js +158 -0
- package/dist/src/build/request.js.map +1 -0
- package/dist/src/bundle/upload.d.ts.map +1 -1
- package/dist/src/bundle/upload.js +160 -1
- package/dist/src/bundle/upload.js.map +1 -1
- package/dist/src/bundle/upload_interface.d.ts +1 -0
- package/dist/src/bundle/upload_interface.d.ts.map +1 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/sdk.js +165 -165
- package/package.json +1 -1
package/dist/package.json
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { OptionsBase } from '../utils';
|
|
2
|
+
export interface BuildCredentials {
|
|
3
|
+
BUILD_CERTIFICATE_BASE64?: string;
|
|
4
|
+
BUILD_PROVISION_PROFILE_BASE64?: string;
|
|
5
|
+
BUILD_PROVISION_PROFILE_BASE64_PROD?: string;
|
|
6
|
+
P12_PASSWORD?: string;
|
|
7
|
+
APPLE_ID?: string;
|
|
8
|
+
APPLE_APP_SPECIFIC_PASSWORD?: string;
|
|
9
|
+
APPLE_KEY_ID?: string;
|
|
10
|
+
APPLE_ISSUER_ID?: string;
|
|
11
|
+
APPLE_KEY_CONTENT?: string;
|
|
12
|
+
APP_STORE_CONNECT_TEAM_ID?: string;
|
|
13
|
+
ANDROID_KEYSTORE_FILE?: string;
|
|
14
|
+
KEYSTORE_KEY_ALIAS?: string;
|
|
15
|
+
KEYSTORE_KEY_PASSWORD?: string;
|
|
16
|
+
KEYSTORE_STORE_PASSWORD?: string;
|
|
17
|
+
PLAY_CONFIG_JSON?: string;
|
|
18
|
+
[key: string]: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export interface BuildRequestOptions extends OptionsBase {
|
|
21
|
+
path?: string;
|
|
22
|
+
lane: 'ios' | 'android';
|
|
23
|
+
buildMode?: 'debug' | 'release';
|
|
24
|
+
credentials?: BuildCredentials;
|
|
25
|
+
userId?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface BuildRequestResponse {
|
|
28
|
+
jobId: string;
|
|
29
|
+
folder: string;
|
|
30
|
+
status: 'queued' | 'reserved';
|
|
31
|
+
artifactKey: string;
|
|
32
|
+
uploadUrl: string;
|
|
33
|
+
machine?: {
|
|
34
|
+
id: string;
|
|
35
|
+
ip: string;
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
} | null;
|
|
38
|
+
}
|
|
39
|
+
export interface BuildRequestResult {
|
|
40
|
+
success: boolean;
|
|
41
|
+
jobId?: string;
|
|
42
|
+
uploadUrl?: string;
|
|
43
|
+
status?: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function requestBuildInternal(appId: string, options: BuildRequestOptions, silent?: boolean): Promise<BuildRequestResult>;
|
|
47
|
+
export declare function requestBuildCommand(appId: string, options: BuildRequestOptions): Promise<void>;
|
|
48
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/build/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAS3C,MAAM,WAAW,gBAAgB;IAE/B,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,mCAAmC,CAAC,EAAE,MAAM,CAAA;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAGlC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAGzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAClC;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,KAAK,GAAG,SAAS,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC/B,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAA;QACV,EAAE,EAAE,MAAM,CAAA;QACV,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACvB,GAAG,IAAI,CAAA;CACT;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA2BD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA+JnI;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpG"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { mkdir, readFile, rm, stat } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { basename, join, resolve } from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { log } from '@clack/prompts';
|
|
7
|
+
import { createSupabaseClient, findSavedKey, getConfig, verifyUser } from '../utils';
|
|
8
|
+
async function zipDirectory(projectDir, outputPath) {
|
|
9
|
+
return new Promise((resolvePromise, reject) => {
|
|
10
|
+
const args = ['-rq', outputPath, '.'];
|
|
11
|
+
const child = spawn('zip', args, { cwd: projectDir, stdio: 'inherit' });
|
|
12
|
+
child.on('error', (error) => {
|
|
13
|
+
if (error.code === 'ENOENT') {
|
|
14
|
+
reject(new Error('zip command not found. Please install zip utility.'));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
reject(error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
child.on('close', (code) => {
|
|
21
|
+
if (code === 0) {
|
|
22
|
+
resolvePromise();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
reject(new Error(`zip process exited with code ${code}`));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export async function requestBuildInternal(appId, options, silent = false) {
|
|
31
|
+
try {
|
|
32
|
+
options.apikey = options.apikey || findSavedKey(silent);
|
|
33
|
+
const config = await getConfig();
|
|
34
|
+
appId = appId || config?.config.appId;
|
|
35
|
+
if (!appId) {
|
|
36
|
+
throw new Error('Missing argument, you need to provide a appId, or be in a capacitor project');
|
|
37
|
+
}
|
|
38
|
+
const projectDir = resolve(options.path || process.cwd());
|
|
39
|
+
const supabase = await createSupabaseClient(options.apikey, options.supaHost, options.supaAnon);
|
|
40
|
+
await verifyUser(supabase, options.apikey, ['write', 'all']);
|
|
41
|
+
if (!silent) {
|
|
42
|
+
log.info(`Requesting native build for ${appId}`);
|
|
43
|
+
log.info(`Platform: ${options.lane}`);
|
|
44
|
+
log.info(`Project: ${projectDir}`);
|
|
45
|
+
}
|
|
46
|
+
// Prepare request payload for Capgo backend
|
|
47
|
+
const requestPayload = {
|
|
48
|
+
app_id: appId,
|
|
49
|
+
platform: options.lane,
|
|
50
|
+
};
|
|
51
|
+
// Add build mode if specified
|
|
52
|
+
if (options.buildMode) {
|
|
53
|
+
requestPayload.build_mode = options.buildMode;
|
|
54
|
+
}
|
|
55
|
+
// Add credentials if provided
|
|
56
|
+
if (options.credentials) {
|
|
57
|
+
requestPayload.credentials = options.credentials;
|
|
58
|
+
}
|
|
59
|
+
// Request build from Capgo backend (POST /build/request)
|
|
60
|
+
if (!silent)
|
|
61
|
+
log.info('Requesting build from Capgo...');
|
|
62
|
+
const host = options.supaHost || 'https://api.capgo.app';
|
|
63
|
+
const response = await fetch(`${host}/build/request`, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
'Content-Type': 'application/json',
|
|
67
|
+
'authorization': options.apikey,
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify(requestPayload),
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const errorText = await response.text();
|
|
73
|
+
throw new Error(`Failed to request build: ${response.status} - ${errorText}`);
|
|
74
|
+
}
|
|
75
|
+
const buildRequest = await response.json();
|
|
76
|
+
if (!silent) {
|
|
77
|
+
log.success(`Build job created: ${buildRequest.job_id}`);
|
|
78
|
+
log.info(`Status: ${buildRequest.status}`);
|
|
79
|
+
}
|
|
80
|
+
// Create temporary directory for zip
|
|
81
|
+
const tempDir = join(tmpdir(), `capgo-build-${Date.now()}`);
|
|
82
|
+
await mkdir(tempDir, { recursive: true });
|
|
83
|
+
const zipPath = join(tempDir, `${basename(projectDir)}.zip`);
|
|
84
|
+
try {
|
|
85
|
+
// Zip the project directory
|
|
86
|
+
if (!silent)
|
|
87
|
+
log.info(`Zipping project from ${projectDir}...`);
|
|
88
|
+
await zipDirectory(projectDir, zipPath);
|
|
89
|
+
const zipStats = await stat(zipPath);
|
|
90
|
+
const sizeMB = (zipStats.size / 1024 / 1024).toFixed(2);
|
|
91
|
+
if (!silent)
|
|
92
|
+
log.success(`Created zip: ${zipPath} (${sizeMB} MB)`);
|
|
93
|
+
// Upload to presigned R2 URL
|
|
94
|
+
if (!silent)
|
|
95
|
+
log.info('Uploading to builder...');
|
|
96
|
+
const fileBuffer = await readFile(zipPath);
|
|
97
|
+
const uploadResponse = await fetch(buildRequest.upload_url, {
|
|
98
|
+
method: 'PUT',
|
|
99
|
+
headers: {
|
|
100
|
+
'Content-Type': 'application/zip',
|
|
101
|
+
'Content-Length': String(zipStats.size),
|
|
102
|
+
},
|
|
103
|
+
body: fileBuffer,
|
|
104
|
+
});
|
|
105
|
+
if (!uploadResponse.ok) {
|
|
106
|
+
const errorText = await uploadResponse.text();
|
|
107
|
+
throw new Error(`Upload failed: ${uploadResponse.status} - ${errorText}`);
|
|
108
|
+
}
|
|
109
|
+
if (!silent)
|
|
110
|
+
log.success('Upload complete!');
|
|
111
|
+
// Start the build job via Capgo backend
|
|
112
|
+
if (!silent)
|
|
113
|
+
log.info('Starting build job...');
|
|
114
|
+
const startResponse = await fetch(`${host}/build/start/${buildRequest.build_request_id}`, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
'authorization': options.apikey,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
if (!startResponse.ok) {
|
|
121
|
+
const errorText = await startResponse.text();
|
|
122
|
+
throw new Error(`Failed to start build: ${startResponse.status} - ${errorText}`);
|
|
123
|
+
}
|
|
124
|
+
const startResult = await startResponse.json();
|
|
125
|
+
if (!silent) {
|
|
126
|
+
log.success('Build started successfully!');
|
|
127
|
+
log.info(`Job ID: ${buildRequest.job_id}`);
|
|
128
|
+
log.info('You can monitor the build in the Capgo dashboard.');
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
jobId: buildRequest.job_id,
|
|
133
|
+
uploadUrl: buildRequest.upload_url,
|
|
134
|
+
status: startResult.status || buildRequest.status,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
// Clean up temp directory
|
|
139
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
144
|
+
if (!silent)
|
|
145
|
+
log.error(errorMessage);
|
|
146
|
+
return {
|
|
147
|
+
success: false,
|
|
148
|
+
error: errorMessage,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export async function requestBuildCommand(appId, options) {
|
|
153
|
+
const result = await requestBuildInternal(appId, options, false);
|
|
154
|
+
if (!result.success) {
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../../src/build/request.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,OAAO,MAAM,cAAc,CAAA;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAuDpF,KAAK,UAAU,YAAY,CAAC,UAAkB,EAAE,UAAkB;IAChE,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QAEvE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;YACjD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAA;YACzE,CAAC;iBACI,CAAC;gBACJ,MAAM,CAAC,KAAK,CAAC,CAAA;YACf,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,cAAc,EAAE,CAAA;YAClB,CAAC;iBACI,CAAC;gBACJ,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC,CAAA;YAC3D,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAa,EAAE,OAA4B,EAAE,MAAM,GAAG,KAAK;IACpG,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;QAChC,KAAK,GAAG,KAAK,IAAI,MAAM,EAAE,MAAM,CAAC,KAAK,CAAA;QAErC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAA;QAChG,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAEzD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;QAC/F,MAAM,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;QAE5D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,IAAI,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAA;YAChD,GAAG,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;YACrC,GAAG,CAAC,IAAI,CAAC,YAAY,UAAU,EAAE,CAAC,CAAA;QACpC,CAAC;QAED,4CAA4C;QAC5C,MAAM,cAAc,GAKhB;YACF,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,OAAO,CAAC,IAAI;SACvB,CAAA;QAED,8BAA8B;QAC9B,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,cAAc,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAA;QAC/C,CAAC;QAED,8BAA8B;QAC9B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QAClD,CAAC;QAED,yDAAyD;QACzD,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAE5C,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,uBAAuB,CAAA;QACxD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,gBAAgB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,OAAO,CAAC,MAAM;aAChC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;SACrC,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAA;QAC/E,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAKvC,CAAA;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,OAAO,CAAC,sBAAsB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;YACxD,GAAG,CAAC,IAAI,CAAC,WAAW,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5C,CAAC;QAED,qCAAqC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAC3D,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAE5D,IAAI,CAAC;YACH,4BAA4B;YAC5B,IAAI,CAAC,MAAM;gBACT,GAAG,CAAC,IAAI,CAAC,wBAAwB,UAAU,KAAK,CAAC,CAAA;YAEnD,MAAM,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YAEvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAA;YACpC,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAEvD,IAAI,CAAC,MAAM;gBACT,GAAG,CAAC,OAAO,CAAC,gBAAgB,OAAO,KAAK,MAAM,MAAM,CAAC,CAAA;YAEvD,6BAA6B;YAC7B,IAAI,CAAC,MAAM;gBACT,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;YAErC,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;YAC1C,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;gBAC1D,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,cAAc,EAAE,iBAAiB;oBACjC,gBAAgB,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;iBACxC;gBACD,IAAI,EAAE,UAAU;aACjB,CAAC,CAAA;YAEF,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAA;gBAC7C,MAAM,IAAI,KAAK,CAAC,kBAAkB,cAAc,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAA;YAC3E,CAAC;YAED,IAAI,CAAC,MAAM;gBACT,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;YAEjC,wCAAwC;YACxC,IAAI,CAAC,MAAM;gBACT,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;YAEnC,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,gBAAgB,YAAY,CAAC,gBAAgB,EAAE,EAAE;gBACxF,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,eAAe,EAAE,OAAO,CAAC,MAAM;iBAChC;aACF,CAAC,CAAA;YAEF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;gBACtB,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAA;gBAC5C,MAAM,IAAI,KAAK,CAAC,0BAA0B,aAAa,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAA;YAClF,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,IAAI,EAAyB,CAAA;YAErE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAA;gBAC1C,GAAG,CAAC,IAAI,CAAC,WAAW,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;gBAC1C,GAAG,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAA;YAC/D,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,YAAY,CAAC,MAAM;gBAC1B,SAAS,EAAE,YAAY,CAAC,UAAU;gBAClC,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM;aAClD,CAAA;QACH,CAAC;gBACO,CAAC;YACP,0BAA0B;YAC1B,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC3E,IAAI,CAAC,MAAM;YACT,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAEzB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,YAAY;SACpB,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAa,EAAE,OAA4B;IACnF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAEhE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/bundle/upload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAgBvD,OAAO,EAA8F,oBAAoB,EAAmb,MAAM,UAAU,CAAA;AAI5jB,KAAK,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAA;AAIpE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IACtC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA+cD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,0BAalG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/bundle/upload.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAgBvD,OAAO,EAA8F,oBAAoB,EAAmb,MAAM,UAAU,CAAA;AAI5jB,KAAK,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAA;AAIpE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IACtC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA+cD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,0BAalG;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyc3H;AA2CD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,iBASxE"}
|
|
@@ -434,34 +434,95 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
434
434
|
const pm = getPMAndCommand();
|
|
435
435
|
await checkAlerts();
|
|
436
436
|
const { s3Region, s3Apikey, s3Apisecret, s3BucketName, s3Endpoint, s3Port, s3SSL } = options;
|
|
437
|
+
if (options.verbose) {
|
|
438
|
+
log.info(`[Verbose] Starting upload process with options:`);
|
|
439
|
+
log.info(` - API key: ${options.apikey ? 'provided' : 'from saved key'}`);
|
|
440
|
+
log.info(` - Path: ${options.path || 'from capacitor config'}`);
|
|
441
|
+
log.info(` - Channel: ${options.channel || 'from default upload channel'}`);
|
|
442
|
+
log.info(` - Bundle: ${options.bundle || 'auto-detected'}`);
|
|
443
|
+
log.info(` - External: ${options.external || 'false'}`);
|
|
444
|
+
log.info(` - Encryption: ${options.keyV2 || options.keyDataV2 ? 'v2' : options.key === false ? 'disabled' : 'auto'}`);
|
|
445
|
+
log.info(` - Upload method: ${options.tus ? 'TUS' : options.zip ? 'ZIP' : 'auto'}`);
|
|
446
|
+
log.info(` - Delta updates: ${options.delta || options.partial ? 'enabled' : 'disabled'}`);
|
|
447
|
+
}
|
|
437
448
|
const apikey = getApikey(options);
|
|
449
|
+
if (options.verbose)
|
|
450
|
+
log.info(`[Verbose] API key retrieved successfully`);
|
|
438
451
|
const extConfig = await getConfig();
|
|
452
|
+
if (options.verbose)
|
|
453
|
+
log.info(`[Verbose] Capacitor config loaded successfully`);
|
|
439
454
|
const fileConfig = await getRemoteFileConfig();
|
|
455
|
+
if (options.verbose) {
|
|
456
|
+
log.info(`[Verbose] Remote file config retrieved:`);
|
|
457
|
+
log.info(` - Max upload length: ${Math.floor(fileConfig.maxUploadLength / 1024 / 1024)} MB`);
|
|
458
|
+
log.info(` - Alert upload size: ${Math.floor(fileConfig.alertUploadSize / 1024 / 1024)} MB`);
|
|
459
|
+
log.info(` - TUS upload: ${fileConfig.TUSUpload ? 'enabled' : 'disabled'}`);
|
|
460
|
+
log.info(` - TUS upload forced: ${fileConfig.TUSUploadForced ? 'yes' : 'no'}`);
|
|
461
|
+
log.info(` - Partial upload: ${fileConfig.partialUpload ? 'enabled' : 'disabled'}`);
|
|
462
|
+
log.info(` - Max chunk size: ${Math.floor(fileConfig.maxChunkSize / 1024 / 1024)} MB`);
|
|
463
|
+
}
|
|
440
464
|
const { appid, path } = getAppIdAndPath(preAppid, options, extConfig.config);
|
|
465
|
+
if (options.verbose)
|
|
466
|
+
log.info(`[Verbose] App ID: ${appid}, Build path: ${path}`);
|
|
441
467
|
const bundle = await getBundle(extConfig.config, options);
|
|
468
|
+
if (options.verbose)
|
|
469
|
+
log.info(`[Verbose] Bundle version: ${bundle}`);
|
|
442
470
|
const defaultStorageProvider = options.external ? 'external' : 'r2-direct';
|
|
443
471
|
let encryptionMethod = 'none';
|
|
444
472
|
if (options.autoSetBundle) {
|
|
445
473
|
await updateConfigUpdater({ version: bundle });
|
|
474
|
+
if (options.verbose)
|
|
475
|
+
log.info(`[Verbose] Auto-set bundle version in capacitor.config.json`);
|
|
446
476
|
}
|
|
447
477
|
checkNotifyAppReady(options, path);
|
|
478
|
+
if (options.verbose)
|
|
479
|
+
log.info(`[Verbose] Code check passed (notifyAppReady found and index.html present)`);
|
|
448
480
|
log.info(`Upload ${appid}@${bundle} started from path "${path}" to Capgo cloud`);
|
|
449
481
|
const localConfig = await getLocalConfig();
|
|
482
|
+
if (options.verbose)
|
|
483
|
+
log.info(`[Verbose] Local config loaded: host=${localConfig.hostWeb}`);
|
|
450
484
|
if (options.supaHost && options.supaAnon) {
|
|
451
485
|
log.info('Using custom supabase instance from provided options');
|
|
452
486
|
localConfig.supaHost = options.supaHost;
|
|
453
487
|
localConfig.supaKey = options.supaAnon;
|
|
488
|
+
if (options.verbose)
|
|
489
|
+
log.info(`[Verbose] Custom Supabase host: ${options.supaHost}`);
|
|
454
490
|
}
|
|
455
491
|
const supabase = await createSupabaseClient(apikey, options.supaHost, options.supaAnon);
|
|
492
|
+
if (options.verbose)
|
|
493
|
+
log.info(`[Verbose] Supabase client created successfully`);
|
|
456
494
|
const userId = await verifyUser(supabase, apikey, ['write', 'all', 'upload']);
|
|
495
|
+
if (options.verbose)
|
|
496
|
+
log.info(`[Verbose] User verified successfully, user_id: ${userId}`);
|
|
457
497
|
const channel = options.channel || await getDefaulUploadChannel(appid, supabase, localConfig.hostWeb) || 'dev';
|
|
498
|
+
if (options.verbose)
|
|
499
|
+
log.info(`[Verbose] Target channel: ${channel}`);
|
|
458
500
|
// Now if it does exist we will fetch the org id
|
|
459
501
|
const orgId = await getOrganizationId(supabase, appid);
|
|
502
|
+
if (options.verbose)
|
|
503
|
+
log.info(`[Verbose] Organization ID: ${orgId}`);
|
|
460
504
|
await checkRemoteCliMessages(supabase, orgId, pack.version);
|
|
505
|
+
if (options.verbose)
|
|
506
|
+
log.info(`[Verbose] Remote CLI messages checked`);
|
|
461
507
|
await checkPlanValidUpload(supabase, orgId, apikey, appid, true);
|
|
508
|
+
if (options.verbose)
|
|
509
|
+
log.info(`[Verbose] Plan validation passed`);
|
|
462
510
|
await checkTrial(supabase, orgId, localConfig);
|
|
511
|
+
if (options.verbose)
|
|
512
|
+
log.info(`[Verbose] Trial check completed`);
|
|
513
|
+
if (options.verbose)
|
|
514
|
+
log.info(`[Verbose] Checking compatibility with channel ${channel}...`);
|
|
463
515
|
const { nativePackages, minUpdateVersion } = await verifyCompatibility(supabase, pm, options, channel, appid, bundle);
|
|
516
|
+
if (options.verbose) {
|
|
517
|
+
log.info(`[Verbose] Compatibility check completed:`);
|
|
518
|
+
log.info(` - Native packages: ${nativePackages ? nativePackages.length : 0}`);
|
|
519
|
+
log.info(` - Min update version: ${minUpdateVersion || 'none'}`);
|
|
520
|
+
}
|
|
521
|
+
if (options.verbose)
|
|
522
|
+
log.info(`[Verbose] Checking if version ${bundle} already exists...`);
|
|
464
523
|
const versionAlreadyExists = await checkVersionExists(supabase, appid, bundle, options.versionExistsOk);
|
|
524
|
+
if (options.verbose)
|
|
525
|
+
log.info(`[Verbose] Version exists check: ${versionAlreadyExists ? 'yes (skipping)' : 'no (continuing)'}`);
|
|
465
526
|
if (versionAlreadyExists) {
|
|
466
527
|
return {
|
|
467
528
|
success: true,
|
|
@@ -497,6 +558,8 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
497
558
|
let zipped = null;
|
|
498
559
|
let finalKeyData = '';
|
|
499
560
|
if (!options.external) {
|
|
561
|
+
if (options.verbose)
|
|
562
|
+
log.info(`[Verbose] Preparing bundle file from path: ${path}`);
|
|
500
563
|
const { zipped: _zipped, ivSessionKey, checksum, sessionKey: sk, encryptionMethod: em, finalKeyData: fkd } = await prepareBundleFile(path, options, apikey, orgId, appid, fileConfig.maxUploadLength, fileConfig.alertUploadSize);
|
|
501
564
|
versionData.session_key = ivSessionKey;
|
|
502
565
|
versionData.checksum = checksum;
|
|
@@ -504,11 +567,24 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
504
567
|
zipped = _zipped;
|
|
505
568
|
encryptionMethod = em;
|
|
506
569
|
finalKeyData = fkd;
|
|
570
|
+
if (options.verbose) {
|
|
571
|
+
log.info(`[Verbose] Bundle prepared:`);
|
|
572
|
+
log.info(` - Size: ${Math.floor((_zipped?.byteLength ?? 0) / 1024)} KB`);
|
|
573
|
+
log.info(` - Checksum: ${checksum}`);
|
|
574
|
+
log.info(` - Encryption: ${em}`);
|
|
575
|
+
log.info(` - IV Session Key: ${ivSessionKey ? 'present' : 'none'}`);
|
|
576
|
+
}
|
|
507
577
|
if (!options.ignoreChecksumCheck) {
|
|
578
|
+
if (options.verbose)
|
|
579
|
+
log.info(`[Verbose] Checking for duplicate checksum...`);
|
|
508
580
|
await checkChecksum(supabase, appid, channel, checksum);
|
|
581
|
+
if (options.verbose)
|
|
582
|
+
log.info(`[Verbose] Checksum is unique`);
|
|
509
583
|
}
|
|
510
584
|
}
|
|
511
585
|
else {
|
|
586
|
+
if (options.verbose)
|
|
587
|
+
log.info(`[Verbose] Using external URL: ${options.external}`);
|
|
512
588
|
await sendEvent(apikey, {
|
|
513
589
|
channel: 'app',
|
|
514
590
|
event: 'App external',
|
|
@@ -521,22 +597,38 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
521
597
|
});
|
|
522
598
|
versionData.session_key = options.ivSessionKey;
|
|
523
599
|
versionData.checksum = options.encryptedChecksum;
|
|
600
|
+
if (options.verbose) {
|
|
601
|
+
log.info(`[Verbose] External bundle configured:`);
|
|
602
|
+
log.info(` - URL: ${options.external}`);
|
|
603
|
+
log.info(` - IV Session Key: ${options.ivSessionKey ? 'provided' : 'none'}`);
|
|
604
|
+
log.info(` - Encrypted Checksum: ${options.encryptedChecksum ? 'provided' : 'none'}`);
|
|
605
|
+
}
|
|
524
606
|
}
|
|
525
607
|
if (options.zip) {
|
|
526
608
|
options.tus = false;
|
|
609
|
+
if (options.verbose)
|
|
610
|
+
log.info(`[Verbose] Upload method: ZIP (explicitly set via --zip)`);
|
|
527
611
|
}
|
|
528
612
|
// ALLOW TO OVERRIDE THE FILE CONFIG WITH THE OPTIONS IF THE FILE CONFIG IS FORCED
|
|
529
613
|
else if (!fileConfig.TUSUpload || options.external) {
|
|
530
614
|
options.tus = false;
|
|
615
|
+
if (options.verbose)
|
|
616
|
+
log.info(`[Verbose] Upload method: Standard (TUS not available or external URL)`);
|
|
531
617
|
}
|
|
532
618
|
else {
|
|
533
619
|
options.tus = options.tus || fileConfig.TUSUploadForced;
|
|
620
|
+
if (options.verbose)
|
|
621
|
+
log.info(`[Verbose] Upload method: ${options.tus ? 'TUS (resumable)' : 'Standard'}`);
|
|
534
622
|
}
|
|
535
623
|
if (!fileConfig.partialUpload || options.external) {
|
|
536
624
|
options.delta = false;
|
|
625
|
+
if (options.verbose && options.external)
|
|
626
|
+
log.info(`[Verbose] Delta updates disabled (not available with external URLs)`);
|
|
537
627
|
}
|
|
538
628
|
else {
|
|
539
629
|
options.delta = options.delta || options.partial || options.deltaOnly || options.partialOnly || fileConfig.partialUploadForced;
|
|
630
|
+
if (options.verbose)
|
|
631
|
+
log.info(`[Verbose] Delta updates: ${options.delta ? 'enabled' : 'disabled'}`);
|
|
540
632
|
}
|
|
541
633
|
if (options.encryptPartial && encryptionMethod === 'v1')
|
|
542
634
|
uploadFail('You cannot encrypt the partial update if you are not using the v2 encryption method');
|
|
@@ -549,13 +641,23 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
549
641
|
const coerced = coerceVersion(updaterVersion);
|
|
550
642
|
if (updaterVersion && coerced && semverGte(coerced.version, '6.14.4')) {
|
|
551
643
|
log.info(`Auto-enabling partial update encryption for updater version ${coerced.version} (> 6.14.4)`);
|
|
644
|
+
if (options.verbose)
|
|
645
|
+
log.info(`[Verbose] Partial encryption auto-enabled for updater >= 6.14.4`);
|
|
552
646
|
options.encryptPartial = true;
|
|
553
647
|
}
|
|
554
648
|
}
|
|
649
|
+
if (options.verbose && options.delta)
|
|
650
|
+
log.info(`[Verbose] Preparing delta/partial update manifest...`);
|
|
555
651
|
const manifest = options.delta ? await prepareBundlePartialFiles(path, apikey, orgId, appid, options.encryptPartial ? encryptionMethod : 'none', finalKeyData) : [];
|
|
652
|
+
if (options.verbose && options.delta)
|
|
653
|
+
log.info(`[Verbose] Delta manifest prepared with ${manifest.length} files`);
|
|
654
|
+
if (options.verbose)
|
|
655
|
+
log.info(`[Verbose] Creating version record in database...`);
|
|
556
656
|
const { error: dbError } = await updateOrCreateVersion(supabase, versionData);
|
|
557
657
|
if (dbError)
|
|
558
658
|
uploadFail(`Cannot add bundle ${formatError(dbError)}`);
|
|
659
|
+
if (options.verbose)
|
|
660
|
+
log.info(`[Verbose] Version record created successfully`);
|
|
559
661
|
if (options.tusChunkSize && options.tusChunkSize > fileConfig.maxChunkSize) {
|
|
560
662
|
log.error(`Chunk size ${options.tusChunkSize} is greater than the maximum chunk size ${fileConfig.maxChunkSize}, using the maximum chunk size`);
|
|
561
663
|
options.tusChunkSize = fileConfig.maxChunkSize;
|
|
@@ -563,10 +665,20 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
563
665
|
else if (!options.tusChunkSize) {
|
|
564
666
|
options.tusChunkSize = fileConfig.maxChunkSize;
|
|
565
667
|
}
|
|
668
|
+
if (options.verbose)
|
|
669
|
+
log.info(`[Verbose] TUS chunk size: ${Math.floor(options.tusChunkSize / 1024 / 1024)} MB`);
|
|
566
670
|
if (zipped && (s3BucketName || s3Endpoint || s3Region || s3Apikey || s3Apisecret || s3Port || s3SSL)) {
|
|
567
671
|
if (!s3BucketName || !s3Endpoint || !s3Region || !s3Apikey || !s3Apisecret || !s3Port)
|
|
568
672
|
uploadFail('Missing argument, for S3 upload you need to provide a bucket name, endpoint, region, port, API key, and API secret');
|
|
569
673
|
log.info('Uploading to S3');
|
|
674
|
+
if (options.verbose) {
|
|
675
|
+
log.info(`[Verbose] S3 configuration:`);
|
|
676
|
+
log.info(` - Endpoint: ${s3Endpoint}`);
|
|
677
|
+
log.info(` - Region: ${s3Region}`);
|
|
678
|
+
log.info(` - Bucket: ${s3BucketName}`);
|
|
679
|
+
log.info(` - Port: ${s3Port}`);
|
|
680
|
+
log.info(` - SSL: ${s3SSL ? 'enabled' : 'disabled'}`);
|
|
681
|
+
}
|
|
570
682
|
const endPoint = s3SSL ? `https://${s3Endpoint}` : `http://${s3Endpoint}`;
|
|
571
683
|
const s3Client = new S3Client({
|
|
572
684
|
endPoint: s3Endpoint,
|
|
@@ -579,18 +691,29 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
579
691
|
});
|
|
580
692
|
const fileName = `${appid}-${bundle}`;
|
|
581
693
|
const encodeFileName = encodeURIComponent(fileName);
|
|
694
|
+
if (options.verbose)
|
|
695
|
+
log.info(`[Verbose] Uploading to S3 as: ${fileName}`);
|
|
582
696
|
await s3Client.putObject(fileName, Uint8Array.from(zipped));
|
|
583
697
|
versionData.external_url = `${endPoint}/${encodeFileName}`;
|
|
584
698
|
versionData.storage_provider = 'external';
|
|
699
|
+
if (options.verbose)
|
|
700
|
+
log.info(`[Verbose] S3 upload complete, external URL: ${versionData.external_url}`);
|
|
585
701
|
}
|
|
586
702
|
else if (zipped) {
|
|
587
703
|
if (!options.partialOnly && !options.deltaOnly) {
|
|
704
|
+
if (options.verbose)
|
|
705
|
+
log.info(`[Verbose] Starting full bundle upload to Capgo Cloud...`);
|
|
588
706
|
await uploadBundleToCapgoCloud(apikey, supabase, appid, bundle, orgId, zipped, options, options.tusChunkSize);
|
|
589
707
|
}
|
|
708
|
+
else if (options.verbose) {
|
|
709
|
+
log.info(`[Verbose] Skipping full bundle upload (delta-only mode)`);
|
|
710
|
+
}
|
|
590
711
|
let finalManifest = null;
|
|
591
712
|
try {
|
|
592
713
|
if (options.dryUpload) {
|
|
593
714
|
options.delta = false;
|
|
715
|
+
if (options.verbose)
|
|
716
|
+
log.info(`[Verbose] Dry upload mode: skipping delta upload`);
|
|
594
717
|
}
|
|
595
718
|
const encryptionData = versionData.session_key && options.encryptPartial && sessionKey
|
|
596
719
|
? {
|
|
@@ -598,33 +721,62 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
598
721
|
ivSessionKey: versionData.session_key,
|
|
599
722
|
}
|
|
600
723
|
: undefined;
|
|
724
|
+
if (options.verbose && options.delta) {
|
|
725
|
+
log.info(`[Verbose] Starting delta/partial file upload...`);
|
|
726
|
+
log.info(` - Manifest entries: ${manifest.length}`);
|
|
727
|
+
log.info(` - Encryption: ${encryptionData ? 'enabled' : 'disabled'}`);
|
|
728
|
+
}
|
|
601
729
|
finalManifest = options.delta
|
|
602
730
|
? await uploadPartial(apikey, manifest, path, appid, bundle, orgId, encryptionData, options)
|
|
603
731
|
: null;
|
|
732
|
+
if (options.verbose && finalManifest)
|
|
733
|
+
log.info(`[Verbose] Delta upload complete with ${finalManifest.length} files`);
|
|
604
734
|
}
|
|
605
735
|
catch (err) {
|
|
606
736
|
log.info(`Failed to upload partial files to capgo cloud. Error: ${formatError(err)}. This is not a critical error, the bundle has been uploaded without the partial files`);
|
|
737
|
+
if (options.verbose)
|
|
738
|
+
log.info(`[Verbose] Delta upload error details: ${formatError(err)}`);
|
|
607
739
|
}
|
|
608
740
|
versionData.storage_provider = 'r2';
|
|
609
741
|
versionData.manifest = finalManifest;
|
|
742
|
+
if (options.verbose)
|
|
743
|
+
log.info(`[Verbose] Updating version record with storage provider and manifest...`);
|
|
610
744
|
const { error: dbError2 } = await updateOrCreateVersion(supabase, versionData);
|
|
611
745
|
if (dbError2)
|
|
612
746
|
uploadFail(`Cannot update bundle ${formatError(dbError2)}`);
|
|
747
|
+
if (options.verbose)
|
|
748
|
+
log.info(`[Verbose] Version record updated successfully`);
|
|
613
749
|
}
|
|
614
750
|
// Check we have app access to this appId
|
|
751
|
+
if (options.verbose)
|
|
752
|
+
log.info(`[Verbose] Checking app permissions...`);
|
|
615
753
|
const permissions = await checkAppExistsAndHasPermissionOrgErr(supabase, apikey, appid, OrganizationPerm.upload);
|
|
754
|
+
if (options.verbose) {
|
|
755
|
+
log.info(`[Verbose] Permissions:`);
|
|
756
|
+
log.info(` - Upload: ${hasOrganizationPerm(permissions, OrganizationPerm.upload) ? 'yes' : 'no'}`);
|
|
757
|
+
log.info(` - Write: ${hasOrganizationPerm(permissions, OrganizationPerm.write) ? 'yes' : 'no'}`);
|
|
758
|
+
log.info(` - Admin: ${hasOrganizationPerm(permissions, OrganizationPerm.admin) ? 'yes' : 'no'}`);
|
|
759
|
+
}
|
|
616
760
|
if (options.deleteLinkedBundleOnUpload && hasOrganizationPerm(permissions, OrganizationPerm.write)) {
|
|
761
|
+
if (options.verbose)
|
|
762
|
+
log.info(`[Verbose] Deleting linked bundle in channel ${channel}...`);
|
|
617
763
|
await deleteLinkedBundleOnUpload(supabase, appid, channel);
|
|
618
764
|
}
|
|
619
765
|
else if (options.deleteLinkedBundleOnUpload) {
|
|
620
766
|
log.warn('Cannot delete linked bundle on upload as a upload organization member');
|
|
621
767
|
}
|
|
622
768
|
if (hasOrganizationPerm(permissions, OrganizationPerm.write)) {
|
|
769
|
+
if (options.verbose)
|
|
770
|
+
log.info(`[Verbose] Setting bundle ${bundle} to channel ${channel}...`);
|
|
623
771
|
await setVersionInChannel(supabase, apikey, !!options.bundleUrl, bundle, channel, userId, orgId, appid, localConfig, options.selfAssign);
|
|
772
|
+
if (options.verbose)
|
|
773
|
+
log.info(`[Verbose] Channel updated successfully`);
|
|
624
774
|
}
|
|
625
775
|
else {
|
|
626
776
|
log.warn('Cannot set channel as a upload organization member');
|
|
627
777
|
}
|
|
778
|
+
if (options.verbose)
|
|
779
|
+
log.info(`[Verbose] Sending upload event...`);
|
|
628
780
|
await sendEvent(apikey, {
|
|
629
781
|
channel: 'app',
|
|
630
782
|
event: 'App Uploaded',
|
|
@@ -644,6 +796,13 @@ export async function uploadBundle(preAppid, options, shouldExit = true) {
|
|
|
644
796
|
ivSessionKey: typeof versionData.session_key === 'string' ? versionData.session_key : undefined,
|
|
645
797
|
storageProvider: versionData.storage_provider,
|
|
646
798
|
};
|
|
799
|
+
if (options.verbose) {
|
|
800
|
+
log.info(`[Verbose] Upload completed successfully:`);
|
|
801
|
+
log.info(` - Bundle: ${result.bundle}`);
|
|
802
|
+
log.info(` - Checksum: ${result.checksum}`);
|
|
803
|
+
log.info(` - Encryption: ${result.encryptionMethod}`);
|
|
804
|
+
log.info(` - Storage: ${result.storageProvider}`);
|
|
805
|
+
}
|
|
647
806
|
if (shouldExit && !result.skipped)
|
|
648
807
|
outro('Time to share your update to the world 🌍');
|
|
649
808
|
return result;
|
|
@@ -694,7 +853,7 @@ export async function uploadCommand(appid, options) {
|
|
|
694
853
|
await uploadBundle(appid, options, true);
|
|
695
854
|
}
|
|
696
855
|
catch (error) {
|
|
697
|
-
log.error(formatError(error));
|
|
856
|
+
log.error(`uploadBundle failded: ${formatError(error)}`);
|
|
698
857
|
throw error instanceof Error ? error : new Error(String(error));
|
|
699
858
|
}
|
|
700
859
|
}
|