@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.
@@ -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
- info('==> 设备流登录');
46
- const code = await requestDeviceCode(api);
47
- info(` 请在浏览器打开(或扫码)并登录确认:`);
48
- info(` ${code.verificationUriComplete}`);
49
- info(` 授权码: ${code.userCode}`);
50
- const login = await pollDeviceLogin(api, code);
51
- info(`✔ 登录成功:${login.user.username}`);
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, login.accessToken, publicKey);
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, login.accessToken);
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, login.accessToken, {
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, login.accessToken);
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 ?? false);
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, login.accessToken, pluginId, signedBytes, opts.changelog);
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
- if (token)
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qomicex/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },