electrobun 1.2.3-beta.0 → 1.3.0-beta.2
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/bin/electrobun.cjs +27 -37
- package/bun.lock +7 -29
- package/dist/api/bun/core/Updater.ts +28 -58
- package/package.json +3 -5
- package/src/cli/index.ts +29 -74
package/bin/electrobun.cjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { execSync, spawn } = require('child_process');
|
|
4
|
-
const { existsSync, mkdirSync,
|
|
4
|
+
const { existsSync, mkdirSync, unlinkSync, chmodSync, copyFileSync, createWriteStream } = require('fs');
|
|
5
5
|
const { join, dirname } = require('path');
|
|
6
6
|
const https = require('https');
|
|
7
|
-
const tar = require('tar');
|
|
8
7
|
|
|
9
8
|
// Detect platform and architecture
|
|
10
9
|
function getPlatform() {
|
|
@@ -38,25 +37,25 @@ async function downloadFile(url, filePath) {
|
|
|
38
37
|
return new Promise((resolve, reject) => {
|
|
39
38
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
40
39
|
const file = createWriteStream(filePath);
|
|
41
|
-
|
|
40
|
+
|
|
42
41
|
https.get(url, (response) => {
|
|
43
42
|
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
44
43
|
// Follow redirect
|
|
45
44
|
return downloadFile(response.headers.location, filePath).then(resolve).catch(reject);
|
|
46
45
|
}
|
|
47
|
-
|
|
46
|
+
|
|
48
47
|
if (response.statusCode !== 200) {
|
|
49
48
|
reject(new Error(`Download failed: ${response.statusCode}`));
|
|
50
49
|
return;
|
|
51
50
|
}
|
|
52
|
-
|
|
51
|
+
|
|
53
52
|
response.pipe(file);
|
|
54
|
-
|
|
53
|
+
|
|
55
54
|
file.on('finish', () => {
|
|
56
55
|
file.close();
|
|
57
56
|
resolve();
|
|
58
57
|
});
|
|
59
|
-
|
|
58
|
+
|
|
60
59
|
file.on('error', reject);
|
|
61
60
|
}).on('error', reject);
|
|
62
61
|
});
|
|
@@ -68,13 +67,12 @@ async function ensureCliBinary() {
|
|
|
68
67
|
if (existsSync(binLocation)) {
|
|
69
68
|
return binLocation;
|
|
70
69
|
}
|
|
71
|
-
|
|
70
|
+
|
|
72
71
|
// Check if core dependencies already exist in cache
|
|
73
72
|
if (existsSync(cliBinary)) {
|
|
74
73
|
// Copy to bin location if it exists in cache but not in bin
|
|
75
74
|
mkdirSync(dirname(binLocation), { recursive: true });
|
|
76
|
-
|
|
77
|
-
fs.copyFileSync(cliBinary, binLocation);
|
|
75
|
+
copyFileSync(cliBinary, binLocation);
|
|
78
76
|
if (platform !== 'win') {
|
|
79
77
|
chmodSync(binLocation, '755');
|
|
80
78
|
}
|
|
@@ -82,55 +80,47 @@ async function ensureCliBinary() {
|
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
console.log('Downloading electrobun CLI for your platform...');
|
|
85
|
-
|
|
83
|
+
|
|
86
84
|
// Get the package version to download the matching release
|
|
87
85
|
const packageJson = require(join(electrobunDir, 'package.json'));
|
|
88
86
|
const version = packageJson.version;
|
|
89
87
|
const tag = `v${version}`;
|
|
90
|
-
|
|
88
|
+
|
|
91
89
|
const tarballUrl = `https://github.com/blackboardsh/electrobun/releases/download/${tag}/electrobun-cli-${platform}-${arch}.tar.gz`;
|
|
92
90
|
const tarballPath = join(cacheDir, `electrobun-${platform}-${arch}.tar.gz`);
|
|
93
|
-
|
|
91
|
+
|
|
94
92
|
try {
|
|
95
93
|
// Download tarball
|
|
96
94
|
await downloadFile(tarballUrl, tarballPath);
|
|
97
|
-
|
|
98
|
-
// Extract
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
cwd: cacheDir
|
|
102
|
-
// No strip needed - CLI tarball contains just the binary
|
|
103
|
-
});
|
|
104
|
-
|
|
95
|
+
|
|
96
|
+
// Extract using system tar (available on macOS, Linux, and Windows 10+)
|
|
97
|
+
execSync(`tar -xzf "${tarballPath}"`, { cwd: cacheDir, stdio: 'pipe' });
|
|
98
|
+
|
|
105
99
|
// Clean up tarball
|
|
106
100
|
unlinkSync(tarballPath);
|
|
107
|
-
|
|
101
|
+
|
|
108
102
|
// Check if CLI binary was extracted
|
|
109
103
|
if (!existsSync(cliBinary)) {
|
|
110
104
|
throw new Error(`CLI binary not found at ${cliBinary} after extraction`);
|
|
111
105
|
}
|
|
112
|
-
|
|
106
|
+
|
|
113
107
|
// Make executable on Unix systems
|
|
114
108
|
if (platform !== 'win') {
|
|
115
109
|
chmodSync(cliBinary, '755');
|
|
116
110
|
}
|
|
117
|
-
|
|
111
|
+
|
|
118
112
|
// Copy CLI to bin location so npm scripts can find it
|
|
119
|
-
const binLocation = join(electrobunDir, 'bin', 'electrobun' + binExt);
|
|
120
113
|
mkdirSync(dirname(binLocation), { recursive: true });
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const fs = require('fs');
|
|
124
|
-
fs.copyFileSync(cliBinary, binLocation);
|
|
125
|
-
|
|
114
|
+
copyFileSync(cliBinary, binLocation);
|
|
115
|
+
|
|
126
116
|
// Make the bin location executable too
|
|
127
117
|
if (platform !== 'win') {
|
|
128
118
|
chmodSync(binLocation, '755');
|
|
129
119
|
}
|
|
130
|
-
|
|
120
|
+
|
|
131
121
|
console.log('electrobun CLI downloaded successfully!');
|
|
132
122
|
return binLocation;
|
|
133
|
-
|
|
123
|
+
|
|
134
124
|
} catch (error) {
|
|
135
125
|
throw new Error(`Failed to download electrobun CLI: ${error.message}`);
|
|
136
126
|
}
|
|
@@ -140,26 +130,26 @@ async function main() {
|
|
|
140
130
|
try {
|
|
141
131
|
const args = process.argv.slice(2);
|
|
142
132
|
const cliPath = await ensureCliBinary();
|
|
143
|
-
|
|
133
|
+
|
|
144
134
|
// Replace this process with the actual CLI
|
|
145
135
|
const child = spawn(cliPath, args, {
|
|
146
136
|
stdio: 'inherit',
|
|
147
137
|
cwd: process.cwd()
|
|
148
138
|
});
|
|
149
|
-
|
|
139
|
+
|
|
150
140
|
child.on('exit', (code) => {
|
|
151
141
|
process.exit(code || 0);
|
|
152
142
|
});
|
|
153
|
-
|
|
143
|
+
|
|
154
144
|
child.on('error', (error) => {
|
|
155
145
|
console.error('Failed to start electrobun CLI:', error.message);
|
|
156
146
|
process.exit(1);
|
|
157
147
|
});
|
|
158
|
-
|
|
148
|
+
|
|
159
149
|
} catch (error) {
|
|
160
150
|
console.error('Error:', error.message);
|
|
161
151
|
process.exit(1);
|
|
162
152
|
}
|
|
163
153
|
}
|
|
164
154
|
|
|
165
|
-
main();
|
|
155
|
+
main();
|
package/bun.lock
CHANGED
|
@@ -10,12 +10,10 @@
|
|
|
10
10
|
"png-to-ico": "^2.1.8",
|
|
11
11
|
"rcedit": "^4.0.1",
|
|
12
12
|
"rpc-anywhere": "1.5.0",
|
|
13
|
-
"tar": "^6.2.1",
|
|
14
13
|
},
|
|
15
14
|
"devDependencies": {
|
|
16
15
|
"@types/archiver": "^6.0.3",
|
|
17
16
|
"@types/bun": "1.1.9",
|
|
18
|
-
"@types/tar": "^6.1.13",
|
|
19
17
|
"typescript": "^5.9.3",
|
|
20
18
|
},
|
|
21
19
|
},
|
|
@@ -41,12 +39,10 @@
|
|
|
41
39
|
|
|
42
40
|
"@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
|
|
43
41
|
|
|
44
|
-
"@types/node": ["@types/node@
|
|
42
|
+
"@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="],
|
|
45
43
|
|
|
46
44
|
"@types/readdir-glob": ["@types/readdir-glob@1.1.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg=="],
|
|
47
45
|
|
|
48
|
-
"@types/tar": ["@types/tar@6.1.13", "", { "dependencies": { "@types/node": "*", "minipass": "^4.0.0" } }, "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw=="],
|
|
49
|
-
|
|
50
46
|
"@types/webextension-polyfill": ["@types/webextension-polyfill@0.12.3", "", {}, "sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg=="],
|
|
51
47
|
|
|
52
48
|
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
|
@@ -81,8 +77,6 @@
|
|
|
81
77
|
|
|
82
78
|
"bun-types": ["bun-types@1.1.27", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-rHXAiIDefeMS/fleNM1rRDYqolJGNRdch3+AuCRwcZWaqTa1vjGBNsahH/HVV7Y82frllYhJomCVSEiHzLzkgg=="],
|
|
83
79
|
|
|
84
|
-
"chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
|
85
|
-
|
|
86
80
|
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
87
81
|
|
|
88
82
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
@@ -113,8 +107,6 @@
|
|
|
113
107
|
|
|
114
108
|
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
|
|
115
109
|
|
|
116
|
-
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
|
117
|
-
|
|
118
110
|
"glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
|
|
119
111
|
|
|
120
112
|
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
|
@@ -147,11 +139,7 @@
|
|
|
147
139
|
|
|
148
140
|
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
|
149
141
|
|
|
150
|
-
"minipass": ["minipass@
|
|
151
|
-
|
|
152
|
-
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
|
153
|
-
|
|
154
|
-
"mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
|
142
|
+
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
|
155
143
|
|
|
156
144
|
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
|
157
145
|
|
|
@@ -197,8 +185,6 @@
|
|
|
197
185
|
|
|
198
186
|
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
199
187
|
|
|
200
|
-
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
|
201
|
-
|
|
202
188
|
"tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
|
|
203
189
|
|
|
204
190
|
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
|
|
@@ -215,23 +201,17 @@
|
|
|
215
201
|
|
|
216
202
|
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
|
217
203
|
|
|
218
|
-
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
|
219
|
-
|
|
220
204
|
"zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
|
|
221
205
|
|
|
222
|
-
"
|
|
206
|
+
"@types/readdir-glob/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
|
|
223
207
|
|
|
224
|
-
"
|
|
225
|
-
|
|
226
|
-
"glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
|
227
|
-
|
|
228
|
-
"lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
|
208
|
+
"@types/ws/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
|
|
229
209
|
|
|
230
|
-
"
|
|
210
|
+
"bun-types/@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
|
|
231
211
|
|
|
232
|
-
"
|
|
212
|
+
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
|
233
213
|
|
|
234
|
-
"
|
|
214
|
+
"lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
|
235
215
|
|
|
236
216
|
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
237
217
|
|
|
@@ -239,8 +219,6 @@
|
|
|
239
219
|
|
|
240
220
|
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
241
221
|
|
|
242
|
-
"tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
|
243
|
-
|
|
244
222
|
"wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
245
223
|
|
|
246
224
|
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { join, dirname, resolve
|
|
1
|
+
import { join, dirname, resolve } from "path";
|
|
2
2
|
import { homedir } from "os";
|
|
3
3
|
import { renameSync, unlinkSync, mkdirSync, rmdirSync, statSync, readdirSync } from "fs";
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
|
-
import tar from "tar";
|
|
6
5
|
import { ZstdInit } from "@oneidentity/zstd-js/wasm";
|
|
7
6
|
import { OS as currentOS, ARCH as currentArch } from '../../shared/platform';
|
|
8
7
|
import { getPlatformPrefix, getTarballFileName } from '../../shared/naming';
|
|
@@ -405,25 +404,21 @@ const Updater = {
|
|
|
405
404
|
emitStatus('extracting-version', 'Extracting version info from patched tar...', { currentHash });
|
|
406
405
|
|
|
407
406
|
let hashFilePath = "";
|
|
408
|
-
const untarDir = join(appDataFolder, "self-extraction", "tmpuntar");
|
|
409
|
-
mkdirSync(untarDir, { recursive: true });
|
|
410
407
|
|
|
411
|
-
//
|
|
408
|
+
// Read the hash from the patched tar without full extraction:
|
|
412
409
|
// - macOS/Windows: Resources/version.json (inside the app bundle directory)
|
|
413
410
|
// - Linux: metadata.json (alongside the AppImage, since AppImage is opaque)
|
|
414
411
|
const resourcesDir = 'Resources';
|
|
415
|
-
await
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
},
|
|
426
|
-
});
|
|
412
|
+
const patchedTarBytes = await Bun.file(tmpPatchedTarFilePath).arrayBuffer();
|
|
413
|
+
const patchedArchive = new Bun.Archive(patchedTarBytes);
|
|
414
|
+
const patchedFiles = await patchedArchive.files();
|
|
415
|
+
|
|
416
|
+
for (const [filePath] of patchedFiles) {
|
|
417
|
+
if (filePath.endsWith(`${resourcesDir}/version.json`) || filePath.endsWith('metadata.json')) {
|
|
418
|
+
hashFilePath = filePath;
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
427
422
|
|
|
428
423
|
if (!hashFilePath) {
|
|
429
424
|
emitStatus('error', 'Could not find version/metadata file in patched tar', { currentHash });
|
|
@@ -431,9 +426,8 @@ const Updater = {
|
|
|
431
426
|
break;
|
|
432
427
|
}
|
|
433
428
|
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
).json();
|
|
429
|
+
const hashFile = patchedFiles.get(hashFilePath);
|
|
430
|
+
const hashFileJson = JSON.parse(await hashFile!.text());
|
|
437
431
|
const nextHash = hashFileJson.hash;
|
|
438
432
|
|
|
439
433
|
if (seenHashes.includes(nextHash)) {
|
|
@@ -459,7 +453,6 @@ const Updater = {
|
|
|
459
453
|
// delete the old tar file
|
|
460
454
|
unlinkSync(currentTarPath);
|
|
461
455
|
unlinkSync(patchFilePath);
|
|
462
|
-
rmdirSync(untarDir, { recursive: true });
|
|
463
456
|
|
|
464
457
|
currentHash = nextHash;
|
|
465
458
|
currentTarPath = join(
|
|
@@ -612,45 +605,22 @@ const Updater = {
|
|
|
612
605
|
mkdirSync(extractionDir, { recursive: true });
|
|
613
606
|
}
|
|
614
607
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
} catch (error) {
|
|
629
|
-
emitStatus('error', `Extraction failed: ${(error as Error).message}`, { errorMessage: (error as Error).message });
|
|
630
|
-
console.error('Windows tar.exe extraction failed:', error);
|
|
631
|
-
throw error;
|
|
608
|
+
const latestTarBytes = await Bun.file(latestTarPath).arrayBuffer();
|
|
609
|
+
const latestArchive = new Bun.Archive(latestTarBytes);
|
|
610
|
+
await latestArchive.extract(extractionDir);
|
|
611
|
+
|
|
612
|
+
if (currentOS === 'macos') {
|
|
613
|
+
// Find the .app bundle by scanning extracted file paths
|
|
614
|
+
const extractedFiles = await latestArchive.files();
|
|
615
|
+
for (const [filePath] of extractedFiles) {
|
|
616
|
+
const appMatch = filePath.match(/^([^/]+\.app)\//);
|
|
617
|
+
if (appMatch) {
|
|
618
|
+
appBundleSubpath = appMatch[1] + '/';
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
632
621
|
}
|
|
633
622
|
} else {
|
|
634
|
-
|
|
635
|
-
await tar.x({
|
|
636
|
-
// gzip: false,
|
|
637
|
-
file: latestTarPath,
|
|
638
|
-
cwd: extractionDir,
|
|
639
|
-
onentry: (entry: tar.ReadEntry) => {
|
|
640
|
-
if (currentOS === 'macos') {
|
|
641
|
-
// find the first .app bundle in the tarball
|
|
642
|
-
// Some apps may have nested .app bundles
|
|
643
|
-
if (!appBundleSubpath && entry.path.endsWith(".app/")) {
|
|
644
|
-
appBundleSubpath = entry.path;
|
|
645
|
-
}
|
|
646
|
-
} else {
|
|
647
|
-
// For Linux, look for the main executable
|
|
648
|
-
if (!appBundleSubpath) {
|
|
649
|
-
appBundleSubpath = "./";
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
},
|
|
653
|
-
});
|
|
623
|
+
appBundleSubpath = "./"
|
|
654
624
|
}
|
|
655
625
|
|
|
656
626
|
console.log(`Tar extraction completed. Found appBundleSubpath: ${appBundleSubpath}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electrobun",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0-beta.2",
|
|
4
4
|
"description": "Build ultra fast, tiny, and cross-platform desktop apps with Typescript.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Blackboard Technologies Inc.",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"url": "git+https://github.com/blackboardsh/electrobun.git"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
-
"build:cli": "mkdir -p bin && bun build src/cli/index.ts --compile --outfile bin/electrobun",
|
|
29
|
+
"build:cli": "mkdir -p bin && vendors/bun/bun build src/cli/index.ts --compile --outfile bin/electrobun",
|
|
30
30
|
"start": "bun src/bun/index.ts",
|
|
31
31
|
"check-zig-version": "vendors/zig/zig version",
|
|
32
32
|
"build:dev": "bun build.ts",
|
|
@@ -53,7 +53,6 @@
|
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/archiver": "^6.0.3",
|
|
55
55
|
"@types/bun": "1.1.9",
|
|
56
|
-
"@types/tar": "^6.1.13",
|
|
57
56
|
"typescript": "^5.9.3"
|
|
58
57
|
},
|
|
59
58
|
"dependencies": {
|
|
@@ -61,7 +60,6 @@
|
|
|
61
60
|
"archiver": "^7.0.1",
|
|
62
61
|
"png-to-ico": "^2.1.8",
|
|
63
62
|
"rcedit": "^4.0.1",
|
|
64
|
-
"rpc-anywhere": "1.5.0"
|
|
65
|
-
"tar": "^6.2.1"
|
|
63
|
+
"rpc-anywhere": "1.5.0"
|
|
66
64
|
}
|
|
67
65
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { join, dirname, basename
|
|
1
|
+
import { join, dirname, basename } from "path";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import {
|
|
4
4
|
existsSync,
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
} from "fs";
|
|
19
19
|
import { execSync } from "child_process";
|
|
20
20
|
import * as readline from "readline";
|
|
21
|
-
import tar from "tar";
|
|
22
21
|
import archiver from "archiver";
|
|
23
22
|
import { ZstdInit } from "@oneidentity/zstd-js/wasm";
|
|
24
23
|
import { OS, ARCH } from '../shared/platform';
|
|
@@ -43,6 +42,22 @@ const _MAX_CHUNK_SIZE = 1024 * 2;
|
|
|
43
42
|
|
|
44
43
|
// const binExt = OS === 'win' ? '.exe' : '';
|
|
45
44
|
|
|
45
|
+
// Create a tar file using system tar command (preserves file permissions unlike Bun.Archive)
|
|
46
|
+
function createTar(tarPath: string, cwd: string, entries: string[]) {
|
|
47
|
+
execSync(`tar -cf "${tarPath}" ${entries.map(e => `"${e}"`).join(' ')}`, {
|
|
48
|
+
cwd,
|
|
49
|
+
stdio: 'pipe',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Create a tar.gz file using system tar command
|
|
54
|
+
function createTarGz(tarGzPath: string, cwd: string, entries: string[]) {
|
|
55
|
+
execSync(`tar -czf "${tarGzPath}" ${entries.map(e => `"${e}"`).join(' ')}`, {
|
|
56
|
+
cwd,
|
|
57
|
+
stdio: 'pipe',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
// this when run as an npm script this will be where the folder where package.json is.
|
|
47
62
|
const projectRoot = process.cwd();
|
|
48
63
|
|
|
@@ -216,22 +231,9 @@ async function ensureCoreDependencies(targetOS?: 'macos' | 'win' | 'linux', targ
|
|
|
216
231
|
const platformDistPath = join(ELECTROBUN_DEP_PATH, `dist-${platformOS}-${platformArch}`);
|
|
217
232
|
mkdirSync(platformDistPath, { recursive: true });
|
|
218
233
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const relativeTempFile = relative(platformDistPath, tempFile);
|
|
223
|
-
execSync(`tar -xf "${relativeTempFile}"`, {
|
|
224
|
-
stdio: 'inherit',
|
|
225
|
-
cwd: platformDistPath
|
|
226
|
-
});
|
|
227
|
-
} else {
|
|
228
|
-
await tar.x({
|
|
229
|
-
file: tempFile,
|
|
230
|
-
cwd: platformDistPath,
|
|
231
|
-
preservePaths: false,
|
|
232
|
-
strip: 0,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
234
|
+
const tarBytes = await Bun.file(tempFile).arrayBuffer();
|
|
235
|
+
const archive = new Bun.Archive(tarBytes);
|
|
236
|
+
await archive.extract(platformDistPath);
|
|
235
237
|
|
|
236
238
|
// NOTE: We no longer copy main.js from platform-specific downloads
|
|
237
239
|
// Platform-specific downloads should only contain native binaries
|
|
@@ -450,22 +452,9 @@ async function ensureCEFDependencies(targetOS?: 'macos' | 'win' | 'linux', targe
|
|
|
450
452
|
await validateTarFile(tempFile);
|
|
451
453
|
|
|
452
454
|
try {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
const relativeTempFile = relative(platformDistPath, tempFile);
|
|
457
|
-
execSync(`tar -xf "${relativeTempFile}"`, {
|
|
458
|
-
stdio: 'inherit',
|
|
459
|
-
cwd: platformDistPath
|
|
460
|
-
});
|
|
461
|
-
} else {
|
|
462
|
-
await tar.x({
|
|
463
|
-
file: tempFile,
|
|
464
|
-
cwd: platformDistPath,
|
|
465
|
-
preservePaths: false,
|
|
466
|
-
strip: 0,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
455
|
+
const cefTarBytes = await Bun.file(tempFile).arrayBuffer();
|
|
456
|
+
const cefArchive = new Bun.Archive(cefTarBytes);
|
|
457
|
+
await cefArchive.extract(platformDistPath);
|
|
469
458
|
|
|
470
459
|
console.log(`✓ Extraction completed successfully`);
|
|
471
460
|
|
|
@@ -1960,20 +1949,11 @@ if (commandArg === "init") {
|
|
|
1960
1949
|
// tar the signed and notarized app bundle
|
|
1961
1950
|
// Use sanitized appFileName for tarball paths (URL-safe), but tar content uses actual bundle folder
|
|
1962
1951
|
const tmpTarPath = join(buildFolder, `${appFileName}${targetOS === 'macos' ? '.app' : ''}-temp.tar`);
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
gzip: false,
|
|
1966
|
-
file: tmpTarPath,
|
|
1967
|
-
cwd: buildFolder,
|
|
1968
|
-
},
|
|
1969
|
-
[basename(appBundleFolderPath)]
|
|
1970
|
-
);
|
|
1971
|
-
const tmpTarball = Bun.file(tmpTarPath);
|
|
1972
|
-
const tmpTarBuffer = await tmpTarball.arrayBuffer();
|
|
1952
|
+
createTar(tmpTarPath, buildFolder, [basename(appBundleFolderPath)]);
|
|
1953
|
+
const tmpTarBuffer = await Bun.file(tmpTarPath).arrayBuffer();
|
|
1973
1954
|
// Note: wyhash is the default in Bun.hash but that may change in the future
|
|
1974
1955
|
// so we're being explicit here.
|
|
1975
1956
|
const hash = Bun.hash.wyhash(tmpTarBuffer, 43770n).toString(36);
|
|
1976
|
-
|
|
1977
1957
|
unlinkSync(tmpTarPath);
|
|
1978
1958
|
// const bunVersion = execSync(`${bunBinarySourcePath} --version`).toString().trim();
|
|
1979
1959
|
|
|
@@ -2108,14 +2088,7 @@ if (commandArg === "init") {
|
|
|
2108
2088
|
console.log(`Creating tar of installer contents: ${appImageTarPath}`);
|
|
2109
2089
|
|
|
2110
2090
|
// Tar the inner directory
|
|
2111
|
-
|
|
2112
|
-
{
|
|
2113
|
-
file: appImageTarPath,
|
|
2114
|
-
cwd: tempDirPath,
|
|
2115
|
-
gzip: false, // We'll compress with zstd after
|
|
2116
|
-
},
|
|
2117
|
-
[appFileName]
|
|
2118
|
-
);
|
|
2091
|
+
createTar(appImageTarPath, tempDirPath, [appFileName]);
|
|
2119
2092
|
|
|
2120
2093
|
// Clean up temp directory
|
|
2121
2094
|
rmSync(tempDirPath, { recursive: true });
|
|
@@ -2163,14 +2136,7 @@ if (commandArg === "init") {
|
|
|
2163
2136
|
// For Linux, we've already created the tar in the AppImage section above
|
|
2164
2137
|
// For macOS/Windows, tar the signed and notarized app bundle
|
|
2165
2138
|
if (targetOS !== 'linux') {
|
|
2166
|
-
|
|
2167
|
-
{
|
|
2168
|
-
gzip: false,
|
|
2169
|
-
file: tarPath,
|
|
2170
|
-
cwd: buildFolder,
|
|
2171
|
-
},
|
|
2172
|
-
[basename(appBundleFolderPath)]
|
|
2173
|
-
);
|
|
2139
|
+
createTar(tarPath, buildFolder, [basename(appBundleFolderPath)]);
|
|
2174
2140
|
}
|
|
2175
2141
|
|
|
2176
2142
|
let compressedTarPath = `${tarPath}.zst`;
|
|
@@ -2941,19 +2907,8 @@ async function wrapInArchive(filePath: string, _buildFolder: string, archiveType
|
|
|
2941
2907
|
}
|
|
2942
2908
|
}
|
|
2943
2909
|
|
|
2944
|
-
// Create tar.gz archive
|
|
2945
|
-
|
|
2946
|
-
await tar.c(
|
|
2947
|
-
{
|
|
2948
|
-
gzip: true,
|
|
2949
|
-
file: archivePath,
|
|
2950
|
-
cwd: fileDir,
|
|
2951
|
-
portable: true, // Ensures consistent behavior across platforms
|
|
2952
|
-
preservePaths: false,
|
|
2953
|
-
// The tar package should preserve file modes when creating archives
|
|
2954
|
-
},
|
|
2955
|
-
[fileName]
|
|
2956
|
-
);
|
|
2910
|
+
// Create tar.gz archive using system tar (preserves file permissions)
|
|
2911
|
+
createTarGz(archivePath, fileDir, [fileName]);
|
|
2957
2912
|
|
|
2958
2913
|
console.log(`Created archive: ${archivePath} (preserving executable permissions)`);
|
|
2959
2914
|
return archivePath;
|