serverme-cli 1.0.0
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 +51 -0
- package/bin/cli.js +20 -0
- package/bin/install.js +140 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# serverme-cli
|
|
2
|
+
|
|
3
|
+
CLI for [ServerMe](https://serverme.site) — open-source tunnel to expose your local servers to the internet.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g serverme-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Expose an HTTP server
|
|
15
|
+
serverme http 3000
|
|
16
|
+
|
|
17
|
+
# TCP tunnel
|
|
18
|
+
serverme tcp 5432
|
|
19
|
+
|
|
20
|
+
# TLS passthrough
|
|
21
|
+
serverme tls 443
|
|
22
|
+
|
|
23
|
+
# Save auth token
|
|
24
|
+
serverme authtoken YOUR_TOKEN
|
|
25
|
+
|
|
26
|
+
# Multiple tunnels from config
|
|
27
|
+
serverme start
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Other Install Methods
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Homebrew (macOS/Linux)
|
|
34
|
+
brew install serverme/tap/serverme
|
|
35
|
+
|
|
36
|
+
# Go
|
|
37
|
+
go install github.com/jams24/serverme/cli/cmd/serverme@latest
|
|
38
|
+
|
|
39
|
+
# Shell script
|
|
40
|
+
curl -fsSL https://get.serverme.dev | sh
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Links
|
|
44
|
+
|
|
45
|
+
- Website: https://serverme.site
|
|
46
|
+
- GitHub: https://github.com/jams24/serverme
|
|
47
|
+
- Docs: https://serverme.site/docs
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
|
|
8
|
+
const binaryName = os.platform() === "win32" ? "serverme.exe" : "serverme";
|
|
9
|
+
const binaryPath = path.join(__dirname, binaryName);
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(binaryPath)) {
|
|
12
|
+
console.error("serverme binary not found. Run: npm rebuild serverme-cli");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
execFileSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
|
|
18
|
+
} catch (err) {
|
|
19
|
+
process.exit(err.status || 1);
|
|
20
|
+
}
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const os = require("os");
|
|
8
|
+
const zlib = require("zlib");
|
|
9
|
+
const { pipeline } = require("stream/promises");
|
|
10
|
+
|
|
11
|
+
const VERSION = "1.0.0";
|
|
12
|
+
const GITHUB_REPO = "serverme/serverme";
|
|
13
|
+
|
|
14
|
+
function getPlatform() {
|
|
15
|
+
const platform = os.platform();
|
|
16
|
+
const arch = os.arch();
|
|
17
|
+
|
|
18
|
+
const platformMap = { darwin: "darwin", linux: "linux", win32: "windows" };
|
|
19
|
+
const archMap = { x64: "amd64", arm64: "arm64" };
|
|
20
|
+
|
|
21
|
+
const goPlatform = platformMap[platform];
|
|
22
|
+
const goArch = archMap[arch];
|
|
23
|
+
|
|
24
|
+
if (!goPlatform || !goArch) {
|
|
25
|
+
console.error(`Unsupported platform: ${platform}/${arch}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { platform: goPlatform, arch: goArch };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getBinaryName(platform) {
|
|
33
|
+
return platform === "windows" ? "serverme.exe" : "serverme";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function download(url) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
https
|
|
39
|
+
.get(url, (res) => {
|
|
40
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
41
|
+
return download(res.headers.location).then(resolve).catch(reject);
|
|
42
|
+
}
|
|
43
|
+
if (res.statusCode !== 200) {
|
|
44
|
+
return reject(new Error(`HTTP ${res.statusCode}: ${url}`));
|
|
45
|
+
}
|
|
46
|
+
const chunks = [];
|
|
47
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
48
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
49
|
+
res.on("error", reject);
|
|
50
|
+
})
|
|
51
|
+
.on("error", reject);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function install() {
|
|
56
|
+
const { platform, arch } = getPlatform();
|
|
57
|
+
const binaryName = getBinaryName(platform);
|
|
58
|
+
const binDir = path.join(__dirname);
|
|
59
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
60
|
+
|
|
61
|
+
// Skip if already installed
|
|
62
|
+
if (fs.existsSync(binaryPath)) {
|
|
63
|
+
try {
|
|
64
|
+
execSync(`"${binaryPath}" version`, { stdio: "pipe" });
|
|
65
|
+
console.log("serverme already installed");
|
|
66
|
+
return;
|
|
67
|
+
} catch {
|
|
68
|
+
// Corrupted binary, re-download
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const ext = platform === "windows" ? "zip" : "tar.gz";
|
|
73
|
+
const url = `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}/serverme_${platform}_${arch}.${ext}`;
|
|
74
|
+
|
|
75
|
+
console.log(`Downloading serverme v${VERSION} for ${platform}/${arch}...`);
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const data = await download(url);
|
|
79
|
+
|
|
80
|
+
if (ext === "tar.gz") {
|
|
81
|
+
// Extract tar.gz
|
|
82
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "serverme-"));
|
|
83
|
+
const tarPath = path.join(tmpDir, "serverme.tar.gz");
|
|
84
|
+
fs.writeFileSync(tarPath, data);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
execSync(`tar -xzf "${tarPath}" -C "${tmpDir}"`, { stdio: "pipe" });
|
|
88
|
+
const extracted = path.join(tmpDir, "serverme");
|
|
89
|
+
if (fs.existsSync(extracted)) {
|
|
90
|
+
fs.copyFileSync(extracted, binaryPath);
|
|
91
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
// tar failed, try node-native gunzip
|
|
95
|
+
console.log("Extracting with Node.js...");
|
|
96
|
+
const gunzipped = zlib.gunzipSync(data);
|
|
97
|
+
// Simple tar extraction — find the binary in the tar
|
|
98
|
+
// Tar header: 512-byte blocks, filename at offset 0, size at offset 124
|
|
99
|
+
let offset = 0;
|
|
100
|
+
while (offset < gunzipped.length - 512) {
|
|
101
|
+
const header = gunzipped.subarray(offset, offset + 512);
|
|
102
|
+
const name = header.toString("utf8", 0, 100).replace(/\0/g, "");
|
|
103
|
+
const sizeStr = header.toString("utf8", 124, 136).replace(/\0/g, "").trim();
|
|
104
|
+
const size = parseInt(sizeStr, 8) || 0;
|
|
105
|
+
|
|
106
|
+
if (name === "serverme" || name === "./serverme") {
|
|
107
|
+
const fileData = gunzipped.subarray(offset + 512, offset + 512 + size);
|
|
108
|
+
fs.writeFileSync(binaryPath, fileData);
|
|
109
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
offset += 512 + Math.ceil(size / 512) * 512;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
118
|
+
} else {
|
|
119
|
+
// ZIP (Windows) — just write the data, user needs to handle
|
|
120
|
+
fs.writeFileSync(binaryPath, data);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (fs.existsSync(binaryPath)) {
|
|
124
|
+
console.log(`serverme v${VERSION} installed successfully`);
|
|
125
|
+
} else {
|
|
126
|
+
throw new Error("Binary not found after extraction");
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error(`Failed to download serverme: ${err.message}`);
|
|
130
|
+
console.error("");
|
|
131
|
+
console.error("You can install manually:");
|
|
132
|
+
console.error(
|
|
133
|
+
" go install github.com/jams24/serverme/cli/cmd/serverme@latest"
|
|
134
|
+
);
|
|
135
|
+
console.error(" or visit: https://github.com/jams24/serverme/releases");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
install();
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "serverme-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI for ServerMe — open-source tunnel to expose localhost to the internet",
|
|
5
|
+
"bin": {
|
|
6
|
+
"serverme": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node bin/install.js"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"serverme",
|
|
13
|
+
"tunnel",
|
|
14
|
+
"ngrok",
|
|
15
|
+
"localhost",
|
|
16
|
+
"cli",
|
|
17
|
+
"expose",
|
|
18
|
+
"webhook"
|
|
19
|
+
],
|
|
20
|
+
"author": "ServerMe",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/jams24/serverme"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://serverme.site",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
},
|
|
30
|
+
"os": [
|
|
31
|
+
"darwin",
|
|
32
|
+
"linux",
|
|
33
|
+
"win32"
|
|
34
|
+
],
|
|
35
|
+
"cpu": [
|
|
36
|
+
"x64",
|
|
37
|
+
"arm64"
|
|
38
|
+
]
|
|
39
|
+
}
|