dsh-cloudq 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/lib/client.js +61 -9
- package/lib/index.js +5 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -30,6 +30,40 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
const PACKAGE_ID = "dsh-cloudq";
|
|
31
31
|
const STYLE_ID = "dsh-cloudq-styles";
|
|
32
32
|
const CSS = `
|
|
33
|
+
/* DSH signals dark mode through body[data-ds-dark-theme]; the --dsw-alias-*
|
|
34
|
+
tokens are intentionally only defined there so light mode keeps using the
|
|
35
|
+
per-usage fallbacks (pixel-identical), while dark mode resolves them here. */
|
|
36
|
+
body[data-ds-dark-theme] {
|
|
37
|
+
--dsw-alias-bg-card: #212123;
|
|
38
|
+
--dsw-alias-bg-inverse: #f2f3f5;
|
|
39
|
+
--dsw-alias-bg-layer-2: #262629;
|
|
40
|
+
--dsw-alias-bg-layer-3: #212123;
|
|
41
|
+
--dsw-alias-bg-sub: #1b1b1e;
|
|
42
|
+
--dsw-alias-border-l1: #2a2a2e;
|
|
43
|
+
--dsw-alias-border-l2: #343439;
|
|
44
|
+
--dsw-alias-button-elevated-fill: #2c2c31;
|
|
45
|
+
--dsw-alias-interactive-bg: rgba(91, 141, 239, .16);
|
|
46
|
+
--dsw-alias-interactive-bg-hover: #2a2b30;
|
|
47
|
+
--dsw-alias-interactive-border: #43434a;
|
|
48
|
+
--dsw-alias-label-inverse: #0f0f0f;
|
|
49
|
+
--dsw-alias-label-primary: #ecedf0;
|
|
50
|
+
--dsw-alias-label-secondary: #a4a7ad;
|
|
51
|
+
--dsw-alias-label-tertiary: #7e838b;
|
|
52
|
+
--dsw-alias-state-business-primary: #5b8def;
|
|
53
|
+
--dsw-alias-state-business-primary-bg: rgba(91, 141, 239, .16);
|
|
54
|
+
--dsw-alias-state-danger: #e5635c;
|
|
55
|
+
--dsw-alias-state-danger-bg: rgba(213, 73, 65, .18);
|
|
56
|
+
--dsw-alias-state-success-bg: rgba(34, 197, 94, .16);
|
|
57
|
+
--dsw-alias-state-success-text: #4ade80;
|
|
58
|
+
--dsw-alias-state-warning-bg: rgba(245, 158, 11, .16);
|
|
59
|
+
--dsw-alias-state-warning-text: #f2b04a;
|
|
60
|
+
}
|
|
61
|
+
body[data-ds-dark-theme] .dsh-cloudq-arch__preview {
|
|
62
|
+
background-color: #1b1b1e;
|
|
63
|
+
background-image:
|
|
64
|
+
linear-gradient(30deg, transparent 49.5%, #2c2c31 49.5%, #2c2c31 50.5%, transparent 50.5%),
|
|
65
|
+
linear-gradient(-30deg, transparent 49.5%, #2c2c31 49.5%, #2c2c31 50.5%, transparent 50.5%);
|
|
66
|
+
}
|
|
33
67
|
.dsh-cloudq-trigger {
|
|
34
68
|
display: inline-flex;
|
|
35
69
|
height: 30px;
|
|
@@ -1759,7 +1793,7 @@ grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
|
1759
1793
|
height: 260px;
|
|
1760
1794
|
overflow: hidden;
|
|
1761
1795
|
border: 1px solid var(--dsw-alias-border-l2, #e1e4e8);
|
|
1762
|
-
background: #fff;
|
|
1796
|
+
background: var(--dsw-alias-bg-card, #fff);
|
|
1763
1797
|
color: inherit;
|
|
1764
1798
|
text-decoration: none;
|
|
1765
1799
|
transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
|
|
@@ -1776,7 +1810,7 @@ grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
|
1776
1810
|
align-items: center;
|
|
1777
1811
|
justify-content: center;
|
|
1778
1812
|
overflow: hidden;
|
|
1779
|
-
background-color: #fff;
|
|
1813
|
+
background-color: var(--dsw-alias-bg-sub, #fff);
|
|
1780
1814
|
background-image:
|
|
1781
1815
|
linear-gradient(30deg, transparent 49.5%, #edf0f3 49.5%, #edf0f3 50.5%, transparent 50.5%),
|
|
1782
1816
|
linear-gradient(-30deg, transparent 49.5%, #edf0f3 49.5%, #edf0f3 50.5%, transparent 50.5%);
|
|
@@ -2134,7 +2168,7 @@ display: none;
|
|
|
2134
2168
|
hint.className = "dsh-cloudq-panel__hint";
|
|
2135
2169
|
hint.textContent = "正在加载用量…";
|
|
2136
2170
|
tableWrap.appendChild(hint);
|
|
2137
|
-
cloudqRequest(`${API_USAGE}?start=${encodeURIComponent(range.start)}&end=${encodeURIComponent(range.end)}`).then((data) => {
|
|
2171
|
+
requireCloudqCredential().then(() => cloudqRequest(`${API_USAGE}?start=${encodeURIComponent(range.start)}&end=${encodeURIComponent(range.end)}`)).then((data) => {
|
|
2138
2172
|
if (panelView !== "usage" || !panelExpanded) return;
|
|
2139
2173
|
value.textContent = formatCredits(data.overview?.TotalCredits);
|
|
2140
2174
|
const rows = Array.isArray(data.detail) ? data.detail : [];
|
|
@@ -2300,7 +2334,7 @@ display: none;
|
|
|
2300
2334
|
hint.className = "dsh-cloudq-panel__hint";
|
|
2301
2335
|
hint.textContent = "正在加载灵感…";
|
|
2302
2336
|
list.appendChild(hint);
|
|
2303
|
-
cloudqRequest(API_INSPIRATIONS).then((data) => {
|
|
2337
|
+
requireCloudqCredential().then(() => cloudqRequest(API_INSPIRATIONS)).then((data) => {
|
|
2304
2338
|
inspirationCache = Array.isArray(data.inspirations) ? data.inspirations : [];
|
|
2305
2339
|
paint(inspirationCache);
|
|
2306
2340
|
}).catch((error) => {
|
|
@@ -2442,7 +2476,7 @@ display: none;
|
|
|
2442
2476
|
hint.className = "dsh-cloudq-panel__hint";
|
|
2443
2477
|
hint.textContent = "正在加载制品…";
|
|
2444
2478
|
panelBody.appendChild(hint);
|
|
2445
|
-
cloudqRequest(API_ARTIFACTS).then((data) => {
|
|
2479
|
+
requireCloudqCredential().then(() => cloudqRequest(API_ARTIFACTS)).then((data) => {
|
|
2446
2480
|
artifactCache = Array.isArray(data?.sessions) ? data.sessions : [];
|
|
2447
2481
|
artifactTotal = Number(data?.total) || artifactCache.length;
|
|
2448
2482
|
paint(artifactCache, artifactTotal);
|
|
@@ -2742,7 +2776,7 @@ display: none;
|
|
|
2742
2776
|
paintDirectories(architectureDirectoriesCache, architectureFirstFolderId);
|
|
2743
2777
|
return;
|
|
2744
2778
|
}
|
|
2745
|
-
cloudqRequest(API_ARCH_DIRECTORIES).then((data) => {
|
|
2779
|
+
requireCloudqCredential().then(() => cloudqRequest(API_ARCH_DIRECTORIES)).then((data) => {
|
|
2746
2780
|
architectureDirectoriesCache = Array.isArray(data?.folders) ? data.folders : [];
|
|
2747
2781
|
architectureFirstFolderId = Number(data?.firstFolderId) || null;
|
|
2748
2782
|
paintDirectories(architectureDirectoriesCache, architectureFirstFolderId);
|
|
@@ -3041,14 +3075,32 @@ display: none;
|
|
|
3041
3075
|
this.code = code;
|
|
3042
3076
|
}
|
|
3043
3077
|
};
|
|
3078
|
+
const CLOUDQ_AUTH_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
3079
|
+
"NeedAuth",
|
|
3080
|
+
"CredentialExpired",
|
|
3081
|
+
"AuthFailure"
|
|
3082
|
+
]);
|
|
3044
3083
|
/**
|
|
3045
|
-
* Panel-facing error text.
|
|
3046
|
-
*
|
|
3084
|
+
* Panel-facing error text. Credential problems carry an actionable Host
|
|
3085
|
+
* message and are shown directly instead of a raw load failure prefix.
|
|
3047
3086
|
*/
|
|
3048
3087
|
function cloudqPanelErrorText(error, prefix) {
|
|
3049
|
-
if (error instanceof CloudQApiError && error.code
|
|
3088
|
+
if (error instanceof CloudQApiError && CLOUDQ_AUTH_ERROR_CODES.has(error.code)) return error.message;
|
|
3050
3089
|
return `${prefix}:${error instanceof Error ? error.message : "未知错误"}`;
|
|
3051
3090
|
}
|
|
3091
|
+
/**
|
|
3092
|
+
* Reject with an actionable NeedAuth error when no credential is configured,
|
|
3093
|
+
* so data views show the settings guide without calling the CloudQ APIs.
|
|
3094
|
+
* Returns undefined when the status check itself fails, letting the data
|
|
3095
|
+
* request surface its own error.
|
|
3096
|
+
*/
|
|
3097
|
+
function requireCloudqCredential() {
|
|
3098
|
+
return cloudqRequest(API_CREDENTIAL).then((response) => {
|
|
3099
|
+
if (response.status?.logged_in !== true) throw new CloudQApiError("尚未配置 AK/SK,请前往「设置 → 插件 → CloudQ」完成配置后重试。", "NeedAuth");
|
|
3100
|
+
}).catch((error) => {
|
|
3101
|
+
if (error instanceof CloudQApiError && error.code === "NeedAuth") throw error;
|
|
3102
|
+
});
|
|
3103
|
+
}
|
|
3052
3104
|
async function cloudqRequest(url, init, timeoutMs = 2e4) {
|
|
3053
3105
|
const controller = new AbortController();
|
|
3054
3106
|
const timeout = window.setTimeout(() => controller.abort(), timeoutMs);
|
package/lib/index.js
CHANGED
|
@@ -424,7 +424,11 @@ async function runScript(scriptName, args, options) {
|
|
|
424
424
|
try {
|
|
425
425
|
return await runScript$1(resolve(skillDirectory(), "scripts"), scriptName, args, options);
|
|
426
426
|
} catch (error) {
|
|
427
|
-
if (error instanceof HttpError
|
|
427
|
+
if (error instanceof HttpError) {
|
|
428
|
+
if (error.code === "NeedAuth") throw new HttpError(401, "NeedAuth", "尚未配置 AK/SK,请前往「设置 → 插件 → CloudQ」完成配置。");
|
|
429
|
+
if (error.code === "CredentialExpired") throw new HttpError(401, "CredentialExpired", "凭证已过期,请前往「设置 → 插件 → CloudQ」重新配置。");
|
|
430
|
+
if (typeof error.code === "string" && error.code.startsWith("AuthFailure")) throw new HttpError(401, "AuthFailure", "AK/SK 无效或权限不足,请前往「设置 → 插件 → CloudQ」检查配置。");
|
|
431
|
+
}
|
|
428
432
|
throw error;
|
|
429
433
|
}
|
|
430
434
|
}
|