@ahqstore/cli 0.7.0 → 0.10.1

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/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
- }
@@ -1,98 +0,0 @@
1
- macro_rules! f {
2
- ($($x:tt)*) => {
3
- format!($($x)*)
4
- };
5
- }
6
-
7
- macro_rules! s {
8
- ($($x:tt)*) => {
9
- stringify!($($x)*)
10
- };
11
- }
12
-
13
- #[macro_export]
14
- macro_rules! windowsPlatform {
15
- ($num: ident, $win: ident, $config: ident, $gh_r: ident, $final_config: ident, $platform: ident, $options: ident, $finder: ident) => {
16
- $num += 1;
17
- if let Some(platform) = $config.platform.$platform {
18
- if matches!(&platform, &InstallerFormat::LinuxAppImage | &InstallerFormat::AndroidApkZip) {
19
- ERR.println(&"Invalid File Format, expected a valid windows format");
20
- process::exit(1);
21
- }
22
-
23
- let Some(options) = $config.platform.$options else {
24
- ERR.println(&f!("{} Options not found!", s!($win)));
25
- process::exit(1);
26
- };
27
- let Some(finder) = $config.finder.$finder else {
28
- ERR.println(&f!("{} Finder config not found!", s!($win)));
29
- process::exit(1);
30
- };
31
-
32
- let assets = crate::app::build::find_assets(&$gh_r, &finder);
33
-
34
- if assets.len() > 1 {
35
- ERR.println(&f!("Multiple assets found while parsing {}", s!($win)));
36
- process::exit(1);
37
- }
38
- if assets.len() == 0 {
39
- ERR.println(&f!("No assets found while parsing {}", s!($win)));
40
- process::exit(1);
41
- }
42
-
43
- $final_config.downloadUrls.insert(
44
- $num,
45
- DownloadUrl {
46
- installerType: platform,
47
- asset: assets[0].name.clone(),
48
- url: "".into(),
49
- },
50
- );
51
-
52
- $final_config.install.$win = Some(InstallerOptionsWindows {
53
- assetId: $num,
54
- exec: options.zip_file_exec.map_or(None, |a| Some(a.to_string())),
55
- installerArgs: options
56
- .exe_installer_args
57
- .map_or(None, |a| Some(a.iter().map(|x| x.to_string()).collect())),
58
- });
59
- }
60
- };
61
- }
62
-
63
- #[macro_export]
64
- macro_rules! linuxPlatform {
65
- ($num: ident, $linux: ident, $config: ident, $gh_r: ident, $final_config: ident, $platform: ident, $finder: ident) => {
66
- $num += 1;
67
- if let Some(platform) = $config.platform.$platform {
68
- if !matches!(&platform, &InstallerFormat::LinuxAppImage) {
69
- ERR.println(&"Invalid File Format, expected LinuxAppImage");
70
- }
71
-
72
- let Some(finder) = $config.finder.$finder else {
73
- ERR.println(&f!("{} Finder Config not found!", s!($linux)));
74
- process::exit(1);
75
- };
76
-
77
- let assets = find_assets(&$gh_r, &finder);
78
-
79
- if assets.len() > 1 {
80
- ERR.println(&f!("Multiple assets found while parsing {}", s!($linux)));
81
- process::exit(1);
82
- }
83
-
84
- $final_config.downloadUrls.insert(
85
- $num,
86
- DownloadUrl {
87
- installerType: platform,
88
- asset: assets[0].name.clone(),
89
- url: "".into()
90
- },
91
- );
92
-
93
- $final_config.install.$linux = Some(InstallerOptionsLinux {
94
- assetId: $num
95
- });
96
- }
97
- };
98
- }
@@ -1,219 +0,0 @@
1
- use ahqstore_types::{
2
- AHQStoreApplication, DownloadUrl, InstallerFormat, InstallerOptions, InstallerOptionsAndroid, InstallerOptionsLinux, InstallerOptionsWindows, Str
3
- };
4
- use lazy_static::lazy_static;
5
- use reqwest::blocking::{Client, ClientBuilder};
6
- use serde::{Deserialize, Serialize};
7
- use serde_json::{from_str, to_string};
8
- use std::{collections::HashMap, env, fs, process};
9
-
10
- use crate::app::ERR;
11
-
12
- use super::INFO;
13
-
14
- mod config;
15
- mod icon;
16
- mod release;
17
- use config::*;
18
- use icon::*;
19
- use release::*;
20
-
21
- #[macro_use]
22
- mod macros;
23
-
24
- lazy_static! {
25
- pub static ref CLIENT: Client = ClientBuilder::new()
26
- .user_agent("AHQ Store / App Builder")
27
- .build()
28
- .unwrap();
29
- }
30
-
31
- #[derive(Debug, Deserialize, Serialize)]
32
- struct GHRelease {
33
- pub tag_name: String,
34
- pub upload_url: String,
35
- pub assets: Vec<GHAsset>,
36
- }
37
-
38
- #[derive(Debug, Deserialize, Serialize)]
39
- struct GHAsset {
40
- pub name: String,
41
- pub browser_download_url: String,
42
- }
43
- pub fn build_config(upload: bool, gh_action: bool) {
44
- let Some(_) = fs::read_dir("./.ahqstore").ok() else {
45
- ERR.println(&".ahqstore dir couldn't be accessed!");
46
- process::exit(1);
47
- };
48
- if !gh_action {
49
- INFO.print(&"INFO ");
50
- println!("Checking .ahqstore");
51
- }
52
-
53
- let config = get_config();
54
-
55
- let repo = env::var("GITHUB_REPOSITORY").unwrap_or("%NUL".into());
56
-
57
- if &repo == "%NUL" {
58
- ERR.println(&"GITHUB_REPOSITORY not set");
59
- process::exit(1);
60
- }
61
-
62
- let r_id = env::var("RELEASE_ID").unwrap_or("latest".into());
63
-
64
- if &r_id == "latest" && upload {
65
- ERR.println(&"RELEASE_ID variable not present");
66
- process::exit(1);
67
- };
68
- if &r_id == "latest" {
69
- INFO.print(&"INFO ");
70
- println!("Getting latest release");
71
- }
72
-
73
- let gh_token = env::var("GH_TOKEN").unwrap_or("".into());
74
-
75
- if &gh_token == "" && upload {
76
- ERR.println(&"GH_TOKEN variable not present");
77
- process::exit(1);
78
- };
79
-
80
- let (version, gh_r) = fetch_release(&repo, &r_id, &gh_token);
81
-
82
- let icon = get_icon(&config.appId);
83
- let dspl_images = get_images(&config.appId);
84
-
85
- let mut resources = HashMap::new();
86
- resources.insert(0, icon);
87
-
88
- #[allow(non_snake_case)]
89
- let displayImages = dspl_images.into_iter().enumerate().map(|(uid, icon)| {
90
- resources.insert(uid as u8 + 1u8, icon);
91
-
92
- uid as u8
93
- }).collect();
94
-
95
- let app_id = config.appId.clone();
96
-
97
- let mut final_config: AHQStoreApplication = AHQStoreApplication {
98
- releaseTagName: gh_r.tag_name.clone(),
99
- appDisplayName: config.appDisplayName,
100
- appId: config.appId,
101
- appShortcutName: config.appShortcutName,
102
- authorId: config.authorId,
103
- description: config.description,
104
- downloadUrls: HashMap::default(),
105
- displayImages,
106
- resources: Some(resources),
107
- license_or_tos: config.license_or_tos,
108
- install: InstallerOptions {
109
- linux: None,
110
- android: None,
111
- linuxArm64: None,
112
- linuxArm7: None,
113
- winarm: None,
114
- win32: None,
115
- },
116
- repo: config.repo,
117
- version,
118
- site: config.site,
119
- source: config.redistributed,
120
- verified: false
121
- };
122
-
123
- let mut num = 0;
124
- // Win x86_64
125
- windowsPlatform!(num, win32, config, gh_r, final_config, winAmd64Platform, winAmd64Options, windowsAmd64Finder);
126
-
127
- // Win Arm64
128
- windowsPlatform!(num, winarm, config, gh_r, final_config, winArm64Platform, winArm64Options, windowsArm64Finder);
129
-
130
- // Linux x86_64
131
- linuxPlatform!(num, linux, config, gh_r, final_config, linuxAmd64Platform, linuxAmd64Finder);
132
-
133
- // Linux Arm64
134
- linuxPlatform!(num, linuxArm64, config, gh_r, final_config, linuxArm64Platform, linuxArm64Finder);
135
-
136
- // Linux Armv7
137
- linuxPlatform!(num, linuxArm7, config, gh_r, final_config, linuxArm32Platform, linuxArm32Finder);
138
-
139
- num += 1;
140
-
141
- // Android Universal
142
- if let Some(platform) = config.platform.androidUniversal {
143
- if !matches!(platform, InstallerFormat::AndroidApkZip) {
144
- ERR.println(&"Invalid File Format, expected AndroidApkZip");
145
- }
146
-
147
- let Some(finder) = config.finder.androidUniversalFinder else {
148
- ERR.println(&"Android Finder Config not found!");
149
- process::exit(1);
150
- };
151
-
152
- let assets = find_assets(&gh_r, &finder);
153
-
154
- if assets.len() > 1 {
155
- ERR.println(&"Multiple assets found while parsing android");
156
- process::exit(1);
157
- }
158
-
159
- final_config.downloadUrls.insert(
160
- num,
161
- DownloadUrl {
162
- installerType: platform,
163
- asset: assets[0].name.clone(),
164
- url: "".into()
165
- },
166
- );
167
-
168
- final_config.install.android = Some(InstallerOptionsAndroid {
169
- assetId: num
170
- });
171
- }
172
-
173
- INFO.println(&"Validating config");
174
- match final_config.validate() {
175
- Ok(x) => {
176
- println!("{x}");
177
- },
178
- Err(x) => {
179
- ERR.println(&"An error occured!");
180
- println!("{x}");
181
-
182
- panic!("👆🏼 Please fix the above issues!");
183
- }
184
- }
185
-
186
- let config_file = to_string(&final_config).unwrap();
187
-
188
- if !gh_action {
189
- println!("{} {}.json", &*INFO, &app_id);
190
- println!("{}", &config_file);
191
- }
192
-
193
- if upload {
194
- let uup = gh_r
195
- .upload_url
196
- .replace("{?name,label}", &format!("?name={app_id}.json"));
197
-
198
- let resp = CLIENT
199
- .post(uup)
200
- .header("Content-Length", config_file.len())
201
- .header("Content-Type", "text/plain")
202
- .header("Accept", "application/json")
203
- .body(config_file)
204
- .bearer_auth(&gh_token)
205
- .send()
206
- .unwrap()
207
- .text()
208
- .unwrap();
209
-
210
- if gh_action {
211
- let val: GHAsset = from_str(&resp).unwrap();
212
-
213
- println!("AHQ_STORE_FILE_URL={}", &val.browser_download_url);
214
- } else {
215
- INFO.println(&"GitHub Response");
216
- println!("{resp}");
217
- }
218
- }
219
- }
@@ -1,50 +0,0 @@
1
- use std::process;
2
-
3
- use serde_json::{from_str, to_string};
4
- use sha2::{Digest, Sha256};
5
-
6
- use crate::app::{
7
- build::{GHRelease, Str},
8
- ERR, WARN,
9
- };
10
-
11
- use super::CLIENT;
12
-
13
- pub fn fetch_release(repo: &str, r_id: &str, gh_token: &str) -> (Str, GHRelease) {
14
- let Ok(resp) = ({
15
- let mut resp = CLIENT.get(format!(
16
- "https://api.github.com/repos/{repo}/releases/{r_id}"
17
- ));
18
-
19
- if gh_token != "" {
20
- resp = resp.bearer_auth(gh_token);
21
- } else {
22
- WARN.println(&"You may set GH_TOKEN environment variable to load private repos");
23
- }
24
-
25
- resp.send()
26
- }) else {
27
- ERR.println(&"Unable to fetch release");
28
- process::exit(1)
29
- };
30
-
31
- let Ok(release) = resp.text() else {
32
- ERR.println(&"Unable to read release");
33
- process::exit(1);
34
- };
35
-
36
- let Ok(resp) = from_str::<GHRelease>(&release) else {
37
- ERR.println(&"Unable to parse release");
38
- process::exit(1);
39
- };
40
-
41
- let mut hasher = Sha256::new();
42
-
43
- hasher.update(release.as_bytes());
44
-
45
- let hashed = hasher.finalize();
46
- let hashed = hashed.to_vec();
47
- let version = to_string(&hashed).unwrap_or("**UNKNOWN**".to_string());
48
-
49
- (version, resp)
50
- }
Binary file