@itsbjoern/roost 0.1.4
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 +19 -0
- package/bin/roost +35 -0
- package/install.js +148 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## @itsbjoern/roost
|
|
2
|
+
|
|
3
|
+
This is the npm wrapper for the Roost CLI.
|
|
4
|
+
|
|
5
|
+
It downloads a prebuilt `roost` binary from the GitHub Releases of `itsbjoern/roost`
|
|
6
|
+
for your platform and exposes it as the `roost` command.
|
|
7
|
+
|
|
8
|
+
### Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g @itsbjoern/roost
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
roost init
|
|
18
|
+
```
|
|
19
|
+
|
package/bin/roost
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { spawn } = require("child_process");
|
|
6
|
+
|
|
7
|
+
function run() {
|
|
8
|
+
const exeName = process.platform === "win32" ? "roost.exe" : "roost";
|
|
9
|
+
const exePath = path.join(__dirname, exeName);
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(exePath)) {
|
|
12
|
+
console.error(
|
|
13
|
+
"roost: binary not found. Try reinstalling:\n" +
|
|
14
|
+
" npm uninstall -g @itsbjoern/roost && npm install -g @itsbjoern/roost\n" +
|
|
15
|
+
"or download a release binary / build from source:\n" +
|
|
16
|
+
" https://github.com/itsbjoern/roost#install"
|
|
17
|
+
);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const child = spawn(exePath, process.argv.slice(2), {
|
|
22
|
+
stdio: "inherit",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
child.on("exit", (code, signal) => {
|
|
26
|
+
if (signal) {
|
|
27
|
+
process.kill(process.pid, signal);
|
|
28
|
+
} else {
|
|
29
|
+
process.exit(code == null ? 1 : code);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
run();
|
|
35
|
+
|
package/install.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require("https");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
const { pipeline } = require("stream");
|
|
8
|
+
const { promisify } = require("util");
|
|
9
|
+
const tar = require("tar");
|
|
10
|
+
|
|
11
|
+
const streamPipeline = promisify(pipeline);
|
|
12
|
+
|
|
13
|
+
function getTarget() {
|
|
14
|
+
const platform = process.platform;
|
|
15
|
+
const arch = process.arch;
|
|
16
|
+
|
|
17
|
+
if (platform === "linux" && arch === "x64") {
|
|
18
|
+
return "x86_64-unknown-linux-gnu";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
22
|
+
return "aarch64-apple-darwin";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (platform === "win32" && arch === "x64") {
|
|
26
|
+
return "x86_64-pc-windows-msvc";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function download(url, dest) {
|
|
33
|
+
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
|
34
|
+
|
|
35
|
+
await new Promise((resolve, reject) => {
|
|
36
|
+
const file = fs.createWriteStream(dest);
|
|
37
|
+
|
|
38
|
+
https
|
|
39
|
+
.get(url, (res) => {
|
|
40
|
+
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
41
|
+
// Redirect
|
|
42
|
+
https.get(res.headers.location, (res2) => {
|
|
43
|
+
if (res2.statusCode !== 200) {
|
|
44
|
+
reject(
|
|
45
|
+
new Error(`Failed to download binary. HTTP status code: ${res2.statusCode}`)
|
|
46
|
+
);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
streamPipeline(res2, file).then(resolve).catch(reject);
|
|
50
|
+
}).on("error", reject);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (res.statusCode !== 200) {
|
|
55
|
+
reject(
|
|
56
|
+
new Error(`Failed to download binary. HTTP status code: ${res.statusCode}`)
|
|
57
|
+
);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
streamPipeline(res, file).then(resolve).catch(reject);
|
|
62
|
+
})
|
|
63
|
+
.on("error", reject);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function main() {
|
|
68
|
+
const target = getTarget();
|
|
69
|
+
if (!target) {
|
|
70
|
+
console.error(
|
|
71
|
+
"roost: prebuilt binary is not available for this platform yet.\n" +
|
|
72
|
+
"Supported from npm: linux-x64, darwin-arm64, win32-x64.\n" +
|
|
73
|
+
"You can still install by downloading a release binary or building from source:\n" +
|
|
74
|
+
" https://github.com/itsbjoern/roost#install"
|
|
75
|
+
);
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const pkgPath = path.join(__dirname, "package.json");
|
|
81
|
+
let version = null;
|
|
82
|
+
try {
|
|
83
|
+
// eslint-disable-next-line import/no-dynamic-require, global-require
|
|
84
|
+
version = require(pkgPath).version;
|
|
85
|
+
} catch {
|
|
86
|
+
// best-effort; fall back to env if present
|
|
87
|
+
version = process.env.npm_package_version || null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!version) {
|
|
91
|
+
console.error("roost: could not determine package version for download URL.");
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const tag = `v${version}`;
|
|
97
|
+
const fileName = `roost-${target}.tar.gz`;
|
|
98
|
+
const url = `https://github.com/itsbjoern/roost/releases/download/${tag}/${fileName}`;
|
|
99
|
+
|
|
100
|
+
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "roost-"));
|
|
101
|
+
const archivePath = path.join(tmpDir, fileName);
|
|
102
|
+
const binDir = path.join(__dirname, "bin");
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
console.log(`roost: downloading ${url}`);
|
|
106
|
+
await download(url, archivePath);
|
|
107
|
+
|
|
108
|
+
await fs.promises.mkdir(binDir, { recursive: true });
|
|
109
|
+
|
|
110
|
+
await tar.x({
|
|
111
|
+
file: archivePath,
|
|
112
|
+
cwd: binDir,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const exeName = process.platform === "win32" ? "roost.exe" : "roost";
|
|
116
|
+
const binPath = path.join(binDir, exeName);
|
|
117
|
+
|
|
118
|
+
const exists = fs.existsSync(binPath);
|
|
119
|
+
if (!exists) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Extracted archive did not contain expected binary at ${binPath}`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (process.platform !== "win32") {
|
|
126
|
+
await fs.promises.chmod(binPath, 0o755);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log("roost: binary installed.");
|
|
130
|
+
} catch (err) {
|
|
131
|
+
console.error(`roost: failed to install binary from GitHub Releases.\n${err}`);
|
|
132
|
+
console.error(
|
|
133
|
+
"You can download a binary manually or build from source:\n" +
|
|
134
|
+
" https://github.com/itsbjoern/roost#install"
|
|
135
|
+
);
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
} finally {
|
|
138
|
+
// best-effort cleanup
|
|
139
|
+
try {
|
|
140
|
+
await fs.promises.rm(tmpDir, { recursive: true, force: true });
|
|
141
|
+
} catch {
|
|
142
|
+
// ignore
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
void main();
|
|
148
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@itsbjoern/roost",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Roost CLI - local HTTPS reverse proxy with automatic cert management",
|
|
5
|
+
"bin": {
|
|
6
|
+
"roost": "bin/roost"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node install.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"install.js",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"https",
|
|
18
|
+
"tls",
|
|
19
|
+
"ssl",
|
|
20
|
+
"certificates",
|
|
21
|
+
"proxy",
|
|
22
|
+
"local-development",
|
|
23
|
+
"devtools"
|
|
24
|
+
],
|
|
25
|
+
"author": "Björn Friedrichs (https://bjoernf.com)",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/itsbjoern/roost.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/itsbjoern/roost/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/itsbjoern/roost#readme",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=16"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"tar": "^7.4.3"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
}
|
|
44
|
+
}
|