@qmuse/qmuse-cli 1.0.4 → 1.0.5-dev.2
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/api.js +4 -0
- package/dist/cli.js +58 -12
- package/dist/login.js +5 -10
- package/package.json +2 -1
package/dist/api.js
CHANGED
|
@@ -11,6 +11,10 @@ export function createSessionExchangeRequest(opts) {
|
|
|
11
11
|
export function consumeSessionExchangeToken(token, opts) {
|
|
12
12
|
return apiCall('POST', '/api/login/session-exchange/consume', { token }, { anonymous: true, ...opts });
|
|
13
13
|
}
|
|
14
|
+
/** 查询服务端实际登录身份,不触发 /api/user/me 的奖励和活跃副作用。 */
|
|
15
|
+
export function whoami(cfg) {
|
|
16
|
+
return apiCall('GET', '/api/user/whoami', undefined, cfg);
|
|
17
|
+
}
|
|
14
18
|
export function listSpaces(pageIndex = 1, pageSize = 20, cfg) {
|
|
15
19
|
const path = `/api/space/list?pageIndex=${pageIndex}&pageSize=${pageSize}`;
|
|
16
20
|
return apiCall('GET', path, undefined, cfg);
|
package/dist/cli.js
CHANGED
|
@@ -94,8 +94,7 @@ function output(value, flags) {
|
|
|
94
94
|
process.stdout.write(`${json}\n`);
|
|
95
95
|
}
|
|
96
96
|
function fail(message) {
|
|
97
|
-
|
|
98
|
-
process.exit(1);
|
|
97
|
+
throw new Error(message);
|
|
99
98
|
}
|
|
100
99
|
function requireAuth(cfg) {
|
|
101
100
|
if (!hasAuth(cfg)) {
|
|
@@ -619,18 +618,64 @@ async function cmdDev(command, flags) {
|
|
|
619
618
|
}
|
|
620
619
|
async function cmdWhoami(flags) {
|
|
621
620
|
const cfg = resolveCfg(flags);
|
|
621
|
+
const apiBaseUrl = `${cfg.baseUrl}${cfg.apiPrefix || ''}`;
|
|
622
|
+
if (!hasAuth(cfg)) {
|
|
623
|
+
if (flags['--json'] === true) {
|
|
624
|
+
output({
|
|
625
|
+
apiBaseUrl,
|
|
626
|
+
loggedIn: false,
|
|
627
|
+
...(cfg.spaceId ? { spaceId: cfg.spaceId } : {}),
|
|
628
|
+
}, flags);
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
log.info(`QMuse API: ${apiBaseUrl}`);
|
|
632
|
+
log.info('登录状态 : 未登录');
|
|
633
|
+
if (cfg.spaceId)
|
|
634
|
+
log.info(`本地空间 : ${cfg.spaceId}`);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const result = await api.whoami(cfg);
|
|
638
|
+
if (!result.ok || !result.data?.userId) {
|
|
639
|
+
if (result.status === 401) {
|
|
640
|
+
if (flags['--json'] === true) {
|
|
641
|
+
output({
|
|
642
|
+
apiBaseUrl,
|
|
643
|
+
loggedIn: false,
|
|
644
|
+
...(cfg.spaceId ? { spaceId: cfg.spaceId } : {}),
|
|
645
|
+
}, flags);
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
log.info(`QMuse API: ${apiBaseUrl}`);
|
|
649
|
+
log.info('登录状态 : 会话已失效');
|
|
650
|
+
if (cfg.spaceId)
|
|
651
|
+
log.info(`本地空间 : ${cfg.spaceId}`);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
fail(`查询当前用户失败: ${result.errorMessage ?? result.errorCode ?? `HTTP ${result.status}`}`);
|
|
655
|
+
}
|
|
656
|
+
const currentUser = result.data;
|
|
622
657
|
if (flags['--json'] === true) {
|
|
623
658
|
output({
|
|
624
|
-
apiBaseUrl
|
|
625
|
-
loggedIn:
|
|
626
|
-
|
|
659
|
+
apiBaseUrl,
|
|
660
|
+
loggedIn: true,
|
|
661
|
+
userId: currentUser.userId,
|
|
662
|
+
userName: currentUser.userName,
|
|
663
|
+
...(currentUser.avatarUrl ? { avatarUrl: currentUser.avatarUrl } : {}),
|
|
664
|
+
spaceId: currentUser.spaceId,
|
|
665
|
+
spaceName: currentUser.spaceName ?? null,
|
|
666
|
+
tenantCode: currentUser.tenantCode,
|
|
627
667
|
}, flags);
|
|
628
668
|
return;
|
|
629
669
|
}
|
|
630
|
-
log.info(`QMuse API: ${
|
|
631
|
-
log.info(
|
|
632
|
-
|
|
633
|
-
|
|
670
|
+
log.info(`QMuse API: ${apiBaseUrl}`);
|
|
671
|
+
log.info('登录状态 : 已登录');
|
|
672
|
+
log.info(`当前用户 : ${currentUser.userName} [${currentUser.userId}]`);
|
|
673
|
+
const spaceName = currentUser.spaceName?.trim();
|
|
674
|
+
const spaceLabel = currentUser.spaceId
|
|
675
|
+
? (spaceName ? `${spaceName} [${currentUser.spaceId}]` : currentUser.spaceId)
|
|
676
|
+
: '(无)';
|
|
677
|
+
log.info(`当前空间 : ${spaceLabel}`);
|
|
678
|
+
log.info(`业务租户 : ${currentUser.tenantCode ?? 'QMuse 默认'}`);
|
|
634
679
|
}
|
|
635
680
|
async function cmdConfig(command, flags) {
|
|
636
681
|
const sub = command[1];
|
|
@@ -821,10 +866,11 @@ async function main() {
|
|
|
821
866
|
const msg = err instanceof Error ? err.message : String(err);
|
|
822
867
|
if (flags['--json'] === true) {
|
|
823
868
|
output({ success: false, message: msg }, flags);
|
|
824
|
-
process.exitCode = 1;
|
|
825
869
|
}
|
|
826
|
-
else
|
|
827
|
-
|
|
870
|
+
else {
|
|
871
|
+
log.error(msg);
|
|
872
|
+
}
|
|
873
|
+
process.exitCode = 1;
|
|
828
874
|
}
|
|
829
875
|
finally {
|
|
830
876
|
finishUpdateNotice();
|
package/dist/login.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* QMuse 网页确认登录:服务端创建短期请求,浏览器确认后由 CLI 轮询换取会话。
|
|
3
3
|
*/
|
|
4
|
-
import { execFile } from 'node:child_process';
|
|
5
4
|
import { createInterface } from 'node:readline';
|
|
5
|
+
import open from 'open';
|
|
6
6
|
import * as api from './api.js';
|
|
7
7
|
import { buildUrl } from './client.js';
|
|
8
8
|
import { apiOrigin, loadConfig, saveSession } from './config.js';
|
|
@@ -52,10 +52,7 @@ export function closePrompt() {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
export function openBrowser(url) {
|
|
55
|
-
|
|
56
|
-
return new Promise(resolve => {
|
|
57
|
-
execFile(command, [url], error => resolve(!error));
|
|
58
|
-
});
|
|
55
|
+
return open(url, { wait: false }).then(() => true, () => false);
|
|
59
56
|
}
|
|
60
57
|
export function persistSession(sessionId, targetConfig = loadConfig()) {
|
|
61
58
|
const origin = apiOrigin(targetConfig.baseUrl);
|
|
@@ -103,11 +100,9 @@ export async function loginBrowser(cfg, options = {}, dependencyOverrides) {
|
|
|
103
100
|
log.info('正在打开 QMuse 登录页面...');
|
|
104
101
|
log.info(`确认码:${token.slice(-6).toUpperCase()}`);
|
|
105
102
|
if (!await dependencies.open(authUrl.toString())) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
message: '无法打开 QMuse 登录页面,请检查系统默认浏览器配置后重试',
|
|
110
|
-
};
|
|
103
|
+
log.warn('无法自动打开浏览器,请复制下面的一次性地址到浏览器中打开:');
|
|
104
|
+
log.raw(`${authUrl.toString()}\n`);
|
|
105
|
+
log.warn('该地址包含一次性登录凭证,请勿分享');
|
|
111
106
|
}
|
|
112
107
|
log.info('等待网页确认登录...');
|
|
113
108
|
const deadline = dependencies.now() + Math.min(SESSION_EXCHANGE_POLL_TIMEOUT_MS, expiresInSeconds * 1000);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qmuse/qmuse-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5-dev.2",
|
|
4
4
|
"description": "将本地 React 项目安全导入 QMuse 的命令行客户端",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@napi-rs/keyring": "2.0.0",
|
|
23
23
|
"ignore": "^7.0.8",
|
|
24
|
+
"open": "^11.0.4",
|
|
24
25
|
"semver": "7.7.4",
|
|
25
26
|
"yazl": "^3.3.1"
|
|
26
27
|
},
|