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 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
+ }