@shello/bin 0.1.0 → 0.2.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/shello.js +27 -5
- package/package.json +8 -14
- package/postinstall.js +0 -139
package/bin/shello.js
CHANGED
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const { execFileSync } = require('child_process')
|
|
3
|
-
const fs = require('fs')
|
|
4
3
|
const path = require('path')
|
|
5
4
|
|
|
6
|
-
const
|
|
5
|
+
const PLATFORMS = {
|
|
6
|
+
'darwin-arm64': '@shello/bin-darwin-arm64',
|
|
7
|
+
'darwin-x64': '@shello/bin-darwin-x64',
|
|
8
|
+
'linux-arm64': '@shello/bin-linux-arm64',
|
|
9
|
+
'linux-x64': '@shello/bin-linux-x64',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const platformKey = `${process.platform}-${process.arch}`
|
|
13
|
+
const pkg = PLATFORMS[platformKey]
|
|
14
|
+
|
|
15
|
+
if (!pkg) {
|
|
16
|
+
console.error(`Unsupported platform: ${platformKey}`)
|
|
17
|
+
console.error('Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64')
|
|
18
|
+
console.error('Install manually: curl -fsSL https://get.shello.to | sh')
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
7
21
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
22
|
+
let binary
|
|
23
|
+
try {
|
|
24
|
+
binary = path.join(
|
|
25
|
+
path.dirname(require.resolve(`${pkg}/package.json`)),
|
|
26
|
+
'bin',
|
|
27
|
+
'shello',
|
|
28
|
+
)
|
|
29
|
+
} catch {
|
|
30
|
+
console.error(`Platform package ${pkg} is not installed.`)
|
|
31
|
+
console.error('Try reinstalling: npm install -g @shello/bin')
|
|
32
|
+
console.error('Or install manually: curl -fsSL https://get.shello.to | sh')
|
|
11
33
|
process.exit(1)
|
|
12
34
|
}
|
|
13
35
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shello/bin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "P2P terminal access — no ports, no cloud, just connect",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,21 +21,15 @@
|
|
|
21
21
|
"shello": "./bin/shello.js"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
|
-
"bin/shello.js"
|
|
25
|
-
"postinstall.js"
|
|
26
|
-
],
|
|
27
|
-
"scripts": {
|
|
28
|
-
"postinstall": "node postinstall.js"
|
|
29
|
-
},
|
|
30
|
-
"os": [
|
|
31
|
-
"darwin",
|
|
32
|
-
"linux"
|
|
33
|
-
],
|
|
34
|
-
"cpu": [
|
|
35
|
-
"arm64",
|
|
36
|
-
"x64"
|
|
24
|
+
"bin/shello.js"
|
|
37
25
|
],
|
|
38
26
|
"engines": {
|
|
39
27
|
"node": ">=16"
|
|
28
|
+
},
|
|
29
|
+
"optionalDependencies": {
|
|
30
|
+
"@shello/bin-darwin-arm64": "0.2.0",
|
|
31
|
+
"@shello/bin-darwin-x64": "0.2.0",
|
|
32
|
+
"@shello/bin-linux-arm64": "0.2.0",
|
|
33
|
+
"@shello/bin-linux-x64": "0.2.0"
|
|
40
34
|
}
|
|
41
35
|
}
|
package/postinstall.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require('fs')
|
|
3
|
-
const path = require('path')
|
|
4
|
-
const https = require('https')
|
|
5
|
-
const crypto = require('crypto')
|
|
6
|
-
|
|
7
|
-
const REPO = 'shelloto/shello'
|
|
8
|
-
const BINARY = 'shello'
|
|
9
|
-
|
|
10
|
-
const PLATFORM_MAP = { darwin: 'darwin', linux: 'linux' }
|
|
11
|
-
const ARCH_MAP = { arm64: 'arm64', x64: 'amd64' }
|
|
12
|
-
|
|
13
|
-
const platform = PLATFORM_MAP[process.platform]
|
|
14
|
-
const arch = ARCH_MAP[process.arch]
|
|
15
|
-
|
|
16
|
-
if (process.env.SHELLO_SKIP_INSTALL) {
|
|
17
|
-
console.log('Skipping shello binary download (SHELLO_SKIP_INSTALL set)')
|
|
18
|
-
process.exit(0)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!platform || !arch) {
|
|
22
|
-
console.error(`Unsupported platform: ${process.platform}/${process.arch}`)
|
|
23
|
-
console.error('Supported: darwin/arm64, darwin/x64, linux/arm64, linux/x64')
|
|
24
|
-
process.exit(1)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const binDir = path.join(__dirname, 'bin')
|
|
28
|
-
const binPath = path.join(binDir, BINARY)
|
|
29
|
-
|
|
30
|
-
function httpsGet(url) {
|
|
31
|
-
return new Promise((resolve, reject) => {
|
|
32
|
-
https.get(url, { headers: { 'User-Agent': 'shello-npm' } }, (res) => {
|
|
33
|
-
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
34
|
-
return httpsGet(res.headers.location).then(resolve).catch(reject)
|
|
35
|
-
}
|
|
36
|
-
if (res.statusCode !== 200) {
|
|
37
|
-
return reject(new Error(`HTTP ${res.statusCode} from ${url}`))
|
|
38
|
-
}
|
|
39
|
-
resolve(res)
|
|
40
|
-
}).on('error', reject)
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function fetchJSON(url) {
|
|
45
|
-
return new Promise((resolve, reject) => {
|
|
46
|
-
httpsGet(url).then((res) => {
|
|
47
|
-
let data = ''
|
|
48
|
-
res.on('data', (chunk) => (data += chunk))
|
|
49
|
-
res.on('end', () => {
|
|
50
|
-
try {
|
|
51
|
-
resolve(JSON.parse(data))
|
|
52
|
-
} catch (e) {
|
|
53
|
-
reject(new Error(`Failed to parse JSON from ${url}: ${e.message}`))
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
}).catch(reject)
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function fetchText(url) {
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
httpsGet(url).then((res) => {
|
|
63
|
-
let data = ''
|
|
64
|
-
res.on('data', (chunk) => (data += chunk))
|
|
65
|
-
res.on('end', () => resolve(data))
|
|
66
|
-
}).catch(reject)
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function download(url, dest) {
|
|
71
|
-
return new Promise((resolve, reject) => {
|
|
72
|
-
httpsGet(url).then((res) => {
|
|
73
|
-
const file = fs.createWriteStream(dest)
|
|
74
|
-
res.pipe(file)
|
|
75
|
-
file.on('finish', () => {
|
|
76
|
-
file.close()
|
|
77
|
-
resolve()
|
|
78
|
-
})
|
|
79
|
-
file.on('error', (err) => {
|
|
80
|
-
fs.unlink(dest, () => {})
|
|
81
|
-
reject(err)
|
|
82
|
-
})
|
|
83
|
-
}).catch(reject)
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async function main() {
|
|
88
|
-
const release = await fetchJSON(
|
|
89
|
-
`https://api.github.com/repos/${REPO}/releases/latest`
|
|
90
|
-
)
|
|
91
|
-
const tag = release.tag_name
|
|
92
|
-
if (!tag) {
|
|
93
|
-
throw new Error('No releases found. Install manually: https://say.shello.to')
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const binaryName = `${BINARY}-${platform}-${arch}`
|
|
97
|
-
const binaryURL = `https://github.com/${REPO}/releases/download/${tag}/${binaryName}`
|
|
98
|
-
|
|
99
|
-
console.log(`Downloading ${BINARY} ${tag} (${platform}/${arch})...`)
|
|
100
|
-
|
|
101
|
-
fs.mkdirSync(binDir, { recursive: true })
|
|
102
|
-
await download(binaryURL, binPath)
|
|
103
|
-
fs.chmodSync(binPath, 0o755)
|
|
104
|
-
|
|
105
|
-
// Verify checksum if available
|
|
106
|
-
try {
|
|
107
|
-
const checksums = await fetchText(
|
|
108
|
-
`https://github.com/${REPO}/releases/download/${tag}/checksums.txt`
|
|
109
|
-
)
|
|
110
|
-
const expected = checksums
|
|
111
|
-
.split('\n')
|
|
112
|
-
.find((line) => line.includes(binaryName))
|
|
113
|
-
if (expected) {
|
|
114
|
-
const hash = crypto
|
|
115
|
-
.createHash('sha256')
|
|
116
|
-
.update(fs.readFileSync(binPath))
|
|
117
|
-
.digest('hex')
|
|
118
|
-
const expectedHash = expected.split(/\s+/)[0]
|
|
119
|
-
if (hash !== expectedHash) {
|
|
120
|
-
fs.unlinkSync(binPath)
|
|
121
|
-
throw new Error(
|
|
122
|
-
`Checksum mismatch: expected ${expectedHash}, got ${hash}`
|
|
123
|
-
)
|
|
124
|
-
}
|
|
125
|
-
console.log('Checksum verified.')
|
|
126
|
-
}
|
|
127
|
-
} catch (e) {
|
|
128
|
-
if (e.message.includes('Checksum mismatch')) throw e
|
|
129
|
-
// Checksums file not available — that's OK
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
console.log(`Installed ${BINARY} ${tag} to ${binPath}`)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
main().catch((err) => {
|
|
136
|
-
console.error(`Failed to install shello: ${err.message}`)
|
|
137
|
-
console.error('You can install manually: curl -fsSL https://get.shello.to | sh')
|
|
138
|
-
process.exit(1)
|
|
139
|
-
})
|