@seyuna/cli 0.0.2-dev.10 → 0.0.2-dev.13
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/seyuna +32 -0
- package/index.js +32 -0
- package/install.js +123 -0
- package/package.json +9 -3
- package/node-install.js +0 -60
package/bin/seyuna
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const childProcess = require("child_process");
|
|
5
|
+
|
|
6
|
+
// Lookup table for all platforms and binary distribution packages
|
|
7
|
+
const BINARY_DISTRIBUTION_PACKAGES = {
|
|
8
|
+
darwin: "@seyuna/cli-darwin",
|
|
9
|
+
linux: "@seyuna/cli-linux",
|
|
10
|
+
freebsd: "@seyuna/cli-linux",
|
|
11
|
+
win32: "@seyuna/cli-win32",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Windows binaries end with .exe so we need to special case them.
|
|
15
|
+
const binaryName = process.platform === "win32" ? "seyuna.exe" : "seyuna";
|
|
16
|
+
|
|
17
|
+
// Determine package name for this platform
|
|
18
|
+
const platformSpecificPackageName =
|
|
19
|
+
BINARY_DISTRIBUTION_PACKAGES[process.platform];
|
|
20
|
+
|
|
21
|
+
function getBinaryPath() {
|
|
22
|
+
try {
|
|
23
|
+
// Resolving will fail if the optionalDependency was not installed
|
|
24
|
+
return require.resolve(`${platformSpecificPackageName}/bin/${binaryName}`);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
return path.join(__dirname, "..", binaryName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
childProcess.execFileSync(getBinaryPath(), process.argv.slice(2), {
|
|
31
|
+
stdio: "inherit",
|
|
32
|
+
});
|
package/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const childProcess = require("child_process");
|
|
3
|
+
|
|
4
|
+
// Lookup table for all platforms and binary distribution packages
|
|
5
|
+
const BINARY_DISTRIBUTION_PACKAGES = {
|
|
6
|
+
darwin: "@seyuna/cli-darwin",
|
|
7
|
+
linux: "@seyuna/cli-linux",
|
|
8
|
+
freebsd: "@seyuna/cli-linux",
|
|
9
|
+
win32: "@seyuna/cli-win32",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Windows binaries end with .exe so we need to special case them.
|
|
13
|
+
const binaryName = process.platform === "win32" ? "seyuna.exe" : "seyuna";
|
|
14
|
+
|
|
15
|
+
// Determine package name for this platform
|
|
16
|
+
const platformSpecificPackageName =
|
|
17
|
+
BINARY_DISTRIBUTION_PACKAGES[process.platform];
|
|
18
|
+
|
|
19
|
+
function getBinaryPath() {
|
|
20
|
+
try {
|
|
21
|
+
// Resolving will fail if the optionalDependency was not installed
|
|
22
|
+
return require.resolve(`${platformSpecificPackageName}/bin/${binaryName}`);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return path.join(__dirname, "..", binaryName);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports.runBinary = function (...args) {
|
|
29
|
+
childProcess.execFileSync(getBinaryPath(), args, {
|
|
30
|
+
stdio: "inherit",
|
|
31
|
+
});
|
|
32
|
+
};
|
package/install.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const zlib = require("zlib");
|
|
4
|
+
const https = require("https");
|
|
5
|
+
|
|
6
|
+
// Lookup table for all platforms and binary distribution packages
|
|
7
|
+
const BINARY_DISTRIBUTION_PACKAGES = {
|
|
8
|
+
darwin: "@seyuna/cli-darwin",
|
|
9
|
+
linux: "@seyuna/cli-linux",
|
|
10
|
+
freebsd: "@seyuna/cli-linux",
|
|
11
|
+
win32: "@seyuna/cli-win32",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Adjust the version you want to install.
|
|
15
|
+
const BINARY_DISTRIBUTION_VERSION = "0.0.2-dev.13";
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// Windows binaries end with .exe so we need to special case them.
|
|
19
|
+
const binaryName = process.platform === "win32" ? "seyuna.exe" : "seyuna";
|
|
20
|
+
|
|
21
|
+
// Determine package name for this platform
|
|
22
|
+
const platformSpecificPackageName =
|
|
23
|
+
BINARY_DISTRIBUTION_PACKAGES[process.platform];
|
|
24
|
+
|
|
25
|
+
// Compute the path we want to emit the fallback binary to
|
|
26
|
+
const fallbackBinaryPath = path.join(__dirname, binaryName);
|
|
27
|
+
|
|
28
|
+
function makeRequest(url) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
https
|
|
31
|
+
.get(url, (response) => {
|
|
32
|
+
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
33
|
+
const chunks = [];
|
|
34
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
35
|
+
response.on("end", () => {
|
|
36
|
+
resolve(Buffer.concat(chunks));
|
|
37
|
+
});
|
|
38
|
+
} else if (
|
|
39
|
+
response.statusCode >= 300 &&
|
|
40
|
+
response.statusCode < 400 &&
|
|
41
|
+
response.headers.location
|
|
42
|
+
) {
|
|
43
|
+
// Follow redirects
|
|
44
|
+
makeRequest(response.headers.location).then(resolve, reject);
|
|
45
|
+
} else {
|
|
46
|
+
reject(
|
|
47
|
+
new Error(
|
|
48
|
+
`npm responded with status code ${response.statusCode} when downloading the package!`
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
.on("error", (error) => {
|
|
54
|
+
reject(error);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function extractFileFromTarball(tarballBuffer, filepath) {
|
|
60
|
+
// Tar archives are organized in 512 byte blocks.
|
|
61
|
+
// Blocks can either be header blocks or data blocks.
|
|
62
|
+
// Header blocks contain file names of the archive in the first 100 bytes, terminated by a null byte.
|
|
63
|
+
// The size of a file is contained in bytes 124-135 of a header block.
|
|
64
|
+
// The following blocks will be data blocks containing the file.
|
|
65
|
+
let offset = 0;
|
|
66
|
+
while (offset < tarballBuffer.length) {
|
|
67
|
+
const header = tarballBuffer.subarray(offset, offset + 512);
|
|
68
|
+
offset += 512;
|
|
69
|
+
|
|
70
|
+
const fileName = header.toString("utf-8", 0, 100).replace(/\0.*/g, "");
|
|
71
|
+
const fileSize = parseInt(
|
|
72
|
+
header.toString("utf-8", 124, 136).replace(/\0.*/g, ""),
|
|
73
|
+
8
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (fileName === filepath) {
|
|
77
|
+
return tarballBuffer.subarray(offset, offset + fileSize);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Clamp offset to the uppoer multiple of 512
|
|
81
|
+
offset = (offset + fileSize + 511) & ~511;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function downloadBinaryFromNpm() {
|
|
86
|
+
// Download the tarball of the right binary distribution package
|
|
87
|
+
const tarballDownloadBuffer = await makeRequest(
|
|
88
|
+
`https://registry.npmjs.org/@seyuna/cli/-/${platformSpecificPackageName}-${BINARY_DISTRIBUTION_VERSION}.tgz`
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const tarballBuffer = zlib.unzipSync(tarballDownloadBuffer);
|
|
92
|
+
|
|
93
|
+
// Extract binary from package and write to disk
|
|
94
|
+
fs.writeFileSync(
|
|
95
|
+
fallbackBinaryPath,
|
|
96
|
+
extractFileFromTarball(tarballBuffer, `package/bin/${binaryName}`)
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Make binary executable
|
|
100
|
+
fs.chmodSync(fallbackBinaryPath, "755");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isPlatformSpecificPackageInstalled() {
|
|
104
|
+
try {
|
|
105
|
+
// Resolving will fail if the optionalDependency was not installed
|
|
106
|
+
require.resolve(`${platformSpecificPackageName}/bin/${binaryName}`);
|
|
107
|
+
return true;
|
|
108
|
+
} catch (e) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Skip downloading the binary if it was already installed via optionalDependencies
|
|
114
|
+
if (!isPlatformSpecificPackageInstalled()) {
|
|
115
|
+
console.log(
|
|
116
|
+
"Platform specific package not found. Will manually download binary."
|
|
117
|
+
);
|
|
118
|
+
downloadBinaryFromNpm();
|
|
119
|
+
} else {
|
|
120
|
+
console.log(
|
|
121
|
+
"Platform specific package already installed. Will fall back to manually downloading binary."
|
|
122
|
+
);
|
|
123
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seyuna/cli",
|
|
3
|
-
"version": "0.0.2-dev.
|
|
3
|
+
"version": "0.0.2-dev.13",
|
|
4
|
+
"main": "./index.js",
|
|
4
5
|
"bin": {
|
|
5
6
|
"seyuna": "./bin/seyuna"
|
|
6
7
|
},
|
|
7
8
|
"scripts": {
|
|
8
|
-
"postinstall": "node
|
|
9
|
+
"postinstall": "node ./install.js"
|
|
9
10
|
},
|
|
10
11
|
"description": "Seyuna CLI",
|
|
11
12
|
"author": "Seyuna",
|
|
12
13
|
"license": "MIT",
|
|
13
14
|
"engines": {
|
|
14
15
|
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"optionalDependencies": {
|
|
18
|
+
"@seyuna/cli-darwin": "0.0.2-dev.13",
|
|
19
|
+
"@seyuna/cli-linux": "0.0.2-dev.13",
|
|
20
|
+
"@seyuna/cli-win32": "0.0.2-dev.13"
|
|
15
21
|
}
|
|
16
|
-
}
|
|
22
|
+
}
|
package/node-install.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { mkdir, chmod, readFile } from "fs/promises";
|
|
2
|
-
import { createWriteStream } from "fs";
|
|
3
|
-
import { Readable } from "stream";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
import process from "process";
|
|
7
|
-
|
|
8
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const version = "0.0.2-dev.10";
|
|
10
|
-
|
|
11
|
-
async function downloadFile(url, dest) {
|
|
12
|
-
const res = await fetch(url);
|
|
13
|
-
if (!res.ok) {
|
|
14
|
-
throw new Error(`Failed to download ${url}: ${res.status} ${res.statusText}`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
await mkdir(path.dirname(dest), { recursive: true });
|
|
18
|
-
|
|
19
|
-
const readable = Readable.fromWeb(res.body);
|
|
20
|
-
const fileStream = createWriteStream(dest);
|
|
21
|
-
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
readable.pipe(fileStream);
|
|
24
|
-
readable.on("error", reject);
|
|
25
|
-
fileStream.on("finish", resolve);
|
|
26
|
-
fileStream.on("error", reject);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function main() {
|
|
31
|
-
|
|
32
|
-
const platform = process.platform;
|
|
33
|
-
let target;
|
|
34
|
-
if (platform === "win32") {
|
|
35
|
-
target = "seyuna-windows.exe";
|
|
36
|
-
} else if (platform === "darwin") {
|
|
37
|
-
target = "seyuna-macos";
|
|
38
|
-
} else if (platform === "linux") {
|
|
39
|
-
target = "seyuna-linux";
|
|
40
|
-
} else {
|
|
41
|
-
console.error(`Unsupported platform: ${platform}`);
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const releaseUrl = `https://github.com/seyuna-corp/seyuna-cli/releases/download/v${version}/${target}`;
|
|
46
|
-
const dest = path.join(__dirname, "bin", platform === "win32" ? "seyuna.exe" : "seyuna");
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
await downloadFile(releaseUrl, dest);
|
|
50
|
-
if (platform !== "win32") {
|
|
51
|
-
await chmod(dest, 0o755);
|
|
52
|
-
}
|
|
53
|
-
console.log(`seyuna CLI v${version} installed to ${dest}`);
|
|
54
|
-
} catch (err) {
|
|
55
|
-
console.error(err);
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
main();
|