dsh-plugin-discovery 1.2.0 → 1.2.4
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 +103 -96
- package/client.js +496 -21
- package/data/recommended.json +1206 -1206
- package/index.js +281 -14
- package/package.json +74 -74
package/client.js
CHANGED
|
@@ -49,6 +49,20 @@ window.__ModuleLoader__.load({
|
|
|
49
49
|
installLog: "安装输出:{text}",
|
|
50
50
|
installFailed: "安装失败",
|
|
51
51
|
retry: "重试",
|
|
52
|
+
copy: "复制",
|
|
53
|
+
copied: "已复制",
|
|
54
|
+
copyFailed: "复制失败",
|
|
55
|
+
riskInstall: "承担风险安装",
|
|
56
|
+
riskTitle: "版本不兼容,确认风险后安装?",
|
|
57
|
+
riskDesc:
|
|
58
|
+
"插件 {package} 与当前 DSH {runtime} 声明的 peer 不匹配。强行安装可能导致崩溃或数据丢失。仅在你明确愿意承担该风险时继续。",
|
|
59
|
+
riskAck: "我已了解风险,仍要为这对精确版本授予豁免并重试安装",
|
|
60
|
+
riskCancel: "取消",
|
|
61
|
+
riskConfirm: "确认豁免并安装",
|
|
62
|
+
riskWorking: "正在授权并重试…",
|
|
63
|
+
riskAltTitle: "推荐改用兼容插件",
|
|
64
|
+
riskAltDesc: "以下精选包更可能匹配当前 DSH 版本,可直接安装代替强行豁免:",
|
|
65
|
+
riskAltInstall: "安装推荐",
|
|
52
66
|
browseRecommend: "为你推荐",
|
|
53
67
|
browseCategory: "分类浏览",
|
|
54
68
|
browseSearch: "在线搜索",
|
|
@@ -129,6 +143,20 @@ window.__ModuleLoader__.load({
|
|
|
129
143
|
installLog: "Output: {text}",
|
|
130
144
|
installFailed: "Install failed",
|
|
131
145
|
retry: "Retry",
|
|
146
|
+
copy: "Copy",
|
|
147
|
+
copied: "Copied",
|
|
148
|
+
copyFailed: "Copy failed",
|
|
149
|
+
riskInstall: "Install anyway",
|
|
150
|
+
riskTitle: "Incompatible version — install at your own risk?",
|
|
151
|
+
riskDesc:
|
|
152
|
+
"Plugin {package} does not match peers for DSH {runtime}. Forcing install may crash or lose data. Continue only if you accept that risk.",
|
|
153
|
+
riskAck: "I understand the risk and grant an exact-version exemption for this pair",
|
|
154
|
+
riskCancel: "Cancel",
|
|
155
|
+
riskConfirm: "Grant exemption and install",
|
|
156
|
+
riskWorking: "Granting and retrying…",
|
|
157
|
+
riskAltTitle: "Try a compatible plugin instead",
|
|
158
|
+
riskAltDesc: "These curated packages are more likely to match this DSH version:",
|
|
159
|
+
riskAltInstall: "Install recommended",
|
|
132
160
|
browseRecommend: "For you",
|
|
133
161
|
browseCategory: "Categories",
|
|
134
162
|
browseSearch: "Online search",
|
|
@@ -593,7 +621,7 @@ window.__ModuleLoader__.load({
|
|
|
593
621
|
},
|
|
594
622
|
errorBox: {
|
|
595
623
|
display: "flex",
|
|
596
|
-
alignItems: "
|
|
624
|
+
alignItems: "flex-start",
|
|
597
625
|
justifyContent: "space-between",
|
|
598
626
|
gap: "12px",
|
|
599
627
|
padding: "12px 14px",
|
|
@@ -602,6 +630,115 @@ window.__ModuleLoader__.load({
|
|
|
602
630
|
background: "var(--dsw-alias-settings-card-fill, #ffffff)",
|
|
603
631
|
color: "var(--dsw-alias-state-warn-primary, var(--dsw-alias-label-secondary))",
|
|
604
632
|
fontSize: "13px",
|
|
633
|
+
lineHeight: "20px",
|
|
634
|
+
},
|
|
635
|
+
errorText: {
|
|
636
|
+
flex: 1,
|
|
637
|
+
minWidth: 0,
|
|
638
|
+
whiteSpace: "pre-wrap",
|
|
639
|
+
wordBreak: "break-word",
|
|
640
|
+
overflowWrap: "anywhere",
|
|
641
|
+
},
|
|
642
|
+
errorActions: {
|
|
643
|
+
display: "flex",
|
|
644
|
+
alignItems: "center",
|
|
645
|
+
gap: "8px",
|
|
646
|
+
flexShrink: 0,
|
|
647
|
+
flexWrap: "wrap",
|
|
648
|
+
justifyContent: "flex-end",
|
|
649
|
+
},
|
|
650
|
+
riskOverlay: {
|
|
651
|
+
position: "fixed",
|
|
652
|
+
inset: 0,
|
|
653
|
+
zIndex: 10000,
|
|
654
|
+
display: "flex",
|
|
655
|
+
alignItems: "center",
|
|
656
|
+
justifyContent: "center",
|
|
657
|
+
padding: "24px",
|
|
658
|
+
background: "rgba(15, 23, 42, 0.45)",
|
|
659
|
+
},
|
|
660
|
+
riskDialog: {
|
|
661
|
+
width: "min(520px, 100%)",
|
|
662
|
+
maxHeight: "90vh",
|
|
663
|
+
overflow: "auto",
|
|
664
|
+
borderRadius: "var(--dsw-radius-md, 12px)",
|
|
665
|
+
border: "1px solid var(--dsw-alias-border-l2, #d0d5dd)",
|
|
666
|
+
background: "var(--dsw-alias-settings-card-fill, #ffffff)",
|
|
667
|
+
color: "var(--dsw-alias-label-primary)",
|
|
668
|
+
padding: "20px",
|
|
669
|
+
boxShadow: "0 16px 40px rgba(15, 23, 42, 0.18)",
|
|
670
|
+
},
|
|
671
|
+
riskTitle: {
|
|
672
|
+
margin: "0 0 10px",
|
|
673
|
+
fontSize: "16px",
|
|
674
|
+
fontWeight: 600,
|
|
675
|
+
lineHeight: "24px",
|
|
676
|
+
},
|
|
677
|
+
riskDesc: {
|
|
678
|
+
margin: "0 0 14px",
|
|
679
|
+
fontSize: "13px",
|
|
680
|
+
lineHeight: "20px",
|
|
681
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
682
|
+
whiteSpace: "pre-wrap",
|
|
683
|
+
},
|
|
684
|
+
riskAckRow: {
|
|
685
|
+
display: "flex",
|
|
686
|
+
alignItems: "flex-start",
|
|
687
|
+
gap: "10px",
|
|
688
|
+
margin: "0 0 16px",
|
|
689
|
+
fontSize: "13px",
|
|
690
|
+
lineHeight: "20px",
|
|
691
|
+
},
|
|
692
|
+
riskAltBox: {
|
|
693
|
+
margin: "0 0 16px",
|
|
694
|
+
padding: "12px",
|
|
695
|
+
borderRadius: "var(--dsw-radius-sm, 8px)",
|
|
696
|
+
border: "1px solid var(--dsw-alias-border-l2, #d0d5dd)",
|
|
697
|
+
background: "var(--dsw-alias-settings-card-fill-secondary, #f8fafc)",
|
|
698
|
+
},
|
|
699
|
+
riskAltTitle: {
|
|
700
|
+
margin: "0 0 6px",
|
|
701
|
+
fontSize: "13px",
|
|
702
|
+
fontWeight: 600,
|
|
703
|
+
lineHeight: "20px",
|
|
704
|
+
},
|
|
705
|
+
riskAltDesc: {
|
|
706
|
+
margin: "0 0 10px",
|
|
707
|
+
fontSize: "12px",
|
|
708
|
+
lineHeight: "18px",
|
|
709
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
710
|
+
},
|
|
711
|
+
riskAltList: {
|
|
712
|
+
display: "flex",
|
|
713
|
+
flexDirection: "column",
|
|
714
|
+
gap: "8px",
|
|
715
|
+
},
|
|
716
|
+
riskAltRow: {
|
|
717
|
+
display: "flex",
|
|
718
|
+
alignItems: "center",
|
|
719
|
+
justifyContent: "space-between",
|
|
720
|
+
gap: "10px",
|
|
721
|
+
},
|
|
722
|
+
riskAltMeta: {
|
|
723
|
+
minWidth: 0,
|
|
724
|
+
flex: 1,
|
|
725
|
+
},
|
|
726
|
+
riskAltSpec: {
|
|
727
|
+
fontSize: "13px",
|
|
728
|
+
fontWeight: 500,
|
|
729
|
+
lineHeight: "18px",
|
|
730
|
+
wordBreak: "break-all",
|
|
731
|
+
},
|
|
732
|
+
riskAltHint: {
|
|
733
|
+
fontSize: "12px",
|
|
734
|
+
lineHeight: "16px",
|
|
735
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
736
|
+
},
|
|
737
|
+
riskFooter: {
|
|
738
|
+
display: "flex",
|
|
739
|
+
justifyContent: "flex-end",
|
|
740
|
+
gap: "8px",
|
|
741
|
+
flexWrap: "wrap",
|
|
605
742
|
},
|
|
606
743
|
updateBox: {
|
|
607
744
|
display: "flex",
|
|
@@ -751,12 +888,25 @@ window.__ModuleLoader__.load({
|
|
|
751
888
|
const err = result.error;
|
|
752
889
|
return {
|
|
753
890
|
ok: false,
|
|
754
|
-
message: (err && (err.message || err.code)) || fallbackMessage,
|
|
891
|
+
message: (err && (err.message || err.diagnostic || err.code)) || fallbackMessage,
|
|
755
892
|
};
|
|
756
893
|
}
|
|
757
894
|
return result.value;
|
|
758
895
|
}
|
|
759
896
|
|
|
897
|
+
function pickInstallError(res, fallback, lastDetail) {
|
|
898
|
+
const primary = String((res && (res.detail || res.message)) || "").trim();
|
|
899
|
+
const weak =
|
|
900
|
+
!primary ||
|
|
901
|
+
/^install failed$/i.test(primary) ||
|
|
902
|
+
/^安装失败([((]failed[))])?$/i.test(primary);
|
|
903
|
+
if (!weak) return primary;
|
|
904
|
+
const extra = String(lastDetail || "").trim();
|
|
905
|
+
const title = fallback || "安装失败";
|
|
906
|
+
if (extra && extra !== primary) return `${title}\n${extra}`;
|
|
907
|
+
return primary || title;
|
|
908
|
+
}
|
|
909
|
+
|
|
760
910
|
function Panel(props) {
|
|
761
911
|
const api = props.api;
|
|
762
912
|
const t = props.t;
|
|
@@ -775,6 +925,11 @@ window.__ModuleLoader__.load({
|
|
|
775
925
|
const [results, setResults] = React.useState([]);
|
|
776
926
|
const [message, setMessage] = React.useState("");
|
|
777
927
|
const [error, setError] = React.useState("");
|
|
928
|
+
const [copyHint, setCopyHint] = React.useState("");
|
|
929
|
+
const [riskPrompt, setRiskPrompt] = React.useState(null);
|
|
930
|
+
const [riskOpen, setRiskOpen] = React.useState(false);
|
|
931
|
+
const [riskAck, setRiskAck] = React.useState(false);
|
|
932
|
+
const [riskBusy, setRiskBusy] = React.useState(false);
|
|
778
933
|
const [busy, setBusy] = React.useState(false);
|
|
779
934
|
const [resolveInput, setResolveInput] = React.useState("");
|
|
780
935
|
const [installDetail, setInstallDetail] = React.useState("");
|
|
@@ -783,6 +938,7 @@ window.__ModuleLoader__.load({
|
|
|
783
938
|
const [page, setPage] = React.useState(1);
|
|
784
939
|
const jobsRef = React.useRef(jobs);
|
|
785
940
|
const installedNamesRef = React.useRef(installedNames);
|
|
941
|
+
const installDetailRef = React.useRef("");
|
|
786
942
|
React.useEffect(() => {
|
|
787
943
|
jobsRef.current = jobs;
|
|
788
944
|
writeJobCache(jobs);
|
|
@@ -790,6 +946,37 @@ window.__ModuleLoader__.load({
|
|
|
790
946
|
React.useEffect(() => {
|
|
791
947
|
installedNamesRef.current = installedNames;
|
|
792
948
|
}, [installedNames]);
|
|
949
|
+
React.useEffect(() => {
|
|
950
|
+
installDetailRef.current = installDetail;
|
|
951
|
+
}, [installDetail]);
|
|
952
|
+
React.useEffect(() => {
|
|
953
|
+
setCopyHint("");
|
|
954
|
+
}, [error]);
|
|
955
|
+
|
|
956
|
+
const openRiskPrompt = React.useCallback((res, item) => {
|
|
957
|
+
const rows = Array.isArray(res && res.incompatible) ? res.incompatible : [];
|
|
958
|
+
const first = rows[0];
|
|
959
|
+
if (!(res && res.needsRiskExemption) || !first) return;
|
|
960
|
+
const packageVersion = `${first.name}@${first.version}`;
|
|
961
|
+
const runtimeVersion = first.runtimeVersion || "unknown";
|
|
962
|
+
const recommendations = Array.isArray(res && res.recommendations) ? res.recommendations : [];
|
|
963
|
+
setRiskAck(false);
|
|
964
|
+
setRiskPrompt({
|
|
965
|
+
spec: (res && res.installSpec) || (item && (item.installSpec || item.spec)) || first.name,
|
|
966
|
+
item: item || null,
|
|
967
|
+
packageVersion,
|
|
968
|
+
runtimeVersion,
|
|
969
|
+
incompatible: rows,
|
|
970
|
+
recommendations,
|
|
971
|
+
});
|
|
972
|
+
setRiskOpen(true);
|
|
973
|
+
}, []);
|
|
974
|
+
|
|
975
|
+
const closeRiskPrompt = React.useCallback(() => {
|
|
976
|
+
if (riskBusy) return;
|
|
977
|
+
setRiskOpen(false);
|
|
978
|
+
setRiskAck(false);
|
|
979
|
+
}, [riskBusy]);
|
|
793
980
|
|
|
794
981
|
const refreshInstalled = React.useCallback(async () => {
|
|
795
982
|
if (!api || typeof api.listInstalled !== "function") return;
|
|
@@ -1045,18 +1232,36 @@ window.__ModuleLoader__.load({
|
|
|
1045
1232
|
setMessage(res.message || t("installed"));
|
|
1046
1233
|
await refreshInstalled();
|
|
1047
1234
|
} else {
|
|
1235
|
+
const lastDetail =
|
|
1236
|
+
(jobsRef.current[job.requestId] && jobsRef.current[job.requestId].detail) ||
|
|
1237
|
+
installDetailRef.current;
|
|
1238
|
+
const errText = pickInstallError(res, t("installFailed"), lastDetail);
|
|
1048
1239
|
finishJob(job.requestId, {
|
|
1049
1240
|
status: "failed",
|
|
1050
|
-
detail:
|
|
1241
|
+
detail: errText,
|
|
1242
|
+
});
|
|
1243
|
+
setError(errText);
|
|
1244
|
+
openRiskPrompt(res, {
|
|
1245
|
+
spec: job.spec,
|
|
1246
|
+
installSpec: job.spec,
|
|
1247
|
+
title: job.packageName || job.spec,
|
|
1051
1248
|
});
|
|
1052
|
-
setError((res && res.message) || t("installFailed"));
|
|
1053
1249
|
}
|
|
1054
1250
|
} catch (e) {
|
|
1055
1251
|
if (cancelled) return;
|
|
1252
|
+
const lastDetail =
|
|
1253
|
+
(jobsRef.current[job.requestId] && jobsRef.current[job.requestId].detail) ||
|
|
1254
|
+
installDetailRef.current;
|
|
1255
|
+
const errText = pickInstallError(
|
|
1256
|
+
{ message: (e && e.message) || String(e) },
|
|
1257
|
+
t("installFailed"),
|
|
1258
|
+
lastDetail,
|
|
1259
|
+
);
|
|
1056
1260
|
finishJob(job.requestId, {
|
|
1057
1261
|
status: "failed",
|
|
1058
|
-
detail:
|
|
1262
|
+
detail: errText,
|
|
1059
1263
|
});
|
|
1264
|
+
setError(errText);
|
|
1060
1265
|
} finally {
|
|
1061
1266
|
if (!cancelled) setInstallDetail("");
|
|
1062
1267
|
}
|
|
@@ -1151,11 +1356,20 @@ window.__ModuleLoader__.load({
|
|
|
1151
1356
|
setMessage(installed.message || t("installed"));
|
|
1152
1357
|
await refreshInstalled();
|
|
1153
1358
|
} else {
|
|
1359
|
+
const lastDetail =
|
|
1360
|
+
(jobsRef.current[requestId] && jobsRef.current[requestId].detail) ||
|
|
1361
|
+
installDetailRef.current;
|
|
1362
|
+
const errText = pickInstallError(installed, t("installFailed"), lastDetail);
|
|
1154
1363
|
finishJob(requestId, {
|
|
1155
1364
|
status: "failed",
|
|
1156
|
-
detail:
|
|
1365
|
+
detail: errText,
|
|
1366
|
+
});
|
|
1367
|
+
setError(errText);
|
|
1368
|
+
openRiskPrompt(installed, {
|
|
1369
|
+
spec: res.spec,
|
|
1370
|
+
installSpec: res.spec,
|
|
1371
|
+
title: (res.inspection && res.inspection.name) || res.spec,
|
|
1157
1372
|
});
|
|
1158
|
-
setError((installed && installed.message) || t("inspectFailed"));
|
|
1159
1373
|
}
|
|
1160
1374
|
} else {
|
|
1161
1375
|
setResults([]);
|
|
@@ -1204,23 +1418,79 @@ window.__ModuleLoader__.load({
|
|
|
1204
1418
|
await refreshInstalled();
|
|
1205
1419
|
setMessage(res.message || t("installed"));
|
|
1206
1420
|
} else {
|
|
1421
|
+
const lastDetail =
|
|
1422
|
+
(jobsRef.current[requestId] && jobsRef.current[requestId].detail) || installDetailRef.current;
|
|
1423
|
+
const errText = pickInstallError(res, t("installFailed"), lastDetail);
|
|
1207
1424
|
finishJob(requestId, {
|
|
1208
1425
|
status: "failed",
|
|
1209
|
-
detail:
|
|
1426
|
+
detail: errText,
|
|
1210
1427
|
});
|
|
1211
|
-
setError(
|
|
1428
|
+
setError(errText);
|
|
1429
|
+
openRiskPrompt(res, item);
|
|
1212
1430
|
}
|
|
1213
1431
|
} catch (e) {
|
|
1432
|
+
const lastDetail =
|
|
1433
|
+
(jobsRef.current[requestId] && jobsRef.current[requestId].detail) || installDetailRef.current;
|
|
1434
|
+
const errText = pickInstallError(
|
|
1435
|
+
{ message: (e && e.message) || String(e) },
|
|
1436
|
+
t("installFailed"),
|
|
1437
|
+
lastDetail,
|
|
1438
|
+
);
|
|
1214
1439
|
finishJob(requestId, {
|
|
1215
1440
|
status: "failed",
|
|
1216
|
-
detail:
|
|
1441
|
+
detail: errText,
|
|
1217
1442
|
});
|
|
1218
|
-
setError(
|
|
1443
|
+
setError(errText);
|
|
1219
1444
|
} finally {
|
|
1220
1445
|
setInstallDetail("");
|
|
1221
1446
|
}
|
|
1222
1447
|
};
|
|
1223
1448
|
|
|
1449
|
+
const confirmRiskInstall = async () => {
|
|
1450
|
+
if (!riskPrompt || !riskAck || !api || typeof api.grantVersionExemption !== "function") return;
|
|
1451
|
+
setRiskBusy(true);
|
|
1452
|
+
setMessage("");
|
|
1453
|
+
try {
|
|
1454
|
+
const granted = await api.grantVersionExemption(
|
|
1455
|
+
riskPrompt.packageVersion,
|
|
1456
|
+
riskPrompt.runtimeVersion,
|
|
1457
|
+
true,
|
|
1458
|
+
);
|
|
1459
|
+
if (!granted || !granted.ok) {
|
|
1460
|
+
setError((granted && granted.message) || t("installFailed"));
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1463
|
+
const item = riskPrompt.item || {
|
|
1464
|
+
spec: riskPrompt.spec,
|
|
1465
|
+
installSpec: riskPrompt.spec,
|
|
1466
|
+
title: riskPrompt.packageVersion,
|
|
1467
|
+
};
|
|
1468
|
+
setRiskOpen(false);
|
|
1469
|
+
setRiskAck(false);
|
|
1470
|
+
setError("");
|
|
1471
|
+
await onInstall(item);
|
|
1472
|
+
} catch (e) {
|
|
1473
|
+
setError((e && e.message) || String(e));
|
|
1474
|
+
} finally {
|
|
1475
|
+
setRiskBusy(false);
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
const installRecommendedAlt = async (alt) => {
|
|
1480
|
+
if (!alt || riskBusy) return;
|
|
1481
|
+
const item = {
|
|
1482
|
+
spec: alt.installSpec || alt.spec,
|
|
1483
|
+
installSpec: alt.installSpec || alt.spec,
|
|
1484
|
+
title: alt.title || alt.spec,
|
|
1485
|
+
source: alt.source || "catalog",
|
|
1486
|
+
catalogId: alt.catalogId,
|
|
1487
|
+
};
|
|
1488
|
+
setRiskOpen(false);
|
|
1489
|
+
setRiskAck(false);
|
|
1490
|
+
setError("");
|
|
1491
|
+
await onInstall(item);
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1224
1494
|
const sourceOptions = [
|
|
1225
1495
|
{ value: "all", label: t("sourceAll") },
|
|
1226
1496
|
{ value: "npm", label: t("sourceNpm") },
|
|
@@ -1334,6 +1604,9 @@ window.__ModuleLoader__.load({
|
|
|
1334
1604
|
: t("selfUpdateOriginNpm");
|
|
1335
1605
|
|
|
1336
1606
|
return h(
|
|
1607
|
+
React.Fragment,
|
|
1608
|
+
null,
|
|
1609
|
+
h(
|
|
1337
1610
|
"div",
|
|
1338
1611
|
{ style: styles.page },
|
|
1339
1612
|
h(
|
|
@@ -1501,16 +1774,67 @@ window.__ModuleLoader__.load({
|
|
|
1501
1774
|
? h(
|
|
1502
1775
|
"div",
|
|
1503
1776
|
{ style: styles.errorBox },
|
|
1504
|
-
h("
|
|
1777
|
+
h("div", { style: styles.errorText }, error),
|
|
1505
1778
|
h(
|
|
1506
|
-
|
|
1507
|
-
{
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1779
|
+
"div",
|
|
1780
|
+
{ style: styles.errorActions },
|
|
1781
|
+
h(
|
|
1782
|
+
Btn,
|
|
1783
|
+
{
|
|
1784
|
+
size: "sm",
|
|
1785
|
+
variant: "outline",
|
|
1786
|
+
disabled: busy || riskBusy,
|
|
1787
|
+
onClick: async () => {
|
|
1788
|
+
const text = String(error || "");
|
|
1789
|
+
try {
|
|
1790
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
1791
|
+
await navigator.clipboard.writeText(text);
|
|
1792
|
+
} else {
|
|
1793
|
+
const ta = document.createElement("textarea");
|
|
1794
|
+
ta.value = text;
|
|
1795
|
+
ta.setAttribute("readonly", "");
|
|
1796
|
+
ta.style.position = "fixed";
|
|
1797
|
+
ta.style.left = "-9999px";
|
|
1798
|
+
document.body.appendChild(ta);
|
|
1799
|
+
ta.select();
|
|
1800
|
+
document.execCommand("copy");
|
|
1801
|
+
document.body.removeChild(ta);
|
|
1802
|
+
}
|
|
1803
|
+
setCopyHint(t("copied"));
|
|
1804
|
+
window.setTimeout(() => setCopyHint(""), 1600);
|
|
1805
|
+
} catch {
|
|
1806
|
+
setCopyHint(t("copyFailed"));
|
|
1807
|
+
window.setTimeout(() => setCopyHint(""), 1600);
|
|
1808
|
+
}
|
|
1809
|
+
},
|
|
1810
|
+
},
|
|
1811
|
+
copyHint || t("copy"),
|
|
1812
|
+
),
|
|
1813
|
+
riskPrompt
|
|
1814
|
+
? h(
|
|
1815
|
+
Btn,
|
|
1816
|
+
{
|
|
1817
|
+
size: "sm",
|
|
1818
|
+
variant: "outline",
|
|
1819
|
+
disabled: busy || riskBusy,
|
|
1820
|
+
onClick: () => {
|
|
1821
|
+
setRiskAck(false);
|
|
1822
|
+
setRiskOpen(true);
|
|
1823
|
+
},
|
|
1824
|
+
},
|
|
1825
|
+
t("riskInstall"),
|
|
1826
|
+
)
|
|
1827
|
+
: null,
|
|
1828
|
+
h(
|
|
1829
|
+
Btn,
|
|
1830
|
+
{
|
|
1831
|
+
size: "sm",
|
|
1832
|
+
variant: "outline",
|
|
1833
|
+
disabled: busy || riskBusy,
|
|
1834
|
+
onClick: onSearch,
|
|
1835
|
+
},
|
|
1836
|
+
t("retry"),
|
|
1837
|
+
),
|
|
1514
1838
|
),
|
|
1515
1839
|
)
|
|
1516
1840
|
: null,
|
|
@@ -1634,6 +1958,110 @@ window.__ModuleLoader__.load({
|
|
|
1634
1958
|
)
|
|
1635
1959
|
: null,
|
|
1636
1960
|
),
|
|
1961
|
+
),
|
|
1962
|
+
riskOpen && riskPrompt
|
|
1963
|
+
? h(
|
|
1964
|
+
"div",
|
|
1965
|
+
{
|
|
1966
|
+
style: styles.riskOverlay,
|
|
1967
|
+
onClick: (e) => {
|
|
1968
|
+
if (e.target === e.currentTarget) closeRiskPrompt();
|
|
1969
|
+
},
|
|
1970
|
+
},
|
|
1971
|
+
h(
|
|
1972
|
+
"div",
|
|
1973
|
+
{
|
|
1974
|
+
style: styles.riskDialog,
|
|
1975
|
+
role: "dialog",
|
|
1976
|
+
"aria-modal": "true",
|
|
1977
|
+
onClick: (e) => e.stopPropagation(),
|
|
1978
|
+
},
|
|
1979
|
+
h("h2", { style: styles.riskTitle }, t("riskTitle")),
|
|
1980
|
+
h(
|
|
1981
|
+
"p",
|
|
1982
|
+
{ style: styles.riskDesc },
|
|
1983
|
+
format(t("riskDesc"), {
|
|
1984
|
+
package: riskPrompt.packageVersion,
|
|
1985
|
+
runtime: riskPrompt.runtimeVersion,
|
|
1986
|
+
}),
|
|
1987
|
+
),
|
|
1988
|
+
Array.isArray(riskPrompt.recommendations) && riskPrompt.recommendations.length
|
|
1989
|
+
? h(
|
|
1990
|
+
"div",
|
|
1991
|
+
{ style: styles.riskAltBox },
|
|
1992
|
+
h("div", { style: styles.riskAltTitle }, t("riskAltTitle")),
|
|
1993
|
+
h("p", { style: styles.riskAltDesc }, t("riskAltDesc")),
|
|
1994
|
+
h(
|
|
1995
|
+
"div",
|
|
1996
|
+
{ style: styles.riskAltList },
|
|
1997
|
+
...riskPrompt.recommendations.map((alt) =>
|
|
1998
|
+
h(
|
|
1999
|
+
"div",
|
|
2000
|
+
{ key: alt.spec, style: styles.riskAltRow },
|
|
2001
|
+
h(
|
|
2002
|
+
"div",
|
|
2003
|
+
{ style: styles.riskAltMeta },
|
|
2004
|
+
h("div", { style: styles.riskAltSpec }, alt.title || alt.spec),
|
|
2005
|
+
h(
|
|
2006
|
+
"div",
|
|
2007
|
+
{ style: styles.riskAltHint },
|
|
2008
|
+
alt.spec === (alt.title || "")
|
|
2009
|
+
? alt.reason || ""
|
|
2010
|
+
: alt.spec,
|
|
2011
|
+
),
|
|
2012
|
+
),
|
|
2013
|
+
h(
|
|
2014
|
+
Btn,
|
|
2015
|
+
{
|
|
2016
|
+
size: "sm",
|
|
2017
|
+
variant: "outline",
|
|
2018
|
+
disabled: riskBusy,
|
|
2019
|
+
onClick: () => void installRecommendedAlt(alt),
|
|
2020
|
+
},
|
|
2021
|
+
t("riskAltInstall"),
|
|
2022
|
+
),
|
|
2023
|
+
),
|
|
2024
|
+
),
|
|
2025
|
+
),
|
|
2026
|
+
)
|
|
2027
|
+
: null,
|
|
2028
|
+
h(
|
|
2029
|
+
"label",
|
|
2030
|
+
{ style: styles.riskAckRow },
|
|
2031
|
+
h("input", {
|
|
2032
|
+
type: "checkbox",
|
|
2033
|
+
checked: riskAck,
|
|
2034
|
+
disabled: riskBusy,
|
|
2035
|
+
onChange: (e) => setRiskAck(!!e.target.checked),
|
|
2036
|
+
}),
|
|
2037
|
+
h("span", null, t("riskAck")),
|
|
2038
|
+
),
|
|
2039
|
+
h(
|
|
2040
|
+
"div",
|
|
2041
|
+
{ style: styles.riskFooter },
|
|
2042
|
+
h(
|
|
2043
|
+
Btn,
|
|
2044
|
+
{
|
|
2045
|
+
size: "sm",
|
|
2046
|
+
variant: "outline",
|
|
2047
|
+
disabled: riskBusy,
|
|
2048
|
+
onClick: closeRiskPrompt,
|
|
2049
|
+
},
|
|
2050
|
+
t("riskCancel"),
|
|
2051
|
+
),
|
|
2052
|
+
h(
|
|
2053
|
+
Btn,
|
|
2054
|
+
{
|
|
2055
|
+
size: "sm",
|
|
2056
|
+
disabled: riskBusy || !riskAck,
|
|
2057
|
+
onClick: () => void confirmRiskInstall(),
|
|
2058
|
+
},
|
|
2059
|
+
riskBusy ? t("riskWorking") : t("riskConfirm"),
|
|
2060
|
+
),
|
|
2061
|
+
),
|
|
2062
|
+
),
|
|
2063
|
+
)
|
|
2064
|
+
: null,
|
|
1637
2065
|
);
|
|
1638
2066
|
}
|
|
1639
2067
|
|
|
@@ -1651,6 +2079,10 @@ window.__ModuleLoader__.load({
|
|
|
1651
2079
|
const SPEC_CODEC = strictJson("dsh-plugin-discovery#pluginDiscovery/installPlugin:spec");
|
|
1652
2080
|
const INSTALL_OPTIONS_CODEC = strictJson("dsh-plugin-discovery#pluginDiscovery/installPlugin:options");
|
|
1653
2081
|
const INSTALL_RESULT = strictJson("dsh-plugin-discovery#pluginDiscovery/installPlugin:result");
|
|
2082
|
+
const GRANT_PACKAGE = strictJson("dsh-plugin-discovery#pluginDiscovery/grantVersionExemption:packageVersion");
|
|
2083
|
+
const GRANT_RUNTIME = strictJson("dsh-plugin-discovery#pluginDiscovery/grantVersionExemption:runtimeVersion");
|
|
2084
|
+
const GRANT_ACCEPT = strictJson("dsh-plugin-discovery#pluginDiscovery/grantVersionExemption:acceptRisk");
|
|
2085
|
+
const GRANT_RESULT = strictJson("dsh-plugin-discovery#pluginDiscovery/grantVersionExemption:result");
|
|
1654
2086
|
const LIST_INSTALLED_RESULT = strictJson("dsh-plugin-discovery#pluginDiscovery/listInstalled:result");
|
|
1655
2087
|
const WAIT_REQUEST_ID = strictJson("dsh-plugin-discovery#pluginDiscovery/waitInstall:requestId");
|
|
1656
2088
|
const WAIT_RESULT = strictJson("dsh-plugin-discovery#pluginDiscovery/waitInstall:result");
|
|
@@ -1754,6 +2186,19 @@ window.__ModuleLoader__.load({
|
|
|
1754
2186
|
],
|
|
1755
2187
|
result: INSTALL_RESULT,
|
|
1756
2188
|
},
|
|
2189
|
+
{
|
|
2190
|
+
id: "dsh-plugin-discovery#pluginDiscovery/grantVersionExemption",
|
|
2191
|
+
service: "pluginDiscovery",
|
|
2192
|
+
namespace: "pluginDiscovery",
|
|
2193
|
+
method: "grantVersionExemption",
|
|
2194
|
+
invocation: { kind: "direct" },
|
|
2195
|
+
parameters: [
|
|
2196
|
+
{ name: "packageVersion", wire: "packageVersion", source: "json", codec: GRANT_PACKAGE },
|
|
2197
|
+
{ name: "runtimeVersion", wire: "runtimeVersion", source: "json", codec: GRANT_RUNTIME },
|
|
2198
|
+
{ name: "acceptRisk", wire: "acceptRisk", source: "json", codec: GRANT_ACCEPT },
|
|
2199
|
+
],
|
|
2200
|
+
result: GRANT_RESULT,
|
|
2201
|
+
},
|
|
1757
2202
|
{
|
|
1758
2203
|
id: "dsh-plugin-discovery#pluginDiscovery/listInstalled",
|
|
1759
2204
|
service: "pluginDiscovery",
|
|
@@ -1875,10 +2320,27 @@ window.__ModuleLoader__.load({
|
|
|
1875
2320
|
packageName: value && value.packageName,
|
|
1876
2321
|
requestId: value && value.requestId,
|
|
1877
2322
|
message: value && value.message,
|
|
2323
|
+
detail: value && value.detail,
|
|
2324
|
+
code: value && value.code,
|
|
2325
|
+
incompatible: value && value.incompatible,
|
|
2326
|
+
needsRiskExemption: !!(value && value.needsRiskExemption),
|
|
2327
|
+
recommendations: value && value.recommendations,
|
|
2328
|
+
installSpec: (value && value.installSpec) || spec,
|
|
1878
2329
|
};
|
|
1879
2330
|
}
|
|
1880
2331
|
return value;
|
|
1881
2332
|
},
|
|
2333
|
+
grantVersionExemption: async (packageVersion, runtimeVersion, acceptRisk) => {
|
|
2334
|
+
if (mountError) return { ok: false, message: mountError };
|
|
2335
|
+
const remote = remoteNs();
|
|
2336
|
+
if (!remote || typeof remote.grantVersionExemption !== "function") {
|
|
2337
|
+
return { ok: false, message: "remote.pluginDiscovery.grantVersionExemption unavailable" };
|
|
2338
|
+
}
|
|
2339
|
+
const wire = await remote.grantVersionExemption(packageVersion, runtimeVersion, acceptRisk);
|
|
2340
|
+
const value = unwrapRemote(wire, "grantVersionExemption failed");
|
|
2341
|
+
if (wire && wire.ok === false) return { ok: false, message: value.message };
|
|
2342
|
+
return value;
|
|
2343
|
+
},
|
|
1882
2344
|
listInstalled: async () => {
|
|
1883
2345
|
if (mountError) return { ok: false, names: [] };
|
|
1884
2346
|
const remote = remoteNs();
|
|
@@ -1898,7 +2360,20 @@ window.__ModuleLoader__.load({
|
|
|
1898
2360
|
}
|
|
1899
2361
|
const wire = await remote.waitInstall(requestId);
|
|
1900
2362
|
const value = unwrapRemote(wire, "waitInstall failed");
|
|
1901
|
-
if (wire && wire.ok === false)
|
|
2363
|
+
if (wire && wire.ok === false) {
|
|
2364
|
+
return {
|
|
2365
|
+
ok: false,
|
|
2366
|
+
message: (value && value.message) || "waitInstall failed",
|
|
2367
|
+
detail: value && value.detail,
|
|
2368
|
+
code: value && value.code,
|
|
2369
|
+
incompatible: value && value.incompatible,
|
|
2370
|
+
needsRiskExemption: !!(value && value.needsRiskExemption),
|
|
2371
|
+
recommendations: value && value.recommendations,
|
|
2372
|
+
installSpec: value && value.installSpec,
|
|
2373
|
+
packageName: value && value.packageName,
|
|
2374
|
+
pending: !!(value && value.pending),
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
1902
2377
|
return value;
|
|
1903
2378
|
},
|
|
1904
2379
|
subscribePluginChanged: (listener) => {
|