@ahqstore/cli 0.7.0 → 0.10.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/Cargo.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  edition = "2021"
3
3
  name = "ahqstore_cli_rs"
4
- version = "0.7.0"
4
+ version = "0.10.0"
5
5
  description = "AHQ Store CLI"
6
6
  repository = "https://github.com/ahqstore/cli"
7
7
  homepage = "https://github.com/ahqstore/cli"
@@ -22,11 +22,6 @@ pkg-url = "{ repo }/releases/download/{ version }/{ name }-{ target }.zip"
22
22
  pkg-fmt = "zip"
23
23
 
24
24
  [dependencies]
25
- # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
26
- napi = { version = "2", default-features = false, features = [
27
- "napi4",
28
- ], optional = true }
29
- napi-derive = { version = "2", optional = true }
30
25
  inquire = { version = "0", features = ["editor"] }
31
26
  chalk_rs = "1"
32
27
  lazy_static = "1"
@@ -39,17 +34,11 @@ image = { version = "0.25", default-features = false, features = [
39
34
  "rayon",
40
35
  "png",
41
36
  ] }
42
- rand = "0.8"
37
+ rand = "0.9"
43
38
 
44
39
  [target.'cfg(unix)'.dependencies]
45
40
  openssl-sys = { version = "0.9", features = ["vendored"] }
46
41
 
47
- [build-dependencies]
48
- napi-build = { version = "2", optional = true }
49
-
50
42
  [profile.release]
51
43
  lto = true
52
44
  strip = "symbols"
53
-
54
- [features]
55
- node = ["dep:napi", "dep:napi-build", "dep:napi-derive"]
package/build.rs CHANGED
@@ -1,8 +1,4 @@
1
- #[cfg(feature = "node")]
2
- extern crate napi_build;
3
-
1
+ // Checking for targets
4
2
  fn main() {
5
- // Ensures that users can download it too
6
- #[cfg(feature = "node")]
7
- napi_build::setup();
8
- }
3
+
4
+ }
package/bundle.ps1 CHANGED
@@ -1,4 +1,13 @@
1
1
  mkdir dist
2
- cp ./target/release/ahqstore.exe ./dist/ahqstore.exe
3
- cp ./target/release/ahqstore.exe ./dist/ahqstore_cli_rs.exe
4
- compress-archive ./dist/* ./ahqstore_cli_rs-$env:TARGET
2
+
3
+ Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore.exe" -ErrorAction Continue
4
+ Copy-Item "./target/$env:TARGET/release/ahqstore.exe" "./dist/ahqstore_cli_rs.exe" -ErrorAction Continue
5
+
6
+ Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore" -ErrorAction Continue
7
+ Copy-Item "./target/$env:TARGET/release/ahqstore" "./dist/ahqstore_cli_rs" -ErrorAction Continue
8
+
9
+ compress-archive ./dist/* ./ahqstore_cli_rs-$env:TARGET
10
+
11
+ Copy-Item "./target/$env:TARGET/release/ahqstore_cli_rs.dll" "./ahqstore_cli_rs-$env:TARGET.dll" -ErrorAction Continue
12
+ Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.so" "./libahqstore_cli_rs-$env:TARGET.so" -ErrorAction Continue
13
+ Copy-Item "./target/$env:TARGET/release/libahqstore_cli_rs.dylib" "./libahqstore_cli_rs-$env:TARGET.dylib" -ErrorAction Continue
package/js/cli.js ADDED
@@ -0,0 +1,99 @@
1
+ #! /usr/bin/env node
2
+ // @ts-check
3
+
4
+ import { existsSync, mkdirSync, rmSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { argv, env, platform } from "node:process";
7
+
8
+ import { downloadModuleWithProgress } from "./download.js";
9
+
10
+ import c from "ansi-colors";
11
+
12
+ import koffi from "koffi";
13
+
14
+ import pkg from "../package.json" with { type: "json" };
15
+
16
+ export function getPrefixSuffix() {
17
+ let prefix = "";
18
+ let suffix = "";
19
+
20
+ switch (platform) {
21
+ case "win32":
22
+ suffix = ".dll";
23
+ break;
24
+ case "darwin":
25
+ prefix = "lib";
26
+ suffix = ".dylib";
27
+ break;
28
+ case "linux":
29
+ prefix = "lib";
30
+ suffix = ".so";
31
+ break;
32
+ default:
33
+ prefix = "lib";
34
+ suffix = ".so";
35
+ console.warn(c.yellow("We're guessing a UNIX compatible system."));
36
+ }
37
+
38
+ return { prefix, suffix };
39
+ }
40
+
41
+ /**
42
+ * @param {string} name
43
+ */
44
+ function getLibraryFilename(name) {
45
+ const { prefix, suffix } = getPrefixSuffix();
46
+
47
+ return `${prefix}${name}${suffix}`;
48
+ }
49
+
50
+ console.log(import.meta.dirname);
51
+
52
+ const dylibDir = join(import.meta.dirname, "lib");
53
+
54
+ if (!existsSync(dylibDir)) {
55
+ console.warn(
56
+ c.red.redBright(
57
+ "Binary not found, downloading AHQ Store CLI Binary for this version",
58
+ ),
59
+ );
60
+
61
+ mkdirSync(dylibDir);
62
+ }
63
+
64
+ const dylib = join(dylibDir, getLibraryFilename("ahqstore_cli_rs"));
65
+
66
+ let dlib = koffi.load(dylib);
67
+
68
+ const ver = dlib.func("get_ver", "str", []);
69
+
70
+ /**
71
+ * Note that we've leaked some memory here
72
+ * @type {string}
73
+ */
74
+ const output = ver();
75
+
76
+ if (output != pkg.version) {
77
+ console.warn(c.red.yellowBright("We need to update binaries..."));
78
+
79
+ // Unload current one
80
+ dlib.unload();
81
+
82
+ rmSync(dylib);
83
+
84
+ /// Download
85
+ // TODO: Load newer
86
+
87
+ // Load newer
88
+ dlib = koffi.load(dylib);
89
+ }
90
+
91
+ dlib.func("init_args", "void", [])();
92
+
93
+ const pushArg = dlib.func("add_arg", "void", ["str"]);
94
+
95
+ argv.slice(2).forEach((a) => {
96
+ pushArg(a);
97
+ });
98
+
99
+ dlib.func("node_entrypoint", "void", ["bool"])(env["CI"] == "true");
package/js/download.js ADDED
@@ -0,0 +1,29 @@
1
+ // @ts-check
2
+
3
+ import { SingleBar } from "cli-progress";
4
+ import c from "ansi-colors";
5
+
6
+ import pkg from "../package.json" with { type: "json" };
7
+ import { getPrefixSuffix } from "./cli.js";
8
+ import { getRustTarget } from "./rust.js";
9
+
10
+ const bar = new SingleBar({
11
+ format:
12
+ "Downloading |" + c.cyan("{bar}") + "| {percentage}% || {value}/{total} KB",
13
+ barCompleteChar: "\u2588",
14
+ barIncompleteChar: "\u2591",
15
+ hideCursor: true,
16
+ });
17
+
18
+ bar.start(300, 0);
19
+
20
+ bar.increment();
21
+ bar.update(20);
22
+
23
+ async function getDownload() {
24
+ const { prefix, suffix } = getPrefixSuffix();
25
+
26
+ return `https://github.com/ahqstore/cli/releases/download/${pkg.version}/${prefix}ahqstore_cli_rs-${getRustTarget()}.${suffix}`;
27
+ }
28
+
29
+ export async function downloadModuleWithProgress() {}
@@ -0,0 +1,29 @@
1
+ import { getRustTarget } from "./rust.js";
2
+
3
+ import { platform, arch } from "node:process";
4
+
5
+ import c from "ansi-colors";
6
+
7
+ try {
8
+ const target = getRustTarget();
9
+
10
+ console.log(c.green(`Supported Target found: `) + c.yellow(`${target}`));
11
+ console.warn(
12
+ c.yellow(
13
+ "The cli will download the supported binaries the first time it loads."
14
+ )
15
+ );
16
+ } catch (_) {
17
+ console.error(
18
+ c.redBright(
19
+ `ERROR: Your OS is not supported for the cli: ${platform}-${arch} has no binaries available right now`
20
+ )
21
+ );
22
+ console.error(
23
+ c.yellowBright(
24
+ `Want to get support for your target? Head over to https://github.com/ahqstore/cli/issues`
25
+ )
26
+ );
27
+
28
+ process.exit(1);
29
+ }
package/js/rust.js ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Maps the Node.js platform and architecture to a Rust target triple.
3
+ * @returns {string} The Rust target triple (e.g., 'x86_64-pc-windows-msvc').
4
+ * @throws {Error} If the platform/architecture combination is not supported.
5
+ */
6
+ export function getRustTarget() {
7
+ const os = process.platform;
8
+ const arch = process.arch;
9
+
10
+ if (os === "win32") {
11
+ if (arch === "ia32") {
12
+ return "i686-pc-windows-msvc";
13
+ } else if (arch === "x64") {
14
+ return "x86_64-pc-windows-msvc";
15
+ } else if (arch === "arm64") {
16
+ return "aarch64-pc-windows-msvc";
17
+ }
18
+ } else if (os === "darwin") {
19
+ if (arch === "x64") {
20
+ return "x86_64-apple-darwin";
21
+ } else if (arch === "arm64") {
22
+ return "aarch64-apple-darwin";
23
+ }
24
+ } else if (os === "linux") {
25
+ if (arch === "ia32") {
26
+ return "i686-unknown-linux-gnu";
27
+ } else if (arch === "x64") {
28
+ return "x86_64-unknown-linux-gnu";
29
+ } else if (arch === "arm") {
30
+ return "armv7-unknown-linux-gnueabihf";
31
+ } else if (arch === "arm64") {
32
+ return "aarch64-unknown-linux-gnu";
33
+ }
34
+ }
35
+
36
+ throw new Error(`Unsupported platform: ${os} ${arch}`);
37
+ }
package/package.json CHANGED
@@ -1,53 +1,36 @@
1
1
  {
2
2
  "name": "@ahqstore/cli",
3
- "version": "0.7.0",
4
- "readme": "./README.md",
5
- "napi": {
6
- "name": "cli",
7
- "triples": {
8
- "additional": [
9
- "aarch64-apple-darwin",
10
- "aarch64-unknown-linux-gnu",
11
- "aarch64-pc-windows-msvc",
12
- "i686-pc-windows-msvc",
13
- "universal-apple-darwin",
14
- "riscv64gc-unknown-linux-gnu"
15
- ]
16
- }
17
- },
18
- "license": "MIT",
19
- "devDependencies": {
20
- "@napi-rs/cli": "^2.18.4"
21
- },
22
- "ava": {
23
- "timeout": "3m"
24
- },
25
- "engines": {
26
- "node": ">= 10"
3
+ "version": "0.10.0",
4
+ "description": "AHQ Store Official CLI, A port of the rust version to NodeJS",
5
+ "keywords": [
6
+ "cli",
7
+ "ahqstore",
8
+ "management"
9
+ ],
10
+ "homepage": "https://github.com/ahqstore/cli#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/ahqstore/cli/issues"
27
13
  },
28
14
  "repository": {
29
- "url": "https://github.com/ahqstore/cli"
15
+ "type": "git",
16
+ "url": "git+https://github.com/ahqstore/cli.git"
30
17
  },
18
+ "license": "MIT",
19
+ "author": "AHQ Softwares <ahqsecret@gmail.com>",
20
+ "type": "module",
31
21
  "bin": {
32
- "ahqstore": "./index.js"
22
+ "ahqstore": "./js/cli.js"
33
23
  },
24
+ "readme": "README.md",
34
25
  "scripts": {
35
- "artifacts": "napi artifacts",
36
- "build": "napi build --platform --release --features node",
37
- "build:debug": "napi build --platform --features node",
38
- "prepublishOnly": "napi prepublish -t npm",
39
- "universal": "napi universal",
40
- "version": "napi version"
26
+ "postinstall": "node js/postinstall.js"
41
27
  },
42
- "optionalDependencies": {
43
- "@ahqstore/cli-win32-x64-msvc": "0.7.0",
44
- "@ahqstore/cli-darwin-x64": "0.7.0",
45
- "@ahqstore/cli-linux-x64-gnu": "0.7.0",
46
- "@ahqstore/cli-darwin-arm64": "0.7.0",
47
- "@ahqstore/cli-linux-arm64-gnu": "0.7.0",
48
- "@ahqstore/cli-win32-arm64-msvc": "0.7.0",
49
- "@ahqstore/cli-win32-ia32-msvc": "0.7.0",
50
- "@ahqstore/cli-darwin-universal": "0.7.0",
51
- "@ahqstore/cli-linux-riscv64-gnu": "0.7.0"
28
+ "dependencies": {
29
+ "ansi-colors": "^4.1.3",
30
+ "cli-progress": "^3.12.0",
31
+ "koffi": "^2.14.0"
32
+ },
33
+ "engines": {
34
+ "node": ">=22"
52
35
  }
53
- }
36
+ }
@@ -0,0 +1,2 @@
1
+ onlyBuiltDependencies:
2
+ - koffi
package/index.js DELETED
@@ -1,182 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /* tslint:disable */
4
- /* eslint-disable */
5
- /* prettier-ignore */
6
-
7
- /* auto-generated by NAPI-RS */
8
- /* and modified by @ahqsoftwares */
9
-
10
- const { existsSync, readFileSync } = require('fs')
11
- const { join } = require("path");
12
-
13
- const { platform, arch } = process;
14
-
15
- let nativeBinding = null;
16
- let localFileExisted = false;
17
- let loadError = null;
18
-
19
- function isMusl() {
20
- // For Node 10
21
- if (!process.report || typeof process.report.getReport !== "function") {
22
- try {
23
- const lddPath = require("child_process")
24
- .execSync("which ldd")
25
- .toString()
26
- .trim();
27
- return readFileSync(lddPath, "utf8").includes("musl");
28
- } catch (e) {
29
- return true;
30
- }
31
- } else {
32
- const { glibcVersionRuntime } = process.report.getReport().header;
33
- return !glibcVersionRuntime;
34
- }
35
- }
36
-
37
- switch (platform) {
38
- case "win32":
39
- switch (arch) {
40
- case "x64":
41
- localFileExisted = existsSync(
42
- join(__dirname, "cli.win32-x64-msvc.node")
43
- );
44
- try {
45
- if (localFileExisted) {
46
- nativeBinding = require("./cli.win32-x64-msvc.node");
47
- } else {
48
- nativeBinding = require("@ahqstore/cli-win32-x64-msvc");
49
- }
50
- } catch (e) {
51
- loadError = e;
52
- }
53
- break;
54
- case "ia32":
55
- localFileExisted = existsSync(
56
- join(__dirname, "cli.win32-ia32-msvc.node")
57
- );
58
- try {
59
- if (localFileExisted) {
60
- nativeBinding = require("./cli.win32-ia32-msvc.node");
61
- } else {
62
- nativeBinding = require("@ahqstore/cli-win32-ia32-msvc");
63
- }
64
- } catch (e) {
65
- loadError = e;
66
- }
67
- break;
68
- case "arm64":
69
- localFileExisted = existsSync(
70
- join(__dirname, "cli.win32-arm64-msvc.node")
71
- );
72
- try {
73
- if (localFileExisted) {
74
- nativeBinding = require("./cli.win32-arm64-msvc.node");
75
- } else {
76
- nativeBinding = require("@ahqstore/cli-win32-arm64-msvc");
77
- }
78
- } catch (e) {
79
- loadError = e;
80
- }
81
- break;
82
- default:
83
- throw new Error(`Unsupported architecture on Windows: ${arch}`);
84
- }
85
- break;
86
- case "darwin":
87
- localFileExisted = existsSync(join(__dirname, "cli.darwin-universal.node"));
88
- try {
89
- if (localFileExisted) {
90
- nativeBinding = require("./cli.darwin-universal.node");
91
- } else {
92
- nativeBinding = require("@ahqstore/cli-darwin-universal");
93
- }
94
- break;
95
- } catch {}
96
- switch (arch) {
97
- case "x64":
98
- localFileExisted = existsSync(join(__dirname, "cli.darwin-x64.node"));
99
- try {
100
- if (localFileExisted) {
101
- nativeBinding = require("./cli.darwin-x64.node");
102
- } else {
103
- nativeBinding = require("@ahqstore/cli-darwin-x64");
104
- }
105
- } catch (e) {
106
- loadError = e;
107
- }
108
- break;
109
- case "arm64":
110
- localFileExisted = existsSync(join(__dirname, "cli.darwin-arm64.node"));
111
- try {
112
- if (localFileExisted) {
113
- nativeBinding = require("./cli.darwin-arm64.node");
114
- } else {
115
- nativeBinding = require("@ahqstore/cli-darwin-arm64");
116
- }
117
- } catch (e) {
118
- loadError = e;
119
- }
120
- break;
121
- default:
122
- throw new Error(`Unsupported architecture on macOS: ${arch}`);
123
- }
124
- break;
125
- case "linux":
126
- switch (arch) {
127
- case "x64":
128
- if (isMusl()) {
129
- throw new Error("MUSL Bindings are not supported!");
130
- } else {
131
- localFileExisted = existsSync(
132
- join(__dirname, "cli.linux-x64-gnu.node")
133
- );
134
- try {
135
- if (localFileExisted) {
136
- nativeBinding = require("./cli.linux-x64-gnu.node");
137
- } else {
138
- nativeBinding = require("@ahqstore/cli-linux-x64-gnu");
139
- }
140
- } catch (e) {
141
- loadError = e;
142
- }
143
- }
144
- break;
145
- case "arm64":
146
- if (isMusl()) {
147
- throw new Error("MUSL Bindings are not supported!");
148
- } else {
149
- localFileExisted = existsSync(
150
- join(__dirname, "cli.linux-arm64-gnu.node")
151
- );
152
- try {
153
- if (localFileExisted) {
154
- nativeBinding = require("./cli.linux-arm64-gnu.node");
155
- } else {
156
- nativeBinding = require("@ahqstore/cli-linux-arm64-gnu");
157
- }
158
- } catch (e) {
159
- loadError = e;
160
- }
161
- }
162
- break;
163
- default:
164
- throw new Error(`Unsupported architecture on Linux: ${arch}`);
165
- }
166
- break;
167
- default:
168
- throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`);
169
- }
170
-
171
- if (!nativeBinding) {
172
- if (loadError) {
173
- throw loadError;
174
- }
175
- throw new Error(`Failed to load native binding`);
176
- }
177
-
178
- const { nodeEntrypoint } = nativeBinding;
179
-
180
- const args = process.argv.slice(2) || [];
181
-
182
- nodeEntrypoint(args, process.env["GH_ACTION"] != null);
@@ -1,54 +0,0 @@
1
- use std::{env, fs, process};
2
-
3
- use serde_json::from_str;
4
-
5
- use crate::app::{
6
- shared::{Config, Finder, IMetadata},
7
- ERR,
8
- };
9
-
10
- use super::{GHAsset, GHRelease};
11
-
12
- pub fn get_config<'a>() -> IMetadata<'a> {
13
- let Ok(config) = fs::read_to_string("./.ahqstore/config.json") else {
14
- ERR.println(&"Unable to read config file!");
15
- process::exit(1);
16
- };
17
- let config = config.leak();
18
- let Ok(mut config) = from_str::<'a, Config>(config) else {
19
- ERR.println(&"Unable to read config file!");
20
- process::exit(1);
21
- };
22
-
23
- if let Ok(app_id) = env::var("APP_ID") {
24
- config.remove(&app_id).expect("Key not present in JSON")
25
- } else {
26
- config.into_values().nth(0).expect("No Key present in JSON")
27
- }
28
- }
29
-
30
- pub fn find_assets<'a>(gh_r: &'a GHRelease, finder: &'a Finder) -> Vec<&'a GHAsset> {
31
- gh_r
32
- .assets
33
- .iter()
34
- .filter(|a| {
35
- if let Some(x) = finder.startsWith {
36
- if !a.name.starts_with(&x) {
37
- return false;
38
- }
39
- }
40
- if let Some(x) = finder.contains {
41
- if !a.name.contains(&x) {
42
- return false;
43
- }
44
- }
45
- if let Some(x) = finder.endsWith {
46
- if !a.name.ends_with(&x) {
47
- return false;
48
- }
49
- }
50
-
51
- true
52
- })
53
- .collect::<Vec<_>>()
54
- }
@@ -1,47 +0,0 @@
1
- use crate::app::ERR;
2
- use image::{load_from_memory_with_format as load_img, ImageFormat};
3
- use std::fs;
4
- use std::process;
5
-
6
- pub fn get_icon(uid: &str) -> Vec<u8> {
7
- let base_img = format!("./.ahqstore/images/{uid}/icon.png");
8
-
9
- let Ok(icon) = fs::read(&base_img) else {
10
- ERR.println(&"Unable to read icon file!");
11
- process::exit(1);
12
- };
13
-
14
- validate_png(&icon);
15
-
16
- icon
17
- }
18
-
19
- pub fn get_images(uid: &str) -> Vec<Vec<u8>> {
20
- let base_img = format!("./.ahqstore/images/{uid}");
21
-
22
- let Ok(image_dir) = fs::read_dir(&base_img) else {
23
- ERR.println(&"Unable to read image dir!");
24
- process::exit(1);
25
- };
26
-
27
- let mut entries = image_dir
28
- .map(|res| res.expect("Unable to unwrap dir entry").path())
29
- .filter(|f| !f.ends_with("icon.png"))
30
- .map(|res| fs::read(res).expect("Unable to read bytes"))
31
- .map(|img| {
32
- validate_png(&img);
33
- return img;
34
- })
35
- .collect::<Vec<_>>();
36
-
37
- entries.truncate(10);
38
-
39
- entries
40
- }
41
-
42
- pub fn validate_png(data: &Vec<u8>) {
43
- let Ok(_) = load_img(&data, ImageFormat::Png) else {
44
- ERR.println(&"Invalid PNG");
45
- process::exit(1);
46
- };
47
- }