@taleshape/shaper 0.1.1 → 0.1.2
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/shaper +8 -0
- package/install.js +73 -18
- package/package.json +4 -2
- package/shaper.js +0 -20
package/bin/shaper
ADDED
package/install.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const os = require('os');
|
|
4
|
+
const crypto = require('crypto');
|
|
4
5
|
const axios = require('axios');
|
|
5
6
|
|
|
6
7
|
const BIN_DIR = path.join(__dirname, 'bin');
|
|
@@ -30,11 +31,9 @@ async function getRelease(version) {
|
|
|
30
31
|
return response.data;
|
|
31
32
|
} catch (error) {
|
|
32
33
|
if (error.response?.status === 404) {
|
|
33
|
-
|
|
34
|
-
} else {
|
|
35
|
-
console.error('Error fetching release:', error.message);
|
|
34
|
+
throw new Error(`Version v${version} not found. Please check if this version exists in the releases.`);
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
throw new Error(`Error fetching release: ${error.message}`);
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -42,7 +41,9 @@ async function downloadFile(url, dest) {
|
|
|
42
41
|
const response = await axios({
|
|
43
42
|
method: 'GET',
|
|
44
43
|
url: url,
|
|
45
|
-
responseType: 'stream'
|
|
44
|
+
responseType: 'stream',
|
|
45
|
+
maxContentLength: 100 * 1024 * 1024, // 100MB max
|
|
46
|
+
validateStatus: status => status === 200
|
|
46
47
|
});
|
|
47
48
|
|
|
48
49
|
const writer = fs.createWriteStream(dest);
|
|
@@ -51,40 +52,94 @@ async function downloadFile(url, dest) {
|
|
|
51
52
|
return new Promise((resolve, reject) => {
|
|
52
53
|
writer.on('finish', resolve);
|
|
53
54
|
writer.on('error', reject);
|
|
55
|
+
response.data.on('error', reject);
|
|
54
56
|
});
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
fs.
|
|
61
|
-
|
|
59
|
+
function calculateSHA256(filePath) {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const hash = crypto.createHash('sha256');
|
|
62
|
+
const stream = fs.createReadStream(filePath);
|
|
63
|
+
|
|
64
|
+
stream.on('error', err => reject(err));
|
|
65
|
+
stream.on('data', chunk => hash.update(chunk));
|
|
66
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
67
|
+
});
|
|
68
|
+
}
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
const
|
|
70
|
+
async function verifyChecksum(filePath, expectedChecksum) {
|
|
71
|
+
const actualChecksum = await calculateSHA256(filePath);
|
|
72
|
+
if (actualChecksum !== expectedChecksum) {
|
|
73
|
+
throw new Error(`Checksum verification failed for ${path.basename(filePath)}\nExpected: ${expectedChecksum}\nActual: ${actualChecksum}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
function loadChecksums() {
|
|
78
|
+
const checksumsPath = path.join(__dirname, 'bin', 'SHA256SUMS');
|
|
79
|
+
if (!fs.existsSync(checksumsPath)) {
|
|
80
|
+
throw new Error('SHA256SUMS file not found in package');
|
|
69
81
|
}
|
|
70
82
|
|
|
83
|
+
const checksumsContent = fs.readFileSync(checksumsPath, 'utf8');
|
|
84
|
+
const checksums = {};
|
|
85
|
+
checksumsContent.split('\n').forEach(line => {
|
|
86
|
+
if (line.trim()) {
|
|
87
|
+
const [checksum, filename] = line.split(/\s+/);
|
|
88
|
+
checksums[filename] = checksum;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return checksums;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function main() {
|
|
71
96
|
try {
|
|
97
|
+
// Create bin directory if it doesn't exist
|
|
98
|
+
if (!fs.existsSync(BIN_DIR)) {
|
|
99
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const platform = `${process.platform}-${process.arch}`;
|
|
103
|
+
const assetName = PLATFORM_MAP[platform];
|
|
104
|
+
|
|
105
|
+
if (!assetName) {
|
|
106
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Load checksums from the package
|
|
110
|
+
console.log('Loading checksums...');
|
|
111
|
+
const checksums = loadChecksums();
|
|
112
|
+
const expectedChecksum = checksums[assetName];
|
|
113
|
+
|
|
114
|
+
if (!expectedChecksum) {
|
|
115
|
+
throw new Error(`No checksum found for ${assetName} in SHA256SUMS`);
|
|
116
|
+
}
|
|
117
|
+
|
|
72
118
|
const release = await getRelease(VERSION);
|
|
73
119
|
const asset = release.assets.find(a => a.name === assetName);
|
|
74
120
|
|
|
75
121
|
if (!asset) {
|
|
76
|
-
|
|
77
|
-
process.exit(1);
|
|
122
|
+
throw new Error(`Asset not found for platform ${platform} in version v${VERSION}`);
|
|
78
123
|
}
|
|
79
124
|
|
|
80
125
|
console.log(`Downloading shaper v${VERSION} for ${platform}...`);
|
|
81
126
|
const binaryPath = path.join(BIN_DIR, 'shaper');
|
|
82
127
|
await downloadFile(asset.browser_download_url, binaryPath);
|
|
128
|
+
|
|
129
|
+
// Verify checksum
|
|
130
|
+
console.log('Verifying checksum...');
|
|
131
|
+
await verifyChecksum(binaryPath, expectedChecksum);
|
|
132
|
+
console.log('Checksum verified successfully');
|
|
133
|
+
|
|
134
|
+
// Set executable permissions
|
|
83
135
|
fs.chmodSync(binaryPath, '755');
|
|
84
136
|
|
|
85
137
|
console.log('Installation complete!');
|
|
86
138
|
} catch (error) {
|
|
87
|
-
console.error('Installation failed:', error);
|
|
139
|
+
console.error('Installation failed:', error.message);
|
|
140
|
+
// Clean up binary if verification failed
|
|
141
|
+
const binaryPath = path.join(BIN_DIR, 'shaper');
|
|
142
|
+
if (fs.existsSync(binaryPath)) fs.unlinkSync(binaryPath);
|
|
88
143
|
process.exit(1);
|
|
89
144
|
}
|
|
90
145
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taleshape/shaper",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Minimal Embedded Analytics and Data Platform",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"shaper": "./shaper
|
|
7
|
+
"shaper": "./bin/shaper"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"postinstall": "node install.js",
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"bin",
|
|
15
|
+
"bin/SHA256SUMS",
|
|
16
|
+
"shaper.js",
|
|
15
17
|
"index.js",
|
|
16
18
|
"install.js",
|
|
17
19
|
"uninstall.js"
|
package/shaper.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const { spawn } = require('child_process');
|
|
5
|
-
|
|
6
|
-
const binaryPath = path.join(__dirname, 'bin', 'shaper');
|
|
7
|
-
|
|
8
|
-
// Forward all arguments to the binary
|
|
9
|
-
const args = process.argv.slice(2);
|
|
10
|
-
|
|
11
|
-
// Spawn the binary with the forwarded arguments
|
|
12
|
-
const child = spawn(binaryPath, args, {
|
|
13
|
-
stdio: 'inherit',
|
|
14
|
-
shell: false
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Forward the exit code
|
|
18
|
-
child.on('exit', (code) => {
|
|
19
|
-
process.exit(code);
|
|
20
|
-
});
|