@rfabric/cli 0.0.6 → 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/rfabric.js CHANGED
@@ -8,19 +8,21 @@ const binaryName = process.platform === "win32" ? "rfabric.exe" : "rfabric";
8
8
  const binaryPath = path.join(__dirname, "..", "vendor", binaryName);
9
9
 
10
10
  const child = spawn(binaryPath, process.argv.slice(2), {
11
- stdio: "inherit",
12
- windowsHide: true,
11
+ stdio: "inherit",
12
+ windowsHide: true,
13
13
  });
14
14
 
15
15
  child.on("exit", (code, signal) => {
16
- if (signal) {
17
- process.kill(process.pid, signal);
18
- return;
19
- }
20
- process.exit(code ?? 1);
16
+ if (signal) {
17
+ process.kill(process.pid, signal);
18
+ return;
19
+ }
20
+ process.exit(code ?? 1);
21
21
  });
22
22
 
23
23
  child.on("error", (error) => {
24
- process.stderr.write(`[rfabric] failed to launch ${binaryPath}: ${error.message}\n`);
25
- process.exit(1);
24
+ process.stderr.write(
25
+ `[rfabric] failed to launch ${binaryPath}: ${error.message}\n`,
26
+ );
27
+ process.exit(1);
26
28
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rfabric/cli",
3
- "version": "0.0.6",
3
+ "version": "0.1.2",
4
4
  "description": "rFabric CLI — terminal-native interface to the rFabric robotics lifecycle platform",
5
5
  "homepage": "https://rfabric.io",
6
6
  "repository": {
@@ -18,7 +18,7 @@ const platform = platformMap[process.platform];
18
18
  const arch = archMap[process.arch];
19
19
 
20
20
  if (!platform || !arch) {
21
- fail(`unsupported platform: ${process.platform}/${process.arch}`);
21
+ fail(`unsupported platform: ${process.platform}/${process.arch}`);
22
22
  }
23
23
 
24
24
  const isWindows = platform === "windows";
@@ -33,102 +33,129 @@ const binaryPath = path.join(vendorDir, binaryName);
33
33
  main().catch((error) => fail(error.message || String(error)));
34
34
 
35
35
  async function main() {
36
- if (fs.existsSync(binaryPath)) {
37
- return;
38
- }
39
-
40
- fs.mkdirSync(vendorDir, { recursive: true });
41
-
42
- log(`downloading ${archiveName}`);
43
- const archiveBuffer = await downloadToBuffer(`${baseUrl}/${archiveName}`);
44
-
45
- log("verifying checksum");
46
- const checksumsText = (await downloadToBuffer(`${baseUrl}/checksums.txt`)).toString("utf8");
47
- const expectedChecksum = parseChecksum(checksumsText, archiveName);
48
- const actualChecksum = crypto.createHash("sha256").update(archiveBuffer).digest("hex");
49
- if (expectedChecksum !== actualChecksum) {
50
- fail(`checksum mismatch (expected ${expectedChecksum}, got ${actualChecksum})`);
51
- }
52
-
53
- log("extracting");
54
- if (isWindows) {
55
- extractZip(archiveBuffer, vendorDir);
56
- } else {
57
- await extractTarGz(archiveBuffer, vendorDir);
58
- }
59
-
60
- if (!fs.existsSync(binaryPath)) {
61
- fail(`binary ${binaryName} not found in archive`);
62
- }
63
-
64
- if (!isWindows) {
65
- fs.chmodSync(binaryPath, 0o755);
66
- }
67
-
68
- log(`installed to ${binaryPath}`);
36
+ if (fs.existsSync(binaryPath)) {
37
+ return;
38
+ }
39
+
40
+ fs.mkdirSync(vendorDir, { recursive: true });
41
+
42
+ log(`downloading ${archiveName}`);
43
+ const archiveBuffer = await downloadToBuffer(`${baseUrl}/${archiveName}`);
44
+
45
+ log("verifying checksum");
46
+ const checksumsText = (
47
+ await downloadToBuffer(`${baseUrl}/checksums.txt`)
48
+ ).toString("utf8");
49
+ const expectedChecksum = parseChecksum(checksumsText, archiveName);
50
+ const actualChecksum = crypto
51
+ .createHash("sha256")
52
+ .update(archiveBuffer)
53
+ .digest("hex");
54
+ if (expectedChecksum !== actualChecksum) {
55
+ fail(
56
+ `checksum mismatch (expected ${expectedChecksum}, got ${actualChecksum})`,
57
+ );
58
+ }
59
+
60
+ log("extracting");
61
+ if (isWindows) {
62
+ extractZip(archiveBuffer, vendorDir);
63
+ } else {
64
+ await extractTarGz(archiveBuffer, vendorDir);
65
+ }
66
+
67
+ if (!fs.existsSync(binaryPath)) {
68
+ fail(`binary ${binaryName} not found in archive`);
69
+ }
70
+
71
+ if (!isWindows) {
72
+ fs.chmodSync(binaryPath, 0o755);
73
+ }
74
+
75
+ log(`installed to ${binaryPath}`);
69
76
  }
70
77
 
71
78
  function downloadToBuffer(url, redirects = 0) {
72
- return new Promise((resolve, reject) => {
73
- if (redirects > 5) {
74
- return reject(new Error(`too many redirects fetching ${url}`));
75
- }
76
- https
77
- .get(url, { headers: { "User-Agent": "rfabric-npm-postinstall" } }, (response) => {
78
- if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 307) {
79
- return resolve(downloadToBuffer(response.headers.location, redirects + 1));
80
- }
81
- if (response.statusCode !== 200) {
82
- return reject(new Error(`HTTP ${response.statusCode} fetching ${url}`));
83
- }
84
- const chunks = [];
85
- response.on("data", (chunk) => chunks.push(chunk));
86
- response.on("end", () => resolve(Buffer.concat(chunks)));
87
- response.on("error", reject);
88
- })
89
- .on("error", reject);
90
- });
79
+ return new Promise((resolve, reject) => {
80
+ if (redirects > 5) {
81
+ return reject(new Error(`too many redirects fetching ${url}`));
82
+ }
83
+ https
84
+ .get(
85
+ url,
86
+ { headers: { "User-Agent": "rfabric-npm-postinstall" } },
87
+ (response) => {
88
+ if (
89
+ response.statusCode === 301 ||
90
+ response.statusCode === 302 ||
91
+ response.statusCode === 307
92
+ ) {
93
+ return resolve(
94
+ downloadToBuffer(response.headers.location, redirects + 1),
95
+ );
96
+ }
97
+ if (response.statusCode !== 200) {
98
+ return reject(
99
+ new Error(`HTTP ${response.statusCode} fetching ${url}`),
100
+ );
101
+ }
102
+ const chunks = [];
103
+ response.on("data", (chunk) => chunks.push(chunk));
104
+ response.on("end", () => resolve(Buffer.concat(chunks)));
105
+ response.on("error", reject);
106
+ },
107
+ )
108
+ .on("error", reject);
109
+ });
91
110
  }
92
111
 
93
112
  function parseChecksum(checksumsText, fileName) {
94
- for (const line of checksumsText.split(/\r?\n/)) {
95
- const match = line.match(/^([a-fA-F0-9]+)\s+(\S+)$/);
96
- if (match && match[2] === fileName) {
97
- return match[1];
98
- }
113
+ for (const line of checksumsText.split(/\r?\n/)) {
114
+ const match = line.match(/^([a-fA-F0-9]+)\s+(\S+)$/);
115
+ if (match && match[2] === fileName) {
116
+ return match[1];
99
117
  }
100
- fail(`no checksum entry for ${fileName}`);
118
+ }
119
+ fail(`no checksum entry for ${fileName}`);
101
120
  }
102
121
 
103
122
  async function extractTarGz(buffer, targetDir) {
104
- const result = spawnSync("tar", ["-xzf", "-", "-C", targetDir], { input: buffer });
105
- if (result.status !== 0) {
106
- fail(`tar extraction failed: ${result.stderr?.toString() || "unknown error"}`);
107
- }
123
+ const result = spawnSync("tar", ["-xzf", "-", "-C", targetDir], {
124
+ input: buffer,
125
+ });
126
+ if (result.status !== 0) {
127
+ fail(
128
+ `tar extraction failed: ${result.stderr?.toString() || "unknown error"}`,
129
+ );
130
+ }
108
131
  }
109
132
 
110
133
  function extractZip(buffer, targetDir) {
111
- const tmp = path.join(targetDir, `__archive__.zip`);
112
- fs.writeFileSync(tmp, buffer);
113
- try {
114
- const result = spawnSync(
115
- "powershell",
116
- ["-NoProfile", "-Command", `Expand-Archive -Force -Path "${tmp}" -DestinationPath "${targetDir}"`],
117
- { stdio: "inherit" }
118
- );
119
- if (result.status !== 0) {
120
- fail("zip extraction failed");
121
- }
122
- } finally {
123
- fs.unlinkSync(tmp);
134
+ const tmp = path.join(targetDir, `__archive__.zip`);
135
+ fs.writeFileSync(tmp, buffer);
136
+ try {
137
+ const result = spawnSync(
138
+ "powershell",
139
+ [
140
+ "-NoProfile",
141
+ "-Command",
142
+ `Expand-Archive -Force -Path "${tmp}" -DestinationPath "${targetDir}"`,
143
+ ],
144
+ { stdio: "inherit" },
145
+ );
146
+ if (result.status !== 0) {
147
+ fail("zip extraction failed");
124
148
  }
149
+ } finally {
150
+ fs.unlinkSync(tmp);
151
+ }
125
152
  }
126
153
 
127
154
  function log(message) {
128
- process.stdout.write(`[rfabric] ${message}\n`);
155
+ process.stdout.write(`[rfabric] ${message}\n`);
129
156
  }
130
157
 
131
158
  function fail(message) {
132
- process.stderr.write(`[rfabric] error: ${message}\n`);
133
- process.exit(1);
159
+ process.stderr.write(`[rfabric] error: ${message}\n`);
160
+ process.exit(1);
134
161
  }