@qomicex/cli 0.1.3 → 0.1.5
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/dist/commands/publish.js +21 -14
- package/dist/index.js +3 -1
- package/dist/lib/store.js +4 -1
- package/package.json +1 -1
package/dist/commands/publish.js
CHANGED
|
@@ -40,18 +40,25 @@ export async function publishCommand(opts = {}) {
|
|
|
40
40
|
// 清掉旧签名文件,避免脏残留
|
|
41
41
|
for (const k of ['signature.json', 'signature.cert.json'])
|
|
42
42
|
delete entries[k];
|
|
43
|
-
// 3)
|
|
43
|
+
// 3) 认证:QOMICEX_API_KEY 存在则跳过设备流(CI 场景),否则设备流登录
|
|
44
44
|
const api = opts.api ?? process.env.QOMICEX_STORE_API ?? DEFAULT_API_BASE;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
let token = '';
|
|
46
|
+
if (process.env.QOMICEX_API_KEY) {
|
|
47
|
+
info('==> 使用 API Key 认证(CI 模式)');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
info('==> 设备流登录');
|
|
51
|
+
const code = await requestDeviceCode(api);
|
|
52
|
+
info(` 请在浏览器打开(或扫码)并登录确认:`);
|
|
53
|
+
info(` ${code.verificationUriComplete}`);
|
|
54
|
+
info(` 授权码: ${code.userCode}`);
|
|
55
|
+
const login = await pollDeviceLogin(api, code);
|
|
56
|
+
token = login.accessToken;
|
|
57
|
+
info(`✔ 登录成功:${login.user.username}`);
|
|
58
|
+
}
|
|
52
59
|
// 4) 注册/刷新签名公钥,获取商店根钥签发的证书
|
|
53
60
|
info('==> 注册签名公钥');
|
|
54
|
-
const keyRes = await registerDevKey(api,
|
|
61
|
+
const keyRes = await registerDevKey(api, token, publicKey);
|
|
55
62
|
const certJson = JSON.stringify(keyRes.cert);
|
|
56
63
|
info(`✔ 签名证书就绪(keyId: ${keyRes.keyId})`);
|
|
57
64
|
// 5) 签名
|
|
@@ -61,7 +68,7 @@ export async function publishCommand(opts = {}) {
|
|
|
61
68
|
// 6) 查找/创建插件记录
|
|
62
69
|
info('==> 确认插件记录');
|
|
63
70
|
let pluginId = '';
|
|
64
|
-
const mine = await fetchMinePlugins(api,
|
|
71
|
+
const mine = await fetchMinePlugins(api, token);
|
|
65
72
|
const existing = mine.find((p) => p.slug === slug);
|
|
66
73
|
if (existing) {
|
|
67
74
|
pluginId = existing.id;
|
|
@@ -69,7 +76,7 @@ export async function publishCommand(opts = {}) {
|
|
|
69
76
|
}
|
|
70
77
|
else {
|
|
71
78
|
try {
|
|
72
|
-
const created = await createPlugin(api,
|
|
79
|
+
const created = await createPlugin(api, token, {
|
|
73
80
|
slug,
|
|
74
81
|
name: String(manifest.name ?? slug),
|
|
75
82
|
description: String(manifest.description ?? ''),
|
|
@@ -80,7 +87,7 @@ export async function publishCommand(opts = {}) {
|
|
|
80
87
|
}
|
|
81
88
|
catch (e) {
|
|
82
89
|
if (e instanceof StoreApiError && e.status === 409) {
|
|
83
|
-
const again = await fetchMinePlugins(api,
|
|
90
|
+
const again = await fetchMinePlugins(api, token);
|
|
84
91
|
const found = again.find((p) => p.slug === slug);
|
|
85
92
|
if (!found)
|
|
86
93
|
throw e;
|
|
@@ -98,13 +105,13 @@ export async function publishCommand(opts = {}) {
|
|
|
98
105
|
info(` 插件: ${slug} v${version}`);
|
|
99
106
|
info(` keyId: ${keyRes.keyId}`);
|
|
100
107
|
info(` 包体: ${signedBytes.length} 字节(已签名)`);
|
|
101
|
-
const ok = await confirm('确认发布到商店?', opts.yes ??
|
|
108
|
+
const ok = await confirm('确认发布到商店?', opts.yes ?? !!process.env.QOMICEX_API_KEY);
|
|
102
109
|
if (!ok) {
|
|
103
110
|
warn('已取消发布');
|
|
104
111
|
return;
|
|
105
112
|
}
|
|
106
113
|
info('==> 上传版本');
|
|
107
|
-
const result = await uploadVersion(api,
|
|
114
|
+
const result = await uploadVersion(api, token, pluginId, signedBytes, opts.changelog);
|
|
108
115
|
info(`✔ 上传完成:${slug} v${version}`);
|
|
109
116
|
info(` 商店地址: ${api.replace('/api/v1', '')}`);
|
|
110
117
|
if (typeof result === 'object' && result && 'status' in result) {
|
package/dist/index.js
CHANGED
|
@@ -54,13 +54,14 @@ qomicex v${VERSION} — Qomicex 插件生态 CLI
|
|
|
54
54
|
manifest 合法性 + 权限最小化 + 长循环告警 + 签名检查
|
|
55
55
|
qomicex bump <major|minor|patch> [--version <v>]
|
|
56
56
|
递增 manifest.json 版本号(或 --version 直接指定)
|
|
57
|
-
qomicex publish [--key <k>] [--slug <s>] [--changelog <c>] [--api <url>] [--org-id <id>] [--package <f>] [--yes]
|
|
57
|
+
qomicex publish [--key <k>] [--slug <s>] [--changelog <c>] [--api <url>] [--org-id <id>] [--package <f>] [--skip-build] [--yes]
|
|
58
58
|
设备流登录 → 注册签名公钥 → 签名 → 上传到商店
|
|
59
59
|
qomicex --help | -h 显示帮助
|
|
60
60
|
qomicex --version | -v 显示版本
|
|
61
61
|
|
|
62
62
|
环境变量:
|
|
63
63
|
QOMICEX_SIGN_KEY 签名私钥(PKCS#8 PEM 或 raw base64 seed),publish 必填
|
|
64
|
+
QOMICEX_API_KEY 商店 API Key(CI 模式下跳过设备流登录,自动确认上传)
|
|
64
65
|
QOMICEX_STORE_API 商店 API base(默认 https://plugins.qomicex.top/api/v1)
|
|
65
66
|
`;
|
|
66
67
|
}
|
|
@@ -109,6 +110,7 @@ async function main() {
|
|
|
109
110
|
orgId: typeof options['org-id'] === 'string' ? options['org-id'] : undefined,
|
|
110
111
|
package: typeof options['package'] === 'string' ? options['package'] : undefined,
|
|
111
112
|
yes: options['yes'] === true,
|
|
113
|
+
skipBuild: options['skip-build'] === true,
|
|
112
114
|
});
|
|
113
115
|
break;
|
|
114
116
|
default:
|
package/dist/lib/store.js
CHANGED
|
@@ -13,7 +13,10 @@ export class StoreApiError extends Error {
|
|
|
13
13
|
}
|
|
14
14
|
async function request(base, path, init, token) {
|
|
15
15
|
const headers = new Headers(init?.headers);
|
|
16
|
-
|
|
16
|
+
const apiKey = process.env.QOMICEX_API_KEY;
|
|
17
|
+
if (apiKey)
|
|
18
|
+
headers.set('X-API-Key', apiKey);
|
|
19
|
+
else if (token)
|
|
17
20
|
headers.set('Authorization', `Bearer ${token}`);
|
|
18
21
|
let res;
|
|
19
22
|
try {
|