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.
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { execSync, spawn } = require('child_process');
4
- const { existsSync, mkdirSync, createWriteStream, unlinkSync, chmodSync } = require('fs');
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
- const fs = require('fs');
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 CLI binary
99
- await tar.x({
100
- file: tarballPath,
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
- // Copy the downloaded CLI to replace this script
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@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
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@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="],
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
- "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
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
- "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
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
- "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
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
- "path-scurry/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
212
+ "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
233
213
 
234
- "png-to-ico/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="],
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, relative } from "path";
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
- // Extract the hash from the patched tar:
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 tar.x({
416
- file: tmpPatchedTarFilePath,
417
- cwd: untarDir,
418
- filter: (path: string) => {
419
- if (path.endsWith(`${resourcesDir}/version.json`) || path.endsWith('metadata.json')) {
420
- hashFilePath = path;
421
- return true;
422
- } else {
423
- return false;
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 hashFileJson = await Bun.file(
435
- join(untarDir, hashFilePath)
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
- // Use Windows native tar.exe on Windows due to npm tar library issues (same as CLI)
616
- if (currentOS === 'win') {
617
- console.log(`Using Windows native tar.exe to extract ${latestTarPath} to ${extractionDir}...`);
618
- try {
619
- const relativeTarPath = relative(extractionDir, latestTarPath);
620
- execSync(`tar -xf "${relativeTarPath}"`, {
621
- stdio: 'inherit',
622
- cwd: extractionDir
623
- });
624
- console.log('Windows tar.exe extraction completed successfully');
625
-
626
- // For Windows/Linux, the app bundle is at root level
627
- appBundleSubpath = "./";
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
- // Use npm tar library on macOS/Linux (keep original behavior)
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.2.3-beta.0",
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, relative } from "path";
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
- // Use Windows native tar.exe on Windows due to npm tar library issues
220
- if (OS === 'win') {
221
- console.log('Using Windows native tar.exe for reliable extraction...');
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
- // Use Windows native tar.exe on Windows due to npm tar library issues
454
- if (OS === 'win') {
455
- console.log('Using Windows native tar.exe for reliable extraction...');
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
- await tar.c(
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
- await tar.create(
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
- await tar.c(
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 preserving permissions
2945
- // Using the tar package for cross-platform compatibility
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;