Skip to content

Commit 44db5be

Browse files
Make stuff a *bit* better
1 parent 70becc0 commit 44db5be

File tree

1 file changed

+61
-79
lines changed

1 file changed

+61
-79
lines changed

β€Žscripts/uploader.jsβ€Ž

Lines changed: 61 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
/**
22
* Chunked file uploader for Sploder-Launcher builds
3-
* Uploads build artifacts in 90MB chunks with API key // Create URLSearchParams for proper form encoding
4-
const formPairs = [];
5-
for (const [key, value] of Object.entries(formFields)) {
6-
formPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
7-
}
8-
9-
const formDataString = formPairs.join('&');
10-
11-
// Debug: Show first part of form data to verify structure
12-
console.log(`πŸ”§ Form data preview: ${formDataString.substring(0, 200)}...`);
13-
console.log(`πŸ“¦ Chunk ${chunkIndex + 1}/${totalChunks}: ${(chunkData.length / 1024 / 1024).toFixed(2)}MB`);cation
3+
* Uploads build artifacts in 90MB chunks with API key authentication
144
*/
155

166
const fs = require('fs');
@@ -22,29 +12,28 @@ const { createHash } = require('crypto');
2212
// Configuration
2313
const CHUNK_SIZE = 90 * 1024 * 1024; // 90MB chunks
2414
const API_KEY = process.env.UPLOAD_API_KEY;
15+
const UPLOAD_URL = process.env.UPLOAD_URL;
2516

17+
// Validate environment
2618
if (!API_KEY) {
2719
console.error('❌ UPLOAD_API_KEY environment variable is required');
2820
process.exit(1);
2921
}
3022

31-
console.log(`πŸ”‘ API Key loaded: ${API_KEY.substring(0, 8)}...${API_KEY.substring(API_KEY.length - 4)}`);
32-
33-
if (!process.env.UPLOAD_URL) {
23+
if (!UPLOAD_URL) {
3424
console.error('❌ UPLOAD_URL environment variable is required');
3525
process.exit(1);
3626
}
3727

38-
const UPLOAD_ENDPOINT = process.env.UPLOAD_URL+'/update/upload.php';
28+
const UPLOAD_ENDPOINT = UPLOAD_URL + '/update/upload.php';
3929

4030
// Parse command line arguments
41-
const args = process.argv.slice(2);
42-
const uploadDirArg = args.find(arg => arg.startsWith('--dir='));
43-
const uploadDir = uploadDirArg ? uploadDirArg.split('=')[1] : './dist';
31+
const uploadDir = process.argv.find(arg => arg.startsWith('--dir='))?.split('=')[1] || './dist';
4432

4533
console.log(`πŸš€ Starting chunked upload from directory: ${uploadDir}`);
4634
console.log(`πŸ“‘ Upload endpoint: ${UPLOAD_ENDPOINT}`);
4735
console.log(`πŸ“¦ Chunk size: ${(CHUNK_SIZE / 1024 / 1024).toFixed(1)}MB`);
36+
console.log(`πŸ”‘ API Key: ${API_KEY.substring(0, 4)}...${API_KEY.substring(API_KEY.length - 4)}\n`);
4837

4938
/**
5039
* Calculate MD5 hash of a file
@@ -66,12 +55,11 @@ function calculateFileHash(filePath) {
6655
function makeRequest(url, options, data) {
6756
return new Promise((resolve, reject) => {
6857
const urlObj = new URL(url);
69-
const isHttps = urlObj.protocol === 'https:';
70-
const client = isHttps ? https : http;
58+
const client = urlObj.protocol === 'https:' ? https : http;
7159

7260
const req = client.request({
7361
hostname: urlObj.hostname,
74-
port: urlObj.port || (isHttps ? 443 : 80),
62+
port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
7563
path: urlObj.pathname + urlObj.search,
7664
method: options.method || 'POST',
7765
headers: options.headers || {}
@@ -80,8 +68,7 @@ function makeRequest(url, options, data) {
8068
res.on('data', chunk => responseData += chunk);
8169
res.on('end', () => {
8270
try {
83-
const parsed = JSON.parse(responseData);
84-
resolve({ status: res.statusCode, data: parsed });
71+
resolve({ status: res.statusCode, data: JSON.parse(responseData) });
8572
} catch (error) {
8673
resolve({ status: res.statusCode, data: responseData });
8774
}
@@ -101,39 +88,40 @@ function makeRequest(url, options, data) {
10188
/**
10289
* Upload a single chunk using multipart/form-data with raw binary data
10390
*/
104-
async function uploadChunk(filePath, fileName, chunkIndex, chunkData, totalChunks, fileHash) {
105-
// Create multipart form data with raw binary data (more efficient than base64)
106-
const boundary = '----WebKitFormBoundary' + Math.random().toString(36).substring(2, 15);
107-
108-
const formFields = {
109-
'api_key': API_KEY,
110-
'file_name': fileName,
111-
'chunk_index': chunkIndex.toString(),
112-
'total_chunks': totalChunks.toString(),
113-
'file_hash': fileHash
114-
};
115-
116-
// Build multipart form data manually
117-
let formData = Buffer.alloc(0);
118-
119-
// Add text fields
120-
for (const [key, value] of Object.entries(formFields)) {
121-
const fieldHeader = `--${boundary}\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n${value}\r\n`;
122-
formData = Buffer.concat([formData, Buffer.from(fieldHeader)]);
123-
}
124-
125-
// Add binary chunk data
126-
const binaryHeader = `--${boundary}\r\nContent-Disposition: form-data; name="chunk_data"; filename="chunk_${chunkIndex}"\r\nContent-Type: application/octet-stream\r\n\r\n`;
127-
const binaryFooter = `\r\n--${boundary}--\r\n`;
128-
129-
formData = Buffer.concat([
130-
formData,
131-
Buffer.from(binaryHeader),
132-
chunkData,
133-
Buffer.from(binaryFooter)
134-
]);
135-
136-
console.log(`πŸ“¦ Chunk ${chunkIndex + 1}/${totalChunks}: ${(chunkData.length / 1024 / 1024).toFixed(2)}MB`);
91+
async function uploadChunk(fileName, chunkIndex, chunkData, totalChunks, fileHash) {
92+
const boundary = '----WebKitFormBoundary' + Math.random().toString(36).substring(2);
93+
94+
// Build multipart form data
95+
const parts = [
96+
`--${boundary}`,
97+
`Content-Disposition: form-data; name="api_key"`,
98+
'',
99+
API_KEY,
100+
`--${boundary}`,
101+
`Content-Disposition: form-data; name="file_name"`,
102+
'',
103+
fileName,
104+
`--${boundary}`,
105+
`Content-Disposition: form-data; name="chunk_index"`,
106+
'',
107+
chunkIndex.toString(),
108+
`--${boundary}`,
109+
`Content-Disposition: form-data; name="total_chunks"`,
110+
'',
111+
totalChunks.toString(),
112+
`--${boundary}`,
113+
`Content-Disposition: form-data; name="file_hash"`,
114+
'',
115+
fileHash,
116+
`--${boundary}`,
117+
`Content-Disposition: form-data; name="chunk_data"; filename="chunk_${chunkIndex}"`,
118+
`Content-Type: application/octet-stream`,
119+
''
120+
];
121+
122+
const header = Buffer.from(parts.join('\r\n') + '\r\n');
123+
const footer = Buffer.from(`\r\n--${boundary}--\r\n`);
124+
const formData = Buffer.concat([header, chunkData, footer]);
137125

138126
const response = await makeRequest(UPLOAD_ENDPOINT, {
139127
method: 'POST',
@@ -148,7 +136,7 @@ async function uploadChunk(filePath, fileName, chunkIndex, chunkData, totalChunk
148136
}
149137

150138
if (!response.data.success) {
151-
throw new Error(`Server error: ${JSON.stringify(response.data)}`);
139+
throw new Error(`Server error: ${response.data.message}`);
152140
}
153141

154142
return response.data;
@@ -162,7 +150,7 @@ async function uploadFile(filePath) {
162150
const fileSize = fs.statSync(filePath).size;
163151
const totalChunks = Math.ceil(fileSize / CHUNK_SIZE);
164152

165-
console.log(`\nπŸ“„ Uploading: ${fileName}`);
153+
console.log(`πŸ“„ Uploading: ${fileName}`);
166154
console.log(`πŸ“Š Size: ${(fileSize / 1024 / 1024).toFixed(2)}MB`);
167155
console.log(`🧩 Chunks: ${totalChunks}`);
168156

@@ -177,13 +165,15 @@ async function uploadFile(filePath) {
177165

178166
for await (const chunk of fileStream) {
179167
const progress = ((chunkIndex + 1) / totalChunks * 100).toFixed(1);
180-
console.log(`⬆️ Uploading chunk ${chunkIndex + 1}/${totalChunks} (${progress}%)`);
168+
const chunkSize = (chunk.length / 1024 / 1024).toFixed(2);
181169

182-
await uploadChunk(filePath, fileName, chunkIndex, chunk, totalChunks, fileHash);
170+
console.log(`⬆️ Uploading chunk ${chunkIndex + 1}/${totalChunks} (${progress}%) - ${chunkSize}MB`);
171+
172+
await uploadChunk(fileName, chunkIndex, chunk, totalChunks, fileHash);
183173
chunkIndex++;
184174
}
185175

186-
console.log(`βœ… Successfully uploaded: ${fileName}`);
176+
console.log(`βœ… Successfully uploaded: ${fileName}\n`);
187177
}
188178

189179
/**
@@ -203,30 +193,21 @@ function findFilesToUpload(directory) {
203193
const fullPath = path.join(directory, item.name);
204194

205195
if (item.isFile()) {
206-
// Windows installer files (.exe)
196+
// Windows installer files
207197
if (item.name.endsWith('.exe') && item.name.includes('Setup')) {
208198
files.push({ path: fullPath, type: 'windows-installer' });
209199
}
210-
// Windows portable files (.zip)
200+
// Windows portable files
211201
else if (item.name.endsWith('.zip') && item.name.includes('Portable')) {
212202
files.push({ path: fullPath, type: 'windows-portable' });
213203
}
214-
// macOS zip file (direct file)
204+
// macOS zip file
215205
else if (item.name === 'Sploder-macOS.zip') {
216206
files.push({ path: fullPath, type: 'macos-app' });
217207
}
218-
} else if (item.isDirectory()) {
219-
// macOS app files (in mac/ directory) - only add if zip doesn't already exist
220-
if (item.name === 'mac') {
221-
const macZipPath = path.join(directory, 'Sploder-macOS.zip');
222-
if (fs.existsSync(macZipPath)) {
223-
// Zip file already exists, don't add the directory
224-
console.log(`πŸ“ Note: Using existing ${macZipPath} instead of mac directory`);
225-
} else {
226-
console.log(`πŸ“ Note: macOS app directory found but no zip file. Consider creating ${macZipPath}`);
227-
}
228-
}
229208
}
209+
// Note: Directory handling removed to avoid duplicates
210+
// The build script should create Sploder-macOS.zip directly
230211
}
231212

232213
return files;
@@ -245,25 +226,26 @@ async function main() {
245226
return;
246227
}
247228

248-
console.log(`\nπŸ“‹ Found ${files.length} files to upload:`);
229+
console.log(`πŸ“‹ Found ${files.length} files to upload:`);
249230
files.forEach(file => {
250231
console.log(` β€’ ${path.basename(file.path)} (${file.type})`);
251232
});
233+
console.log('');
252234

253235
// Upload each file
254236
for (const file of files) {
255237
try {
256238
await uploadFile(file.path);
257239
} catch (error) {
258-
console.error(`❌ Failed to upload ${file.path}:`, error.message);
240+
console.error(`❌ Failed to upload ${file.path}: ${error.message}`);
259241
process.exit(1);
260242
}
261243
}
262244

263-
console.log('\nπŸŽ‰ All files uploaded successfully!');
245+
console.log('πŸŽ‰ All files uploaded successfully!');
264246

265247
} catch (error) {
266-
console.error('❌ Upload process failed:', error.message);
248+
console.error(`❌ Upload process failed: ${error.message}`);
267249
process.exit(1);
268250
}
269251
}

0 commit comments

Comments
Β (0)