ztnet-cli 0.1.12 → 0.1.16
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/LICENSE +8 -8
- package/README.md +21 -21
- package/artifacts/ztnet-0.1.16-aarch64-apple-darwin.tar.gz +0 -0
- package/artifacts/ztnet-0.1.16-aarch64-apple-darwin.tar.gz.sha256 +1 -0
- package/artifacts/ztnet-0.1.16-x86_64-pc-windows-msvc.zip +0 -0
- package/artifacts/ztnet-0.1.16-x86_64-pc-windows-msvc.zip.sha256 +1 -0
- package/artifacts/ztnet-0.1.16-x86_64-unknown-linux-gnu.tar.gz +0 -0
- package/artifacts/ztnet-0.1.16-x86_64-unknown-linux-gnu.tar.gz.sha256 +1 -0
- package/bin/ztnet.js +30 -30
- package/package.json +37 -37
- package/scripts/install.js +180 -180
- package/artifacts/ztnet-0.1.12-aarch64-apple-darwin.tar.gz +0 -0
- package/artifacts/ztnet-0.1.12-aarch64-apple-darwin.tar.gz.sha256 +0 -1
- package/artifacts/ztnet-0.1.12-x86_64-pc-windows-msvc.zip +0 -0
- package/artifacts/ztnet-0.1.12-x86_64-pc-windows-msvc.zip.sha256 +0 -1
- package/artifacts/ztnet-0.1.12-x86_64-unknown-linux-gnu.tar.gz +0 -0
- package/artifacts/ztnet-0.1.12-x86_64-unknown-linux-gnu.tar.gz.sha256 +0 -1
package/LICENSE
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
GNU Affero General Public License v3.0 (AGPL-3.0-only)
|
|
2
|
-
|
|
3
|
-
This npm package is distributed under the same license as the upstream project:
|
|
4
|
-
https://github.com/JKamsker/ztnet-cli
|
|
5
|
-
|
|
6
|
-
You can find the full license text at:
|
|
7
|
-
https://www.gnu.org/licenses/agpl-3.0.txt
|
|
8
|
-
|
|
1
|
+
GNU Affero General Public License v3.0 (AGPL-3.0-only)
|
|
2
|
+
|
|
3
|
+
This npm package is distributed under the same license as the upstream project:
|
|
4
|
+
https://github.com/JKamsker/ztnet-cli
|
|
5
|
+
|
|
6
|
+
You can find the full license text at:
|
|
7
|
+
https://www.gnu.org/licenses/agpl-3.0.txt
|
|
8
|
+
|
package/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# ztnet-cli (npm)
|
|
2
|
-
|
|
3
|
-
This package installs the prebuilt **ZTNet CLI** (`ztnet`) for your platform.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g ztnet-cli
|
|
9
|
-
ztnet --help
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## How it works
|
|
13
|
-
|
|
14
|
-
On install, `ztnet-cli` downloads the matching `ztnet` binary from the GitHub Releases for the same version.
|
|
15
|
-
|
|
16
|
-
Supported platforms:
|
|
17
|
-
|
|
18
|
-
- Windows (x64)
|
|
19
|
-
- Linux (x64)
|
|
20
|
-
- macOS (arm64, x64)
|
|
21
|
-
|
|
1
|
+
# ztnet-cli (npm)
|
|
2
|
+
|
|
3
|
+
This package installs the prebuilt **ZTNet CLI** (`ztnet`) for your platform.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g ztnet-cli
|
|
9
|
+
ztnet --help
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## How it works
|
|
13
|
+
|
|
14
|
+
On install, `ztnet-cli` downloads the matching `ztnet` binary from the GitHub Releases for the same version.
|
|
15
|
+
|
|
16
|
+
Supported platforms:
|
|
17
|
+
|
|
18
|
+
- Windows (x64)
|
|
19
|
+
- Linux (x64)
|
|
20
|
+
- macOS (arm64, x64)
|
|
21
|
+
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aca1c95e736eeddb61bd1012e21f7a80b460303d31df8646ad60303451952c26 ztnet-0.1.16-aarch64-apple-darwin.tar.gz
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9aeaefaae431377e90ac6e2251a439316ee573ae3443c1f997aebc160892796d ztnet-0.1.16-x86_64-pc-windows-msvc.zip
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
167426187cc710afb58be9ba004091ec0412ccc3ccfef0fee4ec480fd075a45a ztnet-0.1.16-x86_64-unknown-linux-gnu.tar.gz
|
package/bin/ztnet.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const childProcess = require("node:child_process");
|
|
4
|
-
const fs = require("node:fs");
|
|
5
|
-
const path = require("node:path");
|
|
6
|
-
|
|
7
|
-
const packageRoot = path.join(__dirname, "..");
|
|
8
|
-
const vendorDir = path.join(packageRoot, "vendor");
|
|
9
|
-
const exeName = process.platform === "win32" ? "ztnet.exe" : "ztnet";
|
|
10
|
-
const exePath = path.join(vendorDir, exeName);
|
|
11
|
-
|
|
12
|
-
if (!fs.existsSync(exePath)) {
|
|
13
|
-
console.error(`[ztnet-cli] Missing native binary: ${exePath}`);
|
|
14
|
-
console.error(
|
|
15
|
-
"[ztnet-cli] Reinstall to re-run the downloader: npm install -g ztnet-cli",
|
|
16
|
-
);
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const result = childProcess.spawnSync(exePath, process.argv.slice(2), {
|
|
21
|
-
stdio: "inherit",
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
if (result.error) {
|
|
25
|
-
console.error(`[ztnet-cli] Failed to run ${exePath}: ${result.error.message}`);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
process.exit(result.status ?? 1);
|
|
30
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const childProcess = require("node:child_process");
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
|
|
7
|
+
const packageRoot = path.join(__dirname, "..");
|
|
8
|
+
const vendorDir = path.join(packageRoot, "vendor");
|
|
9
|
+
const exeName = process.platform === "win32" ? "ztnet.exe" : "ztnet";
|
|
10
|
+
const exePath = path.join(vendorDir, exeName);
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(exePath)) {
|
|
13
|
+
console.error(`[ztnet-cli] Missing native binary: ${exePath}`);
|
|
14
|
+
console.error(
|
|
15
|
+
"[ztnet-cli] Reinstall to re-run the downloader: npm install -g ztnet-cli",
|
|
16
|
+
);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const result = childProcess.spawnSync(exePath, process.argv.slice(2), {
|
|
21
|
+
stdio: "inherit",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (result.error) {
|
|
25
|
+
console.error(`[ztnet-cli] Failed to run ${exePath}: ${result.error.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
process.exit(result.status ?? 1);
|
|
30
|
+
|
package/package.json
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ztnet-cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "ZTNet CLI \u2014 manage ZeroTier networks via ZTNet",
|
|
5
|
-
"license": "AGPL-3.0-only",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/JKamsker/ztnet-cli.git"
|
|
9
|
-
},
|
|
10
|
-
"homepage": "https://github.com/JKamsker/ztnet-cli",
|
|
11
|
-
"bugs": {
|
|
12
|
-
"url": "https://github.com/JKamsker/ztnet-cli/issues"
|
|
13
|
-
},
|
|
14
|
-
"bin": {
|
|
15
|
-
"ztnet": "bin/ztnet.js"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"bin/",
|
|
19
|
-
"artifacts/",
|
|
20
|
-
"scripts/",
|
|
21
|
-
"README.md",
|
|
22
|
-
"LICENSE"
|
|
23
|
-
],
|
|
24
|
-
"engines": {
|
|
25
|
-
"node": ">=18"
|
|
26
|
-
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"postinstall": "node scripts/install.js"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"extract-zip": "^2.0.1",
|
|
32
|
-
"tar": "^6.2.0"
|
|
33
|
-
},
|
|
34
|
-
"publishConfig": {
|
|
35
|
-
"access": "public"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "ztnet-cli",
|
|
3
|
+
"version": "0.1.16",
|
|
4
|
+
"description": "ZTNet CLI \u2014 manage ZeroTier networks via ZTNet",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/JKamsker/ztnet-cli.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/JKamsker/ztnet-cli",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/JKamsker/ztnet-cli/issues"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"ztnet": "bin/ztnet.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/",
|
|
19
|
+
"artifacts/",
|
|
20
|
+
"scripts/",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"postinstall": "node scripts/install.js"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"extract-zip": "^2.0.1",
|
|
32
|
+
"tar": "^6.2.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/scripts/install.js
CHANGED
|
@@ -1,161 +1,161 @@
|
|
|
1
|
-
const crypto = require("node:crypto");
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const https = require("node:https");
|
|
4
|
-
const os = require("node:os");
|
|
5
|
-
const path = require("node:path");
|
|
6
|
-
|
|
7
|
-
const extractZip = require("extract-zip");
|
|
8
|
-
const tar = require("tar");
|
|
9
|
-
|
|
10
|
-
function resolvePlatformTarget() {
|
|
11
|
-
const platform = process.platform;
|
|
12
|
-
const arch = process.arch;
|
|
13
|
-
|
|
14
|
-
if (platform === "win32" && arch === "x64") {
|
|
15
|
-
return { target: "x86_64-pc-windows-msvc", archiveExt: "zip", exe: "ztnet.exe" };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (platform === "linux" && arch === "x64") {
|
|
19
|
-
return { target: "x86_64-unknown-linux-gnu", archiveExt: "tar.gz", exe: "ztnet" };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (platform === "darwin" && arch === "arm64") {
|
|
23
|
-
return { target: "aarch64-apple-darwin", archiveExt: "tar.gz", exe: "ztnet" };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (platform === "darwin" && arch === "x64") {
|
|
27
|
-
return { target: "x86_64-apple-darwin", archiveExt: "tar.gz", exe: "ztnet" };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function readPackageJsonVersion(packageRoot) {
|
|
34
|
-
const pkgJsonPath = path.join(packageRoot, "package.json");
|
|
35
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
36
|
-
if (!pkg?.version) throw new Error("Failed to read version from package.json");
|
|
37
|
-
return String(pkg.version);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function httpGet(url) {
|
|
41
|
-
return new Promise((resolve, reject) => {
|
|
42
|
-
https
|
|
43
|
-
.get(
|
|
44
|
-
url,
|
|
45
|
-
{
|
|
46
|
-
headers: {
|
|
47
|
-
"User-Agent": "ztnet-cli-npm-installer",
|
|
48
|
-
Accept: "application/octet-stream",
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
(res) => {
|
|
52
|
-
const code = res.statusCode ?? 0;
|
|
53
|
-
|
|
54
|
-
if (code >= 300 && code < 400 && res.headers.location) {
|
|
55
|
-
res.resume();
|
|
56
|
-
resolve(httpGet(res.headers.location));
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (code !== 200) {
|
|
61
|
-
const chunks = [];
|
|
62
|
-
res.on("data", (c) => chunks.push(c));
|
|
63
|
-
res.on("end", () => {
|
|
64
|
-
const body = Buffer.concat(chunks).toString("utf8").slice(0, 3000);
|
|
65
|
-
reject(new Error(`GET ${url} failed: HTTP ${code}\n${body}`));
|
|
66
|
-
});
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const chunks = [];
|
|
71
|
-
res.on("data", (c) => chunks.push(c));
|
|
72
|
-
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
73
|
-
res.on("error", reject);
|
|
74
|
-
},
|
|
75
|
-
)
|
|
76
|
-
.on("error", reject);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function downloadToFile(url, outPath) {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
82
|
-
https
|
|
83
|
-
.get(
|
|
84
|
-
url,
|
|
85
|
-
{
|
|
86
|
-
headers: {
|
|
87
|
-
"User-Agent": "ztnet-cli-npm-installer",
|
|
88
|
-
Accept: "application/octet-stream",
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
(res) => {
|
|
92
|
-
const code = res.statusCode ?? 0;
|
|
93
|
-
|
|
94
|
-
if (code >= 300 && code < 400 && res.headers.location) {
|
|
95
|
-
res.resume();
|
|
96
|
-
resolve(downloadToFile(res.headers.location, outPath));
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (code !== 200) {
|
|
101
|
-
const chunks = [];
|
|
102
|
-
res.on("data", (c) => chunks.push(c));
|
|
103
|
-
res.on("end", () => {
|
|
104
|
-
const body = Buffer.concat(chunks).toString("utf8").slice(0, 3000);
|
|
105
|
-
reject(new Error(`Download ${url} failed: HTTP ${code}\n${body}`));
|
|
106
|
-
});
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const file = fs.createWriteStream(outPath);
|
|
111
|
-
res.pipe(file);
|
|
112
|
-
|
|
113
|
-
file.on("finish", () => file.close(resolve));
|
|
114
|
-
file.on("error", (err) => {
|
|
115
|
-
try {
|
|
116
|
-
fs.unlinkSync(outPath);
|
|
117
|
-
} catch {
|
|
118
|
-
// ignore
|
|
119
|
-
}
|
|
120
|
-
reject(err);
|
|
121
|
-
});
|
|
122
|
-
},
|
|
123
|
-
)
|
|
124
|
-
.on("error", reject);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function sha256File(filePath) {
|
|
129
|
-
return new Promise((resolve, reject) => {
|
|
130
|
-
const hash = crypto.createHash("sha256");
|
|
131
|
-
const stream = fs.createReadStream(filePath);
|
|
132
|
-
stream.on("data", (chunk) => hash.update(chunk));
|
|
133
|
-
stream.on("error", reject);
|
|
134
|
-
stream.on("end", () => resolve(hash.digest("hex")));
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function ensureDir(dirPath) {
|
|
139
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function safeCopyFile(src, dest) {
|
|
143
|
-
ensureDir(path.dirname(dest));
|
|
144
|
-
fs.copyFileSync(src, dest);
|
|
145
|
-
}
|
|
146
|
-
|
|
1
|
+
const crypto = require("node:crypto");
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const https = require("node:https");
|
|
4
|
+
const os = require("node:os");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
|
|
7
|
+
const extractZip = require("extract-zip");
|
|
8
|
+
const tar = require("tar");
|
|
9
|
+
|
|
10
|
+
function resolvePlatformTarget() {
|
|
11
|
+
const platform = process.platform;
|
|
12
|
+
const arch = process.arch;
|
|
13
|
+
|
|
14
|
+
if (platform === "win32" && arch === "x64") {
|
|
15
|
+
return { target: "x86_64-pc-windows-msvc", archiveExt: "zip", exe: "ztnet.exe" };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (platform === "linux" && arch === "x64") {
|
|
19
|
+
return { target: "x86_64-unknown-linux-gnu", archiveExt: "tar.gz", exe: "ztnet" };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
23
|
+
return { target: "aarch64-apple-darwin", archiveExt: "tar.gz", exe: "ztnet" };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (platform === "darwin" && arch === "x64") {
|
|
27
|
+
return { target: "x86_64-apple-darwin", archiveExt: "tar.gz", exe: "ztnet" };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readPackageJsonVersion(packageRoot) {
|
|
34
|
+
const pkgJsonPath = path.join(packageRoot, "package.json");
|
|
35
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
36
|
+
if (!pkg?.version) throw new Error("Failed to read version from package.json");
|
|
37
|
+
return String(pkg.version);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function httpGet(url) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
https
|
|
43
|
+
.get(
|
|
44
|
+
url,
|
|
45
|
+
{
|
|
46
|
+
headers: {
|
|
47
|
+
"User-Agent": "ztnet-cli-npm-installer",
|
|
48
|
+
Accept: "application/octet-stream",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
(res) => {
|
|
52
|
+
const code = res.statusCode ?? 0;
|
|
53
|
+
|
|
54
|
+
if (code >= 300 && code < 400 && res.headers.location) {
|
|
55
|
+
res.resume();
|
|
56
|
+
resolve(httpGet(res.headers.location));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (code !== 200) {
|
|
61
|
+
const chunks = [];
|
|
62
|
+
res.on("data", (c) => chunks.push(c));
|
|
63
|
+
res.on("end", () => {
|
|
64
|
+
const body = Buffer.concat(chunks).toString("utf8").slice(0, 3000);
|
|
65
|
+
reject(new Error(`GET ${url} failed: HTTP ${code}\n${body}`));
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const chunks = [];
|
|
71
|
+
res.on("data", (c) => chunks.push(c));
|
|
72
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
73
|
+
res.on("error", reject);
|
|
74
|
+
},
|
|
75
|
+
)
|
|
76
|
+
.on("error", reject);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function downloadToFile(url, outPath) {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
https
|
|
83
|
+
.get(
|
|
84
|
+
url,
|
|
85
|
+
{
|
|
86
|
+
headers: {
|
|
87
|
+
"User-Agent": "ztnet-cli-npm-installer",
|
|
88
|
+
Accept: "application/octet-stream",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
(res) => {
|
|
92
|
+
const code = res.statusCode ?? 0;
|
|
93
|
+
|
|
94
|
+
if (code >= 300 && code < 400 && res.headers.location) {
|
|
95
|
+
res.resume();
|
|
96
|
+
resolve(downloadToFile(res.headers.location, outPath));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (code !== 200) {
|
|
101
|
+
const chunks = [];
|
|
102
|
+
res.on("data", (c) => chunks.push(c));
|
|
103
|
+
res.on("end", () => {
|
|
104
|
+
const body = Buffer.concat(chunks).toString("utf8").slice(0, 3000);
|
|
105
|
+
reject(new Error(`Download ${url} failed: HTTP ${code}\n${body}`));
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const file = fs.createWriteStream(outPath);
|
|
111
|
+
res.pipe(file);
|
|
112
|
+
|
|
113
|
+
file.on("finish", () => file.close(resolve));
|
|
114
|
+
file.on("error", (err) => {
|
|
115
|
+
try {
|
|
116
|
+
fs.unlinkSync(outPath);
|
|
117
|
+
} catch {
|
|
118
|
+
// ignore
|
|
119
|
+
}
|
|
120
|
+
reject(err);
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
)
|
|
124
|
+
.on("error", reject);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function sha256File(filePath) {
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
const hash = crypto.createHash("sha256");
|
|
131
|
+
const stream = fs.createReadStream(filePath);
|
|
132
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
133
|
+
stream.on("error", reject);
|
|
134
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function ensureDir(dirPath) {
|
|
139
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function safeCopyFile(src, dest) {
|
|
143
|
+
ensureDir(path.dirname(dest));
|
|
144
|
+
fs.copyFileSync(src, dest);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
147
|
async function main() {
|
|
148
148
|
const packageRoot = path.join(__dirname, "..");
|
|
149
149
|
const resolved = resolvePlatformTarget();
|
|
150
|
-
|
|
151
|
-
if (!resolved) {
|
|
152
|
-
console.error(
|
|
153
|
-
`[ztnet-cli] Unsupported platform/arch: ${process.platform}/${process.arch}`,
|
|
154
|
-
);
|
|
155
|
-
process.exit(1);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const version = readPackageJsonVersion(packageRoot);
|
|
150
|
+
|
|
151
|
+
if (!resolved) {
|
|
152
|
+
console.error(
|
|
153
|
+
`[ztnet-cli] Unsupported platform/arch: ${process.platform}/${process.arch}`,
|
|
154
|
+
);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const version = readPackageJsonVersion(packageRoot);
|
|
159
159
|
const repo = process.env.ZTNET_CLI_GITHUB_REPO || "JKamsker/ztnet-cli";
|
|
160
160
|
const tag = `v${version}`;
|
|
161
161
|
|
|
@@ -208,28 +208,28 @@ async function main() {
|
|
|
208
208
|
} else {
|
|
209
209
|
throw new Error(`Unsupported archive type: ${resolved.archiveExt}`);
|
|
210
210
|
}
|
|
211
|
-
|
|
212
|
-
const extractedBinary = path.join(extractDir, resolved.exe);
|
|
213
|
-
if (!fs.existsSync(extractedBinary)) {
|
|
214
|
-
throw new Error(`Expected extracted binary not found: ${extractedBinary}`);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
safeCopyFile(extractedBinary, destBinary);
|
|
218
|
-
|
|
219
|
-
if (process.platform !== "win32") {
|
|
220
|
-
fs.chmodSync(destBinary, 0o755);
|
|
221
|
-
}
|
|
222
|
-
} finally {
|
|
223
|
-
try {
|
|
224
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
225
|
-
} catch {
|
|
226
|
-
// ignore
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
main().catch((err) => {
|
|
232
|
-
console.error(`[ztnet-cli] Install failed: ${err?.message || String(err)}`);
|
|
233
|
-
process.exit(1);
|
|
234
|
-
});
|
|
235
|
-
|
|
211
|
+
|
|
212
|
+
const extractedBinary = path.join(extractDir, resolved.exe);
|
|
213
|
+
if (!fs.existsSync(extractedBinary)) {
|
|
214
|
+
throw new Error(`Expected extracted binary not found: ${extractedBinary}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
safeCopyFile(extractedBinary, destBinary);
|
|
218
|
+
|
|
219
|
+
if (process.platform !== "win32") {
|
|
220
|
+
fs.chmodSync(destBinary, 0o755);
|
|
221
|
+
}
|
|
222
|
+
} finally {
|
|
223
|
+
try {
|
|
224
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
225
|
+
} catch {
|
|
226
|
+
// ignore
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
main().catch((err) => {
|
|
232
|
+
console.error(`[ztnet-cli] Install failed: ${err?.message || String(err)}`);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
});
|
|
235
|
+
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
51ae0a72def91ab25aace355f44fd8c6feb34a848f8630eb307c9204e1f2fe7a ztnet-0.1.12-aarch64-apple-darwin.tar.gz
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
7c6fd2c3c4fcc2cafd40f20b14ded78f8c31bbf4ae195d1b07562b9c435d0017 ztnet-0.1.12-x86_64-pc-windows-msvc.zip
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3138263312e945b64f0b72c75f817cc74909aba551bcfabfa42d10502cc4977f ztnet-0.1.12-x86_64-unknown-linux-gnu.tar.gz
|