@manasvinyadav000/swrm 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/bin/swrm.js +34 -0
- package/package.json +43 -0
- package/scripts/install.js +114 -0
package/bin/swrm.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const binName = process.platform === 'win32' ? 'swrm.exe' : 'swrm';
|
|
8
|
+
const binPath = path.join(__dirname, '..', 'dist', binName);
|
|
9
|
+
|
|
10
|
+
// stdio: 'inherit' hands the child the parent's actual stdin/stdout/stderr
|
|
11
|
+
// file descriptors, so the Bubble Tea TUI gets a real TTY — raw keyboard
|
|
12
|
+
// input, terminal resize events, and full-speed output — with no piping
|
|
13
|
+
// overhead in between.
|
|
14
|
+
const result = spawnSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
|
|
15
|
+
|
|
16
|
+
if (result.error) {
|
|
17
|
+
if (result.error.code === 'ENOENT') {
|
|
18
|
+
console.error(
|
|
19
|
+
`[swrm] Could not find the swrm binary at:\n ${binPath}\n\n` +
|
|
20
|
+
'Try reinstalling: npm install -g @manasvinyadav000/swrm'
|
|
21
|
+
);
|
|
22
|
+
} else {
|
|
23
|
+
console.error(`[swrm] Failed to launch: ${result.error.message}`);
|
|
24
|
+
}
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (result.signal) {
|
|
29
|
+
// Killed by a signal (e.g. Ctrl+C forwarded at the OS level) rather than
|
|
30
|
+
// exiting normally — there's no meaningful exit code to forward.
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@manasvinyadav000/swrm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first BitTorrent TUI with a VPN kill-switch and in-app streaming.",
|
|
5
|
+
"homepage": "https://github.com/ManasvinYadav/swrm#readme",
|
|
6
|
+
"bugs": "https://github.com/ManasvinYadav/swrm/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ManasvinYadav/swrm.git"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Manasvin Yadav",
|
|
13
|
+
"bin": {
|
|
14
|
+
"swrm": "./bin/swrm.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin",
|
|
18
|
+
"scripts"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"postinstall": "node ./scripts/install.js"
|
|
22
|
+
},
|
|
23
|
+
"os": [
|
|
24
|
+
"darwin",
|
|
25
|
+
"linux",
|
|
26
|
+
"win32"
|
|
27
|
+
],
|
|
28
|
+
"cpu": [
|
|
29
|
+
"x64",
|
|
30
|
+
"arm64"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=14"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"bittorrent",
|
|
37
|
+
"torrent",
|
|
38
|
+
"tui",
|
|
39
|
+
"cli",
|
|
40
|
+
"streaming",
|
|
41
|
+
"vpn"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Downloads the prebuilt swrm binary matching this package's version and the
|
|
5
|
+
// current platform/arch from GitHub Releases. Pure Node stdlib — no runtime
|
|
6
|
+
// dependencies for the npm package.
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const https = require('https');
|
|
11
|
+
|
|
12
|
+
const REPO = 'ManasvinYadav/swrm';
|
|
13
|
+
const pkg = require('../package.json');
|
|
14
|
+
|
|
15
|
+
const PLATFORM_MAP = { darwin: 'darwin', linux: 'linux', win32: 'windows' };
|
|
16
|
+
const ARCH_MAP = { x64: 'amd64', arm64: 'arm64' };
|
|
17
|
+
|
|
18
|
+
function fail(message) {
|
|
19
|
+
console.error(`[swrm install] ${message}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function resolveTarget() {
|
|
24
|
+
const os = PLATFORM_MAP[process.platform];
|
|
25
|
+
const arch = ARCH_MAP[process.arch];
|
|
26
|
+
if (!os) {
|
|
27
|
+
fail(
|
|
28
|
+
`Unsupported platform "${process.platform}". swrm ships prebuilt binaries for ` +
|
|
29
|
+
'macOS, Linux, and Windows only — try building from source instead.'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (!arch) {
|
|
33
|
+
fail(
|
|
34
|
+
`Unsupported architecture "${process.arch}". swrm ships prebuilt binaries for ` +
|
|
35
|
+
'x64 and arm64 only — try building from source instead.'
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
const ext = os === 'windows' ? '.exe' : '';
|
|
39
|
+
return { os, arch, ext, assetName: `swrm-${os}-${arch}${ext}` };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Follows 3xx redirects manually (GitHub release assets redirect to
|
|
43
|
+
// objects.githubusercontent.com) and streams the response straight to disk.
|
|
44
|
+
function download(url, destPath, redirectsLeft) {
|
|
45
|
+
if (redirectsLeft === undefined) redirectsLeft = 5;
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const request = https.get(
|
|
48
|
+
url,
|
|
49
|
+
{ headers: { 'User-Agent': 'swrm-npm-installer' } },
|
|
50
|
+
(res) => {
|
|
51
|
+
const { statusCode, headers } = res;
|
|
52
|
+
|
|
53
|
+
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
54
|
+
res.resume();
|
|
55
|
+
if (redirectsLeft <= 0) {
|
|
56
|
+
reject(new Error(`Too many redirects fetching ${url}`));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
download(headers.location, destPath, redirectsLeft - 1).then(resolve, reject);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (statusCode !== 200) {
|
|
64
|
+
res.resume();
|
|
65
|
+
reject(new Error(`Download failed with HTTP ${statusCode} for ${url}`));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const fileStream = fs.createWriteStream(destPath);
|
|
70
|
+
res.pipe(fileStream);
|
|
71
|
+
fileStream.on('finish', () => fileStream.close(() => resolve()));
|
|
72
|
+
fileStream.on('error', reject);
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
request.on('error', reject);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function main() {
|
|
80
|
+
const { os, ext, assetName } = resolveTarget();
|
|
81
|
+
const tag = `v${pkg.version}`;
|
|
82
|
+
const url = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
|
|
83
|
+
|
|
84
|
+
const distDir = path.join(__dirname, '..', 'dist');
|
|
85
|
+
fs.mkdirSync(distDir, { recursive: true });
|
|
86
|
+
const destPath = path.join(distDir, `swrm${ext}`);
|
|
87
|
+
|
|
88
|
+
console.log(`[swrm install] Downloading ${assetName} (${tag})...`);
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
await download(url, destPath);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
try {
|
|
94
|
+
fs.unlinkSync(destPath);
|
|
95
|
+
} catch (_) {
|
|
96
|
+
// nothing to clean up
|
|
97
|
+
}
|
|
98
|
+
fail(
|
|
99
|
+
`Could not download the swrm binary.\n` +
|
|
100
|
+
` URL: ${url}\n` +
|
|
101
|
+
` Reason: ${err.message}\n\n` +
|
|
102
|
+
` If this keeps happening, build from source: https://github.com/${REPO}#building-from-source`
|
|
103
|
+
);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (os !== 'windows') {
|
|
108
|
+
fs.chmodSync(destPath, 0o755);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(`[swrm install] Installed to ${destPath}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
main();
|