mjpic 1.0.6 → 1.0.8
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/.vercel/project.json +1 -0
- package/README.md +105 -0
- package/api/cli.ts +42 -3
- package/deploy/mjpic-start.desktop +20 -0
- package/deploy/node_install.sh +111 -0
- package/deploy//344/275/277/347/224/250/350/257/264/346/230/216.txt +17 -0
- package/dist/cli/cli.js +36 -2
- package/dist/client/assets/{index-BQfYCBRX.js → index-C4AVPLLP.js} +25 -25
- package/dist/client/index.html +1 -1
- package/package.json +4 -3
- package/scripts/get-random-port.js +40 -0
- package/src/components/dialogs/SaveDialog.tsx +1 -1
- package/src/components/layout/Header.tsx +43 -18
- package/src/components/layout/RightPanel.tsx +0 -21
- package/vite.config.ts +3 -1
- package/tmp/guangxi.jpg +0 -0
- package//345/217/202/350/200/203/345/233/276/347/211/207//346/210/252/345/261/2172026-02-18 16.47.45_/345/233/276/347/211/207/345/260/272/345/257/270/350/260/203/350/212/202_/351/242/204/350/256/276/345/260/272/345/257/270.jpg +0 -0
- package//345/217/202/350/200/203/345/233/276/347/211/207//346/210/252/345/261/2172026-02-18 16.47.51_/345/233/276/347/211/207/345/260/272/345/257/270/350/260/203/350/212/202_/346/211/213/345/267/245/350/276/223/345/205/245/345/260/272/345/257/270.jpg +0 -0
- package//345/217/202/350/200/203/345/233/276/347/211/207//346/210/252/345/261/2172026-02-18 16.54.56_/345/233/276/347/211/207/345/260/272/345/257/270/350/260/203/350/212/202_/346/267/273/345/212/240/345/270/270/347/224/250/345/260/272/345/257/270.jpg +0 -0
- package//345/217/202/350/200/203/345/233/276/347/211/207//346/210/252/345/261/2172026-02-18 16.55.11_/345/233/276/347/211/207/345/260/272/345/257/270/350/260/203/350/212/202_/345/210/240/351/231/244/345/270/270/347/224/250/345/260/272/345/257/270.jpg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"neverMindDeployCard":true}
|
package/README.md
CHANGED
|
@@ -40,3 +40,108 @@ mjpic dev
|
|
|
40
40
|
1. 克隆仓库
|
|
41
41
|
2. 安装依赖:`npm install`
|
|
42
42
|
3. 启动开发服务器:`npm run dev`
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## 安装使用
|
|
46
|
+
|
|
47
|
+
### 安装
|
|
48
|
+
|
|
49
|
+
Q:Arm架构的麒麟操作系统V10如何安装Node.js?
|
|
50
|
+
|
|
51
|
+
■ 豆包:
|
|
52
|
+
|
|
53
|
+
方法一:直接手工安装
|
|
54
|
+
|
|
55
|
+
访问Node.js官网 https://nodejs.org/zh-cn/download
|
|
56
|
+
|
|
57
|
+
uname -m # aarch64表示系统架构是ARM64
|
|
58
|
+
|
|
59
|
+
下载Linux ARM64版本
|
|
60
|
+
|
|
61
|
+
cd ~/下载
|
|
62
|
+
wget https://nodejs.org/dist/v24.13.1/node-v24.13.1-linux-arm64.tar.xz
|
|
63
|
+
tar -xvf node-xxx-arm64.tar.xz
|
|
64
|
+
sudo mv node-xxx-arm64 /usr/local/nodejs
|
|
65
|
+
|
|
66
|
+
配置环境变量
|
|
67
|
+
|
|
68
|
+
sudo vim /etc/profile
|
|
69
|
+
export NODE_HOME=/usr/local/nodejs
|
|
70
|
+
export PATH=$NODE_HOME/bin:$PATH
|
|
71
|
+
source /etc/profile
|
|
72
|
+
|
|
73
|
+
测试安装是否成功
|
|
74
|
+
|
|
75
|
+
node -v
|
|
76
|
+
|
|
77
|
+
方法二:配合`/deploy/node_install.sh`脚本安装
|
|
78
|
+
|
|
79
|
+
1. 保存`node_install.sh 到`下载 目录。
|
|
80
|
+
|
|
81
|
+
2. 打开终端(terminal)。
|
|
82
|
+
|
|
83
|
+
3. 进入下载目录:
|
|
84
|
+
|
|
85
|
+
cd ~/下载
|
|
86
|
+
|
|
87
|
+
4. 赋予脚本可执行权限:
|
|
88
|
+
|
|
89
|
+
chmod +x node_install.sh
|
|
90
|
+
|
|
91
|
+
5. 以root权限运行脚本:
|
|
92
|
+
|
|
93
|
+
sudo ./node_install.sh
|
|
94
|
+
|
|
95
|
+
6. 使环境变量生效
|
|
96
|
+
|
|
97
|
+
source ~/.bashrc
|
|
98
|
+
|
|
99
|
+
7. 下载 敏捷图片(mjpic):
|
|
100
|
+
|
|
101
|
+
npm install mjpic@latest
|
|
102
|
+
|
|
103
|
+
8. 运行 敏捷图片(mjpic):
|
|
104
|
+
|
|
105
|
+
npx mjpic build --port 3030
|
|
106
|
+
|
|
107
|
+
### 创建桌面快捷方式
|
|
108
|
+
|
|
109
|
+
Q:如何在麒麟操作系统V10的桌面创建一个快捷方式,单击后直接在终端运行 npx mjpic build --port 3030 命令?
|
|
110
|
+
|
|
111
|
+
■ 豆包:
|
|
112
|
+
|
|
113
|
+
方法一:
|
|
114
|
+
|
|
115
|
+
cd ~/桌面
|
|
116
|
+
|
|
117
|
+
vim mjpic-start.desktop
|
|
118
|
+
|
|
119
|
+
[Desktop Entry]
|
|
120
|
+
快捷方式类型(应用程序)
|
|
121
|
+
Type=Application
|
|
122
|
+
显示名称(桌面显示的文件名)
|
|
123
|
+
Name=敏捷图片
|
|
124
|
+
注释(鼠标悬停显示)
|
|
125
|
+
Comment=启动mjpic服务,端口3030
|
|
126
|
+
图标(可选,可替换为自己的图标路径,也可留空)
|
|
127
|
+
Icon=image
|
|
128
|
+
关键:执行的命令(xterm/gnome-terminal 打开终端并执行命令)
|
|
129
|
+
麒麟V10优先用 gnome-terminal,若不行换 xterm
|
|
130
|
+
Exec=mate-terminal -- bash --login -c "source ~/.bashrc; npx mjpic build --port 3030; exec bash"
|
|
131
|
+
执行终端窗口是否保持打开(yes=执行完不关闭,no=执行完关闭)
|
|
132
|
+
Terminal=yes
|
|
133
|
+
分类(桌面显示的归类)
|
|
134
|
+
Categories=Graphics
|
|
135
|
+
编码
|
|
136
|
+
Encoding=UTF-8
|
|
137
|
+
是否允许执行
|
|
138
|
+
Executable=true
|
|
139
|
+
|
|
140
|
+
chmod +x ~/桌面/mjpic-start.desktop
|
|
141
|
+
|
|
142
|
+
注:如有相关提示,选择始终允许执行。
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
方法二:
|
|
146
|
+
|
|
147
|
+
9. 关闭终端,保存 mjpic-start.desktop 到 桌面,右键属性勾选可执行权限。双击新建图标运行。
|
package/api/cli.ts
CHANGED
|
@@ -5,6 +5,7 @@ import fs from 'fs';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import open from 'open';
|
|
8
|
+
import net from 'net';
|
|
8
9
|
import app from './app.js';
|
|
9
10
|
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -12,8 +13,46 @@ const __dirname = path.dirname(__filename);
|
|
|
12
13
|
|
|
13
14
|
const program = new Command();
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
// Check if a port is available
|
|
17
|
+
const isPortAvailable = (port: number): Promise<boolean> => {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const server = net.createServer();
|
|
20
|
+
server.once('error', () => resolve(false));
|
|
21
|
+
server.once('listening', () => {
|
|
22
|
+
server.close();
|
|
23
|
+
resolve(true);
|
|
24
|
+
});
|
|
25
|
+
server.listen(port);
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Generate a random port between min and max, excluding common ports
|
|
30
|
+
const getRandomPort = async (): Promise<number> => {
|
|
31
|
+
const commonPorts = [3000, 5000, 5173, 8000, 8080, 8888, 4200];
|
|
32
|
+
const min = 10000;
|
|
33
|
+
const max = 65535;
|
|
34
|
+
|
|
35
|
+
// Try up to 50 times to find a port
|
|
36
|
+
for (let i = 0; i < 50; i++) {
|
|
37
|
+
const port = Math.floor(Math.random() * (max - min + 1) + min);
|
|
38
|
+
if (!commonPorts.includes(port) && await isPortAvailable(port)) {
|
|
39
|
+
return port;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Fallback to 0 (let OS choose) if we can't find one, though OS might pick a common one (unlikely)
|
|
44
|
+
return 0;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const startServer = async (options: { port?: string; host: string }, file?: string) => {
|
|
48
|
+
let port: number;
|
|
49
|
+
|
|
50
|
+
if (options.port) {
|
|
51
|
+
port = parseInt(options.port, 10);
|
|
52
|
+
} else {
|
|
53
|
+
port = await getRandomPort();
|
|
54
|
+
}
|
|
55
|
+
|
|
17
56
|
const host = options.host;
|
|
18
57
|
|
|
19
58
|
if (file) {
|
|
@@ -58,7 +97,7 @@ program
|
|
|
58
97
|
|
|
59
98
|
const attachServeOptions = (cmd: Command) => {
|
|
60
99
|
cmd
|
|
61
|
-
.option('-p, --port <number>', 'server port'
|
|
100
|
+
.option('-p, --port <number>', 'server port')
|
|
62
101
|
.option('--host <string>', 'server host', 'localhost')
|
|
63
102
|
.argument('[file]', 'image file to open')
|
|
64
103
|
.action(async (file, options) => {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[Desktop Entry]
|
|
2
|
+
# 快捷方式类型(应用程序)
|
|
3
|
+
Type=Application
|
|
4
|
+
# 显示名称(桌面显示的文件名)
|
|
5
|
+
Name=敏捷图片
|
|
6
|
+
# 注释(鼠标悬停显示)
|
|
7
|
+
Comment=启动mjpic服务,端口3030
|
|
8
|
+
# 图标(可选,可替换为自己的图标路径,也可留空)
|
|
9
|
+
Icon=image
|
|
10
|
+
# 关键:执行的命令(xterm/gnome-terminal 打开终端并执行命令)
|
|
11
|
+
# 麒麟V10优先用 gnome-terminal,若不行换 xterm
|
|
12
|
+
Exec=mate-terminal -- bash --login -c "source ~/.bashrc; npx mjpic build --port 3030; exec bash"
|
|
13
|
+
# 执行终端窗口是否保持打开(yes=执行完不关闭,no=执行完关闭)
|
|
14
|
+
Terminal=yes
|
|
15
|
+
# 分类(桌面显示的归类)
|
|
16
|
+
Categories=Graphics
|
|
17
|
+
# 编码
|
|
18
|
+
Encoding=UTF-8
|
|
19
|
+
# 是否允许执行
|
|
20
|
+
Executable=true
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Node.js ARM64架构 麒麟V10 自动安装脚本
|
|
3
|
+
# 版本:v24.13.1
|
|
4
|
+
# 修复:sudo执行时使用原始用户目录 + 环境变量全局生效
|
|
5
|
+
|
|
6
|
+
# 定义Node.js版本和下载地址
|
|
7
|
+
NODE_VERSION="v24.13.1"
|
|
8
|
+
NODE_ARCH="linux-arm64"
|
|
9
|
+
NODE_PACKAGE="node-${NODE_VERSION}-${NODE_ARCH}.tar.xz"
|
|
10
|
+
DOWNLOAD_URL="https://nodejs.org/dist/${NODE_VERSION}/${NODE_PACKAGE}"
|
|
11
|
+
INSTALL_DIR="/usr/local/nodejs"
|
|
12
|
+
|
|
13
|
+
# 关键修复1:获取执行sudo前的原始用户(而非root)
|
|
14
|
+
ORIGINAL_USER=${SUDO_USER:-$USER}
|
|
15
|
+
ORIGINAL_USER_HOME="/home/${ORIGINAL_USER}"
|
|
16
|
+
DOWNLOAD_DIR="${ORIGINAL_USER_HOME}/下载"
|
|
17
|
+
|
|
18
|
+
# 检查是否为root权限(移动文件需要sudo)
|
|
19
|
+
if [ $EUID -ne 0 ]; then
|
|
20
|
+
echo "错误:请使用root权限运行此脚本(sudo ./node_install.sh)"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# 步骤1:进入原始用户的下载目录
|
|
25
|
+
echo "===== 进入原始用户(${ORIGINAL_USER})的下载目录:${DOWNLOAD_DIR} ====="
|
|
26
|
+
cd "${DOWNLOAD_DIR}" || {
|
|
27
|
+
echo "错误:${DOWNLOAD_DIR} 目录不存在,创建该目录..."
|
|
28
|
+
mkdir -p "${DOWNLOAD_DIR}"
|
|
29
|
+
chown "${ORIGINAL_USER}:${ORIGINAL_USER}" "${DOWNLOAD_DIR}"
|
|
30
|
+
cd "${DOWNLOAD_DIR}"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# 步骤2:下载Node.js安装包
|
|
34
|
+
echo -e "\n===== 开始下载Node.js ${NODE_VERSION} ====="
|
|
35
|
+
if [ -f "${NODE_PACKAGE}" ]; then
|
|
36
|
+
echo "检测到已存在同名安装包,跳过下载..."
|
|
37
|
+
else
|
|
38
|
+
wget "${DOWNLOAD_URL}" -O "${NODE_PACKAGE}" || {
|
|
39
|
+
echo "下载失败!请更换淘宝镜像源:"
|
|
40
|
+
echo "DOWNLOAD_URL=\"https://npm.taobao.org/mirrors/node/${NODE_VERSION}/${NODE_PACKAGE}\""
|
|
41
|
+
exit 1
|
|
42
|
+
}
|
|
43
|
+
chown "${ORIGINAL_USER}:${ORIGINAL_USER}" "${NODE_PACKAGE}"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# 步骤3:解压安装包
|
|
47
|
+
echo -e "\n===== 解压安装包 ====="
|
|
48
|
+
tar -xvf "${NODE_PACKAGE}" || {
|
|
49
|
+
echo "解压失败!安装包可能损坏,请删除后重新下载"
|
|
50
|
+
exit 1
|
|
51
|
+
}
|
|
52
|
+
chown -R "${ORIGINAL_USER}:${ORIGINAL_USER}" "node-${NODE_VERSION}-${NODE_ARCH}"
|
|
53
|
+
|
|
54
|
+
# 步骤4:移动到系统目录
|
|
55
|
+
echo -e "\n===== 移动安装目录到 ${INSTALL_DIR} ====="
|
|
56
|
+
if [ -d "${INSTALL_DIR}" ]; then
|
|
57
|
+
echo "检测到已存在${INSTALL_DIR},先备份并删除..."
|
|
58
|
+
mv "${INSTALL_DIR}" "${INSTALL_DIR}_bak_$(date +%Y%m%d%H%M%S)"
|
|
59
|
+
fi
|
|
60
|
+
mv "node-${NODE_VERSION}-${NODE_ARCH}" "${INSTALL_DIR}" || {
|
|
61
|
+
echo "移动目录失败!请检查权限"
|
|
62
|
+
exit 1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# 步骤5:配置环境变量(关键修复2:确保全局生效)
|
|
66
|
+
echo -e "\n===== 配置系统环境变量 ====="
|
|
67
|
+
# 方案1:写入/etc/profile(系统级,所有用户生效)
|
|
68
|
+
if ! grep -q "NODE_HOME=${INSTALL_DIR}" /etc/profile; then
|
|
69
|
+
echo "" >> /etc/profile
|
|
70
|
+
echo "# Node.js environment variables" >> /etc/profile
|
|
71
|
+
echo "export NODE_HOME=${INSTALL_DIR}" >> /etc/profile
|
|
72
|
+
echo "export PATH=\$NODE_HOME/bin:\$PATH" >> /etc/profile
|
|
73
|
+
echo "系统级环境变量已添加到/etc/profile"
|
|
74
|
+
else
|
|
75
|
+
echo "系统级环境变量已存在,无需重复添加"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# 方案2:写入原始用户的~/.bashrc(用户级,避免source失效)
|
|
79
|
+
USER_BASHRC="${ORIGINAL_USER_HOME}/.bashrc"
|
|
80
|
+
if ! grep -q "NODE_HOME=${INSTALL_DIR}" "${USER_BASHRC}"; then
|
|
81
|
+
echo "" >> "${USER_BASHRC}"
|
|
82
|
+
echo "# Node.js environment variables" >> "${USER_BASHRC}"
|
|
83
|
+
echo "export NODE_HOME=${INSTALL_DIR}" >> "${USER_BASHRC}"
|
|
84
|
+
echo "export PATH=\$NODE_HOME/bin:\$PATH" >> "${USER_BASHRC}"
|
|
85
|
+
chown "${ORIGINAL_USER}:${ORIGINAL_USER}" "${USER_BASHRC}"
|
|
86
|
+
echo "用户级环境变量已添加到${USER_BASHRC}"
|
|
87
|
+
else
|
|
88
|
+
echo "用户级环境变量已存在,无需重复添加"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# 步骤6:验证安装(直接用绝对路径验证,避免环境变量未生效的误判)
|
|
92
|
+
echo -e "\n===== 验证安装结果 ====="
|
|
93
|
+
# 直接使用Node.js的绝对路径验证,不受当前shell环境影响
|
|
94
|
+
NODE_ABS_PATH="${INSTALL_DIR}/bin/node"
|
|
95
|
+
NPM_ABS_PATH="${INSTALL_DIR}/bin/npm"
|
|
96
|
+
|
|
97
|
+
if [ -f "${NODE_ABS_PATH}" ] && [ -f "${NPM_ABS_PATH}" ]; then
|
|
98
|
+
echo "Node.js 绝对路径验证:$(${NODE_ABS_PATH} -v)"
|
|
99
|
+
echo "npm 绝对路径验证:$(${NPM_ABS_PATH} -v)"
|
|
100
|
+
echo -e "\n===== 安装成功!====="
|
|
101
|
+
echo "注意:环境变量需以下方式生效:"
|
|
102
|
+
echo "1. 普通用户执行:source ~/.bashrc (立即生效)"
|
|
103
|
+
echo "2. 或重启终端/重新登录(永久生效)"
|
|
104
|
+
echo "3. 验证命令:node -v && npm -v"
|
|
105
|
+
else
|
|
106
|
+
echo -e "\n===== 安装失败!====="
|
|
107
|
+
echo "未找到Node.js/npm的可执行文件,请检查安装目录:${INSTALL_DIR}/bin"
|
|
108
|
+
exit 1
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
exit 0
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# 敏捷图片(mjpic)安装使用说明
|
|
2
|
+
|
|
3
|
+
1. 保存 node_install.sh 到 下载 目录。
|
|
4
|
+
2. 打开终端(terminal)。
|
|
5
|
+
3. 进入下载目录:
|
|
6
|
+
cd ~/下载
|
|
7
|
+
4. 赋予脚本可执行权限:
|
|
8
|
+
chmod +x node_install.sh
|
|
9
|
+
5. 以root权限运行脚本:
|
|
10
|
+
sudo ./node_install.sh
|
|
11
|
+
6. 使环境变量生效
|
|
12
|
+
source ~/.bashrc
|
|
13
|
+
7. 下载 敏捷图片(mjpic):
|
|
14
|
+
npm install mjpic@latest
|
|
15
|
+
8. 运行 敏捷图片(mjpic):
|
|
16
|
+
npx mjpic build --port 3030
|
|
17
|
+
9. 关闭终端,保存 mjpic-start.desktop 到 桌面,右键属性勾选可执行权限。双击新建图标运行。
|
package/dist/cli/cli.js
CHANGED
|
@@ -5,12 +5,46 @@ import fs from 'fs';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import open from 'open';
|
|
8
|
+
import net from 'net';
|
|
8
9
|
import app from './app.js';
|
|
9
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
11
|
const __dirname = path.dirname(__filename);
|
|
11
12
|
const program = new Command();
|
|
13
|
+
// Check if a port is available
|
|
14
|
+
const isPortAvailable = (port) => {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const server = net.createServer();
|
|
17
|
+
server.once('error', () => resolve(false));
|
|
18
|
+
server.once('listening', () => {
|
|
19
|
+
server.close();
|
|
20
|
+
resolve(true);
|
|
21
|
+
});
|
|
22
|
+
server.listen(port);
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
// Generate a random port between min and max, excluding common ports
|
|
26
|
+
const getRandomPort = async () => {
|
|
27
|
+
const commonPorts = [3000, 5000, 5173, 8000, 8080, 8888, 4200];
|
|
28
|
+
const min = 10000;
|
|
29
|
+
const max = 65535;
|
|
30
|
+
// Try up to 50 times to find a port
|
|
31
|
+
for (let i = 0; i < 50; i++) {
|
|
32
|
+
const port = Math.floor(Math.random() * (max - min + 1) + min);
|
|
33
|
+
if (!commonPorts.includes(port) && await isPortAvailable(port)) {
|
|
34
|
+
return port;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Fallback to 0 (let OS choose) if we can't find one, though OS might pick a common one (unlikely)
|
|
38
|
+
return 0;
|
|
39
|
+
};
|
|
12
40
|
const startServer = async (options, file) => {
|
|
13
|
-
|
|
41
|
+
let port;
|
|
42
|
+
if (options.port) {
|
|
43
|
+
port = parseInt(options.port, 10);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
port = await getRandomPort();
|
|
47
|
+
}
|
|
14
48
|
const host = options.host;
|
|
15
49
|
if (file) {
|
|
16
50
|
const absPath = path.resolve(file);
|
|
@@ -47,7 +81,7 @@ program
|
|
|
47
81
|
.version('1.0.6');
|
|
48
82
|
const attachServeOptions = (cmd) => {
|
|
49
83
|
cmd
|
|
50
|
-
.option('-p, --port <number>', 'server port'
|
|
84
|
+
.option('-p, --port <number>', 'server port')
|
|
51
85
|
.option('--host <string>', 'server host', 'localhost')
|
|
52
86
|
.argument('[file]', 'image file to open')
|
|
53
87
|
.action(async (file, options) => {
|