dsh-provider-qoder 0.4.3 → 0.5.0
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/README.md +12 -8
- package/README_CN.md +12 -8
- package/lib/client.js +883 -219
- package/lib/index.d.ts +63 -24
- package/lib/index.js +2142 -357
- package/package.json +3 -1
package/lib/client.js
CHANGED
|
@@ -5,6 +5,7 @@ window.__ModuleLoader__.load({
|
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
8
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
10
|
//#region src/dsh/credential-contract.ts
|
|
10
11
|
/** Shared DSH host/browser contract for the one managed Qoder credential. */
|
|
@@ -14,6 +15,172 @@ window.__ModuleLoader__.load({
|
|
|
14
15
|
return source === "env" || source?.endsWith("-env") === true;
|
|
15
16
|
}
|
|
16
17
|
//#endregion
|
|
18
|
+
//#region src/client/queue-status.ts
|
|
19
|
+
/** Match DSH's running status clock: whole hours, minutes and seconds. */
|
|
20
|
+
function formatQueueDuration(ms, t) {
|
|
21
|
+
const total = Math.max(0, Math.floor(ms / 1e3));
|
|
22
|
+
const hours = Math.floor(total / 3600);
|
|
23
|
+
const minutes = Math.floor(total / 60) % 60;
|
|
24
|
+
const seconds = total % 60;
|
|
25
|
+
return (hours > 0 ? `${hours}${t("queueHourUnit")}` : "") + (total >= 60 ? `${minutes}${t("queueMinuteUnit")}` : "") + `${seconds}${t("queueSecondUnit")}`;
|
|
26
|
+
}
|
|
27
|
+
function parseQueueSnapshots(value, sessionId) {
|
|
28
|
+
if (!Array.isArray(value) || value.length > 256) throw new Error("Invalid queue snapshots");
|
|
29
|
+
return value.map((item) => {
|
|
30
|
+
if (!item || typeof item !== "object" || item.sessionId !== sessionId || typeof item.callId !== "string" || !item.callId || typeof item.model !== "string" || item.modelName !== void 0 && (typeof item.modelName !== "string" || !item.modelName.trim()) || ![
|
|
31
|
+
"waitElapsedMs",
|
|
32
|
+
"maxWaitMs",
|
|
33
|
+
"updatedAt"
|
|
34
|
+
].every((key) => typeof item[key] === "number" && Number.isFinite(item[key]) && item[key] >= 0) || !["queueCount", "waitTimeMs"].every((key) => item[key] === void 0 || typeof item[key] === "number" && Number.isFinite(item[key]) && item[key] >= 0)) throw new Error("Invalid queue snapshot");
|
|
35
|
+
return item;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function watchQueueStatus(rpc, sessionId, visibility, changed) {
|
|
39
|
+
let disposed = false;
|
|
40
|
+
let generation = 0;
|
|
41
|
+
let timer;
|
|
42
|
+
let active;
|
|
43
|
+
let items = [];
|
|
44
|
+
const poll = async () => {
|
|
45
|
+
if (disposed || visibility.hidden || active) return;
|
|
46
|
+
const revision = generation;
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
active = controller;
|
|
49
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
50
|
+
try {
|
|
51
|
+
const result = await rpc.call("queue", { sessionId }, controller.signal);
|
|
52
|
+
if (disposed || revision !== generation) return;
|
|
53
|
+
if (!result.ok) throw new Error("Queue status unavailable");
|
|
54
|
+
items = parseQueueSnapshots(result.value, sessionId);
|
|
55
|
+
changed({
|
|
56
|
+
items,
|
|
57
|
+
unavailable: false
|
|
58
|
+
});
|
|
59
|
+
} catch {
|
|
60
|
+
if (!disposed && revision === generation) changed({
|
|
61
|
+
items,
|
|
62
|
+
unavailable: true
|
|
63
|
+
});
|
|
64
|
+
} finally {
|
|
65
|
+
clearTimeout(timeout);
|
|
66
|
+
if (active === controller) active = void 0;
|
|
67
|
+
if (!disposed && revision === generation && !visibility.hidden) timer = setTimeout(() => {
|
|
68
|
+
poll();
|
|
69
|
+
}, 1e3);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const stop = () => {
|
|
73
|
+
generation++;
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
active?.abort();
|
|
76
|
+
active = void 0;
|
|
77
|
+
};
|
|
78
|
+
const onVisibility = () => {
|
|
79
|
+
stop();
|
|
80
|
+
if (!visibility.hidden) poll();
|
|
81
|
+
};
|
|
82
|
+
visibility.addEventListener("visibilitychange", onVisibility);
|
|
83
|
+
poll();
|
|
84
|
+
return () => {
|
|
85
|
+
disposed = true;
|
|
86
|
+
stop();
|
|
87
|
+
visibility.removeEventListener("visibilitychange", onVisibility);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region \0dsh-css:/home/runner/work/dsh-provider-qoder/dsh-provider-qoder/src/client/QoderQueueStatus.module.css.mjs
|
|
92
|
+
const css$2 = "._8MdOdG_queues{box-sizing:border-box;width:calc(100% - 2 * var(--dsh-composer-side-clearance,16px) - 2 * var(--dsh-composer-dock-inset,8px));max-width:calc(var(--dsh-composer-card-max-width,952px) - 2 * var(--dsh-composer-dock-inset,8px));padding:0 var(--dsh-composer-dock-inset,8px);--dsw-alias-label-shimmer:var(--dsw-alias-label-deep-diving-shimmer);color:var(--dsw-alias-label-deep-diving,#4d6bfe);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(22px + var(--dsh-content-font-delta,0px));flex:none;margin:0 auto}._8MdOdG_panel{isolation:isolate;border-radius:var(--dsw-radius-lg,16px);width:100%;padding:2px 0;position:relative;overflow:hidden}._8MdOdG_panel:before{z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-1,#242629));backdrop-filter:var(--dsw-menu-backdrop-filter,none);content:\"\";pointer-events:none;position:absolute;inset:0}._8MdOdG_panel:after{border:.5px solid var(--dsw-alias-border-l1,#42454a);border-radius:inherit;content:\"\";pointer-events:none;position:absolute;inset:0}._8MdOdG_row{min-width:0}._8MdOdG_row+._8MdOdG_row{box-shadow:inset 0 1px 0 var(--dsw-alias-border-l1,#42454a)}._8MdOdG_row[data-unavailable]{color:var(--dsw-alias-label-secondary)}._8MdOdG_summary{box-sizing:border-box;cursor:pointer;align-items:center;gap:10px;width:100%;min-width:0;min-height:36px;padding:7px 12px;list-style:none;display:flex}._8MdOdG_summary::-webkit-details-marker{display:none}._8MdOdG_summary:focus-visible{outline-offset:-2px;border-radius:var(--dsw-radius-md,8px);outline:2px solid}._8MdOdG_icon{flex:none;width:14px;height:14px}._8MdOdG_text{font-variant-numeric:tabular-nums;overflow-wrap:anywhere;flex:1;min-width:0}._8MdOdG_chevron{width:6px;height:6px;color:var(--dsw-alias-label-tertiary);border-bottom:1.5px solid;border-right:1.5px solid;flex:none;margin:0 3px 3px;transform:rotate(45deg)}._8MdOdG_row>details[open] ._8MdOdG_chevron{margin-bottom:-3px;transform:rotate(225deg)}._8MdOdG_details{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:2px 16px;padding:0 12px 10px 36px;display:flex}._8MdOdG_visuallyHidden{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}";
|
|
93
|
+
const tagId$2 = "dsh-provider-qoder/QoderQueueStatus.module.css";
|
|
94
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
95
|
+
const tag = document.createElement("style");
|
|
96
|
+
tag.dataset.plugin = "dsh-provider-qoder";
|
|
97
|
+
tag.dataset.pluginCss = tagId$2;
|
|
98
|
+
tag.textContent = css$2;
|
|
99
|
+
document.head.appendChild(tag);
|
|
100
|
+
}
|
|
101
|
+
var QoderQueueStatus_module_css_default = {
|
|
102
|
+
"chevron": "_8MdOdG_chevron",
|
|
103
|
+
"details": "_8MdOdG_details",
|
|
104
|
+
"icon": "_8MdOdG_icon",
|
|
105
|
+
"panel": "_8MdOdG_panel",
|
|
106
|
+
"queues": "_8MdOdG_queues",
|
|
107
|
+
"row": "_8MdOdG_row",
|
|
108
|
+
"summary": "_8MdOdG_summary",
|
|
109
|
+
"text": "_8MdOdG_text",
|
|
110
|
+
"visuallyHidden": "_8MdOdG_visuallyHidden"
|
|
111
|
+
};
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/client/QoderQueueStatus.tsx
|
|
114
|
+
function QueueRow({ item, unavailable, t }) {
|
|
115
|
+
const elapsed = Math.min(item.maxWaitMs, item.waitElapsedMs + Math.max(0, Date.now() - item.updatedAt));
|
|
116
|
+
const name = item.modelName ?? item.model;
|
|
117
|
+
const status = unavailable ? t("queueUnavailable") : t("queueWaiting", { model: name });
|
|
118
|
+
const label = unavailable ? status : t("queueRunningFor", {
|
|
119
|
+
model: name,
|
|
120
|
+
duration: formatQueueDuration(elapsed, t)
|
|
121
|
+
});
|
|
122
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
123
|
+
className: QoderQueueStatus_module_css_default.row,
|
|
124
|
+
"data-unavailable": unavailable || void 0,
|
|
125
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
126
|
+
className: QoderQueueStatus_module_css_default.visuallyHidden,
|
|
127
|
+
role: "status",
|
|
128
|
+
"aria-live": "polite",
|
|
129
|
+
"aria-atomic": "true",
|
|
130
|
+
children: status
|
|
131
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
|
|
132
|
+
className: QoderQueueStatus_module_css_default.summary,
|
|
133
|
+
"aria-label": status,
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconQueueOutlineRegular, {
|
|
136
|
+
className: QoderQueueStatus_module_css_default.icon,
|
|
137
|
+
"aria-hidden": "true"
|
|
138
|
+
}),
|
|
139
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
140
|
+
active: !unavailable,
|
|
141
|
+
className: QoderQueueStatus_module_css_default.text,
|
|
142
|
+
"aria-hidden": "true",
|
|
143
|
+
children: label
|
|
144
|
+
}),
|
|
145
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
146
|
+
className: QoderQueueStatus_module_css_default.chevron,
|
|
147
|
+
"aria-hidden": "true"
|
|
148
|
+
})
|
|
149
|
+
]
|
|
150
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
151
|
+
className: QoderQueueStatus_module_css_default.details,
|
|
152
|
+
children: [
|
|
153
|
+
item.queueCount !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueCount", { count: item.queueCount }) }),
|
|
154
|
+
item.waitTimeMs !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueEstimate", { seconds: Math.ceil(item.waitTimeMs / 1e3) }) }),
|
|
155
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueBudget", { seconds: Math.ceil(item.maxWaitMs / 1e3) }) }),
|
|
156
|
+
item.serviceAvailable === false && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("queueServiceUnavailable") })
|
|
157
|
+
]
|
|
158
|
+
})] })]
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/** A provider contribution in DSH's input dock, using its shared process-row primitives. */
|
|
162
|
+
function QoderQueueStatus({ sessionId, rpc, t }) {
|
|
163
|
+
const [view, setView] = (0, react.useState)();
|
|
164
|
+
(0, react.useEffect)(() => watchQueueStatus(rpc, sessionId, document, (state) => setView({
|
|
165
|
+
sessionId,
|
|
166
|
+
state
|
|
167
|
+
})), [rpc, sessionId]);
|
|
168
|
+
const state = view?.sessionId === sessionId ? view.state : void 0;
|
|
169
|
+
if (!state?.items.length) return null;
|
|
170
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
171
|
+
className: QoderQueueStatus_module_css_default.queues,
|
|
172
|
+
"aria-label": t("queueTitle"),
|
|
173
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
174
|
+
className: QoderQueueStatus_module_css_default.panel,
|
|
175
|
+
children: state.items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QueueRow, {
|
|
176
|
+
item,
|
|
177
|
+
unavailable: state.unavailable,
|
|
178
|
+
t
|
|
179
|
+
}, item.callId))
|
|
180
|
+
})
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
17
184
|
//#region src/qoder/catalog.ts
|
|
18
185
|
function positiveNumber(value) {
|
|
19
186
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
@@ -170,6 +337,61 @@ window.__ModuleLoader__.load({
|
|
|
170
337
|
//#endregion
|
|
171
338
|
//#region src/client/locales.ts
|
|
172
339
|
const zh = {
|
|
340
|
+
accountConnectionTitle: "Qoder 账号",
|
|
341
|
+
signInDescription: "登录 Qoder,使用当前区域的订阅和模型。",
|
|
342
|
+
manageAccount: "管理账号",
|
|
343
|
+
manageCredential: "管理凭据",
|
|
344
|
+
changeAccount: "更换账号",
|
|
345
|
+
editPat: "编辑 PAT",
|
|
346
|
+
patActive: "正在使用 PAT",
|
|
347
|
+
saveAndUsePat: "保存并使用 PAT",
|
|
348
|
+
useSavedPat: "使用已保存的 PAT",
|
|
349
|
+
signInAgain: "重新登录",
|
|
350
|
+
reopenLogin: "重新打开官网",
|
|
351
|
+
loginLinkCopied: "链接已复制",
|
|
352
|
+
loginTimeRemaining: "链接剩余有效时间:{seconds} 秒",
|
|
353
|
+
regionChanged: "已切换服务区域;原区域如有未完成的登录,已取消。",
|
|
354
|
+
regionChangeFailed: "服务区域切换失败,请重试。",
|
|
355
|
+
browserRejected: "Qoder 未完成授权,请重新登录。",
|
|
356
|
+
browserStorageFailed: "官网授权已完成,但凭据保存失败。请检查存储后重新登录。",
|
|
357
|
+
authorizationConnectionFailed: "暂时无法连接或读取登录状态,请稍后重试。",
|
|
358
|
+
patSaveFailed: "PAT 保存或启用失败,请重试。",
|
|
359
|
+
browserRemoveFailed: "浏览器授权移除失败,请检查凭据存储是否可写后重试。",
|
|
360
|
+
browserLoginTitle: "Qoder 官网登录",
|
|
361
|
+
browserMethod: "浏览器授权",
|
|
362
|
+
savedBrowserAccount: "已保存的浏览器账号",
|
|
363
|
+
patMethod: "PAT 鉴权",
|
|
364
|
+
signedOut: "未连接",
|
|
365
|
+
sharedAuthorization: "当前区域的账号由所有连接此 DSH 实例的客户端共享。",
|
|
366
|
+
signInQoder: "通过 Qoder 登录",
|
|
367
|
+
signOutQoder: "移除浏览器授权",
|
|
368
|
+
usePat: "使用 PAT",
|
|
369
|
+
useBrowser: "使用已保存的浏览器授权",
|
|
370
|
+
cancelLogin: "取消登录",
|
|
371
|
+
openLogin: "打开登录页面",
|
|
372
|
+
copyLogin: "复制登录链接",
|
|
373
|
+
copyLoginFailed: "无法复制,请使用“打开登录页面”。",
|
|
374
|
+
browserWaiting: "等待在 Qoder 官网完成验证与授权…",
|
|
375
|
+
browserSaving: "正在保存授权…",
|
|
376
|
+
browserComplete: "已登录。",
|
|
377
|
+
browserCancelled: "登录已取消。",
|
|
378
|
+
browserTimeout: "登录链接已过期,请重新发起登录。",
|
|
379
|
+
browserFailed: "登录未完成,或授权保存失败。请检查账号状态后重试。",
|
|
380
|
+
browserExpired: "浏览器授权已失效,请重新登录。",
|
|
381
|
+
browserUnsaved: "续期凭据尚未保存,重启后可能需要重新登录;下次使用时将重试保存。",
|
|
382
|
+
browserOperationFailed: "无法更新登录状态,请重试。",
|
|
383
|
+
queueTitle: "Qoder 模型排队",
|
|
384
|
+
queueWaiting: "{model} 正在排队",
|
|
385
|
+
queueRunningFor: "{model} 正在排队,用时 {duration} ···",
|
|
386
|
+
queueHourUnit: "小时",
|
|
387
|
+
queueMinuteUnit: "分",
|
|
388
|
+
queueSecondUnit: "秒",
|
|
389
|
+
queueCount: "排队数量:{count}",
|
|
390
|
+
queueEstimate: "预计等待 {seconds} 秒",
|
|
391
|
+
queueElapsed: "已等待 {seconds} 秒",
|
|
392
|
+
queueUnavailable: "Qoder 排队状态暂不可用",
|
|
393
|
+
queueServiceUnavailable: "服务暂不可用,继续等待",
|
|
394
|
+
queueBudget: "等待上限 {seconds} 秒",
|
|
173
395
|
nav: "Qoder",
|
|
174
396
|
title: "Qoder 凭据",
|
|
175
397
|
configured: "已配置",
|
|
@@ -183,7 +405,7 @@ window.__ModuleLoader__.load({
|
|
|
183
405
|
regionGlobal: "国际版 (Global)",
|
|
184
406
|
regionChina: "中国区 (CN)",
|
|
185
407
|
regionHint: "请确保 PAT 与所选服务区域匹配。",
|
|
186
|
-
tokenLabel: "
|
|
408
|
+
tokenLabel: "Personal Access Token (PAT)",
|
|
187
409
|
tokenPlaceholder: "输入新的 Personal Access Token",
|
|
188
410
|
configuredHint: "已配置——输入新值可替换",
|
|
189
411
|
readOnly: "当前凭据存储不可写。",
|
|
@@ -218,7 +440,7 @@ window.__ModuleLoader__.load({
|
|
|
218
440
|
accountTitle: "Qoder",
|
|
219
441
|
accountLoading: "正在读取账号与额度…",
|
|
220
442
|
accountFailed: "无法读取账号信息与额度。",
|
|
221
|
-
accountCredentialHint: "
|
|
443
|
+
accountCredentialHint: "请先在“模型”设置中登录 Qoder 或选择已配置的 PAT。",
|
|
222
444
|
refresh: "刷新",
|
|
223
445
|
refreshing: "正在刷新…",
|
|
224
446
|
userQuotaTitle: "个人额度",
|
|
@@ -242,6 +464,61 @@ window.__ModuleLoader__.load({
|
|
|
242
464
|
searchModeHint: "智能路由模式下,使用 Qoder 模型时走 Qoder 搜索,使用其他模型时自动回退给备用搜索。"
|
|
243
465
|
};
|
|
244
466
|
const en = {
|
|
467
|
+
accountConnectionTitle: "Qoder account",
|
|
468
|
+
signInDescription: "Sign in to use your subscription and models for this region.",
|
|
469
|
+
manageAccount: "Manage account",
|
|
470
|
+
manageCredential: "Manage credentials",
|
|
471
|
+
changeAccount: "Change account",
|
|
472
|
+
editPat: "Edit PAT",
|
|
473
|
+
patActive: "Using PAT",
|
|
474
|
+
saveAndUsePat: "Save and use PAT",
|
|
475
|
+
useSavedPat: "Use saved PAT",
|
|
476
|
+
signInAgain: "Sign in again",
|
|
477
|
+
reopenLogin: "Reopen Qoder website",
|
|
478
|
+
loginLinkCopied: "Link copied",
|
|
479
|
+
loginTimeRemaining: "Link expires in {seconds} seconds",
|
|
480
|
+
regionChanged: "Region changed; any unfinished sign-in for the previous region was cancelled.",
|
|
481
|
+
regionChangeFailed: "Could not change region. Please retry.",
|
|
482
|
+
browserRejected: "Qoder authorization was not completed. Sign in again.",
|
|
483
|
+
browserStorageFailed: "Website authorization completed, but credentials could not be saved. Check storage and sign in again.",
|
|
484
|
+
authorizationConnectionFailed: "Could not connect or read sign-in status. Please retry shortly.",
|
|
485
|
+
patSaveFailed: "Could not save or activate the PAT. Please retry.",
|
|
486
|
+
browserRemoveFailed: "Could not remove browser authorization. Check that credential storage is writable and retry.",
|
|
487
|
+
browserLoginTitle: "Qoder website sign-in",
|
|
488
|
+
browserMethod: "Browser authorization",
|
|
489
|
+
savedBrowserAccount: "Saved browser account",
|
|
490
|
+
patMethod: "PAT authentication",
|
|
491
|
+
signedOut: "Disconnected",
|
|
492
|
+
sharedAuthorization: "The account for this region is shared by all clients connected to this DSH instance.",
|
|
493
|
+
signInQoder: "Sign in with Qoder",
|
|
494
|
+
signOutQoder: "Remove browser authorization",
|
|
495
|
+
usePat: "Use PAT",
|
|
496
|
+
useBrowser: "Use saved browser authorization",
|
|
497
|
+
cancelLogin: "Cancel sign-in",
|
|
498
|
+
openLogin: "Open sign-in page",
|
|
499
|
+
copyLogin: "Copy sign-in link",
|
|
500
|
+
copyLoginFailed: "Could not copy. Use Open sign-in page.",
|
|
501
|
+
browserWaiting: "Complete verification and authorization on the Qoder website…",
|
|
502
|
+
browserSaving: "Saving authorization…",
|
|
503
|
+
browserComplete: "Signed in.",
|
|
504
|
+
browserCancelled: "Sign-in cancelled.",
|
|
505
|
+
browserTimeout: "Sign-in link expired. Start a new sign-in.",
|
|
506
|
+
browserFailed: "Sign-in or saving authorization failed. Check account status and retry.",
|
|
507
|
+
browserExpired: "Browser authorization expired. Sign in again.",
|
|
508
|
+
browserUnsaved: "Renewed credentials have not been saved. Restarting may require sign-in; saving will be retried on next use.",
|
|
509
|
+
browserOperationFailed: "Could not update sign-in status. Please retry.",
|
|
510
|
+
queueTitle: "Qoder model queue",
|
|
511
|
+
queueWaiting: "{model} is queued",
|
|
512
|
+
queueRunningFor: "{model} queued for {duration} ···",
|
|
513
|
+
queueHourUnit: "h",
|
|
514
|
+
queueMinuteUnit: "m",
|
|
515
|
+
queueSecondUnit: "s",
|
|
516
|
+
queueCount: "Queue count: {count}",
|
|
517
|
+
queueEstimate: "Estimated wait: {seconds}s",
|
|
518
|
+
queueElapsed: "Waited {seconds}s",
|
|
519
|
+
queueUnavailable: "Qoder queue status is temporarily unavailable",
|
|
520
|
+
queueServiceUnavailable: "Service unavailable; waiting",
|
|
521
|
+
queueBudget: "Wait limit: {seconds}s",
|
|
245
522
|
nav: "Qoder",
|
|
246
523
|
title: "Qoder credential",
|
|
247
524
|
configured: "Configured",
|
|
@@ -255,7 +532,7 @@ window.__ModuleLoader__.load({
|
|
|
255
532
|
regionGlobal: "Global",
|
|
256
533
|
regionChina: "China (CN)",
|
|
257
534
|
regionHint: "Ensure your PAT matches the selected service region.",
|
|
258
|
-
tokenLabel: "
|
|
535
|
+
tokenLabel: "Personal Access Token (PAT)",
|
|
259
536
|
tokenPlaceholder: "Enter a new Personal Access Token",
|
|
260
537
|
configuredHint: "Configured — enter a new value to replace",
|
|
261
538
|
readOnly: "The current credential store is read-only.",
|
|
@@ -290,7 +567,7 @@ window.__ModuleLoader__.load({
|
|
|
290
567
|
accountTitle: "Qoder",
|
|
291
568
|
accountLoading: "Reading account and quota…",
|
|
292
569
|
accountFailed: "Could not read account details or quota.",
|
|
293
|
-
accountCredentialHint: "
|
|
570
|
+
accountCredentialHint: "Sign in to Qoder or select a configured PAT in Models settings first.",
|
|
294
571
|
refresh: "Refresh",
|
|
295
572
|
refreshing: "Refreshing…",
|
|
296
573
|
userQuotaTitle: "Personal Quota",
|
|
@@ -505,7 +782,7 @@ window.__ModuleLoader__.load({
|
|
|
505
782
|
};
|
|
506
783
|
//#endregion
|
|
507
784
|
//#region \0dsh-css:/home/runner/work/dsh-provider-qoder/dsh-provider-qoder/src/client/QoderCredentialCard.module.css.mjs
|
|
508
|
-
const css$1 = ".SRqrhW_credential{color:var(--dsw-alias-label-primary);border-radius:10px;margin-top:12px}.SRqrhW_credential p{margin:8px 0 0}.SRqrhW_credentialEditor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.SRqrhW_credentialRowHead{align-items:center;gap:10px;display:flex}.SRqrhW_credentialIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.SRqrhW_credentialName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.SRqrhW_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.SRqrhW_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.SRqrhW_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.SRqrhW_regionBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px;display:inline-flex}.SRqrhW_regionSelector{flex-direction:column;gap:8px;margin-bottom:14px;display:flex}.SRqrhW_regionGroup{gap:8px;display:flex}.SRqrhW_regionOption{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);user-select:none;border-radius:8px;align-items:center;gap:6px;padding:6px 12px;font-size:12px;line-height:18px;transition:all .12s;display:inline-flex}.SRqrhW_regionOption:hover:not(.SRqrhW_regionOptionDisabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.SRqrhW_credential button.SRqrhW_regionOptionActive{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);color:var(--dsw-alias-brand-primary);font-weight:500}.SRqrhW_regionOptionDisabled{cursor:not-allowed;opacity:.5}.SRqrhW_editButton{box-sizing:border-box;font:inherit;background:0 0;margin-left:auto;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2)!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_editButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.SRqrhW_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;padding:14px 16px}.SRqrhW_customized{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);margin-top:12px;transition:all .12s;overflow:hidden}.SRqrhW_customizedSummary{box-sizing:border-box;border-radius:var(--dsw-radius-xl,12px);cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;gap:8px;margin:0;padding:12px 14px;font-size:13px;font-weight:600;line-height:18px;list-style:none;transition:background .12s;display:flex}.SRqrhW_customizedSummary:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelSummaryBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:400;line-height:16px;display:inline-flex}.SRqrhW_customizedSummary::-webkit-details-marker{display:none}.SRqrhW_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary{border-bottom:.5px solid var(--dsw-alias-border-l2);border-bottom-right-radius:0;border-bottom-left-radius:0}.SRqrhW_customizedBody{padding:12px 14px 14px}.SRqrhW_modelCatalog{flex-direction:column;gap:10px;display:flex}.SRqrhW_modelList{flex-direction:column;gap:10px;max-height:360px;padding-right:4px;display:flex;overflow-y:auto}.SRqrhW_modelList::-webkit-scrollbar{width:4px}.SRqrhW_modelList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);border-radius:2px}.SRqrhW_modelCatalogHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.SRqrhW_modelCatalogHeadCompact{justify-content:flex-end;align-items:center;gap:12px;display:flex}.SRqrhW_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.SRqrhW_modelCatalogMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:2px 0 0!important}.SRqrhW_linkButton{box-sizing:border-box;font:inherit;background:0 0;font-size:12px;line-height:18px;border:none!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoice{border-radius:6px;flex-direction:column;gap:4px;padding:6px 8px;font-size:13px;display:flex}.SRqrhW_modelChoice:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoiceHead{cursor:pointer;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;gap:8px;display:grid}.SRqrhW_modelTier{align-items:center;gap:8px;padding-left:24px;display:flex}.SRqrhW_modelTierLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.SRqrhW_modelTierSelect{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);height:24px;color:inherit;font:inherit;cursor:pointer;border:0;border-radius:6px;padding:0 6px;font-size:12px}.SRqrhW_modelTierHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px;margin:0!important}.SRqrhW_modelChoiceName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.SRqrhW_modelChoice code{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_modelRate{min-width:34px;color:var(--dsw-alias-brand-primary);text-align:right;font-size:12px;font-weight:600}.SRqrhW_modelUnavailable{cursor:not-allowed;opacity:.55}.SRqrhW_modelBadge{color:var(--dsw-alias-state-error-primary);font-size:11px}@media (prefers-reduced-motion:reduce){.SRqrhW_customizedSummary:before{transition:none}}.SRqrhW_head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:20px;display:flex}.SRqrhW_heading{margin:0;font-size:18px;font-weight:600}.SRqrhW_status{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_configured,.SRqrhW_success{color:var(--dsw-alias-state-success-primary)}.SRqrhW_label{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;display:block}.SRqrhW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;margin-top:6px;padding:0 10px}.SRqrhW_input:focus{border-color:var(--dsw-alias-brand-primary)}.SRqrhW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.SRqrhW_input:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_hint{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.SRqrhW_credential button{cursor:pointer;height:32px;color:var(--dsw-alias-label-primary);border:1px solid #0000;border-radius:16px;padding:0 12px}.SRqrhW_credential button:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)!important}.SRqrhW_primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.SRqrhW_secondary{background:0 0;border-color:var(--dsw-alias-border-l2)!important}.SRqrhW_secondary:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_danger{background:0 0;border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.SRqrhW_danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.SRqrhW_error{color:var(--dsw-alias-state-error-primary);font-size:12px}.SRqrhW_success{font-size:12px}.SRqrhW_accountSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_accountHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_userInfo{align-items:center;gap:10px;min-width:0;display:flex}.SRqrhW_avatar{background:var(--dsw-alias-brand-primary);width:32px;height:32px;color:var(--dsw-alias-label-primary-foreground);text-transform:uppercase;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.SRqrhW_userDetails{flex-direction:column;gap:2px;min-width:0;display:flex}.SRqrhW_userName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.SRqrhW_userEmail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.SRqrhW_refreshBtn{border:1px solid var(--dsw-alias-border-l2)!important;height:26px!important;color:var(--dsw-alias-label-secondary)!important;background:0 0!important;border-radius:13px!important;padding:0 8px!important;font-size:12px!important}.SRqrhW_refreshBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important}.SRqrhW_quotaBlock{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:8px;display:flex}.SRqrhW_quotaHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_quotaLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.SRqrhW_quotaTop{justify-content:space-between;align-items:baseline;gap:8px;font-size:12px;display:flex}.SRqrhW_quotaTop strong{color:var(--dsw-alias-brand-primary);font-size:13px}.SRqrhW_quotaDescription{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0!important}.SRqrhW_quotaProgress{background:var(--dsw-alias-border-l3);width:100%;height:6px;accent-color:var(--dsw-alias-brand-primary);-webkit-appearance:none;appearance:none;border:0;border-radius:999px;overflow:hidden}.SRqrhW_quotaProgress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.SRqrhW_quotaProgress::-webkit-progress-value{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaProgress::-moz-progress-bar{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.SRqrhW_accountLoadingText,.SRqrhW_accountEmptyText{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}.SRqrhW_userNameRow{align-items:center;gap:8px;display:flex}.SRqrhW_planBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.SRqrhW_orgTag{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_suspendedBanner{background:var(--dsw-alias-state-error-subtle,#ff4d4f1a);color:var(--dsw-alias-state-error-primary);border-radius:6px;align-items:center;gap:6px;margin-bottom:8px;padding:6px 10px;font-size:12px;display:flex}.SRqrhW_searchModeSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_searchModeHintText{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:12px;line-height:18px}";
|
|
785
|
+
const css$1 = ".SRqrhW_credential{color:var(--dsw-alias-label-primary);border-radius:10px;margin-top:12px}.SRqrhW_connectionBody{flex-direction:column;gap:10px;display:flex}.SRqrhW_connectionHead,.SRqrhW_subscriberRow{justify-content:space-between;align-items:center;gap:16px;display:flex}.SRqrhW_connectionHead{flex-wrap:wrap}.SRqrhW_subscriberRow{padding:10px 0}.SRqrhW_subscriberAvatar{width:42px;height:42px;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);border-radius:50%;flex:none;place-items:center;font-size:18px;font-weight:600;display:grid}.SRqrhW_subscriberIdentity{overflow-wrap:anywhere;flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.SRqrhW_subscriberIdentity>span{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_connectionActions{flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;display:flex}.SRqrhW_loginProgress{background:var(--dsw-alias-interactive-bg-hover);border-radius:10px;flex-direction:column;gap:8px;padding:14px;display:flex}.SRqrhW_managementPanel{background:var(--dsw-alias-bg-module-platform);border-radius:10px;flex-wrap:wrap;align-items:center;gap:10px;padding:12px;display:flex}.SRqrhW_credential .SRqrhW_textButton{color:var(--dsw-alias-brand-primary);background:0 0;border:0!important;padding:4px 2px!important}.SRqrhW_primaryLink{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-radius:18px;padding:8px 14px;font-size:12px;text-decoration:none;display:inline-flex}.SRqrhW_credential p.SRqrhW_sharedNote{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);margin-top:6px;padding-top:12px;font-size:12px}@media (width<=480px){.SRqrhW_subscriberRow{flex-wrap:wrap}.SRqrhW_subscriberIdentity{flex-basis:calc(100% - 60px)}}.SRqrhW_credential p{margin:8px 0 0}.SRqrhW_credentialEditor{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.SRqrhW_credentialRowHead{align-items:center;gap:10px;display:flex}.SRqrhW_credentialIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.SRqrhW_credentialName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.SRqrhW_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.SRqrhW_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.SRqrhW_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.SRqrhW_regionBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px;display:inline-flex}.SRqrhW_regionSelector{flex-direction:column;gap:8px;margin-bottom:14px;display:flex}.SRqrhW_regionGroup{gap:8px;display:flex}.SRqrhW_regionOption{border:1px solid var(--dsw-alias-border-l2);cursor:pointer;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);user-select:none;border-radius:8px;align-items:center;gap:6px;padding:6px 12px;font-size:12px;line-height:18px;transition:all .12s;display:inline-flex}.SRqrhW_regionOption:hover:not(.SRqrhW_regionOptionDisabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.SRqrhW_credential button.SRqrhW_regionOptionActive{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-selected);color:var(--dsw-alias-brand-primary);font-weight:500}.SRqrhW_regionOptionDisabled{cursor:not-allowed;opacity:.5}.SRqrhW_editButton{box-sizing:border-box;font:inherit;background:0 0;margin-left:auto;font-size:12px;line-height:18px;border:1px solid var(--dsw-alias-border-l2)!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_editButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.SRqrhW_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;padding:14px 16px}.SRqrhW_customized{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);margin-top:12px;transition:all .12s;overflow:hidden}.SRqrhW_customizedSummary{box-sizing:border-box;border-radius:var(--dsw-radius-xl,12px);cursor:pointer;width:100%;color:var(--dsw-alias-label-primary);user-select:none;align-items:center;gap:8px;margin:0;padding:12px 14px;font-size:13px;font-weight:600;line-height:18px;list-style:none;transition:background .12s;display:flex}.SRqrhW_customizedSummary:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelSummaryBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-tertiary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:400;line-height:16px;display:inline-flex}.SRqrhW_customizedSummary::-webkit-details-marker{display:none}.SRqrhW_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.SRqrhW_customized[open]>.SRqrhW_customizedSummary{border-bottom:.5px solid var(--dsw-alias-border-l2);border-bottom-right-radius:0;border-bottom-left-radius:0}.SRqrhW_customizedBody{padding:12px 14px 14px}.SRqrhW_modelCatalog{flex-direction:column;gap:10px;display:flex}.SRqrhW_modelList{flex-direction:column;gap:10px;max-height:360px;padding-right:4px;display:flex;overflow-y:auto}.SRqrhW_modelList::-webkit-scrollbar{width:4px}.SRqrhW_modelList::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);border-radius:2px}.SRqrhW_modelCatalogHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.SRqrhW_modelCatalogHeadCompact{justify-content:flex-end;align-items:center;gap:12px;display:flex}.SRqrhW_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.SRqrhW_modelCatalogMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin:2px 0 0!important}.SRqrhW_linkButton{box-sizing:border-box;font:inherit;background:0 0;font-size:12px;line-height:18px;border:none!important;border-radius:14px!important;height:28px!important;padding:0 10px!important}.SRqrhW_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoice{border-radius:6px;flex-direction:column;gap:4px;padding:6px 8px;font-size:13px;display:flex}.SRqrhW_modelChoice:hover{background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_modelChoiceHead{cursor:pointer;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;gap:8px;display:grid}.SRqrhW_modelTier{align-items:center;gap:8px;padding-left:24px;display:flex}.SRqrhW_modelTierLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px}.SRqrhW_modelTierSelect{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);height:24px;color:inherit;font:inherit;cursor:pointer;border:0;border-radius:6px;padding:0 6px;font-size:12px}.SRqrhW_modelTierHint{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:18px;margin:0!important}.SRqrhW_modelChoiceName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.SRqrhW_modelChoice code{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_modelRate{min-width:34px;color:var(--dsw-alias-brand-primary);text-align:right;font-size:12px;font-weight:600}.SRqrhW_modelUnavailable{cursor:not-allowed;opacity:.55}.SRqrhW_modelBadge{color:var(--dsw-alias-state-error-primary);font-size:11px}@media (prefers-reduced-motion:reduce){.SRqrhW_customizedSummary:before{transition:none}}.SRqrhW_head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:20px;display:flex}.SRqrhW_heading{margin:0;font-size:18px;font-weight:600}.SRqrhW_status{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_configured,.SRqrhW_success{color:var(--dsw-alias-state-success-primary)}.SRqrhW_label{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px;display:block}.SRqrhW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;height:32px;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;margin-top:6px;padding:0 10px}.SRqrhW_input:focus{border-color:var(--dsw-alias-brand-primary)}.SRqrhW_input::placeholder{color:var(--dsw-alias-label-dimmed)}.SRqrhW_input:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_hint{color:var(--dsw-alias-label-secondary);font-size:12px}.SRqrhW_actions{justify-content:flex-end;gap:8px;margin-top:14px;display:flex}.SRqrhW_credential button{cursor:pointer;height:32px;color:var(--dsw-alias-label-primary);border:1px solid #0000;border-radius:16px;padding:0 12px}.SRqrhW_credential button:disabled{cursor:not-allowed;opacity:.4}.SRqrhW_primary{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)!important}.SRqrhW_primary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.SRqrhW_secondary{background:0 0;border-color:var(--dsw-alias-border-l2)!important}.SRqrhW_secondary:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.SRqrhW_danger{background:0 0;border-color:var(--dsw-alias-state-error-primary)!important;color:var(--dsw-alias-state-error-primary)!important}.SRqrhW_danger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.SRqrhW_error{color:var(--dsw-alias-state-error-primary);font-size:12px}.SRqrhW_success{font-size:12px}.SRqrhW_accountSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_accountHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_userInfo{align-items:center;gap:10px;min-width:0;display:flex}.SRqrhW_avatar{background:var(--dsw-alias-brand-primary);width:32px;height:32px;color:var(--dsw-alias-label-primary-foreground);text-transform:uppercase;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:14px;font-weight:600;display:flex}.SRqrhW_userDetails{flex-direction:column;gap:2px;min-width:0;display:flex}.SRqrhW_userName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;overflow:hidden}.SRqrhW_userEmail{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.SRqrhW_refreshBtn{border:1px solid var(--dsw-alias-border-l2)!important;height:26px!important;color:var(--dsw-alias-label-secondary)!important;background:0 0!important;border-radius:13px!important;padding:0 8px!important;font-size:12px!important}.SRqrhW_refreshBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)!important}.SRqrhW_quotaBlock{border-top:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:8px;display:flex}.SRqrhW_quotaHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.SRqrhW_quotaLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:600}.SRqrhW_quotaTop{justify-content:space-between;align-items:baseline;gap:8px;font-size:12px;display:flex}.SRqrhW_quotaTop strong{color:var(--dsw-alias-brand-primary);font-size:13px}.SRqrhW_quotaDescription{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px;margin:0!important}.SRqrhW_quotaProgress{background:var(--dsw-alias-border-l3);width:100%;height:6px;accent-color:var(--dsw-alias-brand-primary);-webkit-appearance:none;appearance:none;border:0;border-radius:999px;overflow:hidden}.SRqrhW_quotaProgress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.SRqrhW_quotaProgress::-webkit-progress-value{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaProgress::-moz-progress-bar{background:var(--dsw-alias-brand-primary);border-radius:999px}.SRqrhW_quotaMeta{color:var(--dsw-alias-label-tertiary);justify-content:space-between;align-items:center;gap:8px;font-size:11px;display:flex}.SRqrhW_accountLoadingText,.SRqrhW_accountEmptyText{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}.SRqrhW_userNameRow{align-items:center;gap:8px;display:flex}.SRqrhW_planBadge{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:4px;align-items:center;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.SRqrhW_orgTag{color:var(--dsw-alias-label-tertiary);font-size:11px}.SRqrhW_suspendedBanner{background:var(--dsw-alias-state-error-subtle,#ff4d4f1a);color:var(--dsw-alias-state-error-primary);border-radius:6px;align-items:center;gap:6px;margin-bottom:8px;padding:6px 10px;font-size:12px;display:flex}.SRqrhW_searchModeSection{border:.5px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-xl,12px);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;display:flex}.SRqrhW_searchModeHintText{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:12px;line-height:18px}";
|
|
509
786
|
const tagId$1 = "dsh-provider-qoder/QoderCredentialCard.module.css";
|
|
510
787
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
511
788
|
const tag = document.createElement("style");
|
|
@@ -522,6 +799,9 @@ window.__ModuleLoader__.load({
|
|
|
522
799
|
"actions": "SRqrhW_actions",
|
|
523
800
|
"avatar": "SRqrhW_avatar",
|
|
524
801
|
"configured": "SRqrhW_configured",
|
|
802
|
+
"connectionActions": "SRqrhW_connectionActions",
|
|
803
|
+
"connectionBody": "SRqrhW_connectionBody",
|
|
804
|
+
"connectionHead": "SRqrhW_connectionHead",
|
|
525
805
|
"credential": "SRqrhW_credential",
|
|
526
806
|
"credentialDot": "SRqrhW_credentialDot",
|
|
527
807
|
"credentialDotConfigured": "SRqrhW_credentialDotConfigured",
|
|
@@ -543,6 +823,8 @@ window.__ModuleLoader__.load({
|
|
|
543
823
|
"input": "SRqrhW_input",
|
|
544
824
|
"label": "SRqrhW_label",
|
|
545
825
|
"linkButton": "SRqrhW_linkButton",
|
|
826
|
+
"loginProgress": "SRqrhW_loginProgress",
|
|
827
|
+
"managementPanel": "SRqrhW_managementPanel",
|
|
546
828
|
"modelBadge": "SRqrhW_modelBadge",
|
|
547
829
|
"modelCatalog": "SRqrhW_modelCatalog",
|
|
548
830
|
"modelCatalogHead": "SRqrhW_modelCatalogHead",
|
|
@@ -563,6 +845,7 @@ window.__ModuleLoader__.load({
|
|
|
563
845
|
"orgTag": "SRqrhW_orgTag",
|
|
564
846
|
"planBadge": "SRqrhW_planBadge",
|
|
565
847
|
"primary": "SRqrhW_primary",
|
|
848
|
+
"primaryLink": "SRqrhW_primaryLink",
|
|
566
849
|
"quotaBlock": "SRqrhW_quotaBlock",
|
|
567
850
|
"quotaDescription": "SRqrhW_quotaDescription",
|
|
568
851
|
"quotaHeader": "SRqrhW_quotaHeader",
|
|
@@ -580,9 +863,14 @@ window.__ModuleLoader__.load({
|
|
|
580
863
|
"searchModeHintText": "SRqrhW_searchModeHintText",
|
|
581
864
|
"searchModeSection": "SRqrhW_searchModeSection",
|
|
582
865
|
"secondary": "SRqrhW_secondary",
|
|
866
|
+
"sharedNote": "SRqrhW_sharedNote",
|
|
583
867
|
"status": "SRqrhW_status",
|
|
868
|
+
"subscriberAvatar": "SRqrhW_subscriberAvatar",
|
|
869
|
+
"subscriberIdentity": "SRqrhW_subscriberIdentity",
|
|
870
|
+
"subscriberRow": "SRqrhW_subscriberRow",
|
|
584
871
|
"success": "SRqrhW_success",
|
|
585
872
|
"suspendedBanner": "SRqrhW_suspendedBanner",
|
|
873
|
+
"textButton": "SRqrhW_textButton",
|
|
586
874
|
"userDetails": "SRqrhW_userDetails",
|
|
587
875
|
"userEmail": "SRqrhW_userEmail",
|
|
588
876
|
"userInfo": "SRqrhW_userInfo",
|
|
@@ -612,7 +900,7 @@ window.__ModuleLoader__.load({
|
|
|
612
900
|
const fetching = snapshot.pending === "discovering";
|
|
613
901
|
const failure = snapshot.failureMessage || (snapshot.failure ? t(snapshot.failure) : void 0);
|
|
614
902
|
const renderRate = (model) => {
|
|
615
|
-
if (model.
|
|
903
|
+
if (model.priceFactor === 0 || model.priceFactor === void 0 && model.isFree) return t("modelRateFree");
|
|
616
904
|
if (model.priceFactor === void 0) return t("modelRateUnknown");
|
|
617
905
|
const current = formatRateFactor(model.priceFactor);
|
|
618
906
|
if (model.originalPriceFactor !== void 0 && model.originalPriceFactor > model.priceFactor) return t("modelRateDiscount", {
|
|
@@ -869,7 +1157,7 @@ window.__ModuleLoader__.load({
|
|
|
869
1157
|
const renderAccount = () => {
|
|
870
1158
|
if (!configured) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
871
1159
|
className: QoderCredentialCard_module_css_default.accountSection,
|
|
872
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1160
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
873
1161
|
className: QoderCredentialCard_module_css_default.accountEmptyText,
|
|
874
1162
|
children: t("accountCredentialHint")
|
|
875
1163
|
})
|
|
@@ -1098,228 +1386,539 @@ window.__ModuleLoader__.load({
|
|
|
1098
1386
|
});
|
|
1099
1387
|
}
|
|
1100
1388
|
//#endregion
|
|
1101
|
-
//#region src/client/
|
|
1102
|
-
|
|
1103
|
-
|
|
1389
|
+
//#region src/client/QoderBrowserLogin.tsx
|
|
1390
|
+
/** A single current identity, with browser and PAT management revealed only when needed. */
|
|
1391
|
+
function QoderBrowserLogin({ region, operations, credentials, onBusyChange, t }) {
|
|
1392
|
+
const [view, setView] = (0, react.useState)();
|
|
1393
|
+
const [pat, setPat] = (0, react.useState)();
|
|
1394
|
+
const [profile, setProfile] = (0, react.useState)();
|
|
1395
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
1396
|
+
const [error, setError] = (0, react.useState)();
|
|
1397
|
+
const [readFailed, setReadFailed] = (0, react.useState)(false);
|
|
1104
1398
|
const [editing, setEditing] = (0, react.useState)(false);
|
|
1399
|
+
const [menu, setMenu] = (0, react.useState)(false);
|
|
1105
1400
|
const [draft, setDraft] = (0, react.useState)("");
|
|
1106
|
-
const [
|
|
1107
|
-
const [
|
|
1108
|
-
const [
|
|
1109
|
-
const [
|
|
1110
|
-
const
|
|
1401
|
+
const [copyFailed, setCopyFailed] = (0, react.useState)(false);
|
|
1402
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
1403
|
+
const [now, setNow] = (0, react.useState)(Date.now());
|
|
1404
|
+
const [accountRevision, setAccountRevision] = (0, react.useState)(0);
|
|
1405
|
+
const mounted = (0, react.useRef)(false);
|
|
1406
|
+
const revision = (0, react.useRef)(0);
|
|
1407
|
+
const mutating = (0, react.useRef)(false);
|
|
1408
|
+
const waitingRef = (0, react.useRef)(false);
|
|
1409
|
+
const wakeRef = (0, react.useRef)(void 0);
|
|
1410
|
+
const attempt = view?.attempt;
|
|
1411
|
+
const pending = attempt !== void 0 && [
|
|
1412
|
+
"waiting",
|
|
1413
|
+
"verifying",
|
|
1414
|
+
"saving"
|
|
1415
|
+
].includes(attempt.phase);
|
|
1416
|
+
const connected = view?.configured === true && !view.expired;
|
|
1417
|
+
const identity = view?.method === "browser" ? view.profile : profile;
|
|
1418
|
+
const patConfigured = pat?.configured === true && !isEnvironmentCredentialSource(pat.source);
|
|
1419
|
+
const remaining = Math.max(0, Math.ceil(((attempt?.expiresAt ?? now) - now) / 1e3));
|
|
1420
|
+
const read = async () => {
|
|
1421
|
+
const info = await (credentials.describePat ?? credentials.describe)();
|
|
1422
|
+
const result = operations ? await operations.read(region) : void 0;
|
|
1423
|
+
if (result && !result.ok) throw new Error("Authorization status unavailable");
|
|
1424
|
+
if (!result && !info) throw new Error("Credential status unavailable");
|
|
1425
|
+
return {
|
|
1426
|
+
info,
|
|
1427
|
+
value: result?.value ?? {
|
|
1428
|
+
region,
|
|
1429
|
+
method: "pat",
|
|
1430
|
+
configured: info?.configured === true && !isEnvironmentCredentialSource(info.source),
|
|
1431
|
+
writable: false
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
};
|
|
1111
1435
|
(0, react.useEffect)(() => {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
const
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1436
|
+
mounted.current = true;
|
|
1437
|
+
let active = true;
|
|
1438
|
+
let timer;
|
|
1439
|
+
const poll = async (identityChanged = false) => {
|
|
1440
|
+
const version = revision.current;
|
|
1441
|
+
try {
|
|
1442
|
+
const result = await read();
|
|
1443
|
+
if (active && mounted.current && version === revision.current && !mutating.current) {
|
|
1444
|
+
waitingRef.current = result.value.attempt !== void 0 && [
|
|
1445
|
+
"waiting",
|
|
1446
|
+
"verifying",
|
|
1447
|
+
"saving"
|
|
1448
|
+
].includes(result.value.attempt.phase);
|
|
1449
|
+
setView(result.value);
|
|
1450
|
+
setPat(result.info);
|
|
1451
|
+
setReadFailed(false);
|
|
1452
|
+
setNow(Date.now());
|
|
1453
|
+
if (identityChanged) setAccountRevision((value) => value + 1);
|
|
1454
|
+
}
|
|
1455
|
+
} catch {
|
|
1456
|
+
if (mounted.current && version === revision.current) setReadFailed(true);
|
|
1457
|
+
}
|
|
1458
|
+
if (active && mounted.current) {
|
|
1459
|
+
clearTimeout(timer);
|
|
1460
|
+
timer = setTimeout(() => {
|
|
1461
|
+
poll();
|
|
1462
|
+
}, waitingRef.current ? 1e3 : 1e4);
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
poll();
|
|
1466
|
+
wakeRef.current = () => {
|
|
1467
|
+
clearTimeout(timer);
|
|
1468
|
+
timer = setTimeout(() => {
|
|
1469
|
+
poll();
|
|
1470
|
+
}, 1e3);
|
|
1471
|
+
};
|
|
1472
|
+
const unsubscribe = credentials.subscribe?.(() => {
|
|
1473
|
+
if (mutating.current || !active) return;
|
|
1474
|
+
revision.current++;
|
|
1475
|
+
setProfile(void 0);
|
|
1476
|
+
poll(true);
|
|
1119
1477
|
});
|
|
1120
|
-
|
|
1478
|
+
return () => {
|
|
1479
|
+
active = false;
|
|
1480
|
+
mounted.current = false;
|
|
1481
|
+
wakeRef.current = void 0;
|
|
1482
|
+
clearTimeout(timer);
|
|
1483
|
+
unsubscribe?.();
|
|
1484
|
+
revision.current++;
|
|
1485
|
+
};
|
|
1486
|
+
}, [
|
|
1487
|
+
operations,
|
|
1488
|
+
credentials,
|
|
1489
|
+
region
|
|
1490
|
+
]);
|
|
1121
1491
|
(0, react.useEffect)(() => {
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1492
|
+
let active = true;
|
|
1493
|
+
setProfile(void 0);
|
|
1494
|
+
if (view?.method === "pat" && view.configured) {
|
|
1495
|
+
const version = revision.current;
|
|
1496
|
+
credentials.getAccount().then((result) => {
|
|
1497
|
+
if (active && version === revision.current && result?.ok) setProfile(result.value.profile);
|
|
1498
|
+
}).catch(() => {});
|
|
1499
|
+
}
|
|
1500
|
+
return () => {
|
|
1501
|
+
active = false;
|
|
1502
|
+
};
|
|
1503
|
+
}, [
|
|
1504
|
+
credentials,
|
|
1505
|
+
view?.method,
|
|
1506
|
+
view?.configured,
|
|
1507
|
+
accountRevision
|
|
1508
|
+
]);
|
|
1509
|
+
const mutate = async (action) => {
|
|
1510
|
+
if (mutating.current) return;
|
|
1511
|
+
const popup = action === "begin" ? window.open("about:blank", "_blank") : null;
|
|
1512
|
+
if (popup) popup.opener = null;
|
|
1513
|
+
const version = ++revision.current;
|
|
1514
|
+
mutating.current = true;
|
|
1515
|
+
onBusyChange?.(true);
|
|
1516
|
+
setBusy(true);
|
|
1517
|
+
setError(void 0);
|
|
1518
|
+
setMenu(false);
|
|
1519
|
+
try {
|
|
1520
|
+
let result;
|
|
1521
|
+
if (action === "savePat") if (draft.trim()) {
|
|
1522
|
+
if (!await credentials.store(draft.trim())) throw new Error("PAT save failed");
|
|
1523
|
+
} else if (patConfigured) {
|
|
1524
|
+
if (operations) result = await operations.select(region, "pat");
|
|
1525
|
+
} else throw new Error("A PAT is required");
|
|
1526
|
+
else if (action === "removePat") {
|
|
1527
|
+
if (!await credentials.remove()) throw new Error("PAT removal failed");
|
|
1528
|
+
} else if (operations) result = action === "begin" ? await operations.begin(region) : action === "cancel" ? await operations.cancel(region) : await operations.select(region, action);
|
|
1529
|
+
if (result && !result.ok) {
|
|
1530
|
+
if (mounted.current && version === revision.current) {
|
|
1531
|
+
const code = result.error.code;
|
|
1532
|
+
setError(action === "none" ? "browserRemoveFailed" : code === "TIMEOUT" ? "browserTimeout" : code === "UNAUTHENTICATED" ? "browserRejected" : "authorizationConnectionFailed");
|
|
1533
|
+
}
|
|
1534
|
+
popup?.close();
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
const current = result?.value;
|
|
1538
|
+
if (!mounted.current || version !== revision.current) {
|
|
1539
|
+
popup?.close();
|
|
1167
1540
|
return;
|
|
1168
1541
|
}
|
|
1169
|
-
|
|
1542
|
+
if (popup && current?.attempt?.url) popup.location.replace(current.attempt.url);
|
|
1543
|
+
else popup?.close();
|
|
1544
|
+
const refreshed = current ? {
|
|
1545
|
+
value: current,
|
|
1546
|
+
info: pat
|
|
1547
|
+
} : await read();
|
|
1548
|
+
if (!mounted.current || version !== revision.current) {
|
|
1549
|
+
popup?.close();
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
setView(refreshed.value);
|
|
1553
|
+
setPat(refreshed.info);
|
|
1554
|
+
setReadFailed(false);
|
|
1555
|
+
setNow(Date.now());
|
|
1556
|
+
waitingRef.current = refreshed.value.attempt !== void 0 && [
|
|
1557
|
+
"waiting",
|
|
1558
|
+
"verifying",
|
|
1559
|
+
"saving"
|
|
1560
|
+
].includes(refreshed.value.attempt.phase);
|
|
1561
|
+
if (action === "savePat" || action === "removePat") {
|
|
1562
|
+
setDraft("");
|
|
1563
|
+
setEditing(false);
|
|
1564
|
+
setProfile(void 0);
|
|
1565
|
+
setAccountRevision((value) => value + 1);
|
|
1566
|
+
}
|
|
1567
|
+
} catch {
|
|
1568
|
+
popup?.close();
|
|
1569
|
+
if (mounted.current && version === revision.current) setError(action === "savePat" ? "patSaveFailed" : action === "removePat" ? "removeFailed" : action === "none" ? "browserRemoveFailed" : "authorizationConnectionFailed");
|
|
1570
|
+
} finally {
|
|
1571
|
+
mutating.current = false;
|
|
1572
|
+
onBusyChange?.(false);
|
|
1573
|
+
if (mounted.current && version === revision.current) {
|
|
1574
|
+
revision.current++;
|
|
1575
|
+
setBusy(false);
|
|
1576
|
+
}
|
|
1577
|
+
if (mounted.current) wakeRef.current?.();
|
|
1170
1578
|
}
|
|
1171
|
-
if (normalized.length === 0 || await operations.store(normalized)) {
|
|
1172
|
-
setDraft("");
|
|
1173
|
-
setNotice("saved");
|
|
1174
|
-
if (normalized.length > 0) await load();
|
|
1175
|
-
setEditing(false);
|
|
1176
|
-
} else setNotice("saveFailed");
|
|
1177
|
-
setMutation(void 0);
|
|
1178
1579
|
};
|
|
1179
|
-
const
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
setDraft("");
|
|
1185
|
-
await load();
|
|
1186
|
-
} else setNotice("removeFailed");
|
|
1187
|
-
setMutation(void 0);
|
|
1580
|
+
const openPat = () => {
|
|
1581
|
+
setMenu(false);
|
|
1582
|
+
setDraft("");
|
|
1583
|
+
setError(void 0);
|
|
1584
|
+
setEditing(true);
|
|
1188
1585
|
};
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1586
|
+
const initial = (identity?.name || identity?.email || "Q").slice(0, 1).toUpperCase();
|
|
1587
|
+
const failure = attempt?.phase === "failed" ? attempt.failure === "storage" ? "browserStorageFailed" : attempt.failure === "connection" ? "authorizationConnectionFailed" : "browserRejected" : void 0;
|
|
1588
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1589
|
+
className: QoderCredentialCard_module_css_default.connectionBody,
|
|
1590
|
+
"aria-label": t("accountConnectionTitle"),
|
|
1192
1591
|
children: [
|
|
1193
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1194
|
-
|
|
1195
|
-
children:
|
|
1196
|
-
|
|
1592
|
+
!view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1593
|
+
role: "status",
|
|
1594
|
+
children: t(readFailed ? "authorizationConnectionFailed" : "loading")
|
|
1595
|
+
}) : null,
|
|
1596
|
+
readFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1597
|
+
type: "button",
|
|
1598
|
+
className: QoderCredentialCard_module_css_default.secondary,
|
|
1599
|
+
onClick: () => wakeRef.current?.(),
|
|
1600
|
+
children: t("retry")
|
|
1601
|
+
}) : null,
|
|
1602
|
+
view ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1603
|
+
connected || view.expired ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1604
|
+
className: QoderCredentialCard_module_css_default.subscriberRow,
|
|
1197
1605
|
children: [
|
|
1198
1606
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1199
|
-
className: QoderCredentialCard_module_css_default.
|
|
1200
|
-
|
|
1607
|
+
className: QoderCredentialCard_module_css_default.subscriberAvatar,
|
|
1608
|
+
"aria-hidden": "true",
|
|
1609
|
+
children: initial
|
|
1201
1610
|
}),
|
|
1202
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1203
|
-
className: QoderCredentialCard_module_css_default.
|
|
1204
|
-
children:
|
|
1611
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1612
|
+
className: QoderCredentialCard_module_css_default.subscriberIdentity,
|
|
1613
|
+
children: [
|
|
1614
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: identity?.name || t(view.method === "pat" ? "patActive" : "browserMethod") }),
|
|
1615
|
+
identity?.email ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: identity.email }) : null,
|
|
1616
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1617
|
+
className: QoderCredentialCard_module_css_default.label,
|
|
1618
|
+
children: t(view.method === "browser" ? "browserMethod" : "patMethod")
|
|
1619
|
+
})
|
|
1620
|
+
]
|
|
1205
1621
|
}),
|
|
1622
|
+
!pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1623
|
+
type: "button",
|
|
1624
|
+
className: QoderCredentialCard_module_css_default.secondary,
|
|
1625
|
+
"aria-expanded": menu,
|
|
1626
|
+
"aria-controls": "qoder-account-management",
|
|
1627
|
+
disabled: busy,
|
|
1628
|
+
onClick: () => setMenu(!menu),
|
|
1629
|
+
children: t(view.method === "pat" ? "manageCredential" : "manageAccount")
|
|
1630
|
+
}) : null
|
|
1631
|
+
]
|
|
1632
|
+
}) : !pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1633
|
+
className: QoderCredentialCard_module_css_default.label,
|
|
1634
|
+
children: t("signInDescription")
|
|
1635
|
+
}) : null,
|
|
1636
|
+
pending ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1637
|
+
className: QoderCredentialCard_module_css_default.loginProgress,
|
|
1638
|
+
role: "status",
|
|
1639
|
+
children: [
|
|
1640
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t(attempt.phase === "saving" ? "browserSaving" : "browserWaiting") }),
|
|
1206
1641
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1207
|
-
className:
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1642
|
+
className: QoderCredentialCard_module_css_default.label,
|
|
1643
|
+
children: t("loginTimeRemaining", { seconds: remaining })
|
|
1644
|
+
}),
|
|
1645
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1646
|
+
className: QoderCredentialCard_module_css_default.connectionActions,
|
|
1647
|
+
children: [
|
|
1648
|
+
attempt.url ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1649
|
+
className: QoderCredentialCard_module_css_default.primaryLink,
|
|
1650
|
+
href: attempt.url,
|
|
1651
|
+
target: "_blank",
|
|
1652
|
+
rel: "noopener noreferrer",
|
|
1653
|
+
referrerPolicy: "no-referrer",
|
|
1654
|
+
children: t("reopenLogin")
|
|
1655
|
+
}) : null,
|
|
1656
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1657
|
+
type: "button",
|
|
1658
|
+
className: QoderCredentialCard_module_css_default.secondary,
|
|
1659
|
+
disabled: busy || !view.writable,
|
|
1660
|
+
onClick: () => {
|
|
1661
|
+
mutate("cancel");
|
|
1662
|
+
},
|
|
1663
|
+
children: t("cancelLogin")
|
|
1664
|
+
}),
|
|
1665
|
+
attempt.url ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1666
|
+
type: "button",
|
|
1667
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1668
|
+
onClick: () => {
|
|
1669
|
+
if (!navigator.clipboard) {
|
|
1670
|
+
setCopyFailed(true);
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
navigator.clipboard.writeText(attempt.url).then(() => {
|
|
1674
|
+
if (mounted.current) {
|
|
1675
|
+
setCopied(true);
|
|
1676
|
+
setCopyFailed(false);
|
|
1677
|
+
}
|
|
1678
|
+
}, () => {
|
|
1679
|
+
if (mounted.current) setCopyFailed(true);
|
|
1680
|
+
});
|
|
1681
|
+
},
|
|
1682
|
+
children: t(copied ? "loginLinkCopied" : "copyLogin")
|
|
1683
|
+
}) : null
|
|
1684
|
+
]
|
|
1211
1685
|
})
|
|
1212
1686
|
]
|
|
1213
|
-
})
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1687
|
+
}) : null,
|
|
1688
|
+
view.expired ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1689
|
+
role: "status",
|
|
1690
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1691
|
+
children: t("browserExpired")
|
|
1692
|
+
}) : null,
|
|
1693
|
+
view.unsaved ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1694
|
+
role: "alert",
|
|
1695
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1696
|
+
children: t("browserUnsaved")
|
|
1697
|
+
}) : null,
|
|
1698
|
+
!pending && attempt?.phase === "timeout" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1699
|
+
role: "status",
|
|
1700
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1701
|
+
children: t("browserTimeout")
|
|
1702
|
+
}) : null,
|
|
1703
|
+
!pending && failure ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1704
|
+
role: "alert",
|
|
1705
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1706
|
+
children: t(failure)
|
|
1707
|
+
}) : null,
|
|
1708
|
+
menu && !pending && !editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1709
|
+
id: "qoder-account-management",
|
|
1710
|
+
className: QoderCredentialCard_module_css_default.managementPanel,
|
|
1711
|
+
children: [
|
|
1712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1713
|
+
type: "button",
|
|
1714
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1715
|
+
disabled: busy || !view.writable,
|
|
1716
|
+
onClick: () => {
|
|
1717
|
+
mutate("begin");
|
|
1718
|
+
},
|
|
1719
|
+
children: t("changeAccount")
|
|
1720
|
+
}),
|
|
1721
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1722
|
+
type: "button",
|
|
1723
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1724
|
+
disabled: busy || !pat?.writable,
|
|
1725
|
+
onClick: openPat,
|
|
1726
|
+
children: t(view.method === "pat" ? "editPat" : "usePat")
|
|
1727
|
+
}),
|
|
1728
|
+
view.method !== "browser" && view.profile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1729
|
+
type: "button",
|
|
1730
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1731
|
+
disabled: busy || !view.writable,
|
|
1732
|
+
onClick: () => {
|
|
1733
|
+
mutate("browser");
|
|
1734
|
+
},
|
|
1735
|
+
children: t("useBrowser")
|
|
1736
|
+
}) : null,
|
|
1737
|
+
view.profile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1738
|
+
type: "button",
|
|
1739
|
+
className: QoderCredentialCard_module_css_default.danger,
|
|
1740
|
+
disabled: busy || !view.writable,
|
|
1741
|
+
onClick: () => {
|
|
1742
|
+
mutate("none");
|
|
1743
|
+
},
|
|
1744
|
+
children: t("signOutQoder")
|
|
1745
|
+
}) : null
|
|
1746
|
+
]
|
|
1747
|
+
}) : null,
|
|
1748
|
+
!pending && !editing && (!connected || view.expired) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1749
|
+
className: QoderCredentialCard_module_css_default.connectionActions,
|
|
1750
|
+
children: [
|
|
1751
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1752
|
+
type: "button",
|
|
1753
|
+
className: QoderCredentialCard_module_css_default.primary,
|
|
1754
|
+
disabled: busy || !view.writable,
|
|
1755
|
+
onClick: () => {
|
|
1756
|
+
mutate("begin");
|
|
1757
|
+
},
|
|
1758
|
+
children: t(view.expired ? "signInAgain" : "signInQoder")
|
|
1759
|
+
}),
|
|
1760
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1761
|
+
type: "button",
|
|
1762
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1763
|
+
disabled: busy || !pat?.writable,
|
|
1764
|
+
onClick: openPat,
|
|
1765
|
+
children: t("usePat")
|
|
1766
|
+
}),
|
|
1767
|
+
view.profile && view.method !== "browser" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1768
|
+
type: "button",
|
|
1769
|
+
className: QoderCredentialCard_module_css_default.textButton,
|
|
1770
|
+
disabled: busy || !view.writable,
|
|
1771
|
+
onClick: () => {
|
|
1772
|
+
mutate("browser");
|
|
1773
|
+
},
|
|
1774
|
+
children: t("useBrowser")
|
|
1775
|
+
}) : null
|
|
1776
|
+
]
|
|
1777
|
+
}) : null,
|
|
1778
|
+
editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1779
|
+
className: QoderCredentialCard_module_css_default.editor,
|
|
1780
|
+
children: [
|
|
1781
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1782
|
+
className: QoderCredentialCard_module_css_default.label,
|
|
1783
|
+
htmlFor: "qoder-managed-credential",
|
|
1784
|
+
children: t("tokenLabel")
|
|
1785
|
+
}),
|
|
1786
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1787
|
+
id: "qoder-managed-credential",
|
|
1788
|
+
className: QoderCredentialCard_module_css_default.input,
|
|
1789
|
+
type: "password",
|
|
1790
|
+
autoComplete: "new-password",
|
|
1791
|
+
value: draft,
|
|
1792
|
+
disabled: busy || !pat?.writable,
|
|
1793
|
+
placeholder: patConfigured ? t("configuredHint") : t("tokenPlaceholder"),
|
|
1794
|
+
onChange: (event) => setDraft(event.currentTarget.value)
|
|
1795
|
+
}),
|
|
1796
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1797
|
+
className: QoderCredentialCard_module_css_default.connectionActions,
|
|
1798
|
+
children: [
|
|
1799
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1800
|
+
type: "button",
|
|
1801
|
+
className: QoderCredentialCard_module_css_default.primary,
|
|
1802
|
+
disabled: busy || !pat?.writable || !draft.trim() && !patConfigured,
|
|
1803
|
+
onClick: () => {
|
|
1804
|
+
mutate("savePat");
|
|
1805
|
+
},
|
|
1806
|
+
children: t(busy ? "saving" : draft.trim() || !patConfigured ? "saveAndUsePat" : "useSavedPat")
|
|
1807
|
+
}),
|
|
1808
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1809
|
+
type: "button",
|
|
1810
|
+
className: QoderCredentialCard_module_css_default.secondary,
|
|
1811
|
+
disabled: busy,
|
|
1812
|
+
onClick: () => {
|
|
1813
|
+
setDraft("");
|
|
1814
|
+
setEditing(false);
|
|
1815
|
+
setError(void 0);
|
|
1816
|
+
},
|
|
1817
|
+
children: t("cancel")
|
|
1818
|
+
}),
|
|
1819
|
+
patConfigured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1820
|
+
type: "button",
|
|
1821
|
+
className: QoderCredentialCard_module_css_default.danger,
|
|
1822
|
+
disabled: busy || !pat?.writable,
|
|
1823
|
+
onClick: () => {
|
|
1824
|
+
if (window.confirm(t("confirmRemove"))) mutate("removePat");
|
|
1825
|
+
},
|
|
1826
|
+
children: t("remove")
|
|
1827
|
+
}) : null
|
|
1828
|
+
]
|
|
1829
|
+
})
|
|
1830
|
+
]
|
|
1831
|
+
}) : null
|
|
1832
|
+
] }) : null,
|
|
1833
|
+
view && !view.writable && !pat?.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1834
|
+
className: QoderCredentialCard_module_css_default.label,
|
|
1835
|
+
children: t("readOnly")
|
|
1836
|
+
}) : null,
|
|
1837
|
+
copyFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1838
|
+
role: "alert",
|
|
1839
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1840
|
+
children: t("copyLoginFailed")
|
|
1841
|
+
}) : null,
|
|
1842
|
+
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1843
|
+
role: "alert",
|
|
1844
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1845
|
+
children: t(error)
|
|
1846
|
+
}) : null,
|
|
1847
|
+
readFailed && view ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1848
|
+
role: "alert",
|
|
1849
|
+
className: QoderCredentialCard_module_css_default.error,
|
|
1850
|
+
children: t("authorizationConnectionFailed")
|
|
1851
|
+
}) : null
|
|
1852
|
+
]
|
|
1853
|
+
});
|
|
1854
|
+
}
|
|
1855
|
+
//#endregion
|
|
1856
|
+
//#region src/client/QoderCredentialCard.tsx
|
|
1857
|
+
/** Region selection stays outside the keyed account state, so old identities never flash. */
|
|
1858
|
+
function QoderCredentialCard({ operations, t }) {
|
|
1859
|
+
const snapshot = (0, react.useSyncExternalStore)(operations.subscribeModels, operations.getModelSnapshot, operations.getModelSnapshot);
|
|
1860
|
+
const region = regionOf(snapshot.value);
|
|
1861
|
+
const [changing, setChanging] = (0, react.useState)(false);
|
|
1862
|
+
const [accountBusy, setAccountBusy] = (0, react.useState)(false);
|
|
1863
|
+
const [notice, setNotice] = (0, react.useState)();
|
|
1864
|
+
const mutating = (0, react.useRef)(false);
|
|
1865
|
+
const canChange = snapshot.status === "ready" && snapshot.writable && !changing && !accountBusy;
|
|
1866
|
+
const changeRegion = async (next) => {
|
|
1867
|
+
if (!canChange || next === region || mutating.current) return;
|
|
1868
|
+
mutating.current = true;
|
|
1869
|
+
setChanging(true);
|
|
1870
|
+
setNotice(void 0);
|
|
1871
|
+
try {
|
|
1872
|
+
setNotice(await operations.storeRegion(next) ? "regionChanged" : "regionChangeFailed");
|
|
1873
|
+
} catch {
|
|
1874
|
+
setNotice("regionChangeFailed");
|
|
1875
|
+
} finally {
|
|
1876
|
+
mutating.current = false;
|
|
1877
|
+
setChanging(false);
|
|
1878
|
+
}
|
|
1879
|
+
};
|
|
1880
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1881
|
+
className: `${QoderCredentialCard_module_css_default.credential} ${QoderCredentialCard_module_css_default.credentialEditor}`,
|
|
1882
|
+
"aria-label": t("accountConnectionTitle"),
|
|
1883
|
+
children: [
|
|
1884
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1885
|
+
className: QoderCredentialCard_module_css_default.connectionHead,
|
|
1886
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
1887
|
+
className: QoderCredentialCard_module_css_default.credentialName,
|
|
1888
|
+
children: t("accountConnectionTitle")
|
|
1889
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1890
|
+
className: QoderCredentialCard_module_css_default.regionGroup,
|
|
1891
|
+
role: "radiogroup",
|
|
1892
|
+
"aria-label": t("regionLabel"),
|
|
1893
|
+
children: ["global", "china"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1894
|
+
type: "button",
|
|
1895
|
+
role: "radio",
|
|
1896
|
+
"aria-checked": region === value,
|
|
1897
|
+
disabled: !canChange,
|
|
1898
|
+
className: `${QoderCredentialCard_module_css_default.regionOption} ${region === value ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
|
|
1899
|
+
onClick: () => {
|
|
1900
|
+
changeRegion(value);
|
|
1901
|
+
},
|
|
1902
|
+
children: t(value === "china" ? "regionChina" : "regionGlobal")
|
|
1903
|
+
}, value))
|
|
1226
1904
|
})]
|
|
1227
1905
|
}),
|
|
1228
|
-
notice
|
|
1229
|
-
className: notice === "saved" ? QoderCredentialCard_module_css_default.success : QoderCredentialCard_module_css_default.error,
|
|
1906
|
+
notice ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1230
1907
|
role: "status",
|
|
1908
|
+
className: notice === "regionChangeFailed" ? QoderCredentialCard_module_css_default.error : QoderCredentialCard_module_css_default.label,
|
|
1231
1909
|
children: t(notice)
|
|
1232
|
-
}),
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
role: "radiogroup",
|
|
1245
|
-
"aria-label": t("regionLabel"),
|
|
1246
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1247
|
-
type: "button",
|
|
1248
|
-
role: "radio",
|
|
1249
|
-
"aria-checked": regionDraft === "global",
|
|
1250
|
-
className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "global" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
|
|
1251
|
-
disabled: !canModifyRegion || busy,
|
|
1252
|
-
onClick: () => {
|
|
1253
|
-
setRegionDraft("global");
|
|
1254
|
-
setRegionDirty(true);
|
|
1255
|
-
},
|
|
1256
|
-
children: t("regionGlobal")
|
|
1257
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1258
|
-
type: "button",
|
|
1259
|
-
role: "radio",
|
|
1260
|
-
"aria-checked": regionDraft === "china",
|
|
1261
|
-
className: `${QoderCredentialCard_module_css_default.regionOption} ${regionDraft === "china" ? QoderCredentialCard_module_css_default.regionOptionActive : ""}`,
|
|
1262
|
-
disabled: !canModifyRegion || busy,
|
|
1263
|
-
onClick: () => {
|
|
1264
|
-
setRegionDraft("china");
|
|
1265
|
-
setRegionDirty(true);
|
|
1266
|
-
},
|
|
1267
|
-
children: t("regionChina")
|
|
1268
|
-
})]
|
|
1269
|
-
})]
|
|
1270
|
-
}),
|
|
1271
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1272
|
-
className: QoderCredentialCard_module_css_default.label,
|
|
1273
|
-
htmlFor: "qoder-managed-credential",
|
|
1274
|
-
children: t("tokenLabel")
|
|
1275
|
-
}),
|
|
1276
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1277
|
-
id: "qoder-managed-credential",
|
|
1278
|
-
className: QoderCredentialCard_module_css_default.input,
|
|
1279
|
-
type: "password",
|
|
1280
|
-
autoComplete: "new-password",
|
|
1281
|
-
value: draft,
|
|
1282
|
-
disabled: !writable || busy,
|
|
1283
|
-
placeholder: configured ? t("configuredHint") : t("tokenPlaceholder"),
|
|
1284
|
-
onChange: (event) => setDraft(event.currentTarget.value)
|
|
1285
|
-
}),
|
|
1286
|
-
!writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1287
|
-
className: QoderCredentialCard_module_css_default.error,
|
|
1288
|
-
role: "alert",
|
|
1289
|
-
children: t("readOnly")
|
|
1290
|
-
}) : null,
|
|
1291
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1292
|
-
className: QoderCredentialCard_module_css_default.actions,
|
|
1293
|
-
children: [
|
|
1294
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1295
|
-
type: "button",
|
|
1296
|
-
className: QoderCredentialCard_module_css_default.secondary,
|
|
1297
|
-
disabled: busy,
|
|
1298
|
-
onClick: closeEditor,
|
|
1299
|
-
children: t("cancel")
|
|
1300
|
-
}),
|
|
1301
|
-
configured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1302
|
-
type: "button",
|
|
1303
|
-
className: QoderCredentialCard_module_css_default.danger,
|
|
1304
|
-
disabled: !writable || busy,
|
|
1305
|
-
onClick: () => {
|
|
1306
|
-
remove();
|
|
1307
|
-
},
|
|
1308
|
-
children: mutation === "removing" ? t("removing") : t("remove")
|
|
1309
|
-
}) : null,
|
|
1310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1311
|
-
type: "button",
|
|
1312
|
-
className: QoderCredentialCard_module_css_default.primary,
|
|
1313
|
-
disabled: busy || !regionDirty && normalized.length === 0 || regionDirty && !canModifyRegion || normalized.length > 0 && !writable,
|
|
1314
|
-
onClick: () => {
|
|
1315
|
-
save();
|
|
1316
|
-
},
|
|
1317
|
-
children: mutation === "saving" ? t("saving") : t("save")
|
|
1318
|
-
})
|
|
1319
|
-
]
|
|
1320
|
-
})
|
|
1321
|
-
]
|
|
1322
|
-
}) : null
|
|
1910
|
+
}) : null,
|
|
1911
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QoderBrowserLogin, {
|
|
1912
|
+
region,
|
|
1913
|
+
operations: operations.authorization,
|
|
1914
|
+
credentials: operations,
|
|
1915
|
+
onBusyChange: setAccountBusy,
|
|
1916
|
+
t
|
|
1917
|
+
}, region),
|
|
1918
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1919
|
+
className: QoderCredentialCard_module_css_default.sharedNote,
|
|
1920
|
+
children: t("sharedAuthorization")
|
|
1921
|
+
})
|
|
1323
1922
|
]
|
|
1324
1923
|
});
|
|
1325
1924
|
}
|
|
@@ -1868,8 +2467,26 @@ window.__ModuleLoader__.load({
|
|
|
1868
2467
|
const tierEvents = createSessionTierEvents();
|
|
1869
2468
|
ctx.effect(() => () => tierEvents.dispose(), "provider-qoder: session context tier events");
|
|
1870
2469
|
const readModelSnapshot = () => modelScope.getSnapshot();
|
|
2470
|
+
const authorizationOperations = {
|
|
2471
|
+
read: (region) => rpc.call("authorization", { region }),
|
|
2472
|
+
begin: (region) => rpc.call("beginLogin", { region }),
|
|
2473
|
+
cancel: (region) => rpc.call("cancelLogin", { region }),
|
|
2474
|
+
select: (region, method) => rpc.call("selectAuthorization", {
|
|
2475
|
+
region,
|
|
2476
|
+
method
|
|
2477
|
+
})
|
|
2478
|
+
};
|
|
1871
2479
|
const operations = {
|
|
2480
|
+
authorization: authorizationOperations,
|
|
1872
2481
|
describe: async () => {
|
|
2482
|
+
const result = await authorizationOperations.read(regionOf(readModelSnapshot().value));
|
|
2483
|
+
return result.ok ? {
|
|
2484
|
+
configured: result.value.configured && !result.value.expired,
|
|
2485
|
+
source: result.value.method,
|
|
2486
|
+
writable: result.value.writable
|
|
2487
|
+
} : void 0;
|
|
2488
|
+
},
|
|
2489
|
+
describePat: async () => {
|
|
1873
2490
|
try {
|
|
1874
2491
|
const response = await credentials.describe([qoderCredentialRef]);
|
|
1875
2492
|
return response.ok ? response.value[qoderCredentialRef] : void 0;
|
|
@@ -1879,7 +2496,13 @@ window.__ModuleLoader__.load({
|
|
|
1879
2496
|
},
|
|
1880
2497
|
store: async (value) => {
|
|
1881
2498
|
try {
|
|
1882
|
-
|
|
2499
|
+
const response = await credentials.set(qoderCredentialRef, value.trim());
|
|
2500
|
+
if (response.ok) {
|
|
2501
|
+
const region = regionOf(readModelSnapshot().value);
|
|
2502
|
+
const current = await authorizationOperations.read(region);
|
|
2503
|
+
if (current.ok && current.value.method !== "pat") return (await authorizationOperations.select(region, "pat")).ok;
|
|
2504
|
+
}
|
|
2505
|
+
return response.ok;
|
|
1883
2506
|
} catch {
|
|
1884
2507
|
return false;
|
|
1885
2508
|
}
|
|
@@ -1922,26 +2545,56 @@ window.__ModuleLoader__.load({
|
|
|
1922
2545
|
},
|
|
1923
2546
|
discoverModels: async () => await rpc.call("models", {}),
|
|
1924
2547
|
setSessionTier: async (sessionId, modelId, tierKey, region) => {
|
|
2548
|
+
const scope = {
|
|
2549
|
+
sessionId,
|
|
2550
|
+
modelId,
|
|
2551
|
+
tierKey,
|
|
2552
|
+
region
|
|
2553
|
+
};
|
|
1925
2554
|
try {
|
|
1926
|
-
const res = await rpc.call("sessionTier",
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
region
|
|
2555
|
+
const res = await rpc.call("sessionTier", scope);
|
|
2556
|
+
if (!res.ok) console.error("[Qoder context tier] Failed to save selection", {
|
|
2557
|
+
...scope,
|
|
2558
|
+
error: res.error
|
|
1931
2559
|
});
|
|
1932
2560
|
return res.ok ? res.value : void 0;
|
|
1933
|
-
} catch {
|
|
2561
|
+
} catch (error) {
|
|
2562
|
+
console.error("[Qoder context tier] Failed to save selection", {
|
|
2563
|
+
...scope,
|
|
2564
|
+
error
|
|
2565
|
+
});
|
|
1934
2566
|
return;
|
|
1935
2567
|
}
|
|
1936
2568
|
},
|
|
1937
2569
|
readSessionTier: async (scope) => {
|
|
1938
|
-
|
|
1939
|
-
|
|
2570
|
+
try {
|
|
2571
|
+
const result = await rpc.call("readSessionTier", scope);
|
|
2572
|
+
if (!result.ok) console.error("[Qoder context tier] Failed to read selection", {
|
|
2573
|
+
...scope,
|
|
2574
|
+
error: result.error
|
|
2575
|
+
});
|
|
2576
|
+
return result.ok ? result.value : void 0;
|
|
2577
|
+
} catch (error) {
|
|
2578
|
+
console.error("[Qoder context tier] Failed to read selection", {
|
|
2579
|
+
...scope,
|
|
2580
|
+
error
|
|
2581
|
+
});
|
|
2582
|
+
return;
|
|
2583
|
+
}
|
|
1940
2584
|
},
|
|
1941
2585
|
subscribeSessionTiers: (scope, listener) => tierEvents.subscribe(scope, listener),
|
|
1942
|
-
subscribe: (listener) =>
|
|
1943
|
-
|
|
1944
|
-
|
|
2586
|
+
subscribe: (listener) => {
|
|
2587
|
+
const reference = ctx.remote.$on("credentials/reference-updated", (ref) => {
|
|
2588
|
+
if (ref === "QODER_MANAGED_CREDENTIAL") listener();
|
|
2589
|
+
});
|
|
2590
|
+
const record = ctx.remote.$on("credentials/record-updated", (key) => {
|
|
2591
|
+
if (key === `provider-qoder/${regionOf(readModelSnapshot().value)}`) listener();
|
|
2592
|
+
});
|
|
2593
|
+
return () => {
|
|
2594
|
+
reference();
|
|
2595
|
+
record();
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
1945
2598
|
};
|
|
1946
2599
|
const rawT = ctx.locale.bind(localeNamespace);
|
|
1947
2600
|
const t = (key, values) => {
|
|
@@ -1953,6 +2606,17 @@ window.__ModuleLoader__.load({
|
|
|
1953
2606
|
* switch re-resolves provider copy instead of reusing a setup-time snapshot.
|
|
1954
2607
|
*/
|
|
1955
2608
|
const activeLocale = () => ctx.locale.getLocale().active;
|
|
2609
|
+
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
2610
|
+
name: "conversation.input.dock",
|
|
2611
|
+
id: "qoder-model-queue",
|
|
2612
|
+
order: 30,
|
|
2613
|
+
locale: localeNamespace,
|
|
2614
|
+
inject: (sessionId) => ({
|
|
2615
|
+
sessionId,
|
|
2616
|
+
rpc,
|
|
2617
|
+
t
|
|
2618
|
+
})
|
|
2619
|
+
}, QoderQueueStatus));
|
|
1956
2620
|
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
1957
2621
|
name: "settings.section",
|
|
1958
2622
|
id: "qoder",
|