zcompress-vite-plugin 0.1.4 → 0.1.5
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/README.md +14 -0
- package/index.js +8 -4
- package/install.js +90 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,6 +74,13 @@ zcompress({
|
|
|
74
74
|
})
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
也可用环境变量(不改代码):
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
export ZCOMPRESS_BINARY=/absolute/path/to/zcompress
|
|
81
|
+
npm run build
|
|
82
|
+
```
|
|
83
|
+
|
|
77
84
|
默认 `failOnError: true`,失败会直接中断构建(不会静默跳过压缩)。
|
|
78
85
|
|
|
79
86
|
## License
|
|
@@ -161,6 +168,13 @@ zcompress({
|
|
|
161
168
|
})
|
|
162
169
|
```
|
|
163
170
|
|
|
171
|
+
Or use env var (no code change):
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
export ZCOMPRESS_BINARY=/absolute/path/to/zcompress
|
|
175
|
+
npm run build
|
|
176
|
+
```
|
|
177
|
+
|
|
164
178
|
Default `failOnError: true` ensures builds fail loudly (instead of silently skipping compression).
|
|
165
179
|
|
|
166
180
|
## License
|
package/index.js
CHANGED
|
@@ -49,14 +49,18 @@ const DEFAULT_OPTIONS = {
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Find the zcompress binary.
|
|
52
|
-
* Order: 1) downloaded by postinstall
|
|
52
|
+
* Order: 1) ZCOMPRESS_BINARY env 2) downloaded by postinstall 3) local zig build 4) PATH
|
|
53
53
|
*/
|
|
54
54
|
function findBinary() {
|
|
55
|
-
// 1)
|
|
55
|
+
// 1) explicit env override
|
|
56
|
+
const envBinary = process.env.ZCOMPRESS_BINARY;
|
|
57
|
+
if (envBinary) return envBinary;
|
|
58
|
+
|
|
59
|
+
// 2) postinstall-downloaded binary inside package
|
|
56
60
|
const packagedBin = join(__dirname, 'bin', process.platform === 'win32' ? 'zcompress.exe' : 'zcompress');
|
|
57
61
|
if (existsSync(packagedBin)) return packagedBin;
|
|
58
62
|
|
|
59
|
-
//
|
|
63
|
+
// 3) local zig build
|
|
60
64
|
const zigPaths = [
|
|
61
65
|
join(process.cwd(), 'zig-out', 'bin', 'zcompress'),
|
|
62
66
|
join(process.cwd(), 'zig-out', 'bin', 'zcompress.exe'),
|
|
@@ -65,7 +69,7 @@ function findBinary() {
|
|
|
65
69
|
if (existsSync(p)) return p;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
//
|
|
72
|
+
// 4) PATH
|
|
69
73
|
return 'zcompress';
|
|
70
74
|
}
|
|
71
75
|
|
package/install.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Postinstall script — downloads the prebuilt zcompress binary from GitHub Releases.
|
|
5
|
-
* Falls back gracefully if
|
|
5
|
+
* Falls back gracefully if binary can't be fetched.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { createWriteStream, existsSync, chmodSync, mkdirSync, unlinkSync, readFileSync } from 'node:fs';
|
|
@@ -20,10 +20,10 @@ const pkgJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8')
|
|
|
20
20
|
const VERSION = pkgJson.version;
|
|
21
21
|
|
|
22
22
|
const PLATFORM_MAP = {
|
|
23
|
-
'darwin-arm64':
|
|
24
|
-
'darwin-x64':
|
|
25
|
-
'linux-x64':
|
|
26
|
-
'win32-x64':
|
|
23
|
+
'darwin-arm64': 'zcompress-macos-arm64',
|
|
24
|
+
'darwin-x64': 'zcompress-macos-x64',
|
|
25
|
+
'linux-x64': 'zcompress-linux-x64',
|
|
26
|
+
'win32-x64': 'zcompress-windows-x64.exe',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
function getPlatformKey() {
|
|
@@ -33,8 +33,54 @@ function getPlatformKey() {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function getBinaryName() {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
return PLATFORM_MAP[getPlatformKey()] || null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function request(url) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
get(url, {
|
|
42
|
+
headers: {
|
|
43
|
+
'User-Agent': 'zcompress-vite-plugin-install',
|
|
44
|
+
Accept: 'application/vnd.github+json',
|
|
45
|
+
},
|
|
46
|
+
}, (res) => resolve(res)).on('error', reject);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function fetchJson(url) {
|
|
51
|
+
const res = await request(url);
|
|
52
|
+
if (res.statusCode !== 200) {
|
|
53
|
+
throw new Error(`HTTP ${res.statusCode}`);
|
|
54
|
+
}
|
|
55
|
+
const chunks = [];
|
|
56
|
+
for await (const chunk of res) chunks.push(chunk);
|
|
57
|
+
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function downloadToFile(url, destPath) {
|
|
61
|
+
const res = await request(url);
|
|
62
|
+
|
|
63
|
+
// Follow redirect (GitHub release assets usually 302)
|
|
64
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
65
|
+
return downloadToFile(res.headers.location, destPath);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (res.statusCode !== 200) {
|
|
69
|
+
throw new Error(`HTTP ${res.statusCode}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const file = createWriteStream(destPath);
|
|
73
|
+
await pipeline(res, file);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function resolveFallbackAssetUrl(binaryName) {
|
|
77
|
+
// Fallback strategy: use latest release asset for this platform when current version asset is missing.
|
|
78
|
+
const latest = await fetchJson(`https://api.github.com/repos/${REPO}/releases/latest`);
|
|
79
|
+
const asset = (latest.assets || []).find((a) => a.name === binaryName);
|
|
80
|
+
if (!asset?.browser_download_url) {
|
|
81
|
+
throw new Error('Latest release has no matching asset');
|
|
82
|
+
}
|
|
83
|
+
return asset.browser_download_url;
|
|
38
84
|
}
|
|
39
85
|
|
|
40
86
|
async function downloadBinary() {
|
|
@@ -52,56 +98,55 @@ async function downloadBinary() {
|
|
|
52
98
|
return true;
|
|
53
99
|
}
|
|
54
100
|
|
|
55
|
-
|
|
56
|
-
console.log(`[zcompress] ↓ Downloading ${url} ...`);
|
|
101
|
+
mkdirSync(BIN_DIR, { recursive: true });
|
|
57
102
|
|
|
103
|
+
const versionedUrl = `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
|
|
104
|
+
const tried = [];
|
|
105
|
+
|
|
106
|
+
// Attempt 1: exact npm version
|
|
58
107
|
try {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await
|
|
62
|
-
const file = createWriteStream(destPath);
|
|
63
|
-
get(url, (response) => {
|
|
64
|
-
// Follow redirects
|
|
65
|
-
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
66
|
-
get(response.headers.location, (redirectRes) => {
|
|
67
|
-
pipeline(redirectRes, file).then(resolve).catch(reject);
|
|
68
|
-
}).on('error', reject);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (response.statusCode !== 200) {
|
|
72
|
-
file.close();
|
|
73
|
-
unlinkSync(destPath);
|
|
74
|
-
reject(new Error(`HTTP ${response.statusCode}`));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
pipeline(response, file).then(resolve).catch(reject);
|
|
78
|
-
}).on('error', reject);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Make executable on Unix
|
|
82
|
-
if (process.platform !== 'win32') {
|
|
83
|
-
chmodSync(destPath, 0o755);
|
|
84
|
-
}
|
|
108
|
+
tried.push(versionedUrl);
|
|
109
|
+
console.log(`[zcompress] ↓ Downloading ${versionedUrl} ...`);
|
|
110
|
+
await downloadToFile(versionedUrl, destPath);
|
|
85
111
|
|
|
112
|
+
if (process.platform !== 'win32') chmodSync(destPath, 0o755);
|
|
86
113
|
console.log(`[zcompress] ✓ Binary installed: ${destPath}`);
|
|
87
114
|
return true;
|
|
88
115
|
} catch (err) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
// cleanup partial
|
|
117
|
+
try { unlinkSync(destPath); } catch {}
|
|
118
|
+
|
|
119
|
+
// If 404 or similar, try latest release as fallback
|
|
120
|
+
const msg = String(err?.message || err);
|
|
121
|
+
if (!msg.includes('404')) {
|
|
122
|
+
console.log(`[zcompress] ⚠ Download failed (${msg}).`);
|
|
93
123
|
} else {
|
|
94
|
-
console.log(`[zcompress] ⚠
|
|
124
|
+
console.log(`[zcompress] ⚠ Asset missing for v${VERSION}: ${binaryName}`);
|
|
95
125
|
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Attempt 2: latest release fallback
|
|
129
|
+
try {
|
|
130
|
+
const latestAssetUrl = await resolveFallbackAssetUrl(binaryName);
|
|
131
|
+
tried.push(latestAssetUrl);
|
|
132
|
+
console.log(`[zcompress] ↓ Falling back to latest release asset: ${latestAssetUrl}`);
|
|
133
|
+
await downloadToFile(latestAssetUrl, destPath);
|
|
134
|
+
|
|
135
|
+
if (process.platform !== 'win32') chmodSync(destPath, 0o755);
|
|
136
|
+
console.log(`[zcompress] ✓ Binary installed from latest release: ${destPath}`);
|
|
137
|
+
return true;
|
|
138
|
+
} catch (err) {
|
|
139
|
+
try { unlinkSync(destPath); } catch {}
|
|
140
|
+
console.log(`[zcompress] ⚠ Fallback download failed (${err.message}).`);
|
|
141
|
+
console.log('[zcompress] Tried URLs:');
|
|
142
|
+
for (const u of tried) console.log(` - ${u}`);
|
|
96
143
|
console.log('[zcompress] ℹ Build from source: cd zcompress && zig build -Doptimize=ReleaseFast');
|
|
97
|
-
// Clean up partial download
|
|
98
|
-
try { unlinkSync(destPath); } catch (_) { /* ignore */ }
|
|
99
144
|
return false;
|
|
100
145
|
}
|
|
101
146
|
}
|
|
102
147
|
|
|
103
148
|
// Run download, but don't fail install if it doesn't work
|
|
104
|
-
downloadBinary().catch(() => {
|
|
105
|
-
console.log(
|
|
106
|
-
console.log('[zcompress] ℹ Install it
|
|
149
|
+
downloadBinary().catch((err) => {
|
|
150
|
+
console.log(`[zcompress] ⚠ Binary download skipped (${err.message}).`);
|
|
151
|
+
console.log('[zcompress] ℹ Install it manually and set plugin option `binaryPath`.');
|
|
107
152
|
});
|