webctx 0.1.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/AGENTS.md +84 -0
- package/CONTRIBUTORS.md +93 -0
- package/LICENSE +21 -0
- package/Makefile +69 -0
- package/README.md +95 -0
- package/bin/webctx.js +28 -0
- package/cmd/webctx/main.go +11 -0
- package/docs/porting-status.md +173 -0
- package/go.mod +3 -0
- package/internal/app/app.go +139 -0
- package/internal/app/app_test.go +77 -0
- package/internal/app/scrape.go +310 -0
- package/internal/app/tools.go +558 -0
- package/internal/buildinfo/buildinfo.go +16 -0
- package/package.json +55 -0
- package/scripts/postinstall.js +137 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
const https = require("node:https");
|
|
6
|
+
const { spawnSync } = require("node:child_process");
|
|
7
|
+
|
|
8
|
+
const pkg = require("../package.json");
|
|
9
|
+
const cliName = pkg.config?.cliBinaryName || "webctx";
|
|
10
|
+
|
|
11
|
+
const repoURL = pkg.repository?.url || "";
|
|
12
|
+
const repoMatch = repoURL.match(/github\.com[:/](.+?)\/(.+?)(?:\.git)?$/);
|
|
13
|
+
if (!repoMatch) {
|
|
14
|
+
console.error("package.json repository.url must point to a GitHub repo.");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const repoOwner = repoMatch[1];
|
|
19
|
+
const repoName = repoMatch[2];
|
|
20
|
+
|
|
21
|
+
const goosMap = {
|
|
22
|
+
darwin: "darwin",
|
|
23
|
+
linux: "linux",
|
|
24
|
+
win32: "windows"
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const goarchMap = {
|
|
28
|
+
x64: "amd64",
|
|
29
|
+
arm64: "arm64"
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const goos = goosMap[process.platform];
|
|
33
|
+
const goarch = goarchMap[process.arch];
|
|
34
|
+
|
|
35
|
+
const rootDir = path.resolve(__dirname, "..");
|
|
36
|
+
const binDir = path.join(rootDir, "bin");
|
|
37
|
+
const binaryName = process.platform === "win32" ? `${cliName}.exe` : `${cliName}-bin`;
|
|
38
|
+
const destination = path.join(binDir, binaryName);
|
|
39
|
+
|
|
40
|
+
function buildLdflags(version) {
|
|
41
|
+
const resolvedVersion = `${version || ""}`.trim() || "dev";
|
|
42
|
+
return `-s -w -X github.com/amxv/webctx/internal/buildinfo.Version=${resolvedVersion}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function main() {
|
|
46
|
+
if (!goos || !goarch) {
|
|
47
|
+
console.warn(`Unsupported platform/arch: ${process.platform}/${process.arch}`);
|
|
48
|
+
fallbackBuildOrExit();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
53
|
+
|
|
54
|
+
const version = pkg.version;
|
|
55
|
+
const assetName = `${cliName}_${goos}_${goarch}${goos === "windows" ? ".exe" : ""}`;
|
|
56
|
+
const assetURL = `https://github.com/${repoOwner}/${repoName}/releases/download/v${version}/${assetName}`;
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
await downloadToFile(assetURL, destination);
|
|
60
|
+
if (goos !== "windows") {
|
|
61
|
+
fs.chmodSync(destination, 0o755);
|
|
62
|
+
}
|
|
63
|
+
console.log(`Installed ${cliName} binary from ${assetURL}`);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.warn(`Failed to download prebuilt binary: ${err.message}`);
|
|
66
|
+
fallbackBuildOrExit();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function fallbackBuildOrExit() {
|
|
71
|
+
const hasGo = spawnSync("go", ["version"], { stdio: "ignore" }).status === 0;
|
|
72
|
+
const hasSource = fs.existsSync(path.join(rootDir, "cmd", cliName, "main.go"));
|
|
73
|
+
|
|
74
|
+
if (!hasGo || !hasSource) {
|
|
75
|
+
console.error("Unable to install CLI binary. Missing release asset and local Go build fallback.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const result = spawnSync(
|
|
80
|
+
"go",
|
|
81
|
+
["build", "-trimpath", `-ldflags=${buildLdflags(pkg.version)}`, "-o", destination, `./cmd/${cliName}`],
|
|
82
|
+
{ cwd: rootDir, stdio: "inherit" }
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
if (result.status !== 0) {
|
|
86
|
+
process.exit(result.status || 1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (goos !== "windows") {
|
|
90
|
+
fs.chmodSync(destination, 0o755);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log("Installed CLI binary by building from source.");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function downloadToFile(url, destinationPath) {
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
const request = https.get(url, (response) => {
|
|
99
|
+
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
100
|
+
response.resume();
|
|
101
|
+
downloadToFile(response.headers.location, destinationPath).then(resolve).catch(reject);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (response.statusCode !== 200) {
|
|
106
|
+
response.resume();
|
|
107
|
+
reject(new Error(`HTTP ${response.statusCode}`));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const file = fs.createWriteStream(destinationPath);
|
|
112
|
+
response.pipe(file);
|
|
113
|
+
|
|
114
|
+
file.on("finish", () => {
|
|
115
|
+
file.close((err) => {
|
|
116
|
+
if (err) {
|
|
117
|
+
reject(err);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
file.on("error", (err) => {
|
|
125
|
+
fs.rmSync(destinationPath, { force: true });
|
|
126
|
+
reject(err);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
request.on("error", reject);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
main().catch((err) => {
|
|
135
|
+
console.error(err.message);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|