@jayyuen66/dsh-ocr-review 0.1.10 → 0.1.12
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/CHANGELOG.md +54 -2
- package/README.md +8 -8
- package/README.zh-CN.md +9 -9
- package/THIRD_PARTY_NOTICES.md +11 -8
- package/client.js +54 -639
- package/cordis.patch.yml +3 -0
- package/docs/DETAIL.md +2 -2
- package/docs/DETAIL.zh.md +2 -2
- package/host.js +5 -5
- package/package.json +59 -57
package/client.js
CHANGED
|
@@ -8,6 +8,7 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
9
9
|
let react = require("react");
|
|
10
10
|
let zod = require("zod");
|
|
11
|
+
let _jayyuen66_dsh_plugin_shared_client = require("@jayyuen66/dsh-plugin-shared/client");
|
|
11
12
|
// src/ui-messages.ts
|
|
12
13
|
const UI_MESSAGES = {
|
|
13
14
|
zh: {
|
|
@@ -213,592 +214,6 @@ const UI_MESSAGES = {
|
|
|
213
214
|
binaryGuideDismiss: "Got it"
|
|
214
215
|
}
|
|
215
216
|
};
|
|
216
|
-
// node_modules/@jayyuen66/dsh-plugin-shared/dist/record.js
|
|
217
|
-
function e$3(e) {
|
|
218
|
-
return typeof e == `object` && !!e && !Array.isArray(e);
|
|
219
|
-
}
|
|
220
|
-
const t$3 = { absent: !0 };
|
|
221
|
-
function n$2(e, n) {
|
|
222
|
-
try {
|
|
223
|
-
return {
|
|
224
|
-
absent: !1,
|
|
225
|
-
value: e[n]
|
|
226
|
-
};
|
|
227
|
-
} catch {
|
|
228
|
-
return t$3;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
function i$1(r, i) {
|
|
232
|
-
let a = e$3(r) ? n$2(r, i) : t$3;
|
|
233
|
-
return a.absent ? void 0 : a.value;
|
|
234
|
-
}
|
|
235
|
-
// node_modules/@jayyuen66/dsh-plugin-shared/dist/card-apply.js
|
|
236
|
-
const e$2 = (e) => e.length > 0 && !(e in Object.prototype);
|
|
237
|
-
function t$2(e, t, n) {
|
|
238
|
-
n === void 0 ? e[t] = void 0 : Object.defineProperty(e, t, n);
|
|
239
|
-
}
|
|
240
|
-
function n$1(n, r, i) {
|
|
241
|
-
if (!e$2(r)) throw Error(`claimApply 的 flag 不得为空、也不得命中 Object.prototype 的成员(__proto__ 一类会让占位静默失灵或遮蔽全局成员):${r}`);
|
|
242
|
-
let a = globalThis, o = Object.hasOwn(a, r) ? a[r] : void 0;
|
|
243
|
-
if (o === !0 || typeof o == `symbol`) return !1;
|
|
244
|
-
let s = Object.getOwnPropertyDescriptor(a, r), c = Symbol(r);
|
|
245
|
-
a[r] = c;
|
|
246
|
-
try {
|
|
247
|
-
n.effect(() => () => {
|
|
248
|
-
a[r] === c && t$2(a, r, s);
|
|
249
|
-
}, i);
|
|
250
|
-
} catch (e) {
|
|
251
|
-
throw a[r] === c && t$2(a, r, s), e;
|
|
252
|
-
}
|
|
253
|
-
return !0;
|
|
254
|
-
}
|
|
255
|
-
// node_modules/@jayyuen66/dsh-plugin-shared/dist/card-diff.js
|
|
256
|
-
function e$1(t, n, r) {
|
|
257
|
-
if (t == null || n == null) return (t ?? null) === (n ?? null);
|
|
258
|
-
if (Object.is(t, n)) return !0;
|
|
259
|
-
if (typeof t != `object` || typeof n != `object`) return !1;
|
|
260
|
-
if (r.get(t) === n) return !0;
|
|
261
|
-
if (r.set(t, n), Array.isArray(t) || Array.isArray(n)) return !Array.isArray(t) || !Array.isArray(n) || t.length !== n.length ? !1 : t.every((t, i) => e$1(t, n[i], r));
|
|
262
|
-
let i = Object.keys(t), a = Object.keys(n);
|
|
263
|
-
return i.length === a.length && i.every((i) => Object.hasOwn(n, i) && e$1(Reflect.get(t, i), Reflect.get(n, i), r));
|
|
264
|
-
}
|
|
265
|
-
function t$1(t, n) {
|
|
266
|
-
let r = [];
|
|
267
|
-
for (let i of Object.keys(t)) e$1(t[i], n[i], /* @__PURE__ */ new WeakMap()) || r.push(i);
|
|
268
|
-
return r;
|
|
269
|
-
}
|
|
270
|
-
// node_modules/@jayyuen66/dsh-plugin-shared/dist/card-ui.js
|
|
271
|
-
const c = `
|
|
272
|
-
.dsu-form{display:flex;flex-direction:column}
|
|
273
|
-
.dsu-section{margin-top:24px;padding-top:24px;border-top:.5px solid var(--dsw-alias-border-l1)}
|
|
274
|
-
.dsu-form>.dsu-section:first-child{margin-top:0;padding-top:0;border-top:0}
|
|
275
|
-
.dsu-sectionTitle{margin:0;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary)}
|
|
276
|
-
.dsu-sectionHint{margin:4px 0 0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
277
|
-
.dsu-statusbar{display:flex;flex-wrap:wrap;gap:4px 8px;margin-top:8px;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
278
|
-
.dsu-field{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,360px);column-gap:32px;align-items:center;padding:12px 0;border-top:.5px solid var(--dsw-alias-border-l2)}
|
|
279
|
-
.dsu-fieldMeta{display:flex;flex-direction:column;gap:4px;min-width:0}
|
|
280
|
-
.dsu-labelRow{display:flex;align-items:center;gap:6px;min-width:0}
|
|
281
|
-
.dsu-label{font-size:13px;font-weight:500;line-height:1.5;color:var(--dsw-alias-label-primary)}
|
|
282
|
-
.dsu-labelMono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}
|
|
283
|
-
.dsu-hint{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
284
|
-
.dsu-control{min-width:0;display:flex;align-items:center;gap:8px}
|
|
285
|
-
.dsu-fieldWide{grid-template-columns:minmax(0,1fr);align-items:start}
|
|
286
|
-
.dsu-fieldWide .dsu-control{width:100%;max-width:720px;margin-top:2px}
|
|
287
|
-
.dsu-help{display:inline-flex;align-items:center;gap:6px;min-width:0}
|
|
288
|
-
.dsu-helpBtn{appearance:none;border:0;background:transparent;padding:0;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-tertiary);cursor:help;border-radius:50%;flex:none}
|
|
289
|
-
.dsu-help:hover .dsu-helpBtn,.dsu-helpBtn:focus-visible{color:var(--dsw-alias-label-primary)}
|
|
290
|
-
.dsu-helpBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
|
|
291
|
-
.dsu-tip{position:fixed;z-index:60;box-sizing:border-box;max-width:min(340px,calc(100vw - 16px));max-height:calc(100vh - 16px);overflow:auto;overflow-wrap:anywhere;padding:10px 12px;border-radius:10px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);box-shadow:0 12px 32px rgb(0 0 0 / 45%);font-size:12px;line-height:1.6;font-weight:400;color:var(--dsw-alias-label-secondary)}
|
|
292
|
-
.dsu-input{width:100%;height:34px;padding:0 12px;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font:inherit;font-size:13px}
|
|
293
|
-
.dsu-input:focus-visible{outline:none;border-color:var(--dsw-alias-state-business-primary)}
|
|
294
|
-
.dsu-input[aria-invalid="true"]{border-color:var(--dsw-alias-state-error-primary)}
|
|
295
|
-
.dsu-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}
|
|
296
|
-
.dsu-input::placeholder{color:var(--dsw-alias-label-tertiary)}
|
|
297
|
-
.dsu-textarea{height:auto;min-height:96px;padding:8px 12px;line-height:1.6;resize:vertical}
|
|
298
|
-
.dsu-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
|
|
299
|
-
.dsu-numberWrap{display:flex;flex-direction:column;gap:4px;width:100%;min-width:0}
|
|
300
|
-
.dsu-number{display:flex;align-items:center;gap:8px;min-width:0}
|
|
301
|
-
.dsu-number .dsu-input{min-width:0}
|
|
302
|
-
.dsu-unit{flex:none;font-size:12px;color:var(--dsw-alias-label-tertiary)}
|
|
303
|
-
.dsu-error{margin:0;font-size:12px;line-height:1.5;color:var(--dsw-alias-state-error-primary)}
|
|
304
|
-
.dsu-switch{appearance:none;width:36px;height:20px;border-radius:999px;border:0;padding:2px;background:var(--dsw-alias-border-l3);display:flex;align-items:center;cursor:pointer;flex:none;transition:background-color .16s}
|
|
305
|
-
.dsu-knob{width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-label-primary);transition:transform .16s,background-color .16s}
|
|
306
|
-
.dsu-switch[aria-checked="true"]{background:var(--dsw-alias-label-primary)}
|
|
307
|
-
.dsu-switch[aria-checked="true"] .dsu-knob{transform:translateX(16px);background:var(--dsw-alias-label-primary-foreground)}
|
|
308
|
-
.dsu-switch:disabled{opacity:.4;cursor:not-allowed}
|
|
309
|
-
.dsu-switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
|
|
310
|
-
.dsu-selectWrap{position:relative;width:100%;min-width:0}
|
|
311
|
-
.dsu-select{display:flex;align-items:center;justify-content:space-between;gap:8px;text-align:left;cursor:pointer}
|
|
312
|
-
.dsu-select[aria-expanded="true"]{border-color:var(--dsw-alias-state-business-primary)}
|
|
313
|
-
.dsu-selectValue{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
314
|
-
.dsu-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s}
|
|
315
|
-
.dsu-select[aria-expanded="true"] .dsu-chevron{transform:rotate(180deg)}
|
|
316
|
-
.dsu-menu{position:fixed;z-index:70;padding:4px;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);border-radius:12px;box-shadow:0 12px 32px rgb(0 0 0 / 50%);max-height:280px;overflow:auto}
|
|
317
|
-
.dsu-option{appearance:none;border:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.4;width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px;border-radius:8px;cursor:pointer;text-align:left}
|
|
318
|
-
.dsu-option:hover,.dsu-option[data-active="true"]{background:var(--dsw-alias-bg-layer-3)}
|
|
319
|
-
.dsu-option:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed}
|
|
320
|
-
.dsu-option:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}
|
|
321
|
-
.dsu-optionGroup{padding:6px 10px 2px;font-size:11px;font-weight:600;color:var(--dsw-alias-label-tertiary)}
|
|
322
|
-
.dsu-check{opacity:0;flex:none}
|
|
323
|
-
.dsu-option[aria-selected="true"] .dsu-check{opacity:1}
|
|
324
|
-
.dsu-savebar{display:flex;align-items:center;gap:8px;padding:12px 0;margin-top:24px;border-top:.5px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base)}
|
|
325
|
-
.dsu-savebar[data-dirty="true"]{position:sticky;bottom:0;z-index:2;box-shadow:0 -12px 24px rgb(0 0 0 / 35%)}
|
|
326
|
-
.dsu-btn{appearance:none;border:.5px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:1.5;border-radius:var(--dsw-radius-md);padding:5px 14px;cursor:pointer;transition:background-color .12s,border-color .12s,color .12s,filter .12s}
|
|
327
|
-
.dsu-btn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l3)}
|
|
328
|
-
.dsu-btn:active:not(:disabled){background:var(--dsw-alias-bg-layer-1)}
|
|
329
|
-
.dsu-btn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}
|
|
330
|
-
.dsu-btn:disabled{opacity:.4;cursor:not-allowed}
|
|
331
|
-
.dsu-btnPrimary{background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}
|
|
332
|
-
.dsu-btnPrimary:hover:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.9)}
|
|
333
|
-
.dsu-btnPrimary:active:not(:disabled){background:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);filter:brightness(.84)}
|
|
334
|
-
.dsu-btnDanger{color:var(--dsw-alias-state-error-primary)}
|
|
335
|
-
.dsu-btnDanger:hover:not(:disabled){color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2)}
|
|
336
|
-
.dsu-status{margin-left:auto;font-size:12px;color:var(--dsw-alias-label-tertiary)}
|
|
337
|
-
.dsu-statusError{color:var(--dsw-alias-state-error-primary)}
|
|
338
|
-
.dsu-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(200px,100%),1fr));gap:0 24px}
|
|
339
|
-
.dsu-grid>.dsu-field{display:flex;flex-direction:column;align-items:stretch;gap:6px;padding:10px 0;border-top:.5px solid var(--dsw-alias-border-l1)}
|
|
340
|
-
.dsu-grid>.dsu-field .dsu-control{width:100%}
|
|
341
|
-
@media (max-width:640px){
|
|
342
|
-
.dsu-field{grid-template-columns:minmax(0,1fr);align-items:start}
|
|
343
|
-
.dsu-control{width:100%;max-width:720px}
|
|
344
|
-
.dsu-section{margin-top:20px;padding-top:20px}
|
|
345
|
-
}
|
|
346
|
-
@media (prefers-reduced-motion:reduce){
|
|
347
|
-
.dsu-switch,.dsu-knob,.dsu-chevron,.dsu-btn{transition:none}
|
|
348
|
-
}
|
|
349
|
-
`;
|
|
350
|
-
function l(e, t = 30) {
|
|
351
|
-
return e.length <= t ? { hint: e } : { detail: e };
|
|
352
|
-
}
|
|
353
|
-
function u(t) {
|
|
354
|
-
return (0, react.createElement)(`div`, { className: `dsu-form` }, t.children);
|
|
355
|
-
}
|
|
356
|
-
function d(t) {
|
|
357
|
-
return (0, react.createElement)(`section`, { className: `dsu-section` }, (0, react.createElement)(`h2`, { className: `dsu-sectionTitle` }, t.title), t.hint === void 0 ? null : (0, react.createElement)(`p`, { className: `dsu-sectionHint` }, t.hint), t.children);
|
|
358
|
-
}
|
|
359
|
-
function m(a) {
|
|
360
|
-
let c = (0, react.useId)(), [l, u] = (0, react.useState)(!1), [d, f] = (0, react.useState)(!1), p = (0, react.useRef)(!1), m = (0, react.useRef)(!1), h = (0, react.useRef)(!1), g = (0, react.useRef)(null), _ = (0, react.useRef)(null), v = (0, react.useRef)(null), y = (0, react.useCallback)(() => {
|
|
361
|
-
v.current !== null && (clearTimeout(v.current), v.current = null);
|
|
362
|
-
}, []), b = (0, react.useCallback)(() => {
|
|
363
|
-
let e = g.current, t = _.current;
|
|
364
|
-
/* v8 ignore next 3 -- place 只在 open 的 layout effect 与挂载期监听器里调用;refs 为空只可能是卸载竞态 */
|
|
365
|
-
if (e === null || t === null) return;
|
|
366
|
-
let n = e.getBoundingClientRect(), r = t.offsetWidth, i = t.offsetHeight, { left: a } = n, o = n.bottom + 8;
|
|
367
|
-
o + i > window.innerHeight - 8 && (o = n.top - i - 8), a + r > window.innerWidth - 8 && (a = window.innerWidth - r - 8);
|
|
368
|
-
let s = Math.max(8, window.innerWidth - r - 8), c = Math.max(8, window.innerHeight - i - 8);
|
|
369
|
-
t.style.left = `${Math.min(Math.max(8, a), s)}px`, t.style.top = `${Math.min(Math.max(8, o), c)}px`;
|
|
370
|
-
}, []), x = (0, react.useCallback)(() => {
|
|
371
|
-
y(), h.current = !1, f(!1), u(!1);
|
|
372
|
-
}, [y]), S = (0, react.useCallback)(() => {
|
|
373
|
-
y(), u(!0);
|
|
374
|
-
}, [y]), C = (0, react.useCallback)(() => {
|
|
375
|
-
y(), !(p.current || m.current || h.current) && (v.current = setTimeout(() => {
|
|
376
|
-
/* v8 ignore next 3 -- 任何重新进入/钉住都会 cancelHide;这次复查只防未来的异步路径 */
|
|
377
|
-
v.current = null, p.current || m.current || h.current || u(!1);
|
|
378
|
-
}, 120));
|
|
379
|
-
}, [y]), w = (0, react.useCallback)((e) => {
|
|
380
|
-
h.current = e, f(e);
|
|
381
|
-
}, []);
|
|
382
|
-
(0, react.useLayoutEffect)(() => {
|
|
383
|
-
if (!l) return () => {};
|
|
384
|
-
b();
|
|
385
|
-
let e = (e) => {
|
|
386
|
-
let { target: t } = e;
|
|
387
|
-
t instanceof Node && _.current?.contains(t) === !0 || (h.current ? b() : x());
|
|
388
|
-
}, t = () => {
|
|
389
|
-
b();
|
|
390
|
-
};
|
|
391
|
-
return window.addEventListener(`scroll`, e, !0), window.addEventListener(`resize`, t), () => {
|
|
392
|
-
window.removeEventListener(`scroll`, e, !0), window.removeEventListener(`resize`, t);
|
|
393
|
-
};
|
|
394
|
-
}, [
|
|
395
|
-
l,
|
|
396
|
-
a.detail,
|
|
397
|
-
b,
|
|
398
|
-
x
|
|
399
|
-
]), (0, react.useEffect)(() => {
|
|
400
|
-
if (!l) return () => {};
|
|
401
|
-
let e = (e) => {
|
|
402
|
-
e.key === `Escape` && x();
|
|
403
|
-
};
|
|
404
|
-
return document.addEventListener(`keydown`, e), () => {
|
|
405
|
-
document.removeEventListener(`keydown`, e);
|
|
406
|
-
};
|
|
407
|
-
}, [l, x]), (0, react.useEffect)(() => y, [y]);
|
|
408
|
-
let T = (0, react.createElement)(`button`, {
|
|
409
|
-
ref: g,
|
|
410
|
-
type: `button`,
|
|
411
|
-
className: `dsu-helpBtn`,
|
|
412
|
-
"aria-label": `${a.label} 说明`,
|
|
413
|
-
"aria-describedby": c,
|
|
414
|
-
"aria-pressed": d,
|
|
415
|
-
onClick: () => {
|
|
416
|
-
h.current ? x() : (w(!0), S());
|
|
417
|
-
}
|
|
418
|
-
}, (0, react.createElement)(`svg`, {
|
|
419
|
-
width: 12,
|
|
420
|
-
height: 12,
|
|
421
|
-
viewBox: `0 0 14 14`,
|
|
422
|
-
"aria-hidden": !0
|
|
423
|
-
}, (0, react.createElement)(`circle`, {
|
|
424
|
-
cx: 7,
|
|
425
|
-
cy: 7,
|
|
426
|
-
r: 6,
|
|
427
|
-
fill: `none`,
|
|
428
|
-
stroke: `currentColor`,
|
|
429
|
-
strokeWidth: 1.2
|
|
430
|
-
}), (0, react.createElement)(`path`, {
|
|
431
|
-
d: `M7 6.2v4`,
|
|
432
|
-
stroke: `currentColor`,
|
|
433
|
-
strokeWidth: 1.3,
|
|
434
|
-
strokeLinecap: `round`
|
|
435
|
-
}), (0, react.createElement)(`circle`, {
|
|
436
|
-
cx: 7,
|
|
437
|
-
cy: 4.3,
|
|
438
|
-
r: .8,
|
|
439
|
-
fill: `currentColor`
|
|
440
|
-
}))), E = (0, react.createElement)(`div`, {
|
|
441
|
-
ref: _,
|
|
442
|
-
id: c,
|
|
443
|
-
role: `tooltip`,
|
|
444
|
-
className: `dsu-tip`,
|
|
445
|
-
hidden: !l
|
|
446
|
-
}, a.detail), D = a.showLabel === !1 ? null : (0, react.createElement)(`span`, { className: `dsu-label${a.compact === !0 ? ` dsu-labelMono` : ``}` }, a.label);
|
|
447
|
-
return (0, react.createElement)(`span`, {
|
|
448
|
-
className: `dsu-help`,
|
|
449
|
-
onMouseEnter: () => {
|
|
450
|
-
p.current = !0, S();
|
|
451
|
-
},
|
|
452
|
-
onMouseLeave: () => {
|
|
453
|
-
p.current = !1, C();
|
|
454
|
-
},
|
|
455
|
-
onFocus: () => {
|
|
456
|
-
m.current = !0, S();
|
|
457
|
-
},
|
|
458
|
-
onBlur: (e) => {
|
|
459
|
-
let t = e.relatedTarget;
|
|
460
|
-
t instanceof Node && e.currentTarget.contains(t) || (m.current = !1, C());
|
|
461
|
-
}
|
|
462
|
-
}, D, T, E);
|
|
463
|
-
}
|
|
464
|
-
function h(t) {
|
|
465
|
-
let n = `dsu-label${t.compact === !0 ? ` dsu-labelMono` : ``}`, r = t.controlId === void 0 ? (0, react.createElement)(`span`, { className: n }, t.label) : (0, react.createElement)(`label`, {
|
|
466
|
-
className: n,
|
|
467
|
-
htmlFor: t.controlId
|
|
468
|
-
}, t.label);
|
|
469
|
-
return (0, react.createElement)(`div`, { className: `dsu-labelRow` }, r, t.detail === void 0 ? null : (0, react.createElement)(m, {
|
|
470
|
-
label: t.label,
|
|
471
|
-
detail: t.detail,
|
|
472
|
-
showLabel: !1
|
|
473
|
-
}));
|
|
474
|
-
}
|
|
475
|
-
function g(t) {
|
|
476
|
-
let n = t.controlId === void 0 ? void 0 : `${t.controlId}-hint`;
|
|
477
|
-
return (0, react.createElement)(`div`, { className: `dsu-field${t.wide === !0 ? ` dsu-fieldWide` : ``}` }, (0, react.createElement)(`div`, { className: `dsu-fieldMeta` }, (0, react.createElement)(h, {
|
|
478
|
-
label: t.label,
|
|
479
|
-
detail: t.detail,
|
|
480
|
-
compact: t.compact,
|
|
481
|
-
controlId: t.controlId
|
|
482
|
-
}), t.hint === void 0 ? null : (0, react.createElement)(`p`, {
|
|
483
|
-
className: `dsu-hint`,
|
|
484
|
-
id: n
|
|
485
|
-
}, t.hint)), (0, react.createElement)(`div`, { className: `dsu-control` }, t.children));
|
|
486
|
-
}
|
|
487
|
-
function _(t) {
|
|
488
|
-
let n = (0, react.useId)(), i = t.hint === void 0 ? void 0 : `${n}-hint`;
|
|
489
|
-
return (0, react.createElement)(g, {
|
|
490
|
-
...t,
|
|
491
|
-
controlId: n
|
|
492
|
-
}, (0, react.createElement)(`button`, {
|
|
493
|
-
type: `button`,
|
|
494
|
-
role: `switch`,
|
|
495
|
-
id: n,
|
|
496
|
-
className: `dsu-switch`,
|
|
497
|
-
"aria-checked": t.checked,
|
|
498
|
-
"aria-describedby": i,
|
|
499
|
-
"data-field": t.field,
|
|
500
|
-
disabled: t.disabled === !0,
|
|
501
|
-
onClick: () => {
|
|
502
|
-
t.onChange(!t.checked);
|
|
503
|
-
}
|
|
504
|
-
}, (0, react.createElement)(`span`, { className: `dsu-knob` })));
|
|
505
|
-
}
|
|
506
|
-
function v(t) {
|
|
507
|
-
let i = typeof t.value == `number` && Number.isFinite(t.value) ? String(t.value) : ``, [a, c] = (0, react.useState)(i), [l, u] = (0, react.useState)(!1), d = (0, react.useRef)(void 0), f = (0, react.useId)(), p = (0, react.useId)(), m = [t.hint === void 0 ? void 0 : `${f}-hint`, l ? p : void 0].filter((e) => e !== void 0), h = m.length === 0 ? void 0 : m.join(` `);
|
|
508
|
-
(0, react.useEffect)(() => {
|
|
509
|
-
t.value !== d.current && (d.current = t.value, c(i), u(!1));
|
|
510
|
-
}, [t.value, i]);
|
|
511
|
-
let _ = (e) => {
|
|
512
|
-
let n = t.min ?? -1 / 0, r = t.max ?? 1 / 0;
|
|
513
|
-
if (!Number.isFinite(e) || e < n || e > r) return !1;
|
|
514
|
-
let { step: i } = t;
|
|
515
|
-
if (i === void 0 || i <= 0) return !0;
|
|
516
|
-
let a = (e - (t.min ?? 0)) / i;
|
|
517
|
-
return Math.abs(a - Math.round(a)) < 1e-9;
|
|
518
|
-
}, v = (e) => {
|
|
519
|
-
if (c(e), e === ``) {
|
|
520
|
-
u(!1), d.current = void 0, t.onChange(void 0);
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
let n = Number(e);
|
|
524
|
-
_(n) ? (u(!1), d.current = n, t.onChange(n)) : u(!0);
|
|
525
|
-
}, y = () => {
|
|
526
|
-
a === `` || l || c(String(Number(a)));
|
|
527
|
-
};
|
|
528
|
-
return (0, react.createElement)(g, {
|
|
529
|
-
...t,
|
|
530
|
-
controlId: f
|
|
531
|
-
}, (0, react.createElement)(`div`, { className: `dsu-numberWrap` }, (0, react.createElement)(`div`, { className: `dsu-number` }, (0, react.createElement)(`input`, {
|
|
532
|
-
className: `dsu-input`,
|
|
533
|
-
type: `number`,
|
|
534
|
-
inputMode: `numeric`,
|
|
535
|
-
id: f,
|
|
536
|
-
value: a,
|
|
537
|
-
min: t.min,
|
|
538
|
-
max: t.max,
|
|
539
|
-
step: t.step,
|
|
540
|
-
placeholder: t.placeholder,
|
|
541
|
-
"aria-invalid": l || void 0,
|
|
542
|
-
"aria-describedby": h,
|
|
543
|
-
"data-field": t.field,
|
|
544
|
-
disabled: t.disabled === !0,
|
|
545
|
-
onChange: (e) => {
|
|
546
|
-
v(e.target.value);
|
|
547
|
-
},
|
|
548
|
-
onBlur: y
|
|
549
|
-
}), t.unit === void 0 ? null : (0, react.createElement)(`span`, { className: `dsu-unit` }, t.unit)), l ? (0, react.createElement)(`p`, {
|
|
550
|
-
className: `dsu-error`,
|
|
551
|
-
id: p
|
|
552
|
-
}, t.invalidHint) : null));
|
|
553
|
-
}
|
|
554
|
-
function y(t) {
|
|
555
|
-
let [i, a] = (0, react.useState)(t.value), [o, c] = (0, react.useState)(!1), l = (0, react.useId)(), u = t.hint === void 0 ? void 0 : `${l}-hint`;
|
|
556
|
-
(0, react.useEffect)(() => {
|
|
557
|
-
o || a(t.value);
|
|
558
|
-
}, [t.value, o]);
|
|
559
|
-
let d = {
|
|
560
|
-
id: l,
|
|
561
|
-
className: `dsu-input${t.multiline === !0 ? ` dsu-textarea` : ``}${t.monospace === !0 ? ` dsu-mono` : ``}`,
|
|
562
|
-
value: i,
|
|
563
|
-
placeholder: t.placeholder,
|
|
564
|
-
"aria-describedby": u,
|
|
565
|
-
"data-field": t.field,
|
|
566
|
-
disabled: t.disabled === !0,
|
|
567
|
-
onFocus: () => {
|
|
568
|
-
c(!0);
|
|
569
|
-
},
|
|
570
|
-
onBlur: () => {
|
|
571
|
-
c(!1);
|
|
572
|
-
},
|
|
573
|
-
onChange: (e) => {
|
|
574
|
-
a(e.target.value), t.onChange(e.target.value);
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
return (0, react.createElement)(g, {
|
|
578
|
-
...t,
|
|
579
|
-
controlId: l
|
|
580
|
-
}, t.multiline === !0 ? (0, react.createElement)(`textarea`, d) : (0, react.createElement)(`input`, d));
|
|
581
|
-
}
|
|
582
|
-
function x(c) {
|
|
583
|
-
let [l, u] = (0, react.useState)(!1), [d, f] = (0, react.useState)(0), p = (0, react.useRef)(null), m = (0, react.useRef)(null), h = (0, react.useId)(), _ = (0, react.useId)(), v = c.hint === void 0 ? void 0 : `${_}-hint`, { disabled: y, value: b, options: x, onChange: S } = c, C = (0, react.useMemo)(() => x.map((e, t) => ({
|
|
584
|
-
option: e,
|
|
585
|
-
index: t
|
|
586
|
-
})).filter((e) => e.option.disabled !== !0), [x]), w = x.find((e) => e.value === b)?.label ?? b, T = x[d], E = T !== void 0 && T.disabled !== !0, D = (0, react.useCallback)(() => {
|
|
587
|
-
let e = p.current, t = m.current;
|
|
588
|
-
/* v8 ignore next 3 -- place 只在 open 的 layout effect 里调用;refs 为空只可能是卸载竞态 */
|
|
589
|
-
if (e === null || t === null) return;
|
|
590
|
-
let n = e.getBoundingClientRect(), r = Math.min(n.width, window.innerWidth - 16), { left: i } = n;
|
|
591
|
-
i + r > window.innerWidth - 8 && (i = window.innerWidth - r - 8);
|
|
592
|
-
let a = t.offsetHeight, o = n.bottom + 6;
|
|
593
|
-
o + a > window.innerHeight - 8 && (o = n.top - a - 6);
|
|
594
|
-
let s = Math.max(8, window.innerWidth - r - 8), c = Math.max(8, window.innerHeight - a - 8);
|
|
595
|
-
t.style.width = `${r}px`, t.style.left = `${Math.min(Math.max(8, i), s)}px`, t.style.top = `${Math.min(Math.max(8, o), c)}px`;
|
|
596
|
-
}, []), O = (0, react.useCallback)(() => {
|
|
597
|
-
u(!1);
|
|
598
|
-
}, []), k = (0, react.useCallback)(() => {
|
|
599
|
-
if (y === !0) return;
|
|
600
|
-
let e = C.find((e) => e.option.value === b) ?? C.at(0);
|
|
601
|
-
e !== void 0 && (f(e.index), u(!0));
|
|
602
|
-
}, [
|
|
603
|
-
y,
|
|
604
|
-
b,
|
|
605
|
-
C
|
|
606
|
-
]), A = (0, react.useCallback)((e) => {
|
|
607
|
-
/* v8 ignore next 3 -- 浮层只能经由 openMenu 打开;组件禁用时打不开 */
|
|
608
|
-
if (y === !0) return;
|
|
609
|
-
let t = x[e];
|
|
610
|
-
/* v8 ignore next 3 -- disabled 选项在浏览器里不派发 click;越界下标由调用面保证 */
|
|
611
|
-
t !== void 0 && t.disabled !== !0 && (S(t.value), O(), p.current?.focus());
|
|
612
|
-
}, [
|
|
613
|
-
y,
|
|
614
|
-
x,
|
|
615
|
-
S,
|
|
616
|
-
O
|
|
617
|
-
]), j = (0, react.useCallback)((e) => {
|
|
618
|
-
let t = C.findIndex((e) => e.index === d);
|
|
619
|
-
/* v8 ignore next 5 -- open 时归一 effect 已保证 enabled 非空且 active 落在可用项上 */
|
|
620
|
-
if (t === -1 || C.length === 0) return;
|
|
621
|
-
let n = (t + e + C.length) % C.length, r = C[n];
|
|
622
|
-
/* v8 ignore next 3 -- next 由取模保证在界内 */
|
|
623
|
-
r !== void 0 && f(r.index);
|
|
624
|
-
}, [d, C]);
|
|
625
|
-
(0, react.useLayoutEffect)(() => {
|
|
626
|
-
if (!l) return () => {};
|
|
627
|
-
D();
|
|
628
|
-
let e = (e) => {
|
|
629
|
-
let t = e.target;
|
|
630
|
-
m.current?.contains(t) !== !0 && p.current?.contains(t) !== !0 && O();
|
|
631
|
-
}, t = (e) => {
|
|
632
|
-
let { target: t } = e;
|
|
633
|
-
t instanceof Node && m.current?.contains(t) === !0 || O();
|
|
634
|
-
}, n = () => {
|
|
635
|
-
D();
|
|
636
|
-
};
|
|
637
|
-
return document.addEventListener(`pointerdown`, e, !0), window.addEventListener(`scroll`, t, !0), window.addEventListener(`resize`, n), () => {
|
|
638
|
-
document.removeEventListener(`pointerdown`, e, !0), window.removeEventListener(`scroll`, t, !0), window.removeEventListener(`resize`, n);
|
|
639
|
-
};
|
|
640
|
-
}, [
|
|
641
|
-
l,
|
|
642
|
-
c.options,
|
|
643
|
-
D,
|
|
644
|
-
O
|
|
645
|
-
]), (0, react.useEffect)(() => {
|
|
646
|
-
if (!l) return;
|
|
647
|
-
if (y === !0 || C.length === 0) {
|
|
648
|
-
O();
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
if (C.some((e) => e.index === d)) return;
|
|
652
|
-
let e = C.find((e) => e.option.value === b) ?? C.at(0);
|
|
653
|
-
/* v8 ignore next 3 -- enabled 非空在上一分支已保证 */
|
|
654
|
-
e !== void 0 && f(e.index);
|
|
655
|
-
}, [
|
|
656
|
-
l,
|
|
657
|
-
y,
|
|
658
|
-
b,
|
|
659
|
-
x,
|
|
660
|
-
d,
|
|
661
|
-
O,
|
|
662
|
-
C
|
|
663
|
-
]), (0, react.useLayoutEffect)(() => {
|
|
664
|
-
if (!l) return;
|
|
665
|
-
let e = m.current;
|
|
666
|
-
/* v8 ignore next 2 -- 同上,menu 在 open 的 commit 之后必然已挂上 */
|
|
667
|
-
if (e === null) return;
|
|
668
|
-
let t = e.querySelector(`[data-active="true"]`);
|
|
669
|
-
/* v8 ignore next 2 -- active 已由归一 effect 保证落在可用项上 */
|
|
670
|
-
t !== null && (t.offsetTop < e.scrollTop ? e.scrollTop = t.offsetTop : t.offsetTop + t.offsetHeight > e.scrollTop + e.clientHeight && (e.scrollTop = t.offsetTop + t.offsetHeight - e.clientHeight));
|
|
671
|
-
}, [
|
|
672
|
-
l,
|
|
673
|
-
d,
|
|
674
|
-
x
|
|
675
|
-
]);
|
|
676
|
-
let M = (e) => {
|
|
677
|
-
if (e.key === `ArrowDown` || e.key === `ArrowUp`) {
|
|
678
|
-
if (e.preventDefault(), !l) {
|
|
679
|
-
k();
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
j(e.key === `ArrowDown` ? 1 : -1);
|
|
683
|
-
} else if (e.key === `Home` || e.key === `End`) {
|
|
684
|
-
if (e.preventDefault(), l || k(), C.length === 0) return;
|
|
685
|
-
let t = e.key === `Home` ? C.at(0) : C.at(-1);
|
|
686
|
-
/* v8 ignore next 3 -- enabled 为空已在上一条返回 */
|
|
687
|
-
if (t === void 0) return;
|
|
688
|
-
f(t.index);
|
|
689
|
-
} else if (e.key === `Enter` || e.key === ` `) {
|
|
690
|
-
if (e.preventDefault(), !l) {
|
|
691
|
-
k();
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
A(d);
|
|
695
|
-
} else (e.key === `Tab` || e.key === `Escape`) && O();
|
|
696
|
-
}, N = [], P;
|
|
697
|
-
for (let [t, n] of x.entries()) n.group !== P && (n.group !== void 0 && N.push((0, react.createElement)(`div`, {
|
|
698
|
-
key: `group-${t}-${n.group}`,
|
|
699
|
-
className: `dsu-optionGroup`,
|
|
700
|
-
role: `presentation`
|
|
701
|
-
}, n.group)), P = n.group), N.push((0, react.createElement)(`button`, {
|
|
702
|
-
key: `option-${n.value}`,
|
|
703
|
-
type: `button`,
|
|
704
|
-
role: `option`,
|
|
705
|
-
id: `${h}-${t}`,
|
|
706
|
-
className: `dsu-option`,
|
|
707
|
-
tabIndex: -1,
|
|
708
|
-
"aria-selected": n.value === c.value,
|
|
709
|
-
"data-active": t === d,
|
|
710
|
-
disabled: n.disabled === !0,
|
|
711
|
-
onMouseDown: (e) => {
|
|
712
|
-
e.preventDefault();
|
|
713
|
-
},
|
|
714
|
-
onClick: () => {
|
|
715
|
-
A(t);
|
|
716
|
-
},
|
|
717
|
-
onMouseEnter: () => {
|
|
718
|
-
/* v8 ignore next -- happy-dom 对 disabled 元素不派发 mouse 事件;浏览器实现各有差异,保留禁用检查 */
|
|
719
|
-
n.disabled !== !0 && f(t);
|
|
720
|
-
}
|
|
721
|
-
}, (0, react.createElement)(`span`, null, n.label), (0, react.createElement)(`svg`, {
|
|
722
|
-
className: `dsu-check`,
|
|
723
|
-
width: 14,
|
|
724
|
-
height: 14,
|
|
725
|
-
viewBox: `0 0 14 14`,
|
|
726
|
-
"aria-hidden": !0
|
|
727
|
-
}, (0, react.createElement)(`path`, {
|
|
728
|
-
d: `M2.5 7.5l3 3 6-7`,
|
|
729
|
-
fill: `none`,
|
|
730
|
-
stroke: `currentColor`,
|
|
731
|
-
strokeWidth: 1.5,
|
|
732
|
-
strokeLinecap: `round`,
|
|
733
|
-
strokeLinejoin: `round`
|
|
734
|
-
}))));
|
|
735
|
-
return (0, react.createElement)(g, {
|
|
736
|
-
...c,
|
|
737
|
-
controlId: _
|
|
738
|
-
}, (0, react.createElement)(`div`, {
|
|
739
|
-
className: `dsu-selectWrap`,
|
|
740
|
-
onBlur: (e) => {
|
|
741
|
-
let t = e.relatedTarget;
|
|
742
|
-
t instanceof Node && e.currentTarget.contains(t) || O();
|
|
743
|
-
}
|
|
744
|
-
}, (0, react.createElement)(`button`, {
|
|
745
|
-
ref: p,
|
|
746
|
-
type: `button`,
|
|
747
|
-
id: _,
|
|
748
|
-
className: `dsu-select dsu-input`,
|
|
749
|
-
role: `combobox`,
|
|
750
|
-
"aria-haspopup": `listbox`,
|
|
751
|
-
"aria-expanded": l,
|
|
752
|
-
"aria-controls": `${h}-list`,
|
|
753
|
-
"aria-activedescendant": l && E ? `${h}-${d}` : void 0,
|
|
754
|
-
"aria-describedby": v,
|
|
755
|
-
"data-field": c.field,
|
|
756
|
-
disabled: y === !0 || x.length === 0,
|
|
757
|
-
onClick: () => {
|
|
758
|
-
l ? O() : k();
|
|
759
|
-
},
|
|
760
|
-
onKeyDown: M
|
|
761
|
-
}, (0, react.createElement)(`span`, { className: `dsu-selectValue` }, w), (0, react.createElement)(`svg`, {
|
|
762
|
-
className: `dsu-chevron`,
|
|
763
|
-
width: 14,
|
|
764
|
-
height: 14,
|
|
765
|
-
viewBox: `0 0 14 14`,
|
|
766
|
-
"aria-hidden": !0
|
|
767
|
-
}, (0, react.createElement)(`path`, {
|
|
768
|
-
d: `M3 5l4 4 4-4`,
|
|
769
|
-
fill: `none`,
|
|
770
|
-
stroke: `currentColor`,
|
|
771
|
-
strokeWidth: 1.5,
|
|
772
|
-
strokeLinecap: `round`,
|
|
773
|
-
strokeLinejoin: `round`
|
|
774
|
-
}))), (0, react.createElement)(`div`, {
|
|
775
|
-
ref: m,
|
|
776
|
-
id: `${h}-list`,
|
|
777
|
-
role: `listbox`,
|
|
778
|
-
className: `dsu-menu`,
|
|
779
|
-
"aria-label": c.label,
|
|
780
|
-
hidden: !l
|
|
781
|
-
}, ...N)));
|
|
782
|
-
}
|
|
783
|
-
function S(t) {
|
|
784
|
-
let n = !t.writable || t.busy || !t.dirty, r;
|
|
785
|
-
return r = t.error === null ? t.writable ? t.dirty ? t.dirtyLabel : t.cleanLabel : t.readOnlyLabel : t.error, (0, react.createElement)(`div`, {
|
|
786
|
-
className: `dsu-savebar`,
|
|
787
|
-
"data-dirty": t.dirty
|
|
788
|
-
}, (0, react.createElement)(`button`, {
|
|
789
|
-
type: `button`,
|
|
790
|
-
className: `dsu-btn dsu-btnPrimary`,
|
|
791
|
-
"data-field": `save`,
|
|
792
|
-
disabled: n,
|
|
793
|
-
onClick: t.onSave
|
|
794
|
-
}, t.busy ? t.savingLabel : t.saveLabel), (0, react.createElement)(`button`, {
|
|
795
|
-
type: `button`,
|
|
796
|
-
className: `dsu-btn`,
|
|
797
|
-
"data-field": `discard`,
|
|
798
|
-
disabled: n,
|
|
799
|
-
onClick: t.onDiscard
|
|
800
|
-
}, t.revertLabel), (0, react.createElement)(`span`, { className: t.error === null ? `dsu-status` : `dsu-status dsu-statusError` }, r));
|
|
801
|
-
}
|
|
802
217
|
// lib/remote-shape.ts
|
|
803
218
|
/** 宿主服务键 = 客户端线上命名空间(两侧共用的唯一来源)。 */
|
|
804
219
|
const OCR_REMOTE_NAMESPACE = "ocrReview";
|
|
@@ -953,9 +368,9 @@ const OCR_DESCRIPTORS = [
|
|
|
953
368
|
}
|
|
954
369
|
];
|
|
955
370
|
/** 这个值能当远程面用吗(只核我们要调的那一位;服务来自别的实现或版本时保守当作没有)。 */
|
|
956
|
-
const isRemoteMounter = (value) =>
|
|
371
|
+
const isRemoteMounter = (value) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(value) && typeof value["$mount"] === "function";
|
|
957
372
|
/** 同上:命名空间服务(挂载之后才有,缺它说明网关没认这枚贡献)。 */
|
|
958
|
-
const isOcrNamespace = (value) =>
|
|
373
|
+
const isOcrNamespace = (value) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(value) && typeof value["providers"] === "function" && typeof value["select"] === "function" && typeof value["migrate"] === "function" && typeof value["test"] === "function" && typeof value["probe"] === "function" && typeof value["mcp"] === "function" && typeof value["saveMcp"] === "function" && typeof value["auth"] === "function" && typeof value["chatGpt"] === "function";
|
|
959
374
|
/** 网关回执 → 值;载体/网关失败抛(卡片那层按「请求失败」显示)。
|
|
960
375
|
* 机器码放 `cause`:卡片只展示 message,`REMOTE_...` 这类内部标识不是给用户看的。 */
|
|
961
376
|
function unwrap(result) {
|
|
@@ -1114,7 +529,7 @@ const PROVIDER_SCHEMA = zod.z.object({
|
|
|
1114
529
|
displayName: STRING_OR_EMPTY,
|
|
1115
530
|
apiKeyEnv: NULLABLE_STRING,
|
|
1116
531
|
baseURL: STRING_OR_EMPTY,
|
|
1117
|
-
models: zod.z.preprocess((value) => Array.isArray(value) ? value.map((item) =>
|
|
532
|
+
models: zod.z.preprocess((value) => Array.isArray(value) ? value.map((item) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(item) ? item : {}) : [], zod.z.array(MODEL_SCHEMA)),
|
|
1118
533
|
hasKey: TRUE_ONLY
|
|
1119
534
|
});
|
|
1120
535
|
const CURRENT_SCHEMA = zod.z.object({
|
|
@@ -1174,7 +589,7 @@ function binaryOf(raw) {
|
|
|
1174
589
|
async function loadCliStatus(reader) {
|
|
1175
590
|
if (reader === void 0) return null;
|
|
1176
591
|
try {
|
|
1177
|
-
return binaryOf(
|
|
592
|
+
return binaryOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(await reader.providers(), "ocrBinary"));
|
|
1178
593
|
} catch {
|
|
1179
594
|
return null;
|
|
1180
595
|
}
|
|
@@ -1196,10 +611,10 @@ const EMPTY_PAYLOAD = {
|
|
|
1196
611
|
ocrBinary: null
|
|
1197
612
|
};
|
|
1198
613
|
const PROVIDERS_PAYLOAD_SCHEMA = zod.z.object({
|
|
1199
|
-
providers: zod.z.preprocess((value) => Array.isArray(value) ? value.map((item) =>
|
|
1200
|
-
current: zod.z.preprocess((value) =>
|
|
614
|
+
providers: zod.z.preprocess((value) => Array.isArray(value) ? value.map((item) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(item) ? item : {}) : [], zod.z.array(PROVIDER_SCHEMA)),
|
|
615
|
+
current: zod.z.preprocess((value) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(value) ? value : {}, CURRENT_SCHEMA),
|
|
1201
616
|
getCredReady: TRUE_ONLY,
|
|
1202
|
-
source: zod.z.preprocess((value) =>
|
|
617
|
+
source: zod.z.preprocess((value) => (0, _jayyuen66_dsh_plugin_shared_client.isRecord)(value) ? value : {}, SOURCE_SCHEMA),
|
|
1203
618
|
endpointVerify: zod.z.preprocess((value) => {
|
|
1204
619
|
const parsed = ENDPOINT_VERIFY_SCHEMA.safeParse(value);
|
|
1205
620
|
return parsed.success ? parsed.data : null;
|
|
@@ -1345,7 +760,7 @@ function buildCliStatusRow(deps) {
|
|
|
1345
760
|
className: statusClass(deps.probeMsg.ok),
|
|
1346
761
|
"data-field": "probe-result"
|
|
1347
762
|
}, deps.probeMsg.text) : null;
|
|
1348
|
-
return (0, react.createElement)(
|
|
763
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Section, {
|
|
1349
764
|
title: t("binaryTitle"),
|
|
1350
765
|
hint: t("binaryProbeHint")
|
|
1351
766
|
}, status, versionLine, installLine, controls, probe);
|
|
@@ -1500,7 +915,7 @@ function buildActionField(deps) {
|
|
|
1500
915
|
onClick: deps.onMigrate,
|
|
1501
916
|
"data-field": "migrate"
|
|
1502
917
|
}, t("migrateKeys"));
|
|
1503
|
-
return (0, react.createElement)(
|
|
918
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Field, {
|
|
1504
919
|
label: t("actionsLabel"),
|
|
1505
920
|
wide: true
|
|
1506
921
|
}, (0, react.createElement)("div", { className: ACTIONS_CLASS }, applyBtn, testBtn, migrateBtn));
|
|
@@ -1565,16 +980,16 @@ function buildReadyProviderSection(deps, data) {
|
|
|
1565
980
|
}];
|
|
1566
981
|
const modelUrl = deps.chosenProvider?.baseURL ?? "";
|
|
1567
982
|
return [
|
|
1568
|
-
(0, react.createElement)(
|
|
983
|
+
(0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.SelectField, {
|
|
1569
984
|
label: "Provider",
|
|
1570
|
-
...
|
|
985
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("providerHint")),
|
|
1571
986
|
field: "ocrProvider",
|
|
1572
987
|
value: deps.effectiveProvider,
|
|
1573
988
|
options: providerOptions,
|
|
1574
989
|
disabled: data.providers.length === 0,
|
|
1575
990
|
onChange: deps.onPickProvider
|
|
1576
991
|
}),
|
|
1577
|
-
(0, react.createElement)(
|
|
992
|
+
(0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.SelectField, {
|
|
1578
993
|
label: "Model",
|
|
1579
994
|
...modelUrl === "" ? {} : { hint: modelUrl },
|
|
1580
995
|
field: "ocrModel",
|
|
@@ -1583,9 +998,9 @@ function buildReadyProviderSection(deps, data) {
|
|
|
1583
998
|
disabled: !deps.chosenProvider || deps.modelOptions.length === 0,
|
|
1584
999
|
onChange: deps.onPickModel
|
|
1585
1000
|
}),
|
|
1586
|
-
(0, react.createElement)(
|
|
1001
|
+
(0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.SelectField, {
|
|
1587
1002
|
label: t("effortLabel"),
|
|
1588
|
-
...
|
|
1003
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("effortHint")),
|
|
1589
1004
|
field: "effort",
|
|
1590
1005
|
value: deps.effortValue,
|
|
1591
1006
|
options: effortOptions,
|
|
@@ -1594,9 +1009,9 @@ function buildReadyProviderSection(deps, data) {
|
|
|
1594
1009
|
deps.onField("effort", next);
|
|
1595
1010
|
}
|
|
1596
1011
|
}),
|
|
1597
|
-
(0, react.createElement)(
|
|
1012
|
+
(0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.SelectField, {
|
|
1598
1013
|
label: t("languageLabel"),
|
|
1599
|
-
...
|
|
1014
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("languageHint")),
|
|
1600
1015
|
field: "language",
|
|
1601
1016
|
value: deps.languageValue,
|
|
1602
1017
|
options: languageOptions,
|
|
@@ -1605,9 +1020,9 @@ function buildReadyProviderSection(deps, data) {
|
|
|
1605
1020
|
deps.onField("language", next);
|
|
1606
1021
|
}
|
|
1607
1022
|
}),
|
|
1608
|
-
(0, react.createElement)(
|
|
1023
|
+
(0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.ToggleField, {
|
|
1609
1024
|
label: t("autoVerifyLabel"),
|
|
1610
|
-
...
|
|
1025
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("autoVerifyHint")),
|
|
1611
1026
|
field: "autoVerify",
|
|
1612
1027
|
checked: deps.autoVerifyValue,
|
|
1613
1028
|
disabled: !deps.writable,
|
|
@@ -1634,7 +1049,7 @@ function buildProviderSection(deps) {
|
|
|
1634
1049
|
const reason = sourceMessage === "" ? t("noReason") : sourceMessage;
|
|
1635
1050
|
body = (0, react.createElement)("p", { className: "dsu-error" }, t("readProvidersFailed", { reason }));
|
|
1636
1051
|
}
|
|
1637
|
-
return (0, react.createElement)(
|
|
1052
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Section, { title: t("modelSection") }, body);
|
|
1638
1053
|
}
|
|
1639
1054
|
/** provider 预选:显式选择 > 当前 OCR 配置(仍存在)> 第一个有 key 的 provider。 */
|
|
1640
1055
|
function resolveBackend(providerList, current, selProvider) {
|
|
@@ -1667,9 +1082,9 @@ function resolveSelection(providerList, current, selProvider, selModel) {
|
|
|
1667
1082
|
/** 审查参数小节:评论条数、运行超时、配置文件路径 + 保存条。 */
|
|
1668
1083
|
function buildSettingsSection(deps, writable, setField) {
|
|
1669
1084
|
const { t } = deps;
|
|
1670
|
-
const maxCommentsRow = (0, react.createElement)(
|
|
1085
|
+
const maxCommentsRow = (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.NumberField, {
|
|
1671
1086
|
label: t("maxCommentsLabel"),
|
|
1672
|
-
...
|
|
1087
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("maxCommentsHint")),
|
|
1673
1088
|
field: "maxComments",
|
|
1674
1089
|
value: deps.maxCommentsValue,
|
|
1675
1090
|
...COUNT_SCHEMA.minValue === null ? {} : { min: COUNT_SCHEMA.minValue },
|
|
@@ -1680,9 +1095,9 @@ function buildSettingsSection(deps, writable, setField) {
|
|
|
1680
1095
|
setField("maxComments", next);
|
|
1681
1096
|
}
|
|
1682
1097
|
});
|
|
1683
|
-
const timeoutRow = (0, react.createElement)(
|
|
1098
|
+
const timeoutRow = (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.NumberField, {
|
|
1684
1099
|
label: t("timeoutLabel"),
|
|
1685
|
-
...
|
|
1100
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("timeoutHint")),
|
|
1686
1101
|
field: "timeoutMinutes",
|
|
1687
1102
|
value: deps.timeoutMinutesValue,
|
|
1688
1103
|
...COUNT_SCHEMA.minValue === null ? {} : { min: COUNT_SCHEMA.minValue },
|
|
@@ -1693,9 +1108,9 @@ function buildSettingsSection(deps, writable, setField) {
|
|
|
1693
1108
|
setField("timeoutMinutes", next);
|
|
1694
1109
|
}
|
|
1695
1110
|
});
|
|
1696
|
-
const configPathRow = (0, react.createElement)(
|
|
1111
|
+
const configPathRow = (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.TextField, {
|
|
1697
1112
|
label: t("configPathLabel"),
|
|
1698
|
-
...
|
|
1113
|
+
...(0, _jayyuen66_dsh_plugin_shared_client.splitHint)(t("configPathHint")),
|
|
1699
1114
|
field: "ocrConfigPath",
|
|
1700
1115
|
value: deps.ocrConfigPathValue,
|
|
1701
1116
|
placeholder: "~/.opencodereview/config.json",
|
|
@@ -1706,7 +1121,7 @@ function buildSettingsSection(deps, writable, setField) {
|
|
|
1706
1121
|
setField("ocrConfigPath", next.trim());
|
|
1707
1122
|
}
|
|
1708
1123
|
});
|
|
1709
|
-
const saveRow = (0, react.createElement)(
|
|
1124
|
+
const saveRow = (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.SaveBar, {
|
|
1710
1125
|
dirty: deps.dirty,
|
|
1711
1126
|
writable,
|
|
1712
1127
|
busy: deps.settingsBusy,
|
|
@@ -1721,7 +1136,7 @@ function buildSettingsSection(deps, writable, setField) {
|
|
|
1721
1136
|
onDiscard: deps.onDiscard
|
|
1722
1137
|
});
|
|
1723
1138
|
const statusHintNode = deps.statusHint !== null && deps.statusHint !== "" ? (0, react.createElement)("p", { className: "dsu-hint" }, deps.statusHint) : null;
|
|
1724
|
-
return (0, react.createElement)(
|
|
1139
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Section, { title: t("reviewSection") }, statusHintNode, maxCommentsRow, timeoutRow, configPathRow, saveRow);
|
|
1725
1140
|
}
|
|
1726
1141
|
function buildMcpAdmin(props) {
|
|
1727
1142
|
const { t } = props;
|
|
@@ -1743,7 +1158,7 @@ function buildMcpAdmin(props) {
|
|
|
1743
1158
|
onClick: props.onMcpSave
|
|
1744
1159
|
}, props.mcpBusy ? t("mcpSaving") : t("mcpSave"));
|
|
1745
1160
|
const message = props.mcpMsg === null ? null : (0, react.createElement)("p", { className: "dsu-hint" }, props.mcpMsg);
|
|
1746
|
-
return (0, react.createElement)(
|
|
1161
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Section, {
|
|
1747
1162
|
title: t("mcpTitle"),
|
|
1748
1163
|
hint: t("mcpHint")
|
|
1749
1164
|
}, props.available ? textarea : (0, react.createElement)("p", { className: "dsu-hint" }, t("adminUnavailable")), (0, react.createElement)("div", { className: ACTIONS_CLASS }, button), message);
|
|
@@ -1776,7 +1191,7 @@ function buildAuthAdmin(props) {
|
|
|
1776
1191
|
}, props.authBusy ? t("chatGptUsing") : t("chatGptUse"));
|
|
1777
1192
|
const output = props.authOutput === null ? null : (0, react.createElement)("pre", { className: "ocr-status dsu-mono" }, props.authOutput);
|
|
1778
1193
|
const message = props.authMsg === null ? null : (0, react.createElement)("p", { className: "dsu-hint" }, props.authMsg);
|
|
1779
|
-
return (0, react.createElement)(
|
|
1194
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.Section, {
|
|
1780
1195
|
title: t("chatGptTitle"),
|
|
1781
1196
|
hint: t("chatGptHint")
|
|
1782
1197
|
}, (0, react.createElement)("div", { className: ACTIONS_CLASS }, check), (0, react.createElement)("p", { className: "dsu-hint" }, `${t("chatGptLoginHint")} ${props.loginCommand}`), output, (0, react.createElement)("p", { className: "dsu-hint" }, t("chatGptModelLabel")), model, (0, react.createElement)("div", { className: ACTIONS_CLASS }, use), message);
|
|
@@ -1795,8 +1210,8 @@ async function refreshProviders(reader, t, sinks) {
|
|
|
1795
1210
|
try {
|
|
1796
1211
|
if (reader === void 0) throw new Error(t("remoteUnavailable"));
|
|
1797
1212
|
const json = await reader.providers();
|
|
1798
|
-
if (
|
|
1799
|
-
const detail = strOf(
|
|
1213
|
+
if ((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "ok") === false) {
|
|
1214
|
+
const detail = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "error"));
|
|
1800
1215
|
throw new Error(detail === "" ? t("remoteUnavailable") : detail);
|
|
1801
1216
|
}
|
|
1802
1217
|
const payload = providersPayloadOf(json);
|
|
@@ -1813,8 +1228,8 @@ function readerPost(reader, t) {
|
|
|
1813
1228
|
if (reader === void 0) throw new Error(t("remoteUnavailable"));
|
|
1814
1229
|
switch (action) {
|
|
1815
1230
|
case "select": {
|
|
1816
|
-
const provider = strOf(
|
|
1817
|
-
const model = strOf(
|
|
1231
|
+
const provider = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(body, "provider"));
|
|
1232
|
+
const model = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(body, "model"));
|
|
1818
1233
|
const reply = await reader.select(provider, model);
|
|
1819
1234
|
return { json: () => Promise.resolve(reply) };
|
|
1820
1235
|
}
|
|
@@ -1852,13 +1267,13 @@ async function runApplySelection(deps) {
|
|
|
1852
1267
|
provider: effectiveProvider,
|
|
1853
1268
|
model: effectiveModel
|
|
1854
1269
|
})).json();
|
|
1855
|
-
if (
|
|
1270
|
+
if ((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(selJson, "ok") === true) {
|
|
1856
1271
|
let testText;
|
|
1857
1272
|
let verified = true;
|
|
1858
|
-
const llmTestRaw =
|
|
1859
|
-
if (
|
|
1860
|
-
const testOutput = strOf(
|
|
1861
|
-
verified =
|
|
1273
|
+
const llmTestRaw = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(selJson, "llmTest");
|
|
1274
|
+
if ((0, _jayyuen66_dsh_plugin_shared_client.isRecord)(llmTestRaw)) {
|
|
1275
|
+
const testOutput = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(llmTestRaw, "output")).slice(0, 400);
|
|
1276
|
+
verified = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(llmTestRaw, "ok") === true;
|
|
1862
1277
|
testText = verified ? t("llmTestPassed") : `${t("llmTestFailed")}${testOutput}`;
|
|
1863
1278
|
} else testText = t("notVerified");
|
|
1864
1279
|
const appliedText = t("applied", {
|
|
@@ -1872,7 +1287,7 @@ async function runApplySelection(deps) {
|
|
|
1872
1287
|
});
|
|
1873
1288
|
deps.refresh();
|
|
1874
1289
|
} else {
|
|
1875
|
-
const failure = strOf(
|
|
1290
|
+
const failure = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(selJson, "error"));
|
|
1876
1291
|
deps.setActionMsg({
|
|
1877
1292
|
ok: false,
|
|
1878
1293
|
text: failure === "" ? t("applyFailed") : failure
|
|
@@ -1895,11 +1310,11 @@ async function runMigrateKeys(deps) {
|
|
|
1895
1310
|
deps.setActionMsg(null);
|
|
1896
1311
|
try {
|
|
1897
1312
|
const json = await (await deps.post("migrate")).json();
|
|
1898
|
-
const migratedVal =
|
|
1899
|
-
const skippedVal =
|
|
1313
|
+
const migratedVal = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "migrated");
|
|
1314
|
+
const skippedVal = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "skippedUnknown");
|
|
1900
1315
|
const migrated = Array.isArray(migratedVal) ? migratedVal.filter((item) => typeof item === "string") : [];
|
|
1901
1316
|
const skipped = Array.isArray(skippedVal) ? skippedVal.filter((item) => typeof item === "string") : [];
|
|
1902
|
-
const ok =
|
|
1317
|
+
const ok = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "ok") === true;
|
|
1903
1318
|
const migratedText = migrated.length > 0 ? t("migratedPrefix") + migrated.join(", ") : t("noPlainKey");
|
|
1904
1319
|
const skippedText = skipped.length > 0 ? t("skippedPrefix") + skipped.join(", ") : "";
|
|
1905
1320
|
const head = ok ? migratedText + skippedText : t("migrateFailed");
|
|
@@ -1925,8 +1340,8 @@ async function runTestConnection(deps) {
|
|
|
1925
1340
|
deps.setActionMsg(null);
|
|
1926
1341
|
try {
|
|
1927
1342
|
const json = await (await deps.post("test")).json();
|
|
1928
|
-
const ok =
|
|
1929
|
-
const testOutput = strOf(
|
|
1343
|
+
const ok = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "ok") === true;
|
|
1344
|
+
const testOutput = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "output"));
|
|
1930
1345
|
deps.setActionMsg({
|
|
1931
1346
|
ok,
|
|
1932
1347
|
text: (ok ? t("llmTestPassed") : t("llmTestFailed")) + testOutput
|
|
@@ -1953,12 +1368,12 @@ async function runProbe(deps) {
|
|
|
1953
1368
|
deps.setProbeMsg(null);
|
|
1954
1369
|
try {
|
|
1955
1370
|
const json = await (await deps.post("probe")).json();
|
|
1956
|
-
const ok =
|
|
1957
|
-
const head = ok ? t("probeVersion", { version: strOf(
|
|
1958
|
-
const output = strOf(
|
|
1371
|
+
const ok = (0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "ok") === true;
|
|
1372
|
+
const head = ok ? t("probeVersion", { version: strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "version")) }) : t("probeReason", { reason: strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "reason")) });
|
|
1373
|
+
const output = strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "output"));
|
|
1959
1374
|
const lines = [
|
|
1960
1375
|
head,
|
|
1961
|
-
strOf(
|
|
1376
|
+
strOf((0, _jayyuen66_dsh_plugin_shared_client.fieldOf)(json, "changeText")),
|
|
1962
1377
|
output
|
|
1963
1378
|
].filter((line) => line !== "");
|
|
1964
1379
|
deps.setProbeMsg({
|
|
@@ -1981,7 +1396,7 @@ async function runProbe(deps) {
|
|
|
1981
1396
|
* 传输失败仍以 rejection 表达。 */
|
|
1982
1397
|
async function saveSettingsDraft(deps) {
|
|
1983
1398
|
const { t, value, touched } = deps;
|
|
1984
|
-
const keys =
|
|
1399
|
+
const keys = (0, _jayyuen66_dsh_plugin_shared_client.diffTouched)(touched, value);
|
|
1985
1400
|
if (keys.length === 0) return;
|
|
1986
1401
|
deps.setSettingsBusy(true);
|
|
1987
1402
|
deps.setSaveError(null);
|
|
@@ -2222,7 +1637,7 @@ function OcrCard(props) {
|
|
|
2222
1637
|
const [touched, setTouched] = (0, react.useState)({});
|
|
2223
1638
|
const [settingsBusy, setSettingsBusy] = (0, react.useState)(false);
|
|
2224
1639
|
const [saveError, setSaveError] = (0, react.useState)(null);
|
|
2225
|
-
const dirty =
|
|
1640
|
+
const dirty = (0, _jayyuen66_dsh_plugin_shared_client.diffTouched)(touched, value).length > 0;
|
|
2226
1641
|
const setField = (field, draft) => {
|
|
2227
1642
|
setTouched((prev) => ({
|
|
2228
1643
|
...prev,
|
|
@@ -2294,7 +1709,7 @@ function OcrCard(props) {
|
|
|
2294
1709
|
t,
|
|
2295
1710
|
writable
|
|
2296
1711
|
});
|
|
2297
|
-
return (0, react.createElement)(
|
|
1712
|
+
return (0, react.createElement)(_jayyuen66_dsh_plugin_shared_client.CardForm, null, cliStatus, providerPanel, settingsSection, adminSection);
|
|
2298
1713
|
}
|
|
2299
1714
|
const inject = [
|
|
2300
1715
|
"slots",
|
|
@@ -2302,11 +1717,11 @@ const inject = [
|
|
|
2302
1717
|
"locale"
|
|
2303
1718
|
];
|
|
2304
1719
|
function apply(ctx) {
|
|
2305
|
-
if (!
|
|
1720
|
+
if (!(0, _jayyuen66_dsh_plugin_shared_client.claimApply)(ctx, "ocrReviewCardApplied", "ocr-review-card: apply claim")) return;
|
|
2306
1721
|
ctx.effect(() => {
|
|
2307
1722
|
const tag = document.createElement("style");
|
|
2308
1723
|
tag.id = "ocr-review-card-css";
|
|
2309
|
-
tag.textContent = `${CARD_CSS}\n${
|
|
1724
|
+
tag.textContent = `${CARD_CSS}\n${_jayyuen66_dsh_plugin_shared_client.CARD_UI_CSS}`;
|
|
2310
1725
|
document.head.append(tag);
|
|
2311
1726
|
return () => {
|
|
2312
1727
|
tag.remove();
|