dsh-plugin 1.4.10 → 1.4.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/client/client.js +297 -297
- package/lib/http/routes.js +57 -16
- package/lib/services/install/task-queue.js +50 -12
- package/lib/services/probe.js +18 -5
- package/lib/types/services/install/install-types.d.ts +2 -0
- package/lib/types/services/install/task-queue.d.ts +7 -0
- package/package.json +1 -1
- package/src/server/http/routes.ts +53 -14
- package/src/server/services/install/install-types.ts +2 -0
- package/src/server/services/install/task-queue.ts +48 -11
- package/src/server/services/probe.ts +18 -4
package/client/client.js
CHANGED
|
@@ -698,42 +698,42 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
698
698
|
css: css$11
|
|
699
699
|
});
|
|
700
700
|
var Header_module_css_default = {
|
|
701
|
-
"
|
|
702
|
-
"
|
|
703
|
-
"tabActive": "qikqja_tabActive",
|
|
704
|
-
"search": "qikqja_search",
|
|
701
|
+
"adArrow": "qikqja_adArrow",
|
|
702
|
+
"aboutBtn": "qikqja_aboutBtn",
|
|
705
703
|
"copyIcon": "qikqja_copyIcon",
|
|
706
|
-
"
|
|
704
|
+
"segBtn": "qikqja_segBtn",
|
|
705
|
+
"header": "qikqja_header",
|
|
706
|
+
"version": "qikqja_version",
|
|
707
|
+
"logoIcon": "qikqja_logoIcon",
|
|
708
|
+
"headerRight": "qikqja_headerRight",
|
|
709
|
+
"adText": "qikqja_adText",
|
|
710
|
+
"githubIcon": "qikqja_githubIcon",
|
|
707
711
|
"taglineLink": "qikqja_taglineLink",
|
|
708
712
|
"resultSeg": "qikqja_resultSeg",
|
|
709
|
-
"
|
|
710
|
-
"
|
|
711
|
-
"
|
|
712
|
-
"
|
|
713
|
+
"search": "qikqja_search",
|
|
714
|
+
"searchRow": "qikqja_searchRow",
|
|
715
|
+
"controls": "qikqja_controls",
|
|
716
|
+
"resultCount": "qikqja_resultCount",
|
|
717
|
+
"segLabel": "qikqja_segLabel",
|
|
713
718
|
"adBadge": "qikqja_adBadge",
|
|
714
719
|
"githubLink": "qikqja_githubLink",
|
|
720
|
+
"headerTitleRow": "qikqja_headerTitleRow",
|
|
715
721
|
"sortGroup": "qikqja_sortGroup",
|
|
716
|
-
"
|
|
717
|
-
"
|
|
722
|
+
"tabActive": "qikqja_tabActive",
|
|
723
|
+
"segGroup": "qikqja_segGroup",
|
|
724
|
+
"title": "qikqja_title",
|
|
725
|
+
"tagline": "qikqja_tagline",
|
|
718
726
|
"tabsRow": "qikqja_tabsRow",
|
|
719
727
|
"root": "qikqja_root",
|
|
720
|
-
"searchRow": "qikqja_searchRow",
|
|
721
|
-
"version": "qikqja_version",
|
|
722
|
-
"logoIcon": "qikqja_logoIcon",
|
|
723
|
-
"resultCount": "qikqja_resultCount",
|
|
724
|
-
"brandTitle": "qikqja_brandTitle",
|
|
725
|
-
"hubUpdateBadge": "qikqja_hubUpdateBadge",
|
|
726
|
-
"tabs": "qikqja_tabs",
|
|
727
|
-
"adArrow": "qikqja_adArrow",
|
|
728
|
-
"tagline": "qikqja_tagline",
|
|
729
|
-
"segLabel": "qikqja_segLabel",
|
|
730
728
|
"langBtn": "qikqja_langBtn",
|
|
731
|
-
"
|
|
729
|
+
"versionBtn": "qikqja_versionBtn",
|
|
730
|
+
"segBtnActive": "qikqja_segBtnActive",
|
|
732
731
|
"adBanner": "qikqja_adBanner",
|
|
733
|
-
"
|
|
734
|
-
"
|
|
735
|
-
"
|
|
736
|
-
"
|
|
732
|
+
"brandTitle": "qikqja_brandTitle",
|
|
733
|
+
"tabs": "qikqja_tabs",
|
|
734
|
+
"hubUpdateBadge": "qikqja_hubUpdateBadge",
|
|
735
|
+
"tab": "qikqja_tab",
|
|
736
|
+
"tabCount": "qikqja_tabCount"
|
|
737
737
|
};
|
|
738
738
|
//#endregion
|
|
739
739
|
//#region \0dsh-css:src/client/styles/Modal.module.css.mjs
|
|
@@ -752,136 +752,136 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
752
752
|
css: css$10
|
|
753
753
|
});
|
|
754
754
|
var Modal_module_css_default = {
|
|
755
|
-
"
|
|
756
|
-
"
|
|
757
|
-
"
|
|
758
|
-
"
|
|
759
|
-
"
|
|
760
|
-
"
|
|
761
|
-
"
|
|
762
|
-
"
|
|
763
|
-
"
|
|
764
|
-
"
|
|
765
|
-
"
|
|
766
|
-
"
|
|
767
|
-
"
|
|
768
|
-
"
|
|
755
|
+
"detailPath": "BiQ1zG_detailPath",
|
|
756
|
+
"overlay": "BiQ1zG_overlay",
|
|
757
|
+
"queueRowDesc": "BiQ1zG_queueRowDesc",
|
|
758
|
+
"confirmIcon": "BiQ1zG_confirmIcon",
|
|
759
|
+
"resultDesc": "BiQ1zG_resultDesc",
|
|
760
|
+
"queueSection": "BiQ1zG_queueSection",
|
|
761
|
+
"modalLabel": "BiQ1zG_modalLabel",
|
|
762
|
+
"resultRestarting": "BiQ1zG_resultRestarting",
|
|
763
|
+
"restartLater": "BiQ1zG_restartLater",
|
|
764
|
+
"restartNowWarning": "BiQ1zG_restartNowWarning",
|
|
765
|
+
"resultCheck": "BiQ1zG_resultCheck",
|
|
766
|
+
"queueSectionTitle": "BiQ1zG_queueSectionTitle",
|
|
767
|
+
"noticeRowOk": "BiQ1zG_noticeRowOk",
|
|
768
|
+
"noticeRowUpdate": "BiQ1zG_noticeRowUpdate",
|
|
769
|
+
"failPrepareHint": "BiQ1zG_failPrepareHint",
|
|
770
|
+
"detailValue": "BiQ1zG_detailValue",
|
|
769
771
|
"failCopy": "BiQ1zG_failCopy",
|
|
770
|
-
"
|
|
771
|
-
"
|
|
772
|
-
"
|
|
772
|
+
"modalCopy": "BiQ1zG_modalCopy",
|
|
773
|
+
"modalClose": "BiQ1zG_modalClose",
|
|
774
|
+
"modalIn": "BiQ1zG_modalIn",
|
|
775
|
+
"queueRowTarget": "BiQ1zG_queueRowTarget",
|
|
776
|
+
"restartNow": "BiQ1zG_restartNow",
|
|
777
|
+
"hubUpdateMetaItem": "BiQ1zG_hubUpdateMetaItem",
|
|
778
|
+
"detailGrid": "BiQ1zG_detailGrid",
|
|
779
|
+
"toastFail": "BiQ1zG_toastFail",
|
|
780
|
+
"progressText": "BiQ1zG_progressText",
|
|
781
|
+
"detailPathText": "BiQ1zG_detailPathText",
|
|
782
|
+
"failEmpty": "BiQ1zG_failEmpty",
|
|
773
783
|
"failKindInstall": "BiQ1zG_failKindInstall",
|
|
774
|
-
"
|
|
775
|
-
"
|
|
776
|
-
"
|
|
784
|
+
"pendingRowActions": "BiQ1zG_pendingRowActions",
|
|
785
|
+
"noticeBadgeFail": "BiQ1zG_noticeBadgeFail",
|
|
786
|
+
"noticeHead": "BiQ1zG_noticeHead",
|
|
787
|
+
"modalTitleQueued": "BiQ1zG_modalTitleQueued",
|
|
788
|
+
"modalActions": "BiQ1zG_modalActions",
|
|
789
|
+
"progressFill": "BiQ1zG_progressFill",
|
|
790
|
+
"noticeIgnore": "BiQ1zG_noticeIgnore",
|
|
777
791
|
"cliOnlyHint": "BiQ1zG_cliOnlyHint",
|
|
778
|
-
"
|
|
779
|
-
"
|
|
792
|
+
"detailStatusPending": "BiQ1zG_detailStatusPending",
|
|
793
|
+
"modalCmd": "BiQ1zG_modalCmd",
|
|
794
|
+
"queueRowPct": "BiQ1zG_queueRowPct",
|
|
795
|
+
"progress": "BiQ1zG_progress",
|
|
796
|
+
"uninstallConfirm": "BiQ1zG_uninstallConfirm",
|
|
797
|
+
"noticeUpdateGo": "BiQ1zG_noticeUpdateGo",
|
|
798
|
+
"noticeTextFail": "BiQ1zG_noticeTextFail",
|
|
799
|
+
"aboutModal": "BiQ1zG_aboutModal",
|
|
800
|
+
"failKindUninstall": "BiQ1zG_failKindUninstall",
|
|
801
|
+
"modalRow": "BiQ1zG_modalRow",
|
|
802
|
+
"queueRowHead": "BiQ1zG_queueRowHead",
|
|
780
803
|
"failHead": "BiQ1zG_failHead",
|
|
781
|
-
"noticeRowOk": "BiQ1zG_noticeRowOk",
|
|
782
804
|
"detailModal": "BiQ1zG_detailModal",
|
|
783
|
-
"
|
|
784
|
-
"
|
|
805
|
+
"modalTitleBusy": "BiQ1zG_modalTitleBusy",
|
|
806
|
+
"modalCloseIcon": "BiQ1zG_modalCloseIcon",
|
|
807
|
+
"toastIn": "BiQ1zG_toastIn",
|
|
785
808
|
"hubUpdateMeta": "BiQ1zG_hubUpdateMeta",
|
|
786
|
-
"
|
|
787
|
-
"
|
|
788
|
-
"
|
|
789
|
-
"
|
|
809
|
+
"modal": "BiQ1zG_modal",
|
|
810
|
+
"detailDim": "BiQ1zG_detailDim",
|
|
811
|
+
"modalCmdCopy": "BiQ1zG_modalCmdCopy",
|
|
812
|
+
"detailStatusRunning": "BiQ1zG_detailStatusRunning",
|
|
813
|
+
"errorModal": "BiQ1zG_errorModal",
|
|
814
|
+
"modalTitle": "BiQ1zG_modalTitle",
|
|
790
815
|
"overlayIn": "BiQ1zG_overlayIn",
|
|
791
|
-
"
|
|
792
|
-
"
|
|
793
|
-
"modalIn": "BiQ1zG_modalIn",
|
|
794
|
-
"queueRowHead": "BiQ1zG_queueRowHead",
|
|
795
|
-
"detailLabel": "BiQ1zG_detailLabel",
|
|
796
|
-
"queueRowPct": "BiQ1zG_queueRowPct",
|
|
797
|
-
"noticeRow": "BiQ1zG_noticeRow",
|
|
798
|
-
"resultRestarting": "BiQ1zG_resultRestarting",
|
|
816
|
+
"failedCopyHint": "BiQ1zG_failedCopyHint",
|
|
817
|
+
"errorHint": "BiQ1zG_errorHint",
|
|
799
818
|
"progressFillFail": "BiQ1zG_progressFillFail",
|
|
800
819
|
"failBigIssue": "BiQ1zG_failBigIssue",
|
|
801
|
-
"
|
|
802
|
-
"detailPath": "BiQ1zG_detailPath",
|
|
803
|
-
"restartNowWarning": "BiQ1zG_restartNowWarning",
|
|
804
|
-
"noticeUpdateGo": "BiQ1zG_noticeUpdateGo",
|
|
805
|
-
"failDiagBtn": "BiQ1zG_failDiagBtn",
|
|
806
|
-
"failClear": "BiQ1zG_failClear",
|
|
807
|
-
"modalCmdCopy": "BiQ1zG_modalCmdCopy",
|
|
808
|
-
"noticeRowMain": "BiQ1zG_noticeRowMain",
|
|
809
|
-
"failRow": "BiQ1zG_failRow",
|
|
810
|
-
"noticeBadgeFail": "BiQ1zG_noticeBadgeFail",
|
|
811
|
-
"hubUpdateNotes": "BiQ1zG_hubUpdateNotes",
|
|
812
|
-
"progressTrack": "BiQ1zG_progressTrack",
|
|
813
|
-
"confirmPrimary": "BiQ1zG_confirmPrimary",
|
|
814
|
-
"logModal": "BiQ1zG_logModal",
|
|
815
|
-
"toastIn": "BiQ1zG_toastIn",
|
|
816
|
-
"modalCancel": "BiQ1zG_modalCancel",
|
|
817
|
-
"modalActions": "BiQ1zG_modalActions",
|
|
818
|
-
"confirmIconWrap": "BiQ1zG_confirmIconWrap",
|
|
819
|
-
"detailPathText": "BiQ1zG_detailPathText",
|
|
820
|
-
"modal": "BiQ1zG_modal",
|
|
821
|
-
"toastFail": "BiQ1zG_toastFail",
|
|
820
|
+
"aboutContent": "BiQ1zG_aboutContent",
|
|
822
821
|
"queueRowTrack": "BiQ1zG_queueRowTrack",
|
|
823
|
-
"
|
|
822
|
+
"pendingRowStatus": "BiQ1zG_pendingRowStatus",
|
|
823
|
+
"detailStars": "BiQ1zG_detailStars",
|
|
824
|
+
"detailArrow": "BiQ1zG_detailArrow",
|
|
825
|
+
"queuedHint": "BiQ1zG_queuedHint",
|
|
826
|
+
"progressHead": "BiQ1zG_progressHead",
|
|
824
827
|
"errorTitle": "BiQ1zG_errorTitle",
|
|
825
828
|
"confirmIconDanger": "BiQ1zG_confirmIconDanger",
|
|
826
|
-
"
|
|
827
|
-
"
|
|
828
|
-
"
|
|
829
|
-
"
|
|
829
|
+
"queueRowStatus": "BiQ1zG_queueRowStatus",
|
|
830
|
+
"modalWide": "BiQ1zG_modalWide",
|
|
831
|
+
"linkIcon": "BiQ1zG_linkIcon",
|
|
832
|
+
"failClear": "BiQ1zG_failClear",
|
|
833
|
+
"detailLink": "BiQ1zG_detailLink",
|
|
834
|
+
"logModal": "BiQ1zG_logModal",
|
|
835
|
+
"failList": "BiQ1zG_failList",
|
|
830
836
|
"noticeBadgeIcon": "BiQ1zG_noticeBadgeIcon",
|
|
837
|
+
"aboutMeta": "BiQ1zG_aboutMeta",
|
|
838
|
+
"queueRow": "BiQ1zG_queueRow",
|
|
839
|
+
"modalCancel": "BiQ1zG_modalCancel",
|
|
840
|
+
"noticeRowMain": "BiQ1zG_noticeRowMain",
|
|
841
|
+
"hubUpdateNotes": "BiQ1zG_hubUpdateNotes",
|
|
842
|
+
"noticeVersion": "BiQ1zG_noticeVersion",
|
|
843
|
+
"noticeFoot": "BiQ1zG_noticeFoot",
|
|
844
|
+
"trustHint": "BiQ1zG_trustHint",
|
|
845
|
+
"failRow": "BiQ1zG_failRow",
|
|
831
846
|
"resultTitle": "BiQ1zG_resultTitle",
|
|
832
|
-
"
|
|
833
|
-
"
|
|
834
|
-
"
|
|
847
|
+
"errorCopySoft": "BiQ1zG_errorCopySoft",
|
|
848
|
+
"detailPathBtn": "BiQ1zG_detailPathBtn",
|
|
849
|
+
"noticeTime": "BiQ1zG_noticeTime",
|
|
835
850
|
"noticeMain": "BiQ1zG_noticeMain",
|
|
836
|
-
"
|
|
837
|
-
"
|
|
838
|
-
"
|
|
839
|
-
"
|
|
840
|
-
"
|
|
841
|
-
"
|
|
842
|
-
"
|
|
843
|
-
"
|
|
851
|
+
"modalInstall": "BiQ1zG_modalInstall",
|
|
852
|
+
"noticeRow": "BiQ1zG_noticeRow",
|
|
853
|
+
"detailLabel": "BiQ1zG_detailLabel",
|
|
854
|
+
"noticeTextOk": "BiQ1zG_noticeTextOk",
|
|
855
|
+
"failDiagBtn": "BiQ1zG_failDiagBtn",
|
|
856
|
+
"failRepo": "BiQ1zG_failRepo",
|
|
857
|
+
"detailPathActions": "BiQ1zG_detailPathActions",
|
|
858
|
+
"progressTrack": "BiQ1zG_progressTrack",
|
|
859
|
+
"modalCmdText": "BiQ1zG_modalCmdText",
|
|
860
|
+
"confirmIconWrap": "BiQ1zG_confirmIconWrap",
|
|
861
|
+
"modalDesc": "BiQ1zG_modalDesc",
|
|
862
|
+
"queueRowBody": "BiQ1zG_queueRowBody",
|
|
863
|
+
"failNetworkTarget": "BiQ1zG_failNetworkTarget",
|
|
844
864
|
"hubUpdateModal": "BiQ1zG_hubUpdateModal",
|
|
845
|
-
"detailArrow": "BiQ1zG_detailArrow",
|
|
846
|
-
"detailStatusPending": "BiQ1zG_detailStatusPending",
|
|
847
|
-
"queueRowTarget": "BiQ1zG_queueRowTarget",
|
|
848
|
-
"errorCopySoft": "BiQ1zG_errorCopySoft",
|
|
849
|
-
"modalLabel": "BiQ1zG_modalLabel",
|
|
850
|
-
"modalWide": "BiQ1zG_modalWide",
|
|
851
|
-
"noticeList": "BiQ1zG_noticeList",
|
|
852
|
-
"noticeIgnore": "BiQ1zG_noticeIgnore",
|
|
853
|
-
"failKindUninstall": "BiQ1zG_failKindUninstall",
|
|
854
|
-
"detailStars": "BiQ1zG_detailStars",
|
|
855
|
-
"resultDesc": "BiQ1zG_resultDesc",
|
|
856
865
|
"detailRow": "BiQ1zG_detailRow",
|
|
866
|
+
"errorBox": "BiQ1zG_errorBox",
|
|
867
|
+
"stripCancel": "BiQ1zG_stripCancel",
|
|
857
868
|
"modalValue": "BiQ1zG_modalValue",
|
|
869
|
+
"helpModal": "BiQ1zG_helpModal",
|
|
870
|
+
"toast": "BiQ1zG_toast",
|
|
871
|
+
"noticeList": "BiQ1zG_noticeList",
|
|
872
|
+
"dangerConfirm": "BiQ1zG_dangerConfirm",
|
|
873
|
+
"modalBody": "BiQ1zG_modalBody",
|
|
874
|
+
"detailMono": "BiQ1zG_detailMono",
|
|
875
|
+
"resultCheckIcon": "BiQ1zG_resultCheckIcon",
|
|
876
|
+
"modalHead": "BiQ1zG_modalHead",
|
|
877
|
+
"detailUpdateHint": "BiQ1zG_detailUpdateHint",
|
|
878
|
+
"failKind": "BiQ1zG_failKind",
|
|
858
879
|
"noticeBadgeOk": "BiQ1zG_noticeBadgeOk",
|
|
859
|
-
"modalTitle": "BiQ1zG_modalTitle",
|
|
860
880
|
"noticeRemove": "BiQ1zG_noticeRemove",
|
|
861
|
-
"
|
|
862
|
-
"
|
|
863
|
-
"
|
|
864
|
-
"
|
|
865
|
-
"progressText": "BiQ1zG_progressText",
|
|
866
|
-
"noticeTextOk": "BiQ1zG_noticeTextOk",
|
|
867
|
-
"noticeHead": "BiQ1zG_noticeHead",
|
|
868
|
-
"progressHead": "BiQ1zG_progressHead",
|
|
869
|
-
"hubUpdateMetaItem": "BiQ1zG_hubUpdateMetaItem",
|
|
870
|
-
"detailLink": "BiQ1zG_detailLink",
|
|
871
|
-
"detailPathBtn": "BiQ1zG_detailPathBtn",
|
|
872
|
-
"detailValue": "BiQ1zG_detailValue",
|
|
873
|
-
"modalHead": "BiQ1zG_modalHead",
|
|
874
|
-
"errorBox": "BiQ1zG_errorBox",
|
|
875
|
-
"errorHint": "BiQ1zG_errorHint",
|
|
876
|
-
"queueSectionTitle": "BiQ1zG_queueSectionTitle",
|
|
877
|
-
"failRepo": "BiQ1zG_failRepo",
|
|
878
|
-
"aboutMeta": "BiQ1zG_aboutMeta",
|
|
879
|
-
"resultCheckIcon": "BiQ1zG_resultCheckIcon",
|
|
880
|
-
"queueRowStatus": "BiQ1zG_queueRowStatus",
|
|
881
|
-
"modalBody": "BiQ1zG_modalBody",
|
|
882
|
-
"progress": "BiQ1zG_progress",
|
|
883
|
-
"noticeFoot": "BiQ1zG_noticeFoot",
|
|
884
|
-
"resultCheck": "BiQ1zG_resultCheck"
|
|
881
|
+
"detailStatusText": "BiQ1zG_detailStatusText",
|
|
882
|
+
"confirmPrimary": "BiQ1zG_confirmPrimary",
|
|
883
|
+
"result": "BiQ1zG_result",
|
|
884
|
+
"modalLink": "BiQ1zG_modalLink"
|
|
885
885
|
};
|
|
886
886
|
//#endregion
|
|
887
887
|
//#region src/client/logic/install-command.ts
|
|
@@ -951,7 +951,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
951
951
|
* tsdown 构建时用 define 把 __PLUGIN_VERSION__ 替换成 package.json 的版本号;
|
|
952
952
|
* node --test 直接 import 本模块时该标识符不存在,typeof 守卫兜底为空串。
|
|
953
953
|
*/
|
|
954
|
-
const PLUGIN_VERSION = "1.4.
|
|
954
|
+
const PLUGIN_VERSION = "1.4.12";
|
|
955
955
|
const CATEGORY_ORDER = [
|
|
956
956
|
"interface",
|
|
957
957
|
"session",
|
|
@@ -1588,7 +1588,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1588
1588
|
*/
|
|
1589
1589
|
const hubHasUpdate = (() => {
|
|
1590
1590
|
if (!hubUpdateInfo) return false;
|
|
1591
|
-
if (hubUpdateInfo.version === "1.4.
|
|
1591
|
+
if (hubUpdateInfo.version === "1.4.12") return false;
|
|
1592
1592
|
const publishedAt = hubUpdateInfo.publishedAt;
|
|
1593
1593
|
if (publishedAt) {
|
|
1594
1594
|
const publishedMs = Date.parse(publishedAt);
|
|
@@ -4167,40 +4167,40 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
4167
4167
|
css: css$9
|
|
4168
4168
|
});
|
|
4169
4169
|
var List_module_css_default = {
|
|
4170
|
-
"
|
|
4171
|
-
"
|
|
4172
|
-
"
|
|
4173
|
-
"
|
|
4170
|
+
"state": "_3XaZHa_state",
|
|
4171
|
+
"desc": "_3XaZHa_desc",
|
|
4172
|
+
"stats": "_3XaZHa_stats",
|
|
4173
|
+
"star": "_3XaZHa_star",
|
|
4174
|
+
"cardTitle": "_3XaZHa_cardTitle",
|
|
4174
4175
|
"stateActions": "_3XaZHa_stateActions",
|
|
4176
|
+
"uninstallBtn": "_3XaZHa_uninstallBtn",
|
|
4177
|
+
"body": "_3XaZHa_body",
|
|
4175
4178
|
"categoryBadge": "_3XaZHa_categoryBadge",
|
|
4176
|
-
"
|
|
4177
|
-
"
|
|
4179
|
+
"fork": "_3XaZHa_fork",
|
|
4180
|
+
"actions": "_3XaZHa_actions",
|
|
4181
|
+
"retryBtn": "_3XaZHa_retryBtn",
|
|
4182
|
+
"footLink": "_3XaZHa_footLink",
|
|
4178
4183
|
"installBtnUpdate": "_3XaZHa_installBtnUpdate",
|
|
4179
|
-
"
|
|
4180
|
-
"
|
|
4181
|
-
"footer": "_3XaZHa_footer",
|
|
4182
|
-
"uninstallBtn": "_3XaZHa_uninstallBtn",
|
|
4183
|
-
"detailBtn": "_3XaZHa_detailBtn",
|
|
4184
|
+
"list": "_3XaZHa_list",
|
|
4185
|
+
"card": "_3XaZHa_card",
|
|
4184
4186
|
"cardMain": "_3XaZHa_cardMain",
|
|
4185
|
-
"
|
|
4187
|
+
"versionBadge": "_3XaZHa_versionBadge",
|
|
4188
|
+
"stateTitle": "_3XaZHa_stateTitle",
|
|
4186
4189
|
"date": "_3XaZHa_date",
|
|
4187
|
-
"actions": "_3XaZHa_actions",
|
|
4188
4190
|
"installBtn": "_3XaZHa_installBtn",
|
|
4189
|
-
"
|
|
4190
|
-
"
|
|
4191
|
+
"detailBtn": "_3XaZHa_detailBtn",
|
|
4192
|
+
"updateBadge": "_3XaZHa_updateBadge",
|
|
4193
|
+
"topic": "_3XaZHa_topic",
|
|
4194
|
+
"cardSide": "_3XaZHa_cardSide",
|
|
4195
|
+
"footer": "_3XaZHa_footer",
|
|
4191
4196
|
"verified": "_3XaZHa_verified",
|
|
4192
|
-
"
|
|
4197
|
+
"stateDesc": "_3XaZHa_stateDesc",
|
|
4198
|
+
"cardHead": "_3XaZHa_cardHead",
|
|
4193
4199
|
"installBtnCopied": "_3XaZHa_installBtnCopied",
|
|
4194
|
-
"
|
|
4195
|
-
"body": "_3XaZHa_body",
|
|
4200
|
+
"diagBtn": "_3XaZHa_diagBtn",
|
|
4196
4201
|
"topics": "_3XaZHa_topics",
|
|
4197
|
-
"
|
|
4198
|
-
"
|
|
4199
|
-
"stats": "_3XaZHa_stats",
|
|
4200
|
-
"cardHead": "_3XaZHa_cardHead",
|
|
4201
|
-
"cardTitle": "_3XaZHa_cardTitle",
|
|
4202
|
-
"installBtnInstalled": "_3XaZHa_installBtnInstalled",
|
|
4203
|
-
"moreSentinel": "_3XaZHa_moreSentinel"
|
|
4202
|
+
"moreSentinel": "_3XaZHa_moreSentinel",
|
|
4203
|
+
"installBtnInstalled": "_3XaZHa_installBtnInstalled"
|
|
4204
4204
|
};
|
|
4205
4205
|
//#endregion
|
|
4206
4206
|
//#region src/client/hooks/useIncrementalList.ts
|
|
@@ -4407,15 +4407,15 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
4407
4407
|
css: css$8
|
|
4408
4408
|
});
|
|
4409
4409
|
var SectionTabs_module_css_default = {
|
|
4410
|
-
"tabIcon": "_7tvizq_tabIcon",
|
|
4411
|
-
"tab": "_7tvizq_tab",
|
|
4412
|
-
"tabCount": "_7tvizq_tabCount",
|
|
4413
|
-
"noticeIcon": "_7tvizq_noticeIcon",
|
|
4414
4410
|
"noticeBtn": "_7tvizq_noticeBtn",
|
|
4411
|
+
"tabIcon": "_7tvizq_tabIcon",
|
|
4412
|
+
"tabCountActive": "_7tvizq_tabCountActive",
|
|
4415
4413
|
"noticeCount": "_7tvizq_noticeCount",
|
|
4416
4414
|
"root": "_7tvizq_root",
|
|
4417
|
-
"
|
|
4418
|
-
"tabActive": "_7tvizq_tabActive"
|
|
4415
|
+
"tab": "_7tvizq_tab",
|
|
4416
|
+
"tabActive": "_7tvizq_tabActive",
|
|
4417
|
+
"tabCount": "_7tvizq_tabCount",
|
|
4418
|
+
"noticeIcon": "_7tvizq_noticeIcon"
|
|
4419
4419
|
};
|
|
4420
4420
|
//#endregion
|
|
4421
4421
|
//#region src/client/components/layout/SectionTabs.tsx
|
|
@@ -4492,42 +4492,42 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
4492
4492
|
css: css$7
|
|
4493
4493
|
});
|
|
4494
4494
|
var InstalledView_module_css_default = {
|
|
4495
|
-
"
|
|
4496
|
-
"
|
|
4495
|
+
"rowTitle": "_1nXeGW_rowTitle",
|
|
4496
|
+
"segRow": "_1nXeGW_segRow",
|
|
4497
|
+
"segLabel": "_1nXeGW_segLabel",
|
|
4498
|
+
"segGroup": "_1nXeGW_segGroup",
|
|
4497
4499
|
"rowUninstall": "_1nXeGW_rowUninstall",
|
|
4498
|
-
"
|
|
4500
|
+
"rowMeta": "_1nXeGW_rowMeta",
|
|
4501
|
+
"rowSourceTagManual": "_1nXeGW_rowSourceTagManual",
|
|
4502
|
+
"list": "_1nXeGW_list",
|
|
4503
|
+
"rowTitleLine": "_1nXeGW_rowTitleLine",
|
|
4504
|
+
"exampleRow": "_1nXeGW_exampleRow",
|
|
4505
|
+
"rowSourceTag": "_1nXeGW_rowSourceTag",
|
|
4506
|
+
"statusPending": "_1nXeGW_statusPending",
|
|
4507
|
+
"rowSourceTagHub": "_1nXeGW_rowSourceTagHub",
|
|
4508
|
+
"segBtnActive": "_1nXeGW_segBtnActive",
|
|
4499
4509
|
"rowDesc": "_1nXeGW_rowDesc",
|
|
4500
|
-
"rowMain": "_1nXeGW_rowMain",
|
|
4501
4510
|
"versionBadge": "_1nXeGW_versionBadge",
|
|
4502
|
-
"
|
|
4503
|
-
"toolbar": "_1nXeGW_toolbar",
|
|
4504
|
-
"rowRepo": "_1nXeGW_rowRepo",
|
|
4505
|
-
"rowSourceTag": "_1nXeGW_rowSourceTag",
|
|
4511
|
+
"segBtn": "_1nXeGW_segBtn",
|
|
4506
4512
|
"rowActions": "_1nXeGW_rowActions",
|
|
4507
|
-
"
|
|
4508
|
-
"statusInactive": "_1nXeGW_statusInactive",
|
|
4513
|
+
"rowDetail": "_1nXeGW_rowDetail",
|
|
4509
4514
|
"rowRestart": "_1nXeGW_rowRestart",
|
|
4510
|
-
"
|
|
4511
|
-
"
|
|
4512
|
-
"
|
|
4513
|
-
"
|
|
4514
|
-
"rowMeta": "_1nXeGW_rowMeta",
|
|
4515
|
-
"rowTitleLine": "_1nXeGW_rowTitleLine",
|
|
4516
|
-
"segLabel": "_1nXeGW_segLabel",
|
|
4515
|
+
"toolbar": "_1nXeGW_toolbar",
|
|
4516
|
+
"updateBadge": "_1nXeGW_updateBadge",
|
|
4517
|
+
"rowCategory": "_1nXeGW_rowCategory",
|
|
4518
|
+
"statusInactive": "_1nXeGW_statusInactive",
|
|
4517
4519
|
"searchWrap": "_1nXeGW_searchWrap",
|
|
4518
|
-
"
|
|
4519
|
-
"segRow": "_1nXeGW_segRow",
|
|
4520
|
-
"exampleBadge": "_1nXeGW_exampleBadge",
|
|
4521
|
-
"statusDot": "_1nXeGW_statusDot",
|
|
4520
|
+
"rowMain": "_1nXeGW_rowMain",
|
|
4522
4521
|
"rowUpdate": "_1nXeGW_rowUpdate",
|
|
4522
|
+
"statusDot": "_1nXeGW_statusDot",
|
|
4523
4523
|
"empty": "_1nXeGW_empty",
|
|
4524
|
+
"emptyTitle": "_1nXeGW_emptyTitle",
|
|
4525
|
+
"rowRepo": "_1nXeGW_rowRepo",
|
|
4526
|
+
"exampleBadge": "_1nXeGW_exampleBadge",
|
|
4527
|
+
"row": "_1nXeGW_row",
|
|
4524
4528
|
"emptyDesc": "_1nXeGW_emptyDesc",
|
|
4525
|
-
"
|
|
4526
|
-
"
|
|
4527
|
-
"statusPending": "_1nXeGW_statusPending",
|
|
4528
|
-
"rowCategory": "_1nXeGW_rowCategory",
|
|
4529
|
-
"rowSourceTagHub": "_1nXeGW_rowSourceTagHub",
|
|
4530
|
-
"updateBadge": "_1nXeGW_updateBadge"
|
|
4529
|
+
"root": "_1nXeGW_root",
|
|
4530
|
+
"searchInput": "_1nXeGW_searchInput"
|
|
4531
4531
|
};
|
|
4532
4532
|
//#endregion
|
|
4533
4533
|
//#region src/client/components/views/InstalledView.tsx
|
|
@@ -4773,28 +4773,28 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
4773
4773
|
css: css$6
|
|
4774
4774
|
});
|
|
4775
4775
|
var CustomInstallView_module_css_default = {
|
|
4776
|
+
"helpNote": "zISxCG_helpNote",
|
|
4776
4777
|
"installCards": "zISxCG_installCards",
|
|
4777
|
-
"installLabel": "zISxCG_installLabel",
|
|
4778
4778
|
"installInsertBtn": "zISxCG_installInsertBtn",
|
|
4779
|
-
"installExample": "zISxCG_installExample",
|
|
4780
|
-
"installRow": "zISxCG_installRow",
|
|
4781
|
-
"channelOffBtn": "zISxCG_channelOffBtn",
|
|
4782
|
-
"helpCmd": "zISxCG_helpCmd",
|
|
4783
|
-
"channelOffText": "zISxCG_channelOffText",
|
|
4784
4779
|
"installInput": "zISxCG_installInput",
|
|
4785
|
-
"
|
|
4780
|
+
"installInputError": "zISxCG_installInputError",
|
|
4781
|
+
"installBtn": "zISxCG_installBtn",
|
|
4786
4782
|
"installCard": "zISxCG_installCard",
|
|
4787
|
-
"
|
|
4788
|
-
"
|
|
4789
|
-
"
|
|
4783
|
+
"channelOffText": "zISxCG_channelOffText",
|
|
4784
|
+
"installError": "zISxCG_installError",
|
|
4785
|
+
"helpCmd": "zISxCG_helpCmd",
|
|
4786
|
+
"channelOff": "zISxCG_channelOff",
|
|
4787
|
+
"installHelpBtn": "zISxCG_installHelpBtn",
|
|
4790
4788
|
"desc": "zISxCG_desc",
|
|
4791
|
-
"
|
|
4792
|
-
"
|
|
4789
|
+
"installLabel": "zISxCG_installLabel",
|
|
4790
|
+
"channelOffBtn": "zISxCG_channelOffBtn",
|
|
4793
4791
|
"helpBody": "zISxCG_helpBody",
|
|
4794
|
-
"
|
|
4795
|
-
"
|
|
4796
|
-
"
|
|
4797
|
-
"
|
|
4792
|
+
"installExample": "zISxCG_installExample",
|
|
4793
|
+
"helpLine": "zISxCG_helpLine",
|
|
4794
|
+
"root": "zISxCG_root",
|
|
4795
|
+
"installRow": "zISxCG_installRow",
|
|
4796
|
+
"installCardHead": "zISxCG_installCardHead",
|
|
4797
|
+
"installCardDisabled": "zISxCG_installCardDisabled"
|
|
4798
4798
|
};
|
|
4799
4799
|
//#endregion
|
|
4800
4800
|
//#region src/client/components/views/CustomInstallView.tsx
|
|
@@ -5084,30 +5084,30 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
5084
5084
|
css: css$5
|
|
5085
5085
|
});
|
|
5086
5086
|
var SettingsView_module_css_default = {
|
|
5087
|
-
"
|
|
5088
|
-
"pageHeader": "_506LLG_pageHeader",
|
|
5089
|
-
"settingRowStack": "_506LLG_settingRowStack",
|
|
5090
|
-
"textInput": "_506LLG_textInput",
|
|
5087
|
+
"settingLabel": "_506LLG_settingLabel",
|
|
5091
5088
|
"navIcon": "_506LLG_navIcon",
|
|
5092
|
-
"proxyControl": "_506LLG_proxyControl",
|
|
5093
|
-
"pageTitle": "_506LLG_pageTitle",
|
|
5094
5089
|
"navItem": "_506LLG_navItem",
|
|
5095
|
-
"
|
|
5096
|
-
"
|
|
5097
|
-
"
|
|
5098
|
-
"settingLabel": "_506LLG_settingLabel",
|
|
5099
|
-
"settingRow": "_506LLG_settingRow",
|
|
5090
|
+
"navItemActive": "_506LLG_navItemActive",
|
|
5091
|
+
"content": "_506LLG_content",
|
|
5092
|
+
"card": "_506LLG_card",
|
|
5100
5093
|
"settingControlStack": "_506LLG_settingControlStack",
|
|
5101
5094
|
"proxyHint": "_506LLG_proxyHint",
|
|
5095
|
+
"proxyHintFail": "_506LLG_proxyHintFail",
|
|
5096
|
+
"pageHeader": "_506LLG_pageHeader",
|
|
5097
|
+
"settingTitle": "_506LLG_settingTitle",
|
|
5098
|
+
"pageTitle": "_506LLG_pageTitle",
|
|
5099
|
+
"sidebar": "_506LLG_sidebar",
|
|
5102
5100
|
"settingDesc": "_506LLG_settingDesc",
|
|
5101
|
+
"settingControl": "_506LLG_settingControl",
|
|
5102
|
+
"proxyControl": "_506LLG_proxyControl",
|
|
5103
5103
|
"proxyHintOk": "_506LLG_proxyHintOk",
|
|
5104
5104
|
"resetBtn": "_506LLG_resetBtn",
|
|
5105
5105
|
"pageDesc": "_506LLG_pageDesc",
|
|
5106
|
-
"
|
|
5107
|
-
"
|
|
5108
|
-
"
|
|
5109
|
-
"
|
|
5110
|
-
"
|
|
5106
|
+
"textInput": "_506LLG_textInput",
|
|
5107
|
+
"settingRow": "_506LLG_settingRow",
|
|
5108
|
+
"settingRowStack": "_506LLG_settingRowStack",
|
|
5109
|
+
"controlDropdown": "_506LLG_controlDropdown",
|
|
5110
|
+
"root": "_506LLG_root"
|
|
5111
5111
|
};
|
|
5112
5112
|
//#endregion
|
|
5113
5113
|
//#region \0dsh-css:src/client/styles/Dropdown.module.css.mjs
|
|
@@ -5126,18 +5126,18 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
5126
5126
|
css: css$4
|
|
5127
5127
|
});
|
|
5128
5128
|
var Dropdown_module_css_default = {
|
|
5129
|
-
"
|
|
5130
|
-
"dropdownPanel": "B_Gxsq_dropdownPanel",
|
|
5129
|
+
"dropdownLabel": "B_Gxsq_dropdownLabel",
|
|
5131
5130
|
"dropdownItemActive": "B_Gxsq_dropdownItemActive",
|
|
5132
|
-
"dropdownFill": "B_Gxsq_dropdownFill",
|
|
5133
|
-
"dropdownCount": "B_Gxsq_dropdownCount",
|
|
5134
|
-
"dropdownItemLabel": "B_Gxsq_dropdownItemLabel",
|
|
5135
5131
|
"dropdownArrowOpen": "B_Gxsq_dropdownArrowOpen",
|
|
5136
5132
|
"dropdownBtn": "B_Gxsq_dropdownBtn",
|
|
5137
|
-
"
|
|
5138
|
-
"
|
|
5133
|
+
"dropdownArrow": "B_Gxsq_dropdownArrow",
|
|
5134
|
+
"dropdownFill": "B_Gxsq_dropdownFill",
|
|
5139
5135
|
"dropdownItem": "B_Gxsq_dropdownItem",
|
|
5140
|
-
"
|
|
5136
|
+
"dropdownItemLabel": "B_Gxsq_dropdownItemLabel",
|
|
5137
|
+
"dropdownPanel": "B_Gxsq_dropdownPanel",
|
|
5138
|
+
"dropdownCount": "B_Gxsq_dropdownCount",
|
|
5139
|
+
"dropdownCountActive": "B_Gxsq_dropdownCountActive",
|
|
5140
|
+
"dropdown": "B_Gxsq_dropdown"
|
|
5141
5141
|
};
|
|
5142
5142
|
//#endregion
|
|
5143
5143
|
//#region \0dsh-css:src/client/styles/Toggle.module.css.mjs
|
|
@@ -5156,9 +5156,9 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
5156
5156
|
css: css$3
|
|
5157
5157
|
});
|
|
5158
5158
|
var Toggle_module_css_default = {
|
|
5159
|
+
"toggle": "k-cD4G_toggle",
|
|
5159
5160
|
"toggleOn": "k-cD4G_toggleOn",
|
|
5160
|
-
"knob": "k-cD4G_knob"
|
|
5161
|
-
"toggle": "k-cD4G_toggle"
|
|
5161
|
+
"knob": "k-cD4G_knob"
|
|
5162
5162
|
};
|
|
5163
5163
|
//#endregion
|
|
5164
5164
|
//#region src/client/components/ui/Toggle.tsx
|
|
@@ -5258,29 +5258,29 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
5258
5258
|
css: css$2
|
|
5259
5259
|
});
|
|
5260
5260
|
var DiagnosticsView_module_css_default = {
|
|
5261
|
-
"envDesc": "k9eRya_envDesc",
|
|
5262
|
-
"badgeIdle": "k9eRya_badgeIdle",
|
|
5263
|
-
"summary": "k9eRya_summary",
|
|
5264
|
-
"envTitle": "k9eRya_envTitle",
|
|
5265
|
-
"badgeOk": "k9eRya_badgeOk",
|
|
5266
|
-
"runBtn": "k9eRya_runBtn",
|
|
5267
|
-
"head": "k9eRya_head",
|
|
5268
|
-
"badgeRunning": "k9eRya_badgeRunning",
|
|
5269
|
-
"summaryRunning": "k9eRya_summaryRunning",
|
|
5270
|
-
"diagPulse": "k9eRya_diagPulse",
|
|
5271
|
-
"badge": "k9eRya_badge",
|
|
5272
5261
|
"envCopyBtn": "k9eRya_envCopyBtn",
|
|
5273
|
-
"
|
|
5274
|
-
"envLabel": "k9eRya_envLabel",
|
|
5275
|
-
"summaryOk": "k9eRya_summaryOk",
|
|
5276
|
-
"display": "k9eRya_display",
|
|
5262
|
+
"head": "k9eRya_head",
|
|
5277
5263
|
"meta": "k9eRya_meta",
|
|
5264
|
+
"diagPulse": "k9eRya_diagPulse",
|
|
5278
5265
|
"summaryFail": "k9eRya_summaryFail",
|
|
5266
|
+
"runBtn": "k9eRya_runBtn",
|
|
5267
|
+
"envLabel": "k9eRya_envLabel",
|
|
5279
5268
|
"headHint": "k9eRya_headHint",
|
|
5280
|
-
"
|
|
5269
|
+
"badge": "k9eRya_badge",
|
|
5270
|
+
"envTitle": "k9eRya_envTitle",
|
|
5281
5271
|
"panel": "k9eRya_panel",
|
|
5272
|
+
"row": "k9eRya_row",
|
|
5273
|
+
"envRow": "k9eRya_envRow",
|
|
5274
|
+
"display": "k9eRya_display",
|
|
5275
|
+
"badgeRunning": "k9eRya_badgeRunning",
|
|
5276
|
+
"badgeIdle": "k9eRya_badgeIdle",
|
|
5277
|
+
"badgeOk": "k9eRya_badgeOk",
|
|
5278
|
+
"badgeFail": "k9eRya_badgeFail",
|
|
5279
|
+
"summaryOk": "k9eRya_summaryOk",
|
|
5280
|
+
"summary": "k9eRya_summary",
|
|
5282
5281
|
"name": "k9eRya_name",
|
|
5283
|
-
"
|
|
5282
|
+
"envDesc": "k9eRya_envDesc",
|
|
5283
|
+
"summaryRunning": "k9eRya_summaryRunning"
|
|
5284
5284
|
};
|
|
5285
5285
|
//#endregion
|
|
5286
5286
|
//#region src/client/components/views/DiagnosticsView.tsx
|
|
@@ -5458,57 +5458,57 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
5458
5458
|
css: css$1
|
|
5459
5459
|
});
|
|
5460
5460
|
var LogsView_module_css_default = {
|
|
5461
|
-
"
|
|
5462
|
-
"
|
|
5463
|
-
"
|
|
5464
|
-
"
|
|
5465
|
-
"search": "_3j77BW_search",
|
|
5466
|
-
"message": "_3j77BW_message",
|
|
5467
|
-
"footFail": "_3j77BW_footFail",
|
|
5468
|
-
"pathDialogRow": "_3j77BW_pathDialogRow",
|
|
5469
|
-
"entry": "_3j77BW_entry",
|
|
5470
|
-
"searchInput": "_3j77BW_searchInput",
|
|
5471
|
-
"foot": "_3j77BW_foot",
|
|
5461
|
+
"btn": "_3j77BW_btn",
|
|
5462
|
+
"clearBtn": "_3j77BW_clearBtn",
|
|
5463
|
+
"head": "_3j77BW_head",
|
|
5464
|
+
"pathDialogDesc": "_3j77BW_pathDialogDesc",
|
|
5472
5465
|
"badgeError": "_3j77BW_badgeError",
|
|
5473
|
-
"
|
|
5466
|
+
"badgeWarn": "_3j77BW_badgeWarn",
|
|
5474
5467
|
"catInstall": "_3j77BW_catInstall",
|
|
5475
|
-
"
|
|
5476
|
-
"head": "_3j77BW_head",
|
|
5477
|
-
"btn": "_3j77BW_btn",
|
|
5468
|
+
"headHint": "_3j77BW_headHint",
|
|
5478
5469
|
"filterBar": "_3j77BW_filterBar",
|
|
5479
|
-
"
|
|
5480
|
-
"
|
|
5481
|
-
"
|
|
5482
|
-
"badge": "_3j77BW_badge",
|
|
5483
|
-
"list": "_3j77BW_list",
|
|
5484
|
-
"empty": "_3j77BW_empty",
|
|
5485
|
-
"more": "_3j77BW_more",
|
|
5486
|
-
"badgeInfo": "_3j77BW_badgeInfo",
|
|
5487
|
-
"footPath": "_3j77BW_footPath",
|
|
5488
|
-
"catDiagnostics": "_3j77BW_catDiagnostics",
|
|
5470
|
+
"filterChip": "_3j77BW_filterChip",
|
|
5471
|
+
"pathDialogRow": "_3j77BW_pathDialogRow",
|
|
5472
|
+
"event": "_3j77BW_event",
|
|
5489
5473
|
"footActions": "_3j77BW_footActions",
|
|
5490
|
-
"
|
|
5474
|
+
"badgeSuccess": "_3j77BW_badgeSuccess",
|
|
5475
|
+
"actions": "_3j77BW_actions",
|
|
5476
|
+
"pathText": "_3j77BW_pathText",
|
|
5477
|
+
"footPath": "_3j77BW_footPath",
|
|
5491
5478
|
"pathDraft": "_3j77BW_pathDraft",
|
|
5492
|
-
"pathDialogDesc": "_3j77BW_pathDialogDesc",
|
|
5493
|
-
"pathDialogHint": "_3j77BW_pathDialogHint",
|
|
5494
5479
|
"footCount": "_3j77BW_footCount",
|
|
5480
|
+
"filterChipActive": "_3j77BW_filterChipActive",
|
|
5481
|
+
"badge": "_3j77BW_badge",
|
|
5482
|
+
"catUpdate": "_3j77BW_catUpdate",
|
|
5483
|
+
"list": "_3j77BW_list",
|
|
5495
5484
|
"pathDialogReset": "_3j77BW_pathDialogReset",
|
|
5496
|
-
"
|
|
5485
|
+
"catBadge": "_3j77BW_catBadge",
|
|
5486
|
+
"catUninstall": "_3j77BW_catUninstall",
|
|
5497
5487
|
"pathDialogFoot": "_3j77BW_pathDialogFoot",
|
|
5498
|
-
"
|
|
5499
|
-
"
|
|
5500
|
-
"
|
|
5488
|
+
"message": "_3j77BW_message",
|
|
5489
|
+
"search": "_3j77BW_search",
|
|
5490
|
+
"searchInput": "_3j77BW_searchInput",
|
|
5491
|
+
"time": "_3j77BW_time",
|
|
5501
5492
|
"moreEnd": "_3j77BW_moreEnd",
|
|
5502
|
-
"
|
|
5503
|
-
"
|
|
5504
|
-
"
|
|
5505
|
-
"
|
|
5506
|
-
"
|
|
5507
|
-
"catSettings": "_3j77BW_catSettings",
|
|
5508
|
-
"pathText": "_3j77BW_pathText",
|
|
5493
|
+
"logList": "_3j77BW_logList",
|
|
5494
|
+
"catDiagnostics": "_3j77BW_catDiagnostics",
|
|
5495
|
+
"badgeInfo": "_3j77BW_badgeInfo",
|
|
5496
|
+
"footFail": "_3j77BW_footFail",
|
|
5497
|
+
"badgeDebug": "_3j77BW_badgeDebug",
|
|
5509
5498
|
"pathDialog": "_3j77BW_pathDialog",
|
|
5510
|
-
"
|
|
5511
|
-
"
|
|
5499
|
+
"catSettings": "_3j77BW_catSettings",
|
|
5500
|
+
"entry": "_3j77BW_entry",
|
|
5501
|
+
"pathDialogHint": "_3j77BW_pathDialogHint",
|
|
5502
|
+
"linkBtn": "_3j77BW_linkBtn",
|
|
5503
|
+
"catSystem": "_3j77BW_catSystem",
|
|
5504
|
+
"pathRow": "_3j77BW_pathRow",
|
|
5505
|
+
"more": "_3j77BW_more",
|
|
5506
|
+
"foot": "_3j77BW_foot",
|
|
5507
|
+
"panel": "_3j77BW_panel",
|
|
5508
|
+
"pathLabel": "_3j77BW_pathLabel",
|
|
5509
|
+
"headActions": "_3j77BW_headActions",
|
|
5510
|
+
"previewRow": "_3j77BW_previewRow",
|
|
5511
|
+
"empty": "_3j77BW_empty"
|
|
5512
5512
|
};
|
|
5513
5513
|
//#endregion
|
|
5514
5514
|
//#region src/client/components/modals/LogsModal.tsx
|
|
@@ -6757,7 +6757,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
6757
6757
|
openSection: settingsSection,
|
|
6758
6758
|
onConsumedOpenSection: () => setSettingsSection(null)
|
|
6759
6759
|
}), showHubUpdate && (0, react.createElement)(HubUpdateModal, {
|
|
6760
|
-
info: catalog.hubUpdateInfo ?? { version: "1.4.
|
|
6760
|
+
info: catalog.hubUpdateInfo ?? { version: "1.4.12" },
|
|
6761
6761
|
lang,
|
|
6762
6762
|
t,
|
|
6763
6763
|
hasUpdate: catalog.hubHasUpdate,
|
package/lib/http/routes.js
CHANGED
|
@@ -228,26 +228,50 @@ function sendJson(response, status, value) {
|
|
|
228
228
|
});
|
|
229
229
|
response.end(JSON.stringify(value));
|
|
230
230
|
}
|
|
231
|
+
/** 本机回环主机名:`localhost` / `127.0.0.1` / `[::1]` 指向同一台机器的同一个端口,
|
|
232
|
+
* 字符串不同但同源,必须按同一来源比较(dsh-plugin-hub#72)。 */
|
|
233
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '127.0.0.1', '[::1]']);
|
|
234
|
+
/** 把 `host[:port]` 形式的 authority 归一化成 `loopback:端口` —— 三个回环别名
|
|
235
|
+
* 映射成同一个身份,端口缺省按 http 的 80 补齐;非回环主机名、以及解析不出来的值
|
|
236
|
+
* 都返回 null。 */
|
|
237
|
+
function loopbackAuthority(authority) {
|
|
238
|
+
try {
|
|
239
|
+
const parsed = new URL(`http://${authority}`);
|
|
240
|
+
if (!LOOPBACK_HOSTNAMES.has(parsed.hostname.toLowerCase()))
|
|
241
|
+
return null;
|
|
242
|
+
return `loopback:${parsed.port === '' ? '80' : parsed.port}`;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
231
248
|
/** POST mutations are only accepted from the local web server origin or the desktop host page.
|
|
232
249
|
* Exported for tests (tests/routes.test.ts) — the origin check is the whole CSRF defence. */
|
|
233
250
|
export function isSameOrigin(request) {
|
|
234
|
-
|
|
235
|
-
|
|
251
|
+
// 服务只绑定本机回环地址:Host 不是回环(局域网 IP、被改写的域名)一律拒绝,
|
|
252
|
+
// 顺带挡掉 DNS rebinding(Host 是攻击者域名,即便解析到 127.0.0.1)。
|
|
253
|
+
const host = request.headers.host;
|
|
254
|
+
const hostKey = host === undefined ? null : loopbackAuthority(host);
|
|
255
|
+
if (hostKey === null)
|
|
236
256
|
return false;
|
|
257
|
+
const origin = request.headers.origin;
|
|
258
|
+
// 桌面端宿主把 `/dsh-plugin-hub/*` 转发给本地 http server 时可能不带 Origin 头,
|
|
259
|
+
// 此时所有 POST 都会被判成 untrusted origin(dsh-plugin-hub#72)。浏览器对 POST 请求
|
|
260
|
+
// 必定携带 Origin(含同源 POST 与跨站表单),能省略该头的只有本机原生客户端,
|
|
261
|
+
// 而它们本来就能伪造任意 Origin,因此放行不扩大 CSRF 面。
|
|
262
|
+
if (origin === undefined || origin === '')
|
|
263
|
+
return true;
|
|
237
264
|
try {
|
|
238
265
|
const url = new URL(origin);
|
|
239
|
-
// 桌面端(Electron 宿主)的页面跑在宿主自定义协议下,origin 形如 `dsh-app://app
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
// 外部网页无法把 Origin 伪造成 `dsh-app://…`,放行不扩大 CSRF 面。
|
|
266
|
+
// 桌面端(Electron 宿主)的页面跑在宿主自定义协议下,origin 形如 `dsh-app://app`,
|
|
267
|
+
// 与 Host(如 localhost:3081)必然不等,因此必须显式放行该协议,否则桌面端全部 POST
|
|
268
|
+
// 都会被判成 untrusted origin。该协议只有宿主自身能产生,外部网页无法把 Origin
|
|
269
|
+
// 伪造成 `dsh-app://…`,放行不扩大 CSRF 面。
|
|
244
270
|
if (url.protocol === 'dsh-app:')
|
|
245
271
|
return true;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const localHostnames = new Set(['localhost', '127.0.0.1', '[::1]']);
|
|
250
|
-
return url.host === host && localHostnames.has(url.hostname);
|
|
272
|
+
// 按归一化后的「主机名:端口」比较:`localhost` / `127.0.0.1` / `[::1]` 不再互相拒绝,
|
|
273
|
+
// 端口仍然必须一致(另一个本机进程不能被当成同一来源)。
|
|
274
|
+
return loopbackAuthority(url.host) === hostKey;
|
|
251
275
|
}
|
|
252
276
|
catch {
|
|
253
277
|
return false;
|
|
@@ -851,10 +875,27 @@ export function mountPluginHubRoutes(webServer, profile, loader) {
|
|
|
851
875
|
? settings.proxy
|
|
852
876
|
: (systemProxy() ?? process.env.HTTPS_PROXY ?? process.env.https_proxy ?? '');
|
|
853
877
|
const isGitChannel = repoTarget !== null && target === repoTarget;
|
|
854
|
-
const
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
878
|
+
const npmProbeTarget = `${(settings.npmRegistry.replace(/\/+$/, '') || 'https://registry.npmjs.org')}/`;
|
|
879
|
+
// git 通道的探针换成克隆握手本身:git ls-remote 走的就是 pnpm 克隆前的同一套
|
|
880
|
+
// https 传输。curl 打 github.com 主页会被按协议/端口区分的防火墙与 TLS 复检
|
|
881
|
+
// 拦截(能 git 克隆、打不开网页),把可装的仓库误判成 [network] 而中止
|
|
882
|
+
// (见 issue #71)。握手失败时再用 curl 复核一次主页连通性:只有两者都不通
|
|
883
|
+
// 才判「网络不通」;仅握手失败(仓库不存在、私有仓库、需要凭据)放行,
|
|
884
|
+
// 交给后续预检与真实安装给出准确原因。
|
|
885
|
+
const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '');
|
|
886
|
+
let net;
|
|
887
|
+
if (gitProbeTarget !== null) {
|
|
888
|
+
net = await gitLsRemote(gitProbeTarget, effectiveProxy, 6000);
|
|
889
|
+
if (!net.ok) {
|
|
890
|
+
const reachable = await probeUrl('https://github.com/', effectiveProxy, 6000);
|
|
891
|
+
if (reachable.ok)
|
|
892
|
+
net = reachable;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
else {
|
|
896
|
+
net = await probeUrl(npmProbeTarget, effectiveProxy, 6000);
|
|
897
|
+
}
|
|
898
|
+
const probeTarget = gitProbeTarget ?? npmProbeTarget;
|
|
858
899
|
if (!net.ok) {
|
|
859
900
|
// 错误消息按客户端界面语言提示:中文界面给中文、英文界面给英文,
|
|
860
901
|
// 让用户一眼看懂是网络问题而非插件问题
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { spawn, spawnSync } from 'node:child_process';
|
|
11
11
|
import { resolvePackageEntry } from './package-entry.js';
|
|
12
|
-
import { readFileSync, statSync } from 'node:fs';
|
|
12
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
13
13
|
import { dirname, join, resolve } from 'node:path';
|
|
14
14
|
import { CAPTURE_LIMIT_BYTES, MAX_TASKS, MAX_TASK_LINES } from './install-types.js';
|
|
15
15
|
import { npmTooLowMarker } from './npm-check.js';
|
|
@@ -112,19 +112,55 @@ function pushLine(task, line) {
|
|
|
112
112
|
task.progress = Math.max(task.progress, 6 + Math.min(79, task.lines.length * 2));
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
function cliInvocation() {
|
|
115
|
+
function cliInvocation(profile) {
|
|
116
116
|
const entry = process.argv[1];
|
|
117
|
-
if (entry !== undefined
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
if (entry !== undefined) {
|
|
118
|
+
// 打包桌面端(Electron):宿主入口在 app.asar 内,机器上根本没有 `dsh` 可执行文件
|
|
119
|
+
//(Windows 那条 dsh.cmd shim 只存在于宿主进程自己的 PATH 里),直接回退 PATH 必然
|
|
120
|
+
// 报 [dsh-missing](见 issue #71)。这里改用应用自己的 CLI 引导脚本调起同一份打包
|
|
121
|
+
// CLI:Electron 可执行文件 + --expose-internals + desktop-cli.js,与内置终端、
|
|
122
|
+
// 官方插件页安装完全同一条路径 —— desktop profile 由应用独占管理的授权也在其中。
|
|
123
|
+
const bootstrap = desktopCliBootstrap(entry);
|
|
124
|
+
if (bootstrap !== null) {
|
|
125
|
+
return {
|
|
126
|
+
file: process.execPath,
|
|
127
|
+
prefixArgs: ['--expose-internals', bootstrap],
|
|
128
|
+
// 工作目录用 profile 目录(真实存在的目录):asar 内的路径不能作为 spawn 的 cwd
|
|
129
|
+
cwd: profileDirectory(profile),
|
|
130
|
+
useShell: false,
|
|
131
|
+
// Electron 可执行文件只有带这个变量才按 Node 运行引导脚本
|
|
132
|
+
env: { ELECTRON_RUN_AS_NODE: '1' },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (/[\\/](?:bin\.(?:js|ts)|dsh)$/.test(entry)) {
|
|
136
|
+
const absoluteEntry = resolve(entry);
|
|
137
|
+
return {
|
|
138
|
+
file: process.execPath,
|
|
139
|
+
prefixArgs: [...process.execArgv, absoluteEntry],
|
|
140
|
+
cwd: dirname(absoluteEntry),
|
|
141
|
+
useShell: false,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
125
144
|
}
|
|
126
145
|
return { file: 'dsh', prefixArgs: [], cwd: process.cwd(), useShell: process.platform === 'win32' };
|
|
127
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* 打包桌面端宿主的 CLI 引导脚本路径(`<asar 根>/lib/desktop-cli.js`,即应用内
|
|
149
|
+
* pnpm 服务的 dshBootstrapPath)。宿主入口落在 app.asar 内时按 asar 根反推候选路径,
|
|
150
|
+
* 命中存在的那个才采用;布局不认识(官方改版)时返回 null,调用方回退原逻辑。
|
|
151
|
+
* 导出供单测覆盖路径推导。
|
|
152
|
+
*/
|
|
153
|
+
export function desktopCliBootstrap(entry) {
|
|
154
|
+
const marker = /[\\/]app\.asar(?=[\\/]|$)/i.exec(entry);
|
|
155
|
+
if (marker === null)
|
|
156
|
+
return null;
|
|
157
|
+
const root = entry.slice(0, marker.index + marker[0].length);
|
|
158
|
+
for (const candidate of [join(root, 'lib', 'desktop-cli.js'), join(root, 'dsh', 'lib', 'desktop-cli.js')]) {
|
|
159
|
+
if (existsSync(candidate))
|
|
160
|
+
return candidate;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
128
164
|
/**
|
|
129
165
|
* dsh 命令存在性探测:which/where 找 PATH 里的 dsh。
|
|
130
166
|
* Windows shell 模式命令缺失时 cmd 只输出 GBK 乱码「不是内部或外部命令」(UTF-8 解码后
|
|
@@ -286,7 +322,7 @@ function spawnMutation(options) {
|
|
|
286
322
|
const isGlobalNpm = (globalNpm ?? []).length > 0;
|
|
287
323
|
const invocation = isGlobalNpm
|
|
288
324
|
? { file: 'npm', prefixArgs: [], cwd: process.cwd(), useShell: process.platform === 'win32' }
|
|
289
|
-
: cliInvocation();
|
|
325
|
+
: cliInvocation(profile);
|
|
290
326
|
// 更新已安装的 npm 包:显式指定 @latest。pnpm add <pkg>(无版本)对已存在依赖
|
|
291
327
|
// (尤其精确 spec 如 "1.3.0")是幂等的 —— 输出 "Already up to date" 且不改 package.json,
|
|
292
328
|
// 导致「更新成功」但实际仍停留在旧版本;git 地址与全局安装不受此影响。
|
|
@@ -334,7 +370,9 @@ function spawnMutation(options) {
|
|
|
334
370
|
}
|
|
335
371
|
child = spawn(invocation.file, attemptArgs, {
|
|
336
372
|
cwd: invocation.cwd,
|
|
337
|
-
env
|
|
373
|
+
// invocation.env 是「必须叠加」的变量(打包桌面端的 ELECTRON_RUN_AS_NODE):
|
|
374
|
+
// 没有它时保持 env 原样透传,有它时必须基于完整环境叠加,否则子进程会丢掉 PATH。
|
|
375
|
+
env: invocation.env === undefined ? env : { ...(env ?? process.env), ...invocation.env },
|
|
338
376
|
shell: invocation.useShell,
|
|
339
377
|
// detached 使子进程成为独立进程组组长:取消时能整组清理(见 stopChild),
|
|
340
378
|
// 且宿主进程崩溃后安装任务不会被连带误杀
|
package/lib/services/probe.js
CHANGED
|
@@ -30,6 +30,8 @@ export function curlTlsArgs() {
|
|
|
30
30
|
export function curlRevokeFlagUnsupported(code, stderr) {
|
|
31
31
|
return code === 2 && /ssl-revoke-best-effort/i.test(stderr) && /unknown|unrecognized/i.test(stderr);
|
|
32
32
|
}
|
|
33
|
+
/** 彻底关闭证书吊销检查的兜底参数(curl ≥ 7.19),比降级参数覆盖更老的 Windows curl。 */
|
|
34
|
+
const NO_REVOKE_ARG = '--ssl-no-revoke';
|
|
33
35
|
/** stderr 是否指向 Schannel 取不到证书吊销信息(据此归因为环境 TLS 问题,而非网络不通)。 */
|
|
34
36
|
export function tlsRevocationBlocked(stderr) {
|
|
35
37
|
return /CRYPT_E_NO_REVOCATION_CHECK|CRYPT_E_REVOCATION_OFFLINE|0x80092012/i.test(stderr);
|
|
@@ -135,13 +137,24 @@ function runCurl(args, env, timeoutMs) {
|
|
|
135
137
|
});
|
|
136
138
|
}
|
|
137
139
|
/** 带 TLS 兜底的 curl 调用:先按平台参数跑(Windows 带吊销检查降级),
|
|
138
|
-
* 若本机 curl 不认这个参数(curl < 7.70
|
|
140
|
+
* 若本机 curl 不认这个参数(curl < 7.70)则去掉参数重跑一次,保证老版本不因此直接失败;
|
|
141
|
+
* 降级后仍被吊销检查拦死(CRYPT_E_NO_REVOCATION_CHECK)时,再用 --ssl-no-revoke
|
|
142
|
+
* 彻底关掉吊销检查跑一次 —— 该参数 curl ≥ 7.19 即存在,覆盖面比降级参数更广,
|
|
143
|
+
* 否则「能上网但取不到 CRL」的 Windows 机器会把所有通道误报成不可达(见 issue #71)。
|
|
144
|
+
* 吊销检查只影响本次探测自身的信任判断,不改变系统 TLS 配置。 */
|
|
139
145
|
async function curlWithTlsFallback(args, env, timeoutMs) {
|
|
140
146
|
const tlsArgs = curlTlsArgs();
|
|
141
|
-
|
|
142
|
-
if (tlsArgs.length
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
let run = await runCurl([...tlsArgs, ...args], env, timeoutMs);
|
|
148
|
+
if (tlsArgs.length > 0 && curlRevokeFlagUnsupported(run.code, run.stderr)) {
|
|
149
|
+
run = await runCurl(args, env, timeoutMs);
|
|
150
|
+
}
|
|
151
|
+
if (tlsArgs.length > 0 && tlsRevocationBlocked(run.stderr)) {
|
|
152
|
+
const retry = await runCurl([NO_REVOKE_ARG, ...args], env, timeoutMs);
|
|
153
|
+
// 只在兜底本身跑起来(非「不认识该参数」)时采用其结果,否则保留原始失败线索
|
|
154
|
+
if (retry.code !== null && !curlRevokeFlagUnsupported(retry.code, retry.stderr))
|
|
155
|
+
run = retry;
|
|
156
|
+
}
|
|
157
|
+
return run;
|
|
145
158
|
}
|
|
146
159
|
/**
|
|
147
160
|
* curl 子进程探测:spawn curl -s -w '%{http_code}' 并注入代理 env。
|
|
@@ -33,6 +33,13 @@ export declare function hasQueuedTarget(target: string): boolean;
|
|
|
33
33
|
* Returns false when the task is unknown or already finished.
|
|
34
34
|
*/
|
|
35
35
|
export declare function cancelTask(id: number): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* 打包桌面端宿主的 CLI 引导脚本路径(`<asar 根>/lib/desktop-cli.js`,即应用内
|
|
38
|
+
* pnpm 服务的 dshBootstrapPath)。宿主入口落在 app.asar 内时按 asar 根反推候选路径,
|
|
39
|
+
* 命中存在的那个才采用;布局不认识(官方改版)时返回 null,调用方回退原逻辑。
|
|
40
|
+
* 导出供单测覆盖路径推导。
|
|
41
|
+
*/
|
|
42
|
+
export declare function desktopCliBootstrap(entry: string): string | null;
|
|
36
43
|
/**
|
|
37
44
|
* Enqueue a plugin mutation and return its task. Tasks run strictly serially:
|
|
38
45
|
* the queue worker starts the next one only after the previous finishes.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.12",
|
|
4
4
|
"description": "A community plugin marketplace for DeepSeek Harness, built to the official plugin spec — browse, search and install 10000+ human-curated community plugins without leaving the app. · DeepSeek Harness 社区插件市场(遵循官方开发规范):10000+ 人工精选社区插件,每日更新。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -256,23 +256,47 @@ function sendJson(response: ServerResponse, status: number, value: unknown): voi
|
|
|
256
256
|
response.end(JSON.stringify(value))
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
+
/** 本机回环主机名:`localhost` / `127.0.0.1` / `[::1]` 指向同一台机器的同一个端口,
|
|
260
|
+
* 字符串不同但同源,必须按同一来源比较(dsh-plugin-hub#72)。 */
|
|
261
|
+
const LOOPBACK_HOSTNAMES = new Set(['localhost', '127.0.0.1', '[::1]'])
|
|
262
|
+
|
|
263
|
+
/** 把 `host[:port]` 形式的 authority 归一化成 `loopback:端口` —— 三个回环别名
|
|
264
|
+
* 映射成同一个身份,端口缺省按 http 的 80 补齐;非回环主机名、以及解析不出来的值
|
|
265
|
+
* 都返回 null。 */
|
|
266
|
+
function loopbackAuthority(authority: string): string | null {
|
|
267
|
+
try {
|
|
268
|
+
const parsed = new URL(`http://${authority}`)
|
|
269
|
+
if (!LOOPBACK_HOSTNAMES.has(parsed.hostname.toLowerCase())) return null
|
|
270
|
+
return `loopback:${parsed.port === '' ? '80' : parsed.port}`
|
|
271
|
+
} catch {
|
|
272
|
+
return null
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
259
276
|
/** POST mutations are only accepted from the local web server origin or the desktop host page.
|
|
260
277
|
* Exported for tests (tests/routes.test.ts) — the origin check is the whole CSRF defence. */
|
|
261
278
|
export function isSameOrigin(request: IncomingMessage): boolean {
|
|
279
|
+
// 服务只绑定本机回环地址:Host 不是回环(局域网 IP、被改写的域名)一律拒绝,
|
|
280
|
+
// 顺带挡掉 DNS rebinding(Host 是攻击者域名,即便解析到 127.0.0.1)。
|
|
281
|
+
const host = request.headers.host
|
|
282
|
+
const hostKey = host === undefined ? null : loopbackAuthority(host)
|
|
283
|
+
if (hostKey === null) return false
|
|
262
284
|
const origin = request.headers.origin
|
|
263
|
-
|
|
285
|
+
// 桌面端宿主把 `/dsh-plugin-hub/*` 转发给本地 http server 时可能不带 Origin 头,
|
|
286
|
+
// 此时所有 POST 都会被判成 untrusted origin(dsh-plugin-hub#72)。浏览器对 POST 请求
|
|
287
|
+
// 必定携带 Origin(含同源 POST 与跨站表单),能省略该头的只有本机原生客户端,
|
|
288
|
+
// 而它们本来就能伪造任意 Origin,因此放行不扩大 CSRF 面。
|
|
289
|
+
if (origin === undefined || origin === '') return true
|
|
264
290
|
try {
|
|
265
291
|
const url = new URL(origin)
|
|
266
|
-
// 桌面端(Electron 宿主)的页面跑在宿主自定义协议下,origin 形如 `dsh-app://app
|
|
267
|
-
//
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
// 外部网页无法把 Origin 伪造成 `dsh-app://…`,放行不扩大 CSRF 面。
|
|
292
|
+
// 桌面端(Electron 宿主)的页面跑在宿主自定义协议下,origin 形如 `dsh-app://app`,
|
|
293
|
+
// 与 Host(如 localhost:3081)必然不等,因此必须显式放行该协议,否则桌面端全部 POST
|
|
294
|
+
// 都会被判成 untrusted origin。该协议只有宿主自身能产生,外部网页无法把 Origin
|
|
295
|
+
// 伪造成 `dsh-app://…`,放行不扩大 CSRF 面。
|
|
271
296
|
if (url.protocol === 'dsh-app:') return true
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return url.host === host && localHostnames.has(url.hostname)
|
|
297
|
+
// 按归一化后的「主机名:端口」比较:`localhost` / `127.0.0.1` / `[::1]` 不再互相拒绝,
|
|
298
|
+
// 端口仍然必须一致(另一个本机进程不能被当成同一来源)。
|
|
299
|
+
return loopbackAuthority(url.host) === hostKey
|
|
276
300
|
} catch {
|
|
277
301
|
return false
|
|
278
302
|
}
|
|
@@ -840,10 +864,25 @@ export function mountPluginHubRoutes(webServer: WebServerService, profile: strin
|
|
|
840
864
|
? settings.proxy
|
|
841
865
|
: (systemProxy() ?? process.env.HTTPS_PROXY ?? process.env.https_proxy ?? '')
|
|
842
866
|
const isGitChannel = repoTarget !== null && target === repoTarget
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
867
|
+
const npmProbeTarget = `${(settings.npmRegistry.replace(/\/+$/, '') || 'https://registry.npmjs.org')}/`
|
|
868
|
+
// git 通道的探针换成克隆握手本身:git ls-remote 走的就是 pnpm 克隆前的同一套
|
|
869
|
+
// https 传输。curl 打 github.com 主页会被按协议/端口区分的防火墙与 TLS 复检
|
|
870
|
+
// 拦截(能 git 克隆、打不开网页),把可装的仓库误判成 [network] 而中止
|
|
871
|
+
// (见 issue #71)。握手失败时再用 curl 复核一次主页连通性:只有两者都不通
|
|
872
|
+
// 才判「网络不通」;仅握手失败(仓库不存在、私有仓库、需要凭据)放行,
|
|
873
|
+
// 交给后续预检与真实安装给出准确原因。
|
|
874
|
+
const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '')
|
|
875
|
+
let net: Awaited<ReturnType<typeof probeUrl>>
|
|
876
|
+
if (gitProbeTarget !== null) {
|
|
877
|
+
net = await gitLsRemote(gitProbeTarget, effectiveProxy, 6000)
|
|
878
|
+
if (!net.ok) {
|
|
879
|
+
const reachable = await probeUrl('https://github.com/', effectiveProxy, 6000)
|
|
880
|
+
if (reachable.ok) net = reachable
|
|
881
|
+
}
|
|
882
|
+
} else {
|
|
883
|
+
net = await probeUrl(npmProbeTarget, effectiveProxy, 6000)
|
|
884
|
+
}
|
|
885
|
+
const probeTarget = gitProbeTarget ?? npmProbeTarget
|
|
847
886
|
if (!net.ok) {
|
|
848
887
|
// 错误消息按客户端界面语言提示:中文界面给中文、英文界面给英文,
|
|
849
888
|
// 让用户一眼看懂是网络问题而非插件问题
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { spawn, spawnSync } from 'node:child_process'
|
|
11
11
|
import { resolvePackageEntry } from './package-entry.ts'
|
|
12
|
-
import { readFileSync, statSync } from 'node:fs'
|
|
12
|
+
import { existsSync, readFileSync, statSync } from 'node:fs'
|
|
13
13
|
import { dirname, join, resolve } from 'node:path'
|
|
14
14
|
import type { InstallResult, InstallTask, Invocation, QueueItem } from './install-types.ts'
|
|
15
15
|
import { CAPTURE_LIMIT_BYTES, MAX_TASKS, MAX_TASK_LINES } from './install-types.ts'
|
|
@@ -129,20 +129,55 @@ function pushLine(task: InstallTask, line: string): void {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
function cliInvocation(): Invocation {
|
|
132
|
+
function cliInvocation(profile: string): Invocation {
|
|
133
133
|
const entry = process.argv[1]
|
|
134
|
-
if (entry !== undefined
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
if (entry !== undefined) {
|
|
135
|
+
// 打包桌面端(Electron):宿主入口在 app.asar 内,机器上根本没有 `dsh` 可执行文件
|
|
136
|
+
//(Windows 那条 dsh.cmd shim 只存在于宿主进程自己的 PATH 里),直接回退 PATH 必然
|
|
137
|
+
// 报 [dsh-missing](见 issue #71)。这里改用应用自己的 CLI 引导脚本调起同一份打包
|
|
138
|
+
// CLI:Electron 可执行文件 + --expose-internals + desktop-cli.js,与内置终端、
|
|
139
|
+
// 官方插件页安装完全同一条路径 —— desktop profile 由应用独占管理的授权也在其中。
|
|
140
|
+
const bootstrap = desktopCliBootstrap(entry)
|
|
141
|
+
if (bootstrap !== null) {
|
|
142
|
+
return {
|
|
143
|
+
file: process.execPath,
|
|
144
|
+
prefixArgs: ['--expose-internals', bootstrap],
|
|
145
|
+
// 工作目录用 profile 目录(真实存在的目录):asar 内的路径不能作为 spawn 的 cwd
|
|
146
|
+
cwd: profileDirectory(profile),
|
|
147
|
+
useShell: false,
|
|
148
|
+
// Electron 可执行文件只有带这个变量才按 Node 运行引导脚本
|
|
149
|
+
env: { ELECTRON_RUN_AS_NODE: '1' },
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (/[\\/](?:bin\.(?:js|ts)|dsh)$/.test(entry)) {
|
|
153
|
+
const absoluteEntry = resolve(entry)
|
|
154
|
+
return {
|
|
155
|
+
file: process.execPath,
|
|
156
|
+
prefixArgs: [...process.execArgv, absoluteEntry],
|
|
157
|
+
cwd: dirname(absoluteEntry),
|
|
158
|
+
useShell: false,
|
|
159
|
+
}
|
|
141
160
|
}
|
|
142
161
|
}
|
|
143
162
|
return { file: 'dsh', prefixArgs: [], cwd: process.cwd(), useShell: process.platform === 'win32' }
|
|
144
163
|
}
|
|
145
164
|
|
|
165
|
+
/**
|
|
166
|
+
* 打包桌面端宿主的 CLI 引导脚本路径(`<asar 根>/lib/desktop-cli.js`,即应用内
|
|
167
|
+
* pnpm 服务的 dshBootstrapPath)。宿主入口落在 app.asar 内时按 asar 根反推候选路径,
|
|
168
|
+
* 命中存在的那个才采用;布局不认识(官方改版)时返回 null,调用方回退原逻辑。
|
|
169
|
+
* 导出供单测覆盖路径推导。
|
|
170
|
+
*/
|
|
171
|
+
export function desktopCliBootstrap(entry: string): string | null {
|
|
172
|
+
const marker = /[\\/]app\.asar(?=[\\/]|$)/i.exec(entry)
|
|
173
|
+
if (marker === null) return null
|
|
174
|
+
const root = entry.slice(0, marker.index + marker[0].length)
|
|
175
|
+
for (const candidate of [join(root, 'lib', 'desktop-cli.js'), join(root, 'dsh', 'lib', 'desktop-cli.js')]) {
|
|
176
|
+
if (existsSync(candidate)) return candidate
|
|
177
|
+
}
|
|
178
|
+
return null
|
|
179
|
+
}
|
|
180
|
+
|
|
146
181
|
/**
|
|
147
182
|
* dsh 命令存在性探测:which/where 找 PATH 里的 dsh。
|
|
148
183
|
* Windows shell 模式命令缺失时 cmd 只输出 GBK 乱码「不是内部或外部命令」(UTF-8 解码后
|
|
@@ -335,7 +370,7 @@ function spawnMutation(options: {
|
|
|
335
370
|
const isGlobalNpm = (globalNpm ?? []).length > 0
|
|
336
371
|
const invocation = isGlobalNpm
|
|
337
372
|
? { file: 'npm', prefixArgs: [], cwd: process.cwd(), useShell: process.platform === 'win32' }
|
|
338
|
-
: cliInvocation()
|
|
373
|
+
: cliInvocation(profile)
|
|
339
374
|
// 更新已安装的 npm 包:显式指定 @latest。pnpm add <pkg>(无版本)对已存在依赖
|
|
340
375
|
// (尤其精确 spec 如 "1.3.0")是幂等的 —— 输出 "Already up to date" 且不改 package.json,
|
|
341
376
|
// 导致「更新成功」但实际仍停留在旧版本;git 地址与全局安装不受此影响。
|
|
@@ -383,7 +418,9 @@ function spawnMutation(options: {
|
|
|
383
418
|
}
|
|
384
419
|
child = spawn(invocation.file, attemptArgs, {
|
|
385
420
|
cwd: invocation.cwd,
|
|
386
|
-
env
|
|
421
|
+
// invocation.env 是「必须叠加」的变量(打包桌面端的 ELECTRON_RUN_AS_NODE):
|
|
422
|
+
// 没有它时保持 env 原样透传,有它时必须基于完整环境叠加,否则子进程会丢掉 PATH。
|
|
423
|
+
env: invocation.env === undefined ? env : { ...(env ?? process.env), ...invocation.env },
|
|
387
424
|
shell: invocation.useShell,
|
|
388
425
|
// detached 使子进程成为独立进程组组长:取消时能整组清理(见 stopChild),
|
|
389
426
|
// 且宿主进程崩溃后安装任务不会被连带误杀
|
|
@@ -51,6 +51,9 @@ export function curlRevokeFlagUnsupported(code: number | null, stderr: string):
|
|
|
51
51
|
return code === 2 && /ssl-revoke-best-effort/i.test(stderr) && /unknown|unrecognized/i.test(stderr)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/** 彻底关闭证书吊销检查的兜底参数(curl ≥ 7.19),比降级参数覆盖更老的 Windows curl。 */
|
|
55
|
+
const NO_REVOKE_ARG = '--ssl-no-revoke'
|
|
56
|
+
|
|
54
57
|
/** stderr 是否指向 Schannel 取不到证书吊销信息(据此归因为环境 TLS 问题,而非网络不通)。 */
|
|
55
58
|
export function tlsRevocationBlocked(stderr: string): boolean {
|
|
56
59
|
return /CRYPT_E_NO_REVOCATION_CHECK|CRYPT_E_REVOCATION_OFFLINE|0x80092012/i.test(stderr)
|
|
@@ -159,12 +162,23 @@ function runCurl(args: string[], env: NodeJS.ProcessEnv, timeoutMs: number): Pro
|
|
|
159
162
|
}
|
|
160
163
|
|
|
161
164
|
/** 带 TLS 兜底的 curl 调用:先按平台参数跑(Windows 带吊销检查降级),
|
|
162
|
-
* 若本机 curl 不认这个参数(curl < 7.70
|
|
165
|
+
* 若本机 curl 不认这个参数(curl < 7.70)则去掉参数重跑一次,保证老版本不因此直接失败;
|
|
166
|
+
* 降级后仍被吊销检查拦死(CRYPT_E_NO_REVOCATION_CHECK)时,再用 --ssl-no-revoke
|
|
167
|
+
* 彻底关掉吊销检查跑一次 —— 该参数 curl ≥ 7.19 即存在,覆盖面比降级参数更广,
|
|
168
|
+
* 否则「能上网但取不到 CRL」的 Windows 机器会把所有通道误报成不可达(见 issue #71)。
|
|
169
|
+
* 吊销检查只影响本次探测自身的信任判断,不改变系统 TLS 配置。 */
|
|
163
170
|
async function curlWithTlsFallback(args: string[], env: NodeJS.ProcessEnv, timeoutMs: number): Promise<CurlRun> {
|
|
164
171
|
const tlsArgs = curlTlsArgs()
|
|
165
|
-
|
|
166
|
-
if (tlsArgs.length
|
|
167
|
-
|
|
172
|
+
let run = await runCurl([...tlsArgs, ...args], env, timeoutMs)
|
|
173
|
+
if (tlsArgs.length > 0 && curlRevokeFlagUnsupported(run.code, run.stderr)) {
|
|
174
|
+
run = await runCurl(args, env, timeoutMs)
|
|
175
|
+
}
|
|
176
|
+
if (tlsArgs.length > 0 && tlsRevocationBlocked(run.stderr)) {
|
|
177
|
+
const retry = await runCurl([NO_REVOKE_ARG, ...args], env, timeoutMs)
|
|
178
|
+
// 只在兜底本身跑起来(非「不认识该参数」)时采用其结果,否则保留原始失败线索
|
|
179
|
+
if (retry.code !== null && !curlRevokeFlagUnsupported(retry.code, retry.stderr)) run = retry
|
|
180
|
+
}
|
|
181
|
+
return run
|
|
168
182
|
}
|
|
169
183
|
|
|
170
184
|
/**
|